Viessmann ohne API – Optolink-Splitter (3)

Jetzt beginnt der schönere Teil. Hat man einmal die wesentlichen Datenpunkte gefunden kann man diese ganz einfach über einen MQTT In Node in Node-Red verarbeiten.

Node-Red

Bevor ihr allerdings eure komplette API Kopplung löscht, empfehle ich, erst einmal ein Backup zu machen. Des Weiteren würde ich in einem ersten Schritt, die Optolink Geschichte in einem eigenen Tab ausprobieren und schauen, ob die angezeigten Optolink Werte tatsächlich mit den API Werten übereinstimmen. Bei Außentemperatur, Speichertemperatur und ein paar anderen liefert Viessmann die Werte zeitverzögert aus. Es muss also nicht immer zu 100% übereinstimmen.

Einfache Werte auslesen

Zum Glück kommen die meisten Werte verzögerungsfrei aus dem System – egal ob mit Optolink oder der API ausgelesen. Hier ein Beispiel für dieWarmwassertemperatur:

Der MQTT In Node erhält das Topic, das wir in der Polling Liste von settings_ini.py für Warmwassertemperatur definiert haben. Die Quality of Service definiere ich persönlich mit "1" was bei wackeligen Verbindungen etwas mehr Betriebssicherheit bietet – wie ich meine.

Bei "Ausgang" empfehle ich "String" zu verwenden. Natürlich geht auch "Auto-Erkennung", meistens jedenfalls. Bei Hexadezimal Werten allerdings nicht.

Weiterverarbeitung

Normalerweise können wir wie oben direkt ein Dashboard Element an den MQTT In Node dranhängen.

Manchmal jedoch können wir Dashboard Switches nicht 1 zu 1 übernehmen, da die API mit "on" oder "off" Werten arbeitet und Optolink mit 1 oder 0. Hier entsprechend den Dashboard Node anpassen.

Zu viele Werte

Die Außentemperatur wird von Viessmann in der API nur ca. jede Stunde oder bei größeren Änderungen aktualisiert. Wir haben jetzt die Möglichkeit, die Temperatur alle 30 Sekunden abzugreifen. Will man diesen Wert aber in Influx speichern, ist  das ein Overkill. Anstatt einer schönen Temperaturlinie gibt es ein zittriges Band von Werten.

Links – Abfrageintervall 30 Sek. Rechts – gefiltert alle 10 Minuten

Ich habe mir so beholfen:

Nach dem MQTT In Node kommt ein Delay Node, der nur alle 10 Minuten einen Wert durchlässt sowie ein Filter Node, der nur bei Wertänderungen die payload.msg weiterleitet. Das spart etwas Platz in der Datenbank. Ferner benutze ich das Topic Vitodens/AussenTemp_fltrd  0x5525 und nicht den in Phil's Original Polling Liste ebenfalls verfügbaren Wert bei 0x800.

Alternativ könnten wir die Temperatur nicht über die Pollingliste sondern alle x Minuten direkt auslesen. Weiter unten steht mehr dazu.

Hexadezimale Werte – lauter kleine Endians

Endian hat nichts mit den amerikanischen Ureinwohnern zu tun, sondern mit Gullivers Reisen und der Art, wie man gekochte Eier aufschlägt 🙂

Informatiker können dieses Kapitel gerne überspringen…

Einige Werte sind weder Integer noch Float sondern hexadezimal. Zum Beispiel die Verbrauchswerte [kWh]. Bei Gasgeräten stehten diese in der Gegend von 0x9000 bei Wärmepumpen und anderer moderner Technologie wahrscheinlich an einer anderen Stelle.

In der Polling Liste werden diese als "raw" ausgelesen:

("HeizgVerbrTag", 0x9000, 32, 'raw'),

MQTT spuckt dann für 8 Tage Verbrauchsdaten z.B. folgendes aus: 2A00000004000000000000000d000000180000000e0000000000000000000000

So etwas erschließt sich nicht von selbst. Der Hex String ist 64 Zeichen lang, je Byte sind das zwei Zeichen, also insgesamt 32 Byte, somit 4 Byte pro Tag.
Die 4 Byte (8 Zeichen) ganz links stehen für "heute".

Was man jetzt beachten muss, ist, dass die 4 Byte nach der "Little Endian" Notation da stehen. Das heißt, das niederwertigste Byte kommt zuerst, dann das nächst höherwertige und so fort. Auf das Dezimalsystem übertragen hieße das, die Zahl '3456' wird als '6543 dargestellt. Also Einer zuerst, dann Zehner, dann Hunderter, dann Tausender.

Nach dieser Einleitung wissen wir hoffentlich, wie die ersten 4 Byte zu interpretieren sind:, nämlich als

0000002A

oder dezimal 42 – die Antwort auf  'Life, the Universe And Everything'. Das heißt, wir haben heute einen Bespielverbrauch von 42 kWh gehabt.

Da diese Hex Werte für Nicht-Informatiker wie mich schwer zu verdauen sind, habe ich spaßeshalber einmal Chat  GPT gefragt, ob es mir nicht eine Aufdrösel-Routine zur Verfügung stellen könnte. Frage war: "Ich brauche ein Javascript Skript, das eine lange Kette von 4 Byte hexadezimal Werten zerlegt und unter Berücksichtigung von Little Endian in Dezimalwerte umwandelt." Und siehe da, es hat geklappt: Auf einen Node Red Funktionsknoten angepasst sieht das so aus:

Schön kommentieren kann die KI auch noch.

