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 Denis,

das ist schon seltsam, warum dein UMG103 nicht antwortet. Was passiert eigentlich wenn Du nur das UMG103 definierst und kein UMG604 Gerät anlegst? Vielleicht hat das UMG604 ein Problem mit der gleichzeitigen Kommunikation als Endgerät und als Gateway?

Wenn es generell nicht antwortet, dann muss es einen Unterschied in der Kommunikation zwischen dem Fhem-Modul als Master und dem OPC-Server als Master geben, der allerdings nur bei der Kommunikation über das UMG604 als Gateway zuschlägt.
Vielleicht hat das UMG604 Gateway ein Problem damit, dass mehrere Register gleichzeitig abgefragt werden.
Hast Du mal versucht, den "combine" key in der deviceInfo weg zu lassen, so dass immer nur ein Register gleichzeitig abgefragt wird?

Übrigens scheint das mit dem Update noch nicht erfolgreich gewesen zu sein. Der Log-Eintrag von DevIO sieht noch alt aus ...
Wie hast Du das update denn gemacht?

Gruss
   Stefan

StefanStrobel

Hallo,

ich hätte nochmal was Neues zum Test:

Eine stark überarbeitete Version des Modbus-Basismoduls. Sie unterstützt jetzt auch Coils und es gibt viele Attribute zum Überschreiben der parseInfo und devInfo Strukturen. Damit das alles gut zusammen passt, musste ich ein paar Keys in der parseInfo umbenennen. (defaultpoll ist nur noch poll, defaultpolldelay nur noch polldelay)
Anbei die neuen Files. Eine vollständige Doku ist wieder in den Files enthalten.

Neu ist auch das Modul ModbusAttr. Das verwendet das Basismodul, enthält aber selbst keine parseInfo sondern erlaubt dem Anwender sein Gerät vollständig über Attribute zu definieren.

Beispiel:

define PWP ModbusAttr 5 30
attr PWP obj-h256-reading Temp_Wasser_ein
attr PWP obj-h256-expr $val/10

attr PWP obj-h258-reading Temp_Wasser_Aus
attr PWP obj-h258-expr $val/10

attr PWP obj-h262-reading Temp_Luft
attr PWP obj-h262-expr $val / 10

attr PWP obj-h770-reading Temp_Soll
attr PWP obj-h770-expr $val / 10
attr PWP obj-h770-set 1
attr PWP obj-h770-setexpr $val * 10
attr PWP obj-h770-max 32
attr PWP obj-h770-min 10
attr PWP obj-h770-hint 8,10,20,25,28,29,30,30.5,31,31.5,32

attr PWP dev-h-combine 5
attr PWP dev-h-defPoll 1

attr PWP room Pool-WP
attr PWP stateFormat {sprintf("%.1f Grad", ReadingsVal($name,"Temp_Wasser_Ein",0))}
attr PWP webCmd Temp_Soll


Man definiert ein Datenobjekt / Reading, indem man Attribute definiert, die mit obj- beginnen, dann den Typ des Objekts (c/d/h/i) und der dezimalen Adresse anthalten und dann für das Objekt weitere Eigenschaften. Das ganze entspricht den Keys in ParseInfo.
Ebenso kann man Device-Settings bzw. Defaults wie in der devInfo Struktur definieren. Die Attribute beginnen mit dev- dann kommt entweder timing oder der Obejkttyp und dann der Wert. Die Doku des Moduls ModbusAttr enthält eine vollständige Beschreibung.

Bei mir hat es bisher gut funktioniert. Wenn es noch jemand erfolgreich testen kann, würde ich das Basismodul, ModbusSET und ModbusAttr einchecken, so dass die Doku auch in der CommandRef auftaucht und einen Wiki-Eintrag schreiben.

Gruss
   Stefan


golem

Hallo Stefan,

werde ich Montag noch mal kurz testen.

Gruß Denis
Pi - Max-Lan - 8x max Ht -3x Max WT - Max Fk -modbus umg103- 2x Arduino mit Firmata Ethernet- ws300 - 433Mhz Sender Empfänger - 7x 1wire ds1820

