Nach einer Änderung meiner SMA-Anlage am 27.08. fiel mir in FHEM ein etwas… ambitionierter Temperaturwert auf:
BAT_TEMP 21000000
21 Millionen Grad wären für einen Batteriespeicher eher ungünstig. Da die Anlage aber weder verdampft noch ein neues Element im Periodensystem erzeugt hatte, lag die Vermutung nahe, dass hier schlicht ein Daten- oder Skalierungsproblem vorliegt.
Interessant war der Zeitpunkt: Seit dem 27.08., zeitgleich mit dem Umzug bzw. Änderungen rund um das neue Sunny Portal, wurde das Reading BAT_TEMP in meinem FHEM-Device nicht mehr sinnvoll aktualisiert.
Ob das Sunny Portal tatsächlich die Ursache ist, kann ich nicht belegen. Der zeitliche Zusammenhang war bei meiner Anlage allerdings auffällig. Deshalb hier der komplette Diagnoseweg und ein Workaround, falls jemand über dasselbe Problem stolpert.
Die Ausgangslage
Die Anlage besteht im Wesentlichen aus:
- SMA-Wechselrichter
- BYD-Batteriespeicher
- SMA Home Manager
- FHEM mit
SMAInverter - lokale Netzwerkverbindung zum Wechselrichter
Die BYD-Batterie besitzt in dieser Installation keine eigene Netzwerkanbindung. Die Batteriedaten werden über die Kommunikation zwischen Batterie-BMS und Wechselrichter übertragen.
Die entscheidende Frage war daher:
Liefert die BYD tatsächlich einen falschen Temperaturwert oder entsteht der Fehler erst später?
Der Home Manager ist dafür nicht nötig
Zunächst lag der Gedanke nahe, die Batterietemperatur eventuell über den SMA Home Manager auszulesen.
Das ist aber gar nicht notwendig.
Der interessante Datenweg ist:
BYD-Batterie
│
│ CAN / BMS-Kommunikation
▼
SMA-Wechselrichter
│
│ Modbus TCP
▼
FHEM
Der Wechselrichter kennt die Batterietemperatur bereits. Wenn Modbus TCP aktiviert ist, lässt sich der Wert direkt dort abholen.
Damit kann man sowohl Sunny Portal als auch FHEM SMAInverter zunächst komplett aus der Gleichung nehmen. Bei Fehlersuche ist weniger beteiligte Software meistens eine ausgesprochen gesunde Idee.
Prüfen, ob Modbus TCP erreichbar ist
Bei mir ist der Wechselrichter lokal per IP erreichbar. Die konkrete Adresse ist hier selbstverständlich anonymisiert.
Unter Windows PowerShell lässt sich Port 502 einfach prüfen:
Test-NetConnection <WR-IP> -Port 502
Entscheidend ist:
TcpTestSucceeded : True
Damit ist klar: Der Wechselrichter akzeptiert Modbus-TCP-Verbindungen.
Falls hier False erscheint, muss zunächst geprüft werden, ob Modbus TCP im Wechselrichter aktiviert ist und ob Netzwerk bzw. Firewall den Zugriff auf Port 502 erlauben.
Die Batterietemperatur direkt vom SMA-Wechselrichter lesen
Im SMA-Modbus-Profil befindet sich die Batterietemperatur auf Register 30849. Der Wert umfasst zwei Modbus-Register und wird als 32-Bit-Wert übertragen. SMA dokumentiert das Register als Batterietemperatur mit dem Format FIX1, also einer Nachkommastelle.
Der direkte Test ergab bei meiner Anlage folgende Modbus-Antwort:
00 01 00 00 00 07 03 03 04 00 00 00 FA
Der eigentliche Nutzwert ist:
00 00 00 FA
Hexadezimal FA entspricht dezimal:
250
Mit dem Faktor 0,1 ergibt das:
25,0 °C
Und damit war die wichtigste Erkenntnis da:
Die Batterie liefert eine plausible Temperatur und auch der SMA-Wechselrichter stellt sie korrekt bereit.
Der Fehler lag also nicht bei der BYD und auch nicht in der Kommunikation zwischen Batterie und Wechselrichter.
Ursache auf FHEM-Seite eingegrenzt
Damit standen zwei Werte gegenüber:
Direkt per Modbus:
25,0 °C
SMAInverter Reading:
21000000
Damit war klar, dass das Problem irgendwo bei der Verarbeitung bzw. Bereitstellung des BAT_TEMP-Readings durch SMAInverter liegt.
Warum das Verhalten bei meiner Anlage zeitlich genau nach den Änderungen am 27.08. und dem Umzug ins neue Sunny Portal auftrat, ist damit allerdings noch nicht geklärt.
Wichtig ist die Unterscheidung:
Der zeitliche Zusammenhang ist beobachtet. Eine technische Kausalität zwischen Portalumzug und fehlerhaftem FHEM-Reading ist damit nicht bewiesen.
Das Sunny Portal befindet sich schließlich auch nicht im lokalen Datenpfad der Modbus-Abfrage.
Lösung: Batterietemperatur direkt per Modbus in FHEM einlesen
Da der Wechselrichter den richtigen Wert liefert, kann FHEM diesen einfach direkt abfragen.
Dazu habe ich ein zusätzliches ModbusAttr-Device angelegt:
define SMA_BAT_Modbus ModbusAttr 3 60 <WR-IP>:502 TCP
attr SMA_BAT_Modbus dev-h-defPoll 1
attr SMA_BAT_Modbus obj-h30849-reading BAT_TEMP
attr SMA_BAT_Modbus obj-h30849-len 2
attr SMA_BAT_Modbus obj-h30849-unpack N
attr SMA_BAT_Modbus obj-h30849-expr $val/10
attr SMA_BAT_Modbus obj-h30849-format %.1f
attr SMA_BAT_Modbus obj-h30849-poll 1
FHEM liest damit Register 30849 zyklisch aus und erzeugt beispielsweise:
BAT_TEMP 25.0
ModbusAttr unterstützt genau dieses Schema aus Registeradresse, Registerlänge, unpack, Umrechnungsformel und zyklischem Polling.
Damit hatten wir zwar wieder eine korrekte Temperatur, aber zunächst ein neues Problem:
Mein bestehender FHEM-Code verwendet überall das alte Reading:
mySMAInv:BAT_TEMP
Natürlich könnte man jetzt sämtliche DOIFs, Notifys, Logs, SVGs und sonstigen Abhängigkeiten umbauen. Man könnte aber auch seine Lebenszeit für angenehmere Dinge verwenden.
Das vorhandene BAT_TEMP einfach weiterverwenden
Die Lösung besteht darin, den korrekt per Modbus gelesenen Wert wieder in das bestehende Reading des SMAInverter-Devices zu schreiben.
Dafür reicht ein kleines Notify:
define n_BAT_TEMP notify SMA_BAT_Modbus:BAT_TEMP:.* { my $v=ReadingsNum("SMA_BAT_Modbus","BAT_TEMP",0);; fhem("setreading mySMAInv BAT_TEMP $v") }
mySMAInv ist dabei nur ein Beispielname und muss durch den Namen des eigenen SMAInverter-Devices ersetzt werden.
Bei jeder Aktualisierung von:
SMA_BAT_Modbus:BAT_TEMP
wird der Wert ausgelesen und anschließend nach:
mySMAInv:BAT_TEMP
geschrieben.
Das Ergebnis sieht wieder ganz unspektakulär aus:
BAT_TEMP 25.0
Genau so soll es sein.
Der Vorteil: Der komplette bestehende FHEM-Code kann unverändert bleiben.
Alles, was bisher beispielsweise
ReadingsNum("mySMAInv","BAT_TEMP",0)
verwendet hat, funktioniert weiter.
Falls das Notify nicht reagiert
Ein kleiner Stolperstein war bei mir schlicht der Gerätename.
Wenn das Modbus-Device beispielsweise exakt
SMA_BAT_Modbus
heißt, muss natürlich auch das Notify genau auf diesen Namen hören:
SMA_BAT_Modbus:BAT_TEMP:.*
und der Wert muss ebenfalls aus genau diesem Device gelesen werden:
ReadingsNum("SMA_BAT_Modbus","BAT_TEMP",0)
Groß-/Kleinschreibung und unterschiedliche Device-Namen sollte man daher zuerst kontrollieren, bevor man beginnt, das halbe FHEM-Modul auseinanderzunehmen.
Zum manuellen Test des Notify kann man beispielsweise verwenden:
trigger SMA_BAT_Modbus BAT_TEMP: 25.0
Anschließend:
{ReadingsVal("mySMAInv","BAT_TEMP","FEHLT")}
Das sollte dann 25 bzw. 25.0 zurückgeben.
Fazit
Die Fehlersuche hat letztlich ein recht klares Bild ergeben:
BYD-BMS
│
│ Temperatur korrekt
▼
SMA-Wechselrichter
│
│ Modbus Register 30849 = korrekt
▼
FHEM ModbusAttr
│
│ 25,0 °C
▼
Notify
│
▼
bestehendes BAT_TEMP-Reading
Die BYD-Batterie selbst braucht dafür keine eigene Netzwerkverbindung, und auch der Home Manager wird für diese Abfrage nicht benötigt.
Bei meiner Anlage trat der fehlerhafte Wert BAT_TEMP = 21000000 seit dem 27.08. auf, zeitlich zusammen mit Änderungen bzw. dem Umzug der Anlage in das neue Sunny-Portal-Umfeld.
Ob zwischen diesen Ereignissen tatsächlich ein technischer Zusammenhang besteht, ist offen.
Was sich dagegen eindeutig nachweisen ließ:
- Die BYD liefert plausible Daten.
- Der SMA-Wechselrichter kennt die korrekte Batterietemperatur.
- Register
30849liefert den Wert lokal per Modbus korrekt. - FHEM kann diesen Wert problemlos direkt abfragen.
- Das bestehende
BAT_TEMP-Reading lässt sich mit einem kleinen Notify weiterverwenden. - Bestehende Automatisierungen müssen dadurch nicht angepasst werden.
In meinem Fall lieferte der Wechselrichter direkt 250, entsprechend 25,0 °C, während SMAInverter weiterhin 21000000 anzeigte.
Damit war zumindest geklärt, dass die Batterie nicht gerade versucht, einen eigenen kleinen Stern zu zünden. Der Rest ist Software.