Ich möchte allerdings nicht wissen, wieviel Watt Strom durch diese Anfrage verbraucht wurden. Kein Wunder, dass Google und Amazon inzwischen wieder Atomkraftwerke reaktivieren, um die unnatürliche Intelligenz zu betreiben.

Füttert man den "Hex String 2 Decimal" Function Node mit dem ganzen Output von MQTT, kommt folgendes Array heraus:

Analog können wir bei den anderen Verbrauchwerten vorgehen. Aber Achtung: Optolink liefert aus irgend welchen Gründen gwöhnlich nur 55 valide Byte. Der Rest ist dann einfach "00". Der Wochenverbrauch (53 Wochen) ist 212 Byte lang und müsste in 4 Teile gestückelt werden. Siehe Byte-Bitweiser Zugriff direkt unterhalb.

Byte-Bitweiser Zugriff

Wem das in diesem Kapitel Beschriebene zu kompliziert (oder zu langatmig) ist, kann auch einfach Byte-Bitweise auf die Werte zugreifen. Der heutige Verbrauch wäre dann so zu konfigurieren: ("HeizgVerbr_heute", 0x9000, 32, 'b:0:3', 1), (lese ab 0x9000 die Bytes 0 bis 3 und konvertiere in Dezimal ohne zu skalieren)
Der gestrige Verbrauch wäre demnach so einzustellen
("HeizgVerbr_gestern", 0x9000, 32, 'b:4:7, 1), und so weiter.

Die Frage dabei ist, macht es Sinn, MQTT alle 30 Sekunden mit einer Abfrage zu beaufschlagen, deren Ergebnis sich nur sehr selten ändert? Eher nein, weshalb ich für derlei Abfragen anders vorgehe. Siehe unten.

Schreiben von Werten

Während das Auslesen von gepollten Werten sehr komfortabel ist, muss man zum Schreiben mit MQTT die betreffenden Speicheradressen des Viessmann Geräts ansprechen. Hier ein Beispiel zum Setzen der Solltemperatur in Heizkreis 2:

Die Solltemperatur von Heizkreis 2 liegt bei meiner Therme auf 0x3306 und nennt sich BedienRTSolltemperaturM2~0x3306. RT steht für "Raumthermostat".

Nun basteln wir uns die Payload zusammen, die wir mittels MQTT Out Node an das Topic Vitodens/cmnd schicken:

Wie schon in einem Vissmann API Beitrag geschrieben, habe ich das ganze etwas betriebsicherer gemacht. Der Vollständigkeit halber hier noch der komplette Flow dazu

Direkte Abfragen

Wir oben schon erwähnt, belastet das unnötige Abfragen von Werten, die sich nur einmal am Tag oder gar seltener ändern, unseren MQTT Server – zumindest dann, wenn er noch diverse andere MQTT Publisher Clients bedienen muss.

Ich habe ca. 10 Shelly Aktoren, 2 Wechselrichter, ein Smartmeter, Ladegerät, Batterieüberwachung, div. WiFi Thermometer die alle fleißig mit dem MQTT Broker kommunizieren. Da kommt der ganz schön ins Zappeln. Deshalb auch die Beschränkung auf 30 Sekunden Abfrageintervalle beim Optolink-Splitter.

Es bietet sich daher an, zeitgesteuert direkte Abfragen zu starten ohne, dass diese in der Pollingliste drin stehen. Das geschieht analog der manuellen Testeingabe im MQTT Explorer.

Wollen wir z.B. die Verbrauchwerte der letzten 12+1 Monate wissen, können wir das bei 0x90F4 abfragen.

Der Funktionsnode wird wie folgt befüllt:

Die erzeugte Payload wird an einen MQTT Out Node geschickt, welcher die Abfrage durchführt und den Wert am MQTT Server ablegt. Hier werden wie beim Zugriff über den MQTT Client Semikola als Trenner verwendet.

Gelesen wird die Abfrage wieder über einen MQTT In Node, diesmal beim Topic Vitodens/resp Dieses Topic haben wir beim initalen Anpassen der settings_ini.py Datei so definiert.

1;37108;38000000000000000000000000000000000000003d0000007501000077020000fd000000ae040000900400009400000012000000

Die Antwort müssen wir noch zerlegen, da der Optolink Splitter immer noch das Ergebnis der Abfrage und den Dezimalwert der Adresse mitliefert. Uns interessiert der Wert nach dem zweiten Semikolon:

Das gesamte Konstrukt für direkte Abfragen sieht dann so aus:

Mehrere direkte Abfragen

Hat man mehrere direkte Abfragen gebaut, braucht man nur einen MQTT-In Node, der alle direkten Abfragen empfängt. Um die Antwort dann richtig zuordnen zu können, muss anschließend noch über den zweiten Teil der Antwort, die zurückgegebene Dezimaladresse (hier 37108) gefiltert werden.

Wer mag, kann in der Response auch eine Hex Adresse anzeigen lassen – wie in nachfolgendem Beispiel: Dazu den Kommentar in der Zeile resp_addr_format =  in settings_ini.py beachten.

Dieses Beispiel erzeugt zwei direkte Abfragen – Außentemperatur und tageweiser Verbrauch – welche anschließend über einen Response Filter zugeordnet werden.

Zu guter Letzt

Fragen zum Umsetzung in Node Red könnt ihr gerne an mich richten. In Bezug auf Gasgeräte kann ich etwas weiterhelfen,  bei Wärmepumpen und anderen neueren Technologien bitte ich euch, die Diskussionsfunktion bei Github zu nutzen.

 

 

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