Roger

Hallo Stefan,
ich werde es auch testen. Mal schauen, ob ich es am WE schaffe.

Ich habe nun ein zweites Modbus Gerät. Einphasiger Stromzähler SDM220M.
Beide funktionieren parallel an einem Modbus --> damit ist:
Punkt 7: mehrere Modbus-Geräten an einem Bus --> erledigt  :)


Mit den zwei Geräten an einem Bus habe ich nun eine zusätzliche Frage:
12: Wie kann ich sehen wie stark der Bus ausgelastet ist?
Ich habe ja diverse Abfragen mit unterschiedlichen Zyklenzeiten:
- bei jedem Zyklus, nur jeden zweiten/dritten/...
- nur aller 60s, 120s, 180s, ...
Und das Ganze nun von zwei Geräten!

Wie kann ich sehen inwieweit die Zyklen ausgelastet sind?
Wo ist noch wieviel Luft für ev. weitere/häufigere Abfragen?
Möglichst als Reading mit Log-Funktion, damit man das in einer Grafik sehen kann.

Stefan fällt Dir dazu was ein? Müsste ja irgendwie in 98_Modbus.pm realisiert werden.

Meine aktualisierten Gerätedateien, gibt es bei der Rückmeldung vom Test der neuen Version.
mit zyklischem Gruß
Roger
Zotac & RPIs mit 10*FHEM
2*HM-LAN, 2*JeeLink, 2*RS485, SignalESP
HomeMatic, PCA301 Komponenten, ModBus: Stromzähler, Fronius WR, Shelly, Victron

golem

Hallo Stefan,

ich habe mal einen kurzen Test gemacht. Sieht gut aus.
Das Umg604 Mit TCP antwortet und das Umg103 welches am 604 per RS485 angeklemmt ist liefert auch ordentliche werte.


Denis   
Pi - Max-Lan - 8x max Ht -3x Max WT - Max Fk -modbus umg103- 2x Arduino mit Firmata Ethernet- ws300 - 433Mhz Sender Empfänger - 7x 1wire ds1820

Roger

Hallo Stefan,
habe auch umgestellt und getestet --> sieht alles gut aus  :)
Anbei auch die Dateien für die Zähler SDM630M und SDM220M von B+G E-Tech & EASTON.

Hätte noch eine zusätzliche Frage:
13. Kann ich mit zwei Modbus Adaptern arbeiten?
Zwei Modbus Definitionen mit unterschiedlichen /dev Geräten sind bestimmt kein Problem.
Aber woher weiß meine Geräte Definition, an welches Basismodul sie sind anhängen soll?

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

StefanStrobel

Hallo Roger,

Zu Deiner Frage 12: So eine Art Bus-Nutzungs-Überwachung könnte ich noch einbauen.
Das sollte kein großer Aufwand sein. Ich würde aber gerne das Modul mit den Grundfunktionen erst noch vollständig dokumentieren und einchecken, bevor ich weitere Features hinzufüge.

Zu 13: dafür gibt es das Attribut IODev. Allerdings hab ich das noch nicht getestet. Zunächst nimmt ein Client-Modul das erste Modbus-Basismodul, das es findet. Sobald aber das Attribut IODev verarbeitet wird, kümmert sich Fhem darum, dass der Device-Hash des IO Devices im Internal $hash->{IODev} im Client-Modul gesetzt wird. Die Client-Funktionen des Modbus-Moduls verwenden das und selektieren so den gewünschten IO-Device-Hash. Der Hash des Client-Moduls wird dann beim Senden eines Requests in der Queue vermerkt, so dass beim Lesen der Antwort wieder klar ist, welches Client-Modul die Daten weiter verarbeiten möchte.

Gruß
    Stefan

Roger

Hallo Stefan,
das mit dem IODev zu 13. werde ich testen.
Schön, dass zu zu 12. Bus-Nutzungs-Überwachung was einbauen willst.

