Neue Versionen und Support zum Modbus-Modul

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

Vorheriges Thema - Nächstes Thema

StefanStrobel

Hallo,

da der alte Thread ziemlich groß geworden ist und auch Titel des alten Threads (https://forum.fhem.de/index.php/topic,25315.0.html) nicht mehr so gut passt, mache ich einen neuen auf und schließe den alten.
Das Modul unterstützt ja schon lange Modbus RTU oder ASCII über RS232, RS485 oder auch als Modbus-TCP oder Modbus-RTU über TCP.

Hier werde ich in Zukunft neue Versionen zum Testen posten und Fragen beantworten.
Bitte keine Fragen zum Modul als PM. Es ist sinnvoller,  diese hier zu stellen, damit auch andere von der Diskussion profitieren können.

Gruss
    Stefan

StefanStrobel

und hier auch gleich eine neue Version zum Testen.

Neu ist z.B. die Unterstützung von benutzerdefinierten Datentypen. Bei einigen Geräten werden z.B. viele Werte als Fließkommazahl in 2 Registern mit umgekehrter Reihenfolge im big endian Format gespeichert.

um nicht für jedes Objekt 5 Attribute mit Länge, Unpack-Code, revRegs etc. angeben zu müssen, kann man nun einmal den Datentyp mit dev-type- definieren und dann künftig bei jedem Objekt nur noch den Typ zuweisen.

Beispiel:

attr WP dev-type-VT_R4-format %.1f
attr WP dev-type-VT_R4-len 2
attr WP dev-type-VT_R4-revRegs 1
attr WP dev-type-VT_R4-unpack f>

attr WP obj-h1234-reading Temp_Ist
attr WP obj-h1234-type VT_R4

Die ersten vier Attribute erzeugen einen Datentyp mit Namen VT_R4 und legen für diese Typ format, len, revRegs und unpack fest.
Danach wird für das Holding-Register mit der Adresse 1234 ein Reading mit Namen Temp_Ist und der Typ VT_R4 zugewiesen.


Ebenso neu ist ein experimentelles Feature zum automatischen Erzeugen eines individuellen Gerätemoduls aus den Attributen eines Modbus-Attr Geräts.

Mit set WP saveAsModule WP werden die per Attribut definierten Objekte (alles was mit dev- und obj- definiert ist) mit etwas Code drum herum in ein Perl-File geschrieben. Das File würde im obigen Beispiel als /tmp/98_ModbusGenWP.pm gespeichert.
Von dort kann man es ins Modulverzeichnis von Fhem (z.B. /opt/fhem/FHEM) verschieben, Fhem neu starten und dann statt Modbus-Attr mit vielen Attributen ein Gerät mit dem neuen Typ ModbusGenWP definieren.

Wer die Register-Definitionen für seine Heizung oder seinen speziellen Solar-Speicher einfach als Modul weitergeben möchte, kann das mal ausprobieren.

Gruss
   Stefan

Goulasch

#2
Meine Konfig:
define PWP ModbusAttr 3 30 192.168.1.38:502 TCP
attr PWP userattr obj-h30051-reading obj-h30051-unpack obj-h30051-poll
attr PWP obj-h30051-reading WRtyp
attr PWP obj-h30051-unpack N
attr PWP obj-h30051-poll 1
attr PWP verbose 5

Die Slave Adresse lautet "3".

Das Log:
Zitat2017.09.17 18:45:54 5: PWP: GetUpdate called
2017.09.17 18:45:54 4: PWP: update timer modified: will call GetUpdate in 30.0 seconds at 2017-09-17 18:46:24 - Interval 30
2017.09.17 18:45:54 5: PWP: GetUpdate objects from attributes: h30051
2017.09.17 18:45:54 5: PWP: GetUpdate full object list: h30051
2017.09.17 18:45:54 5: PWP: GetUpdate check h30051 => WRtyp, poll = 1, last = 0
2017.09.17 18:45:54 4: PWP: GetUpdate will request WRtyp
2017.09.17 18:45:54 5: PWP: GetUpdate tries to combine read commands
2017.09.17 18:45:54 5: PWP: don't sort objList before sending requests
2017.09.17 18:45:54 4: PWP: Send called with h30051, objLen 1 / reqLen 1 to id 3, op read, qlen 0
2017.09.17 18:45:54 4: PWP: Send queues fc 3 to 3, tid 146, for h30051 (WRtyp), reqLen 1
2017.09.17 18:45:54 5: PWP: handle queue check commDelay (0.1) for PWP: rest -29.9109320640564
2017.09.17 18:45:54 5: PWP: handle queue check sendDelay (0.1) for PWP: rest -29.9211559295654
2017.09.17 18:45:54 5: PWP: HandleSendQueue: finished delay checking, proceed with sending
2017.09.17 18:45:54 4: PWP: HandleSendQueue sends fc 3 to id 3, tid 146 for WRtyp (h30051), len 1, device PWP (TCP), pdu 0375630001, V 3.7.0 - 20.8.2017
2017.09.17 18:45:54 5: SW: 009200000006030375630001
2017.09.17 18:45:54 5: PWP: raw read: 0092000000030383
2017.09.17 18:45:54 5: PWP: ParseFrames got: 0092000000030383
2017.09.17 18:45:54 5: PWP: ParseFrames: Modbus TCP PDU too small (expect 3): 2
2017.09.17 18:45:54 5: PWP: raw read: 02
2017.09.17 18:45:54 5: PWP: ParseFrames got: 009200000003038302
2017.09.17 18:45:54 4: PWP: ParseFrames got error code 83 / 02, illegal data address
2017.09.17 18:45:54 5: PWP: ParseFrames returned error: device replied with exception code 83 / 02, illegal data address

Gemäß SMA definiert sich das auszulesende Register:
Modbus register address   Short description   Type   Format   Unit   Access
30051                           Device class           U32   ENUM      RO


Kann mit diversen Modbus-Server-Client Utillities auf den WR zugreifen.
Verstehe nicht, warum hier jetzt ein "exception" kommt.

Im alten Thread hat der User @Fantomas offensichtlich mit Erfolg auf das Interface zugreifen können.

Goulasch

#3
Antwort kann ich selbst geben :
attr PWP obj-h30051-len 2
fehlte in der Konfig.

Roger

Hi Stefan,
ich Roger bin's nach langer Zeit mal wieder mit einer Frage.

Beim Fronius Wechselrichter werden einige Werte aus zwei Registern gebildet: Wert*10**ScaleFactor.
Nun muss sichergestellt werden, das vor dem Auslesen und der Berechnung von Wert der ScaleFactor ausgelesen wurde.
Wie kann mal das sicherstellen?
Im Log sehe ich, das die Werte in unterschiedlicher Reihenfolge reinkommen --> und machmal ergibt die Berechnung falsche werte, da ScaleFactor zu spät kommt.
Fällt Dir dazu was ein?

Roger
Zotac, BBB, RPIs mit 10*FHEM
2*HM-LAN, 2*JeeLink, 2*RS485, SignalESP
HomeMatic, PCA301 Komponenten, ModBus: Stromzähler, Fronius WR, Shelly

StefanStrobel

Hallo Roger,

ist der ScaleFactor auf einer kleineren Adresse?
Ich habe aus einem ähnlichen Grund vor kurzem ein Attribut "sortUpdate" eingebaut. Dann werden die Requests beim zyklischen Update nach Adresse sortiert.

Gruss
   Stefan

Roger

Hi Stefan,
man das ist ja Klasse. Ja, die ScaleFactoren sind auf kleineren Adressen. Ich probiere man das Attribut sortUpdate.
Ist wohl noch nicht in der CommandRef, denn da hatte ich schon nach so etwas gesucht.

Roger
Zotac, BBB, RPIs mit 10*FHEM
2*HM-LAN, 2*JeeLink, 2*RS485, SignalESP
HomeMatic, PCA301 Komponenten, ModBus: Stromzähler, Fronius WR, Shelly

StefanStrobel

Hi Roger,

sollte seit Juli in der CommandRef zu ModbusAttr drinstehen.
Aber in der Doku vom Basismodul stehen die ganzen Attribute nicht nochmal drin. ;-)

