Neues Modul für Geräte mit Modbus Schnittstelle über RS232 bzw. RS485

Begonnen von StefanStrobel, 12 Juli 2014, 14:50:22

Vorheriges Thema - Nächstes Thema

StefanStrobel

Hallo,

anbei eine neue Zwischen-Version zum Testen.
Ich habe das Connection-Handling generell überarbeitet und speziell bei Modbus-TCP sollte der Reconnect jetzt sauberer laufen.
Zudem gibt es ein neues Attribut textArg für definierte Sets (das wird dann bei ModbusAttr und anderen Modulen auf Basis von 98_Modbus.pm sichtbar). Damit kann man auch nicht numerische Werte als Set-Parameter übergeben. Um die weiterverarbeiten zu können muss dann natürlich ein passender unpack-String angegeben sein.

Als nächstes werde ich das Queue-Handling nochmal umbauen müssen, damit künftig auch Modbus-ASCII sinnvoll integriert werden kann und damit Sonderfälle einfacher möglich werden, die z.B. vor dem Lese / Schreiben erst ein anderes Register befüllen müssen.

Gruss
    Stefan


Bjoernar

Teste ich heute abend....danke schon mal.

Gesendet von meinem Moto G (4) mit Tapatalk


fhem_TS

Guten Abend, Stefan,

erstmal danke für die Arbeit. Könntest du das
ZitatZudem gibt es ein neues Attribut textArg für definierte Sets (das wird dann bei ModbusAttr und anderen Modulen auf Basis von 98_Modbus.pm sichtbar). Damit kann man auch nicht numerische Werte als Set-Parameter übergeben
bitte noch etwas genauer ausführen?

Ich habe folgendes define:
define Helios_KWL ModbusAttr 180 120 IP.ADRESSE TCP

und bei den Attributen finde ich nichts mit textArg.

Funktioniert das irgendwie über "map" ?


Danke schonmal vorab!

Gruß Tobias
fhem@RPi3
FS20 <-> Busware CUL
Homematic <-> HM-USB

eszych

Hallo Zusammen,
mit großem Interesse habe ich die Diskussion zum Thema RS485 / ModBus hier gelesen.
Ich habe seit kurzem eine PV mit SolarEdge Wechselrichtern und einer TESLA Batterie. Das System besteht aus einem 3-Phasen WR (WR-3) an dem die PV Module angeschlossen sind und einem 1-Phasen WR (WR-1) an dem die Batterie angeschlossen ist. WR-1 und WR-3 sind über einen RS485 Bus miteinander verbunden. WR-1, die Batterie und ein SolarEdge Modbus Ertragszähler sind über einen weiteren RS485 Bus verbunden. In diesen Bus habe ich ein Modbus TCP zu Modbus RTU Wandler gehängt - https://www.expertdaq.de/konverter/modbus-tcp-modbus-rtuascii/ex9132c-2-mtcp/
Das System hat zwei Modi: "TCP to RTU Slave" und "RTU to TCP Slave" welchen Modus muss ich nutzen, um Daten vom RS485 Bus mit dem Modul ModbusAttr abgreifen und die aktuellen Produktionswerte aus dem SolarEdge Wechselrichtern WR-1 auslesen zu können?

Danke für eure Hinweise!

Sonnige Grüße
Raspberry Pi 2 - FHEM 5.7
HM-LAN, HM-CFG-USB-2
HM-Sec-SCo, HM-Sec-SC-2, HM-TC-IT-WM-W-EU,
HM-LC-SW4-DR, HM-LC-Sw1-DR, HM-ES-PMSw1-DR,    
HM-ES-PMSw1-Pl - Rademacher Hompilot DuoFern

Bjoernar

Moin, hat leider nicht geholfen.
Hier die Ausgabe aus dem Log:

2016.08.18 09:10:20 3: Wechselrichter1: 6468 successive timeouts 2016.08.18 09:10:22 3: Wechselrichter1: 6469 successive timeouts 2016.08.18 09:10:24 3: Wechselrichter1: 6470 successive timeouts 2016.08.18 09:10:26 3: Wechselrichter1: 6471 successive timeouts 2016.08.18 09:10:28 3: Wechselrichter1: 6472 successive timeouts 2016.08.18 09:10:30 3: Wechselrichter1: 6473 successive timeouts 2016.08.18 09:10:31 3: Wechselrichter1: Send queue too long, dropping request 2016.08.18 09:10:31 3: Wechselrichter1: Send queue too long, dropping request 2016.08.18 09:10:31 3: Wechselrichter1: Send queue too long, dropping request 2016.08.18 09:10:31 3: Wechselrichter1: Send queue too long, dropping request 2016.08.18 09:10:31 3: Wechselrichter1: Send queue too long, dropping request 2016.08.18 09:10:31 3: Wechselrichter1: Send queue too long, dropping request 2016.08.18 09:10:31 3: Wechselrichter1: Send queue too long, dropping request 2016.08.18 09:10:34 3: Wechselrichter1: 6474 successive timeouts 2016.08.18 09:10:36 3: Wechselrichter1: 6475 successive timeouts 2016.08.18 09:10:38 3: Wechselrichter1: 6476 successive timeouts

Gesendet von meinem Moto G (4) mit Tapatalk


Bjoernar

Wiederholt sich immer so weiter.

