Fenecon über Modbus TCP auslesen von Homematic CCU

Hallo,

ich möchte gerne mit meiner Homematic CCU2 über Scripte und das Modbus_interface.tcl Werte wie Speicherbeladung, Einspeisung bzw. Netzbezug und Erzeugung auslesen.
302 _sum/EssSoc
303 _sum/EssActivePower
315 _sum/GridActivePower
327 _sum/ProductionActivePower
415 _sum/EssDischargePower

Die Inspiration dazu habe ich aus folgendem Homematic-Forum Beitrag: ModBus TCP Interface - HomeMatic-Forum / FHZ-Forum

Mit dem QModMaster funktioniert das über den PC einwandfrei.

Wenn ich folgendes Script in der Homematic teste erhalte ich jedoch keinen Wert zurück:

string lGetOut;
string lGetErr;
WriteLine("Hallo Welt!");
WriteLine("Fenecon:  " + (0 + lGetOut));
WriteLine("Error:  " + (0 + lGetErr));
! Lesen des Wertes
system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.179.54 502 302 01 4 1",&lGetOut,&lGetErr);
! Schreiben in Systemvariable formatiert (lGetOut ist ein Sting, die Ausgabe dann ein Zahlenwert)
dom.GetObject('Fenecon').State(0 + lGetOut);
! Ausgabe 
WriteLine("Error:  " + (0 + lGetErr));
WriteLine("Fenecon:  " + (0 + lGetOut));

Folgendes Ergebnis bekomme ich im Ausgabe Screen in Homematic:

Hallo Welt!
Fenecon:  0
Error:  0
Error:  0
Fenecon:  0

Das bedeutet das der Aufruf erfolgreich durchgeführt wird, aber in die Variable lGetOut bzw. der String Fenecon auf 0 bleiben.

Mit dem QModMaster kommt beim Funktionscode 302 60 herraus was 60% Speicherbeladung entspicht.

Ich fürchte mein Problem liegt bei den Parametern des Aufrufes der Funktion:

Nach IP Adresse 192.168.179.54 und port 502 folgende die parameter
302 Functionscode
01 Number Registers
4 Länge ?
1 Wert ?

Bei Länge und Wert weiss ich leider nicht welcher Doku ich entnehmen kann wie die berechnet werden. Das muß vom Type unit16, float32, float64 sow wie von der Einstellung DEX, HEX, BIN, float abhängen.

Aber wie kommt man hier auf die richtigen Übergabe Parameter ?

Gibt es jemand der damit bereits Erfahrung hat un mir weiterhelfen kann ?

Hallo @Pitsunny und willkommen in der OpenEMS Community,

von HomeMatic habe ich keine Ahnung, aber in dem verlinkten Thread ist dieses Script so dokumentiert:

system.Exec(“tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.010.100 502 255 03 528 1”,&lGetOut,&lGetErr);
Lesen : modbus_interface.tcl IP-Adresse Port DeviceNummer Funktion Register Länge

Also konkret:

Für den Ladezustand von FEMS/OpenEMS benötigst du:

  • IP-Adresse: 192.168.179.54
  • Port: 502
  • DeviceNummer: 1
  • Funktion: 03
  • Register: 302
  • Länge: 1 (optional könntest du evtl. auch gleich mehrere Register auf einmal lesen, dann hier die Zahl erhöhen)

Zusammengefasst müsste dann dieser Befehl funktionieren:

system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.179.54 502 1 03 302 1",&lGetOut,&lGetErr);

Gruß,
Stefan

Hallo Stefan,

super - vielen Dank für die Info !!!
Hier das Ergebnis:

Hallo Welt!
Fenecon: 0
Error: 0
Error: 0
Fenecon: 61

Der Speicher ist aktuell auf 61% - Geht also prima !!!

Allerbesten Dank !

Gruß
Peter

1 Like

Hallo Stefan,

ich habe jetzt einige Zeit versucht mal ein float32 Wert auszulesen um z.B. _sum/GridActivePower auszulesen oder andere die in Watt angeben sind.
Es kommt dabei zwar ein Wert raus - aber der ergibt wenig Sinn.
Ich habe das mal mit dem Programm Modbus Poll laufen lassen.

