[Modul] Alle ModBus Zähler von B+G E-Tech

Version Version License
Version Check Style Run Tests
Spenden

Symcon-Modul: B+G E-Tech

Inhaltsverzeichnis

1. Funktionsumfang

Ermöglicht die Einbindung von Energie-Zählern der Firma B+G E-Tech ohne mehrere ModBus-Instanzen in IPS.
Zusätzlich können mehrere Zähler auf einem physikalischen RS485-Bus betrieben werden.

Folgende Module beinhaltet das BGETech Repository:

  • DRS210C
    Zähler vom Typ DRS 210C
  • DRS458
    Zähler vom Typ DRS 458
  • DRT710M
    Zähler vom Typ DRT 710M
  • SDM72D
    Zähler vom Typ SDM 72D
  • SDM120C
    Zähler vom Typ SDM 120C
  • SDM220
    Zähler vom Typ SDM 220
  • SDM230
    Zähler vom Typ SDM 230
  • SDM530
    Zähler vom Typ SDM 530
  • SDM630
    Zähler vom Typ SDM 630

2. Voraussetzungen

  • IPS 5.1 oder höher
  • Unterstützte Zähler
  • physikalisches RS485 Interface für die Zähler

3. Software-Installation

IPS 5.1:
Bei privater Nutzung: Über den ‚Module-Store‘ in IPS.
Bei kommerzieller Nutzung (z.B. als Errichter oder Integrator) wenden Sie sich bitte an den Autor.

4. Einrichten der Instanzen in IP-Symcon

Ist direkt in der Dokumentation der jeweiligen Module beschrieben.

5. Anhang

1. GUID der Module

Modul Typ Prefix GUID
DRS210C Device DRS210C {2CA41C9F-355C-4231-90A5-6D83A90B65BD}
DRS458 Device DRS458 {8CA96C98-3014-44E4-8D15-4EC6B524F1F4}
DRT710M Device DRT710M {187BB86B-A52F-4ADD-A233-92108BD71767}
SDM72D Device SDM72D {08371372-5993-4BAF-A6EC-D70759709CD9}
SDM120C Device SDM120C {32DCCC5C-78D3-475E-885A-652F56DB4D18}
SDM220 Device SDM220 {93668601-F92A-46FC-AE5B-E44451F022EE}
SDM230 Device SDM230 {10D08FCD-D1AC-4CF3-8B19-54B92209DA07}
SDM530 Device SDM530 {9A65E88A-21DC-439F-8602-CA14EE9FDF27}
SDM630 Device SDM630 {BBCA5E14-505E-4394-B653-8CD33AD52037}

2. Changelog

Version 3.30:

  • Import und Export Werte für SDM120C, SDM220, SDM230, SDM530 und SDM630 ergänzt

Version 3.23:

  • Schreibfehler korrigiert
  • Neue Tests
  • Neues Style

Version 3.10:

  • Fehler bei SDM360 L3 total active energy behoben

Version 3.01:

  • Falsche Bezeichnung des SDM210C zu SDM120C umbenannt

Version 3.0:

  • Release für IPS 5.1 und den Module-Store

Version 2.06:

  • IntervallBox und caption ersetzt

Version 2.05:

  • Bugfix für DRT 710M

Version 2.04:

  • DRT 710M ergänzt

Version 2.03:

  • SDM 530 ergänzt

Version 2.2:

  • Intern werden jetzt auch Integer, Boolean und String Variablen unterstützt
  • Fehlende Übersetzungen ergänzt

Version 2.1:

  • Abzufragende Werte können deaktiviert werden

Version 2.0:

  • DRS 458 ergänzt
  • SDM 72D ergänzt
  • SDM 120C ergänzt
  • SDM 220 ergänzt
  • SDM 230 ergänzt
  • SDM 630 fehlende Werte ergänzt und kleiner Bugfixes

Version 1.1:

  • Profile ergänzt
  • Doku ergänzt

Version 1.0:

  • Erstes offizielles Release

3. Spenden

Die Library ist für die nicht kommerzielle Nutzung kostenlos, Schenkungen als Unterstützung für den Autor werden hier akzeptiert:

6. Lizenz

IPS-Modul:
CC BY-NC-SA 4.0