Gesendet von meinem Moto G (4) mit Tapatalk


StefanStrobel

Hallo Björnar,

Auch wenn Dein Log-Auszug leider nicht mit verbose 5 gemacht wurde, sieht es doch so aus, als ob das Attribut

maxTimeoutsToReconnect

nicht gesetzt ist. Ich würde es immer auf 2 oder 3 setzen. Ohne das Attribut verwendet Fhem die normalen Mechanismen des Betriebssystems zum Erkennen, ob eine TCP-Verbindung tatsächlich noch offen ist. In Deinem Fall scheint ja die Verbindung im Netzwerk gekappt zu werden und Fhem bekommt daher nicht mit dass die TCP-Verbindung nicht mehr da ist.

Für solche Fälle hatte ich das maxTimeoutsToReconnect in das Modbus-Modul eingebaut. Das setzt dann nach der angegebenen Zahl von aufeinanderfolgemden Timeouts das Device auf "disconnected" und Fhem versucht dann die Verbindung wieder neu aufzubauen.

Gruss
   Stefan

StefanStrobel

Hallo eszych,

Das sollte in dem Handbuch zu Deinem Konverter stehen. Ich tippe auf TCP zu RTU. Könnte aber auch anders herum gemeint sein.

Gruss
   Stefan

StefanStrobel

Hallo Tobias,

textArg bezieht sich auf die Objekt-spezifischen Attribute.
z.B.

dev-h-defPoll 1
obj-h100-reading test
obj-h100-showGet 1

würde ein Holding-Register mit Adresse 100 pollen lassen und als get bereitstellen.
Ebenso kann man Objekte per set schreiben lassen

obj-h101-reading ziel
obj-h101-set 1
obj-h101-textArg 1
obj-h101-unpack a


textArg erlaubt dann die Übergabe von nicht numerischen Werten beim set.

Leider hat aber textArg in der bisher geposteten Version noch in der Attributliste gefehlt. Mit userattr hätte man es freischalten können, aber so war das nicht gedacht ;-)
Anbei ein update.

Gruss
    Stefan

pejonp

Zitat von: eszych am 17 August 2016, 01:37:47
...
Ich habe seit kurzem eine PV mit SolarEdge Wechselrichtern und einer TESLA Batterie. Das System besteht aus einem 3-Phasen WR (WR-3) an dem die PV Module angeschlossen sind und einem 1-Phasen WR (WR-1) an dem die Batterie angeschlossen ist. WR-1 und WR-3 sind über einen RS485 Bus miteinander verbunden. WR-1, die Batterie und ein SolarEdge Modbus Ertragszähler sind über einen weiteren RS485 Bus verbunden. In diesen Bus habe ich ein Modbus TCP zu Modbus RTU Wandler gehängt....
Hallo eszych,