Das Programm pollt jede Sekunde die Adresse 315 und es werden 2 Werte ausgelesen.
Der erste Wert (Zeile 5) “17459” entspricht einem Strom von Grid von etwa 0.7 kW.
Wenn ich den Strom auf 1kW erhöhe geht der Wert auch hoch auf etwa “17540”, bei 1,7 kW auf “17650”…
Also ich scheine hier schon an der richtige Stelle der Adresse 315 zu sein.
Der zweite Zeile 6) Wert schwankt unabhängig vom Strom zwische den Werte 16384, -16384, 32767, also HEX4000, 8000, etc.
Mir ist jetzt nur nicht klar wie ich den ersten Wert in einen Wert der im FEMS angezeigt wird umrechnen kann.

Wenn Du mir hier nochmal einen Tipp geben könntest wäre ich sehr froh. Dann wäre ich mit der Homematic in der Lage auf die Werte entsprechend zu reagieren und Verbraucher zu schalten.

Vorab schon mal Danke
Gruß
Peter

Bye the way …
Herr Lacanina hat mir beim letzen call mal gesagt, das man für Fenecon und Fenecon Mitarbeiter auch eine Bewertung abgeben kann.
Das würde ich gerne mal machen :slight_smile:
Kannst Du mir bitte mal einen Link mitteilen wo ich das machen kann.
Danke und Gruß
Peter

Hallo Peter,

Float-Werte werden nach der Norm IEEE-754 ausgegeben, die beiden Integer-Werte bringen dir deshalb nicht direkt etwas.

Beispiel. Du liest für die beiden Register

315 = 17459
316 = 16384

Binär steht dort aber eigentlich

315 = 0100010000110011
316 = 0100000000000000

Das kannst du zu einem 32-Bit string zusammenfassen:

315 = 01000100001100110100000000000000

Und per Online-Tool umwandeln:

https://www.h-schmidt.net/FloatConverter/IEEE754.html

Das wären also “717 Wh”.

Die Energie-Register enthalten dabei jeweils nur den aufsummierten Energiewert. Um z. B. die Energie eines Tages zu bekommen, müsstest du jeweils um 0 Uhr auslesen und die Werte dann voneinander abziehen.

Gruß,
Stefan


Unser lieber Nino La Cagnina meinte wahrscheinlich eine Bewertung auf Google :slight_smile:FENECON GmbH - Hauptstandort Rezensionen - Google Suche

Hallo Stefan,

sorry für die späte Rückmeldung. Aber Du hast mir wieder sehr weiter geholfen. Leider habe ich keine SW gefunden die die Umrechnung der Werte macht. Aber ich habe mir dann halt selbst etwas geschrieben, über String Funktionen, um die einzelnen Werte umzurechnen. Etwas langsam, aber klappt prima !
Aller besten Dank für Deine Informationen. Bin jetzt IEEE 754 Spezialist :wink:

Habe auch eben eine Google Rezession eingestellt.

Beste Grüße
Peter

2 Likes

Hier habe ich auch was passendes gefunden. Fenecon verwendet doch GoodWe Technik. Könnte passen.
https://solaranzeige.de/phpBB3/viewtopic.php?t=3236

@Pitsunny Könntest du hier veröffentlichen, wie du es gelöst hast? Ich habe ebenfalls einige Stunden investiert und Informationen aus verschiedenen Foren zusammengetragen. Basierend auf dem oben genannten Add-On habe ich eine Lösung gebastelt, die zumindest für Float 32 auch mit negativen Werten funktioniert.

!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:
!https://homematic-forum.de/forum/viewtopic.php?f=26&t=55722&p=725181&hilit=Float+32+modbus#p725181
!Schritt 1: mit WinSCP im CCU-verzeichnis /usr/local/addons/ ein Unterverzeichnis modbus anlegen
!Schritt 2: in dieses neue Verzeichnis die tcl-Files modbus.tcl und modbus_interface.tcl reinkopieren
!Schritt 3: Das folgende HM-Skript mit den Registernummern und Daten des eigenen Umrichters anpassen 
!Schritt 4: Dieses HM-Skript auf der CCU mit Steuerprogramm z.B. alle 60sec aufrufenstring lGetOut='NAN';
!Schritt 5: Systemvariablen FEMS_... vom Typ Zahl auf der CCU anlegen

string lGetErr='NAN';
var hw;
var lw;
real mantisse;
integer space_pos;
integer hochzahl;
integer richtung;

!FEMS_Speichersystem
system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.x.xxx 502 1 03 302 1",&lGetOut,&lGetErr);
dom.GetObject('FEMS_Speichersystem').State(0 + lGetOut);

