ModBus TCP Interface

Einrichtung, Anschluss und Programmierung der HomeMatic CCU

Moderator: Co-Administratoren

drose28357
Beiträge: 183
Registriert: 14.10.2011, 09:05
System: CCU
Wohnort: Bremen
Hat sich bedankt: 57 Mal
Danksagung erhalten: 7 Mal

Re: ModBus TCP Interface für Huawei SUN2000 Wechselrichter

Beitrag von drose28357 » 10.04.2023, 10:47

Hallo Indi55,
ich kann über Deine Scripte aus Beitrag 1 keine Abfragen über meinem Wechselrichter SUN2000 8KLT-M1 ausführen.
Mit den Programmen RMMS.exe (Radzio_Modbus-Master-Simulator, Windows) und "Modbus TCP CLient" (Android) klappt das Auslesen tadellos.
Mit meinem Testscript leider nicht.
In den folgenden Beispielen verwende ich die Adresse 32016 zum Auslesen von Spannung und Strom der beiden PV-Strings.

Hier mein Testscript, das ich unter "Programme und Verknüpfungen / Script testen" ausführe.

Code: Alles auswählen

! **************** Lesen mit system.Exec ****************
string lGetOut;
string 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

! Lesen des Wertes
! system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.178.142 502 255 03 71 1",&lGetOut,&lGetErr);
! Powermeter
system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.101.107 502 1 03 32016 2",&lGetOut,&lGetErr);

! Schreiben in Systemvariable formatiert (lGetOut ist ein Sting, die Ausgabe dann ein Zahlenwert)
! dom.GetObject('E3DC_Haus').State(0 + lGetOut);
! Ausgabe 
WriteLine("PV-Sting Voltage:  " + (0 + lGetOut));
WriteLine("Fehler:  " + (lGetErr));
Ausgegeben werden PV-Sting Voltage : 0 und Fehler : 0.
Ändere ich die Kontaktdaten (IP-Adresse, Device-ID etc. ) bekomme ich eine Fehlermeldung, d.h. dein Script wird korrekt ausgerufen.

Frage: Gibt es eine Möglichkeit, das Script zu debuggen, z.B. die Reply (RX) in einer Debug-Variable zurückzugeben?
P.S. Oder habe ich das Modbus-Script falsch aufgerufen ???

Hier ein paar Screenshots mit der Android App "Modbus TCP CLient".
1) Konfiguration der Verbindung
Modbus TCP Client_Config.jpg
2) Ergebnisanzeige der Abfrage, die ersten 4 Elemente zeigen Spannung (z.B. 335,6 Volt) und Strom (z.B. 7,85 A)
Modbus TCP Client_Abfrage mit Ergebnis.jpg
3) Protokoll der Abfrage-Nachrichten mit Request (TX) und Antwort (RX). Der letzte Vorgang enthält die Daten für die oben gezeigte Ergebnisanzeige) Die Adresse steht in [125,16] etc. das sieht vernünftig aus.
Modbus TCP Client_Modbus-Nachrichten.jpg
RaspberryMatic auf Raspberry Pi 4 2Gbyte

drose28357
Beiträge: 183
Registriert: 14.10.2011, 09:05
System: CCU
Wohnort: Bremen
Hat sich bedankt: 57 Mal
Danksagung erhalten: 7 Mal

Re: ModBus TCP Interface

Beitrag von drose28357 » 15.04.2023, 12:09

By the way... Mit Node Red auf Raspberrymatic funktioniert die ModBus Kommunikation. Ich kann jetzt eine Systemvariable mit der aktueller PV-Leistung befüllen.
RaspberryMatic auf Raspberry Pi 4 2Gbyte

charlie0815
Beiträge: 19
Registriert: 09.07.2019, 14:33
Hat sich bedankt: 3 Mal

Re: ModBus TCP Interface

Beitrag von charlie0815 » 27.04.2023, 07:49

Hallo zusammen,

ich verwende folgende Umrechnung von funkleuchtturm von einem Integer Wert zu 32bit Float sw

Code: Alles auswählen

! WP Lesen des Wertes kwh des Zaehlers Heizung
dom.GetObject("CUxD.CUX2801001:16.CMD_SETS").State("tclsh /usr/local/addons/modbus/modbus_interface.tcl XXXXXXXXXXX 502 1 04 72 2");
dom.GetObject("CUxD.CUX2801001:16.CMD_QUERY_RET").State(1);
! Zuweisen in Variable
var SMAValue = dom.GetObject("CUxD.CUX2801001:16.CMD_RETS").State();
 !es werden 2 register geliefert, wir wollen aber nur den zweiten teil von ("0 1000")
