Viessmann API und Node-Red - Teil 3 - Daten abfragen

Dies ist das dritte Kapitel meiner Reihe über die Nutzung der Viessmann API mit Node-Red. Einen Einstieg bekommst du am ehesten, indem du mit dem Kapitel 1 – Die Viessmann API und Node-Red Überblick anfängst.

Autorisierung des Requests

Alle für die Autorisierung eines beliebigen Requests nötigen Informationen befinden sich in meinem "Universal Header Node", einem Funktionsnode, der den http Request Node entsprechend für die Abfrage der API bestückt. Der Funktionsnode sieht wie folgt aus und muss nicht individuell angepasst werden.

Das alles setzt voraus, dass die entsprechenden Flow Variablen wie im vorigen Kapitel gesetzt wurden.

In diesem Beispiel sind alle Viessmann Komponenten auf einem Node-Red Tab versammelt; daher werden weitgehend Flow Variable verwendet. Für den Fall, dass die Logik auf mehrere Flows verteilt ist, sind ensprechend Global Variablen zu verwenden.

Feature Überblick

Die Feature Abfrage liefert dir auf einen Schlag alle Parameter, welche deine Anlage bei dem von dir gebuchten Paket zur Verfügung stellt. Die übermittelte Liste (ein großes JSON Objekt) ist für jede Installation unterschiedlich. Sie ist hilfreich, um sich die Parameter herauszusuchen, die einen interessieren. Die Datenpunkte sind im Developer Bereich von Viessmann erklärt.

Die Abfrage erfolgt wie folgt:

Der http Request sieht so aus:

Zur besseren Lesbarkeit noch die URL Zeile als JS Code:

Auch diese Zeile muss nicht angepasst werden. Die im Universal Heade Node davor gesetzten Werte stecken in den doppelten geschweiften Klammern (double moustaches).

Seit Februar 2023 gibt es eine etwas andere API Syntax bei der Feature Abfrage, bzw. einen neuen Endpunkt "features", der den bisherigen Endunkt "equipment" ersetzt.
https://api.viessmann.com/iot/v1/features/installations... Die Anleitung hier ist auf die neuen Verhältnisse angepasst.

Nach dem Triggern erscheint - wenn alles funktioniert wie gewünscht - im Debug Node ein Objekt, das wir durch Anklicken der kleinen Dreiecke analysieren können. Unsere Features stecken in der Payload, bei mir sind das immerhin 110 verschiedene Parameter.

Das Debug Fenster erreicht man über das Anklicken des Käfersymbols oben rechts.

Zum Ansehen eines JSON Objekts gibt es mehrere Möglichkeiten. Entweder einen Online JSON Viewer, oder mit Firefox indem man das abgespeicherte JSON File lädt oder mit Notepad++ und einem JSON Viewer Plugin und sicher noch eine Menge anderer Möglichkeiten. Einfach den "Werte kopieren" Button oben rechts im Debugfenster anklicken und dann in das gewünschte Dokument pasten.

Der Vollständigkeit halber noch der JSON Flow:

Nur wenige Datenpunkte auslesen

Wie du wahrscheinlich weißt, gibt es eine Begrenzung von 1440 Zugriffen innerhalb 24 Stunden. Wenn dich nur wenige Datenpunkte interessieren und diese auch nicht all zu oft abfragen willst, dann ist der direkte Featurezugriff über die URL am einfachsten.

Probieren wir das einfach mit dem Wert "gemeinsame Vorlauftemperatur" - im JSON steht das unter heating.boiler.sensors.temperature.commonSupply.

Die URL Zeile im Read Feature http Request Node sieht wie folgt aus:

Die API liefert uns ein kleines JSON Objekt, aus dem wir den Datenpunkt ganz leicht extrahieren können. Der Extract Value Node sieht so aus:

msg.topic ist nicht unbedingt erforderlich, hilft aber, wenn man ein Chart mit mehreren Kurven baut.

Hier der JSON Flow dazu:

Würdest du diesen Flow jede Minute aufrufen, wären alle 1440 Zugriffe/Tag  verbraucht. In so fern ist das Abfragen weniger einzelner Datenpunkte nur bei geringer Abfragefrequenz sinnvoll.

