ModBus TCP Interface

Einrichtung, Anschluss und Programmierung der HomeMatic CCU

Moderator: Co-Administratoren

Benutzeravatar
funkleuchtturm
Beiträge: 2365
Registriert: 13.06.2011, 16:42
Hat sich bedankt: 23 Mal
Danksagung erhalten: 357 Mal
Kontaktdaten:

Re: ModBus TCP Interface

Beitrag von funkleuchtturm » 16.07.2022, 15:29

Ich finde die originale TCL-Lösung von Indi55 eigentlich optimal, weil damit eine beliebige Anzahl von 16bit-Registern/Worten als ASCII-String vom Wechselrichter abgeholt werden.
Dann kann man relativ transparent und einfach mit einem HM-Skript diesen String zerlegen und nach seinen individuellen Erfordernissen dekodieren. Ich hab die aufwändige Dekodierung für 32bit-float gemacht aber die anderen gebräuchlichen Formate wie U16 oder U32 oder String dürften noch einfacher zu dekodieren sein.
Eine Dekodierung der vielen bei Wechselrichtern verwendeten Formate und Sonderformate auf TCL-Ebene ist für die meisten User viel zu kompliziert und erfordert bei Änderungen das umständliche Speichern des TCL-Programmes auf der CCU. Ein HM-Skript kann ich dagegen "relativ einfach" :mrgreen: ändern und ausprobieren.
Viele Gruesse
Eugen
________________________________________________
SmartHome-Eintopf mit feinem Homeduino-Gemüse
... und für Feinschmecker gibt´s den WIFFI, den WEATHERMAN-2, den PULSECOUNTER und den AIRSNIFFER
mit vielen Kochrezepten für den ambitionierten Homematiker

richard.mayer
Beiträge: 21
Registriert: 12.05.2016, 11:47

Re: ModBus TCP Interface

Beitrag von richard.mayer » 18.07.2022, 00:25

@JensDev:

Anscheinend verwendet SMA wirklich zwei Register. Die Abfrage mit Length 1 scheint nicht zu funktionieren:

Code: Alles auswählen

root@ccu:~# tclsh /usr/local/addons/modbus/modbus_interface.tcl wr1.mayer 502 3 13 30535 1; printf "\n";

root@ccu:~# tclsh /usr/local/addons/modbus/modbus_interface.tcl wr1.mayer 502 3 13 30535 2; printf "\n";
0 0
@eugen: So wie ich das verstehe, wertest du ja den Rückgabewert aus und rechnest dir dann bei negativem Rückgabe Wert den "richtigen" Wert aus in der CCU. Das habe ich mir auch schon überlegt und angefangen zu implementieren.
Was ich mich nur gefragt habe: Was passiert denn, wenn man bei 64+ kWh wieder bei 0 ankommt? Zählt er dann wieder hoch? Dann würde man ja irgendwann ein kleines Problem bekommen, den richtigen Wert zu erraten.

Der leichte Weg bei SMA wäre einfach ein anderen Register zu verwendet, das den Ertrag in kWh und nicht in Wh ausgibt. Leider sind das aber nur volle kWh und keine Kommawerte in diesem Register...

Schöne Grüße und vielen Dank

Richard

Benutzeravatar
funkleuchtturm
Beiträge: 2365
Registriert: 13.06.2011, 16:42
Hat sich bedankt: 23 Mal
Danksagung erhalten: 357 Mal
Kontaktdaten:

Re: ModBus TCP Interface

Beitrag von funkleuchtturm » 18.07.2022, 10:36

richard.mayer hat geschrieben:
18.07.2022, 00:25
Was passiert denn, wenn man bei 64+ kWh wieder bei 0 ankommt? Zählt er dann wieder hoch? Dann würde man ja irgendwann ein kleines Problem bekommen, den richtigen Wert zu erraten.
Du hast das verwendete Gleitkomma-Zahlensystem nicht verstanden. Es wird meistens eine 32bit-float-Zahl verwendet, die einen Zahlenraum von +/- 1,175*10EE-38 bis +/-3,4*10EE38 aufspannt. Schau Dir diese Erklärungen dazu an. Mit diesem Spielzeug kann man selbst die Zahlen kodieren.

Leider variieren die Wechselrichter-Hersteller die Zahlenformate im Modbus, so daß die 32bit bzw. 4 Bytes in der Reihenfolge ABCD oder auch CDAB übertragen werden.
In meinem HM-Skript muß man dementsprechend am Anfang die Zuordnung des "lword" und "hword" vertauschen.
Viele Gruesse
Eugen
________________________________________________
SmartHome-Eintopf mit feinem Homeduino-Gemüse
... und für Feinschmecker gibt´s den WIFFI, den WEATHERMAN-2, den PULSECOUNTER und den AIRSNIFFER
mit vielen Kochrezepten für den ambitionierten Homematiker