Hinweise
Eigentlich machen die Module nichts anderes, als die in IPS vorhandenen ModBus-Instanzen.
Der Unterschied ist nur, dass nach dem auslesen eines Zählers 333ms gewartet wird.
Somit kommen sich diese ‚trägen‘ Geräte auf einem physikalischen Bus nicht mehr in die Quere.

Die enthaltenden Instanzen benötigen jeweils eine Instanz vom Typ ‚ModBus Gateway‘ als übergeordnete Instanz. Dort ist die Geräte ID einzutragen.

Sofern Geräte fehlen, einfach melden. Ich binde diese ein, sofern es eine Doku über die ModBus-Register gibt.
Da ich nicht alle Zähler habe, konnte ich nicht jeden Messwert testen und musste mich auf die Hersteller-Doku stützen.
Bei Fehlern bitte melden :slight_smile:

Michael

Hallo Michale,

ich würde gerne dein Modul an meine Zähler anwenden bzw. Anpassen. Leider habe ich noch nie mit Module gearbeitet :frowning:
Meine Zähler sind von der Fa.Schneider „iEM3155“

Wie mache ich das mit den Modbus Adressen und Einheiten in der module.php?

iem.PNG

Verbrauch abfrage ist beim dem Zähler etwas uncool :slight_smile:

1 x Adresse:3205
Einheit: SmallInt(16bit-Signed)
1 x Adresse:3206
Einheit: Integer (32bit-Signed)

Mit den Beiden Werten im Script weiter Arbeiten:

<?
$adresse3205 = GetValue(49039);
$adresse3206 = GetValue(56641);
$bit = 65536; //2hoch16

$verbrauch = 28753; //Float Variable

$rechnung = (($adresse3205*$bit)+$adresse3206)/1000;

SetValue($verbrauch, $rechnung);

?>

Würde mich freuen wenn du mir etwas Helfen könntest.

Gruß

Funktionscode und Adresse kannst du hier sehen:
IPSBGETech/module.php at 4f5f0dde7aff2f05c9d607dbb2dad4a2060ababf · Nall-chan/IPSBGETech · GitHub

Quantity gibt die Anzahl an 16bit Werten an welche du lesen willst.
Also bei dir einmal 1 und einmal 2.
Die Umrechnung musst du dann zu Fuß machen, ich habe dafür unpack genutzt.
Eventuell kannst du auch gleich einen 64bit Wert lesen? Oder mag das dein Zähler nicht?

Zum testen kann du wie folgt vorgehen:
Lade mein Modul in IPS.
Kopiere den Ordner DRS210C und gibt ihm einen neuen Namen.
Benenne die Klasse in module.php genauso.
Und dann musst du noch die Module.json anpassen.
Ebenfalls den Klassennamen und eine eigene GUID .
Dann IPS neustarten.

Anschließend kannst du eine deiner Instanzen erzeugen und in Echtzeit den Code in einem beliebigen Editor anpassen.
Michael

Hallo Michael,

danke für die Hilfe :slight_smile:
Leider bekomme ich es nicht hin :banghead:
Sitze schon den ganzen Abend dran und nicht mal ein kleiner Erfolg.

Namen und GUID’s habe ich angepasst.

Für Spannung habe ich die Adresse 3026
in module.php habe ich die Adresse auch angepasst:

 $Volt = $this->SendDataToParent(json_encode(Array("DataID" => "{E310B701-4AE7-458E-B618-EC13A1A6F6A8}", "Function" => 3, "Address" => 0xBD2, "Quantity" => 2, "Data" => "")));
        if ($Volt === false)
        {
            $this->unlock($IO);
            return false;
        }
        $Volt = unpack("G", substr($Volt, 2))[1];
        $this->SendDebug('Volt', $Volt, 0);
        SetValue($this->GetIDForIdent("Volt"), $Volt);

Im Symcon kommt aber immer eine Fehlermeldung:

