Neue Versionen und Support zum Modbus-Modul

Begonnen von StefanStrobel, 20 August 2017, 12:11:08

Vorheriges Thema - Nächstes Thema

sukram

Hallo,

dein
unpack nmacht Probleme, weil "n" nur für 16-Bit Werte gilt. Probiere mal

unpack N
Zitat von: Tabadorer am 31 Dezember 2023, 12:26:28Ich habe die starke Vermutung, das es etwas mit
Code Auswählen Erweitern
unpak zu tun haben muss. Zumal hier Werte zulässig sind, die nicht in der fhem Doku gelistet sind (C,a,usw.)

Mehr Informationen, was pack/unpack alles kann, hier: https://perldoc.perl.org/functions/pack

Man bekommt hier ganz leicht einen Knoten im Hirn, weil Perl (bzw. PC im allgemeinen) eine andere Byte-Order als Modbus bzw. die Modbus Geräte machen. Ich bin damit auch öfter gestolpert, auch weil die Darstellung negativer Zahlenwerte mitunter unterschiedlich gehandhabt wird.

Tabadorer

Zitat von: sukram am 01 Januar 2024, 21:33:12Probiere mal

unpack N

Ja der Tipp ist schon gut. Jedoch wird beim schreiben die beiden Bytes vertauscht
In meiner Definition musste ich daher diese Zeilen ändern:
attr SMASI dev-h-defUnpack N
attr SMASI dev-type-ENUM_JN-revRegs 0

Mit aktivem revRegs schreibt er den Wert 1130 statt in 40076 in das Register 40075.


Also für das Lesen benötige ich das Attribut revRegs. Beim Schreiben muss ich es weglassen, damit das klappt.


Nun bekomme nach dem erfolgreichen Schreibvorgang den Fehler
Timeout in Readanswer (in read after write for FCode 16)
Dadurch, das ich showGet aktiv habe, kann ich mit get aktiv den Wert eintragen. Und das funktioniert in dem Fall auch ohne revRegs ganz normal.
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-type ENUM_JN

