Wago /SPS über Modbus(TCP/IP) in FHEM steuern

Begonnen von lechez, 05 Mai 2013, 10:50:13

Vorheriges Thema - Nächstes Thema

lixilian

#285
Klar! Danke Christoph!
Da bin ich wohl blind gewesen.  :o

Bleibt nur noch die Frage mit dem auszulesenden Bit. Wie mache ich das? Leider läuft bei mir schon vieles über einfache Bitregister (z.B. Taster und einfache Status).

EDIT:
Ich denke, ich hab es hinbekommen. Statt ModbusRegister hab ich nun (danke nochmal Christoph für den Hinweis) ModbusCoil genommen und außerdem das Attribut disableRegisterMapping auf 1 statt 0 gesetzt. Was ich da gemacht habe, weiß ich nicht so genau, aber es funktioniert - ich bekomme die Status der Bitwerte ausgelesen. Sehr schön!

pc1246

Hallo lixilian

Wie gesagt ich bin lange raus aus dem Thema! Ich denke aber du musst das als Coil definieren. Ich weiss auch nicht wieweit es einen Wiki-Eintrag gibt! Warte einfach bis ChrisD online ist, der hilft Dir schnell und absolut kompetent!

Gruss Christoph
HP T610
Onkyo_AVR;Enigma2; SB_Server; SB_Player; HM-USB; PhilipsTV; harmony hub; Jeelink mit PCA301; Somfy; S7-300; LGW; HUE; HM-IP auf Charly; div

ChrisD

Hallo,

Es gibt bei Modbus 2 Datentypen die unterschiedlich angesprochen werden müssen:
- Coils (Bits)
- Register (Words)

Dafür gibt es auch die 2 unterschiedlichen Module. Wenn du einzelne Bits lesen/steuern möchtest musst du ModbusCoil verwenden, bei Zahlen dagegen ModbusRegister.

Bei der aktuellen Version der Module kannst du auch direkt die Adressierung aus der SPS verwenden, wenn du z.B. auf das Bit MX0.9 zugreifen möchtest kannst du folgende Definition verwenden:
define SPS_Bit1 ModbusCoil wago MX0.9
Weitere Attribute sind in dem Fall nicht nötig.

Analog dazu kannst du auch WORD, REAL und DWORD anlegen:
define SPS_Word ModbusRegister wago MW20
define SPS_Real ModbusRegister wago MF20
define SPS_DWord ModbusRegister wago MD24


Das Attribut disableRegisterMapping schaltet die Umrechnung von Register- und Coilnummern zu Adressen ab. Bei Wago und einer Reihe anderer SPSen muss es auf 1 gesetzt werden da diese direkt die Adressen verwenden (was nicht ganz der Spezifikation entspricht), bei den meisten anderen Geräten dagegen braucht es nicht gesetzt zu werden. Das Attribut ist ohne Funktion wenn du die Definition mit der Wago-Adressierung, wie oben beschrieben, verwendest.

Grüße,

ChrisD

lixilian

Vielen Dank, Chris, für die ausführliche Antwort! Ich teste Fhem gerade. Die Anbindung an die Wago war das entscheidende Kriterium für den Einsatz und das funktioniert nun. Prima!

th1984

Hallo Allerseits,

ich bin echt begeistert was hier abgeht und wie hier Herausforderungen gelöst werden. Ich bin auch an einem etwas kniffligen Fall dran. Ich habe eine Helios Wohnraumlüftungsanlage. Soweit so gut, nur möchte ich diese nun auch an den FHEM der bei mir auf einem Raspberry läuft draufhängen. Das ganze stelle ich mir über die Ethernetschnittstelle und Modbus ganz einfach vor. Das Problem bei der Geschichte ist jetzt aber folgendes:

Um an die heiß begehrten Daten in der KWL zu kommen, muss ich zwei Dinge tun: zum einen einen Wert in eine Variable schreiben und dann erst auslesen. Das heißt im Klartext ich muss erst auf dem Bus einen Variablennamen senden den ich lesen möchte und diesen dann in dem "Standardregister" lesen.

