ModbusAttr - unpack negative Values - Solvis

Begonnen von Tsturm, 29 November 2020, 22:45:35

Vorheriges Thema - Nächstes Thema

Tsturm

Hallo zusammen,

ich lese aus meiner SolvisMax via Modbus diverse Temperaturen aus. Einige wenige davon - Außentemperatur, Solarkollektor - können auch negativ werden, und dann klappt das Perl-Unpack mit "n" (attr Solvis dev-i-defUnpack n)  nicht mehr. Wie muss ich das Unpack-Kommando setzen, dass ich auch richtige negative Werte bekomme?

Die erste Zeile wird richtig entpackt - 24,9 Grad
Die zweite Zeile sollte so um die -3 Grad ergeben, ergibt aber 6552,2 Grad (alles in 1/10 Grad).
Die negativen Werte sind irgendwie anders zu entpacken, oder aus dem Rohwert umzurechnen. Leider gibt die ansonsten gute Doku von Solvis keinen Hinweis.


2020.11.29 21:47:49.201 5: Solvis: ParseObj unpacked 00f9 with n to 249 hex 323439

2020.11.29 21:46:55.202 5: Solvis: ParseObj unpacked fff2 with n to 65522 hex 3635353232



VG Timmo

List des Moduls - die fraglichen Werte sind "Temp_S10" und "Temp_S8"
DEF        1 60 192.168.178.55:502 TCP
   DeviceName 192.168.178.55:502
   EXPECT     idle
   FD         21
   FUUID      5f207d1e-f33f-b872-d98a-a55fc639f08dfe4b
   INTERVAL   60
   IODev      Solvis
   LASTOPEN   1606668390.6406
   MODBUSID   1
   MODE       master
   MODULEVERSION Modbus 4.1.5 - 17.9.2019
   NAME       Solvis
   NOTIFYDEV  global
   NR         402
   NTFY_ORDER 50-Solvis
   PARTIAL   
   PROTOCOL   TCP
   STATE      opened
   TCPConn    1
   TRIGGERTIME 1606685802.87937
   TRIGGERTIME_FMT 2020-11-29 22:36:42
   TRIGGERTIME_SAVED
   TYPE       ModbusAttr
   devioLoglevel 4
   lastUpdate 1606685742.87937
   nextOpenDelay 60
   Helper:
     DBLOG:
       Temp_S1:
         logdb:
           TIME       1606685746.18864
           VALUE      57.1
       Temp_S10:
         logdb:
           TIME       1606685753.94541
           VALUE      6551.8
       Temp_S11:
         logdb:
           TIME       1606685747.69075
           VALUE      34.7
       Temp_S12:
         logdb:
           TIME       1606685743.18977
           VALUE      25.1
       Temp_S13:
         logdb:
           TIME       1606685757.439
           VALUE      32.5
       Temp_S3:
         logdb:
           TIME       1606685752.44198
           VALUE      23.4
       Temp_S4:
         logdb:
           TIME       1606685750.94014
           VALUE      38
       Temp_S8:
         logdb:
           TIME       1606685755.94635
           VALUE      6546.7
       Temp_S9:
         logdb:
           TIME       1606685749.43818
           VALUE      26.5
   OLDREADINGS:
   QUEUE:
   READ:
     BUFFER     
   READINGS:
     2020-11-29 22:35:46   Temp_S1         57.1
     2020-11-29 22:35:53   Temp_S10        6551.8
     2020-11-29 22:35:47   Temp_S11        34.7
     2020-11-29 22:35:43   Temp_S12        25.1
     2020-11-29 22:35:57   Temp_S13        32.5
     2020-11-29 22:35:52   Temp_S3         23.4
     2020-11-29 22:35:50   Temp_S4         38
     2020-11-29 22:35:55   Temp_S8         6546.7
     2020-11-29 22:35:49   Temp_S9         26.5
     2020-11-29 22:35:44   Waermeerzeuger SX aktuelle Leistung 0
   REMEMBER:
     lid        1
     lname      Solvis
     lrecv      1606685757.43426
     lsend      1606685756.94128
   defptr:
     ModbusAttr 1
     Solvis     1
   gotReadings:
     Temp_S13   32.5
   lastRead:
     i33024     1606685746.18564
     i33026     1606685752.439
     i33027     1606685750.93717
     i33031     1606685755.94076
     i33032     1606685749.4352
     i33033     1606685753.93872
     i33034     1606685747.68775
     i33035     1606685743.18677
     i33036     1606685757.43595
     i33539     1606685744.69014