Ich habe hier nochmal das Log vom Schreibvorgang angehängt.
2024.01.02 18:53:30.441 4: SMASI: set called with EigenverbraucherhoehungAktiv (h40075) setVal = ja
2024.01.02 18:53:30.441 5: SMASI: GetSetChecks with force
2024.01.02 18:53:30.441 5: SMASI: GetSetChecks returns success
2024.01.02 18:53:30.442 5: SMASI: MapConvert called from FormatSetVal converted ja (ja) to 1129 with reversed map ja:1129, nein:1130,
2024.01.02 18:53:30.442 5: SMASI: set packed hex 31313239 with N to hex 00000469
2024.01.02 18:53:30.442 4: SMASI: DoRequest called from SetLDFn created new request, read buffer empty, id 3, fCode 3, tid 229,
request: id 3, write fc 16 h40075, len 2, value 00000469, tid 112, master device SMASI, reading EigenverbraucherhoehungAktiv (set EigenverbraucherhoehungAktiv),
response: no id, no fcode
2024.01.02 18:53:30.443 5: SMASI: QueueRequest called from DoRequest with h40075, qlen 0 from master SMASI through io device SMASI
2024.01.02 18:53:30.443 5: SMASI: ProcessRequestQueue called from QueueRequest as direct:SMASI, qlen 1, force, request: request: id 3, write fc 16 h40075, len 2, value 00000469, tid 112, master device SMASI, reading EigenverbraucherhoehungAktiv (set EigenverbraucherhoehungAktiv), queued 0.00 secs ago
2024.01.02 18:53:30.443 5: SMASI: checkDelays busDelayRead, last activity on bus was 50.695 secs ago, required delay is 5
2024.01.02 18:53:30.443 5: SMASI: checkDelays sendDelay, last send to same device was 50.708 secs ago, required delay is 0.1
2024.01.02 18:53:30.444 5: SMASI: checkDelays commDelay, last communication with same device was 50.695 secs ago, required delay is 0.1
2024.01.02 18:53:30.444 5: SMASI: checkDelays clientSwitchDelay is not relevant
2024.01.02 18:53:30.444 4: SMASI: ProcessRequestQueue (V4.5.6 - 7.11.2023) qlen 1, sending 00700000000b03109c8b00020400000469 via 192.168.1.34:502, read buffer empty, id 3, fCode 3, tid 229,
request: id 3, write fc 16 h40075, len 2, value 00000469, tid 112, master device SMASI, reading EigenverbraucherhoehungAktiv (set EigenverbraucherhoehungAktiv), queued 0.00 secs ago,
response: no id, no fcode
2024.01.02 18:53:30.444 5: SMASI: Send called from ProcessRequestQueue
2024.01.02 18:53:30.445 5: DevIo_SimpleWrite SMASI: 00700000000b03109c8b00020400000469
2024.01.02 18:53:30.446 5: SMASI: ReadAnswer called from SetLDFn
2024.01.02 18:53:30.446 5: SMASI: ReadAnswer remaining timeout is 1.99660897254944
2024.01.02 18:53:30.520 5: SMASI: ReadAnswer got: 00700000000603109c8b0002
2024.01.02 18:53:30.520 5: SMASI: ParseFrameStart called from ReadAnswer protocol TCP expecting id 3
2024.01.02 18:53:30.521 4: SMASI: ParseFrameStart (TCP, master) extracted id 3, fCode 16, tid 112, dlen 6 and potential data 9c8b0002
2024.01.02 18:53:30.521 5: SMASI: HandleResponse called from ReadAnswer
2024.01.02 18:53:30.521 5: SMASI: HandleResponse is now creating response hash, masterHash is HASH(0x55f0acfe54c0)
2024.01.02 18:53:30.521 5: SMASI: HandleResponse is now calling ParseResponse, masterHash is HASH(0x55f0acfe54c0)
2024.01.02 18:53:30.522 5: SMASI: ParseResponse called from HandleResponse, fc 16
2024.01.02 18:53:30.522 4: SMASI: HandleResponse done, current frame / read buffer: 00700000000603109c8b0002, id 3, fCode 16, tid 112,
request: id 3, write fc 16 h40075, len 2, value 00000469, tid 112, master device SMASI, reading EigenverbraucherhoehungAktiv (set EigenverbraucherhoehungAktiv), queued 0.08 secs ago, sent 0.08 secs ago,
response: id 3, fc 16, c40075, len 2
2024.01.02 18:53:30.522 5: SMASI: ResetExpect for HandleResponse from response to idle
2024.01.02 18:53:30.522 5: SMASI: DropFrame called from ReadAnswer - drop 00700000000603109c8b0002
2024.01.02 18:53:30.523 5: SMASI: set is sending read after write
2024.01.02 18:53:30.523 4: SMASI: DoRequest called from SetLDFn created new request, read buffer empty,
request: id 3, read fc 3 h40075, len 2, tid 176, master device SMASI, reading EigenverbraucherhoehungAktiv (set EigenverbraucherhoehungAktiv Rd),
response: no id, no fcode
2024.01.02 18:53:30.523 5: SMASI: QueueRequest called from DoRequest with h40075, qlen 0 from master SMASI through io device SMASI
2024.01.02 18:53:30.524 5: SMASI: ProcessRequestQueue called from QueueRequest as direct:SMASI, qlen 1, force, request: request: id 3, read fc 3 h40075, len 2, tid 176, master device SMASI, reading EigenverbraucherhoehungAktiv (set EigenverbraucherhoehungAktiv Rd), queued 0.00 secs ago
2024.01.02 18:53:30.524 5: SMASI: checkDelays clientSwitchDelay is not relevant
2024.01.02 18:53:30.524 5: SMASI: checkDelays busDelayRead, last activity on bus was 0.003 secs ago, required delay is 5
2024.01.02 18:53:30.524 5: SMASI: checkDelays sendDelay, last send to same device was 0.078 secs ago, required delay is 0.1
2024.01.02 18:53:30.525 5: SMASI: checkDelays commDelay, last communication with same device was 0.003 secs ago, required delay is 0.1
2024.01.02 18:53:30.525 4: SMASI: checkDelays found busDelayRead not over, sleep for 4.997 forced
2024.01.02 18:53:35.522 4: SMASI: checkDelays sleep done, go on with sending
2024.01.02 18:53:35.523 4: SMASI: ProcessRequestQueue (V4.5.6 - 7.11.2023) qlen 1, sending 00b00000000603039c8b0002 via 192.168.1.34:502, read buffer empty,
request: id 3, read fc 3 h40075, len 2, tid 176, master device SMASI, reading EigenverbraucherhoehungAktiv (set EigenverbraucherhoehungAktiv Rd), queued 5.00 secs ago,
response: no id, no fcode
2024.01.02 18:53:35.523 5: SMASI: Send called from ProcessRequestQueue
2024.01.02 18:53:35.523 5: DevIo_SimpleWrite SMASI: 00b00000000603039c8b0002
2024.01.02 18:53:35.525 5: SMASI: ReadAnswer called from SetLDFn
2024.01.02 18:53:35.525 5: SMASI: ReadAnswer remaining timeout is -3.00150990486145
2024.01.02 18:53:35.525 3: SMASI: Timeout in Readanswer, read buffer empty,
request: id 3, read fc 3 h40075, len 2, tid 176, master device SMASI, reading EigenverbraucherhoehungAktiv (set EigenverbraucherhoehungAktiv Rd), queued 5.00 secs ago, sent 5.00 secs ago,
response: no id, no fcode
2024.01.02 18:53:35.538 5: SMASI: readFn buffer: 00b00000000703030400000469 mode master, expect idle
2024.01.02 18:53:35.538 5: SMASI: ParseFrameStart called from ReadFn
2024.01.02 18:53:35.538 4: SMASI: ParseFrameStart (TCP, master) extracted id 3, fCode 3, tid 176, dlen 7 and potential data 0400000469
2024.01.02 18:53:35.539 3: SMASI: readfn got data while EXPECT was set to idle: 00b00000000703030400000469
2024.01.02 18:53:35.539 5: SMASI: DropBuffer for ReadFn clears the reception buffer with 00b00000000703030400000469