20.10.2017 20:32:13 | TimerPool | iEM315 (UpdateTimer): <br />
<b>Warning</b>:  unpack(): Invalid format type G in <b>/var/lib/symcon/modules/IPSBGETech/iEM3155/module.php</b> on line <b>58</b><br />
<br />
<b>Warning</b>:  unpack(): Invalid format type G in <b>/var/lib/symcon/modules/IPSBGETech/iEM3155/module.php</b> on line <b>69</b><br />
<br />
<b>Warning</b>:  unpack(): Invalid format type G in <b>/var/lib/symcon/modules/IPSBGETech/iEM3155/module.php</b> on line <b>80</b><br />
<br />
<b>Warning</b>:  unpack(): Invalid format type G in <b>/var/lib/symcon/modules/IPSBGETech/iEM3155/module.php</b> on line <b>91</b><br />
<br />
<b>Warning</b>:  unpack(): Invalid format type G in <b>/var/lib/symcon/modules/IPSBGETech/iEM3155/module.php</b> on line <b>103</b><br />
<br />
<b>Warning</b>:  unpack(): Invalid format type G in <b>/var/lib/symcon/modules/IPSBGETech/iEM3155/module.php</b> on line <b>115</b><br />
<br />
<b>Warning</b>:  unpack(): Invalid format type G in <b>/var/lib/symcon/modules/IPSBGETech/iEM3155/module.php</b> on line <b>126</b><br />

Was ist format type G ?

Gruß

Du kannst die Adresse auch als Int angeben, ich habe nur Hex genommen, weil die Doku so war von meinem Zähler :wink:

unpack(‚G‘) ist für Float.
Die Formate sind hier erklärt, sonst hilft ausprobieren.
PHP: pack - Manual
Allerdings sehe ich gerade, in der deutschen Doku fehlt ‚G‘ :rolleyes:

Laut Doku für deinen Zähler hast du einen Int64.
Das sollte IPS direkt können
Adresse: 3204
Function: 3
Typ Real64 oder Int64 (ausprobieren)

Wenn du es mit dem Modul versuchen willst, dass sollte es so funktionieren:

Versuch mal:

 $Value = $this->SendDataToParent(json_encode(Array("DataID" => "{E310B701-4AE7-458E-B618-EC13A1A6F6A8}", "Function" => 3, "Address" => 3204, "Quantity" => 4, "Data" => ""))); 


$Value1 = unpack("G", substr($Value , 2))[1]; 
$this->SendDebug('Test unpack G', $Value1 , 0); 

$Value2 = unpack("g", substr($Value , 2))[1]; 
$this->SendDebug('Test unpack g', $Value2 , 0); 

Du solltest dann im Debug der Instanz sehen welcher Wert korrekt ist.

Michael

Hallo Michael,

bei meinem Zähler ist nur der Verbrauch Int64. Die Werte für Spannung, Strom usw. ist Float32.

Danke für den Beispiel. Geht aber trotzdem nicht.
Wenn ich anstatt G ein F nehme, bekomme ich komische werte. Aber ich bekomme welche.
Also ist die Verbindung da.

Spielt es eine Rolle wie der Zähler angebunden ist?

Gruß

Nö. Das ist egal.

Mich wundert dass er auf 2305 überhaupt reagiert. Weil eigentlich ist es ja 2304 und dann 64 Bit.
Und das funktioniert mit der original ModBus-Instanz nicht?

Ansonsten lass dir mal das Ergebnis der Abfrage (von SendDataToParent) mit $this->SendDebug(‚test‘, $Value,1); ausgeben.

Die ersten beiden Hex Werte sind egal.
Der Rest ist die Antwort welche den Wert darstellen soll.
Dann probiere ich es mal umzurechnen :wink:
Michael

Ich glaube wir Reden (Schreiben) an einander vorbei :slight_smile:

Ich bekomme es nicht hin die „Normale“ werte wie Spannung, Strom usw über ein Modul ins IPS zu bekommen.
Geschweige von Verbrauch.

Dein Beispiel ist anscheinend für Int64?

Auf Haupt IPS läuft ja alles. Über Modul aber nicht :banghead:
Schnittstelle an Haupt IPS ist geschlossen. Damit ich am Test IPS Spielen kann.

Egal was ich im module.php mache, kommt die Fehlermeldung und in IPS im Debug Werte 0

Mache ich grundsätzlich was Falsch?

Gruß

Sorry mein Fehler, hatte dein Problem nur an den Int64 wert vom Verbrauch festgemacht.

Verstehe jetzt auch warum ‚g‘ nicht funktioniert bei dir.
Ist leider eine Erweiterung von PHP welche es nicht in IPS gibt.
Also bleibt nur ‚f‘ oder ganz anders rechnen.