Ich habe gerade festgestellt:
14. dass die Attribute: sendDelay, commDelay und timeout bei meinen Geräte-Modulen nicht mehr funktionieren. Hier hattest Du die "" in deviceInfo entfernt.
Sollen diese attribute nicht mehr gesetzt werden könne? Habe ich was falsch umgesetzt?
Zumindest in der commandref von 98_ModbusSET.pm sind sie noch drin.

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

StefanStrobel

Hallo Roger,

Sorry - das mit den Attributen hätte ich deutlicher schreiben können. Ich habe bei der letzten Überarbeitung die Attributnamen an die Namen in parseInfo und devInfo angeglichen, damit das zukünftig weniger verwirrend wird. In der Doku zu ModbusAttr steht die aktuelle Beschreibung. Die Doku zu ModbusSET habe ich noch nicht angepasst.
Jedenfalls heißen diese Attribute jetzt dev-timing-timeout, dev-timing-sendDelay und dev-timing-commDelay.

Entsprechend kann man auch in jedem Client-Modul, das auf 98_Modbus.pm aufbaut alle ParseInfo Elemente über Attribute wie obj-h234-unpack überschreiben.
Alternativ versteht das Modul auch Attribute mit der Schreibweise parseInfoKey-Reading, also z.B. poll-temp_Luft wenn im Client-Modul entsprechende Attributnamen an die AttrList angefügt werden.

Wenn Du das als Autor eines Client-Moduls nicht möchtest, kannst Du einfach das entsprechende Attribut beim Füllen von $modHash->{AttrList} in der _Initialize-Funktion weglassen. Wenn Du den Anwendern alles erlauben möchtest, kannst du einfach die Zuweisung zu $modHash->{AttrList} wie in ModbusSET machen. Dein Modul hat dann auch alle Features von ModbusAttr ...
Ich habe schon angefangen Wiki-Artikel dazu zu schreiben. Es fehlt jedoch noch einiges.

Gruß
    Stefan

StefanStrobel

Hallo,

98_Modbus.pm ist nun eingecheckt, ebenso 98_ModbusAttr.pm und ModbusSET.pm.
Im Wiki habe ich einen ersten Entwurf der Doku abgelegt: http://www.fhemwiki.de/wiki/Modbus
Es wäre schön wenn Ihr die Doku ergänzen möchtet oder von dort auf Eure Module verweisen würdet.
Vermutlich sind auch noch Fehler in der Doku (erster Entwurf) und Verbesserungen sind willkommen :-)

Gruss
   Stefan

privat58

Hallo, bin gerade auf den "Fred" gestossen. Ich habe selber 2 SDM630DC im Einsatz.
Ausgelesen werden die im Moment mit:
define MB_RTU ModbusRTU /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0
attr MB_RTU charformat 8N1
attr MB_RTU pollIntervall 5
attr MB_RTU timeout 8

define U_L1 ModbusRegister 1 30001 #vom erstem Zähler
attr U_L1 IODev MB_RTU
attr U_L1 plcDataType REAL_BE
attr U_L1 room Stromzaehler
attr U_L1 stateFormat {sprintf("%.1f", ReadingsVal($name,"state",0))."V"}

define U_L1 ModbusRegister 2 30001 #vom zweiten Zähler
attr U_L1 IODev MB_RTU
attr U_L1 plcDataType REAL_BE
attr U_L1 room Stromzaehler
attr U_L1 stateFormat {sprintf("%.1f", ReadingsVal($name,"state",0))."V"}


Bisher musste ich für jeden Wert ein eigenes define anlegen.

So wie es ausschaut, brauche ich dies mit dem Modul ModbusSDM630M nicht mehr.
Wie kann ich aber die zwei Zähler mit dem neuen Modul definieren?
Dank an Euch
Steffen

Roger

Hi Steffen,
da ich einen SDM630M und einen SDM220M habe, antworte ich mal.
Du benötigst nur 3 Definitionen:

