StefanW hat geschrieben: ↑Mi Apr 28, 2021 7:06 pm
frag doch mal den Hersteller ob er nicht eine Firmware-Version hat, welche zumindest das (häufige) Wechseln des Exponenten unterlässt. Weil mit mathematischen und zeitlichen Zusammenhängen zwischen verschiedenen Registern kommt kein Modbus Gateway gut zurecht. Genau dafür gibt es ja die Möglichkeit mehrere Register zusammenfassen zu können, damit man große Werte bei toller Auflösung übertragen kann.
Ich hab mir das nun mal bei der OpenWB im OpenSource Code angesehen wie es dort gelöst wurde, da ich mit dem Auslesen über die OpenWB bisher sehr stabile und stetige Verläufe hinbekommen habe (es kam dort nur hin und wieder zu "0" Werten bei Modbus Lesefehlern, aber nie zu diesen Zehnerpotenzsprüngen). Dort wird wohl genau deshalb immer zweimal der Scalefactor (Register 40084) ausgelesen (einmal vor und direkt nochmal nach dem umzurechnenden Wert in Register 40083) und dann nur im Falle daß beide Scalefactor Werte identisch sind der Wert tatsächlich verwendet/ausgegeben. Wenn Werte nicht identisch erfolgt keine Ausgabe und es bleibt beim letzten Wert...
Code: Alles auswählen
resp= client.read_holding_registers(40084,2,unit=slave1id)
multipli = resp.registers[0]
multiplint = format(multipli, '04x')
fmultiplint = int(struct.unpack('>h', multiplint.decode('hex'))[0])
respw= client.read_holding_registers(40083,2,unit=slave1id)
value1w = respw.registers[0]
allw = format(value1w, '04x')
rawprodw = finalw = int(struct.unpack('>h', allw.decode('hex'))[0]) * -1
resp= client.read_holding_registers(40084,2,unit=slave1id)
mult2ipli = resp.registers[0]
mult2iplint = format(mult2ipli, '04x')
fmult2iplint = int(struct.unpack('>h', mult2iplint.decode('hex'))[0])
if fmultiplint == fmult2iplint:
if fmultiplint == 0:
rawprodw = rawprodw
if fmultiplint == -1:
rawprodw = rawprodw / 10
if fmultiplint == -2:
rawprodw = rawprodw / 100
if fmultiplint == -3:
rawprodw = rawprodw / 1000
if fmultiplint == -4:
rawprodw = rawprodw / 10000
if fmultiplint == -5:
rawprodw = rawprodw /
if extprodakt == 1:
resp= client.read_holding_registers(40380,1,unit=slave1id)
value1 = resp.registers[0]
all = format(value1, '04x')
extprod = int(struct.unpack('>h', all.decode('hex'))[0]) * -1
else:
extprod = 0
rawprodw = rawprodw + extprod - storagepower
f = open('/var/www/html/openWB/ramdisk/pvwatt', 'w')
f.write(str(rawprodw))
f.close()
Ich würde das dann aufgrund der o.g. "Probleme" mit init und auch ggf. schnellen Wolken etc. nun auch hier mal versuchen umzusetzen, scheint mir ggf. einfacher zu sein...
@Robosoc / Sven: Trotzdem vielen, vielen Dank für Deinen Einsatz
Das hat mich zumindest nun wieder mal dazu gebracht die Customlogik mir anzusehen und zu verstehen. Vielleicht werde ich irgendwann dann doch mal "warm" mit dieser proprietären "Codierung"...
Mei, is des aber au kompliziert einen einfachen Leistungswert über dieses Sunspec Protokoll zu bekommen