WriteLine("WP Modbus-Wert fuer Zaehkerstand Heizung: "+SMAValue);



var hword = SMAValue;  
integer space_pos = hword.Find(" ");        
!WriteLine("Space: "+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: "+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: "+hword); 

integer hochzahl = hword / 128;             
!WriteLine("hochzahl: "+hochzahl);
if( (hochzahl & 128) > 0) {hochzahl = 1 + (hochzahl & 127);} else {hochzahl = -128 + 1 + (hochzahl & 127);}

real mantisse = 1.0;
if( (hword & 64) > 0)     {mantisse = mantisse + 0.5; }
if( (hword & 32) > 0)     {mantisse = mantisse + 0.25; }
if( (hword & 16) > 0)     {mantisse = mantisse + 0.125; }
if( (hword & 8 ) > 0)     {mantisse = mantisse + 0.0625; }
if( (hword & 4 ) > 0)     {mantisse = mantisse + 0.03125; }
if( (hword & 2 ) > 0)     {mantisse = mantisse + 0.015625; }
if( (hword & 1 ) > 0)     {mantisse = mantisse + 0.0078125; }

if( (lword & 32768) > 0)  {mantisse = mantisse + 0.00390625; }
if( (lword & 16384) > 0)  {mantisse = mantisse + 0.001953125; }
if( (lword & 8182 ) > 0)  {mantisse = mantisse + 0.0009765625; }
if( (lword & 4096 ) > 0)  {mantisse = mantisse + 0.00048828125; }
if( (lword & 2048 ) > 0)  {mantisse = mantisse + 0.000244140625; }
if( (lword & 1024 ) > 0)  {mantisse = mantisse + 0.0001220703125; }
if( (lword & 512  ) > 0)  {mantisse = mantisse + 0.0000610351562; }
if( (lword & 256  ) > 0)  {mantisse = mantisse + 0.0000305175781; }

if( (lword & 128) > 0)    {mantisse = mantisse + 0.0000152587890; }
if( (lword & 64 ) > 0)    {mantisse = mantisse + 0.0000076293945; }
if( (lword & 32 ) > 0)    {mantisse = mantisse + 0.0000038146972; }
if( (lword & 16 ) > 0)    {mantisse = mantisse + 0.0000019073486; }
if( (lword & 8  ) > 0)    {mantisse = mantisse + 0.0000009536743; }
if( (lword & 4  ) > 0)    {mantisse = mantisse + 0.0000004768371; }
if( (lword & 2  ) > 0)    {mantisse = mantisse + 0.0000002384185; }
if( (lword & 1  ) > 0)    {mantisse = mantisse + 0.0000001192092; }

mantisse = mantisse * hochzahl.Exp2();
if( (hword & 32768) > 0) {mantisse = (-1) * mantisse;}  


WriteLine("WP Zaelkerstand Heizung in kWh: "+mantisse);

Ergebnis:
WP Modbus-Wert fuer Zaehkerstand Heizung: 17607 -13992
WP Zaelkerstand Heizung in kWh: 1595.291992

RMMA Modbus Tool liefert einen Wert von 1598.29 - also genau 3 Kwh mehr. (bei gleichen Ausgangsdaten 17607 -13992)
Das deckt sich auch mit dem Zähler im Schrank welcher ausgelesen wird.
Warum liegt das Skript dann 3 kwH drunter?
Finde den Fehler nicht :evil:
Jemand eine Idee?

Für das Auslesen verwende ich CUXD, was in meinem Fall deutlich stabiler läuft als system.exec
Ist vielleicht für den ein oder anderen hilfreich, wenn plötzlich keine Werte mehr ausgelesen werden, wie es bei mir nach 1-2 Stunden immer der Fall war.

charlie0815
Beiträge: 19
Registriert: 09.07.2019, 14:33
Hat sich bedankt: 3 Mal

Re: ModBus TCP Interface

Beitrag von charlie0815 » 27.04.2023, 10:54

mit diesen Werten ist der Unterschied genau 4.
???? :shock:
modbus.JPG

MatzEn
Beiträge: 6
Registriert: 20.08.2019, 17:26

Re: ModBus TCP Interface