Übrigens: Auch wenn alle Zugriffe verbraucht sind, kannst du immer noch mit der App auf deine Heizung zugreifen.

Mehr Datenpunkte öfter auslesen

Da der große "Feature Request" von weiter oben ja alle Datenpunkte inklusive deren Werte auf einmal ausliest, können wir das Ergebnis dieses Requests relativ leicht in einzelne Werte aufdröseln.

Man könnte sich hier einfach an der Position des gesuchten Datenpunkts im Array orientieren. Nehmen wir an, die Außentemperatur ist der 65. Wert in der Feature Overview Tabelle, dann können wir diesen Wert per Javacript ganz einfach extrahieren:

Das klingt zwar ganz einfach, hat aber Nachteile: Viessmann wird die Reihenfolge beliebig ändern, wenn neue Features hinzukommen oder wegfallen. Der Datenpunkt ist also nicht immer an 65. Stelle. Auch wird sich die Position des Datenpunkts von Installation zu Installation unterscheiden.

Um die uns interessierenden Datenpunkte zu extrahieren, müssen wir das JSON Feature Objekt nach dem richtigen Namen durchforsten d.h. parsen.

Das geschieht über die Javascript findindex Methode:

Auf diese Weise lassen sich quasi beliebig viele Datenpunkte auswerten, ohne das Abrufkontingent zu überlasten. Bei meiner Implementation frage ich alle 90 Sekunden nach den Werten. So habe ich immer noch genug Reserve für andere Abfragen oder Einstellungen.

Visualisieren

Will man sich lediglich den aktuellen Wert in Textform anzeigen lassen, dann reicht der Dashboard Text Node aus.

Eine hübschere Darstellung bekommen wir, wenn wir den Dashboard Gauge Node. verwenden. Für die Darstellung von Prozentwerten ist das Donut Gauge sehr nett anzusehen. Füllstände mit dem Level Gauge.

Schaltzustände z.B. Brenner an/aus lassen sich ganz einfach durch umfunktionierte Dashboard Switch Nodes darstellen.Hier lässt sich auch das Standard Icon gegen eine Reihe anderer, auch animierter Symbole austauschen. Obiges Flammensymbol lässt sich einstellen, indem der Switch Mode wie folgt konfiguriert wird:

Mehr über die Verwendung von Font Awesome und Material Design Icons im Kapitel "Node-Red Dashboard Tips & Tricks".

Liniendiagramme

Werte im Zeitverlauf kann man sehr schön mit mit dem Dashboard Chart Node darstellen.

Hierzu einfach den Output Node mit dem Chart Node verbinden. Bei Gruppe einen entsprechenden Überbegriff eintragen, ggf. dahinter (Bleistiftsymbol) noch das passende Tab auswählen. Hier einfach mal ein bisschen spielen...

Wenn man bei Y-Achse nichts einträgt, passt Node-Red die Achse  automatisch an.

Will man mehrere Linien in einem Diagram darstellen, dann sollte jeder Output unbedingt sein eigenes Topic haben. Dieses Topic stellt dann auch die Legende im Chart dar.

Die Farben kann man im Chart Node auswählen, wobei der zuerst ankommende Wert immer die Farbe oben links bekommt, der zweite die rechts daneben, der vierte den linken Farbwert der zweiten Zeile und so fort. Ich habe bislang keine Möglichkeit gefunden, die Farbe direkt festzulegen.

Ich behelfe mir hierbei mit dem Delay Node, der sicherstellt, dass bei nahezu gleichzeitig eintreffenden Werten, der erste direkt durchgelassen, der zweite etwas, der dritte mehr und der vierte Wert lange verzögert wird.

Die Dauer der Aufzeichnung kann ebenfalls im Charte Node Eigenschaftsfenster unter X-Achse festgelegt werden. Ältere Werte fallen dann hinten runter und werden nicht gespeichert. Ebenso vergisst Node-Red alle Werte, wenn es neu gestartet wird.