Beispiel: ich sende folgendes: 0x7630 0x3030 0x3034 0x0000 (was nichts anderes als ein Variablenname ist)
Danach kann ich das Register ab Startadresse 1 mit einer fest vorgegebenen Länge auslesen.

Nun meine Frage, hat jemand sowas ähnliches schon mal umgesetzt? Hat irgendjemand einen Tipp für mich wo ich ähnliches evtl schon finde? Bzw wie ich sowas am einfachsten in FHEM umsetzten kann? Bin für jeden Hinweis dankbar!

Viele Grüße
Thomas


ChrisD

Hallo,

Ich sehe 2 Möglichkeiten es in FHEM umzusetzen:
- ein eigenes Modul welches das Lesen und Schreiben 'kapselt', aufbauend auf 36_ModbusTCPServer
- mit den Funktionen aus 99_Modbus.pm und MBclient.pm sowie etwas Handarbeit, Erklärungen zu den Modulen gibt es u.a. im Beitrag 99.

Die 2. Möglichkeit könntest du so umsetzen:
- die im Anhang befindlichen Dateien im FHEM-Modulverzeichnis speichern
- FHEM neu starten
- einen dummy für die Modbus-Kommunikation anlegen (IP-Adresse anpassen):
define KWL dummy
attr KWL comment 192.168.78.99:502:1

- mit der Funktion write_modbus_multi zuerst die gewünschte Variable anfragen
- mit der Funktion read_modbus_multi das Ergebnis auslesen

Im Modul 99_myUtilsKWL findest du ein Beispiel wie dies funktionieren könnte. Die Funktion myUtilsKWL_Read erwartet 2 Parameter:
- die Anfrage (z.B v0004)
- die Länge der Antwort (für v0004 z.b. 9)
und gibt das Ergebnis aus (z.B. v00004=11.12.0013)

Zum Testen kannst du
{myUtilsKWL_Read("v00004",9)}in der FHEM-Befehlszeile eingeben.

Aus der Dokumentation ist leider nicht klar ersichtlich in welcher Reihenfolge die Bytes in die Words verpackt werden müssen. Hier musst du eventuell mit dem Beispielcode experimentieren. Du kannst die Datei 99_myUtilsKWL direkt in FHEM editieren (unter 'Edit files').

Wenn die Kommunikation bis funktioniert kannst du das Lesen über 'at' regelmäßig ausführen lassen.

Grüße,

ChrisD


th1984

Hallo ChrisD,

vielen Dank für deine Ausführliche Antwort. Ich werde mich mit den beiden Vorgeschlagenen Möglichkeiten auseinandersetzten. Am besten gefallen würde mir ja die Variante 1. Mal sehen ob meine Kenntnisse dafür ausreichend sind.

Die zweite Variante erscheint mir irgendwie einfacher, darum werde ich diese auch gleich als erstes Versuchen wenn ich mal ein zwei ruhige Tage habe. Wenn das dann läuft werde ich Variante 1 gänzlich außen vor lassen.

Ich muss auf jeden Fall schon mal ein großes DANKE loswerden. Freue mich schon jetzt aufs experimentieren ;-)

vg
Thomas

qwikser

Hallo nochmals,

hat sich ja einiges getan seit ich das letzte mal hier reingeschaut habe.   ;) :D
Und bei dem ganzen Fach Chinesisch was man so auf dem letzten paar Seiten liesst traue ich mich fast nicht meine, eher einfachen Fragen, zu stellen.  ::)

Zum einen wollte ich jetzt noch meine Batterie Meldung der MAX! Heizungssysteme an meine WAGO SPS senden, da mittlerweile meine Batterien den Geist aufgeben.

Versucht habe ich es wie folgt:

