Autor Thema: [ModBusAttr] Werte schreiben als Text ?  (Gelesen 226 mal)

Offline cotecmania

  • Sr. Member
  • ****
  • Beiträge: 535
[ModBusAttr] Werte schreiben als Text ?
« am: 24 März 2020, 10:26:29 »
Hallo,

Ich betreibe meinen Solarladeregler LS2024B seit Jahren und er läuft zuverlässig, Werte werden gelesen.
Ich schaffe es aber nicht, die RealTimeClock (RTC) auf dem Gerät zu setzen.
Der Wert z.B. RTC2 ist so definiert und wird korrekt gelesen :

obj-h36884-expr   sprintf("%02d %02d", ($val & 0xff), ($val >> 8) )
obj-h36884-format   %s
obj-h36884-polldelay   x12
obj-h36884-reading   RTC2
obj-h36884-set 1

RTC2 wird z.B. so richtig als reading angezeigt : 16 22

Wenn ich den Wert nun setzen will bekomme ich Fehlermeldungen.
set LS2024B RTC2 17 25  -> Set Value 17 25 is not numeric and textArg not specified
set LS2024B RTC2 1         -> Error code 04 / slave device failure

Das steht in der Doku zum Gerät :
D2 Real time clock 9014
03(read)10(write) D7-0 Hour, D15-8 Day

Das im Log, wenn ich es mit dem Wert 1 teste :
2020.03.24 10:23:20 5: LS2024B: UpdateSetList: setList=interval reread:noArg reconnect:noArg stop:noArg start:noArg close:noArg saveAsModule scanModbusId scanStop:noArg scanModbusObjects Batterie_Typ:User,AGM,Gel,Saeure RTC2 Last_Modus:manuell,nachts,nachts+timer,timer
2020.03.24 10:23:20 5: LS2024B: UpdateSetList: getList=
2020.03.24 10:23:27 5: LS2024B: set called with RTC2 (h36884) setVal = 1
2020.03.24 10:23:27 5: LS2024B: GetSetChecks with force
2020.03.24 10:23:27 5: LS2024B: GetSetChecks returns success
2020.03.24 10:23:27 5: LS2024B: set packed hex 31 with n to hex 0001
2020.03.24 10:23:27 4: LS2024B: DoRequest called from Set created request: id 1, fCode 16, type h, adr 36884, len 1, value 0001 for device LS2024B reading RTC2 (set RTC2), read buffer empty
2020.03.24 10:23:42 5: LS2024B: attr change set updateGetSetList to 1

Wie kann ich den Wert korrekt setzen ?

PS: Einfache Integerwerte wie 0/1 für einen anderen Wert funktionieren

Gruss
Joe
FHEM auf RaspberryPI B (jessie)
2xCUL868 für MAX/Slow_RF, HM-LAN, JeeLink
MAX!/HM-Thermostate, FS20/HM-Rolladenschalter, FS20-EM, LevelJet-Ölstandsmessung, PCA301, IT, KM271, IPCAM, ACER Iconia One mit AMAD/FTUI

Offline StefanStrobel

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1278
Antw:[ModBusAttr] Werte schreiben als Text ?
« Antwort #1 am: 24 März 2020, 20:17:40 »
Hallo Joe,

mit dem Attribut obj-h36884-expr definierst Du wie man von dem 16-Bit Wert im Holding-Register 36884 zu einem Text kommt.
Wenn Du nun einen eingegebenen Text im richtigen Format in das Register schreiben möchtest, dann musst Du den umgekehrten Weg auch definieren.
In der Doku findest Du dazu:
obj-[cdih][1-9][0-9]*-setexpr
    defines a perl expression that converts the user specified value in a set to a raw value that can be sent to the device. This is typically the inversion of -expr above.
Zudem musst Du dem Modul noch beibringen, dass es nach dem Set-Befehl einen String (zwei Zahlen mit Space dazwischen) akzeptieren soll. Die Lösung dafür steht aber schon in der Fehlermeldung drin: textArg.
obj-h36884-textArg 1
Dann kann die setExpr den String zerlegen und daraus eine passende 16-Bit-Zahl machen.

Dann musst Du ggf. noch dafür sorgen, dass mit function code 16 (Hex 10 in Deiner Doku) geschrieben wird und nicht mit 6.
dev-([cdih]-)*write
specifies the function code to use for writing this type of object. The default is 6 for holding registers and 5 for coils. Discrete inputs and input registers can not be written by definition.

Ich hoffe das hilft Dir weiter.

Gruss
   Stefan

Offline cotecmania

  • Sr. Member
  • ****
  • Beiträge: 535
Antw:[ModBusAttr] Werte schreiben als Text ?
« Antwort #2 am: 25 März 2020, 08:55:50 »
Hallo Stefan,

Danke für die Ausführungen. Das mit der Textformatierung habe ich verstanden, allerdings finde ich in der Commandref keine Beschreibung zu "textArg"

Um den Problemen mit dem Stringhandling erstmal aus dem Wege zu gehen, wollte ich einfach mal einen Integer-Wert schreiben z.B. 1 was ja auch nicht funktioniert.
Fehler : Error code 04 / slave device failure
Siehe auch noch mal meinen LOG-Auszug von oben

dev-h-write passt schon mit 16. In der Doku war das wohl ein Hex-Wert 0x10

Diesen Wert hier kann ich problemlos schreiben mit 0 oder 1:
obj-h36970-reading Last_EinAus
obj-h36970-set 1

Warum RTC2 nicht ?