Attributes:
   dev-h-defExpr ModbusLD_ScanFormat($hash, $val)
   dev-h-defLen 1
   dev-h-defUnpack a2
   dev-i-defLen 1
   dev-i-defUnpack n
   dev-timing-commDelay 1
   dev-timing-sendDelay 1
   dev-timing-serverTimeout 5
   dev-timing-timeout 5
   obj-i33024-expr $val / 10
   obj-i33024-poll 1
   obj-i33024-reading Temp_S1
   obj-i33026-expr $val / 10
   obj-i33026-poll 1
   obj-i33026-reading Temp_S3
   obj-i33027-expr $val / 10
   obj-i33027-poll 1
   obj-i33027-reading Temp_S4
   obj-i33031-expr $val / 10
   obj-i33031-poll 1
   obj-i33031-reading Temp_S8
   obj-i33032-expr $val / 10
   obj-i33032-poll 1
   obj-i33032-reading Temp_S9
   obj-i33033-defLen 1
   obj-i33033-defUnpack N
   obj-i33033-expr $val / 10
   obj-i33033-poll 1
   obj-i33033-reading Temp_S10
   obj-i33034-expr $val / 10
   obj-i33034-poll 1
   obj-i33034-reading Temp_S11
   obj-i33035-expr $val / 10
   obj-i33035-poll 1
   obj-i33035-reading Temp_S12
   obj-i33036-expr $val / 10
   obj-i33036-poll 1
   obj-i33036-reading Temp_S13
   obj-i33539-expr $val / 10
   obj-i33539-poll 1
   obj-i33539-reading Waermeerzeuger SX aktuelle Leistung
   room       5_Keller,9.7_Therm
   silentReconnect 1
   userattr   dev-h-defExpr dev-h-defLen dev-h-defUnpack dev-i-defLen dev-i-defUnpack obj-i33024-expr obj-i33024-poll obj-i33024-reading obj-i33026-expr obj-i33026-poll obj-i33026-reading obj-i33027-expr obj-i33027-poll obj-i33027-reading obj-i33031-defLen obj-i33031-defUnpack obj-i33031-expr obj-i33031-poll obj-i33031-reading obj-i33032-expr obj-i33032-poll obj-i33032-reading obj-i33033-expr obj-i33033-poll obj-i33033-reading obj-i33034-expr obj-i33034-poll obj-i33034-reading obj-i33035-expr obj-i33035-poll obj-i33035-reading obj-i33036-expr obj-i33036-poll obj-i33036-reading obj-i33539-expr obj-i33539-poll obj-i33539-reading


Auszug aus dem Logfile mit Verbose=5 mit dem funktionierenden Temperaturwert S9 (die werte werden in =0.1 gradschrtten abgelegt, daher die Division durch 10)