define fenster_battery_bad ModbusCoil 0 12950
attr fenster_battery_bad disableRegisterMapping 1
attr fenster_battery_bad event-on-change-reading state
attr fenster_battery_bad group Bad
attr fenster_battery_bad room Wago-MAX
define act_fenster_battery_bad notify MAX_01b046:battery.* { fhem "set fenster_battery_bad ".($EVTPART0 eq "low"?"on":"off")
#--------------------------------------------------------------------------------------------------------------------------- Bad Fenster Batterie


Anbei auch ein Bild der Readings von diesem Gerät. Das Reading "battery" ändert seinen Zustand von "ok" zu "low".

Auch habe ich festgestellt, wenn ich die neuste Version der Modbus Module benutze, dass fhem keine Daten mehr in meine Wago SPS schreibt.
Hier ein Beispiel was ich meine:

define fenster_aufzu_bad ModbusCoil 0 12949
attr fenster_aufzu_bad disableRegisterMapping 1
attr fenster_aufzu_bad event-on-change-reading state
attr fenster_aufzu_bad group Bad
attr fenster_aufzu_bad room Wago-MAX
define act_fenster_aufzu_bad notify MAX_01b046:onoff.* {fhem "set fenster_aufzu_bad ".($EVTPART1==1?"on":"off")}
#--------------------------------------------------------------------------------------------------------------------------- Bad Fenster Auf/Zu

Dies funktioniert nur mit den "alten" Modbus Modulen, mit den "neueren" von hier https://github.com/ChrisD70/FHEM-Modules funktioniert das Schreiben auf die SPS nicht mehr.

MfG.
Daniel

ChrisD

Hallo,

Kannst du versuchen im notify $EVTPART1 statt $EVTPART0 zu verwenden und am Ende ein '}' hinzuzufügen:
define act_fenster_battery_bad notify MAX_01b046:battery.* { fhem "set fenster_battery_bad ".($EVTPART1 eq "low"?"on":"off")}
Damit sollte der Batteriezustand übertragen werden.

Das Problem beim Schreiben konnte ich nicht reproduzieren, ich verwende im Moment folgende Versionen:
Zitat# $Id: 37_ModbusCoil.pm 0008 $
# $Id: 37_ModbusRegister.pm 0016 $
# $Id: 36_ModbusTCPServer.pm 0015 $
Damit wird der Batteriezustand nach MX41.6 geschrieben.

Wenn du ein Update der Module machst solltest du die 3 Module gleichzeitig aktualisieren und danach FHEM neu starten.

Bei der aktuellen Version brauchst du nicht mehr die Adressen der Wago umzurechnen, du kannst statt
define fenster_battery_bad ModbusCoil 0 12950
attr fenster_battery_bad disableRegisterMapping 1


define fenster_battery_bad ModbusCoil wago MX41.6
verwenden.

Falls du es nochmal mit den neuen Modulen versuchst und das Schreiben weiterhin nicht funktioniert, kannst du die Ausgabe von
list fenster_battery_badposten ?

Grüße,

ChrisD

qwikser

Hallo Chris,

es ist zwar schon ein Paar Tage her, ...aber das mit dem Evtpart1 hat wunderbar funktioniert.
Bin in der zwischen  Zeit umgezogen und habe alles jetzt soweit durch Homematic Komponenten ausgetauscht. Funktioniert wie eine eins.
Auch nutze ich dieses Modul jetzt als Verbindung zwischen meiner IP-Symcon und FHEM - funtzt auch prima.

Vielen Dank nochmals
Daniel  ;D 8)

Smartissimo

Halli Hallo,

ich muss das Thema mal wieder ein wenig aufrühren und benötige dringend Hilfe.

Ich habe einen Raspberry Pi mit FHEM ausgestattet und Ihn mit den neusten Versionen der 99_modbus und dem MBClien versehen. In der 99_modbus Datei von ChrisD wurde die my $modbusIP="192.168.10.2"; angepasst. In der fhem.cfg habe ich meine Befehle aufgeführt. Nachfolgend ein Beispiel:

#Definition Testbefehl
define Testcoil dummy
attr Testcoil devStateIcon On:Restart Off:Shutdown
attr Testcoil icon time_manual_mode
attr Testcoil room Handbetrieb
attr Testcoil setList On Off
attr Testcoil webCmd On:Off
define act_Testcoil notify Test { if (Value("Testcoil") eq "Off") {write_modbus_coil(160,"off")} else {write_modbus_coil(160,"on")}}


