ISKRA MT681 per Opto Koppler auslesen

Hallo zusammen,

Anfang des Jahres hatte ich mich schon mal diesem Projekt gewidmet und musste es leider aus Zeitgründen vernachlässigen. Netterweise hatte mir hier Bunnymc geholfen, nur konnte ich es nicht zu Ende führen.

Nun habe ich zwei Zähler jeweils per USB-Optokoppler an meinen Server angeschlossen. Per Hterm bekomme ich auch HEX Zeichen ausgelesen:

Wenn ich jetzt aber einen Serial Port in IP-Symcon erstelle kommen dort im Debugmodus keine Hex Zeichen sondern nur „Datenmüll?“ an. Des Weiteren läuft der IP-Symcon im Speicher immer voller und stürzt irgendwann ab. Wenn ich zwischenzeitlich den Port aber schließe geht auch die Speichernutzung runter.

Das Cutter Modul habe ich wie folgt eingestellt:

Ich hänge mal die Logdateien an und würde mich freuen wenn sich diese jemand ansehen könnte, da ich jetzt wirklich nicht mehr weiter weiß.

COM5_ASCI.txt (3.3 KB)COM5_HEX.txt (22.5 KB)COM5_ROW.txt (11.3 KB)serial_port_com5.zip (36.4 KB)serial_cutter_com5.zip (8.55 KB)

VG

Thorsten

Hi Thorsten,

ich glaube ich weiss wo es hakt.

  1. Wenn du beim Cutter einen Debuglog machst, kannst du separat nochmal die HEX ausgabe einstellen.
  2. Falls du mein (also das von mir angepasste :slight_smile: ) Script verwendest wird da auch ein Fehler liegen, bin gerade dabei deinen hterm log aufzuschlüsseln und die länge schaut anders aus.
    D.h. im Script sind feste Positionen für Werte angeben, eventuell sind die bei dem Zähler aber anders.

//edit: Ich denke ich habs ganz gut geschafft die einzelnen werte auseinander zu ziehen, das ist die erste Zeile aus deiner Com5_HEX
Mach mal bitte Logs von dem Zähler wenn Last drauf ist und schreib die Zählerwerte dabei bitte mit auf.

Und schau dir mal den Beitrag von buechner an, das Script scheint deutlich tauglicher zu sein als meins:


1B1B1B1B			Start Escape Zeichenfolge
01010101			Start Übertragung Version 1
76					Liste mit 6 Einträgen
	05122D211F				transactionID (5 byte)
	6200					groupNo
	6200					abortOnError
	72						Liste mit 2 Einträgen
		630101					Nachricht 0101 = SML_PublicOpen.Res
		76						Liste mit 6 Einträgen
			01					codepage (leer)
			01					clientID (leer)
			05060F0B0B			reqFileID
			0908050E422D4CAA82	serverID
			01					
			6200
	631519					CRC
00					Ende Nachricht

76					Liste mit 6 Einträgen
	05122D2120				transactionID (5 byte)
	6200					groupNo
	6200					abortOnError
	72						Liste mit 2 Einträgen
		630701					Nachricht 0701 = SML_GetList.Res
		77						Liste mit 7 Einträgen
			01						clientID (leer)
			0908050E422D4CAA82		serverID
			01						listName (leer)
			01						
			75						Liste mit 5 Einträgen
				77						Liste mit 7 Einträgen
					078181C78203FF		objName 129-129:199.130.3*255
										Herstelleridentifikation
					01					status (leer)
					01					valTime (leer)
					01					unit (leer)
					01					scaler (leer)
					0649534B5241		value
					01					valueSignature (leer)

				77						Liste mit 7 Einträgen	
					070100000000FF		objName 1-0:0.0.0*255
										Geräteidentifikation?
					01					status (leer)
					01					valTime (leer)
					01					unit (leer)
					01					scaler (leer)
					0908050E422D4CAA82	value
					01					valueSignature (leer)

				77						Liste mit 7 Einträgen
					070100010801FF		objName 1-0:1.8.1*255
										Wirkarbeit Bezug Tarif 1
					6200				status
					01					valTime (leer)
					621E				unit (unsigned8) 1E = Wh
					52FF				scaler (int8) -1 = *10^-1 = /10
					69000000000485D6DB	value (4*16^6+8*16^5+5*16^4+13*16^3+6*16^2+13*16^1+11*16^0)/10 = 75880155/10 = 7588015,5 Wh = 7588,0155 kWh
					01					valueSignature (leer)

				77						Liste mit 7 Einträgen
					070100600505FF		objName 1-0:96.5.5*255
										(EDL Status word)
					01					status (leer)
					01					valTime (leer)
					01					unit (leer)
					01					scaler (leer)
					6200				status
					01					valueSignature (leer)

				77						Liste mit 7 Einträgen
					070100010700FF		objName 1-0:1.7.0*255
										Active Power+  = Bezugsrichtung
					01					status (leer)
					01					valTime (leer)
					621B				unit (unsigned8) 1B = W
					5200				scaler ??
					5500000000			value (hier 0)
					01					valueSignature (leer)
					
			01
			01
	63AF90					CRC
00						Ende Nachricht


76						Liste mit 6 Einträgen
	05122D2121				transactionID (5 byte)
	6200					groupNo
	6200					abortOnError
	72						Liste mit 2 Einträgen
		630201					Nachricht 0201 =
		71						Liste mit 1 Eintrag
			01						valueSignature
	6337A1000000			CRC Prüfsumme
00					Ende Nachricht
1B1B1B1B			Escape-Sequenz
1A036A10			Ende Nachricht mit Füllbytes

Hi Bunnymc,
da stellst Du mich vor eine Aufgabe. In einem Niedrigenergiehaus Strom zu verbrauchen… :wink:

Ich habe jetzt mal alles angeworfen was ich habe und komme gerade mal auf 1KW/h Verbrauch in 15 Min.

Die Zählerstände sind: 11114 und danach 11115. Falls ich den falschen Zähler hatte wäre es dieser Zählerstand: 7596

Als im Debugmodus war schon HEX eingeschaltet. Das einzige was mir aufgefallen war, ist das es eine Länge von 1 hat.

Vielen Dank nochmals für die Unterstützung.

VG

Thorsten

2014-09-24.zip (57 KB)

Mir ist auch noch aufgefallen, dass ich bei dem aktuellen Lesekopf (siehe Logs oben) in hterm definitiv das Flag „DTR“ aktiviert haben muss, damit die Daten gelsen werden:

DTR.PNG

Wenn ich diesen COM Port dann per ip-symcon auslese, bekomme ich im Debug Modus des Serial Ports nichts angezeigt.

Beim zweiten Lesekopf brauche ich das Flag nicht und hier bekomme ich im Debug Modus etwas angezeigt.

Hi Thorsten,

du verwirrst mich gerade :slight_smile:

Also erstmal bei deinen neuen Logs ist jetzt auch ein Verbrauch zu sehen, im ersten Datenpaket 427Watt.

>Als im Debugmodus war schon HEX eingeschaltet. Das einzige was mir aufgefallen war, ist das es eine Länge von 1 hat.
Wenn du da nochmal draufklickst kommt ein Haken, dann sollte es lesbar sein. Die Länge 1 ist dort normal. Im Debug vom Cutter sollten es die Pakete sein

>Die Zählerstände sind: 11114 und danach 11115. Falls ich den falschen Zähler hatte wäre es dieser Zählerstand: 7596
Der erste (alte) Log war also von dem 7596 Zähler :slight_smile: (Juhu richtig gerechnet)
Der neue Log war vom 11114,4094 (erstes Paket Wert) Zähler

>Mir ist auch noch aufgefallen, dass ich bei dem aktuellen Lesekopf (siehe Logs oben) in hterm definitiv das Flag „DTR“ aktiviert haben >muss, damit die Daten gelsen werden:
Dazu hab ich folgendes gefunden:
COMPort_SetDTR($ID,true);

Schreib bitte nochmal einen genaue Aufschlüsselung was du wie hast

Bsp.:
Zähler 1
Typ: Strom
Aktueller Stand: 7xxx
Lesekopf: von Udo oder … (vielleicht mit Typ, also USB/RS232TTL oder LAN …)
ComPort:
Verhalten in IPS: funktionier; kommt garnichts; kommt nur kryptisch, …

Zähler 2 …

Da du ja 2 Zähler hast, müssen wir eventuell für beide die Protokolle Analysieren. (Habe festgestellt, das MT681 nicht MT681 ist :slight_smile:

Grüße
Rene

Hallo Rene,

ja wenn man noch mal auf den Haken setzt wird die HEX Anzeige ausgewählt. Die Daten kommen jetzt an. Nun fehlt die Cutter Einstellung damit die Daten richtig ausgelesen werden.

Wenn ich am Samstag zurück bin werde ich mal versuchen per PHP den „DTR“ für den Serial Port zu setzen. Wo kann man den Startscripts hinterlegen oder muss ich mir ein neues Script schreiben?

Anbei meine Settings damit Du nicht mehr verwirrt bist! :wink:

Zähler 1
Typ Strom (Normales Netz)
MT681
COM 3
Serial to USB => finde gerade das Model nicht
Zählerstand: 11115 KWh
Lässt sich per hterm nur mit „DTR“ auslesen
Liefert keine Daten am Serial Port in ip-symcon

Zähler2
Typ Strom (Wärmepumpe)
MT681
COM5
USB-IR-Schreib-Lesekopf
Zählerstand 7596 KWh Liefert am Serial Port in ip-symcon jetzt Daten
Lässt sich direkt per hterm auslesen

Hi Thorsten,

  1. Die beiden Zähler arbeiten gleich :slight_smile:

ich hab jetzt mal ein komplett neues Script geschrieben, welches bei dir auch laufen sollte.

Das Script greift sich alles was ab der Obis Hersteller Objektnummer (objName 129-129:199.130.3*255 Herstelleridentifikation) kommt und entschlüsselt alle 7er Listeneinträge.
D.h. es werden alle Alle Werte die kommen nach angegebener byte länge separiert und im Anschluss ausgewertet. Hierbei wird explizit nach der Obis Kennung geguckt und nicht mehr mit längen Angaben gearbeitet (die sind eh überall anders)

Die Variablen musst du dir selber erstellen und oben im Script anpassen,
Für dich interessant:

$id_wirkenergie_t1
$id_wirkleistung_ges

mehr würfelt dein Zähler nicht aus.

Deine Cutter Länge war 212
Script und Variablen sowie Cutter etc musst du für 2 Zähler natürlich alles doppelt anlegen.

<?
$data=str_replace(" ","",ascii2hex($IPS_VALUE));
//Variablen IDs
$id_wirkenergie_ges = 35673 /*[Keller\Stromzähler neu test (Script von mir)\Wirkenergie]*/;
$id_wirkenergie_t1 =	24820 /*[Keller\Stromzähler neu test (Script von mir)\Wirkenergie - Tarif 1]*/;
$id_wirkenergie_t2 =	54534 /*[Keller\Stromzähler neu test (Script von mir)\Wirkenergie - Tarif 2]*/;
$id_wirkleistung_ges = 42784 /*[Keller\Stromzähler neu test (Script von mir)\Wirkleistung]*/;
//folgende aktuell bei mir nicht vorhanden
//	$id_wirkleistung_l1 = 1234	;
//	$id_wirkleistung_l2 = 1234	;
//	$id_wirkleistung_l3 = 1234	;
//	$id_wirkleistung_einspeisung = 1234	;

$pakete=ehz77er($data);

for($i = 1; $i < count($pakete); ++$i)
	{
	//Check ob Inhalt 2tes Array [1] die Wirkenergie Gesamt ist (MT681 - bunnymc - 0100010800FF		objName 1-0:1.8.0*255)
	if ($pakete[$i][1] == "0100010800FF")
		{
		//Einheit auswerten Array 4, könnte gemacht werden aber eigentlich nicht nötig 1E = Wh
		//Scaler Auswerten (00 = Kein Scaler, FF = /10, FE = /100  und mit richtigem Scaler Werte schreiben
		//Da es sich um Watt Stunden handelt habe ich die Berechnung auf kWh angepasst
		if ($pakete[$i][5]=="00")
		   {
			SetValue($id_wirkenergie_ges,hexdec($pakete[$i][6]));
			}
		elseif ($pakete[$i][5]=="FF")
		   {
			SetValue($id_wirkenergie_ges,(hexdec($pakete[$i][6])/10000));
			}
		elseif ($pakete[$i][5]=="FE")
		   {
			SetValue($id_wirkenergie_ges,(hexdec($pakete[$i][6])/100000));
			}
		}
	//Check ob Inhalt 2tes Array [1] die Wirkenergie Tarif 1 ist (MT681 - fussi24&bunnymc - 0100010801FF		objName 1-0:1.8.1*255)
	elseif ($pakete[$i][1] == "0100010801FF")
		{
		//Wie Wirkenergie Gesamt
		if ($pakete[$i][5]=="00")
		   {
			SetValue($id_wirkenergie_t1,hexdec($pakete[$i][6]));
			}
		elseif ($pakete[$i][5]=="FF")
		   {
			SetValue($id_wirkenergie_t1,(hexdec($pakete[$i][6])/10000));
			}
		elseif ($pakete[$i][5]=="FE")
		   {
			SetValue($id_wirkenergie_t1,(hexdec($pakete[$i][6])/100000));
			}
		}
   //Check ob Inhalt 2tes Array [1] die Wirkenergie Tarif 2 ist (MT681 - bunnymc - 0100010802FF		objName 1-0:1.8.2*255)
	elseif ($pakete[$i][1] == "0100010802FF")
		{
		//Wie Wirkenergie Gesamt
		if ($pakete[$i][5]=="00")
		   {
			SetValue($id_wirkenergie_t2,hexdec($pakete[$i][6]));
			}
		elseif ($pakete[$i][5]=="FF")
		   {
			SetValue($id_wirkenergie_t2,(hexdec($pakete[$i][6])/10000));
			}
		elseif ($pakete[$i][5]=="FE")
		   {
			SetValue($id_wirkenergie_t2,(hexdec($pakete[$i][6])/100000));
			}
		}
   //Check ob Inhalt 2tes Array [1] die Wirkleistung Gesamt ist   /MT681 - bunnymc - 0100100700FF		objName 1-0:16.7.0*255)
	elseif ($pakete[$i][1] == "0100100700FF")
		{
		//Einheit auswerten Array 4, könnte gemacht werden aber eigentlich nicht nötig 1E = Wh
		//Scaler Auswerten (00 = Kein Scaler, FF = /10, FE = /100  und mit richtigem Scaler Werte schreiben
		if ($pakete[$i][5]=="00")
		   {
			SetValue($id_wirkleistung_ges,hexdec($pakete[$i][6]));
			}
		elseif ($pakete[$i][5]=="FF")
		   {
			SetValue($id_wirkleistung_ges,(hexdec($pakete[$i][6])/10));
			}
		elseif ($pakete[$i][5]=="FE")
		   {
			SetValue($id_wirkleistung_ges,(hexdec($pakete[$i][6])/100));
			}
		}
	//ACHTUNG folgende Funktion wird AUCH in Gesamt geschrieben !!!
	//Check ob Inhalt 2tes Array [1] die Wirkleistung Bezug+ ist (MT681 - fussi24 - 0100010700FF		objName 1-0:1.7.0*255)
	elseif ($pakete[$i][1] == "0100010700FF")
		{
		//Einheit auswerten Array 4, könnte gemacht werden aber eigentlich nicht nötig 1E = Wh
		//Scaler Auswerten (00 = Kein Scaler, FF = /10, FE = /100  und mit richtigem Scaler Werte schreiben
		if ($pakete[$i][5]=="00")
		   {
			SetValue($id_wirkleistung_ges,hexdec($pakete[$i][6]));
			}
		elseif ($pakete[$i][5]=="FF")
		   {
			SetValue($id_wirkleistung_ges,(hexdec($pakete[$i][6])/10));
			}
		elseif ($pakete[$i][5]=="FE")
		   {
			SetValue($id_wirkleistung_ges,(hexdec($pakete[$i][6])/100));
			}
		}
	//toDO Check ob Inhalt 2tes Array [1] die Wirkleistung Einspeisung- ist
	//toDO Check ob Inhalt 2tes Array [1] die Wirkleistung L1- ist
	//toDO Check ob Inhalt 2tes Array [1] die Wirkleistung L2- ist
	//toDO Check ob Inhalt 2tes Array [1] die Wirkleistung L3- ist
	}



















////// Funktion für die Errechnung
function ehz77er($sml)
{	$sml1=substr($sml, strpos($sml, "77078181C78203FF")); //Schneidet ALLES vor der Herstelleridentifikationsorbiskennzahl ab (objName 129-129:199.130.3*255)
	$daten=explode(chr(0x37).chr(0x37), $sml1); //bei 77er Listen trennen
	for($i = 1; $i < count($daten); ++$i)
		{
		$paket1_len=substr($daten[$i], 1,1); //hiermit bekomme ich die länge des ersten pakets in byte (also immer 2er Pärchen)
		if ($paket1_len!=1) //Wenn die angegebene länge nicht nur 1 Byte(leere Pakete) ist, dann die Daten rausholen
			{
			$paket[$i][1]=substr($daten[$i],2,(($paket1_len*2)-2)); //der Inhalt des Pakets wird anhand der Länge herausgefiltert (das erste byte wird abegschnitten), x2 bei 1 Byte 2 Zeichen hat in HEX)
			}
		else
			{
			$paket[$i][1]="00";
			}
		$paket2_len=substr($daten[$i], (($paket1_len*2)+1),1); //hiermit bekomme ich die länge des zweiten pakets in byte, abhängig von der Länge des ersten Pakets
		if ($paket2_len!=1)
			{
			$paket[$i][2]=substr($daten[$i],(($paket1_len)+2),(($paket2_len*2)-2)); //Wie oben, nur ab hier alles abhängig von den vorherigen längen
			}
		else
			{
			$paket[$i][2]="00";
			}
		$paket3_len=substr($daten[$i], ((($paket1_len+$paket2_len)*2)+1),1);
		if ($paket3_len!=1)
			{
			$paket[$i][3]=substr($daten[$i],((($paket1_len+$paket2_len)*2)+2),(($paket3_len*2)-2));
			}
		else
			{
			$paket[$i][3]="00";
			}
		$paket4_len=substr($daten[$i], ((($paket1_len+$paket2_len+$paket3_len)*2)+1),1);
		if ($paket4_len!=1)
			{
			$paket[$i][4]=substr($daten[$i],((($paket1_len+$paket2_len+$paket3_len)*2)+2),(($paket4_len*2)-2));
			}
		else
			{
			$paket[$i][4]="00";
			}
		$paket5_len=substr($daten[$i], ((($paket1_len+$paket2_len+$paket3_len+$paket4_len)*2)+1),1);
		if ($paket5_len!=1)
			{
			$paket[$i][5]=substr($daten[$i],((($paket1_len+$paket2_len+$paket3_len+$paket4_len)*2)+2),(($paket5_len*2)-2));
			}
		else
			{
			$paket[$i][5]="00";
			}
		$paket6_len=substr($daten[$i], ((($paket1_len+$paket2_len+$paket3_len+$paket4_len+$paket5_len)*2)+1),1);
		if ($paket6_len!=1)
			{
			$paket[$i][6]=substr($daten[$i],((($paket1_len+$paket2_len+$paket3_len+$paket4_len+$paket5_len)*2)+2),(($paket6_len*2)-2));
			}
		else
			{
			$paket[$i][6]="00";
			}
		$paket7_len=substr($daten[$i], ((($paket1_len+$paket2_len+$paket3_len+$paket4_len+$paket5_len+$paket6_len)*2)+1),1);
		if ($paket7_len!=1)
			{
			$paket[$i][7]=substr($daten[$i],((($paket1_len+$paket2_len+$paket3_len+$paket4_len+$paket5_len+$paket6_len)*2)+2),(($paket7_len*2)-2));
			}
		else
			{
			$paket[$i][7]="00";
			}
		}
	return $paket;
// Die Funktion ehz77er wertet, wie der Name schon sagt, aller 77er Pakete (Liste mit 7 Einträgen) der SML Transmission aus.
// Diese werden dann als Doppel Array $Paket [PaketNr][PaketInhalt 1-7]
// In jedem der 7 EInträge wird ausschließlich der Wert des Eintrags zurückgeliefert
// Beispiel:   77078181C78203FF010101010649534B524101
//					77						Liste mit 7 Einträgen
//					  078181C78203FF								objName 129-129:199.130.3*255 Herstelleridentifikation
//				(Bsp.:|07 bedeutet 7 Bytes, 81 81 C7 82 03 FF ist der echte Wert)
//					                01							status (leer)
//					                  01							valTime (leer)
//					                    01						unit (leer)
//					                      01					scaler (leer)
//					                        0649534B5241		value
//					                                    01
}

function ascii2hex($ascii) {
$hex = '';
for ($i = 0; $i < strlen($ascii); $i++) {
$byte = strtoupper(dechex(ord($ascii{$i})));
$byte = str_repeat('0', 2 - strlen($byte)).$byte;
$hex.=$byte." ";
}
return $hex;
}
?>

Ich hoffe das haut hin, hat mich viel nerven gekostet vor allem weil ich nen versteckten Groß/Kleinschreibungsfehler drin hatte :smiley:

(Bei mir kommen die Werte im Script, wie bei dir, auch als ASCII an deswegen oben die konvertierungen.)

Grüße
Rene

Update:

Ich habe das Script noch ein wenig angepasst, die Variablen für Wirkenergie und Leistung müssen jetzt nicht mehr von Hand angelegt werden, sondern es reicht das Script einmal von Hand zu starten. (Trotzdem musst du noch ComPort/Cutter und Register Variable anlegen und verknüpfen)

Achtung ! Bitte packe das Script jwls. in eine eigene Kategorie pro Zähler und lass es dann erst einmal von Hand laufen.
Und natürlich nicht die Namen der Variablen in IPS ändern, sonst werden die nicht mehr gefunden. Du könntest höchsten das Script anpassen.

<?
//manuell starten = prüfen ob Variablen vorhanden und ggf anlegen !
//wenn die Variablen vorhanden sind wird direkt das richtige Profil draufgelegt!
$name_Wirkenergie="Wirkenergie";
$name_Wirkenergie_T1="Wirkenergie - Tarif 1";
$name_Wirkenergie_T2="Wirkenergie - Tarif 2";
$name_Wirkleistung="Wirkleistung";

if($_IPS['SENDER'] == "Execute")
	{
	$parent=IPS_GetParent($_IPS['SELF']);
	$variableid = @IPS_GetVariableIDByName($name_Wirkenergie, $parent);
	    if($variableid === false)
	    {
	        $variableid = IPS_CreateVariable(2);
	        IPS_SetName($variableid, $name_Wirkenergie);
	        IPS_SetParent($variableid, $parent);
	        IPS_SetVariableCustomProfile($variableid, "~Electricity");
	    }
	    else
	    {
	    IPS_SetVariableCustomProfile($variableid, "~Electricity");
	    }
	$variableid = @IPS_GetVariableIDByName($name_Wirkenergie_T1, $parent);
	   if($variableid === false)
	    {
	        $variableid = IPS_CreateVariable(2);
	        IPS_SetName($variableid, $name_Wirkenergie_T1);
	        IPS_SetParent($variableid, $parent);
	        IPS_SetVariableCustomProfile($variableid, "~Electricity");
	    }
		else
	    {
	    IPS_SetVariableCustomProfile($variableid, "~Electricity");
	    }
	$variableid = @IPS_GetVariableIDByName($name_Wirkenergie_T2, $parent);
	    if($variableid === false)
	    {
	        $variableid = IPS_CreateVariable(2);
	        IPS_SetName($variableid, $name_Wirkenergie_T2);
	        IPS_SetParent($variableid, $parent);
	        IPS_SetVariableCustomProfile($variableid, "~Electricity");
	    }
	    else
	    {
	    IPS_SetVariableCustomProfile($variableid, "~Electricity");
	    }
	$variableid = @IPS_GetVariableIDByName($name_Wirkleistung, $parent);
	    if($variableid === false)
	    {
	        $variableid = IPS_CreateVariable(2);
	        IPS_SetName($variableid, $name_Wirkleistung);
	        IPS_SetParent($variableid, $parent);
	        IPS_SetVariableCustomProfile($variableid, "~Watt.3680");
	    }
	    else
	    {
	    IPS_SetVariableCustomProfile($variableid, "~Watt.3680");
	    }
	}//Ende manueller Start

//Auswertung, start über Regvar
if($_IPS['SENDER'] == "RegisterVariable")
	{
	$data=str_replace(" ","",ascii2hex($IPS_VALUE));
	$parent=IPS_GetParent($_IPS['SELF']);
	//Variablen IDs
	$id_wirkenergie_ges = @IPS_GetVariableIDByName($name_Wirkenergie, $parent) /*[Keller\Stromzähler neu test (Script von mir)\Wirkenergie]*/;
	$id_wirkenergie_t1 =	@IPS_GetVariableIDByName($name_Wirkenergie_T1, $parent) /*[Keller\Stromzähler neu test (Script von mir)\Wirkenergie - Tarif 1]*/;
	$id_wirkenergie_t2 =	@IPS_GetVariableIDByName($name_Wirkenergie_T2, $parent) /*[Keller\Stromzähler neu test (Script von mir)\Wirkenergie - Tarif 2]*/;
	$id_wirkleistung_ges = @IPS_GetVariableIDByName($name_Wirkleistung, $parent) /*[Keller\Stromzähler neu test (Script von mir)\Wirkleistung]*/;
	//folgende aktuell bei mir nicht vorhanden
	//	$id_wirkleistung_l1 = 1234	;
	//	$id_wirkleistung_l2 = 1234	;
	//	$id_wirkleistung_l3 = 1234	;
	//	$id_wirkleistung_einspeisung = 1234	;

	$pakete=ehz77er($data);

	for($i = 1; $i < count($pakete); ++$i)
		{
		//Check ob Inhalt 2tes Array [1] die Wirkenergie Gesamt ist (MT681 - bunnymc - 0100010800FF		objName 1-0:1.8.0*255)
		if ($pakete[$i][1] == "0100010800FF")
			{
			//Einheit auswerten Array 4, könnte gemacht werden aber eigentlich nicht nötig 1E = Wh
			//Scaler Auswerten (00 = Kein Scaler, FF = /10, FE = /100  und mit richtigem Scaler Werte schreiben
			//Da es sich um Watt Stunden handelt habe ich die Berechnung auf kWh angepasst
			if ($pakete[$i][5]=="00")
			   {
				SetValue($id_wirkenergie_ges,hexdec($pakete[$i][6]));
				}
			elseif ($pakete[$i][5]=="FF")
			   {
				SetValue($id_wirkenergie_ges,(hexdec($pakete[$i][6])/10000));
				}
			elseif ($pakete[$i][5]=="FE")
			   {
				SetValue($id_wirkenergie_ges,(hexdec($pakete[$i][6])/100000));
				}
			}
		//Check ob Inhalt 2tes Array [1] die Wirkenergie Tarif 1 ist (MT681 - fussi24&bunnymc - 0100010801FF		objName 1-0:1.8.1*255)
		elseif ($pakete[$i][1] == "0100010801FF")
			{
			//Wie Wirkenergie Gesamt
			if ($pakete[$i][5]=="00")
			   {
				SetValue($id_wirkenergie_t1,hexdec($pakete[$i][6]));
				}
			elseif ($pakete[$i][5]=="FF")
			   {
				SetValue($id_wirkenergie_t1,(hexdec($pakete[$i][6])/10000));
				}
			elseif ($pakete[$i][5]=="FE")
			   {
				SetValue($id_wirkenergie_t1,(hexdec($pakete[$i][6])/100000));
				}
			}
	   //Check ob Inhalt 2tes Array [1] die Wirkenergie Tarif 2 ist (MT681 - bunnymc - 0100010802FF		objName 1-0:1.8.2*255)
		elseif ($pakete[$i][1] == "0100010802FF")
			{
			//Wie Wirkenergie Gesamt
			if ($pakete[$i][5]=="00")
			   {
				SetValue($id_wirkenergie_t2,hexdec($pakete[$i][6]));
				}
			elseif ($pakete[$i][5]=="FF")
			   {
				SetValue($id_wirkenergie_t2,(hexdec($pakete[$i][6])/10000));
				}
			elseif ($pakete[$i][5]=="FE")
			   {
				SetValue($id_wirkenergie_t2,(hexdec($pakete[$i][6])/100000));
				}
			}
	   //Check ob Inhalt 2tes Array [1] die Wirkleistung Gesamt ist   /MT681 - bunnymc - 0100100700FF		objName 1-0:16.7.0*255)
		elseif ($pakete[$i][1] == "0100100700FF")
			{
			//Einheit auswerten Array 4, könnte gemacht werden aber eigentlich nicht nötig 1E = Wh
			//Scaler Auswerten (00 = Kein Scaler, FF = /10, FE = /100  und mit richtigem Scaler Werte schreiben
			if ($pakete[$i][5]=="00")
			   {
				SetValue($id_wirkleistung_ges,hexdec($pakete[$i][6]));
				}
			elseif ($pakete[$i][5]=="FF")
			   {
				SetValue($id_wirkleistung_ges,(hexdec($pakete[$i][6])/10));
				}
			elseif ($pakete[$i][5]=="FE")
			   {
				SetValue($id_wirkleistung_ges,(hexdec($pakete[$i][6])/100));
				}
			}
		//ACHTUNG folgende Funktion wird AUCH in Gesamt geschrieben !!!
		//Check ob Inhalt 2tes Array [1] die Wirkleistung Bezug+ ist (MT681 - fussi24 - 0100010700FF		objName 1-0:1.7.0*255)
		elseif ($pakete[$i][1] == "0100010700FF")
			{
			//Einheit auswerten Array 4, könnte gemacht werden aber eigentlich nicht nötig 1E = Wh
			//Scaler Auswerten (00 = Kein Scaler, FF = /10, FE = /100  und mit richtigem Scaler Werte schreiben
			if ($pakete[$i][5]=="00")
			   {
				SetValue($id_wirkleistung_ges,hexdec($pakete[$i][6]));
				}
			elseif ($pakete[$i][5]=="FF")
			   {
				SetValue($id_wirkleistung_ges,(hexdec($pakete[$i][6])/10));
				}
			elseif ($pakete[$i][5]=="FE")
			   {
				SetValue($id_wirkleistung_ges,(hexdec($pakete[$i][6])/100));
				}
			}
		//toDO Check ob Inhalt 2tes Array [1] die Wirkleistung Einspeisung- ist
		//toDO Check ob Inhalt 2tes Array [1] die Wirkleistung L1- ist
		//toDO Check ob Inhalt 2tes Array [1] die Wirkleistung L2- ist
		//toDO Check ob Inhalt 2tes Array [1] die Wirkleistung L3- ist
		}
	} //Ende RegVar aufruf

////// Funktion für die Errechnung
function ehz77er($sml)
{	$sml1=substr($sml, strpos($sml, "77078181C78203FF")); //Schneidet ALLES vor der Herstelleridentifikationsorbiskennzahl ab (objName 129-129:199.130.3*255)
	$daten=explode(chr(0x37).chr(0x37), $sml1); //bei 77er Listen trennen
	for($i = 1; $i < count($daten); ++$i)
		{
		$paket1_len=substr($daten[$i], 1,1); //hiermit bekomme ich die länge des ersten pakets in byte (also immer 2er Pärchen)
		if ($paket1_len!=1) //Wenn die angegebene länge nicht nur 1 Byte(leere Pakete) ist, dann die Daten rausholen
			{
			$paket[$i][1]=substr($daten[$i],2,(($paket1_len*2)-2)); //der Inhalt des Pakets wird anhand der Länge herausgefiltert (das erste byte wird abegschnitten), x2 bei 1 Byte 2 Zeichen hat in HEX)
			}
		else
			{
			$paket[$i][1]="00";
			}
		$paket2_len=substr($daten[$i], (($paket1_len*2)+1),1); //hiermit bekomme ich die länge des zweiten pakets in byte, abhängig von der Länge des ersten Pakets
		if ($paket2_len!=1)
			{
			$paket[$i][2]=substr($daten[$i],(($paket1_len)+2),(($paket2_len*2)-2)); //Wie oben, nur ab hier alles abhängig von den vorherigen längen
			}
		else
			{
			$paket[$i][2]="00";
			}
		$paket3_len=substr($daten[$i], ((($paket1_len+$paket2_len)*2)+1),1);
		if ($paket3_len!=1)
			{
			$paket[$i][3]=substr($daten[$i],((($paket1_len+$paket2_len)*2)+2),(($paket3_len*2)-2));
			}
		else
			{
			$paket[$i][3]="00";
			}
		$paket4_len=substr($daten[$i], ((($paket1_len+$paket2_len+$paket3_len)*2)+1),1);
		if ($paket4_len!=1)
			{
			$paket[$i][4]=substr($daten[$i],((($paket1_len+$paket2_len+$paket3_len)*2)+2),(($paket4_len*2)-2));
			}
		else
			{
			$paket[$i][4]="00";
			}
		$paket5_len=substr($daten[$i], ((($paket1_len+$paket2_len+$paket3_len+$paket4_len)*2)+1),1);
		if ($paket5_len!=1)
			{
			$paket[$i][5]=substr($daten[$i],((($paket1_len+$paket2_len+$paket3_len+$paket4_len)*2)+2),(($paket5_len*2)-2));
			}
		else
			{
			$paket[$i][5]="00";
			}
		$paket6_len=substr($daten[$i], ((($paket1_len+$paket2_len+$paket3_len+$paket4_len+$paket5_len)*2)+1),1);
		if ($paket6_len!=1)
			{
			$paket[$i][6]=substr($daten[$i],((($paket1_len+$paket2_len+$paket3_len+$paket4_len+$paket5_len)*2)+2),(($paket6_len*2)-2));
			}
		else
			{
			$paket[$i][6]="00";
			}
		$paket7_len=substr($daten[$i], ((($paket1_len+$paket2_len+$paket3_len+$paket4_len+$paket5_len+$paket6_len)*2)+1),1);
		if ($paket7_len!=1)
			{
			$paket[$i][7]=substr($daten[$i],((($paket1_len+$paket2_len+$paket3_len+$paket4_len+$paket5_len+$paket6_len)*2)+2),(($paket7_len*2)-2));
			}
		else
			{
			$paket[$i][7]="00";
			}
		}
	return $paket;
// Die Funktion ehz77er wertet, wie der Name schon sagt, aller 77er Pakete (Liste mit 7 Einträgen) der SML Transmission aus.
// Diese werden dann als Doppel Array $Paket [PaketNr][PaketInhalt 1-7]
// In jedem der 7 EInträge wird ausschließlich der Wert des Eintrags zurückgeliefert
// Beispiel:   77078181C78203FF010101010649534B524101
//					77						Liste mit 7 Einträgen
//					  078181C78203FF								objName 129-129:199.130.3*255 Herstelleridentifikation
//				(Bsp.:|07 bedeutet 7 Bytes, 81 81 C7 82 03 FF ist der echte Wert)
//					                01							status (leer)
//					                  01							valTime (leer)
//					                    01						unit (leer)
//					                      01					scaler (leer)
//					                        0649534B5241		value
//					                                    01
}

function ascii2hex($ascii) {
$hex = '';
for ($i = 0; $i < strlen($ascii); $i++) {
$byte = strtoupper(dechex(ord($ascii{$i})));
$byte = str_repeat('0', 2 - strlen($byte)).$byte;
$hex.=$byte." ";
}
return $hex;
}
?>

//Update - Script geupdated
Grüße
Rene

Ps. Darf natürlich auch jeder andere verwenden und anpassen, aber BITTE Nachsicht wenn etwas im Code von einem Programmierer anders gelöst worden wäre, ich bin keiner :slight_smile:

Hallo Rene,

wooh vielen Dank! :wink:

Das werde ich dann Morgen sofort ausprobieren.

Mir ist nur noch nicht ganz klar was ich im Cutter eintragen soll. Die Eingabelänge auf 212 ist mir klar, aber was nehme ich als „Sync Zeichen“?

Vielen Gruß

Thorsten

Hi Thorsten,

Kein Ding.

Der Cutter bleibt so wie du ihn hast nur das die Cutter länger geändert wird.

Wenn etwas nicht klappt sag bescheid.

Bei dem Zähler der dtr an braucht kann ich dir leider wenig weiterhelfen, lies dir am besten dazu mal den Thread den ich oben verlinkt habe durch.

Grüße
Rene

Hallo,
nun habe ich auch so einen Zähler.
Die Einstellungen von Euch habe ich soweit übernommen - tolle Arbeit!

Unter Meldungen kommt immer folgendes:

RegisterVariable -> undefinierte Variable: paket und dann die Zeile 250 mit dem Befehl: „return $paket;“

Der Sprungbefehl ist ganz unten im Code:


            $paket[$i][7]="00";
            }
        }
    return $paket;
// Die Funktion ehz....

Grüße, Tobias

PS: die Werte für L1-3 werden von meinem Zähler auch nicht gesendet

EDIT:
nun funktioniert alles!
Ich habe die RegisterVariable gelöscht und neu angelegt.

Hallo,

habe heute einen MT631 bekommen - PIN habe ich angefordert - meine Frage an Euch - wie würde ich denn die PIN per Lesekopf an den Zähler schicken? bzw. hat jemand mit dem MT631 Erfahrungen.

Grüße,
MaLu

ist zwar eine Anleitung für den MT681 aber sollte auch passen:

LG, Peter

@pitty -

Danke - Sodela, Zähler liefert alle 1 Sekunden eine 322 lange Info raus - beginnend mit 1B1B1B1B01010101 etc. - sieht im Prinzip richtig aus - nur der oben genannte Script wird mit dem ! markiert - wo fang ich am Besten an …?

Danke und Grüße,
MaLu

Schau die mal diese Beispielausgabe an:
Beispielausgabe ISKRA MT681.txt (9,1 KB)

Oder aber etwas Code aus meinem Auslesescript:

//******************************************************************************
// Zählerwerte ermitteln
//******************************************************************************

$data       = $_IPS['VALUE'];                                      // 456 aus Cutter 912 bin2hex($_IPS['VALUE']);
$len        = strlen($data);                                       // len = 456

$pos        = strpos($_IPS['VALUE'],chr(0x01).chr(0x00).chr(0x01).chr(0x08).chr(0x00).chr(0xFF));           //01 00 01 08 00 FF	= Pos.133 = OBIS Kennzahl für Wirkenergie Bezug gesamt tariflos
$pos        = $pos+17;                                              // Start Zählerwert 8 Stellen hex gesamt
$zaehlerSU  = hexdec(bin2hex(substr($data,$pos,8)))/10000.0;

$pos        = $pos+24;                                              // NT 
$zaehlerNT  = hexdec(bin2hex(substr($data,$pos,8)))/10000.0;

$pos        = $pos+24;                                              // HT 
$zaehlerHT  = hexdec(bin2hex(substr($data,$pos,8)))/10000.0;

$pos        = $pos+24;                                              // Wirkenergie Einspeisung gesamt tariflos

$pos        = $pos+24;                                              // Wirkenergie Einspeisung Tarif1

$pos        = $pos+24;                                              // Wirkenergie Einspeisung Tarif2

$pos        = $pos+24;                                              // momentane Gesamtwirkleistung
$zaehlerW   = hexdec(bin2hex(substr($data,$pos,4)));

$pos        = $pos+20;                                              // momentane Wirkleistung in Phase L1

$pos        = $pos+20;                                              // momentane Wirkleistung in Phase L2 

$pos        = $pos+20;                                              // momentane Wirkleistung in Phase L3 

//echo $zaehlerSU." - ".$zaehlerNT." - ".$zaehlerHT." - ".$zaehlerW;

Grüße, Peter

Hallo pitty,

Ui, ich glaube das übersteigt meine Fähigkeiten irgendwie - das Originalskript von oben - das meldet im Log (Das „Braces“ Problem hatte ich geändert).

19.11.2021, 16:48:34 | Cutter | Puffer > 8kb
19.11.2021, 16:48:34 | Cutter | Begrenze Puffer auf die letzten 64kb19.11.2021, 16:48:34 | Register Variable |
Warning: A non-numeric value encountered in C:\ProgramData\Symcon\scripts\42245.ips.php on line 197
Warning: A non-numeric value encountered in C:\ProgramData\Symcon\scripts\42245.ips.php on line 203
Warning: A non-numeric value encountered in C:\ProgramData\Symcon\scripts\42245.ips.php on line 206
Warning: A non-numeric value encountered in C:\ProgramData\Symcon\scripts\42245.ips.php on line 206
Warning: A non-numeric value encountered in C:\ProgramData\Symcon\scripts\42245.ips.php on line 212
Warning: A non-numeric value encountered in C:\ProgramData\Symcon\scripts\42245.ips.php on line 212
Warning: A non-numeric value encountered in C:\ProgramData\Symcon\scripts\42245.ips.php on line 215
Warning: A non-numeric value encountered in C:\ProgramData\Symcon\scripts\42245.ips.php on line 215
Warning: A non-numeric value encountered in C:\ProgramData\Symcon\scripts\42245.ips.php on line 215
Warning: A non-numeric value encountered in C:\ProgramData\Symcon\scripts\42245.ips.php on line 221
Abort Processing during exceed of maximal ErrorCount: A non-numeric value encountered
Error in Script C:\ProgramData\Symcon\scripts\42245.ips.php on Line 221

Hilft das?

Grüße,
MaLu

Hallo MaLu,

ja das ist sehr kompliziert.
Habe leider heute keine Zeit mehr.
Hast du schon den Pin-Code eingegeben?
Ich versuche mal deine Cutter-Ausgabe zu lesen (kann aber noch etwas dauern)
Du kannst ja mal hier nachlesen wie sowas geht:
https://www.stefan-weigert.de/php_loader/sml.php