Beitrag von MatzEn » 18.07.2023, 17:22

Hallo zusammen,

inzwischen habe ich auch einen HUAWEI WR + Akku und würde gerne Informationen per Modbus austauschen.

Frage an drose28357: kannst Du mal bitte genau beschreiben wie nun die Modbus Kommmunikation mit dem HUAWEI WR funktioniert?

Gruß
Matthias

be.pe
Beiträge: 281
Registriert: 11.08.2019, 16:39

Re: ModBus TCP Interface

Beitrag von be.pe » 06.08.2023, 13:13

Hallo,

Kann mir jemand mal den Unterschied der vier
Lese Register erklären:
01 read coils
02 read discrete inputs
03 read holding registers
04 read input registers
Ich möchte aus meinem Huawei Sun 2000 WR 10 kw
verschiedene Werte, wie Produktion der PV, Speicher Ladung und Entladung etc. auslesen, weiss aber nicht welches Register ich verwenden muss?

Benutzeravatar
blackhole
Beiträge: 3730
Registriert: 21.07.2015, 14:03
System: CCU
Hat sich bedankt: 184 Mal
Danksagung erhalten: 587 Mal

Re: ModBus TCP Interface

Beitrag von blackhole » 06.08.2023, 14:00

be.pe hat geschrieben:
06.08.2023, 13:13
Kann mir jemand mal den Unterschied der vier
Lese Register erklären:
01 read coils
02 read discrete inputs
03 read holding registers
04 read input registers

Das sind Modbus-Protokollgrundlagen und können in kompakter Form beispielsweise im entsprechenden Wikipedia-Artikel nachgelesen werden:

:arrow: https://de.wikipedia.org/wiki/Modbus

Gerätespezifisch liefert jeder renomierte Hersteller eine Dokumentation mit Registerwerten und zugehöriger Beschreibung der Register.

be.pe
Beiträge: 281
Registriert: 11.08.2019, 16:39

Re: ModBus TCP Interface

Beitrag von be.pe » 06.08.2023, 17:24

Hey,
ich möchte was aus dem WR auslesen, woher weiß ich denn welche der Funktionen:
01 read coils
02 read discrete inputs
03 read holding registers
04 read input registers
ich verwenden muss um einen Wert auszulesen?
Steht das in der Anleitung von Huawei Modbus oder muss ich einfach testen?

Ich habe anbei mal einen Auschnitt aus dem Definitions Register von Huawei.
Kann mir mal jemand, evt. für eine Registernr. ein Beispiel schreiben im Skript im Bereich fett markiert:
dom.GetObject("CUxD.CUX2801001:16.CMD_SETS").State("tclsh /usr/local/addons/modbus/modbus_interface.tcl XXXXXXXXXXX 502 1 04 72 2");
Danke.

Benutzeravatar
blackhole
Beiträge: 3730
Registriert: 21.07.2015, 14:03
System: CCU
Hat sich bedankt: 184 Mal
Danksagung erhalten: 587 Mal

Re: ModBus TCP Interface

Beitrag von blackhole » 08.08.2023, 09:40

be.pe hat geschrieben:
06.08.2023, 17:24
Ich habe anbei mal einen Auschnitt aus dem Definitions Register von Huawei.

Und was willst du damit anfangen? In deinem Ausschnitt ist kein einziges Register beschrieben.
Du wirst dich mit der vollständigen Dokumentation (den Registerwerten und -beschreibungen) beschäftigen müssen.

be.pe
Beiträge: 281
Registriert: 11.08.2019, 16:39

Re: ModBus TCP Interface

Beitrag von be.pe » 08.08.2023, 11:08

Hey sorry, war mein Fehler, da hab ich doch glatt die falschen Seiten erwischt.
Anbei nocheinmal die korrekten Seiten.
SmartLogger ModBus Interface Definitions.PDF
(764.77 KiB) 54-mal heruntergeladen
Würde dann das auslesen über CuxD von z. B. Position 18 so aussehen:

Code: Alles auswählen

! **************** 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 1 03 40428 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);
Über eine kurze Rückinfo würde ich mich freuen.

Zweite Sache ist, das die nach dem Öffnen des Ports, ein kurze Pause erfolgen muss, bevor der Wert abgefragt werden kann, sonst antworte der WR nicht. Kann man im Script einen Befehl einpflegen, der eine Verzögerung in "ms" bewirkt?
Danke.

Antworten

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