!FEMS_Erzeugung
lGetOut='NAN';
lGetErr='NAN';
richtung= 1.00;
system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.x.xxx 502 1 03 339 2",&lGetOut,&lGetErr);
hw = lGetOut;
space_pos = hw.Find(' ');
lw = 0 + hw.Substr(space_pos);
if(lw < 0) {lw = lw + 32768;}      
hw = 0 + hw.Substr(0,space_pos);          
if(hw < 0) {hw = hw + 32768;richtung= -1.00;} 
hochzahl = hw / 128; 
if( (hochzahl & 128) > 0) {hochzahl = 1 + (hochzahl & 127);} else {hochzahl = -128 + 1 + (hochzahl & 127);}
mantisse = 1.0;
if( (hw & 64) > 0)     {mantisse = mantisse + 0.5; }
if( (hw & 32) > 0)     {mantisse = mantisse + 0.25; }
if( (hw & 16) > 0)     {mantisse = mantisse + 0.125; }
if( (hw & 8 ) > 0)     {mantisse = mantisse + 0.0625; }
if( (hw & 4 ) > 0)     {mantisse = mantisse + 0.03125; }
if( (hw & 2 ) > 0)     {mantisse = mantisse + 0.015625; }
if( (hw & 1 ) > 0)     {mantisse = mantisse + 0.0078125; }

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

if( (lw & 128) > 0)    {mantisse = mantisse + 0.0000152587890; }
if( (lw & 64 ) > 0)    {mantisse = mantisse + 0.0000076293945; }
if( (lw & 32 ) > 0)    {mantisse = mantisse + 0.0000038146972; }
if( (lw & 16 ) > 0)    {mantisse = mantisse + 0.0000019073486; }
if( (lw & 8  ) > 0)    {mantisse = mantisse + 0.0000009536743; }
if( (lw & 4  ) > 0)    {mantisse = mantisse + 0.0000004768371; }
if( (lw & 2  ) > 0)    {mantisse = mantisse + 0.0000002384185; }
if( (lw & 1  ) > 0)    {mantisse = mantisse + 0.0000001192092; }
mantisse = mantisse * hochzahl.Exp2() * richtung * 0.001;
dom.GetObject('FEMS_Erzeugung').State(mantisse);

!FEMS_Netz
lGetOut='NAN';
lGetErr='NAN';
richtung= 1.00;
system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.x.xxx 502 1 03 315 2",&lGetOut,&lGetErr);
hw = lGetOut;
space_pos = hw.Find(' ');
lw = 0 + hw.Substr(space_pos);
if(lw < 0) {lw = lw + 32768;}      
hw = 0 + hw.Substr(0,space_pos);          
if(hw < 0) {hw = hw + 32768;richtung= -1.00;} 
hochzahl = hw / 128; 
if( (hochzahl & 128) > 0) {hochzahl = 1 + (hochzahl & 127);} else {hochzahl = -128 + 1 + (hochzahl & 127);}
mantisse = 1.0;
if( (hw & 64) > 0)     {mantisse = mantisse + 0.5; }
if( (hw & 32) > 0)     {mantisse = mantisse + 0.25; }
if( (hw & 16) > 0)     {mantisse = mantisse + 0.125; }
if( (hw & 8 ) > 0)     {mantisse = mantisse + 0.0625; }
if( (hw & 4 ) > 0)     {mantisse = mantisse + 0.03125; }
if( (hw & 2 ) > 0)     {mantisse = mantisse + 0.015625; }
if( (hw & 1 ) > 0)     {mantisse = mantisse + 0.0078125; }

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

if( (lw & 128) > 0)    {mantisse = mantisse + 0.0000152587890; }
if( (lw & 64 ) > 0)    {mantisse = mantisse + 0.0000076293945; }
if( (lw & 32 ) > 0)    {mantisse = mantisse + 0.0000038146972; }
if( (lw & 16 ) > 0)    {mantisse = mantisse + 0.0000019073486; }
if( (lw & 8  ) > 0)    {mantisse = mantisse + 0.0000009536743; }
if( (lw & 4  ) > 0)    {mantisse = mantisse + 0.0000004768371; }
if( (lw & 2  ) > 0)    {mantisse = mantisse + 0.0000002384185; }
if( (lw & 1  ) > 0)    {mantisse = mantisse + 0.0000001192092; }
mantisse = mantisse * hochzahl.Exp2() * richtung * 0.001;
dom.GetObject('FEMS_Netz').State(mantisse);