Schalten möchte ich ein Coil - also ein Modbus BIT - übersetzt wird das Ganze dann später auf eine Phoenix Contact SPS und entspricht dort dem Wort 109 Bit 15.

Nun mein Problem.
Ich bekomme keine Verbindung zu Stande. Mein Paspberry Pi gibt beim betätigen des Testcoils auch keinen Befehl aus (beobachtet über Wireshark - einzig und allein ein Keep Alive und Ack wird vom Raspi ausgesendet)
Die 99_modbus datei muss ja nicht aufgerufen werden in der cfg da sie ja eine System Kennung hat. Über den Start des Clients finde ich aber auch nichts in meinem Log File:
2015.02.12 12:01:04 0: Server shutdown
2015.02.12 12:01:08 1: Including fhem.cfg
2015.02.12 12:01:09 3: telnetPort: port 7072 opened
2015.02.12 12:01:09 3: WEB: port 8083 opened
2015.02.12 12:01:09 3: WEBphone: port 8084 opened
2015.02.12 12:01:09 3: WEBtablet: port 8085 opened
2015.02.12 12:01:10 2: eventTypes: loaded 52 events from ./log/eventTypes.txt
2015.02.12 12:01:10 1: Including ./log/fhem.save
2015.02.12 12:01:10 1: usb create starting
2015.02.12 12:01:12 3: Probing CUL device /dev/ttyAMA0
2015.02.12 12:01:12 3: Probing TCM_ESP3 device /dev/ttyAMA0
2015.02.12 12:01:12 3: Probing FRM device /dev/ttyAMA0
2015.02.12 12:01:18 1: usb create end
2015.02.12 12:01:18 2: SecurityCheck:  WEB,WEBtablet has no basicAuth attribute. telnetPort has no password/globalpassword attribute.  Restart FHEM for a new check if the problem is fixed, or set the global attribute motd to none to supress this message.
2015.02.12 12:01:18 0: Server started with 51 defined entities (version $Id: fhem.pl 6913 2014-11-08 10:32:44Z rudolfkoenig $, os linux, user fhem, pid 2266)
2015.02.12 12:22:15 1: Including fhem.cfg
2015.02.12 12:22:15 3: telnetPort: port 7072 opened
2015.02.12 12:22:15 3: WEB: port 8083 opened
2015.02.12 12:22:15 3: WEBphone: port 8084 opened
2015.02.12 12:22:15 3: WEBtablet: port 8085 opened
2015.02.12 12:22:15 2: eventTypes: loaded 52 events from ./log/eventTypes.txt
2015.02.12 12:22:16 1: Including ./log/fhem.save


Beim Schalten der Coils steht nur folgendes im Logfile:
015.02.12 12:31:14 2: write error address 161 value 1, er 2 ex 0
2015.02.12 12:31:17 2: write error address 162 value 1, er 2 ex 0
2015.02.12 12:31:21 2: write error address 163 value 1, er 2 ex 0
2015.02.12 12:31:41 2: write error address 164 value 1, er 2 ex 0
2015.02.12 12:31:44 2: write error address 165 value 1, er 2 ex 0
2015.02.12 12:31:47 2: write error address 166 value 1, er 2 ex 0
2015.02.12 12:32:29 2: write error address 161 value 0, er 2 ex 0
2015.02.12 12:32:32 2: write error address 162 value 0, er 2 ex 0
2015.02.12 12:32:35 2: write error address 164 value 0, er 2 ex 0
2015.02.12 12:32:38 2: write error address 165 value 0, er 2 ex 0
2015.02.12 12:32:41 2: write error address 166 value 0, er 2 ex 0
2015.02.12 12:35:24 2: write error address 163 value 0, er 2 ex 0


Wo liegt mein Fehler ?
Ich bitte um Hilfe ☺

ChrisD

Hallo,

Fehlercode 2 bedeutet dass die Gegenseite die Adresse als ungültig ansieht. Was benutzt du im Moment als Gegenstelle für den Raspberry Pi ?

99_modbus wird automatisch geladen und es gibt beim Start auch keine Meldungen im Log.