Das direkte Lesen nach dem schreiben müsste abgeschaltet werden, dann ist alles chique - denke ich. Oder übersehe ich da etwas?
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

StefanStrobel

Hallo,

der timeout ist ein Bug, der bisher noch nie bemerkt wurde, da Verzögerungen von mehreren Sekunden doch sehr unüblich sind (Du hast ein busDelay von 5 Sekunden eingestellt).
Hier eine neue Version zum Testen, die den Timeout bei großen Delays beseitigen sollte.

Gruss
   Stefan

Tabadorer

Danke. Ich habe vor dem Update den busDelay entfernt → funktioniert. Und nach dem Update geht es auch mit dem busDelay von 5s. Aber ich werden den busDelay weglassen, da ich diesen Parameter offenlichtlich nicht benötige.
Top!   :D
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

beaune

Hallo,
ich hab einen Fall, wo beim Lesen eine anderes Modbus Holding Register anzugeben ist als beim Schreiben. Mir ist nicht ganz klar, wie ich das korrekt angeben muß, bzw. so wie ich es dachte klappt es zumindest nicht.

Im Detail sehen die Attribute für das zu schreibende Register so aus:
attr PV obj-h0037-expr $val / 10
attr PV obj-h0037-max 30
attr PV obj-h0037-min 0
attr PV obj-h0037-name 0x25
attr PV obj-h0037-poll 0
attr PV obj-h0037-reading BatteryDischargeMaxCurrent
attr PV obj-h0037-set 1
attr PV obj-h0037-setexpr $val * 10
attr PV obj-h0037-showGet 0
attr PV obj-h0037-type unsigned short
Das funktioniert so auch, mache ich z.B. ein set PV BatteryDischargeMaxCurrent 28, dann kommt 280 im Register an und im Reading steht 28. Alles gut.

Wenn ich nun aber diesen Wert explizit lesen möchte, muß ich das über eine andere Registernummer tun. Das sieht so aus:
attr PV obj-h0145-expr $val / 10
attr PV obj-h0145-name 0x91
attr PV obj-h0145-poll 0
attr PV obj-h0145-reading BatteryDischargeMaxCurrent
attr PV obj-h0145-showGet 1
attr PV obj-h0145-type unsigned short

