Während der Woche der Wärmepumpe haben Sie bundesweit die Möglichkeit, die innovative Wärmepumpentechnologie näher kennenzulernen. Mit über 50 Informationsveranstaltungen beteiligt sich Viessmann Climate Solutions an der Aktionswoche und lädt Sie herzlich ein – vor Ort oder online – dabei zu sein.
Mehr erfahren →Generating the access token for the very first time is a pain in the neck. All the more since the authorization code parameter which has to be created and used to get the authorization token, has a very short 20 seconds time to live (TTL). So, you’d better hurry up and be nimble with ctrl-c and ctrl-v actions when using (semi-)manual solutions with Node-Red snippets, bash or Postman.
Once you’ve generated the access token, refreshing the access token by means of the refresh token every 59 minutes or so, is a snap. However, after 180 days the TTL of the refresh token has expired and you have to go through the cumbersome first-time generation process for the tokens again.
I felt kind of fed up with this – so I played around a bit and came to the solution described here. Please bear with me if my explanations seem a bit trivial or lengthy – I am an amateur not a professional. It took me quite a while to wrap my brain about this, so I’d like to walk you through my train of thought.
I guess there are other solutions around e.g. this one using php: https://www.viessmann-community.com/t5/Getting-started-programming-with/To-help-get-started/td-p/181.... However, I wanted to stay within Node-Red’s environment.
Node-Red has webserver capability by means of two http nodes: http in and http response. They exist under the local address of http://localhost:1880
To create the first call, you’ll need the following parameters:
Both are set by means of the Developer Dashboard at: https://app.developer.viessmann.com/.
I’m assuming that you have already created an account.
The client_id is static, and does not change when you change the redirect_uri setting. It will be created during the first client setting but can be deleted and re-created as you like.
In the generic example the redirect_uri http://localhost:4200 is used. This works fine as long as you use a browser to generate the authorization code which can be copied from the URL field of the browser’s error message.
For our purposes however, we need to change this to http://localhost:1880/authcode. The path authcode can be anything but must be the same as the one used in the URL field of the http in node we’re going to use further down.
Don’t forget to turn off the Google CAPTCHA setting.
Scope is set to scope = "IoT User" this is important otherwise you won’t be able to do much.
Response Type is set to response_type = "code".
Code Challenge is set to
code_challenge=2e21faa1-db2c-4d0b-a10f-575fd372bc8c-575fd372bc8c which is identical to the one used in the “Getting Started” chapter of Viessmann’s documentation. In my opinion you can continue to use that and forget about hashing and encoding as required by the oAuth method. I never was able to grasp the concept.
And, finally we must add the parameter offline_access to also get the refresh token lateron.
The URL assembled to generate the authorization request looks like this (blanks are ecoded by %20) :
https://iam.viessmann.com/idp/v2/authorize?client_id=my_oauth_client_ID&redirect_uri=http://localhost:1880/authcode&response_type=code&code_challenge=2e21faa1-db2c-4d0b-a10f-575fd372bc8c-575fd372bc8c&scope=IoT%20User%20offline_access
Now we can drag an http request node to the development area of Node-Red, additionally a Trigger node and a debug node
The request Node is configured as follows:
Method is GET, URL is the one shown above, Payload is ignored, Basic Authentication is used and is set to your Viessman Login Username and Password, the rest stays as it is.
To receive this request, we need to set up a minimal webserver by using the http in and http response nodes. This looks like so:
The http in node is configured like this:
The URL field has to correspond to the path used in the redirect URI – without server name and port number.
The response node is set to status code 200
Please note that the request part and the response part are not connected by a wire. This is where Internet magic happens.
If all goes well, debug node at the receiving end should show the authorization code after you hit the trigger at the request side. The authorization code can be accessed by using msg.payload.code - we will need it in the following steps.
You will find the complete generic JSON code at the end of this article.
Having created the authorization code represented by msg.payload.code, we can now continue along the Authentication chapter of the Viessmann doc pages. In Node-Red this looks like this:
The top left part we have already covered above.
msg.payload = `grant_type=authorization_code&client_id=my_oauth_client_ID&redirect_uri=http://localhost:1880/authcode&code_verifier=2e21faa1-db2c-4d0b-a10f-575fd372bc8c-575fd372bc8c&code=${msg.payload.code}`;
msg.headers = {};
msg.headers['Content-Type'] = 'application/x-www-form-urlencoded';
return msg;
Watch out, the text after msg.payload is written as one single line only. Also observe the backtics which are necessary to concatenate the fixed part of the payload with the variable “msg.payload.code”. All in all, the JavaScript should consist of 4 lines. You will find the complete JSON (a pdf file) at the end of this article
Observe the setting: Return a parsed JSON object.
If all goes well, the JSON object contains both tokens which can be accessed by msg.payload.access_token and msg.payload.refresh_token.
In my implementation, I have everything concerning the ViCare API in one flow tab. Hence, I’m using flow variables. In case you have distributed the flows on several tabs, you should use global variables instead of flow variables.
Now it’s time to push our response into variables. I use a change node for that.
In addition, you will need the static values for InstallationID, gatewaySerial and deviceID.
You can either generate them once and hard-code them into your flow or re-request them every time, you’re running the initialization logic. In my example, I’m generating them during initialization. It’s a sequence of 3 requests, so we shouldn’t request these values too often – besides it’s unnecessary, they never change.
Refer to section IOT - Overview of the Viessman documentation for their creation or simply go through the JSON (pdf File) provided at the end of this article.
Please note that the automatic Access Token refresh should occur every 59 minutes or so, just in time before the token expires. You could trigger the initialization routine described above. It would generate a new access token from scratch at regular intervals. However, this would eat into your requests allowance and also create extra load on Viessman’s servers.
I recommend to use a specialized refresh flow on the same tab that performs the refresh by using the refresh token. I have written about this in my article “Using Node-Red to visualize ViCare data”. The according JSON Routine is provided there as well.
How should you trigger this initialization process?
If your availability requirements are relaxed, you might as well trigger the initialization manually every time your application fails because of an expired refresh token i.e. every 180 days.
As soon as the refresh token is no longer valid, the Viessmann server’s JSON response will contain a payload.error = "EXPIRED TOKEN" message. You can use this with a switch node to branch to the initialization routine in the rare event the refresh token is expired.
Please refer to my article “Using Node-Red to visualize ViCare data”
I hope that you find this useful. Any comment is highly appreciated. The code can be found in the answer post below or at my website.
Christoph Krzikalla
Gelöst! Gehe zu Lösung.
Ich habe hier nochmal das korrekte JSON per cut&paste eingefügt. Per pdf scheint das nicht zu funktionieren.
Sorry nochmal für die Verwirrung.
VG
Chris
+++++++++++++++++++++++++++++++++++++++++++++++
[
{
"id": "9d0e5593d53b55d0",
"type": "debug",
"z": "31c57f8640528976",
"name": "complete msg object",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1000,
"y": 340,
"wires": []
},
{
"id": "d6e3257c9c2d54ad",
"type": "http request",
"z": "31c57f8640528976",
"name": "1st time Token Request",
"method": "POST",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://iam.viessmann.com/idp/v2/token",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 730,
"y": 460,
"wires": [
[
"9d0e5593d53b55d0",
"a15685d5a21c73f4",
"4cd4555c4b8a54e4",
"e3bde0eca33a67c8"
]
]
},
{
"id": "46386b17e466c5b4",
"type": "function",
"z": "31c57f8640528976",
"name": "set payload & headers",
"func": "msg.payload = `grant_type=authorization_code&client_id=YOURCLIENTID&redirect_uri=http://localhost:1880/authcode&code_verifier=2e21faa1-db2c-4d0b-a10f-575fd372bc8c-575fd372bc8c&code=...}`;\nmsg.headers = {};\nmsg.headers['Content-Type'] = 'application/x-www-form-urlencoded';\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 480,
"y": 460,
"wires": [
[
"d6e3257c9c2d54ad"
]
]
},
{
"id": "d5abc46074c395a0",
"type": "inject",
"z": "31c57f8640528976",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 290,
"y": 240,
"wires": [
[
"c765f5d53247981e"
]
]
},
{
"id": "595c3f168551465e",
"type": "debug",
"z": "31c57f8640528976",
"name": "Request Result",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 620,
"y": 240,
"wires": []
},
{
"id": "904e0e39a0436cf7",
"type": "http in",
"z": "31c57f8640528976",
"name": "",
"url": "/authcode",
"method": "get",
"upload": false,
"swaggerDoc": "",
"x": 240,
"y": 360,
"wires": [
[
"beb9836fcb2f735c",
"1282ee44e06b324d",
"46386b17e466c5b4"
]
]
},
{
"id": "beb9836fcb2f735c",
"type": "debug",
"z": "31c57f8640528976",
"name": "msg.payload.code",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload.code",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 470,
"y": 320,
"wires": []
},
{
"id": "1282ee44e06b324d",
"type": "http response",
"z": "31c57f8640528976",
"name": "Reponse",
"statusCode": "200",
"headers": {},
"x": 440,
"y": 360,
"wires": []
},
{
"id": "13da70accda71262",
"type": "comment",
"z": "31c57f8640528976",
"name": "Generate authorization code",
"info": "",
"x": 320,
"y": 200,
"wires": []
},
{
"id": "c765f5d53247981e",
"type": "http request",
"z": "31c57f8640528976",
"name": "",
"method": "GET",
"ret": "txt",
"paytoqs": "ignore",
"url": "https://iam.viessmann.com/idp/v2/authorize?client_id=a602c3ccb073b72740420f03ad1b21f3&redirect_uri=h...",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "basic",
"senderr": false,
"headers": [],
"x": 450,
"y": 240,
"wires": [
[
"595c3f168551465e"
]
]
},
{
"id": "296e1357a73c8e32",
"type": "comment",
"z": "31c57f8640528976",
"name": "Click here -->",
"info": "",
"x": 110,
"y": 240,
"wires": []
},
{
"id": "751a30abd962d114",
"type": "comment",
"z": "31c57f8640528976",
"name": "after expiry",
"info": "",
"x": 100,
"y": 200,
"wires": []
},
{
"id": "a15685d5a21c73f4",
"type": "debug",
"z": "31c57f8640528976",
"name": "access_token",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 980,
"y": 420,
"wires": []
},
{
"id": "e3bde0eca33a67c8",
"type": "debug",
"z": "31c57f8640528976",
"name": "refresh_token",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 980,
"y": 380,
"wires": []
},
{
"id": "4cd4555c4b8a54e4",
"type": "change",
"z": "31c57f8640528976",
"name": "set token flow variables",
"rules": [
{
"t": "set",
"p": "accessToken",
"pt": "flow",
"to": "payload.access_token",
"tot": "msg"
},
{
"t": "set",
"p": "refreshToken",
"pt": "flow",
"to": "payload.refresh_token",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1010,
"y": 460,
"wires": [
[
"0a5b06420e87d77f"
]
]
},
{
"id": "3d828c3c867062b0",
"type": "http request",
"z": "31c57f8640528976",
"name": "Installation ID",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://api.viessmann.com/iot/v1/equipment/installations",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 680,
"y": 600,
"wires": [
[
"f32181561f6a81ab"
]
]
},
{
"id": "0a5b06420e87d77f",
"type": "function",
"z": "31c57f8640528976",
"name": "Auth Header",
"func": "var atoken = flow.get('accessToken')\nmsg.headers = {\n Authorization: \"Bearer \"+ atoken\n}\nreturn msg;\n\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 450,
"y": 600,
"wires": [
[
"3d828c3c867062b0"
]
]
},
{
"id": "d189c65f2d221d39",
"type": "http request",
"z": "31c57f8640528976",
"name": "Gateway Serial",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://api.viessmann.com/iot/v1/equipment/gateways",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 680,
"y": 640,
"wires": [
[
"a92443f4485556c4"
]
]
},
{
"id": "f32181561f6a81ab",
"type": "change",
"z": "31c57f8640528976",
"name": "set flow.installationID",
"rules": [
{
"t": "set",
"p": "installationID",
"pt": "flow",
"to": "payload.data[0].id",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 880,
"y": 600,
"wires": [
[
"dadfb8ae29d2643b"
]
]
},
{
"id": "a92443f4485556c4",
"type": "change",
"z": "31c57f8640528976",
"name": "set flow.gatewaySerial",
"rules": [
{
"t": "set",
"p": "gatewaySerial",
"pt": "flow",
"to": "payload.data[0].serial",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 880,
"y": 640,
"wires": [
[
"5cfecbbe8f899905"
]
]
},
{
"id": "dadfb8ae29d2643b",
"type": "function",
"z": "31c57f8640528976",
"name": "Auth Header",
"func": "var atoken = flow.get('accessToken')\nmsg.headers = {\n Authorization: \"Bearer \"+ atoken\n}\nreturn msg;\n\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 450,
"y": 640,
"wires": [
[
"d189c65f2d221d39"
]
]
},
{
"id": "f52e123cdd02a6bc",
"type": "http request",
"z": "31c57f8640528976",
"name": "DeviceID",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://api.viessmann.com/iot/v1/equipment/installations/{{iid}}/gateways/{{gws}}/devices/ ",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 660,
"y": 680,
"wires": [
[
"e553113d728f21a8"
]
]
},
{
"id": "e553113d728f21a8",
"type": "change",
"z": "31c57f8640528976",
"name": "",
"rules": [
{
"t": "set",
"p": "deviceID",
"pt": "flow",
"to": "payload.data[0].id",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 870,
"y": 680,
"wires": [
[]
]
},
{
"id": "5cfecbbe8f899905",
"type": "function",
"z": "31c57f8640528976",
"name": "extended auth header",
"func": "//var o = parseFloat(flow.get('2vo1'));\n//var atoken = msg.token\nvar atoken = flow.get('accessToken')\nmsg.headers = {\n Authorization: \"Bearer \"+ atoken\n}\nmsg.iid = flow.get('installationID');\nmsg.gws = flow.get('gatewaySerial');\nreturn msg;\n\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 480,
"y": 680,
"wires": [
[
"f52e123cdd02a6bc"
]
]
},
{
"id": "27904bd00d57b5f8",
"type": "comment",
"z": "31c57f8640528976",
"name": "get tokens 1st time",
"info": "",
"x": 290,
"y": 420,
"wires": []
},
{
"id": "5ddbfc6f31907258",
"type": "comment",
"z": "31c57f8640528976",
"name": "get/set invariable parameters",
"info": "",
"x": 320,
"y": 540,
"wires": []
}
]
Mittlerweile habe ich einige meiner Tutorials auf Deutsch umgestellt, aktualisiert und auf meinem kleinen Tech-Blog veröffentlicht. Ihr findet das auf https://rustimation.eu - wird je nach Erkenntnisfortschritt erweitert und ergänzt.
Chris
Irgendwie wäre es schön, wenn es für derlei Tutorials einen eigenen Forenbereich gäbe. Ferner würde ich mir wünschen, als Autor nachträglich och Änderungen vornehmen zu können.
Oder wäre es besser, nur einen kurzen Einleitungstext zu schreiben und das Tutorial dann als pdf anzuhängen?
Hey.
Great help for my first time start with NodeRed.
But when I copy/paste the initialize token text and import it in NodeRed I get a error message
SyntaxError: Unexpected string in JSON at position 4745
tot": "msg"↵"reg": false
Any idea where my mistake is?
BR
oops!!
Da hat mir der pdf Konverter einen Streich gesielt und zu lange Zeilen mit einem Zeilenumbruchzeichen "verschönert".
Abhilfe fürs Erste: Text mit Ctrl-C und Ctrl-V (bzw. Strg-...) kopieren und in einen Editor pasten. Dann bei den im Import angegebenen Zeilen
hier zum Beispiel Zeile 60 die Zeilen zusammenfügen:
Tut mir ausgesprichen leid. Ich versuche das in der kommenden Woche irgendwie zu beheben. Saublöd. dass man keine JSON oder TXT Dateien im Forum Hochladen kann...
VG
Chris
Ich habe hier nochmal das korrekte JSON per cut&paste eingefügt. Per pdf scheint das nicht zu funktionieren.
Sorry nochmal für die Verwirrung.
VG
Chris
+++++++++++++++++++++++++++++++++++++++++++++++
[
{
"id": "9d0e5593d53b55d0",
"type": "debug",
"z": "31c57f8640528976",
"name": "complete msg object",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1000,
"y": 340,
"wires": []
},
{
"id": "d6e3257c9c2d54ad",
"type": "http request",
"z": "31c57f8640528976",
"name": "1st time Token Request",
"method": "POST",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://iam.viessmann.com/idp/v2/token",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 730,
"y": 460,
"wires": [
[
"9d0e5593d53b55d0",
"a15685d5a21c73f4",
"4cd4555c4b8a54e4",
"e3bde0eca33a67c8"
]
]
},
{
"id": "46386b17e466c5b4",
"type": "function",
"z": "31c57f8640528976",
"name": "set payload & headers",
"func": "msg.payload = `grant_type=authorization_code&client_id=YOURCLIENTID&redirect_uri=http://localhost:1880/authcode&code_verifier=2e21faa1-db2c-4d0b-a10f-575fd372bc8c-575fd372bc8c&code=...}`;\nmsg.headers = {};\nmsg.headers['Content-Type'] = 'application/x-www-form-urlencoded';\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 480,
"y": 460,
"wires": [
[
"d6e3257c9c2d54ad"
]
]
},
{
"id": "d5abc46074c395a0",
"type": "inject",
"z": "31c57f8640528976",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 290,
"y": 240,
"wires": [
[
"c765f5d53247981e"
]
]
},
{
"id": "595c3f168551465e",
"type": "debug",
"z": "31c57f8640528976",
"name": "Request Result",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 620,
"y": 240,
"wires": []
},
{
"id": "904e0e39a0436cf7",
"type": "http in",
"z": "31c57f8640528976",
"name": "",
"url": "/authcode",
"method": "get",
"upload": false,
"swaggerDoc": "",
"x": 240,
"y": 360,
"wires": [
[
"beb9836fcb2f735c",
"1282ee44e06b324d",
"46386b17e466c5b4"
]
]
},
{
"id": "beb9836fcb2f735c",
"type": "debug",
"z": "31c57f8640528976",
"name": "msg.payload.code",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload.code",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 470,
"y": 320,
"wires": []
},
{
"id": "1282ee44e06b324d",
"type": "http response",
"z": "31c57f8640528976",
"name": "Reponse",
"statusCode": "200",
"headers": {},
"x": 440,
"y": 360,
"wires": []
},
{
"id": "13da70accda71262",
"type": "comment",
"z": "31c57f8640528976",
"name": "Generate authorization code",
"info": "",
"x": 320,
"y": 200,
"wires": []
},
{
"id": "c765f5d53247981e",
"type": "http request",
"z": "31c57f8640528976",
"name": "",
"method": "GET",
"ret": "txt",
"paytoqs": "ignore",
"url": "https://iam.viessmann.com/idp/v2/authorize?client_id=a602c3ccb073b72740420f03ad1b21f3&redirect_uri=h...",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "basic",
"senderr": false,
"headers": [],
"x": 450,
"y": 240,
"wires": [
[
"595c3f168551465e"
]
]
},
{
"id": "296e1357a73c8e32",
"type": "comment",
"z": "31c57f8640528976",
"name": "Click here -->",
"info": "",
"x": 110,
"y": 240,
"wires": []
},
{
"id": "751a30abd962d114",
"type": "comment",
"z": "31c57f8640528976",
"name": "after expiry",
"info": "",
"x": 100,
"y": 200,
"wires": []
},
{
"id": "a15685d5a21c73f4",
"type": "debug",
"z": "31c57f8640528976",
"name": "access_token",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 980,
"y": 420,
"wires": []
},
{
"id": "e3bde0eca33a67c8",
"type": "debug",
"z": "31c57f8640528976",
"name": "refresh_token",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 980,
"y": 380,
"wires": []
},
{
"id": "4cd4555c4b8a54e4",
"type": "change",
"z": "31c57f8640528976",
"name": "set token flow variables",
"rules": [
{
"t": "set",
"p": "accessToken",
"pt": "flow",
"to": "payload.access_token",
"tot": "msg"
},
{
"t": "set",
"p": "refreshToken",
"pt": "flow",
"to": "payload.refresh_token",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1010,
"y": 460,
"wires": [
[
"0a5b06420e87d77f"
]
]
},
{
"id": "3d828c3c867062b0",
"type": "http request",
"z": "31c57f8640528976",
"name": "Installation ID",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://api.viessmann.com/iot/v1/equipment/installations",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 680,
"y": 600,
"wires": [
[
"f32181561f6a81ab"
]
]
},
{
"id": "0a5b06420e87d77f",
"type": "function",
"z": "31c57f8640528976",
"name": "Auth Header",
"func": "var atoken = flow.get('accessToken')\nmsg.headers = {\n Authorization: \"Bearer \"+ atoken\n}\nreturn msg;\n\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 450,
"y": 600,
"wires": [
[
"3d828c3c867062b0"
]
]
},
{
"id": "d189c65f2d221d39",
"type": "http request",
"z": "31c57f8640528976",
"name": "Gateway Serial",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://api.viessmann.com/iot/v1/equipment/gateways",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 680,
"y": 640,
"wires": [
[
"a92443f4485556c4"
]
]
},
{
"id": "f32181561f6a81ab",
"type": "change",
"z": "31c57f8640528976",
"name": "set flow.installationID",
"rules": [
{
"t": "set",
"p": "installationID",
"pt": "flow",
"to": "payload.data[0].id",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 880,
"y": 600,
"wires": [
[
"dadfb8ae29d2643b"
]
]
},
{
"id": "a92443f4485556c4",
"type": "change",
"z": "31c57f8640528976",
"name": "set flow.gatewaySerial",
"rules": [
{
"t": "set",
"p": "gatewaySerial",
"pt": "flow",
"to": "payload.data[0].serial",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 880,
"y": 640,
"wires": [
[
"5cfecbbe8f899905"
]
]
},
{
"id": "dadfb8ae29d2643b",
"type": "function",
"z": "31c57f8640528976",
"name": "Auth Header",
"func": "var atoken = flow.get('accessToken')\nmsg.headers = {\n Authorization: \"Bearer \"+ atoken\n}\nreturn msg;\n\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 450,
"y": 640,
"wires": [
[
"d189c65f2d221d39"
]
]
},
{
"id": "f52e123cdd02a6bc",
"type": "http request",
"z": "31c57f8640528976",
"name": "DeviceID",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://api.viessmann.com/iot/v1/equipment/installations/{{iid}}/gateways/{{gws}}/devices/ ",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 660,
"y": 680,
"wires": [
[
"e553113d728f21a8"
]
]
},
{
"id": "e553113d728f21a8",
"type": "change",
"z": "31c57f8640528976",
"name": "",
"rules": [
{
"t": "set",
"p": "deviceID",
"pt": "flow",
"to": "payload.data[0].id",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 870,
"y": 680,
"wires": [
[]
]
},
{
"id": "5cfecbbe8f899905",
"type": "function",
"z": "31c57f8640528976",
"name": "extended auth header",
"func": "//var o = parseFloat(flow.get('2vo1'));\n//var atoken = msg.token\nvar atoken = flow.get('accessToken')\nmsg.headers = {\n Authorization: \"Bearer \"+ atoken\n}\nmsg.iid = flow.get('installationID');\nmsg.gws = flow.get('gatewaySerial');\nreturn msg;\n\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 480,
"y": 680,
"wires": [
[
"f52e123cdd02a6bc"
]
]
},
{
"id": "27904bd00d57b5f8",
"type": "comment",
"z": "31c57f8640528976",
"name": "get tokens 1st time",
"info": "",
"x": 290,
"y": 420,
"wires": []
},
{
"id": "5ddbfc6f31907258",
"type": "comment",
"z": "31c57f8640528976",
"name": "get/set invariable parameters",
"info": "",
"x": 320,
"y": 540,
"wires": []
}
]
Großartig! Import hat auf Anhieb funktioniert.
Vielen Dank!!!
Alter Schwede.
Ich habe mich jetzt echt ne weile mit der API gequält.
Das war der Beitrag, den ich gebraucht habe.
Danke Chris
Mittlerweile habe ich einige meiner Tutorials auf Deutsch umgestellt, aktualisiert und auf meinem kleinen Tech-Blog veröffentlicht. Ihr findet das auf https://rustimation.eu - wird je nach Erkenntnisfortschritt erweitert und ergänzt.
Chris