2020.11.29 21:47:48.701 4: Solvis: ProcessRequestQueue (V4.1.5 - 17.9.2019) qlen 6, sending 00ad00000006010481080001 request: id 1, fCode 4, tid 173, type i, adr 33032, len 1 for device Solvis reading Temp_S9 (getUpdate), queued 5.92 secs ago, read buffer empty
2020.11.29 21:47:48.701 5: SW: 00ad00000006010481080001
2020.11.29 21:47:48.705 5: Solvis: StartQueueTimer called form ProcessRequestQueue sets internal timer to call Modbus_ProcessRequestQueue in 1.000 seconds
2020.11.29 21:47:49.199 5: Solvis: read buffer: 00ad0000000501040200f9
2020.11.29 21:47:49.199 4: Solvis: ParseFrameStart (TCP) extracted id 1, fCode 4, tid 173, dlen 5 and data 0200f9
2020.11.29 21:47:49.199 5: Solvis: HandleResponse called from Read
2020.11.29 21:47:49.200 5: Solvis: ParseResponse called from HandleResponse
2020.11.29 21:47:49.200 5: Solvis: HandleResponse now passing to logical device Solvis for parsing data
2020.11.29 21:47:49.200 5: Solvis: ParseObj called with data 00f9, type i, adr 33032, valuesLen 1, op read
2020.11.29 21:47:49.201 5: Solvis: ParseObj ObjInfo for i33032: reading=Temp_S9, unpack=n, expr=$val / 10, format=, map=
2020.11.29 21:47:49.201 5: Solvis: ParseObj unpacked 00f9 with n to 249 hex 323439
2020.11.29 21:47:49.201 5: Solvis: CheckEval for ParseObj evaluates expr for Temp_S9, val=249, expr=$val / 10
2020.11.29 21:47:49.202 5: Solvis: CheckEval for ParseObj result is 24.9
2020.11.29 21:47:49.202 4: Solvis: ParseObj assigns value 24.9 to Temp_S9
2020.11.29 21:47:49.209 5: Solvis: HandleResponse got 1 readings from ParseObj for Solvis



Auszug aus dem Logfile mit Verbose=5 mit dem nicht funktionierenden Temperaturwert S10 (sollte so um die -3 Grad sein - stattdessen wird 6552.2 errechnet)


2020.11.29 21:46:54.702 4: Solvis: ProcessRequestQueue (V4.1.5 - 17.9.2019) qlen 2, sending 001b00000006010481090001 request: id 1, fCode 4, tid 27, type i, adr 33033, len 1 for device Solvis reading Temp_S10 (getUpdate), queued 11.91 secs ago, read buffer empty
2020.11.29 21:46:54.702 5: SW: 001b00000006010481090001
2020.11.29 21:46:54.706 5: Solvis: StartQueueTimer called form ProcessRequestQueue sets internal timer to call Modbus_ProcessRequestQueue in 1.000 seconds
2020.11.29 21:46:55.200 5: Solvis: read buffer: 001b00000005010402fff2
2020.11.29 21:46:55.200 4: Solvis: ParseFrameStart (TCP) extracted id 1, fCode 4, tid 27, dlen 5 and data 02fff2
2020.11.29 21:46:55.200 5: Solvis: HandleResponse called from Read
2020.11.29 21:46:55.201 5: Solvis: ParseResponse called from HandleResponse
2020.11.29 21:46:55.201 5: Solvis: HandleResponse now passing to logical device Solvis for parsing data
2020.11.29 21:46:55.201 5: Solvis: ParseObj called with data fff2, type i, adr 33033, valuesLen 1, op read
2020.11.29 21:46:55.202 5: Solvis: ParseObj ObjInfo for i33033: reading=Temp_S10, unpack=n, expr=$val / 10, format=, map=
2020.11.29 21:46:55.202 5: Solvis: ParseObj unpacked fff2 with n to 65522 hex 3635353232
2020.11.29 21:46:55.203 5: Solvis: CheckEval for ParseObj evaluates expr for Temp_S10, val=65522, expr=$val / 10
2020.11.29 21:46:55.203 5: Solvis: CheckEval for ParseObj result is 6552.2
2020.11.29 21:46:55.204 4: Solvis: ParseObj assigns value 6552.2 to Temp_S10



Tsturm

Heureka, habs gefunden ...
s>
scheint zu funktionieren.
Viele Grüße - Timmo

reneger

Hi,

ich habe meine SC3 gerade auch ans Netz geklemmt.
Kannst du deine definition hier posten?