Gruss
Joe
FHEM auf RaspberryPI B (jessie)
2xCUL868 für MAX/Slow_RF, HM-LAN, JeeLink
MAX!/HM-Thermostate, FS20/HM-Rolladenschalter, FS20-EM, LevelJet-Ölstandsmessung, PCA301, IT, KM271, IPCAM, ACER Iconia One mit AMAD/FTUI

Offline cotecmania

  • Sr. Member
  • ****
  • Beiträge: 535
Antw:[ModBusAttr] Werte schreiben als Text ?
« Antwort #3 am: 25 März 2020, 11:23:36 »
Hallo nochmals,

Das Problem war, dass die RealTimeClock nur auf einmal beschrieben werden darf, d.h. alle 3 Register müssen mit einem Write beschrieben werden.

Die 3 Bytes auf einmal zu lesen und zu formatieren habe ich geschafft, aber wie sieht das "setexpr" aus, um die Uhrzeit setzen zu können ?

Also die "inversion" zu folgendem ?
obj-h36883-expr sprintf("%02d.%02d.20%02d %02d:%02d:%02d",(($val[1]>>8), $val[2] & 0xff), ($val[2] >> 8), ($val[1] & 0xff) , ($val[0] >> 8),($val[0] & 0xff) )
ergibt
25.03.2020 11:12:08

Gruss und Danke
Joe
FHEM auf RaspberryPI B (jessie)
2xCUL868 für MAX/Slow_RF, HM-LAN, JeeLink
MAX!/HM-Thermostate, FS20/HM-Rolladenschalter, FS20-EM, LevelJet-Ölstandsmessung, PCA301, IT, KM271, IPCAM, ACER Iconia One mit AMAD/FTUI

Offline StefanStrobel

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1278
Antw:[ModBusAttr] Werte schreiben als Text ?
« Antwort #4 am: 25 März 2020, 17:42:38 »
Bitte poste doch erst mal Deine Konfiguration (unpack, len etc.), da das ja zusammen passen muss.

Ich könnte mir vorstellen, dass es am einfachsten ist, in den Expressions von / zu Hex-Strings zu arbeiten und den unpack- / pack-code als H* zu setzen.
Vermutlich ist das aber Geschmackssache ;-)

Gruss
   Stefan

Offline cotecmania

  • Sr. Member
  • ****
  • Beiträge: 535
Antw:[ModBusAttr] Werte schreiben als Text ?
« Antwort #5 am: 25 März 2020, 18:05:35 »
   obj-h36883-expr sprintf("%02d.%02d.20%02d %02d:%02d:%02d",(($val[1]>>8), $val[2] & 0xff), ($val[2] >> 8), ($val[1] & 0xff) , ($val[0] >> 8),($val[0] & 0xff) )
   obj-h36883-len 3
   obj-h36883-reading RTC
   obj-h36883-set 1
   obj-h36883-textArg 1
   obj-h36883-unpack s>s>s>
FHEM auf RaspberryPI B (jessie)
2xCUL868 für MAX/Slow_RF, HM-LAN, JeeLink
MAX!/HM-Thermostate, FS20/HM-Rolladenschalter, FS20-EM, LevelJet-Ölstandsmessung, PCA301, IT, KM271, IPCAM, ACER Iconia One mit AMAD/FTUI

Offline StefanStrobel

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1278
Antw:[ModBusAttr] Werte schreiben als Text ?
« Antwort #6 am: 25 März 2020, 18:23:41 »
Die Herausforderung ist jetzt dass s>s>s> zwar praktisch für das Lesen ist, aber beim Schreiben so nicht funktioniert, da Du beim Set eben nur einen Wert übergeben kannst bzw. die Expression auch nur einen Wert zurückgibt.
Wenn Du aber als unpack-Code so etwas wie "HHHHHHHHHHHH" verwendest, dann bekommst Du in der Expr beim Lesen einen Hex-String, den Du auch gut byteweise auseinandernehmen kannst und beim Schreiben kann Deine setExpr ebenfalls einen Hex-String zusammenbauen.

Gruss
   Stefan

Offline cotecmania

  • Sr. Member
  • ****
  • Beiträge: 535
Antw:[ModBusAttr] Werte schreiben als Text ?
« Antwort #7 am: 25 März 2020, 23:07:23 »
Hallo Stefan,

"HHHHHHHHHHHH" funktioniert nicht.
Ich habe leider nix mit perl am Hut aber nach etwas googeln  fand ich raus, dass unpack mit "H*" folgendes Ergebnis liefert : 042c19151403
Das sind die 6 Bytes, die die Zeitinformation beinhaltet.
Diese Bytefolge kann ich auch direkt wieder mit neuen Werten auf den Laderegler schreiben.
So weit so gut.
Nur will ich das Ganze ja menschlich lesbar :

Das ist somit meine expr:
sprintf("%02d.%02d.20%02d %02d:%02d:%02d", hex(substr($val,4,2)), hex(substr($val,10,2)), hex(substr($val,8,2)), hex(substr($val,6,2)), hex(substr($val,0,2)), hex(substr($val,2,2)))und erzeugt, wie gewünscht so etwas : 25.03.2020 22:59:55

Morgen muss ich schauen, wie ich das wieder in eine Bytefolge (mit setexpr) bringe und dann muesste das Schreiben ja funktionieren.
Ob es der effektivste Weg ist, bezweifle ich ...

Gruss
Joe
FHEM auf RaspberryPI B (jessie)
2xCUL868 für MAX/Slow_RF, HM-LAN, JeeLink
MAX!/HM-Thermostate, FS20/HM-Rolladenschalter, FS20-EM, LevelJet-Ölstandsmessung, PCA301, IT, KM271, IPCAM, ACER Iconia One mit AMAD/FTUI