ModBus: Register in SMA Sunny Island Batterieinverter schreiben

Begonnen von Tabadorer, 24 Dezember 2023, 12:54:19

Vorheriges Thema - Nächstes Thema

Tabadorer

Ich habe von SMA den Batterieinverter Sunny Island SI6.0H-11. Diesen habe ich über ModBus TCP in fhem eingebunden. Das Lesen der Register ist alles kein Problem, aber beim schreiben wird mir der neue Sollwert durch fhem immer in einen HEX-Wert konvertiert.  >:(

Hier vorab meine Definition für meinen Batterieinverter:
defmod SMASI ModbusAttr 3 10 <IP>:502 TCP
attr SMASI busDelay 5
attr SMASI closeAfterResponse 0
attr SMASI dev-h-defLen 2
attr SMASI dev-h-defPoll 0
attr SMASI dev-h-defRevRegs 1
attr SMASI dev-i-defLen 2
attr SMASI dev-i-defPoll 1
attr SMASI dev-i-defRevRegs 1
attr SMASI dev-type-ENUM_JN-hint ja,nein
attr SMASI dev-type-ENUM_JN-len 2
attr SMASI dev-type-ENUM_JN-map 1129:ja, 1130:nein
attr SMASI enableControlSet 1
attr SMASI icon batterie
attr SMASI obj-h40075-name Eigenverbraucherhoehung eingeschaltet
attr SMASI obj-h40075-polldelay 310
attr SMASI obj-h40075-reading EigenverbraucherhoehungAktiv
attr SMASI obj-h40075-set 1
attr SMASI obj-h40075-showGet 1
attr SMASI obj-h40075-unpack n
attr SMASI obj-h40075-type ENUM_JN
attr SMASI obj-i30775-expr $val*-1
attr SMASI obj-i30775-ignoreExpr $val < -8000
attr SMASI obj-i30775-max 5000
attr SMASI obj-i30775-min -5000
attr SMASI obj-i30775-reading BatteryPower
attr SMASI obj-i30775-revRegs 1
attr SMASI obj-i30845-reading StateOfCharge
attr SMASI obj-i30847-polldelay 1800
attr SMASI obj-i30847-reading StateOfHealth
attr SMASI obj-i30849-expr $val/10
attr SMASI obj-i30849-format %.1f
attr SMASI obj-i30849-polldelay 600
attr SMASI obj-i30849-reading BatteryTemp
attr SMASI obj-i30849-revRegs 1
attr SMASI obj-i30851-expr $val/100
attr SMASI obj-i30851-format %.2f
attr SMASI obj-i30851-polldelay 180
attr SMASI obj-i30851-reading BatteryVoltage
attr SMASI obj-i30993-expr $val/1000
attr SMASI obj-i30993-format %.3f
attr SMASI obj-i30993-name Ladefaktor: Verhältnis Batterieladung/-endladung
attr SMASI obj-i30993-reading Ladefaktor
attr SMASI obj-i31009-reading DischargeBoundary
attr SMASI obj-i31009-showGet 0
attr SMASI obj-i31057-name Status Batterienutzungsbereich
attr SMASI obj-i31057-reading BatteryUsageType
attr SMASI room Energie
attr SMASI silentReconnect 1
attr SMASI stateFormat <div>BatteryPower W / StateOfCharge %</div>
attr SMASI verbose 5


Hier das Logging mit Verboselevel 5. In Zeile 4 sieht man das hier etwas in 046a konvertiert wird.
2023.12.24 12:13:15.153 4: SMASI: set called with EigenverbraucherhoehungAktiv (h40075) setVal = 1130
2023.12.24 12:13:15.154 5: SMASI: GetSetChecks with force
2023.12.24 12:13:15.154 5: SMASI: GetSetChecks returns success
2023.12.24 12:13:15.154 5: SMASI: set packed hex 31313330 with n to hex 046a
2023.12.24 12:13:15.155 4: SMASI: DoRequest called from SetLDFn created new request, read buffer empty, id 3, fCode 3, tid 56,
request: id 3, write fc 16 h40075, len 2, value 046a, tid 228, master device SMASI, reading EigenverbraucherhoehungAktiv (set EigenverbraucherhoehungAktiv),
response: no id, no fcode
2023.12.24 12:13:15.155 5: SMASI: QueueRequest called from DoRequest with h40075, qlen 0 from master SMASI through io device SMASI
2023.12.24 12:13:15.155 5: SMASI: ProcessRequestQueue called from QueueRequest as direct:SMASI, qlen 1, force, request: request: id 3, write fc 16 h40075, len 2, value 046a, tid 228, master device SMASI, reading EigenverbraucherhoehungAktiv (set EigenverbraucherhoehungAktiv), queued 0.00 secs ago
2023.12.24 12:13:15.155 5: SMASI: checkDelays sendDelay, last send to same device was 53.591 secs ago, required delay is 0.1
2023.12.24 12:13:15.156 5: SMASI: checkDelays commDelay, last communication with same device was 53.578 secs ago, required delay is 0.1
2023.12.24 12:13:15.156 5: SMASI: checkDelays busDelayRead, last activity on bus was 53.578 secs ago, required delay is 5
2023.12.24 12:13:15.156 5: SMASI: checkDelays clientSwitchDelay is not relevant
2023.12.24 12:13:15.156 4: SMASI: ProcessRequestQueue (V4.5.6 - 7.11.2023) qlen 1, sending 00e40000000903109c8b000204046a via 192.168.1.34:502, read buffer empty, id 3, fCode 3, tid 56,
request: id 3, write fc 16 h40075, len 2, value 046a, tid 228, master device SMASI, reading EigenverbraucherhoehungAktiv (set EigenverbraucherhoehungAktiv), queued 0.00 secs ago,
response: no id, no fcode
2023.12.24 12:13:15.157 5: SMASI: Send called from ProcessRequestQueue
2023.12.24 12:13:15.157 5: DevIo_SimpleWrite SMASI: 00e40000000903109c8b000204046a
2023.12.24 12:13:15.158 5: SMASI: ReadAnswer called from SetLDFn
2023.12.24 12:13:15.159 5: SMASI: ReadAnswer remaining timeout is 1.99646210670471
2023.12.24 12:13:15.174 5: SMASI: ReadAnswer got: 00e400000003039003
2023.12.24 12:13:15.174 5: SMASI: ParseFrameStart called from ReadAnswer protocol TCP expecting id 3
2023.12.24 12:13:15.174 4: SMASI: ParseFrameStart (TCP, master) extracted id 3, fCode 144, tid 228, dlen 3 and potential data 03
2023.12.24 12:13:15.175 5: SMASI: HandleResponse called from ReadAnswer
2023.12.24 12:13:15.175 5: SMASI: HandleResponse is now creating response hash, masterHash is HASH(0x55f377d1a198)
2023.12.24 12:13:15.175 5: SMASI: HandleResponse is now calling ParseResponse, masterHash is HASH(0x55f377d1a198)
2023.12.24 12:13:15.175 5: SMASI: ParseResponse called from HandleResponse, fc 144
2023.12.24 12:13:15.176 4: SMASI: HandleResponse got response with error code 90 / 03, illegal data value
2023.12.24 12:13:15.176 4: SMASI: HandleResponse done, current frame / read buffer: 00e400000003039003, id 3, fCode 144, tid 228,
request: id 3, write fc 16 h40075, len 2, value 046a, tid 228, master device SMASI, reading EigenverbraucherhoehungAktiv (set EigenverbraucherhoehungAktiv), queued 0.02 secs ago, sent 0.02 secs ago,
response: id 3, fc 144, error code 03, h40075, len 2
2023.12.24 12:13:15.176 5: SMASI: ResetExpect for HandleResponse from response to idle
2023.12.24 12:13:15.176 5: SMASI: DropFrame called from ReadAnswer - drop 00e400000003039003
2023.12.24 12:13:15.177 5: SMASI: set is sending read after write
2023.12.24 12:13:15.177 4: SMASI: DoRequest called from SetLDFn created new request, read buffer empty,
request: id 3, read fc 3 h40075, len 2, tid 48, master device SMASI, reading EigenverbraucherhoehungAktiv (set EigenverbraucherhoehungAktiv Rd),
response: no id, no fcode
2023.12.24 12:13:15.177 5: SMASI: QueueRequest called from DoRequest with h40075, qlen 0 from master SMASI through io device SMASI
2023.12.24 12:13:15.177 5: SMASI: ProcessRequestQueue called from QueueRequest as direct:SMASI, qlen 1, force, request: request: id 3, read fc 3 h40075, len 2, tid 48, master device SMASI, reading EigenverbraucherhoehungAktiv (set EigenverbraucherhoehungAktiv Rd), queued 0.00 secs ago
2023.12.24 12:13:15.178 5: SMASI: checkDelays commDelay, last communication with same device was 0.003 secs ago, required delay is 0.1
2023.12.24 12:13:15.178 5: SMASI: checkDelays sendDelay, last send to same device was 0.019 secs ago, required delay is 0.1
2023.12.24 12:13:15.178 5: SMASI: checkDelays busDelayRead, last activity on bus was 0.003 secs ago, required delay is 5
2023.12.24 12:13:15.178 5: SMASI: checkDelays clientSwitchDelay is not relevant
2023.12.24 12:13:15.179 4: SMASI: checkDelays found busDelayRead not over, sleep for 4.997 forced
2023.12.24 12:13:20.176 4: SMASI: checkDelays sleep done, go on with sending
2023.12.24 12:13:20.177 4: SMASI: ProcessRequestQueue (V4.5.6 - 7.11.2023) qlen 1, sending 00300000000603039c8b0002 via 192.168.1.34:502, read buffer empty,
request: id 3, read fc 3 h40075, len 2, tid 48, master device SMASI, reading EigenverbraucherhoehungAktiv (set EigenverbraucherhoehungAktiv Rd), queued 5.00 secs ago,
response: no id, no fcode

Die dem Commandline Tool ModPoll.exe kann ich den Wert beispielsweise mit dieser Zeile richtig schreiben

modpoll -m tcp -p 502 -a 3 -t4 -r 40075 -c 2 -10 192.168.1.34 0 1130

Wenn ich nun den Wert für Eigenverbraucherhöhung auf NEIN ändern möchte, muss die Zahl 1130 per ModBus in das Register 40075 geschrieben werde. Bei SMA ist noch die Eigenart, das ein Wert immer auf zwei Register verteilt ist. Am ehesten kann man das in WireShark zeigen → Siehe Screenshot. Dort habe ich jedoch den Wert 1129 verwendet, was dem HEX Wert 469 entspricht.


Die ModBus Register von SMA kennen diese Datentypen:

TypBeschreibungNaN-Wert
S16Vorzeichenbehaftetes Wort (16 Bit).0x8000
S32Vorzeichenbehaftetes Doppelwort (32 Bit).0x8000 0000
STR3232-Byte-Datenfeld, im Format UTF8.NULL
U16Ein Wort (16 Bit).0xFFFF
U32Ein Doppelwort (32 Bit).0xFFFF FFFF
U32F&uuml;r Statuswerte werden nur die unteren 24 Bit eines Doppelworts (32 Bit) verwendet.0xFFFF FD
U64Ein Vierfachwort (64 Bit).0xFFFF FFFF FFFF
FFFF

Und das Register h40075 ist als U32 →Doppelwort deklariert.


Ich habe die starke Vermutung, das es etwas mit
unpak zu tun haben muss. Zumal hier Werte zulässig sind, die nicht in der fhem Doku gelistet sind (C,a,usw.)


::) Was muss in in fhem einstellen, damit er den Wert so schreibt, wie es im dem Bild oben zu sehen ist?
fhem in Docker auf Lenovo m625q 16gb RAM/2TB SSD | div. SonOFF mit Tasmota | Shelly | busware CUL869 | Homematic | Echo Dot | Fritz DECT Thermostate | ConBee II ZigBee Gateway | Mosquitto MQTT

