Im Beitrag zur „Kommunikation mit Victron Energy Geräten“ wurde beschrieben, wie man die Daten von der Schnittstelle einlesen kann. Hier erkläre ich nun, wie die Daten mit NodeRed weiter verarbeitet werden können.
Kurzbeschreibung:
Die Daten werden von der seriellen Schnittstelle [USB2ttl] eingelesen. Der Datenframe wird auf Länge geprüft [length xxx->xxx Bytes] und danach im Format [csv] gewandelt. Der [read]-Block wertet die gewandelten Daten aus den Datenfeldern aus und weist ihnen Namen zu. Zuletzt werden sie ins [debug]-Fenster ausgegeben.
Im ersten Funktions-Block [length] wird die Länge des Datenframes geprüft und nur bei Übereinstimmung weiter geleitet. (Die Datenlänge kann natürlich angepasst werden.)
if (msg.payload.length > 140 && msg.payload.length < 220)
{
return msg;
}
Im zweiten Block wird der Frame durch den [csv]-Filter geschickt.
Es muss nur die Auswahl der Trennzeichen auf „TAB“ geändert werden.
Erklärung zum [debug]-Block am Ende des Beitrags!
Hängt man nun einen [debug]-Block an den [csv]-Filter, sollte man folgende Ausgabe erhalten:
Man erhält ein Array mit Objekten, die in Zeilen und Spalten aufgeteilt sind. Mit dem kleinen Pfeil vor dem „array[19]“ kann man es aufklappen.
Nun sieht man die Zeilenblöcke [0…9] und [10…18], die man dann in die einzelnen Zeilen weiter unterteilen kann. Klappt man die Objekte weiter auf, sieht man die einzelnen Spalten [col1] & [col2] sowie dessen Werte.
In jeder Zeile befindet sich in [col1] der Name des Wertes. In [col2] der entsprechende Wert. Im Bild sieht man exemplarisch die von Null gezählt 3.Zeile (Index-Nr. 2) mit der Seriennummer des Victron SmartSolar.
- [col1] = Bezeichner
- [col2] = Wert
Im nächsten Schritt hängt man nun einen
In diesem Block wird die Funktion zum ordnen und benennen der von der seriellen Schnittstelle gelesenen Daten geschrieben.
In den [functions]-Block fügt man folgenden Code ein:
'use strict';
let i = msg.payload;
if (i[2].col2 == "HQxxxxxxxG9") // eigene Serien-Nr. einsetzen
{
let msg1 = {};
msg1.topic = 'Solardaten';
msg1.payload = {};
msg1.payload.PV.Leistung = i[6].col2;
msg1.payload.Ertrag = {};
msg1.payload.Ertrag.Gesamt = i[12].col2 / 100;
msg1.payload.Ertrag.Tag = i[13].col2 / 100;
msg1.payload.PV.Strom = Math.round(i[4].col2 / 10) / 100;
msg1.payload.PV.Spannung = Math.round(i[5].col2 / 10) / 100;
msg1.payload.OUT = {};
msg1.payload.OUT.Spannung = Math.round(i[3].col2 / 10) / 100;
}
return msg1;
Kurze Erklärung der „Programmierung“ des [function]-Blocks:
Die „if“ Bedingung prüft, ob die Seriennummer in der 3.Zeile (0,1,2) & 2.Spalte (1,2) enthalten ist. Dies ist eine kleine Vorkehrung um die Daten auf ihre Richtigkeit zu prüfen.
Im nächsten Schritt prüft man nun ob Daten durch den Flow verarbeitet werden.
Durch den [debug]-Block können die Daten im Debug-Fenster gesehen werden.
In den Eigenschaften des [debug]-Blocks können so belassen werden. Alternativ kann die Ausgabe auf „kompletten Nachrichten-Objekt“ eingestellt werden. Dies ist durch die Vorgaben durch den [function]-Block aber in diesem Beispiel nicht nötig.
Um die Ausgabe des [debug]-Blocks zu sehen, muss nur noch das Debug-Nachrichtenfenster aufgerufen werden.
Dazu wird oben rechts das kleine Dreieck angeklickt und der Punkt für die Debug-Nachrichten aufgerufen werden.
Wenn alle Änderungen übernommen (deploy) und der [debug]-Block aktiviert ist, sollten jetzt die formatierten Daten im Debug-Fenster erscheinen.
Diese aufbereiteten Daten können nun weiter verarbeitet und auf einem Dashboard angezeigt werden. Dies wird in einem weiteren Tutorial erklärt.