define HA_Modbus_1 Modbus /dev/ttyUSB0@9600
define HA_SDM630M_1 ModbusSDM630M 1 60
define HA_SDM630M_2 ModbusSDM630M 2 60

Die erste für die Definition des Modbus-Adapters an Deinem Computer.
Die beiden nächsten für die Definition der zwei Modbus Geräte. Diese müssen natürlich unterschiedliche Adressen haben.
Dein SDM630DC hat etwas weniger Register, aber Du kannst aus meinem 98_ModbusSDM630M.pm durch löschen Dir schnell eine Version für Dein Gerät erzeugen  :)

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

privat58

Danke Roger,
dann werde ich mich mal nach Ostern hinsetzen und umschreiben. Deine Vorlage gefällt mir sehr, da es Laien wie mir einfacher macht einzusteigen in die Materie. Auch das Bestimmen der Ausleseintervalle ist aus meiner Sicht gut gelöst.
Steffen

privat58

Ich habe die zwei Zähler jetzt so eingebunden. Das Intervall habe ich von 60 auf 5 gestellt.
Da werden mir die Daten etwas schneller aber nicht aller 5 Sekunden aktualisiert.
Soweit wie ich es verstanden habe, kann ich das Interval nicht per attr so setzen:
attr poll-Power_Sum__W 5
2015-04-06_17:39:15 SDM630M_Haus Power_Sum__W: 78.1 W
2015-04-06_17:40:22 SDM630M_Haus Power_Sum__W: 82.7 W
2015-04-06_17:41:17 SDM630M_Haus Power_Sum__W: 133.0 W
2015-04-06_17:42:23 SDM630M_Haus Power_Sum__W: 86.0 W
2015-04-06_17:43:17 SDM630M_Haus Power_Sum__W: 89.4 W
2015-04-06_17:44:23 SDM630M_Haus Power_Sum__W: 90.3 W
2015-04-06_17:45:17 SDM630M_Haus Power_Sum__W: 89.1 W
2015-04-06_17:46:27 SDM630M_Haus Power_Sum__W: 53.7 W
2015-04-06_17:47:17 SDM630M_Haus Power_Sum__W: 70.6 W
2015-04-06_17:49:04 SDM630M_Haus Power_Sum__W: 64.9 W
2015-04-06_17:49:54 SDM630M_Haus Power_Sum__W: 58.9 W
2015-04-06_17:50:18 SDM630M_Haus Power_Sum__W: 60.5 W
2015-04-06_17:50:22 SDM630M_Haus Power_Sum__W: 59.1 W
2015-04-06_17:50:29 SDM630M_Haus Power_Sum__W: 65.2 W
2015-04-06_17:51:09 SDM630M_Haus Power_Sum__W: 60.9 W
2015-04-06_17:51:27 SDM630M_Haus Power_Sum__W: 115.1 W
2015-04-06_17:52:01 SDM630M_Haus Power_Sum__W: 109.7 W


In der alten Einstellung konnte ich die Leistung aller z.Bsp. 5 Sekunden auslesen und auswerten.
Hintergrund ist der, das ich zwei PV-Anlagen mit Batterie nutze und einen Teil in Warmwasser versenken muss. Ich darf nicht mehr Einspeisen im Jahr als ich entnehme (der schwedischen eon sei Dank).
Ich schalte eine Heizpatrone zu, wenn Überschuss ist. Diese soll aber wieder ausgeschalten werden, wenn z.Bsp. der Wasserkocher angemacht wird, da ich sonst wieder in den Bezug gehe. Für diese "Überschussregelung" nutze ich DOIF.
Gibt es da eine andere Möglichkeit?
Dank an Euch.

privat58

Frage hat sich erledigt. Ich habe jetzt alles aus dem Modul ModbusSDM630M rausgenommen und es funktioniert. Entweder habe ich Probleme mit dem Modbus oder der Raspi schafft es nicht.
Vielen Dank auf jedem Fall noch einmal für das Modul, es ist sehr gut kommentiert, so das selbst ich als Laie es anpassen konnte.
Steffen