ich habe ein SE5000K. Am RS485-1 Anschluß habe ich einen RS-485 Adapter. Damit diese Schnittstelle vom hier beschriebenen ModBus.pm gelesen werden kann, musste ich das Protokoll auf "Nicht-SE Logger" einstellen. Das SolarEdge Master/Slave Protokoll sendet noch einen Header von 0x12345679 (siehe auch hier https://github.com/jbuehl/solaredge/issues/8#issuecomment-177584301) und wird somit nicht erkannt.

Kommunikation  RS485-1 Konf
 RS485-1 Konf  Gerätetyp  Nicht-SE Logger
 RS485-1 Konf  Protokoll  SunSpec
 RS485-1 Konf  Geräte-ID und geben Sie dort die MODBUS-Adresse ein (ein eindeutiger Wert zwischen 1...247). Dies wird das Register C_Geräteadresse festlegen.

pejonp
LaCrossGW 868MHz:WT470+TFA+TX37-IT+EMT7110+W136+WH25A HP1003+WH2621
SignalD(CC1101):Bresser+WS-0101(868MHz WH1080)+Velux KLF200+MAX!+HM-MOD-UART:Smoke HM-SEC-SD+VITOSOLIC 200 RESOL VBUS-LAN+SolarEdge SE5K(Modbus)+Sonnen!eco8(10kWh)+TD3511+DRT710M(Modbus)+ZigBee+Z-Wave+MQTT+vitoconnect

fhem_TS

Hallo Stefan,

das mit userAttr habe ich gestern noch hinbekommen, also lief es soweit schonmal.
Jetzt habe ich folgendes Phänomen:
Ich kann die Anlage nur einmal über den Set Befehl auslesen:
2016.08.22 10:33:05 5: Helios_KWL: Set: key for Register = h1
2016.08.22 10:33:05 5: Helios_KWL: Set: found option Register (h1), setVal = v00105
2016.08.22 10:33:05 4: Helios_KWL: Send called with h 1 len 16 / span - to id 180, queue has 0 requests
2016.08.22 10:33:05 4: Helios_KWL: Send queues fcode 16 for h 1 (Register), len / span 16 : 007e0000000db4100001001020763030313035 pdu 100001001020763030313035, force
2016.08.22 10:33:05 4: Helios_KWL: sends 007e0000000db4100001001020763030313035 (fcode 16 to 180, tid 126 for Register (1), len 16)
2016.08.22 10:33:05 5: SW: 007e0000000db4100001001020763030313035
2016.08.22 10:33:05 5: Helios_KWL: ReadAnswer called and remaining timeout is 1.99864792823792 requested reading is Register
2016.08.22 10:33:05 5: ReadAnswer got: 007e00000006b41000010010
2016.08.22 10:33:05 5: Helios_KWL: ParseFrames got: 007e00000006b41000010010
2016.08.22 10:33:05 4: Helios_KWL: ParseFrames: fcode 16 from 180, tid 126, data 00010010 expect 16 from 180, tid 126 for module Helios_KWL
2016.08.22 10:33:05 5: Helios_KWL: ParseFrames done, reply to fcode 16, 16 objects written
2016.08.22 10:33:05 5: Helios_KWL: ReadAnswer done
2016.08.22 10:33:05 5: Helios_KWL: Set: sending read after write
2016.08.22 10:33:05 4: Helios_KWL: Send called with h 1 len 16 / span - to id 180, queue has 0 requests
2016.08.22 10:33:05 4: Helios_KWL: Send queues fcode 3 for h 1 (Register), len / span 16 : 00a600000006b40300010010 pdu 0300010010, force
2016.08.22 10:33:05 4: Helios_KWL: CheckDelay commDelay for Helios_KWL not over, sleep 0.0913798809051514 forced
2016.08.22 10:33:05 4: Helios_KWL: CheckDelay sendDelay for Helios_KWL not over, sleep 0.0744318962097168 forced
2016.08.22 10:33:05 4: Helios_KWL: sends 00a600000006b40300010010 (fcode 3 to 180, tid 166 for Register (1), len 16)
2016.08.22 10:33:05 5: SW: 00a600000006b40300010010
2016.08.22 10:33:05 5: Helios_KWL: ReadAnswer called and remaining timeout is 1.99872303009033 requested reading is Register
2016.08.22 10:33:05 5: ReadAnswer got: 00a600000023b403207630303130353d32302e36000000000000000000000000000000000000000000
2016.08.22 10:33:05 5: Helios_KWL: ParseFrames got: 00a600000023b403207630303130353d32302e36000000000000000000000000000000000000000000
2016.08.22 10:33:05 4: Helios_KWL: ParseFrames: fcode 3 from 180, tid 166, data 207630303130353d32302e36000000000000000000000000000000000000000000 expect 3 from 180, tid 166 for module Helios_KWL
2016.08.22 10:33:05 5: Helios_KWL: ParseObj called with 7630303130353d32302e36000000000000000000000000000000000000000000 and start 1
2016.08.22 10:33:05 5: Helios_KWL: ParseObj ObjInfo: reading=Register, unpack=(a*), expr=, format=%.20s, map=
2016.08.22 10:33:05 5: Helios_KWL: ParseObj for Register does sprintf with format %.20s value is v00105=20.6
2016.08.22 10:33:05 5: Helios_KWL: ParseObj for Register sprintf result is v00105=20.6
2016.08.22 10:33:05 4: Helios_KWL: ParseObj for Register assigns v00105=20.6
2016.08.22 10:33:05 5: Helios_KWL: ParseFrames done, reply to fCode 3, 1 readings
2016.08.22 10:33:05 5: Helios_KWL: ReadAnswer done


Bein zweiten Versuch bekomme ich einen Fehler obwohl ich nur einen Wert geändert habe (von v00105 auf v00106):
2016.08.22 10:33:12 5: Helios_KWL: Set: key for Register = h1
2016.08.22 10:33:12 5: Helios_KWL: Set: found option Register (h1), setVal = v00106
2016.08.22 10:33:12 4: Helios_KWL: Send called with h 1 len 16 / span - to id 180, queue has 0 requests
2016.08.22 10:33:12 4: Helios_KWL: Send queues fcode 16 for h 1 (Register), len / span 16 : 000f0000000db4100001001020763030313036 pdu 100001001020763030313036, force
2016.08.22 10:33:12 4: Helios_KWL: sends 000f0000000db4100001001020763030313036 (fcode 16 to 180, tid 15 for Register (1), len 16)
2016.08.22 10:33:12 5: SW: 000f0000000db4100001001020763030313036
2016.08.22 10:33:12 5: Helios_KWL: ReadAnswer called and remaining timeout is 1.99873399734497 requested reading is Register
2016.08.22 10:33:13 5: ReadAnswer got: 000f00000003b49003
2016.08.22 10:33:13 5: Helios_KWL: ParseFrames got: 000f00000003b49003
2016.08.22 10:33:13 4: Helios_KWL: ParseFrames: fcode 144 from 180, tid 15, data 03 expect 16 from 180, tid 15 for module Helios_KWL
2016.08.22 10:33:13 5: Helios_KWL: ParseFrames got error code 90 / 03, illegal data value
2016.08.22 10:33:13 5: Helios_KWL: ReadAnswer done, err = got exception code 90 / 03, illegal data value


Nun muß ich die Anlage einmal über ModPoll ansprechen (das funktioniert weiterhin) und dann kann ich wieder einmal einen Wert auslesen.
Hast du dafür auch irgendeine Erklärung?

P.S. Der Test ist nicht mit der aktuellen Version aus deinem Beitrag vom 20.08 gemacht.

Danke und Gruß
Tobias
fhem@RPi3
FS20 <-> Busware CUL
Homematic <-> HM-USB

StefanStrobel

Hallo Tobias,

das ist schon seltsam.
Das einzige was mir aufgefallen ist, ist dass in der Hersteller-Doku der gesendete String am Ende ein \0 haben muss. Das sendest Du momentan nicht mit. Evt. liegt es daran.
Um das anzuhängen könntest Du das setexpr Attribut verwenden um an $val ein Nullzeichen anzufügen. Im Debug-Log solltest Du das dann auch in der gesendeten PDU sehen.

Gruss
    Stefan

pejonp

Hallo,

hier ist diese Umwandlung auch schon einmal aufgegriffen worden (https://forum.fhem.de/index.php/topic,46944.msg396977.html#msg396977).
Hier sieht es aus als wenn der String richtig in ASCII umgewandel wurde:

2016.08.22 10:33:05 5: Helios_KWL: ParseObj called with 7630303130353d32302e36000000000000000000000000000000000000000000 and start 1
2016.08.22 10:33:05 5: Helios_KWL: ParseObj ObjInfo: reading=Register, unpack=(a*), expr=, format=%.20s, map=
2016.08.22 10:33:05 5: Helios_KWL: ParseObj for Register does sprintf with format %.20s value is v00105=20.6
2016.08.22 10:33:05 5: Helios_KWL: ParseObj for Register sprintf result is v00105=20.6
2016.08.22 10:33:05 4: Helios_KWL: ParseObj for Register assigns v00105=20.6

v00105=20.6 -> 7630303130353d3232302e36

jetzt könnte man sich den v00106=??  ansehen.
Vielleicht hilft das weiter.

pejonp

PS: - funktioniert die Abfrage über modbuspoll.exe ?
LaCrossGW 868MHz:WT470+TFA+TX37-IT+EMT7110+W136+WH25A HP1003+WH2621
SignalD(CC1101):Bresser+WS-0101(868MHz WH1080)+Velux KLF200+MAX!+HM-MOD-UART:Smoke HM-SEC-SD+VITOSOLIC 200 RESOL VBUS-LAN+SolarEdge SE5K(Modbus)+Sonnen!eco8(10kWh)+TD3511+DRT710M(Modbus)+ZigBee+Z-Wave+MQTT+vitoconnect

fhem_TS

Hallo Stefan, hallo pejonp,

ZitatDas einzige was mir aufgefallen ist, ist dass in der Hersteller-Doku der gesendete String am Ende ein \0 haben muss.

Das war der entscheidende Hinweis.

Nachdem ich
obj-h1-setexpr ($val."\0")
ergänzt habe scheint jetzt alles zu funktionieren.

Ich werde jetzt mal meine Steuerung umstellen und testen.

Tausend Dank!

Gruß Tobias
fhem@RPi3
FS20 <-> Busware CUL
Homematic <-> HM-USB

eszych

Hallo pejonp,

danke für deine Antwort - irgendwie wurde ich vom Forum nicht informiert, daher erst jetzt eine Rückmeldung...

Das Dokument von SolarEdge kannte ich schon, aber ich möchte nichts in der Kommunikationseinstellung auf den RS485 Bussen ändern, da darüber auch ein Stromzähler eingebunden ist...
Ich habe aber herausgefunden, dass sich auf den Netzwerkinterfaces einach TCP-Modbus aktivieren lässt und die Wechselrichter sich dann mit Hilfe des Moduls "ModbusAttr" auslessen lassen.
Das hattest Du schon in einem anderen Post beschrieben und ich habe es leicht abgewandelt für meine Anlage übernommen.
Leider kann ich mit den Werten nicht so besonders viel Anfangen, denn irgendwie passen die Werte, die ich mit FHEM bekomme nicht mit den Werten aus dem Monitoring-Portal zusammen...

Für alle Insterssierten hier nochmal die leicht abgewandelte Konfig - nicht vergessen das Perl Modul Math::Round zu installieren!!!
########################
## Define 1-Phase PWP ##
########################
define PWP1 ModbusAttr 1 90 192.168.178.181:502 TCP
attr PWP1 userattr dev-h-combine dev-h-defPoll obj-h100-reading obj-h101-reading obj-h103-expr obj-h103-format obj-h103-reading obj-h107-map obj-h107-reading obj-h68-expr obj-h68-reading obj-h69-expr obj-h69-reading obj-h70-expr obj-h70-reading obj-h71-reading obj-h72-reading obj-h75-reading obj-h83-reading obj-h84-expr obj-h84-reading obj-h85-expr obj-h85-reading obj-h86-expr obj-h86-reading obj-h87-expr obj-h87-reading obj-h88-expr obj-h88-reading obj-h89-expr obj-h89-reading obj-h90-expr obj-h90-reading obj-h91-expr obj-h91-reading obj-h92-expr obj-h92-reading obj-h93-expr obj-h93-format obj-h93-len obj-h93-reading obj-h93-unpack obj-h95-expr obj-h95-reading obj-h96-expr obj-h96-reading obj-h97-expr obj-h97-reading obj-h98-expr obj-h98-reading obj-h99-expr obj-h99-reading verbose
attr PWP1 dev-h-combine 50
attr PWP1 dev-h-defPoll 1
attr PWP1 obj-h100-reading PWP1_I_DC_Leistung_W
attr PWP1 obj-h101-reading PWP1_I_DC_Leistung_SF
attr PWP1 obj-h103-expr $val / 100
attr PWP1 obj-h103-format %.f
attr PWP1 obj-h103-reading PWP1_Temp_Kuehler_C
attr PWP1 obj-h107-map 1:Aus, 2:Nachtmodus, 4:WR_An
attr PWP1 obj-h107-reading PWP1_C_Status
attr PWP1 obj-h68-expr $val
attr PWP1 obj-h68-reading PWP1_C_Geraeteadresse
attr PWP1 obj-h69-expr $val
attr PWP1 obj-h69-reading PWP1_C_SunSpec_DID
attr PWP1 obj-h70-expr $val
attr PWP1 obj-h70-reading PWP1_C_SunSpec_Laenge
attr PWP1 obj-h71-reading PWP1_I_AC_Strom_A
attr PWP1 obj-h72-reading PWP1_I_AC_StromL1_A
attr PWP1 obj-h75-reading PWP1_I_AC_Strom_SF
attr PWP1 obj-h83-reading PWP1_I_AC_Leistung_W
attr PWP1 obj-h84-expr $val
attr PWP1 obj-h84-reading PWP1_I_AC_Leistung_SF
attr PWP1 obj-h85-expr $val
attr PWP1 obj-h85-reading PWP1_I_AC_Frequenz_Hz
attr PWP1 obj-h86-expr $val
attr PWP1 obj-h86-reading PWP1_I_AC_Frequenz_SF
attr PWP1 obj-h87-expr $val
attr PWP1 obj-h87-reading PWP1_I_AC_VA
attr PWP1 obj-h88-expr $val
attr PWP1 obj-h88-reading PWP1_I_AC_VA_SF
attr PWP1 obj-h89-expr $val
attr PWP1 obj-h89-reading PWP1_I_AC_VAR
attr PWP1 obj-h90-expr $val
attr PWP1 obj-h90-reading PWP1_I_AC_VAR_SF
attr PWP1 obj-h91-expr $val
attr PWP1 obj-h91-reading PWP1_I_AC_PF_Prozent
attr PWP1 obj-h92-expr $val
attr PWP1 obj-h92-reading PWP1_I_AC_PF_SF
attr PWP1 obj-h93-expr $val / 1000
attr PWP1 obj-h93-format %.2f
attr PWP1 obj-h93-len 2
attr PWP1 obj-h93-reading PWP1_I_AC_Energie_WH_kWh
attr PWP1 obj-h93-unpack l>
attr PWP1 obj-h95-expr $val
attr PWP1 obj-h95-reading PWP1_I_AC_Energie_WH_SF
attr PWP1 obj-h96-expr $val
attr PWP1 obj-h96-reading PWP1_I_DC_Strom_A
attr PWP1 obj-h97-expr $val
attr PWP1 obj-h97-reading PWP1_I_DC_Strom_SF
attr PWP1 obj-h98-expr $val
attr PWP1 obj-h98-reading PWP1_I_DC_Spannung_V
attr PWP1 obj-h99-expr $val
attr PWP1 obj-h99-reading PWP1_I_DC_Spannung_SF
attr PWP1 room Solar
attr PWP1 verbose 1

########################
define PWP1_I_AC_Frequenz_Hz dummy
attr PWP1_I_AC_Frequenz_Hz room Solar

########################
define PWP1_AC_Frequenz_WR notify PWP1:PWP1_I_AC_Frequenz_Hz.* {\
use Math::Round qw/nearest/;;\
    my $a = ReadingsVal("PWP1","PWP1_I_AC_Frequenz_Hz",0) ;; \
    my $b = ReadingsVal("PWP1","PWP1_I_AC_Frequenz_SF",0) ;; \
    my $beginn = 65536;; \
    my $vv = $beginn - $b;;  \
    if ($vv==6){$vv=1000000;;} elsif($vv == 5){$vv=100000;;}elsif($vv == 4){$vv=10000;;}elsif($vv == 3){$vv=1000;;} elsif($v($vv == 2){$vv=100;;}elsif($vv == 1 ){$vv=10;;}else{$vv=1;;};; \
    my $sum1 = nearest(0.001, $a/$vv);; \
    my $text = "$sum1" ;; \
    fhem ("set PWP1_I_AC_Frequenz_Hz $text") ;; \
    };;
attr PWP1_AC_Frequenz_WR room Solar

########################
define PWP1_I_DC_Leistung_W dummy
attr PWP1_I_DC_Leistung_W room Solar

########################
define PWP1_DC_Leistung_WR notify PWP1:PWP1_I_DC_Leistung_W.* {\
use Math::Round qw/nearest/;;\
    my $a = ReadingsVal("PWP1","PWP1_I_DC_Leistung_W",0) ;; \
    my $b = ReadingsVal("PWP1","PWP1_I_DC_Leistung_SF",0) ;; \
    my $beginn = 65536;; \
    my $vv = $beginn - $b;;  \
    if ($vv==6){$vv=1000000;;} elsif($vv == 5){$vv=100000;;}elsif($vv == 4){$vv=10000;;}elsif($vv == 3){$vv=1000;;} elsif($vv == 2){$vv=100;;}elsif($vv == 1 ){$vv=10;;}else{$vv=1;;};; \
    my $sum1 = nearest(0.001, $a/$vv);; \
    my $text = "$sum1" ;; \
    fhem ("set PWP1_I_DC_Leistung_W $text") ;; \
    };;
attr PWP1_DC_Leistung_WR room Solar

########################
define PWP1_I_DC_Strom_A dummy
attr PWP1_I_DC_Strom_A room Solar

########################
define PWP1_DC_Strom_WR notify PWP1:PWP1_I_DC_Strom_A.* {\
use Math::Round qw/nearest/;; \
    my $a = ReadingsVal("PWP1","PWP1_I_DC_Strom_A",0) ;; \
    my $b = ReadingsVal("PWP1","PWP1_I_DC_Strom_SF",0) ;; \
    my $beginn = 65536;; \
    my $vv = $beginn - $b;;  \
    if ($vv==6){$vv=1000000;;} elsif($vv == 5){$vv=100000;;}elsif($vv == 4){$vv=10000;;}elsif($vv == 3){$vv=1000;;} elsif($vv == 2){$vv=100;;}elsif($vv == 1 ){$vv=10;;}else{$vv=1;;};; \
    my $sum1 = nearest(0.001, $a/$vv);; \
    my $text = "$sum1" ;; \
    fhem ("set PWP1_I_DC_Strom_A $text") ;; \
    };;
attr PWP1_DC_Strom_WR room Solar

########################
define PWP1_I_AC_Leistung_W dummy
attr PWP1_I_AC_Leistung_W room Solar

########################
define PWP1_AC_Leistung_WR notify PWP1:PWP1_I_AC_Leistung_W.* {\
use Math::Round qw/nearest/;;\
    my $a = ReadingsVal("PWP1","PWP1_I_AC_Leistung_W",0) ;; \
    my $b = ReadingsVal("PWP1","PWP1_I_AC_Leistung_SF",0) ;; \
    my $beginn = 65536;; \
    my $vv = $beginn - $b;;  \
    if ($vv==6){$vv=1000000;;} elsif($vv == 5){$vv=100000;;} elsif($vv == 4){$vv=10000;;} elsif($vv == 3){$vv=1000;;} elsif($vv == 2){$vv=100;;} elsif($vv == 1 ){$vv=10;;} else{$vv=1;;};; \
    my $sum1 = nearest(0.001, $a/$vv);; \
    my $text = "$sum1" ;; \
    fhem ("set PWP1_I_AC_Leistung_W $text") ;; \
    };;
attr PWP1_AC_Leistung_WR room Solar

########################
define PWP1_I_AC_StromL1_A dummy
attr PWP1_I_AC_StromL1_A room Solar

########################
define PWP1_I_AC_Strom_A dummy
attr PWP1_I_AC_Strom_A room Solar

########################
define PWP1_AC_Strom_WR notify PWP1:PWP1_I_AC_Strom_A.* {\
use Math::Round qw/nearest/;;\
    my $a = ReadingsVal("PWP1","PWP1_I_AC_Strom_A",0) ;; \
    my $a1 = ReadingsVal("PWP1","PWP1_I_AC_StromL1_A",0) ;; \
    my $b = ReadingsVal("PWP1","PWP1_I_AC_Strom_SF",0) ;; \
    my $beginn = 65536;; \
    my $vv = $beginn - $b;;  \
    if ($vv==6){$vv=1000000;;} elsif($vv == 5){$vv=100000;;}elsif($vv == 4){$vv=10000;;}elsif($vv == 3){$vv=1000;;} elsif($vv == 2){$vv=100;;}elsif($vv == 1 ){$vv=10;;}else{$vv=1;;};; \
    my $sum1 = nearest(0.001, $a/$vv);; \
    my $text = "$sum1" ;; \
    fhem ("set PWP1_I_AC_Strom_A $text") ;; \
    $sum1 = nearest(0.001, $a1/$vv);; \
    $text = "$sum1" ;; \
    fhem ("set PWP1_I_AC_StromL1_A $text") ;; \
    };;
attr PWP1_AC_Strom_WR room Solar

########################
## Define 3 Phase PWP ##
########################
define PWP3 ModbusAttr 1 90 192.168.178.182:502 TCP
attr PWP3 userattr dev-h-combine dev-h-defPoll obj-h100-reading obj-h101-reading obj-h103-expr obj-h103-format obj-h103-reading obj-h107-map obj-h107-reading obj-h68-expr obj-h68-reading obj-h69-expr obj-h69-reading obj-h70-expr obj-h70-reading obj-h71-reading obj-h72-reading obj-h73-reading obj-h74-reading obj-h75-reading obj-h83-reading obj-h84-expr obj-h84-reading obj-h85-expr obj-h85-reading obj-h86-expr obj-h86-reading obj-h87-expr obj-h87-reading obj-h88-expr obj-h88-reading obj-h89-expr obj-h89-reading obj-h90-expr obj-h90-reading obj-h91-expr obj-h91-reading obj-h92-expr obj-h92-reading obj-h93-expr obj-h93-format obj-h93-len obj-h93-reading obj-h93-unpack obj-h95-expr obj-h95-reading obj-h96-expr obj-h96-reading obj-h97-expr obj-h97-reading obj-h98-expr obj-h98-reading obj-h99-expr obj-h99-reading verbose
attr PWP3 dev-h-combine 50
attr PWP3 dev-h-defPoll 1
attr PWP3 obj-h100-reading PWP3_I_DC_Leistung_W
attr PWP3 obj-h101-reading PWP3_I_DC_Leistung_SF
attr PWP3 obj-h103-expr $val / 100
attr PWP3 obj-h103-format %.f
attr PWP3 obj-h103-reading PWP3_Temp_Kuehler_C
attr PWP3 obj-h107-map 1:Aus, 2:Nachtmodus, 4:WR_An
attr PWP3 obj-h107-reading PWP3_C_Status
attr PWP3 obj-h68-expr $val
attr PWP3 obj-h68-reading PWP3_C_Geraeteadresse
attr PWP3 obj-h69-expr $val
attr PWP3 obj-h69-reading PWP3_C_SunSpec_DID
attr PWP3 obj-h70-expr $val
attr PWP3 obj-h70-reading PWP3_C_SunSpec_Laenge
attr PWP3 obj-h71-reading PWP3_I_AC_Strom_A
attr PWP3 obj-h72-reading PWP3_I_AC_StromL1_A
attr PWP3 obj-h73-reading PWP3_I_AC_StromL2_A
attr PWP3 obj-h74-reading PWP3_I_AC_StromL3_A
attr PWP3 obj-h75-reading PWP3_I_AC_Strom_SF
attr PWP3 obj-h83-reading PWP3_I_AC_Leistung_W
attr PWP3 obj-h84-expr $val
attr PWP3 obj-h84-reading PWP3_I_AC_Leistung_SF
attr PWP3 obj-h85-expr $val
attr PWP3 obj-h85-reading PWP3_I_AC_Frequenz_Hz
attr PWP3 obj-h86-expr $val
attr PWP3 obj-h86-reading PWP3_I_AC_Frequenz_SF
attr PWP3 obj-h87-expr $val
attr PWP3 obj-h87-reading PWP3_I_AC_VA
attr PWP3 obj-h88-expr $val
attr PWP3 obj-h88-reading PWP3_I_AC_VA_SF
attr PWP3 obj-h89-expr $val
attr PWP3 obj-h89-reading PWP3_I_AC_VAR
attr PWP3 obj-h90-expr $val
attr PWP3 obj-h90-reading PWP3_I_AC_VAR_SF
attr PWP3 obj-h91-expr $val
attr PWP3 obj-h91-reading PWP3_I_AC_PF_Prozent
attr PWP3 obj-h92-expr $val
attr PWP3 obj-h92-reading PWP3_I_AC_PF_SF
attr PWP3 obj-h93-expr $val / 1000
attr PWP3 obj-h93-format %.2f
attr PWP3 obj-h93-len 2
attr PWP3 obj-h93-reading PWP3_I_AC_Energie_WH_kWh
attr PWP3 obj-h93-unpack l>
attr PWP3 obj-h95-expr $val
attr PWP3 obj-h95-reading PWP3_I_AC_Energie_WH_SF
attr PWP3 obj-h96-expr $val
attr PWP3 obj-h96-reading PWP3_I_DC_Strom_A
attr PWP3 obj-h97-expr $val
attr PWP3 obj-h97-reading PWP3_I_DC_Strom_SF
attr PWP3 obj-h98-expr $val
attr PWP3 obj-h98-reading PWP3_I_DC_Spannung_V
attr PWP3 obj-h99-expr $val
attr PWP3 obj-h99-reading PWP3_I_DC_Spannung_SF
attr PWP3 room Solar
attr PWP3 verbose 1

########################
define PWP3_I_AC_Frequenz_Hz dummy
attr PWP3_I_AC_Frequenz_Hz room Solar

########################
define PWP3_AC_Frequenz_WR notify PWP3:PWP3_I_AC_Frequenz_Hz.* {\
use Math::Round qw/nearest/;;\
    my $a = ReadingsVal("PWP3","PWP3_I_AC_Frequenz_Hz",0) ;; \
    my $b = ReadingsVal("PWP3","PWP3_I_AC_Frequenz_SF",0) ;; \
    my $beginn = 65536;; \
    my $vv = $beginn - $b;;  \
    if ($vv==6){$vv=1000000;;} elsif($vv == 5){$vv=100000;;}elsif($vv == 4){$vv=10000;;}elsif($vv == 3){$vv=1000;;} elsif($v($vv == 2){$vv=100;;}elsif($vv == 1 ){$vv=10;;}else{$vv=1;;};; \
    my $sum1 = nearest(0.001, $a/$vv);; \
    my $text = "$sum1" ;; \
    fhem ("set PWP3_I_AC_Frequenz_Hz $text") ;; \
    };;
attr PWP3_AC_Frequenz_WR room Solar

########################
define PWP3_I_DC_Leistung_W dummy
attr PWP3_I_DC_Leistung_W room Solar

########################
define PWP3_DC_Leistung_WR notify PWP3:PWP3_I_DC_Leistung_W.* {\
use Math::Round qw/nearest/;;\
    my $a = ReadingsVal("PWP3","PWP3_I_DC_Leistung_W",0) ;; \
    my $b = ReadingsVal("PWP3","PWP3_I_DC_Leistung_SF",0) ;; \
    my $beginn = 65536;; \
    my $vv = $beginn - $b;;  \
    if ($vv==6){$vv=1000000;;} elsif($vv == 5){$vv=100000;;}elsif($vv == 4){$vv=10000;;}elsif($vv == 3){$vv=1000;;} elsif($vv == 2){$vv=100;;}elsif($vv == 1 ){$vv=10;;}else{$vv=1;;};; \
    my $sum1 = nearest(0.001, $a/$vv);; \
    my $text = "$sum1" ;; \
    fhem ("set PWP3_I_DC_Leistung_W $text") ;; \
    };;
attr PWP3_DC_Leistung_WR room Solar

########################
define PWP3_I_DC_Strom_A dummy
attr PWP3_I_DC_Strom_A room Solar

########################
define PWP3_DC_Strom_WR notify PWP3:PWP3_I_DC_Strom_A.* {\
use Math::Round qw/nearest/;; \
    my $a = ReadingsVal("PWP3","PWP3_I_DC_Strom_A",0) ;; \
    my $b = ReadingsVal("PWP3","PWP3_I_DC_Strom_SF",0) ;; \
    my $beginn = 65536;; \
    my $vv = $beginn - $b;;  \
    if ($vv==6){$vv=1000000;;} elsif($vv == 5){$vv=100000;;}elsif($vv == 4){$vv=10000;;}elsif($vv == 3){$vv=1000;;} elsif($vv == 2){$vv=100;;}elsif($vv == 1 ){$vv=10;;}else{$vv=1;;};; \
    my $sum1 = nearest(0.001, $a/$vv);; \
    my $text = "$sum1" ;; \
    fhem ("set PWP3_I_DC_Strom_A $text") ;; \
    };;
attr PWP3_DC_Strom_WR room Solar

########################
define PWP3_I_AC_Leistung_W dummy
attr PWP3_I_AC_Leistung_W room Solar

########################
define PWP3_AC_Leistung_WR notify PWP3:PWP3_I_AC_Leistung_W.* {\
use Math::Round qw/nearest/;;\
    my $a = ReadingsVal("PWP3","PWP3_I_AC_Leistung_W",0) ;; \
    my $b = ReadingsVal("PWP3","PWP3_I_AC_Leistung_SF",0) ;; \
    my $beginn = 65536;; \
    my $vv = $beginn - $b;;  \
    if ($vv==6){$vv=1000000;;} elsif($vv == 5){$vv=100000;;} elsif($vv == 4){$vv=10000;;} elsif($vv == 3){$vv=1000;;} elsif($vv == 2){$vv=100;;} elsif($vv == 1 ){$vv=10;;} else{$vv=1;;};; \
    my $sum1 = nearest(0.001, $a/$vv);; \
    my $text = "$sum1" ;; \
    fhem ("set PWP3_I_AC_Leistung_W $text") ;; \
    };;
attr PWP3_AC_Leistung_WR room Solar

########################
define PWP3_I_AC_StromL1_A dummy
attr PWP3_I_AC_StromL1_A room Solar

########################
define PWP3_I_AC_StromL2_A dummy
attr PWP3_I_AC_StromL2_A room Solar

########################
define PWP3_I_AC_StromL3_A dummy
attr PWP3_I_AC_StromL3_A room Solar

########################
define PWP3_I_AC_Strom_A dummy
attr PWP3_I_AC_Strom_A room Solar

########################
define PWP3_AC_Strom_WR notify PWP3:PWP3_I_AC_Strom_A.* {\
use Math::Round qw/nearest/;;\
    my $a = ReadingsVal("PWP3","PWP3_I_AC_Strom_A",0) ;; \
    my $a1 = ReadingsVal("PWP3","PWP3_I_AC_StromL1_A",0) ;; \
    my $a2 = ReadingsVal("PWP3","PWP3_I_AC_StromL2_A",0) ;; \
    my $a3 = ReadingsVal("PWP3","PWP3_I_AC_StromL3_A",0) ;; \
    my $b = ReadingsVal("PWP3","PWP3_I_AC_Strom_SF",0) ;; \
    my $beginn = 65536;; \
    my $vv = $beginn - $b;;  \
    if ($vv==6){$vv=1000000;;} elsif($vv == 5){$vv=100000;;}elsif($vv == 4){$vv=10000;;}elsif($vv == 3){$vv=1000;;} elsif($vv == 2){$vv=100;;}elsif($vv == 1 ){$vv=10;;}else{$vv=1;;};; \
    my $sum1 = nearest(0.001, $a/$vv);; \
    my $text = "$sum1" ;; \
    fhem ("set PWP3_I_AC_Strom_A $text") ;; \
    $sum1 = nearest(0.001, $a1/$vv);; \
    $text = "$sum1" ;; \
    fhem ("set PWP3_I_AC_StromL1_A $text") ;; \
    $sum1 = nearest(0.001, $a2/$vv);; \
    $text = "$sum1" ;; \
    fhem ("set PWP3_I_AC_StromL2_A $text") ;; \
    $sum1 = nearest(0.001, $a3/$vv);; \
    $text = "$sum1" ;; \
    fhem ("set PWP3_I_AC_StromL3_A $text") ;; \
    }
attr PWP3_AC_Strom_WR room Solar
Raspberry Pi 2 - FHEM 5.7
HM-LAN, HM-CFG-USB-2
HM-Sec-SCo, HM-Sec-SC-2, HM-TC-IT-WM-W-EU,
HM-LC-SW4-DR, HM-LC-Sw1-DR, HM-ES-PMSw1-DR,    
HM-ES-PMSw1-Pl - Rademacher Hompilot DuoFern