JensDev
Beiträge: 19
Registriert: 10.03.2020, 11:12
System: Alternative CCU (auf Basis OCCU)
Wohnort: Köln
Hat sich bedankt: 4 Mal
Danksagung erhalten: 1 Mal

Re: ModBus TCP Interface

Beitrag von JensDev » 18.07.2022, 11:30

Hier laufen zwei Sachen etwas parallel: Register mit UInt16 / UInt32 und Float. @richard.mayer: laut deinem Post hat dein SMA-WR hat ein U32 - dass wird ziemlich sicher ein unsigned integer mit 32Bit sein (UInt32). Also liefert der über 2 Register jeweils einen 16Bit-Wert, damit sollte der genug Luft nach oben haben - ganz ohne Float.
funkleuchtturm hat das Problem mit Float-Registern in ModBus behandelt - ganz andere Zahldarstellung...

Viele Grüße,
Jens

Benutzeravatar
funkleuchtturm
Beiträge: 2365
Registriert: 13.06.2011, 16:42
Hat sich bedankt: 23 Mal
Danksagung erhalten: 357 Mal
Kontaktdaten:

Re: ModBus TCP Interface

Beitrag von funkleuchtturm » 18.07.2022, 15:44

@richard.mayer
bei dem U32 ist die Auswertung noch viel einfacher als beim 32bit-Float.
Hier das nicht getestete HM-Skript für U32-Format:

Code: Alles auswählen

!modbus_tcp 32bit float Register auslesen mit TCL skript 
!https://homematic-forum.de/forum/viewtopic.php?f=26&t=55722&hilit=tcl+script#p553720
!Installation:
!Schritt 1: mit WinSCP im CCU-verzeichnis /usr/local/addons/ ein neues Verzeichnis modbus anlegen
!Schritt 2: in dieses neue Verzeichnis die tcl-Files modbus.tcl und modbus_interface.tcl reinkopieren
!Schritt 3: Das folgende Skript mit den Registernummern des eigenen Umrichters anpassen 
!Schritt 4: Folgendes HM-Skript auf der CCU z.B. alle 60sec aufrufen

string lGetOut;
string lGetErr;
system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.178.35 1502 71 03 172 2",&lGetOut,&lGetErr);
var hword = lGetOut;                        !WriteLine(hword);
integer space_pos = hword.Find(" ");        !WriteLine(space_pos);

var lword = 0 + hword.Substr(0,space_pos);  !bei datenfolge CDAB
!var lword = 0 + hword.Substr(space_pos);  !bei datenfolge ABCD
if(lword < 0) {lword = lword + 32768;}      !WriteLine(lword); 

hword = 0 + hword.Substr(space_pos);      !bei datenfolge CDAB  
!hword = 0 + hword.Substr(0,space_pos);      !bei datenfolge ABCD   
if(hword < 0) {hword = hword + 32768;}      !WriteLine(hword); 

integer result = lword + (65536 * hword);      WriteLine(result); 

dom.GetObject('kostal_leistung').State(result);
Je nach Reihenfolge der gesendeten Bytes sind die Zeilen mit ABCD oder CDAB mit dem Kommentar-Rufzeichen zu aktivieren
Viele Gruesse
Eugen
________________________________________________
SmartHome-Eintopf mit feinem Homeduino-Gemüse
... und für Feinschmecker gibt´s den WIFFI, den WEATHERMAN-2, den PULSECOUNTER und den AIRSNIFFER
mit vielen Kochrezepten für den ambitionierten Homematiker

richard.mayer
Beiträge: 21
Registriert: 12.05.2016, 11:47

Re: ModBus TCP Interface

Beitrag von richard.mayer » 06.08.2022, 18:36

@funkleuchtturm:
Vielen Dank für die Tipps.
Genau wie in deinem Beispiel hat es leider nicht funktioniert (keine Ahnung, was SMA da macht mit den Variablen), aber ich habe es mir jetzt so hingefrickelt in der CCU, dass es die richtigen Werte von meinen beiden Wechselrichtern ausliest, entsprechend anpasst, wenn der Wert über 32kWh ist, addiert und in eine Systemvariable schreibt.

Betonung auf "hingefrickelt" und fast schon peinlich, das hier so zu posten, aber vielleicht hilft es ja jemandem mit SMA-Componenten weiter... :shock:

Code: Alles auswählen