Am Beispiel Voltage L1 to N ist Adresse 3028, richtig ?
Was bekommst du hier den im Debug angezeigt ?

 $VoltL1 = $this->SendDataToParent(json_encode(Array("DataID" => "{E310B701-4AE7-458E-B618-EC13A1A6F6A8}", "Function" => 3, "Address" => 3028, "Quantity" => 2, "Data" => ""))); 
        if ($VoltL1 === false) 
        { 
            $this->unlock($IO); 
            return false; 
        } 
        $VoltL1 = substr($VoltL1, 2); 
        $this->SendDebug('VoltL1', $VoltL1, 1); //Hex ausgabe

//        SetValue($this->GetIDForIdent("Volt"), $Volt);  

Michael

Hallo,

es kommt schon mal was an :smiley:

64 CA 43 65 

Ändert sich ständig.

Gruß

Irgendwie verstehe ich das aber nicht…

Was wenn du die Adresse auf 3029 bzw. 3027 änderst ?
Ich hatte eine Doku, da waren die Adressen als ‚Offset‘ gemeint. So dass ich immer eine Abziehen musste.

Eigentlich sollte die Umrechnung so funktionieren:

$Value = unpack('f',strrev($Value)));

Michael

Hallo Michael,

ich hab Dein Modul mal installiert, um es zu testen. Leider ohne erfreuliches Ergebnis. Ich lese meinen SDM630Modbus bisher über Client-Socket, Modbus-Gateway und Modbus Device aus. Das funktioniert auch perfekt. (Einstellungen der Modbus-Device im Screenshot, hier L1 Total kWh ).

modbus-device.PNG

Nach der Installation Deines Moduls werden keinerlei Fehler angezeigt. Ich benutze das gleiche Gateway für Dein Modul. Allerdings werden hier keinerlei Werte in die Variablen geschrieben. Er aktualisiert sie zwar regelmäßig, schreibt aber als Wert immer Null.

Muss ich für das Modul ein zweites Gateway installieren?

Viele Grüße,

Burkhard

Nein, ich habe da einen Fehler im Modul, darum bekommst du keine Werte.
Fix kommt so gegen Mittag.

Allerdings brauchst du mein Modul nur dann, wenn du mehrere Zähler auf dem gleichen physikalischen Bus betreiben willst.
Michael

Hallo Michael,

bei mir Laufen 4 von den Zähler an einem Bus. Deswegen die Idee ein Modul zu Erstellen (Probieren zu Erstellen ehe gesagt :D)

Funktioniert einfach nicht :banghead:

in der module.php steht:

$Volt = $this->SendDataToParent(json_encode(Array("DataID" => "{E310B701-4AE7-458E-B618-EC13A1A6F6A8}", "Function" => 3, "Address" => 3029, "Quantity" => 2, "Data" => ""))); 
        if ($Volt === false) 
        { 
            $this->unlock($IO); 
            return false; 
        } 

	$Volt = unpack('f',strrev($Volt));  
        $this->SendDebug('Volt', $Volt, 0); //Hex ausgabe 

Im Debug kommt nichts an.
Als Meldung in IPS kommt:

21.10.2017 09:40:58*| TimerPool*| iEM315 (UpdateTimer): <br />
<b>Warning</b>:  Cannot auto-convert value for parameter Data in <b>/var/lib/symcon/modules/IPSBGETech/iEM3155/module.php</b> on line <b>62</b><br />
<br />
<b>Warning</b>:  unpack(): Invalid format type g in <b>/var/lib/symcon/modules/IPSBGETech/iEM3155/module.php</b> on line <b>74</b><br />
<br />
<b>Warning</b>:  unpack(): Invalid format type g in <b>/var/lib/symcon/modules/IPSBGETech/iEM3155/module.php</b> on line <b>85</b><br />
<br />
<b>Warning</b>:  unpack(): Invalid format type g in <b>/var/lib/symcon/modules/IPSBGETech/iEM3155/module.php</b> on line <b>96</b><br />
<br />
<b>Warning</b>:  unpack(): Invalid format type g in <b>/var/lib/symcon/modules/IPSBGETech/iEM3155/module.php</b> on line <b>108</b><br />
<br />
<b>Warning</b>:  unpack(): Invalid format type g in <b>/var/lib/symcon/modules/IPSBGETech/iEM3155/module.php</b> on line <b>120</b><br />
<br />
<b>Warning</b>:  unpack(): Invalid format type g in <b>/var/lib/symcon/modules/IPSBGETech/iEM3155/module.php</b> on line <b>131</b><br />