Will man das verhindern, müssen die Werte phyikalisch weggeschrieben werden. Am besten in eine Datenbank, wobei sich hier die InfluxDB anbietet, welche für genau diesen Zweck geschaffen wurde. Hierfür gibt es bei Node-Red bereits entsprechende Schreibe- und Lesenodes. Leider ist das Auslesen und Darstellen in Node-Red etwas kompiziert, aber das erkläre ich in im Kapitel über die Influx DB

 

14 Gedanken zu „Viessmann API und Node-Red - Teil 3 - Daten abfragen

  1. Guten Tag Chris,
    ich habe einen Teil deiner nodes einmal in mein node red eingebaut. Das Lesen des Data-Arrays und extrahieren von gewünschten Features funktioniert bis auf das auslesen der Außentemperatur. Adressiere ich das Array im function node direkt ist alles fein. Adressiere ich es über die function node Definition:

    var featureArray=msg.payload.data;
    var idx = featureArray.findIndex( (element) => element.feature === 'heating.sensors.temperature.outside');
    msg.payload=msg.payload.data[idx].properties.value.value;
    return msg;

    bekomme ich nicht den Wert über paylod zurück, sondern das gesamte array. Ich denke, dass er es nicht gefunden hat. Die Data Definitionen um die es geht lauten:

    {
    "feature": "heating.sensors.temperature.outside",
    "gatewayId": "7637415054512237",
    "deviceId": "0",
    "timestamp": "2024-04-08T09:23:41.460Z",
    "isEnabled": true,
    "isReady": true,
    "apiVersion": 1,
    "uri": "https://api.viessmann.com/iot/v1/features/installations/2367104/gateways/7637415054512237/devices/0/features/heating.sensors.temperature.outside",
    "properties": {
    "value": {
    "type": "number",
    "value": 17.6,
    "unit": "celsius"
    },
    "status": {
    "type": "string",
    "value": "connected"
    }
    },
    "commands": {

    }
    },

    Ich würde mich auf ein feedback von dir freuen.

    Grüße
    Joachim

    1. Hallo,
      ich habe auch erst gestutzt, da ich keinen Unterschied feststellen konnte. Erst als ich deinen "findindex" Code verwendet habe bin ich drauf gekommen, was es sein könnte. Kann es sein, dass dein Editor oder WordPress die Single Quotes in smarte Anführungszeichen umwandelt? Leider macht WordPress, auf dem mein Blog basiert das auch.
      Inzwischen habe ich mein WordPress so angepasst, so dass es keine smart Quotes mehr einbaut. Dadurch sehe ich auch, dass du wahrscheinlich alles richtig gemacht hast, d.h. dein einkopierter Code bzw. das Viessmann Feature JSON sind jetzt korrekt dargestellt. Ich muss noch ein bisschen hirnen, um herauszufinden, warum genau dieser eine Featureeintrag sich nicht über die findIndex Methode entschlüsseln lässt.

      Schicke mir bitte mal das ganze (falsche) Antwortarray. Kann es evtl. sein, dass du den Debug Node nicht auf msg.payload als Antwort sondern auf das gesamte message Objekt eingestellt hast? -->>Ausgabe: kompletten Nachrichten Objekt <-- Der Gramatikfehler ist nicht von mir 🙂 Bzgl. Editor: Ich verwende Notepad++, das kostet nichts und ist ausgesprochen leistungsfähig. VG Chris

      1. Hallo Chris,
        habe das Problem gefunden. Irgend etwas war in dem function node nicht korrekt. Änderungen, die ich in dem function node gemacht hatte wurden ebenfalls nicht honoriert. Habe es gelöscht und neu angelegt. Danach war alles ok.

        Gruß
        Joachim

        1. Sehr gut! Manchmal scheint es so, als ob Node-Red einen Schluckauf hätte. Dann die merkwürdig funktionierenden Teile löschen und neu aufzusetzen hilft. Beim Entwickeln immer wieder speichern, dann muss man nicht ganz bei 0 anfangen.
          Viel Spaß noch
          Chris

  2. hallo,
    vielleicht bin ich hier falsch. Ich betreibe seit wenigen Monaten eine Hybridheizung von Viessmann mit WP u Gastherme und bin es einfach leid, dass ich die massenhaft aus der Anlage vorliegenden Daten (auf Viessmann-Servern) nicht als CSV laden und in Excel weiter verarbeiten kann.
    Gibt es eine Lösung auch für Programier-Laien?
    Gruß
    Gerd

    1. Hallo,
      Bis Sie erst einmal auf die Daten zugreifen können, braucht es schon einiges an Progammier- oder Konfigurationsaufwand.
      Mit Node-Red ist das zwar „relativ“ einfach, erfordert aber den Willen, sich mit der Materie auseinander zu setzen.
      Vielleicht finden Sie ja jemanden, der Ihnen das einrichtet.
      Ggf. Gibt es auch plug&play Lösungen auf Basis Home Assistant o.ä.
      Hier in meinem Blog wende ich mich an wohlmeinende Amateure mit etwas Basiswissen und liefere eher „Hilfe zur Selbsthilfe“.
      Eine gute Zeit noch wünsche ich Ihnen.
      Chris

  3. Hallo Chris

    Funktioniert soweit alles perfekt. Danke für deine ausführliche Anleitung und deine Arbeit 🙂

    Bei mir gibt es Features, die zwar vorhanden sind, aber von findIndex nicht gefunden werden. Und zwar alle, die eine Nummer im Feature haben (z.B. heating.circuits.0.circulation.pump).

    Muss ich hier etwas besonders beachten?

    1. Da ist eigentlich nichts Besonderes zu beachten. FindIndex funktioniert auch mit Zahlen.
      Hier ein Beispiel

      var featureArray = msg.payload.data;
      var idx = featureArray.findIndex((element) => element.feature === 'heating.circuits.2.operating.programs.active');
      msg.payload = msg.payload.data[idx].properties.value.value;
      return msg;

      Im Beispiel wird der Status vom 2. Heizkreis abgefragt.
      VG
      Chris

  4. Hallo,
    gibt es eine Möglichkeit boolean Werte umzuwandeln und im Diagramm darstellen zu können. So würde mich interessieren, wenn zB die Warmwasseranforderung vorliegt. Das hätte ich dann gerne in dem Diagramm mit den Warmwasserspeicher Temperaturen dargestellt.
    Danke
    Moritz

  5. Hi Christoph,
    ich weiß ehrlich gesagt nicht, was der Fehler war. Ich habe den Function Node gelöscht und einfach noch mal neu angelegt und dann ging es. Vielleicht war ein Punkt oder eine Klammer zu viel oder zu wenig rein-kopiert.
    Allerbesten Danken für deine Gute Beschreibung, auch deine Kommentare in der Viessmann-Community. Ich habe damit sehr viel gute Lösungen für meine Vitodens200 umsetzen können.
    Besten Gruß
    Christoph

  6. Leider funktioniert das extrahieren der Datenpunkte nicht.
    Woran kann das wohl liegen?
    "TypeError: featureArray.findIndex is not a function"

    Die Features werden korrekt angeziegt und sind auslesbar.

    1. Hallo,
      verstehe ich nicht, warum das einen Fehler wirft.
      Wie sieht der gesamte Function Node bei dir aus?
      Die kritische Zeile ist diese hier (für Außentemperatur). Alle Klammern geschlossen?
      var idx = featureArray.findIndex( (element) => element.feature === 'heating.sensors.temperature.outside');
      Viele Grüße von Christoph zu Christoph

Schreibe einen Kommentar

Ich freue mich über Lob und Kritik.
Falls du Probleme mit der hier vorgestellten Anleitung hast und nicht weiter kommst:
Bitte das Problem oder die Fehlermeldung(en) möglichst genau beschreiben, auch an welcher Stelle (z.B. in welchem Node oder Befehl) und unter welchen Umständen der Fehler auftritt.
Gerne kannst du mir auch ein Mail schreiben. Die Adresse findest du im Impressum.
Ich gebe mir viel Mühe, meinen Lesern weiterzuhelfen. Je konkreter du bist, desto einfacher und schneller kann ich versuchen zu helfen.
Deine E-Mail-Adresse wird nicht veröffentlicht.
Erforderliche Felder sind mit * markiert