ModBus TCP Interface
Moderator: Co-Administratoren
- funkleuchtturm
- Beiträge: 2367
- Registriert: 13.06.2011, 16:42
- Hat sich bedankt: 23 Mal
- Danksagung erhalten: 357 Mal
- Kontaktdaten:
Re: ModBus TCP Interface
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" ändern und ausprobieren.
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" ä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
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
-
- Beiträge: 21
- Registriert: 12.05.2016, 11:47
Re: ModBus TCP Interface
@JensDev:
Anscheinend verwendet SMA wirklich zwei Register. Die Abfrage mit Length 1 scheint nicht zu funktionieren:
@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
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
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
- funkleuchtturm
- Beiträge: 2367
- Registriert: 13.06.2011, 16:42
- Hat sich bedankt: 23 Mal
- Danksagung erhalten: 357 Mal
- Kontaktdaten:
Re: ModBus TCP Interface
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.richard.mayer hat geschrieben: ↑18.07.2022, 00:25Was 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.
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
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
-
- 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
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
funkleuchtturm hat das Problem mit Float-Registern in ModBus behandelt - ganz andere Zahldarstellung...
Viele Grüße,
Jens
- funkleuchtturm
- Beiträge: 2367
- Registriert: 13.06.2011, 16:42
- Hat sich bedankt: 23 Mal
- Danksagung erhalten: 357 Mal
- Kontaktdaten:
Re: ModBus TCP Interface
@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:
Je nach Reihenfolge der gesendeten Bytes sind die Zeilen mit ABCD oder CDAB mit dem Kommentar-Rufzeichen zu aktivieren
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);
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
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
-
- Beiträge: 21
- Registriert: 12.05.2016, 11:47
Re: ModBus TCP Interface
@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...
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...
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);}
-
- 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
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
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
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
zurueck.open
Das Register liefert die werte 0-4 welche ich dann gleich in eine Werte Variable schreiben willstring 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));
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
Re: ModBus TCP Interface
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
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
Re: ModBus TCP Interface
Vielen Dank für das tolle Script, klappt wunderbar mit meinem Kostal Plenticore!
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
Gruß, Alex
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
Gruß, Alex
Re: ModBus TCP Interface
...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.
So kann ich auch meine Ausgänge (Coils) schreiben:
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?
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));
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");
};
....
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?