Node-red-contrib-netatmo 0.3.0: Error: Authenticate error: unauthorized_client

[{"id":"1cbf23a1.c57b7c","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"255cedb1.d40692","type":"inject","z":"1cbf23a1.c57b7c","name":"3 Minuten","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"180","crontab":"","once":true,"onceDelay":"1","topic":"3 Min Timer","payload":"true","payloadType":"bool","x":150,"y":100,"wires":[["f1969024.1987b"]]},{"id":"f1969024.1987b","type":"netatmo-dashboard","z":"1cbf23a1.c57b7c","creds":"e32844f7.84fe58","x":370,"y":100,"wires":[["4f0f230e.dc0d3c"]]},{"id":"4f0f230e.dc0d3c","type":"debug","z":"1cbf23a1.c57b7c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":660,"y":100,"wires":[ ]},{"id":"e32844f7.84fe58","type":"netatmo-config-node","name":"HomeCoach","client_id":"XXXX","client_secret":"XXXX","refresh_token":"XXXX"}]

Thx, but my question is, how i can get the datas from the HomeCoach?

[{"id":"65dd246ebde5169d","type":"function","z":"68cb8365d480cc44","name":"function 42","func":"let a = [{ \"id\": \"1cbf23a1.c57b7c\", \"type\": \"tab\", \"label\": \"Flow 2\", \"disabled\": false, \"info\": \"\" },\n { \"id\": \"255cedb1.d40692\", \"type\": \"inject\", \"z\": \"1cbf23a1.c57b7c\", \"name\": \"3 Minuten\",\n  \"props\": [{ \"p\": \"payload\" }, { \"p\": \"topic\", \"vt\": \"str\" }], \"repeat\": \"180\",\n   \"crontab\": \"\", \"once\": true, \"onceDelay\": \"1\", \"topic\": \"3 Min Timer\", \"payload\": \"true\",\n    \"payloadType\": \"bool\", \"x\": 150, \"y\": 100, \"wires\": [[\"f1969024.1987b\"]] },\n     { \"id\": \"f1969024.1987b\", \"type\": \"netatmo-dashboard\", \"z\": \"1cbf23a1.c57b7c\", \"creds\": \"e32844f7.84fe58\",\n      \"x\": 370, \"y\": 100, \"wires\": [[\"4f0f230e.dc0d3c\"]] }, { \"id\": \"4f0f230e.dc0d3c\", \"type\": \"debug\",\n       \"z\": \"1cbf23a1.c57b7c\", \"name\": \"\", \"active\": true, \"tosidebar\": true, \"console\": false,\n        \"tostatus\": false, \"complete\": \"false\", \"statusVal\": \"\", \"statusType\": \"auto\", \"x\": 660, \"y\": 100,\n         \"wires\": [] }, { \"id\": \"e32844f7.84fe58\", \"type\": \"netatmo-config-node\", \"name\": \"HomeCoach\",\n          \"client_id\": \"64a015b8dce01f3a190c2643\", \"client_secret\": \"6fCm1uAKBUbwHn8gzCnmglhHfRXO1sS\",\n           \"refresh_token\": \"51149bd1187759c7370000ee|2381180867a07d06ae99da90834f8ca6\" }];\nmsg.payload = a;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":550,"y":560,"wires":[["649e1e32f83cf071","aa18b23087008cc0"]]},{"id":"252bd24d08db3d12","type":"inject","z":"68cb8365d480cc44","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":400,"y":560,"wires":[["65dd246ebde5169d"]]},{"id":"e2d14ed7245c7431","type":"debug","z":"68cb8365d480cc44","name":"debug 174","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":950,"y":540,"wires":[]},{"id":"649e1e32f83cf071","type":"function","z":"68cb8365d480cc44","name":"function 43","func":"msg.payload = msg.payload[0].label;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":770,"y":540,"wires":[["e2d14ed7245c7431"]]},{"id":"aa18b23087008cc0","type":"function","z":"68cb8365d480cc44","name":"function 44","func":"msg.payload = msg.payload[2].type;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":770,"y":600,"wires":[["5f4522cff75cd6a8"]]},{"id":"5f4522cff75cd6a8","type":"debug","z":"68cb8365d480cc44","name":"debug 175","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":950,"y":600,"wires":[]}]

I don't know home coach. This is the only help I can provide.

Thank you very much for your help. But i need a Node or something to get the Datas from Netatmo into the Node-Red. And actually there is no working Node to get the Datas :frowning:

I have said it before - oauth2 is horrible. Would be nice if it could be integrated into the http request node (somehow), especially with so many applications using it today and it requires a browser for interaction with the api provider to provide scoped access.