Gruß

EDIT:

Mit:

$Volt = $this->SendDataToParent(json_encode(Array("DataID" => "{E310B701-4AE7-458E-B618-EC13A1A6F6A8}", "Function" => 3, "Address" => 3027, "Quantity" => 2, "Data" => ""))); 
       

	$Volt = unpack('f',strrev($Volt));  
        //$Volt = substr($Volt, 2); 
        $this->SendDebug('Volt', $Volt, 1); //Hex ausgabe

kommt im Debug:

46 61 6C 73 65 

Was heißt das?

echo "\x46\x61\x6C\x73\x65";

Da kommt ‚False‘ raus :wink:
Den Haken im Debug bitte auf default / grau lassen.

Du hast da jetzt einiges durcheinander geworfen, darum kommt false raus :wink:

SendDebug nach dem unpack gibt dann kein Hex mehr aus, sondern schon einen Wert, bzw ein Array.
und unpack ohne vorher die beiden ersten Zeichen abzuschneiden ist auch schlecht.


    $Volt = unpack('f',strrev($Volt));  // falsch, da du die ersten Bytes nicht abgeschnitten hast
        //$Volt = substr($Volt, 2); 
        $this->SendDebug('Volt', $Volt, 1); //Hier zu spät

Die korrekte Reihenfolge wäre.

$Volt = $this->SendDataToParent(json_encode(Array("DataID" => "{E310B701-4AE7-458E-B618-EC13A1A6F6A8}", "Function" => 3, "Address" => 3027, "Quantity" => 2, "Data" => ""))); 

        $Volt = substr($Volt, 2);        // Ersten beiden Bytes weg.
        $this->SendDebug('Volt Hex', $Volt, 1); //Hex ausgabe , letzter Parameter 1
    $Volt = unpack('f',strrev($Volt));  // Umwandeln nach Float
        $this->SendDebug('Volt', $Volt, 0); //Text ausgabe , letzter Parameter 0

Michael

Fix online.

Michael

Hallo Michael,

vielen Dank für Dein Modul und das schnelle Update:D.

Jetzt funktioniert auch Alles. Derzeitig habe ich nur einen SDM630 dran, aber geplant ist noch ein SDM120-Modbus, da ich einen Wohnwagen zur Dauernutzung auf einer L-Leitung laufen lasse und diesen gesondert erfassen will.

Viele Grüße,

Burkhard

Hallo Michael,

habe nach hin und her probieren alles gelöscht und ein Update von deinem Modul gemacht.
Diesmal habe ich den SDM630 Ordner Kopiert und angepasst.
Und siehe da, es funktioniert :D:D:D

Versuche heute Abend mal weiter zu machen.

Gruß und Danke.

Hallo Michael,

ich habe soweit alles geschafft. Leider habe ich noch ein Problem mit Gesamt Verbrauch.

Alle Daten wie Strom, Spannung usw. habe ja Float32
Im Modul zb. Frequenz mit Adresse 3108 sieh es so aus.

//Frequenz

        $Frequenz = $this->SendDataToParent(json_encode(Array("DataID" => "{E310B701-4AE7-458E-B618-EC13A1A6F6A8}", "Function" => 3, "Address" => 3109, "Quantity" => 2, "Data" => "")));
        if ($Frequenz === false)
        {
            $this->unlock($IO);
            return false;
        }
        $Frequenz = unpack("f", strrev(substr($Frequenz, 2)))[1];
        $this->SendDebug('Frequenz', $Frequenz, 0);
        SetValue($this->GetIDForIdent("Frequenz"), $Frequenz);

Verbrauch ist INT64

Im IPS muss ich mit Script Rechnen.
Adresse 3205 ist „SmalInt 16bit“
Adresse 3206 ist „Integer 32bit“

Kann ich einfach auslesen oder muss ich im Modul auch Rechnen?

Gruß

Ausbrobieren :wink:
Quantity auf 4 und Adresse dann 3205 oder 3204.
Rest lassen.
Wenn es nicht funktioniert, dann musst du wohl zwei Werte lesen.
Quantity auf 2 und einmal 3204 und einmal 3206 lesen.

Michael