Für ein neues Projekt würde ich aber die Module 99_modbus und MBClient nicht mehr verwenden. Stattdessen würde ich die Module 36_ModbusTCPServer, 37_ModbusRegister und 37_ModbusCoil benutzen. Diese kannst du mit
update force https://raw.githubusercontent.com/ChrisD70/FHEM-Modules/master/autoupdate/mb/controls_modbus.txt
in FHEM auf dem Raspberry installieren.

Nach einem Neustart von FHEM kannst du dann die Verbindung mit
define SPS ModbusTCPServer 192.168.10.2:502anlegen.

Einzelne Coils kannst du mit
define Testcoil ModbusCoil 0 160
attr Testcoil event-on-change-reading .*
definieren.

Grüße,

ChrisD

Smartissimo

#297
Hallo Chris,

vielen Dank für deine schnelle und kompetente Antwort.

Beim lesen des Beitrages ist mir im Vorfeld bereits der Verweis auf die Fehler IDs aufgefallen.
Ich habe jetzt die Kommunikation auf die neuen Dateien umgestellt.

Damit ist jetzt der erste Teilerfolg gekommen:

Zitat2015.02.12 14:17:25 3: Opening SPS device 192.168.10.2:502
2015.02.12 14:17:25 3: SPS device opened

Meine Gegenstelle sieht wie folgt aus:

http://imgur.com/FbBGxDJ

Das ist der ModBus Master Baustein von Phoenix Contact.
Die ModBus Coils verschiebe ich dann nach dem umrechnen auf Wort und Bit auf ein internes Bit.
Beispiel: Coil 160 = Wort 109 Bit 16

Jetzt habe ich noch eine Frage zu FHEM.

Ich muss ja jetzt das alte define zum event-on-change-reading umwandeln ? Ist das richtig ?

Zitat#Definition Testbefehl
define Testcoil ModbusCoil 0 160
attr Testcoil devStateIcon On:Restart Off:Shutdown
attr Testcoil icon time_manual_mode
attr Testcoil room Handbetrieb
attr Testcoil setList On Off
attr Testcoil webCmd On:Off

attr Testcoil event-on-change-reading .*
define act_Testcoil notify Testcoil  { if (Value("Testcoil ") eq "Off") {write_modbus_coil(160,"off")} else {write_modbus_coil(160,"on")}}

Viele Grüße,

Sven ;)

ChrisD

Hallo,

Das notify benötigst du nicht mehr, das Modul ModbusCoil kümmert sich intern um das Schreiben.
Das Attribut event-on-change-reading solltest du verwenden damit nicht bei jedem Lesen ein Eintrag ins Log oder die Datenbank gemacht wird. Die Attribute setList und webCmd können entfallen.

Zum Testen sollte
define Testcoil ModbusCoil 0 160
attr Testcoil devStateIcon On:Restart Off:Shutdown
attr Testcoil icon time_manual_mode
attr Testcoil room Handbetrieb
attr Testcoil event-on-change-reading .*

reichen.

Je nach SPS und Hersteller gibt es 2 unterschiedliche Zählweisen für die Coils und Register, wenn du ab 0 zählst musst du zusätzlich
attr Testcoil disableRegisterMapping 1verwenden. In dem Fall liegt bei deiner Konfiguration Coil 160 auf Wort 110, Bit 0, wenn du das Attribut disableRegisterMapping nicht verwendest liegt Coil 160 auf Wort 109, Bit 15.

Grüße,

ChrisD

Smartissimo

Hey,

Schritt für Schritt in Richtung Ziel.
Also umgesetzt habe ich es jetzt genau so. Die Verbindung steht nur sehe ich aktuell noch keine Ereignisse die normalerweise auf das Betätigen von On / Off beim Testcoil kommen.
Nachfolgend der Mitschnitt von Wireshark:

http://imgur.com/7NzgTSF

Normalerweise sollte doch das ModBus TCP Paket mit der Quelle Raspberry Pi [192.168.10.62] und dem Ziel [192.168.10.2] zu sehen sein, oder bin ich da falscher Annahme. Bis jetzt juckt das Betätigen des Buttons auch meine SPS recht wenig.
Hast du eine Idee woran das liegen kann ?

Grüße,

Sven