What I used with the old node and still miss in the new node is the ability to read public data from other Netatmo installations, which I used to get rain information in my area.

I had the same issue. Instead I installed the node-red-oauth2 node, which made this relatively easy, as it provides an interface to setup the access.

Example flow (still requires one-time fiddling)


In the authorization code node provide the

clientid
client secret

Click the key button, it will open a window to netatmo, ok for access, window will close
now the code has been filled in, done
deploy
press the inject button

Access token and refresh token are saved as a global object

Now you can access the public data url (make sure to modify the url inside the function node)
Adjust the credentials function node to refresh the token automatically every 55 mins.

[{"id":"cb7f83d9a367348a","type":"inject","z":"225edc0f2ab084a8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":260,"wires":[["2514d8dc875c1b2e"]]},{"id":"990b3fc65eb5a01c","type":"http request","z":"225edc0f2ab084a8","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"credentials":{},"x":445,"y":260,"wires":[["8c7095a7361d00b6"]],"l":false},{"id":"2514d8dc875c1b2e","type":"function","z":"225edc0f2ab084a8","name":"get public data","func":"const access_token = global.get('netatmo_oauth2').token.access_token\nconst headers = {}\nconst types = [\"rain\", \"wind\"]\n\nheaders[\"Authorization\"] = `Bearer ${access_token}`\n\nlet url = \"https://api.netatmo.com/api/getpublicdata?lat_ne=52.147605%20&lon_ne=4.473581&lat_sw=52.108087&lon_sw=4.435644&filter=false\"\n\ntypes.forEach(type=>{\n    url = `${url}&required=${type}`\n    node.send({headers,url})\n})\n\n\nreturn null","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":320,"y":260,"wires":[["990b3fc65eb5a01c"]]},{"id":"8c7095a7361d00b6","type":"debug","z":"225edc0f2ab084a8","name":"debug 383","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":550,"y":260,"wires":[]},{"id":"592dc8f750c3cd36","type":"group","z":"225edc0f2ab084a8","name":"setup credentials","style":{"label":true},"nodes":["9909b6f7dfd95f9f","1ef7250fbe8d2af9","7c6ab1c7a02690d4","6f5aed0bdbad1cae","8198db5e0cfcb195","e1fbe19cb319629c","cdab0b5dadd0e33e","8251478843e59995","28a02df4e332b227"],"x":54,"y":59,"w":642,"h":142},{"id":"9909b6f7dfd95f9f","type":"oauth2","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"Authorization Code","container":"oauth2Response","grant_type":"authorization_code","access_token_url":"https://api.netatmo.com/oauth2/token","authorization_endpoint":"https://api.netatmo.com/oauth2/authorize","redirect_uri":"/oauth2/redirect_uri","open_authentication":"","username":"","password":"","client_id":"","client_secret":"","scope":"read_station","proxy":"","senderr":false,"client_credentials_in_body":false,"rejectUnauthorized":true,"headers":{},"x":330,"y":100,"wires":[["e1fbe19cb319629c"]]},{"id":"1ef7250fbe8d2af9","type":"inject","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":100,"wires":[["9909b6f7dfd95f9f"]]},{"id":"7c6ab1c7a02690d4","type":"inject","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"Refresh Token","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"3300","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":180,"y":160,"wires":[["8251478843e59995"]]},{"id":"6f5aed0bdbad1cae","type":"oauth2","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"Set by msg.oauth2Request","container":"oauth2Response","grant_type":"set_by_credentials","access_token_url":"http://localhost:3000/oauth/token ","username":"pedroet","password":"","client_id":"confidentialApplication","client_secret":"topSecret","scope":"*","headers":{},"x":455,"y":160,"wires":[["28a02df4e332b227"]],"l":false},{"id":"8198db5e0cfcb195","type":"debug","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"DBG 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":600,"y":160,"wires":[]},{"id":"e1fbe19cb319629c","type":"function","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"Set refreshToken","func":"const access_token_url = \"https://api.netatmo.com/oauth2/token\"\n\nif (msg.oauth2Response.access_token) {\n    const netatmo_oauth2 = {}\n    netatmo_oauth2.url = access_token_url\n    netatmo_oauth2.token = msg.oauth2Response\n\n    global.set(\"netatmo_oauth2\", netatmo_oauth2)\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":455,"y":100,"wires":[["cdab0b5dadd0e33e"]],"l":false},{"id":"cdab0b5dadd0e33e","type":"debug","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"DBG 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":550,"y":100,"wires":[]},{"id":"8251478843e59995","type":"function","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"credentials","func":"let netatmo = global.get('netatmo_oauth2');\n\nmsg.oauth2Request = { \n    \"access_token_url\": netatmo.url,\n    \"credentials\": {\n        \"grant_type\": \"refresh_token\",\n        \"client_id\": \"\",\n        \"client_secret\": \"\",\n        \"scope\": \"read_station\",\n        \"refresh_token\": netatmo.token.refresh_token   \n    },\n};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":160,"wires":[["6f5aed0bdbad1cae"]]},{"id":"28a02df4e332b227","type":"function","z":"225edc0f2ab084a8","g":"592dc8f750c3cd36","name":"Set refreshToken","func":"const access_token_url = \"https://api.netatmo.com/oauth2/token\"\n\nif (msg.oauth2Response.access_token) {\n    const netatmo_oauth2 = {}\n    netatmo_oauth2.url = access_token_url\n    netatmo_oauth2.token = msg.oauth2Response\n\n    global.set(\"netatmo_oauth2\", netatmo_oauth2)\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":505,"y":160,"wires":[["8198db5e0cfcb195"]],"l":false}]
1 Like

Hi bakman2,
this looks very promising to me. Thaks for the info!

1 Like

Hi bakman2

thx for additional help. i will try it soon.
Actually i am unable to install the node. I receive everytime the Failure:

2023-08-07T14:57:31.020Z installieren : node-red-contrib-oauth2 5.0.4

2023-08-07T14:57:31.069Z npm install --no-audit --no-update-notifier --no-fund --save --save-prefix="~" --production node-red-contrib-oauth2@5.0.4
2023-08-07T14:57:41.057Z [out] + node-red-contrib-oauth2@5.0.4
2023-08-07T14:57:41.057Z [out] updated 3 packages and moved 1 package in 8.731s
2023-08-07T14:57:41.084Z rc=0

i can't find any dependencies... any idea?

Looks like it installed succesfully. Would recommend to use the node-red palette to install plugins.
If you don't see the node, you may need to restart node-red

@bakman2

It works!!
I had problems with generating the key (I did not realize, that the code is already filled in)
and also in the Refresh token line the oauth2 node shows a status "ERR_BAD_REQUEST" when pressing inject and DBG2 says: oauth2Response.error: invalid_client

Another point: according to

the parameter to get only rain sensors should be required_data=rain
but in your code you use &required=${type}!?

But I get the data I need and now I only have to integrate the new flow in my existing flow.

I had to move msg.payload.body to msg.payload, so that my existing flows continues to work.

I defined an array of types:

...
const types = ["rain", "wind"]
...
types.forEach(type=>{
    url = `${url}&required=${type}`
    node.send({headers,url})
})

So it makes 2 requests, one for rain and another for wind.
Change it to:

const types = ["rain"]

and you will only get rain.

Refresh token line the oauth2 node shows a status "ERR_BAD_REQUEST " when pressing inject and DBG2 says: oauth2Response.error: invalid_client

you will need to provide the credentials in the "credentials" function node (client_id,client_secret) .

I saw the code and understood it :smile:

But your &required= should be a &required_data=

I thought, they can be used from the first line, but obviously they cannot be extracted out of the oauth2 node. It works now, but is there any chance to hide the client secret in the function code, maybe by filling the second oauth2 node with client_id and client_secret instead of "Set by msg.oauth2Request"?

Nevertheless, thank you very much for helping me / us with the oauth2 thing.

image

I receive in all ways this error, restart Node-red oder the Pi doesn't help.

You are correct, my mistake.

I receive in all ways this error, restart Node-red oder the Pi doesn't help.

Which node-red version and node js version do you use ?

Hi Guys,

thanks a lot for all the help.
My Problem was a old version of Node Red to install the Oauth2 Node.

Now i am able to receive the right Array, but i am stil not able to work with them :cry:

So my debug node shows this:
Bildschirmfoto 2023-08-09 um 19.21.12

My function is:

var msg1 = {};

msg1.payload = msg.payload.body.devices[0].station_name;

return msg1;

and it doesn't work. do you see any mistake? I add this Function instead of the "debug383" in your sample.

thx

Looks ok for me. But what Do you mean exactly regarding does not work?

There is no Output in the Debug Node after the Script...

I receive in "debug 384" the right Array. In the Node "debug 385" i receivenothing.

I don't understand why...

Set the debug node to Output Complete Message.

Doesn't work... :frowning:

The function node has two outputs but only one of the outputs has a debug attached. Put another debug node on the other output.

Thank you very much, now it works. It was a failure with the Outputs an the Var's.

Now i can read the homecoach perfectly!

Thx you all!

1 Like