Gruss
   Stefan

Roger

Oh in ModbusAttr hatte ich nicht geschaut, da ich ja mit dem Modul nichts mache.
Vielleicht kannst Du ja ergänzen, das es nach der Adresse sortiert wird. Ich weiß nicht, ob ich beim Durchlesen die Lösung des Problems durch dieses Attribut erkannt hätte.

Und das Wichtigste: Fehler ist weg  :)

mit dankendem Gruß
Roger
Zotac, BBB, RPIs mit 10*FHEM
2*HM-LAN, 2*JeeLink, 2*RS485, SignalESP
HomeMatic, PCA301 Komponenten, ModBus: Stromzähler, Fronius WR, Shelly

Roger

Hi Stefan,
nächste Frage. Ich habe einige Readings umbenennen müssen. Wie kann ich die alten Readings von einem Modul, welches auf 98_Modbus.pm aufsetzt, löschen (also deletereading aufrufen)?
Ich suche nach so was wie X_Define in einem normalen Modul.

(Ich habe mir derzeit mit einer ignoreExpr-Funktion von einem Wert mit poll => "once" beholfen, aber das geht bestimmt sauberer).

Roger
Zotac, BBB, RPIs mit 10*FHEM
2*HM-LAN, 2*JeeLink, 2*RS485, SignalESP
HomeMatic, PCA301 Komponenten, ModBus: Stromzähler, Fronius WR, Shelly

