In der folgenden Anleitung zeigen wir euch, wie man zwei BMS in sein System integriert.
Im Prinzip kopieren wir dafür die Funktionen, welche das BMS über Bluetooth auslesen. Starten, nachdem das erste BMS ausgelesen wurde, eine zweite Abfrage, um das zweite BMS auszulesen, speichern die Werte in neuen Variablen und rechnen sie dann zusammen, um im Frontend kombinierte Werte angezeigt zu bekommen.
Der "BLE Connections" Flow dafür ist eigentlich nicht so komplex, wir haben da noch etwas die Logik angepasst, wann welche Abfrage gestartet wird, zum Beispiel, dass die BMS nur per Bluetooth angefragt werden, wenn die entsprechenden MAC-Adressen im Frontend gesetzt wurden.
Nicht wundern, wir benutzen hier ein anderes Stylesheet, deswegen ist die Darstellung etwas anders als sonst.
Ich habe mal einen Screenshot vom Backend (BLE Connections) gemacht und meine Paint Skills ausgepackt, um die Abfrage für BMS1 (grün) und BMS2 (rot) zu markieren.
In der Function Node ganz rechts oben im roten Kasten werden dann die Werte des zweiten BMS in neue Variablen geschrieben. Der Übersicht halber wurde die Function Node vom ersten BMS einfach kopiert und an alle Variablen ein "_2" angehangen:
Nebenbei, die Werte BMSmaxvolt, BMSminvolt und BMSmaxcap werden quasi live berechnet, solange das System läuft. Es sind also keine Daten, die direkt vom BMS kommen, sondern sie geben einfach die höchste bzw. niedrigsten Werte an, die während der aktuellen Laufzeit erfasst worden sind. Startet man das System neu, setzen sich die Werte zurück.
Die zweite Abfrage wird direkt nach der ersten ausgeführt – vorausgesetzt es wurde im Frontend ein zweites BMS gesetzt – und nach einem 5 Sekunden Delay an den "Sensor Dashboard" Flow geschickt. Dort werden sie dann aufbereitet für die Darstellung im Frontend.
Dabei werden die zwei Temperaturen einzeln angezeigt, also je einmal pro BMS.
Aktuell läuft hier nur ein 150er BMS, deswegen sehen wir im Screenshot nur eine Temperatur. Auch die Kapazität würde addiert anzeigt werden, wenn ein zweites BMS angeschlossen wäre. Für die Darstellung hier im Bild benutzen wir übrigens node-red-contrib-artless-gauge und node-red-contrib-ui-value-trail. Diese müsstet ihr euch installieren, wenn ihr die angehangenen Flows importieren wollt, oder ihr ersetzt sie danach mit den Standard Dashboard Nodes.
Die Berechnung um die Werte nun zu kombinieren findet folgendermaßen statt:
Ampere, Power (Watt) und die Kapazitäten werden aufaddiert, für SoC und Volt wird ein Mittelwert errechnet. Hier im Bild am Beispiel von SoC:
Die erste if-Abfrage überprüft, ob beide SoC Variablen auf "wait" stehen, das würde bedeuten, dass beide BMS keine Werte liefern und somit kein BMS angeschlossen ist.
Im zweiten Block überprüfen wir, ob nur eine der Variablen keine Werte liefert, dementsprechend gehen wir davon aus, dass nur ein BMS angeschlossen ist. Wir prüfen dann, welche der Variablen entweder auf "wait" steht oder keinen Wert bekommen hat, also "undefinded" ist. Zur Sicherheit checken wir ebenfalls nochmal ob der Wert, sollte er vorhanden sein, numerisch ist. Dafür gibt es die Funktion "isNaN" (is not a number). Für die Berechnung benötigen wir numerische Werte, deswegen setzen wir nicht vorhandene Variablen auf 0.
Kleiner JavaScript Ausflug: Wir sehen hier eine verkürzte if-Abfrage, mit der wir einer Variable einen Wert zuweisen können:
bmssoc1 = global.get("BMSsoc") == "wait" ? 0 : global.get("BMSsoc");
bmssoc1 soll also einen Wert bekommen, dafür überprüfen wir, ob global.get("BMSsoc") gleich "wait" ist. Ist das der Fall, setzen wir bmssoc1 auf den numerischen Wert 0, tritt der Fall nicht ein, übergeben wir den Wert von global.get("BMSsoc").
Am Ende des zweiten Blocks steht die Berechnung: bmssoc1 + bmssoc2 geteilt durch die Anzahl an BMS, in diesem Fall 1. Jetzt könnte man sagen, dass eine Division durch 1 keinen Sinn ergibt, rein mathematisch ist das natürlich richtig. Der Punkt ist aber, dass wir nicht wissen, welche der Variablen letztendlich 0 ist und welche einen Wert liefert, deshalb decken wir durch die Berechnung durch 1 einfach alle Möglichkeiten ab. Ein anderer möglicher Weg wäre, vor der Berechnung schon abzufragen, wohin die Werte geliefert werden und wohin nicht. Aber viele Wege führen ja bekanntlicherweise nach Rom.
Sollten in beiden globalen Variablen Werte geliefert werden, tritt der dritte Fall ein und der letzte Block wird ausgeführt. Wir rechnen dann einfach beide Werte zusammen und teilen sie durch die Anzahl, in diesem Fall durch zwei.
Letztendlich schreiben wir den kombinierten Wert in eine neue Variable. Diese übergeben wir dann in der Node "copy data" (einfach mit STRG + f nach der Node suchen, befindet sich links im Sensor Dashboard Flow) wiederum an die globalen Variablen MainBattVolt, MainBattSoc und MainBattAmp. Damit sehen wir die kombinierten Werte dann auch im Touchdisplay und können sie über die APIs abfragen.
Im Anhang findet ihr zwei Flows, einmal für die Darstellung und einmal den kompletten BLE Connections Flow mit zwei Batterie Abfragen.
SensorDashboard Nodes :
https://share.12-s.de/s/yFGGXjQpEdFZM4g
BLE Connections Flow: