Anfängerfrage zu Serial Port / Debug (eHZ auslesen)

Hallo Axel,
also die Daten sind eindeutig im SML Protokoll. :slight_smile:
Ich habe einen SML-Frame aus Deinem Log entnommen und im Screenshot beschrieben wo der Zählerstand (kWh) und Leistung (W) zu finden ist.

Jetzt musst Du die Daten wie folgt verarbeiten:

Serial Port COM ===> Cutter ===> Register Variable ===> Skript ===> Werte in Variable schreiben.

Einstellungen Cutter (Daten vor/nach dem Zählerstand/Leistungsdaten):
Zählerstand [kWh]
linkes Trennzeichen (Hex):FF 62 82 01 62 1E 52 FF 69
rechtes Trennzeichen (Hex): 01 77 07 00 00 60 01 FF
Leistung [W]
linkes Trennzeichen (Hex): FF 62 82 01 62 1B 52 FC 55
rechtes Trennzeichen (Hex): 01 01 01 63

Sollte noch etwas unklar sein … einfach nochmals melden.

Mal eine Frage zum „Scaler“ im SML. Im Moment ist das bei mir „FF“ und damit kann ich das ja scheinbar ignorieren.

Aber wie ist es gedacht? Ich gehe mal davon aus, dass ich das brauche, wenn die 6 bytes nicht mehr ausreichen, um den Zählerstand abzubilden.

Auch wenn das (hoffentlich) noch eine Weile so bleiben wird, wäre ich doch daran interessiert, zu verstehen, wie es gedacht ist.

Gruß, Netsrac

Hi mr_cg,

ich werd verrückt - es funktioniert tatsächlich! Beweis im Anhang.

gesagt getan. Habe tatsächlich 2 Cutter mit den obigen Trennern angelegt, dann 2 Ausleseskripts - eins davon sieht so aus:


<?

$test = strtohex($IPS_VALUE);
$test2 = hexdec($test);
$leistung =  ($test2 / 10000);
SetValue (49509 /*[Keller\Stromzähler\Leistung]*/, $leistung);

function strtohex($x) {
  $s='';
  foreach(str_split($x) as $c) $s.=sprintf("%02X",ord($c));
  return($s);
}

?>

Bei Bedarf kann ich das gerne komplett dokumentieren. Tausend Dank an mr_cg für die Hex-Analyse.

Grüsse,
Axel

Untitled.gif

@ axelp
Super daß es geklappt hat. Welcome to the club!
Eine kleine Doku wäre sicherlich für die Nachwelt sehr gut.
Da die SML Zähler stark im Kommen sind wird die Nachfrage stark ansteigen.

@ netsrac
Der Scaler muß mit dem Meßwert multipliziert werden. Der Scaler gibt im Prinzip die kleinst möglich messbare Schrittweite an. Der Scaler ist im Normalfall immer ein vielfaches (Faktor) … 1, 10, 100, 1000, … oder aber 0,1, 0,01 …

Ich bin derzeit in der Überlegung das Lastprofil auszuwerten um damit z.B. zu erkennen ob gewisse Hausgeräte (z.B. Waschmaschine) derzeit ein/aus geschaltet sind. Somit liese sich z.B. erkennen wenn die Waschmasiche fertig ist um dann den Anwender zu informieren daß die Wäsche entnommen werden kann.

Nächster Schritt ist dann gewisse Verbraucher (z.B. Waschmaschine, Spülmaschine) erst einzuschalten wenn z.B. eine Überkapazität der PV-Anlage vorhanden ist. Somit liese sich der Erzeugte Strom der PV-Anlage ideal für den Eigenverbrauch optimieren.

Hängt aber alles davon ab wann ich hierfür Zeit und Lust habe.
Vielleicht hat aber jemand hier diesbezüglich schon etwas im Petto ???
Wäre für weitere Tipps diesbezüglich offen.

Hi mr_cg,

wie hast du den SML-Frame herausgefunden? Kann man das verallgemeinern? Das war schließlich der Durchbruch bei mir und wird auch anderen so gehen.

How-to folgt dann…

Wegen Lastprofil: wie kann man die Last einzelner Geräte erkennen? Doch nur wenn man genau weis was dran hängt, oder?

Danke & Gruß,
Axel

Ich habe zwar kein Gerät mit SML aber mir scheint, dass das Protokoll offen ist, denn die Spezifikation für SML sind mit den entsprechenden Dokumentationen frei im Netz zu finden.

wie hast du den SML-Frame herausgefunden? Kann man das verallgemeinern? Das war schließlich der Durchbruch bei mir und wird auch anderen so gehen.

Leider gibt es derzeit (noch) keine vernüftige Dokumentation für das SML-Protokoll. Es scheint auch so, daß es teilweise Herstellerspezifische Codes gibt. Basierend auf der verfügbaren Dokumentation (z.B. das VDE Lastenheft) hätte ich es nicht hinbekommen. Dennoch waren die Spezifikationen natürlich auch hilfreich. Den richtigen „Durchbruch“ habe ich aber durch das Vergleichen von unterschiedlichen Frames erzielt. Durch das Vergleichen der Daten konnte ich meine Analysen genau auf die Stellen konzentrieren wo sich Daten im Frame verändert haben. Somit konnte ich herausfinden wo die Zählerstände und Leistungsdaten geschrieben wurden. Dann war es relativ einfach anhand der Spec’s die genaue Wertigkeit und Einheit zu ermittlen. Besonders „tricky“ war mein Hager Zweirichtungszähler welcher auch negative Leistung mit einem beginnenden „HEX-F“ darstellt (bei Überschußeinspeisung). Dies konnte ich aus keiner Dokumentation herauslesen.

Wegen Lastprofil: wie kann man die Last einzelner Geräte erkennen? Doch nur wenn man genau weis was dran hängt, oder?

Es ist natürlich nur möglich Großverbraucher wie z.B. Waschmaschine, Spülmaschine, Wärmespeicher usw. mit einem zentral gemessenem Lastprofil zu erkennen.Verbraucher mit gleicher (und geringer) Leistung und ohne Start/Stop-Charakteristik (z.B. Glühlampen) werden nicht erkennbar sein. Eine Waschmaschine hat immer ein bestimmtes Programm (Waschgang mit Wasser-Aufheizung) welches am Lastgang erkannt werden kann. Auch der letzte Schleudergang lässt sich am Lastgang erkennen.
Auszuwerten gilt immer Leistungsänderungen mit einem Zeitvektor.
Es steckt bestimmt jede Menge Arbeit in diesem „Projekt“ um es auch robust und intelligent zu programmieren wenn z.B. zwischenzeitlich andere Verbraucher ein/aus-geschaltet werden. Aber ich denke es ist machbar … und es würde viele sinnvolle Steuerungen ermöglichen. Mir geht es allerdings in erster Linie um eine effektive Nutzung meiner PV-Anlage. Ich bin mir sicher daß dieses Thema aufgrund der Atom-Debatte immer mehr an Bedeutung gewinnt.

Hallo,

ich habe so viel Hilfe beim Auslesen meines neuen Zählers bekommen, deshalb hier wie versprochen mein How-to.

Aufgabe: Auslesen des Zählerstand und aktueller Leistung eines Hager EHZ361W5 (Anleitung).

Benötigte bzw. benutzte Hardware: co.met COM-IR (siehe hier).

COM-IR anschliessen, dann Terminalprogramm (z.B. hterm oder Putty) nach SML-Spezifikation einstellen: 9600 Baud, No parity, 8 Datenbits, 1 Stopbit.

Jetzt sieht man schon ne Menge Zeichensalat, aber immerhin kann man Hager und Zählernummer im Klartext lesen.

In IPS ein Serial Port anlegen und mit obigen Einstellungen versehen. Mein Hager sendet vor und nach den gesuchten Werten dankenswerterweise immer die gleiche Zeichenabfolge (Hex-Werte), deshalb legt man je ein Cutter für Zählerstand und Leistung an und trägt die Trennzeichen entsprechend Screenshot ein. Hier gilt mein Dank mr_cg, der mich auf das verwendete SML-Protokoll hingewiesen und mir die Trennzeichen durchgegeben hat. Ich weis nicht, ob das bei allen gleich ist. Den Cuttern müssen natürlich noch als übergeordnete Instanz der Serial Port zugewiesen werden. Die Cutter liefern somit nur noch den gewünschten Wert.

Am besten eine eigene Kategorie mit Namen Stromzähler erstellen, darunter zwei Registervariablen („eHZ Register Leistung“ und „eHZ Register Zähler“). Registervariablen mit den entsprechenden Cuttern verbinden und darunter jeweils ein Skript anlegen (siehe Screenshot).

Mein Code für „eHZ Register Zähler“ sieht so aus:

<?
$var = 38752 /*[Keller\Stromzähler\Zählerstand]*/;
$wert = (hexdec(strtohex($IPS_VALUE))/10000); 
// 10000 passt für mein Hager, andere mussten durch 10 teilen. Bitte ausprobieren!

$oldvalue = GetValue($var);

// If ($wert < ($oldvalue + 50) and $wert > ($oldvalue + 0.01)) {
		SetValue ($var, $wert);
// }

function strtohex($x) {
  $s='';
  foreach(str_split($x) as $c) $s.=sprintf("%02X",ord($c));
  return($s);
}
?>

Je eine Variable Zählerstand und Leistung anlegen (Typ Float), Profil anpassen und im Skript ganz oben $var entsprechend anpassen.

Jetzt ist alles in IPS vorbereitet. Bevor jedoch echte Werte geliefert werden, muß der Serial Port noch auf Empfang geschaltet werden. Die Hager Zähler senden ein Datensatz alle 2 Millisekunden, IPS hätte Probleme das zu verarbeiten! Deshalb schalte ich mit einem Skript „Zähler Lesen“ jede Minute kurz auf Empfang:


<?
COMPort_SetDTR(34485 /*[eHZ Serial Port]*/, true);
IPS_Sleep(2100);
COMPort_SetDTR(34485 /*[eHZ Serial Port]*/ , false);
?>

Im Skript ist die ID des Serial Ports entsprechend anzupassen.

In das Skript hinter den Registervariablen habe ich durch den if-Part noch ein wenig Logik eingebaut um Ausreisser abzufangen und mir durch minimale Veränderungen nicht IPS zuzuspammen. Nach der Erstverwendung wird empfohlen, den if-Part wieder zu aktivieren.

Hier noch mein Skript für die „eHZ Register Leistung“:

<?
$var = 49509 /*[Keller\Stromzähler\Leistung]*/;
$wert = (hexdec(strtohex($IPS_VALUE))/10000);
$oldvalue = GetValue ($var);

// IPS_LogMessage("Leistung: ",$wert.", Oldvalue: ".$oldvalue);

If ($wert < ($oldvalue + 8000) and ($wert > ($oldvalue + 2) or $wert < ($oldvalue - 2))) {
		SetValue ($var, $wert);
	}

function strtohex($x) {
  $s='';
  foreach(str_split($x) as $c) $s.=sprintf("%02X",ord($c));
  return($s);
}
?>

Ich hoffe die Anleitung ist hilfreich und verständlich.

Danke & Gruß,
Axel

Cutter.PNG

IPS.PNG

Leistung.PNG

web.PNG

ehz.PNG

Hallo,
na das sieht doch schon mal sehr schön aus!

Da habe ich auch gleich eine Frage, mein Zähler:

[ul]
[li]eHZ EDL21 eHZ-HW8E (EMH) mit SML-Schnittstelle[/li][li]BKE-Datenschnittstelle EHZ001 rückseitig eingebaut[/li][li]Ethernet-Gateway COM-1 von „Co.met“ (Schittstellenwandler „WIZnet WIZ110SR“ modifiziert von RJ10 4P/4C - RJ45)[/li][li]Software: Strom-cockpit App für das iPhone[/li][/ul]

Die Daten stehen jetzt im Netzwerk zur Verfügung.

Anbei mal mein PuTTY Log:


=~=~=~=~=~=~=~=~=~=~=~= PuTTY log 2011.01.12 13:21:19 =~=~=~=~=~=~=~=~=~=~=~=
SML(1B1B1B1B010101017607001900D7797162006200726301017601010700190043D3260B06454D4801001D4062360101636CE5007607001900D77972620062007263070177010B06454D4801001D4062360172620165004390ED7777078181C78203FF0101010104454D480177070100000009FF010101010B06454D4801001D4062360177070100010800FF63018201621E52FF56000045C2C80177070100010801FF0101621E52FF560000459B6C0177070100010802FF0101621E52FF56000000275C01770701000F0700FF0101621B52FF5500000BA00177078181C78205FF010101018302E050C5ACEB0A6B4C5C862D77B2C2A2502434BD1C4A9EB250CA81EF93D26D7B7A52B7F265C9BACF6A370FCF162A213DAE010101638F34007607001900D77974620062007263020171016384A400001B1B1B1B1A017177)
      8589
DE0000000000000000000000000000123
SML(1B1B1B1B010101017607001900D7797762006200726301017601010700190043D3280B06454D4801001D4062360101633F3F007607001900D77978620062007263070177010B06454D4801001D4062360172620165004390EF7777078181C78203FF0101010104454D480177070100000009FF010101010B06454D4801001D4062360177070100010800FF63018201621E52FF56000045C2CA0177070100010801FF0101621E52FF560000459B6E0177070100010802FF0101621E52FF56000000275C01770701000F0700FF0101621B52FF5500000BB90177078181C78205FF010101018302E050C5ACEB0A6B4C5C862D77B2C2A2502434BD1C4A9EB250CA81EF93D26D7B7A52B7F265C9BACF6A370FCF162A213DAE010101639C72007607001900D7797A620062007263020171016359ED00001B1B1B1B1A01993F)
      8591
DE0000000000000000000000000000123

Wie ich sehe liest Du deine Daten über eine COM Schnittstelle in IPS ein. Gibt es eine Möglichkeit die Daten aus dem Netzwerk einzulesen?

Gruß

…wenn ich es richtig gelesen habe, würde es mit „ClientSocket“ gehen.
Der Debugger zeigt auch ankommende Daten, siehe Bild! :slight_smile:

Wie kann ich den Port „Clientsocket“ (so wie Comport) ansteuern?

<?
COMPort_SetDTR(34485 /*[eHZ Serial Port]*/, true);
IPS_Sleep(2100);
COMPort_SetDTR(34485 /*[eHZ Serial Port]*/ , false);
?>

Gruß

…mal sehen ob es damit geht!?


CSCK_SetOpen(19350 /*[Energie\Client Socket]*/,true);

Also irgendwie klappt es nicht so richtig.
Die Daten kommen bis zum „Cutter-Leistung“ und „Cutter-Zählerstand“ siehe Debug-Bilder im Anhang. Das Debug vom ClientSocket habe ich als txt angehangen.

Im Script „eHZ Leser Zähler“ kommt beim Ausführen die Fehlermeldung:


<?
$var = 54771 /*[Energie\Zählerstand]*/;
$wert = (hexdec(strtohex($IPS_VALUE))/10000);
$oldvalue = GetValue($var);

//If ($wert < ($oldvalue + 50) and $wert > ($oldvalue + 0.01)) {
		SetValue ($var, $wert);
// }

function strtohex($x) {
  $s='';
  foreach(str_split($x) as $c) $s.=sprintf("%02X",ord($c));
  return($s);
}
?>

Notice:  Undefined variable: IPS_VALUE in [Energie\eHZ Register Zähler\eHZ Leser Zähler] on line 3

Im Script „eHZ Leser Leistung“ kommt beim Ausführen die Fehlermeldung:


<?
$var = 45696 /*[Energie\Leistung]*/;
$wert = (hexdec(strtohex($IPS_VALUE))/10000);
$oldvalue = GetValue ($var);

//IPS_LogMessage("Leistung: ",$wert.", Oldvalue: ".$oldvalue);

If ($wert < ($oldvalue + 8000) and ($wert > ($oldvalue + 2) or $wert < ($oldvalue - 2))) {
		SetValue ($var, $wert);
	}

function strtohex($x) {
  $s='';
  foreach(str_split($x) as $c) $s.=sprintf("%02X",ord($c));
  return($s);
}
?>

Notice:  Undefined variable: IPS_VALUE in [Energie\eHZ Register Leistung\eHZ Leser Leistung] on line 3

Was kann ich nun machen?:confused:

Gruß

ClientSocket.txt (7.92 KB)

Was kann ich nun machen

Das Script nicht von Hand ausführen, dann kommt auch die Fehlermeldung nicht mehr. Systemvariable!!!

OK. Dann werde ich das nicht mehr machen!

Hallo,
im Register Leistung und Zähler „Debug“ kommen keine Daten an.:confused:

Was kann ich nun machen, ich benötige jetzt mal Hilfe?

Gruß

hast Du die RegVar dem Cutter zugewiesen.

…ja, siehe Anhang!

Deine Cuttereinstellungen stimmen wohl nicht. Er sendet nicht weiter, er sammelt nur Daten. Sowie ich das oben gesehen habe. Wenn Daten weitergegeben werden steht dort sendChunk…

Zwischentipp:

Paresy hat mal einen hilfreichen Anfang für solche Scripts gepostet:

if($IPS_SENDER == "Execute")
 die("Nein... Dieses Skript darf nicht per Execute gestartet werden");

:D:D:D

…ich weiß nicht mehr weiter.
Ich glaube das Problem liegt im Format des SML File, vielleicht kann sich das ja mal einer ansehen.

Danke
Gruß

1335,3kwh_338W_putty.log.txt (14.2 KB)

1336,624kwh_534,30W_putty.log.txt (15.5 KB)

@ inspiron
Die Log-Daten sind „astreines“ SML-Protokoll. :slight_smile:

Die Cutter Einstellungen sind die gleichen welche ich auch axelp gepostet habe:
Zählerstand [kWh]
linkes Trennzeichen (Hex):FF 62 82 01 62 1E 52 FF 69
rechtes Trennzeichen (Hex): 01 77 07 00 00 60 01 FF
Leistung [W]
linkes Trennzeichen (Hex): FF 62 82 01 62 1B 52 FC 55
rechtes Trennzeichen (Hex): 01 01 01 63

Deine Cutter Einstellungen müssten dann wie im angefügtem Scrrenshot aussehen.

P.S.: Alternativ könntest Du auch die Daten aus der EDL-Software exportieren und dann wieder in IPS importieren. Habe ich anfangs auch so gemacht.