dom.GetObject ("CUxD.CUX2801001:2.CMD_SETS").State ("tclsh /usr/local/addons/modbus/modbus_interface.tcl wr1.mayer 502 3 13 30535 10 | /usr/bin/awk '{print $2}'");
dom.GetObject ("CUxD.CUX2801001:2.CMD_QUERY_RET").State (1);
var xtagesleistung = dom.GetObject ("CUxD.CUX2801001:2.CMD_RETS").State();
var x2tagesleistung = xtagesleistung.ToFloat();
!WriteLine(x2tagesleistung);

if(x2tagesleistung < 0) {x2tagesleistung = x2tagesleistung + 32768;
var x3tagesleistung = x2tagesleistung + 32768; 
var tagesleistung = x3tagesleistung/1000;
var tagesleistungstring = tagesleistung.ToString(2);
!WriteLine(tagesleistungstring);
!dom.GetObject("PV-Tagesleistung").State(tagesleistungstring);
                        }
else {
var tagesleistung = x2tagesleistung/1000;
var tagesleistungstring = tagesleistung.ToString(2);
!WriteLine(tagesleistungstring);
!dom.GetObject("PV-Tagesleistung").State(tagesleistungstring);
}


dom.GetObject ("CUxD.CUX2801001:10.CMD_SETS").State ("tclsh /usr/local/addons/modbus/modbus_interface.tcl wr2.mayer 502 3 13 30535 10 | /usr/bin/awk '{print $2}'");
dom.GetObject ("CUxD.CUX2801001:10.CMD_QUERY_RET").State (1);
var westtagesleistung = dom.GetObject ("CUxD.CUX2801001:10.CMD_RETS").State();
var x2westtagesleistung = westtagesleistung.ToFloat();
WriteLine(x2westtagesleistung);

if(x2westtagesleistung < 0) {x2westtagesleistung = x2westtagesleistung + 32768;
var west2tagesleistung = x2westtagesleistung + 32768; 
var westfinaltagesleistung = west2tagesleistung/1000;
var westfinaltagesleistungstring = westfinaltagesleistung.ToString(2);
!WriteLine(westfinaltagesleistungstring);
var westostsuedtagesleistung = tagesleistung + westfinaltagesleistungstring;
  
var westostsuedtagesleistungstring = westostsuedtagesleistung.ToString(2);
WriteLine(westostsuedtagesleistungstring);

dom.GetObject("PV-Tagesleistung").State(westostsuedtagesleistungstring);}
else {
var westfinaltagesleistung = x2westtagesleistung/1000;
var westfinaltagesleistungstring = westfinaltagesleistung.ToString(2);
  
var westostsuedtagesleistung = tagesleistung + westfinaltagesleistungstring;
  
var westostsuedtagesleistungstring = westostsuedtagesleistung.ToString(2);
WriteLine(westostsuedtagesleistungstring);

dom.GetObject("PV-Tagesleistung").State(westostsuedtagesleistungstring);}

nseith
Beiträge: 320
Registriert: 23.06.2013, 11:08
Wohnort: bei Karlsruhe
Hat sich bedankt: 8 Mal
Danksagung erhalten: 3 Mal

Re: ModBus TCP Interface - fuer go-e Charger

Beitrag von nseith » 07.09.2022, 17:49

Hallo in die Runde,

ich versuche gerade den Go-E per Modbus https://github.com/goecharger/go-eCharg ... v1%20DE.md auszulesen, wie ich es auch schon seit laengerem erfolgreich mit dem SMA Wechselrichter mache, allerdings mit dem SMA.tcl script von hier viewtopic.php?f=31&t=47813#p478866

Ich habe mich hier an diesem Script versucht aber ich bekomme immer
open
zurueck.
string lGetOut = "";
string lGetErr = "";
system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.254.65 502 1 04 100 1",&lGetOut,&lGetErr);
!var WBValue=dom.GetObject("_wallb");
!WBValue.State(lGetOut.StrValueByIndex(" ", 1));
WriteLine(lGetOut.StrValueByIndex(" ", 1));
Das Register liefert die werte 0-4 welche ich dann gleich in eine Werte Variable schreiben will
Also wenn Register
100 = 0 dann Variable = unbekannt
100 = 1 dann Variable = bereit

etc.

Leider hat die Suche nach go-e immer nur zu rednote und ioBroker verwiesen - ich will aber nur wissen ob mein Auto steckt ect.

Danke fuer euren Support

henni2000
Beiträge: 1
Registriert: 08.09.2022, 19:32
System: CCU

Re: ModBus TCP Interface

Beitrag von henni2000 » 08.09.2022, 20:08