StefanStrobel

Hallo Roger,

jetzt hast Du mich abgehängt.
deletereading funktioniert doch immer - aber was hat das mit X_Define zu tun?
Sorry - ich steh auf dem Schlauch ...

Gruss
   Stefan

Roger

Hi Stefan,
ich möchte innerhalb meines Modules, welches auf 98_Modbus.pm aufsetzt, beim Start des Modules einmalig eine Aktion durchführen konkret:
fhem("deletereading <devname> <readingname>")
Dafür habe ich bisher nur die Krücke, wie im vorherigen Post beschrieben, gefunden.
In vollständigen FHEM-Modulen, kann man so etwas wohl in der X_Define Sub durchführen.

Ich hoffe das ich mich verständlicher machen konnte  ;D.
Roger
Zotac, BBB, RPIs mit 10*FHEM
2*HM-LAN, 2*JeeLink, 2*RS485, SignalESP
HomeMatic, PCA301 Komponenten, ModBus: Stromzähler, Fronius WR, Shelly

StefanStrobel

Hallo Roger,

Dein Modul definiert vermutlich eine Funktion mit Namen ModbusXYZ_Initialize, die ihrerseits ModbusLD_Initialize aufruft.
Dort wird die Define-Funktion festgelegt:

$modHash->{DefFn}     = "ModbusLD_Define";

Du könntest jetzt in Deiner ModbusXYZ_Initialize direkt nach dem Aufruf von ModbusLD_Initialize einfach die Variable $modHash->{DefFn} überschreiben,
eine eigene Define-Funktion schreiben, die dann ModbusLD_Define aufruft und die Parameter durchreicht.

Gruss
   Stefan

Roger

#13
Hi Stefan,
Danke für den Schubs in die richtige Richtung. Da ich aber gespeicherte Readings beim Serverstart/RereadCFG löschen wollte (die hatte ich umbenennen müssen und wollte die Leichen entfernen), musste ich {NotifyFn} wie von Dir beschrieben umbiegen.

Also vielen Dank für die kompetente Hilfe - in den Mechanismen der FHEM-Module bin ich (noch) nicht so fit.

Allerdings war meine Notlösung mit einer ignoreExpr-Funktion von einem Wert mit poll => "once" bedeutend einfacher.
Vielleicht kannst Du ja noch solche Funktionsaufrufe in 98_Modbus.pm einbauen?
Roger
Zotac, BBB, RPIs mit 10*FHEM
2*HM-LAN, 2*JeeLink, 2*RS485, SignalESP
HomeMatic, PCA301 Komponenten, ModBus: Stromzähler, Fronius WR, Shelly

der-Lolo

Hallo Stefan,
ich habe wieder schwierigkeiten meine Modbus Linie in betrieb zu nehmen. Als erstes fällt mir im Log folgendes auf