Und dann gibts ein Problem:
  • Gebe ich als Readingnamen denselben an, dann klappt das Schreiben nicht, und im Eingabefeld zu set steht der Wert / 10.
  • Gebe ich einen anderen Readingnamen an, dann klappt sowohl Schreiben (mit dem ersten Namen) als auch Lesen mit dem zweiten Namen

Ich möchte natürlich nur ein Reading verwenden, weil es sich aus Gerätesicht um denselben Parameter handelt. Aber das scheint zumindest so, wie ich es gemacht habe, nicht zu gehen. Mache ich was falsch, oder geht das schlicht nicht?

Aurel_B

Ich kenne eine ähnliche Situation von HTTPMOD wo ich auch bei einem Gerät Werte nur auf unterschiedliche Wegen lesen und schreiben kann. Ich denke nicht, dass du das innerhalb vom Modbus Modul auflösen kannst. Was ich gemacht habe: alles in ein Dummy ausgelagert (resp. DOIF), dort habe ich dann mein Reading welches dann via Notifies mit meinen HTTPMOD Devices abgeglichen wird. Im ersten Moment erscheint das umständlich, wenn du allerdings sowieso eine gewisse Logik einbauen möchtest (z.B. dein BatteryDischargeMaxCurrent abhängig von anderen Zuständen zu setzen) wird dieses Auslagern plötzlich hilfreich.

ukdirk

Zitat von: Tedious am 01 Oktober 2021, 16:23:01Hallo Stefan,

vielen Dank für Deine Geduld. Ich hab den Schritt vom Schlauch runter hinbekommen, läuft jetzt. Zur Doku für die Nachwelt, falls jemand mal einen Herz Pelletstar Condendation einbinden will hier ein Teil der Konfig als Guideline. Ist noch nicht komplett, aber das Muster ist klar, insofern kann ich jetzt nach und nach alle Parameter reinbauen.

defmod Pelletheizung ModbusAttr 1 60 192.168.192.86:502 TCP
attr Pelletheizung group Pelletheizung
attr Pelletheizung obj-h00000-expr $val/10
attr Pelletheizung obj-h00000-len 2
attr Pelletheizung obj-h00000-poll 1
attr Pelletheizung obj-h00000-reading Kesseltemperatur
attr Pelletheizung obj-h00000-unpack N
attr Pelletheizung obj-h00002-expr $val/10
attr Pelletheizung obj-h00002-len 2
attr Pelletheizung obj-h00002-poll 1
attr Pelletheizung obj-h00002-reading Bedarfstemperatur_Kessel
attr Pelletheizung obj-h00002-unpack N
attr Pelletheizung obj-h00004-len 2
attr Pelletheizung obj-h00004-poll 1
attr Pelletheizung obj-h00004-reading Kesselstatus
attr Pelletheizung obj-h00004-unpack N
attr Pelletheizung obj-h00006-expr $val/10
attr Pelletheizung obj-h00006-len 2
attr Pelletheizung obj-h00006-poll 1
attr Pelletheizung obj-h00006-reading Kesselleistung
attr Pelletheizung obj-h00006-unpack N
attr Pelletheizung obj-h01362-expr $val/10
attr Pelletheizung obj-h01362-len 2
attr Pelletheizung obj-h01362-poll 1
attr Pelletheizung obj-h01362-reading Kollektor-Rücklauf
attr Pelletheizung obj-h01362-unpack N
attr Pelletheizung obj-h01364-expr $val/10
attr Pelletheizung obj-h01364-len 2
attr Pelletheizung obj-h01364-poll 1
attr Pelletheizung obj-h01364-reading Kollektor-Vorlauf
attr Pelletheizung obj-h01364-unpack N
attr Pelletheizung obj-h01366-expr $val/10
attr Pelletheizung obj-h01366-len 2
attr Pelletheizung obj-h01366-poll 1
attr Pelletheizung obj-h01366-reading Speichertemperatur
attr Pelletheizung obj-h01366-unpack N
attr Pelletheizung obj-h01368-reading scan-h01368
attr Pelletheizung obj-h01370-expr $val/10
attr Pelletheizung obj-h01370-len 2
attr Pelletheizung obj-h01370-poll 1
attr Pelletheizung obj-h01370-reading Pumpendrehzahl
attr Pelletheizung obj-h01370-unpack N
attr Pelletheizung obj-h01378-expr $val/10
attr Pelletheizung obj-h01378-len 2
attr Pelletheizung obj-h01378-poll 1
attr Pelletheizung obj-h01378-reading Ertrag-aktuell
attr Pelletheizung obj-h01378-unpack N
attr Pelletheizung room Heizung

