ModBus TCP Interface

Einrichtung, Anschluss und Programmierung der HomeMatic CCU

Moderator: Co-Administratoren

Benutzeravatar
Indi55
Beiträge: 10
Registriert: 03.11.2016, 19:54
Wohnort: Köln
Danksagung erhalten: 5 Mal

ModBus TCP Interface

Beitrag von Indi55 » 04.01.2020, 17:39

ModBus TCP Interface

Ich habe ein allgemein gültiges ModBus TCP Interface erstellt.
Damit lassen sich alle ModBus Geräte im Netzwerk auslesen und steuern.

Aufruf mit Script.
Beispiel:
system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.010.100 502 255 03 528 1",&lGetOut,&lGetErr);

Syntax:
Lesen : modbus_interface.tcl IP-Adresse Port DeviceNummer Funktion Register Länge
Schreiben : modbus_interface.tcl IP-Adresse Port DeviceNummer Funktion Register Wert

Port : normalerweise 502
DeviceNummer : Beispiel Wallbe 255 , Solaredge 1
Funktion :
01 read coils
02 read discrete inputs
03 read holding registers
04 read input registers
05 write single coils
06 write single register
15 write multible coils
16 write multible registers
Register, Länge und Wert : siehe Dokumentation des ModBus-Geräts

Source Code :
SCRIPT Modbus.rar
(18.57 KiB) 1144-mal heruntergeladen
Alles unter /usr/local/addons/modbus in der CCU abspeichern.
Den beiden Scripten ggf. Ausführungsrechte zuweisen.

Achtung! Bitte mit äusserster Vorsicht ausprobieren!!!!!!
Falsche Werte im Modus Write können
1. Orginale Werte überschreiben. Die sind dann unwiederruflich weg.
2. Können falsche Werte das Gerät oder weitere angeschlossene Devices beschädigen oder zerstören.
Daher zuerst alle Werte die verändert werden sollen sichern. (Auslesen und abspeichern!)

Ich übernehme keine Gewährleistung für etwaige Schäden.
Freue mich aber über Kritik, Anregungen oder Verbesserungen.

Steuere damit eine LadeBox Typ WallBe Pro für ein E-Auto via Smartphone
Ladeleistung, Timer, Ladung An/aus und Status.
Werde die Ladeleistung des Autos nun mit der aus meinen Wechselrichter SolarEdge SEK7
ausgelesenen Solarleistung syncronisieren.

Dank an Andrey-Nakin für die großartige Vorarbeit. Musste nur Kleinigkeiten anpassen. Siehe MIT License.
RaspberryPI 3B+ PivCCU3. LEDs und Taster an GPIO´s, Fenstersensoren, Rolladenaktoren, Sirene,HQ WebUI, CuxD, XML-API, E-Mail, USB Zählersensor am Raspberry, OpenWeatherMap.API, 1 Wire Temperatursensoren.
WallBe Pro Ladebox und Solaredge Solaranalage via ModBus Anbindung. CarWings/NissanEV anbindung.
SMA Sunny Boy Storage.

twoxx
Beiträge: 534
Registriert: 16.03.2015, 18:57
Hat sich bedankt: 1 Mal
Danksagung erhalten: 26 Mal

Re: ModBus TCP Interface

Beitrag von twoxx » 06.01.2020, 18:25

Super Sache!

Damit entfällt die Nutzung von IoBroker oder Redmatic oder ähnliches komplett, wenn man einfach nur ein paar Werte in die CCU übernehmen will!!!
- Charly - Raspymatic mit Redmatic, 420 Systemvariablen, 440 Programmen, 101 Direktverknüpfungen, 121 Geräten
- CCU3- Raspymatic mit Redmatic und Verbindung zur PV-Anlage/Wechselrichter
- Charly - Raspymatic mit Redmatic und Sprachsteuerung per Alexa

dako0815
Beiträge: 2
Registriert: 15.01.2020, 13:50

Re: ModBus TCP Interface

Beitrag von dako0815 » 15.01.2020, 17:09