Hallo zusammen,
vielen Dank für diesen Beitrag. Ich versuche auch gerade meinen Fronius-Wechselrichter mit meiner Wallbox per modbus zu koppeln. Den Fronius-WR kann ich perJson-API auslesen. Die modbus-Verbindung habe ich mit dem TCL-Interface auch erfolgreich getestet, zumindest was das Lesen der Werte angeht. Meine Wallbox benutzt Float32-Werte. Mit dem HM-Skript von @funkleuchtturm kann ich die Float32-Werte auslesen und umwandeln. Allerdings hapert es bei mir noch bei der Konvertieren des Float-Wertes in high/low word, so dass ich sie mit dem TCL-Interface in das entsprechende Register der Wallbox laden kann. Hat sich das zufälligerweise schon Jemand angeschaut und könnte hier Tipps geben?

Viele Grüße,
Stefan

alex k.
Beiträge: 2
Registriert: 17.12.2016, 18:03
Wohnort: Wiernsheim

Re: ModBus TCP Interface

Beitrag von alex k. » 16.10.2022, 22:34

Vielen Dank für das tolle Script, klappt wunderbar mit meinem Kostal Plenticore! :P

Bisher bin in den Unweg über www.solaranzeige.de gegangen, was aber dazu geführt hat, dass die Daten vom Plenticore über die solaranzeige zur Homematic nicht immer rechtzeitig für die Berechnung des Hausverbrauchs vorhanden waren und dann unschöne Zappelkurven entstanden sind.... ich bin schon gespannt wie das morgen aussieht wenn meine PV-Anlage wieder Strom erzeugt :wink:

Gruß, Alex

WolfHenk
Beiträge: 14
Registriert: 29.07.2019, 09:44
Hat sich bedankt: 1 Mal

Re: ModBus TCP Interface

Beitrag von WolfHenk » 29.10.2022, 23:01

...okay... ich versuche nun scon seit Tagen ein modbus slave in den cux rein zu kriegen.

Mit "tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.3.219 502 1 2 0 1" kann ich problemlos die vier Eingänge einzeln lesen (wobei die von 0 bis 3 zählen und ich sie einzeln haben will).
Ich kann sie auch in Systemvariablen abbilden, wie in den vorigen Beiträgen beschrieben. Dazu Aufruf eines Scripts alle 10 Sekunden.

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.3.219 502 1 2 0 1",&lGetOut,&lGetErr);
! Schreiben in Systemvariable formatiert (lGetOut ist ein Sting, die Ausgabe dann ein Zahlenwert)
dom.GetObject('ModbusIn1').State(0 + lGetOut);
! Ausgabe 
WriteLine("ModbusIn1:  " + (0 + lGetOut));

system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.3.219 502 1 2 1 1",&lGetOut,&lGetErr);
dom.GetObject('ModbusIn2').State(0 + lGetOut);
! Ausgabe 
WriteLine("ModbusIn2:  " + (0 + lGetOut));

system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.3.219 502 1 2 2 1",&lGetOut,&lGetErr);
dom.GetObject('ModbusIn3').State(0 + lGetOut);
! Ausgabe 
WriteLine("ModbusIn3:  " + (0 + lGetOut));

system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.3.219 502 1 2 3 1",&lGetOut,&lGetErr);
dom.GetObject('ModbusIn4').State(0 + lGetOut);
! Ausgabe 
WriteLine("ModbusIn4:  " + (0 + lGetOut));
So kann ich auch meine Ausgänge (Coils) schreiben:

Code: Alles auswählen

var out1 = dom.GetObject("ModbusOUT1").Value(); 
if (out1) { 
system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.3.219 502 1 5 0 1",&lGetOut,&lGetErr);
WriteLine("ModbusOUT1: AN");
          };
if (!out1) { 
system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.3.219 502 1 5 0 0",&lGetOut,&lGetErr);
WriteLine("ModbusOUT1: AUS");
          };
          ....
Ziemlich dillettantisch. Ich weiß.

Aber eigentlich will ich ein Gerät daraus haben mit vier Eingängen und vier Ausgängen.
Ich will also die vier Eingänge als Zustand sehen und die vier Coils einzeln schalten können
Ich kriege das aber mit dem Cuxd nicht gebacken. Ich verstehe die Doku nicht.

Achja: Was solls werden: Ich will mit ner Siemens LOGO! kommunizieren und mit einigen anderen Modbus-Geräten. Da die LOGO nicht mailen kann, was die Raspberrymatic dafür gut kann ;) sollen also von der LOGO! Signale kommen, die der Raspberrymatic sagen: Hier, Mail mir mal....
Und an anderer Stelle soll die Rasberrymatic dann auch der Logo verschiedene Signale geben können.
Im Grunde sollen sich die beiden Systeme ergänzen und miteinander Signale tauschen können.

Kann mir hier wer helfen?

Antworten

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