Hi Tedious,

vielen Dank für die Arbeit. Das hilft sehr weiter. Hast Du noch mehr Register hinzugefügt?

Viele Grüße,
Dirk

WW

Zitat von: oniT am 15 Oktober 2019, 21:58:59Hallo Stefan,

ja fein, das ist die Lösung. Ich hatte noch ein paar 00 zu viel, aber jetzt konnten die Werte 0, 33, 66 und 100% für die Leistungsstufe geschrieben werden. Hier wieder ein Auszug aus dem Log:

2019.10.15 20:28:47 5: RTUWrite: set called with 256 (h256) setVal = 100
2019.10.15 20:28:47 5: RTUWrite: GetSetChecks with force
2019.10.15 20:28:47 5: RTUWrite: GetSetChecks returns success
2019.10.15 20:28:47 5: RTUWrite: CheckEval for Set evaluates setexpr for 256, val=100, expr='00000000000000000000'.unpack("H4", pack("n", $val)).'006400010000'
2019.10.15 20:28:47 5: RTUWrite: CheckEval for Set result is 000000000000000000000064006400010000
2019.10.15 20:28:47 5: RTUWrite: set packed hex 303030303030303030303030303030303030303030303634303036343030303130303030 with H* to hex 000000000000000000000064006400010000
2019.10.15 20:28:47 4: RTUWrite: DoRequest called from Set created request: id 99, fCode 16, type h, adr 256, len 8, value 000000000000000000000064006400010000 for device RTUWrite reading 256 (set 256), read buffer empty
2019.10.15 20:28:47 5: ModbusLine: QueueRequest called from DoRequest (RTUWrite) with h256, qlen 0
2019.10.15 20:28:47 4: ModbusLine: ProcessRequestQueue called from QueueRequest, force, qlen 1, next entry to id 99 (RTUWrite), last send to this device was 51.455 secs ago, last read 51.432 secs ago, last read on bus 21.616 secs ago from id 99 (Quantum)
2019.10.15 20:28:47 5: ModbusLine: CheckDelay called from ProcessRequestQueue commDelay (0.1s since 20:27:56.018) for RTUWrite, delay 51.333secs over
2019.10.15 20:28:47 5: ModbusLine: CheckDelay called from ProcessRequestQueue sendDelay (0.1s since 20:27:55.995) for RTUWrite, delay 51.356secs over
2019.10.15 20:28:47 4: ModbusLine: ProcessRequestQueue (V4.1.5 - 17.9.2019) qlen 1, sending 63100100000810000000000000000000000064006400010000545a request: id 99, fCode 16, type h, adr 256, len 8, value 000000000000000000000064006400010000 for device RTUWrite reading 256 (set 256), queued 0.00 secs ago, read buffer empty
2019.10.15 20:28:47 5: SW: 63100100000810000000000000000000000064006400010000545a

Und hier die Definition, für alle die auch einmal solch eine Lösung benötigen.

defmod RTUWrite ModbusAttr 99 3600
attr RTUWrite userattr dev-h-write dev-timing-timeout obj-h256-len obj-h256-reading obj-h256-set obj-h256-setexpr obj-h256-unpack
attr RTUWrite dev-h-write 16
attr RTUWrite dev-timing-timeout 4
attr RTUWrite obj-h256-len 8
attr RTUWrite obj-h256-reading 256
attr RTUWrite obj-h256-set 1
attr RTUWrite obj-h256-setexpr '00000000000000000000'.unpack("H4", pack("n", $val)).'006400010000'
attr RTUWrite obj-h256-unpack H*