!FEMS_Verbrauch
lGetOut='NAN';
lGetErr='NAN';
richtung= 1.00;
system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.x.xxx 502 1 03 343 2",&lGetOut,&lGetErr);
hw = lGetOut;
space_pos = hw.Find(' ');
lw = 0 + hw.Substr(space_pos);
if(lw < 0) {lw = lw + 32768;}      
hw = 0 + hw.Substr(0,space_pos);          
if(hw < 0) {hw = hw + 32768;richtung= -1.00;} 
hochzahl = hw / 128; 
if( (hochzahl & 128) > 0) {hochzahl = 1 + (hochzahl & 127);} else {hochzahl = -128 + 1 + (hochzahl & 127);}
mantisse = 1.0;
if( (hw & 64) > 0)     {mantisse = mantisse + 0.5; }
if( (hw & 32) > 0)     {mantisse = mantisse + 0.25; }
if( (hw & 16) > 0)     {mantisse = mantisse + 0.125; }
if( (hw & 8 ) > 0)     {mantisse = mantisse + 0.0625; }
if( (hw & 4 ) > 0)     {mantisse = mantisse + 0.03125; }
if( (hw & 2 ) > 0)     {mantisse = mantisse + 0.015625; }
if( (hw & 1 ) > 0)     {mantisse = mantisse + 0.0078125; }

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

if( (lw & 128) > 0)    {mantisse = mantisse + 0.0000152587890; }
if( (lw & 64 ) > 0)    {mantisse = mantisse + 0.0000076293945; }
if( (lw & 32 ) > 0)    {mantisse = mantisse + 0.0000038146972; }
if( (lw & 16 ) > 0)    {mantisse = mantisse + 0.0000019073486; }
if( (lw & 8  ) > 0)    {mantisse = mantisse + 0.0000009536743; }
if( (lw & 4  ) > 0)    {mantisse = mantisse + 0.0000004768371; }
if( (lw & 2  ) > 0)    {mantisse = mantisse + 0.0000002384185; }
if( (lw & 1  ) > 0)    {mantisse = mantisse + 0.0000001192092; }
mantisse = mantisse * hochzahl.Exp2() * richtung * 0.001;
dom.GetObject('FEMS_Verbrauch').State(mantisse);

!FEMS_Ladestatus
lGetOut='NAN';
lGetErr='NAN';
richtung= 1.00;
system.Exec("tclsh /usr/local/addons/modbus/modbus_interface.tcl 192.168.x.xxx 502 1 03 303 2",&lGetOut,&lGetErr);
hw = lGetOut;
space_pos = hw.Find(' ');
lw = 0 + hw.Substr(space_pos);
if(lw < 0) {lw = lw + 32768;}      
hw = 0 + hw.Substr(0,space_pos);          
if(hw < 0) {hw = hw + 32768;richtung= -1.00;} 
hochzahl = hw / 128; 
if( (hochzahl & 128) > 0) {hochzahl = 1 + (hochzahl & 127);} else {hochzahl = -128 + 1 + (hochzahl & 127);}
mantisse = 1.0;
if( (hw & 64) > 0)     {mantisse = mantisse + 0.5; }
if( (hw & 32) > 0)     {mantisse = mantisse + 0.25; }
if( (hw & 16) > 0)     {mantisse = mantisse + 0.125; }
if( (hw & 8 ) > 0)     {mantisse = mantisse + 0.0625; }
if( (hw & 4 ) > 0)     {mantisse = mantisse + 0.03125; }
if( (hw & 2 ) > 0)     {mantisse = mantisse + 0.015625; }
if( (hw & 1 ) > 0)     {mantisse = mantisse + 0.0078125; }

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

if( (lw & 128) > 0)    {mantisse = mantisse + 0.0000152587890; }
if( (lw & 64 ) > 0)    {mantisse = mantisse + 0.0000076293945; }
if( (lw & 32 ) > 0)    {mantisse = mantisse + 0.0000038146972; }
if( (lw & 16 ) > 0)    {mantisse = mantisse + 0.0000019073486; }
if( (lw & 8  ) > 0)    {mantisse = mantisse + 0.0000009536743; }
if( (lw & 4  ) > 0)    {mantisse = mantisse + 0.0000004768371; }
if( (lw & 2  ) > 0)    {mantisse = mantisse + 0.0000002384185; }
if( (lw & 1  ) > 0)    {mantisse = mantisse + 0.0000001192092; }
mantisse = mantisse * hochzahl.Exp2() * richtung * 0.001;
dom.GetObject('FEMS_Ladestatus').State(mantisse);