Die Home Control Unit (HCU) in Node-RED integrieren – Teil 3

Im dritten Teil dieser Serie betrachte ich die von der HCU übermittelten Änderungen von Device-Informationen. Diese sollen zum einen zur Aktualisierung der gespeicherten HCU-Daten und zum anderen zur Ausgabe von Gerätänderungen verwendet werden. Um alles zu verstehen, ist es wichtig, mindestens den vorigen Beitrag der Serie zu lesen, da auch dieser darauf aufbaut. Das wesentliche Dokument für alle folgenden Schritte ist auch die Homematic IP Connect API Dokumentation.

HMIP System Events

Wenn eine Plug-in-Message vom Typ „HMIP_SYSTEM_EVENT” ankommt – den unterscheide ich ab sofort auch im Switch-Node –, dann wurde auf der HCU irgendein Ereignis ausgelöst, welches die Änderung eines oder mehrerer Daten verursacht hat. Mehrere Änderungen ergeben sich beispielsweise, wenn ein Taster gedrückt wird und anschließend das Licht angeht oder auf eine bestimmte Helligkeit automatisch gedimmt wird. Die Änderungen befinden sich unter „body.eventTransaction.events” und zwar genau in der Reihenfolge, in der sie auch ausgeführt wurden.

Um ein Array von Objekten unter „body.eventTransaction.events” besser weiterverarbeiten zu können, teile ich dieses vorab mit einem Split-Node in seine Einzelteile auf. Der Split-Node macht aus einem Array eine Liste, d. h., jedes Objekt wird nun sequenziell weitergegeben.

Die Eigenschaften des Split-Nodes sind wie folgt:

Für jedes Objekt in der Liste gibt es einen "pushEventType", der die Art des Ereignisse für das Objekt angibt, sowie das device, auf das sich das Event bezieht.

Folgenden Typen (pushEventType) sind anfangs interessant:
pushEventType Beschreibung
DEVICE_CHANGED Mit diesem Type wird signalisiert, dass sich in einer Deice (einem Gerät) eine Änderung ergeben hat. I.d.R. sind das die für mich interessantesten Nachrichten.
DEVICE_CHANNEL_EVENT
Dieser Type ist nicht dokumentiert. Wenn er auftaucht, dann wurde ein Taster gedrückt (z.B. auf einem 6-Fach Taster). Das zugeörige Objekt liefert die deviceId, den ChannelIndex sowie den channelEventType mit z.B. "KEY_PRESS_SHORT"
DEVICE_ADDED Ein Gerät wurde hinzugefügt (ist interessant, um es im Zwischenspeicher zu ergänzen)
DEVICE_REMOVED Ein Gerät wurde gelöscht (ist interessant, um es im Zwischenspeicher zu löschen)

In diesem Beispiel werde ich nur die Nachricht DEVICE_CHANGED verarbeiten. Nach dem gleichen Prinzip können auch alle anderen Nachrichten verarbeitet werden, um beispielsweise Geräte zu löschen oder hinzuzufügen.

DEVICE_CHANGED-Nachricht verarbeiten

Wenn die Nachricht (pushEventType) des Array-Eintrags den Typ „DEVICE_CHANGED” besitzt, weiß ich, dass es Änderungen an einem Gerät gab (z. B. wurde die Temperatur geändert). Mit diesen Daten kann ich anschließend die in der Flow-Variable „f_systemresponse” zwischengespeicherten HCU-Informationen aktualisieren, sodass ich in dieser Variablen immer die aktuellen Gerätedaten habe.

Das heißt, ich prüfe in einem Switch-Node, ob der pushEventType dem Wert „DEVICE_CHANGED” entspricht. Wenn ja, dann speichere ich den Device-Teil des Objekts mit einem Change-Node in der payload.msg. (Ich ergänze hier auch noch ein Topic, das ich später für einen Join-Node verwenden kann.)

Anschließend tausche ich in einem Funktionsknoten das alte Gerätsobjekt, das sich in „f_systemresponse” befindet, gegen das neue Gerätsobjekt aus. Im Function-Node „Device Änderungen” verwende ich folgenden Code:

Copy to Clipboard

Weitere Typen sind in Kapitel 6.9 zu finden.

Bei meinen Versuchen habe ich festgestellt, dass im ersten Array-Element fast immer der Typ „DEVICE_CHANGED” steht. Das kann ich allerdings nicht garantieren. Daher baue ich in meinen Flow einen Split-Knoten ein, der das gesamte Array aufspaltet und die einzelnen Elemente zur Analyse der Events weiterschickt.

Änderungen eines Devices extrahieren

Mit einer DEVICE_CHANGED-Nachricht wird eine Änderung an einem Gerät angezeigt. Um diese sichtbar zu machen, verwende ich eine Funktion, die alle Änderungen, die in den Daten eines Geräts stattgefunden haben, in einem Array protokolliert und um wichtige Daten wie die Seriennummer, das Label und die ID ergänzt. Zusätzlich füge ich hier ein payload.topic hinzu, welches ich später für einen Join-Node benötige. Der Function-Node wird „Differenzen ermitteln” genannt und beinhaltet folgenden Code:

Copy to Clipboard

Geräteänderungen automatisch anzeigen

Nun sind alle Voraussetzungen vorhanden, um bei einem Ereignis automatisch Geräteänderungen anzuzeigen. Zur Spezifikation der Geräte, die ich anzeigen möchte, verwende ich einen Funktionsknoten („Device-Liste“), in dem ich die Seriennummern der gewünschten Geräte sowie das jeweilige Feld angebe, bei dessen Änderungen ich informiert werden möchte. Das Ganze ist als Array aufgebaut und enthält zusätzlich eine payload.topic-Angabe, die ich im folgenden Join-Node verwenden werde.

Copy to Clipboard

Da ich jetzt alle Änderungen eines Geräts kenne (wie im vorigen Kapitel beschrieben), muss ich nur in den Änderungen nach der jeweiligen Seriennummer und dem gewünschten Feld suchen. Bei Übereinstimmung prüfe ich, ob sich dort eine Werteänderung ergeben hat. Wenn ja, gebe ich das als Ergebnis aus.

Da ein Function-Node nur einen Input hat und ich keine Flow-Variable nutzen möchte, füge ich den Input aus dem Function-Node, der mir die Änderungen ermittelt hat, sowie den Function-Node mit den zu überwachenden Devices mit einem Join-Node zusammen. Das ist möglich, da ich verschiedene payload.topic-Werte verwendet habe. So entsteht ein Objekt mit den beiden Topics „changes” und „search”, in denen alle Daten gemeinsam stehen. Der Node wird wie folgt konfiguriert.

Das Ergebnis des Join-Nodes wird dann in einen Function-Node geleitet ("Werteänderung finden"), der die beschriebene Suche durchführt und eine Ausgabe erzeugt, wenn es zu einem gesuchten Device eine Änderungen bei der gesuchten Eigenschaft gegeben hat.

Copy to Clipboard

Das Ergebnis im Debug-Fenster wäre bei der Erkennung einer Bewegung beispielsweise wie folgt:

Anschließend sollte noch der Funktionsknoten „Device Änderung” aufgerufen werden, damit der Status im Speicher wieder aktuell ist.

Der resultierende Node-Red-Flow sieht mit allen Ergänzungen jetzt wie folgt aus:

Natürlich kann noch ganz viel optimiert werden. Auf dieser Basis können nun weitere Ergänzungen wie z.B. das Steuern eines Devices gebaut werden. Wer weitere Verbesserungen und Informationen hat, kann diese gerne hier posten.