Ist noch nicht dringend, gibt es aber auch irgendwie die Möglichkeit diesen String mit den anderen Registern zusammenzusetzen? Bei dieser Lösung ist dieser ja bis auf h261 fest. Im setexpr wird ja der eingegebene Wert durch $val mit übergeben. Könnte man zum Beispiel in einem DOIF oder notify, ist ja egal, die Setexpr mit anderen Werten zum Beispiel aus einem Dummy zusammenbauen und dann in das "attr RTUWrite obj-h256-setexpr ' ....'" schreiben. Anschließend wird noch der Befehl ausgeführt, fertig. Das ist meiner Meinung nach doch möglich und sollte unktionieren. Ist vielleicht nicht die eleganteste Lösung, aber vermutlich die einfachste. Oder was meinst Du? Gibt es noch eine andere Lösung.

Danke für die Unterstützung, hat mich wieder ein Stück weitergebracht.

Gruß
Tino



Ich habe ein ähnliches Problem und komme hier nicht weiter. Um bei meinem Azzurro-Wechselrichter die max. Entladetiefe zu setzen, muss ein Block von 16 Registern in einem geschrieben werden.

Ich lese die 16 Register aus und schreibe sie in ein Reading:

attr myWechselrichter obj-h04164-len 16
attr myWechselrichter obj-h04164-poll 0
attr myWechselrichter obj-h04164-reading Bat1_Config
attr myWechselrichter obj-h04164-showGet Bat1_Config
attr myWechselrichter obj-h04164-unpack H*

Das Reading "Bat1_Config" wird auch angelegt:
setstate myWechselrichter 2024-02-18 21:06:38 Bat1_Config 00000000000113880000000001a409c409c400500050006411940000000a0000

Die 64 Zeichen repräsentieren die 16 gelesenen Register. Ich müsste nun das 9. Register mit der neuen Entladetiefe ersetzen und im letzten Register die "0000" in "0001" ändern. Und dann die ganzen 16 Register beginnend ab Adresse 4164 zurückschreiben. Und genau an dieser Stelle scheitere ich. Wie kann ich die Änderungen vornehmen und dann schreiben. Hängt vermutlich an meinen mangelnden Kenntnissen bezüglich pack/unpack.

Vielen Dank für Anregungen
Willi
FHEM 6.0 im Docker-Container (OMV4 auf ASRock J3455-ITX), FHEM 6.0 auf Raspi, Fritzbox 7490, CUL433, CUL868, Jeelink868, SIGNALduino, LaCrosseGateway, SonoffZbBridge, Shelly, Sonoff, ESP8266, ESP32, ESP32-Cam, LaCrosse, Revolt, OneWire, Zigbee (Sonoff, Blitzwolf, IKEA, Lidl)

WW

Niemand eine Anregung für mich?

MfG
Willi
FHEM 6.0 im Docker-Container (OMV4 auf ASRock J3455-ITX), FHEM 6.0 auf Raspi, Fritzbox 7490, CUL433, CUL868, Jeelink868, SIGNALduino, LaCrosseGateway, SonoffZbBridge, Shelly, Sonoff, ESP8266, ESP32, ESP32-Cam, LaCrosse, Revolt, OneWire, Zigbee (Sonoff, Blitzwolf, IKEA, Lidl)

Aurel_B

Naja, die Lösung steht ja schon (fast) in deinem zitierten Post. Mit einem

attr myWechselrichter obj-h04164-setexpr '00000000000113880000000001a409c409c40'.unpack("H4", pack("n", $val)).'00050006411940000000a0001'
könnte es klappen.

WW

Zitat von: Aurel_B am 27 Februar 2024, 21:06:53Naja, die Lösung steht ja schon (fast) in deinem zitierten Post. Mit einem

attr myWechselrichter obj-h04164-setexpr '00000000000113880000000001a409c409c40'.unpack("H4", pack("n", $val)).'00050006411940000000a0001'
könnte es klappen.

Leider ist es nicht ganz so einfach: Die Werte der anderen 14 Register ist nicht fest, sondern von anderen Parametern abhängig. Ich müsste also erst die 16 Register lesen, das 9. und das letze Register anpassen und dann die so modifizierten 16 Register zurückschreiben. Also Register 1-8 und 10-15 irgendwie auch mit unpack/pack behandeln(?)
FHEM 6.0 im Docker-Container (OMV4 auf ASRock J3455-ITX), FHEM 6.0 auf Raspi, Fritzbox 7490, CUL433, CUL868, Jeelink868, SIGNALduino, LaCrosseGateway, SonoffZbBridge, Shelly, Sonoff, ESP8266, ESP32, ESP32-Cam, LaCrosse, Revolt, OneWire, Zigbee (Sonoff, Blitzwolf, IKEA, Lidl)