hi Indi55
Ich hab das heute bei mir mal an meiner Wärmepumpe getestet. Allerdings bekomme ich leider immer nur eine 0 zurück :(
Wenn ich das ganze am smartphone über die app Modbus Viewer teste, dann kann ich die werte auslesen. Also Port, IP, Funktion und Register funktionieren eigentlich...

Mein Testscript sieht so aus:
var luft = system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.2.10 502 1 04 3 2",&lGetOut,&lGetErr);
WriteLine(luft);

Bei dem Register aus dem genannten Beispiel bekomme ich über die Smartphone App hex 00 E0 (dez 224) zurück. Hast du vielleicht eine Idee woran das liegt das ich mit dem Script immer nur die 0 zurück bekomme?

haengematte
Beiträge: 6
Registriert: 04.01.2019, 15:54

Re: ModBus TCP Interface

Beitrag von haengematte » 15.01.2020, 19:31

Hallo dako0815,

ich habe das wie folgt gelöst:
Der erste Teil ist das Auslesen mit system.Exec() und der zweite Teil wenn du CUxD verwenden willst.
Ich schreibe mir die Werte von meinem Speicher in die Variablen (hier "E3DC_Haus").

Code: Alles auswählen

! **************** Lesen mit system.Exec ****************
string lGetOut;
string lGetErr;

! Lesen des Wertes
system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.178.142 502 255 03 71 1",&lGetOut,&lGetErr);
! Schreiben in Systemvariable formatiert (lGetOut ist ein Sting, die Ausgabe dann ein Zahlenwert)
dom.GetObject('E3DC_Haus').State(0 + lGetOut);
! Ausgabe 
WriteLine("E3DC_Haus:  " + (0 + lGetOut));


! **************** Lesen mit CUxD ****************
var tst1;
! Lesen des Wertes 
dom.GetObject("CUxD.CUX2801006:16.CMD_SETS").State("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.178.142 502 255 03 71 1");
dom.GetObject("CUxD.CUX2801006:16.CMD_QUERY_RET").State(1);
! Zuweisen in Variable
tst1 = dom.GetObject("CUxD.CUX2801006:16.CMD_RETS").State();
! Schreiben in Systemvariable formatiert (lGetOut ist ein Sting)
dom.GetObject('E3DC_Haus').State(tst1);
! Ausgabe
WriteLine("E3DC_Haus:  " + tst1);
@Indi55:
Das ist eine super Arbeit von dir. Es funktioniert echt super. Somit konnte ich mir einen Raspbi sparen, der mir zuvor die Werte ausgelesen hat.
Danke dir für die Arbeit.

Benutzeravatar
Indi55
Beiträge: 10
Registriert: 03.11.2016, 19:54
Wohnort: Köln
Danksagung erhalten: 5 Mal

Re: ModBus TCP Interface

Beitrag von Indi55 » 15.01.2020, 20:01

Hallo,
es gibt bei einigen Geräten ein Problem mit der Zählweise der Register.
Manche beginnen mit 0 andere mit 1.
Mein Solaredge Solarregler hat dadurch einen Offset von -1, den muss ich
bei den Registeradressen abziehen.
Einfach einen bekannten festen Wert auslesen. Wenn der Wert nicht stimmt eine
Registeradresse darüber oder darunter ausprobieren.

Gruß
RaspberryPI 3B+ PivCCU3. LEDs und Taster an GPIO´s, Fenstersensoren, Rolladenaktoren, Sirene,HQ WebUI, CuxD, XML-API, E-Mail, USB Zählersensor am Raspberry, OpenWeatherMap.API, 1 Wire Temperatursensoren.
WallBe Pro Ladebox und Solaredge Solaranalage via ModBus Anbindung. CarWings/NissanEV anbindung.
SMA Sunny Boy Storage.

dako0815
Beiträge: 2
Registriert: 15.01.2020, 13:50

Re: ModBus TCP Interface

Beitrag von dako0815 » 15.01.2020, 22:16

Hallo haengematte,
vielen Dank für das Beispiel. Damit funktioniert es jetzt bei mir auch :wink: Lag also wohl an dem fehlenden umformatieren :D
Jetzt kann ich richtig loslegen. Das ist sooooooo geil :D

@indi55: Das mit der Zählweise wusste ich und hatte ich auch schon versucht. Aber auch dir auf jedenfall vielen Dank für die Arbeit. Das ist genau das was ich gesucht hatte!!!!

S_N
Beiträge: 1
Registriert: 16.04.2020, 21:34

Re: ModBus TCP Interface

Beitrag von S_N » 16.04.2020, 21:59

Hi, vielleicht kann mir jemand auf die Sprünge helfen:
Ich versuche eine Float-Variable mit 32bit auszulesen. Gemäß der Dokumentation meines Gerätes ist die Reihenfolge CDAB.

Code: Alles auswählen

System.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.0.3 502 1 03 132 4",&lGetOut,&lGetErr);
Ich müsste also die beiden Highbytes mit den beiden Lowbytes tauschen und danach eine Realzahl daraus machen.
Hat jemand eine Idee?

cityofsilence
Beiträge: 269
Registriert: 14.11.2018, 20:43
System: CCU
Wohnort: Bayern
Hat sich bedankt: 14 Mal
Danksagung erhalten: 17 Mal

Re: ModBus TCP Interface

Beitrag von cityofsilence » 29.04.2020, 23:51

Hallo,
ich möchte mich gerne meinen Vorredner anschließen.
Wäre super wenn jemand ein Script oder Idee hätte den ausgelesenen Wert auf 32 Bit Float zu bringen.
Ansonsten funktioniert es top.
Wäre super dann könnte ich den Raspberry endlich abschalten.

Vielen Dank
Gruß André

haengematte
Beiträge: 6
Registriert: 04.01.2019, 15:54

Re: ModBus TCP Interface

Beitrag von haengematte » 11.05.2020, 22:14

Hallo S_N und cityofsilence,

ich habe das so gelöst (Der Code könnte noch schöner aussehen, aber er funktioniert):

Code: Alles auswählen

var tst1
!Berechne niedrigstes byte aus integer
dom.GetObject("CUxD.CUX2801006:16.CMD_SETS").State("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.178.142 502 255 03 81 1");
dom.GetObject("CUxD.CUX2801006:16.CMD_QUERY_RET").State(1);
tst1 = dom.GetObject("CUxD.CUX2801006:16.CMD_RETS").State();
integer eigenCalc;
eigenCalc = (0 + tst1);
eigenCalc = eigenCalc-(eigenCalc/256)*256;
dom.GetObject('E3DC_Eigen').State(eigenCalc);
WriteLine("E3DC_Eigen:  " + eigenCalc);

dom.GetObject("CUxD.CUX2801006:16.CMD_SETS").State("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.178.142 502 255 03 81 1");
dom.GetObject("CUxD.CUX2801006:16.CMD_QUERY_RET").State(1);
tst1 = dom.GetObject("CUxD.CUX2801006:16.CMD_RETS").State();
integer autark;
autark = (0 + tst1)/256;
dom.GetObject('E3DC_Autark').State(autark);
WriteLine("E3DC_Autark:  " + autark);
Das Auslesen mache ich nicht über das System.Exec, sondern verwende CUxD was stabiler ist, geht aber auch mit System.Exec-Befehl.
Ich verwende nur integer Werte in diesem Fall (0+tst1) formatiert mir den Wert.

Tomiliy
Beiträge: 156
Registriert: 03.12.2014, 19:28
Hat sich bedankt: 12 Mal
Danksagung erhalten: 1 Mal

Re: ModBus TCP Interface

Beitrag von Tomiliy » 07.10.2020, 19:41

Hallo,

falls es jemand benötigt,
hier mal das Script für ein E3DC S10e.
Danke an meine Vorarbeiter und an den Ersteller der Hauptscripte :-)