Zitat2017.09.30 12:09:48 0: Server started with 57 defined entities (fhem.pl:15112/2017-09-21 perl:5.024002 os:linux user:fhem pid:12069)
2017.09.30 12:09:48 0: Featurelevel: 5.8
2017.09.30 12:09:48 1: Including ./log/fhem.save
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_Send redefined at ./FHEM/98_Modbus.pm line 2674, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_SwpRegs redefined at ./FHEM/98_Modbus.pm line 2653, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_RevRegs redefined at ./FHEM/98_Modbus.pm line 2630, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_GetIOHash redefined at ./FHEM/98_Modbus.pm line 2602, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_GetUpdate redefined at ./FHEM/98_Modbus.pm line 2478, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_compObjKeys redefined at ./FHEM/98_Modbus.pm line 2459, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_ReadAnswer redefined at ./FHEM/98_Modbus.pm line 2349, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_Set redefined at ./FHEM/98_Modbus.pm line 2212, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_ScanFormat redefined at ./FHEM/98_Modbus.pm line 2167, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_ScanIds redefined at ./FHEM/98_Modbus.pm line 2124, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_ScanObjects redefined at ./FHEM/98_Modbus.pm line 2082, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_ControlSet redefined at ./FHEM/98_Modbus.pm line 1888, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_compObjAttrs redefined at ./FHEM/98_Modbus.pm line 1869, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_Get redefined at ./FHEM/98_Modbus.pm line 1824, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_UpdateGetSetList redefined at ./FHEM/98_Modbus.pm line 1762, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_Undef redefined at ./FHEM/98_Modbus.pm line 1748, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_Attr redefined at ./FHEM/98_Modbus.pm line 1652, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_Attr redefined at ./FHEM/98_Modbus.pm line 1626, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_Define redefined at ./FHEM/98_Modbus.pm line 1565, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_OpenCB redefined at ./FHEM/98_Modbus.pm line 1551, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_SetTimer redefined at ./FHEM/98_Modbus.pm line 1519, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_SetIODev redefined at ./FHEM/98_Modbus.pm line 1476, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_Initialize redefined at ./FHEM/98_Modbus.pm line 1392, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_HandleSendQueue redefined at ./FHEM/98_Modbus.pm line 1210, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_CheckDelay redefined at ./FHEM/98_Modbus.pm line 1178, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_TimeoutSend redefined at ./FHEM/98_Modbus.pm line 1156, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_CountTimeouts redefined at ./FHEM/98_Modbus.pm line 1131, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_LRC redefined at ./FHEM/98_Modbus.pm line 1116, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_CRC redefined at ./FHEM/98_Modbus.pm line 1096, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_Ready redefined at ./FHEM/98_Modbus.pm line 1071, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_Open redefined at ./FHEM/98_Modbus.pm line 1027, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_Read redefined at ./FHEM/98_Modbus.pm line 994, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_EndBUSY redefined at ./FHEM/98_Modbus.pm line 976, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_ParseFrames redefined at ./FHEM/98_Modbus.pm line 784, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_Profiler redefined at ./FHEM/98_Modbus.pm line 700, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_Statistics redefined at ./FHEM/98_Modbus.pm line 668, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_ParseObj redefined at ./FHEM/98_Modbus.pm line 529, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_CheckEval redefined at ./FHEM/98_Modbus.pm line 502, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_ObjKey redefined at ./FHEM/98_Modbus.pm line 484, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_DevInfo redefined at ./FHEM/98_Modbus.pm line 454, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine ModbusLD_ObjInfo redefined at ./FHEM/98_Modbus.pm line 373, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_Notify redefined at ./FHEM/98_Modbus.pm line 335, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_Undef redefined at ./FHEM/98_Modbus.pm line 293, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_Define redefined at ./FHEM/98_Modbus.pm line 265, <$fh> line 400.
2017.09.30 12:09:48 1: PERL WARNING: Subroutine Modbus_Initialize redefined at ./FHEM/98_Modbus.pm line 234, <$fh> line 400.
2017.09.30 12:09:47 1: Including /usr/local/fhem/opt/fhem.cfg
2017.09.30 12:09:45 0: Server shutdown

Ich habe das Modul aus diesem Thread geladen und neu gestartet - es bringt aber keinen unterschied.
FHEM läuft auf einer Synology DiskStation - falls das eine Rolle spielt..
Hast Du eine Idee was da los ist?