Das wäre sehr cool,

Danke und Gruß.

Reneger

Tsturm

Hi Reneger,

muss schauen, dass ich es noch finde (sicher im Backup...)

BTW - Ich habe in den letzten Wochen die ganze Sammlung und Verwaltung von Time-Series (Sensoren, Modbus, JSON-Posts etc.) auf Influx/Telegraf und Grafana umgestellt, da mein FHEM immer weniger performant wurde (ich vermute mal, dass sich die ganzen Abfragen und die DB in die Quere kamen).. Kann ich auch gerne posten, das sind tatsächlich nur 10-20 Zeilen Konfiguration für Influx und wirklich elegante Graphiken, die sehr schnell online erstellt und modifiziert werden können. Ist eine echte Alternative, und fokussiert FHEM auf die Steuerungsthemen.

VG Timmo



VG Timmo

reneger

Moin Timmo,

ja sehr gerne, das kommt bei mir als nächstes dran.
Habe Grafana und eine InfluxDB bisher schon am OpenHAB hängen, aber da ich nun alles auf FHEM umziehe, muss das auch wieder da dran.

Gruß reneger

Tsturm

Dann würde ich definitv nicht über FHEM gehen, es sei denn, dass Du die Anlage tatsächlich steuern willst. Einzelne Events (wenn bestimmte Werte erricht werden etc) kann man aus Influx auch an FEHM schicken, habe das aber noch nicht gemacht.
Schickt Dir meine Config am WE (bin mal wieder im Büro...), wie gesagt, war etwas fummelig bei der Einarbeitung, sind aber am Ende wirklich nur 10 Zeilen, um Modbus auszulesen.

vG timmo

Tsturm

Servus,

hier der Teil meines Telegraf Scripts für das Auslesen des Modbus von der Solvis:

# # Retrieve data from MODBUS slave devices
[[inputs.modbus]]
name_override = "heizung"
#   ## Device name
name = "Solvis"
#
#   ## Slave ID - addresses a MODBUS device on the bus
#   ## Range: 0 - 255 [0 = broadcast; 248 - 255 = reserved]
slave_id = 1
#
#   ## Timeout for each request
timeout = "30s"
#
#   ## Maximum number of retries and the time to wait between retries
#   ## when a slave-device is busy.
busy_retries = 10
busy_retries_wait = "10000ms"
#
#   # TCP - connect via Modbus/TCP
controller = "tcp://192.168.178.55:502"

#   ## Measurements
#   ##
#
#   ## Analog Variables, Input Registers and Holding Registers
#   ## measurement - the (optional) measurement name, defaults to "modbus"
#   ## name        - the variable name
#   ## byte_order  - the ordering of bytes
#   ##  |---AB, ABCD   - Big Endian
#   ##  |---BA, DCBA   - Little Endian
#   ##  |---BADC       - Mid-Big Endian
#   ##  |---CDAB       - Mid-Little Endian
#   ## data_type  - INT16, UINT16, INT32, UINT32, INT64, UINT64,
#   ##              FLOAT32-IEEE, FLOAT64-IEEE (the IEEE 754 binary representation)
#   ##              FLOAT32, FIXED, UFIXED (fixed-point representation on input)
#   ## scale      - the final numeric variable representation
#   ## address    - variable address
#
   holding_registers = [
     { name = "Temp_S01", byte_order = "AB", data_type = "INT16", scale=1.0,  address = [33024]},
{ name = "Temp_S02", byte_order = "AB", data_type = "INT16", scale=1.0,  address = [33025]},
{ name = "Temp_S03", byte_order = "AB", data_type = "INT16", scale=1.0,  address = [33026]},
{ name = "Temp_S04", byte_order = "AB", data_type = "INT16", scale=1.0,  address = [33027]},
{ name = "Temp_S05", byte_order = "AB", data_type = "INT16", scale=1.0,  address = [33028]},
{ name = "Temp_S06", byte_order = "AB", data_type = "INT16", scale=1.0,  address = [33029]},
{ name = "Temp_S07", byte_order = "AB", data_type = "INT16", scale=1.0,  address = [33030]},
{ name = "Temp_S08", byte_order = "AB", data_type = "INT16", scale=1.0,  address = [33031]},
{ name = "Temp_S09", byte_order = "AB", data_type = "INT16", scale=1.0,  address = [33032]},
{ name = "Temp_S10", byte_order = "AB", data_type = "INT16", scale=1.0,  address = [33033]},
{ name = "Temp_S11", byte_order = "AB", data_type = "INT16", scale=1.0,  address = [33034]},
{ name = "Temp_S12", byte_order = "AB", data_type = "INT16", scale=1.0,  address = [33035]},
{ name = "Temp_S13", byte_order = "AB", data_type = "INT16", scale=1.0,  address = [33036]},
{ name = "Temp_S15", byte_order = "AB", data_type = "INT16", scale=1.0,  address = [33038]},
{ name = "Vol_S17", byte_order = "AB", data_type = "INT16", scale=1.0,  address = [33040]},
{ name = "Vol_S18", byte_order = "AB", data_type = "INT16", scale=1.0,  address = [33041]},
{ name = "Leistung", byte_order = "AB", data_type = "INT16", scale=1.0,  address = [33539]}
]