Aurel_B

Hmmmm, ich finde so direkt keinen Fehler in deiner Config. Mir fällt auf, dass Modbusattr "046a" sendet was nur 16bit sind (=also 1 Modbusregister), es sollten allerdings 2x16bit also "0000 046a" gesendet werden? Ich würd mal "attr SMASI dev-type-ENUM_JN-len 2" entfernen, das ist glaub ich redundant (wegen "attr SMASI dev-h-defLen 2").

Tabadorer

Zitat von: Aurel_B am 29 Dezember 2023, 10:52:24Mir fällt auf, dass Modbusattr "046a" sendet was nur 16bit sind (=also 1 Modbusregister)

Ja genau. Er müsste sogar zusätzlich dezimal
0000 1130
senden. Sieht man gut in dem Bild WireShark Dump. Mit hexadezimalen Werten kommt der Batterieinverter nicht klar. Es sind also zwei Fehler :-\

Die Redundanz in der defLen war nicht immer da und hat keinen Einfluss auf dieses Verhalten. Ich probiere mit der Definition noch herum und daher schleichen sich dann mal solche Schönheitsfehler ein.
fhem in Docker auf Lenovo m625q 16gb RAM/2TB SSD | div. SonOFF mit Tasmota | Shelly | busware CUL869 | Homematic | Echo Dot | Fritz DECT Thermostate | ConBee II ZigBee Gateway | Mosquitto MQTT

Aurel_B

Hmmm, ich glaube, da bringst du etwas durcheinander. 046a ist schon korrekt, es fehlen einfach die 16bit vom ersten Register. Wireshark interpretiert dir die 00 00 04 6A als UINT32, gesendet wird nicht die Dezimalzahl. Der Inverter verwirft die Modbus Message weil der Wert zu kurz ist. Am Besten frägst du @StefanStrobel (er ist der Modbus Author) oder stellst deine Frage nochmals in https://forum.fhem.de/index.php?topic=75638.1215

Tabadorer

fhem in Docker auf Lenovo m625q 16gb RAM/2TB SSD | div. SonOFF mit Tasmota | Shelly | busware CUL869 | Homematic | Echo Dot | Fritz DECT Thermostate | ConBee II ZigBee Gateway | Mosquitto MQTT