Code: Alles auswählen

var Hausverbrauch;
var BatteLeistung;
var BatterieStatus;
var Netzleistung;
var Solarproduktion;
var Wallbox;
! Lesen des Wertes Hausverbrauch
dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.99.32 502 01 03 71 1");
dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
! Zuweisen in Variable
Hausverbrauch = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();
! Schreiben in Systemvariable formatiert (lGetOut ist ein Sting)
dom.GetObject('E3DC-Hausverbrauch').State(Hausverbrauch);

! Lesen des Wertes BatteLeistung
dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.99.32 502 01 03 69 1");
dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
! Zuweisen in Variable
BatteLeistung = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();
! Schreiben in Systemvariable formatiert (lGetOut ist ein Sting)
dom.GetObject('E3DC-Batterie').State(BatteLeistung);

! Lesen des Wertes BatterieStatus
dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.99.32 502 01 03 82 1");
dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
! Zuweisen in Variable
BatterieStatus = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();
! Schreiben in Systemvariable formatiert (lGetOut ist ein Sting)
dom.GetObject('E3DC-Batterie-Status').State(BatterieStatus);

! Lesen des Wertes Netzleistung
dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.99.32 502 01 03 73 1");
dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
! Zuweisen in Variable
Netzleistung = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();
! Schreiben in Systemvariable formatiert (lGetOut ist ein Sting)
dom.GetObject('E3DC-NetzStrom').State(Netzleistung);

! Lesen des Wertes Solarproduktion
dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.99.32 502 01 03 67 1");
dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
! Zuweisen in Variable
Solarproduktion = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();
! Schreiben in Systemvariable formatiert (lGetOut ist ein Sting)
dom.GetObject('E3DC-Photovoltaik-Leistung').State(Solarproduktion);

! Lesen des Wertes Wallbox
dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.99.32 502 01 03 77 1");
dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
! Zuweisen in Variable
Wallbox = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();
! Schreiben in Systemvariable formatiert (lGetOut ist ein Sting)
dom.GetObject('E3DC-Wallbox-Leistung').State(Wallbox);

! Ausgabe
WriteLine("E3DC-Hausverbrauch:  " + Hausverbrauch);
WriteLine("E3DC-Batterie:  " + BatteLeistung);
WriteLine("E3DC-Batterie-Status:  " + BatterieStatus);
WriteLine("E3DC-NetzStrom:  " + Netzleistung);
WriteLine("E3DC-Photovoltaik-Leistung:  " + Solarproduktion);
WriteLine("E3DC-Wallbox-Leistung:  " + Wallbox);
--------------------------------------------
4 Kanäle in 42 Geräten:
1x HM-LC-Dim1T-FM, 1x HM-RC-8, 12x HM-Sec-SCo, 3x HM-LC-Sw1-Pl-2, 1x HM-PBI-4-FM, 1x HM-OU-CFM-Pl, 3x HM-Sen-EP, 1x HM-CC-VG-1, 1x HM-Sec-MDIR-2, 12x HM-CC-RT-DN, 1x HM-LC-Bl1PBU-FM, 1x HM-Sen-RD-O, 2x HM-PB-2-WM55-2, 1x HM-TC-IT-WM-W-EU, 1x 10000
--------------------------------------------

Antworten

Zurück zu „HomeMatic Zentrale (CCU / CCU2 / CCU3 / Charly)“