Stromzähler auslesen, Verbindung bricht ab

Hallo,
ich lese erfolgreich meinen Stromzähler(ISKRA-MT681) über die serielle Schnittstelle aus. Wie hier beschrieben.
ISKRA MT681 per Opto Koppler auslesen

IP-Symcon läuft bei mir in einer VM-Ware (Win7). Alle 1-2 Tage werden keine Daten mehr vom Zähler angezeigt. Um das Problem zu beheben, reicht es in VM-Ware den seriellen Port zu trennen und wieder zu verbinden.

Hat jemand eine Idee, wie ich den Fehler einkreisen kann?

Serieller Port ist eine PCI-Karte(kein USB-Wandler).

Und dann gibt es noch eine zweite Schwiriegkeit: Nach einem PC Neustart, muss ich das Skript das erste Mal von Hand „Ausführen“. Danach läuft es dann.


 <?
COMPort_SetDTR(17543 /*[Serial Port Strom Zähler]*/ , true); //17543 ist die ID von der Seriellen Schnittstelle!!!
//https://www.symcon.de/forum/threads/25648-ISKRA-MT681-per-Opto-Koppler-auslesen?highlight=obis
//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);
   // $id_wirkenergie_t1 =    @IPS_GetVariableIDByName($name_Wirkenergie_T1, $parent);
   // $id_wirkenergie_t2 =    @IPS_GetVariableIDByName($name_Wirkenergie_T2, $parent);
    $id_wirkleistung_ges = @IPS_GetVariableIDByName($name_Wirkleistung, $parent);
    //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;
}
?>


Und dann gibt es noch eine zweite Schwiriegkeit: Nach einem PC Neustart, muss ich das Skript das erste Mal von Hand „Ausführen“. Danach läuft es dann.

hier gibt es was für
https://www.symcon.de/service/dokumentation/modulreferenz/event-control/

gruss Jens

oh super - das funktioniert ja sehr gut