# # Process metrics using a Starlark script
[[processors.starlark]]
source = '''
Temps = {
'Temp_S01':0,
'Temp_S02':0,
'Temp_S03':0,
'Temp_S04':0,
'Temp_S05':0,
'Temp_S06':0,
'Temp_S07':0,
'Temp_S08':0,
'Temp_S09':0,
'Temp_S10':0,
'Temp_S11':0,
'Temp_S12':0,
'Temp_S13':0,
'Temp_S15':0,
'Leistung':0,
}
def apply(metric):
  for k, v in metric.fields.items():
if k in Temps:
metric.fields[k] = v / 10
  return metric
'''


Zuerst der Connect zum Modbus Device, dann das Auslesen der Register, und dann die Umrechnung mit Faktor 10 mit Starlak. Die Routine mit "Scale" innerhalb der Abfrage haben ich nicht hinbekommen, irgendwie hat da in einem Schritt die Conversion nicht funktioniert.

Und hier noch die alte Version über FHEM:

define Solvis ModbusAttr 1 60 192.168.178.55:502 TCP
setuuid Solvis 5f207d1e-f33f-b872-d98a-a55fc639f08dfe4b
attr Solvis userattr dev-h-defExpr dev-h-defLen dev-h-defUnpack dev-i-defLen dev-i-defUnpack obj-i33024-expr obj-i33024-poll obj-i33024-reading obj-i33025-expr obj-i33025-poll obj-i33025-reading obj-i33026-expr obj-i33026-poll obj-i33026-reading obj-i33027-expr obj-i33027-poll obj-i33027-reading obj-i33028-expr obj-i33028-poll obj-i33028-reading obj-i33029-expr obj-i33029-poll obj-i33029-reading obj-i33030-expr obj-i33030-poll obj-i33030-reading obj-i33031-expr obj-i33031-poll obj-i33031-reading obj-i33032-expr obj-i33032-poll obj-i33032-reading obj-i33033-expr obj-i33033-poll obj-i33033-reading obj-i33034-expr obj-i33034-poll obj-i33034-reading obj-i33035-expr obj-i33035-poll obj-i33035-reading obj-i33036-expr obj-i33036-poll obj-i33036-reading obj-i33038-expr obj-i33038-poll obj-i33038-reading obj-i33039-expr obj-i33039-poll obj-i33039-reading obj-i33040-expr obj-i33040-poll obj-i33040-reading obj-i33041-expr obj-i33041-poll obj-i33041-reading obj-i33539-expr obj-i33539-poll obj-i33539-reading
attr Solvis dev-h-defExpr ModbusLD_ScanFormat($hash, $val)
attr Solvis dev-h-defLen 1
attr Solvis dev-h-defUnpack a2
attr Solvis dev-i-defLen 1
attr Solvis dev-i-defUnpack s>
attr Solvis dev-timing-commDelay 1
attr Solvis dev-timing-sendDelay 1
attr Solvis dev-timing-serverTimeout 15
attr Solvis dev-timing-timeout 15
attr Solvis obj-i33024-expr $val / 10
attr Solvis obj-i33024-poll 1
attr Solvis obj-i33024-reading Temp_S01
attr Solvis obj-i33025-expr $val / 10
attr Solvis obj-i33025-poll 1
attr Solvis obj-i33025-reading Temp_S02
attr Solvis obj-i33026-expr $val / 10
attr Solvis obj-i33026-poll 1
attr Solvis obj-i33026-reading Temp_S03
attr Solvis obj-i33027-expr $val / 10
attr Solvis obj-i33027-poll 1
attr Solvis obj-i33027-reading Temp_S04
attr Solvis obj-i33028-expr $val / 10
attr Solvis obj-i33028-poll 1
attr Solvis obj-i33028-reading Temp_S05
attr Solvis obj-i33029-expr $val / 10
attr Solvis obj-i33029-poll 1
attr Solvis obj-i33029-reading Temp_S06
attr Solvis obj-i33030-expr $val / 10
attr Solvis obj-i33030-poll 1
attr Solvis obj-i33030-reading Temp_S07
attr Solvis obj-i33031-expr $val / 10
attr Solvis obj-i33031-poll 1
attr Solvis obj-i33031-reading Temp_S08
attr Solvis obj-i33032-expr $val / 10
attr Solvis obj-i33032-poll 1
attr Solvis obj-i33032-reading Temp_S09
attr Solvis obj-i33033-expr $val / 10
attr Solvis obj-i33033-poll 1
attr Solvis obj-i33033-reading Temp_S10
attr Solvis obj-i33034-expr $val / 10
attr Solvis obj-i33034-poll 1
attr Solvis obj-i33034-reading Temp_S11
attr Solvis obj-i33035-expr $val / 10
attr Solvis obj-i33035-poll 1
attr Solvis obj-i33035-reading Temp_S12
attr Solvis obj-i33036-expr $val / 10
attr Solvis obj-i33036-poll 1
attr Solvis obj-i33036-reading Temp_S13
attr Solvis obj-i33038-expr $val / 10
attr Solvis obj-i33038-poll 1
attr Solvis obj-i33038-reading Temp_S07
attr Solvis obj-i33039-expr $val / 10
attr Solvis obj-i33039-poll 1
attr Solvis obj-i33039-reading Temp_S07
attr Solvis obj-i33040-expr $val / 10
attr Solvis obj-i33040-poll 1
attr Solvis obj-i33040-reading Volumen_Strom_S17
attr Solvis obj-i33041-expr $val / 10
attr Solvis obj-i33041-poll 1
attr Solvis obj-i33041-reading Volumen_Strom_S18
attr Solvis obj-i33539-expr $val / 10
attr Solvis obj-i33539-poll 1
attr Solvis obj-i33539-reading Leistung
attr Solvis room 5_Keller,9.7_Therm
attr Solvis silentReconnect 1


Wie gesagt habe ich jetzt den Eindruck, dass FHEM deutlich runder läuft, nachdem ich meine Solvis. meine Solaranlage, einen Weatherman, einen Airsniffer und diverse Temperatursensoren über Influx ablege. Der Overhead durch FHEM fällt weg, und das Schreiben der Daten geht über die auf Zeitreihen optimierten Telegraf Tools. Immer noch alles auf dem gleichen Raspi. Was mir noch fehlt, sind retention Policies im Influx - kommt noch. Graphiken dann über Grafana und Einbindung über iframes.

vG Timmo