300P

FHEM 6.3 - Raspberry Pi 3 / Pi 4 - VControl300 mit VITOVALOR 300P - SMAEM - SMAInverter - DbLog/DbRep - MariaDB/QNAP - div. HTTPMOD - div. Modbus ser+TCP - SolarForecast - Tibber + Ladung mit SMA-SBS25

WW

Zitat von: WW am 18 Februar 2024, 21:35:42...
attr myWechselrichter obj-h04164-len 16
attr myWechselrichter obj-h04164-poll 0
attr myWechselrichter obj-h04164-reading Bat1_Config
attr myWechselrichter obj-h04164-showGet Bat1_Config
attr myWechselrichter obj-h04164-unpack H*

Das Reading "Bat1_Config" wird auch angelegt:
setstate myWechselrichter 2024-02-18 21:06:38 Bat1_Config 00000000000113880000000001a409c409c400500050006411940000000a0000
....

Ich stehe immer noch auf dem Schlauch: Im Reading "Bat1_Config" habe ich ja meine 16 Register als Hex-String. Wie kann ich denn hieraus Teile extrahieren (z.B. Register 1-8 bzw. 10-15)? DIe normalen String-Operationen scheinen hier nicht zu funktionieren. Mir ist nicht klar, was ein Hex-String überhaupt ist.
FHEM 6.0 im Docker-Container (OMV4 auf ASRock J3455-ITX), FHEM 6.0 auf Raspi, Fritzbox 7490, CUL433, CUL868, Jeelink868, SIGNALduino, LaCrosseGateway, SonoffZbBridge, Shelly, Sonoff, ESP8266, ESP32, ESP32-Cam, LaCrosse, Revolt, OneWire, Zigbee (Sonoff, Blitzwolf, IKEA, Lidl)

Aurel_B

Hmmmm, das tönt in der Tat nicht ganz einfach. Was ich machen würde: die ganze Logik in ein separates DOIF auslagen (im Perl Modus) und mir dort Stück für Stück das ganze Register zusammenbauen, so à la

defmod RegisterKonstruieren DOIF {
my $register = unpack("H4", pack("n", ReadingsVal("Foo", "Register1", undef)));
$register .= unpack("H4", pack("n", ReadingsVal("Bar", "Register2", undef)));
}

etc. etc. Macht das so Sinn?

Aurel_B

Zitat von: WW am 27 Februar 2024, 21:47:12Ich stehe immer noch auf dem Schlauch: Im Reading "Bat1_Config" habe ich ja meine 16 Register als Hex-String. Wie kann ich denn hieraus Teile extrahieren (z.B. Register 1-8 bzw. 10-15)? DIe normalen String-Operationen scheinen hier nicht zu funktionieren. Mir ist nicht klar, was ein Hex-String überhaupt ist.


Ein Hex-String würde ich mal einfach als einen String voller Hex-Werten betrachten :-) Im Prinzip müsste irgendwo in der Dokus deines Wechselrichters stehen, was denn genau für Werte in diesem String stecken. Wenn z.B. immer 4 Hex-Werte für einen Wert stehen, so hast du 4x4bit == 16bit, könnte z.B. ein signed short sein. Schau dir z.B. Bitoperationen an, damit kannst du jeweils 16bit aus deinem String extrahieren und dann mit der unpack Funktion in einen vernünftigen Wert umwandeln.

Vielleicht wäre es hilfreich, wenn du uns einen Link zur Modbus Beschreibung deines Wechselrichters posten könntest damit wir mehr verstehen. Generell scheint es mir schade, dass scheinbar alles in ein übergrosses Register gepackt wurde. Dieser riesige Hex-Wert gehört IMHO eigentlich alles in separate Register, das ist ja Sinn und Zweck der Register! Und für einzelne Bits gibt/gäbe es Coils!