IPS 4.0 - Dienst beendet sich "vonselbst"

Hallo,

der IPS Dienst beendet sich „vonselbst“ in der folgenden Situation:

Highcharts Nutzung - Bei der Darstellung eines „grösseren“ Zeitraums - in diesem Fall 1 Monat - kommt folgende Meldung - danach ist der IPS Dienst beendet. Bei Nutzung von Zeiträumen bis zu 2 Wochen kommt dieser Fehler nicht.

Unter 3.4 habe ich keinerlei Probleme mit der Darstellung von bis zu 1 Jahr und denselben Skripten.

Grüsse,
MaLu

Fehlermeldung:

Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 36 bytes) in [System Funktionen\HighCharts\HighChartsPHP\HighChartPHP] on line 431

Stürzt der Dienst ab, oder zeigt er dir nur kein Bild an? Memory exhaused heißt, dass das PHP Memory limit in deiner php.ini zu klein ist. Das kannst du selber erhöhen :slight_smile:

paresy

Hi,

der Dienst hat sich auch bei mir nach ca. 4 Stunden von selbst beendet. Im normalen Log steht nichts besonderes (auch nicht immer dasselbe). V3.4 lief dagegen mit denselben Skripten monatelang stabil.

Im bin jetzt zur 3.4 zurück, da ich mich zu 99.9% auf IPS verlassen können muss.

Gruss
Coyote

Magst du mal schauen, ob im IP-Symcon 4.0 Ordner ein Ordner mit minidump ist und mir den ggf. zusenden?

paresy

Hallo paresy,

der Dienst stürzt ab - nach dem Fehler steht der Dienst in der Konsole auf Dienst starten und IPS ist klarerweise nicht mehr erreichbar - kann den Dienst wieder starten und dann geht es erstmal wieder.

Habe mal unter 3.4 mit noch grösseren Zeiträumen gearbeitet und kann dann tatsächlich auch den Fehler sehen - unter 3.4 sieht man dann keinen Highchart aber IPS läuft einfach weiter :slight_smile:

Grüsse,
MaLu

Magst du mir bei dir im IP-Symcon 4.0 Order den Ordner minidumps packen und zukommen lassen?

paresy

Hallo paresy,

Klar, kein Problem … bin zwar auf 3.4 zurück … aber habe das Verzeichnis behalten :wink: -

Der Dump 300MB umgepackt aber immer noch 100MB gepackt - wohin und wie willst denn das ZIP haben … habt Ihr einen FTP?

Grüsse,
MaLu

Hallo,

Den Dump habe ich Dir mal geschickt …

habe mal unter 3.4 das PHP Memory Limit auf 64MB erhöht - nun kann ich Highcharts Fehler nicht mehr unter 3.4 provozieren. Aber sag mal … irgendwie fühlt sich nun mein IPS im WF schneller an - speziell bei den Highcharts. Hilft das auch für sowas :smiley:

Naja, mal laufen lassen … jetzt gönnt sich IPS.exe rund 250MB Speicher.

Grüsse,
MaLu

Hallo paresy,

ich habe noch ein paarmal getestet … ich kann beliebig mit meinen Highcharts und langen Zeiträumen IPS 4.0 zum „Beenden“ des Dienstes bekommen. Die PHP Einstellungen habe ich wie unter 3.4 nun geändert / gelassen. Das ändert für IPS 4.0 nix. 3.4 habe ich nochmals intensiv getestet … diese Version ist und bleibt stabil und lässt sich nicht beeindrucken.
Ich habe noch zwei andere Situationen gehabt wo sich der Dienst beendet hat. Es entsteht übrigens nicht bei jedem dieser Dienst Beenden Effekte ein Minidump.

Ich gehe in den Standby und mache keine weiteren Tests - wenn Du eine Version hast die „stabil“ ist oder Du den Schwachpunkt gefunden hast … kann ich es gerne „gegentesten“ … ich kann es ja im Prinzip innerhalb kurzer Zeit willentlich prüfen.

Grüsse,
MaLu

Hi paresy,

ich hab das gleiche Problem wie Coyote … regelmäßig nach 4 Stunden und 10 bis 20 Minuten crasht der IPS-Dienst … habe den Dienst so eingestellt, dass er automatisch neu startet und mir beim Start von IPS ne Mail schickt … das Ganze habe ich jetzt 6 mal in Folge nachvollziehen können … ich kann da die Uhr nach stellen, das nächste Mal dürfte er gegen 8:10 crashen :wink:

In den IPS-Logs sieht man nichts besonderes, im Windows System Log und im Application Log dagegen schon. Ich kuck morgen mal nach dem Minidump und melde mich noch mal …

Bis später …

Hi … rechtzeitig um 8:09 kam der nächste Crash … ich habe jetzt wieder bis ca. 12:20 Uhr ruhe :smiley: … nee, im Ernst: Er hat leider nur in 2 Fällen etwas in den Dump reingeschrieben. Dabei allerdings jeweils über 1,5 GByte … selbst gepackt komme ich da auf 650 MByte … ich brauche es vermutlich gar nicht erst zu versuchen, die Datei hier anzuhängen :wink:

Anbei noch ein paar Screenshots der Eventlogs, obwohl ich nicht weiß, ob für Dich da wirklich was brauchbares auszulesen ist …

Nach dem Start des IPS-Dienstes kommen noch 3 PHP-Fehler, die auf fehlende DLL’s hinweisen, das ist aber sicherlich nicht in Zusammenhang mit dem Crash zu sehen … es werden die Dateien php_pdo_oci.dll, php_pgsql.dll und php_pdo_firebird.dll angemosert.

Wäre super, wenn der Fehler möglichst schnell gefunden wird, da der WAF natürlich immer dann irgendwelche Schalter betätigt, wenn der Dienst gerade mal für 2 Minuten weg ist :rolleyes: …

Danke Euch …

minidump.PNG

… 4 Stunden und 10 Minuten entsprechen übrigens genau 15000 Sekunden … vielleicht ein Ansatz?

Magst du mal schauen, ob bei dir der Speicher von der ips.exe hoch geht? Das klingt fast sehr nach einem Speicherleck. Welches Systeme nutzt du?

paresy

Ich analysiere das mal beim nächsten Zyklus … der Dienst sollte sich erfahrungsgemäß gegen 16:30 Uhr beenden …

IPS läuft bei mir auf einem Windows Server 2012 R2 x64 … Hardware ist ein Lenovo Q180 mit Intel Atom D2700 CPU und 4 GB …

Melde mich heute Abend noch einmal … bis später …

Hi paresy …

Bingo … es ist wirklich ein Memory Leak … kurz vorm Crash zog sich ips.exe 1.65 GByte vom Speicher … nach dem Neustart nur noch 270 MByte …

Ich kann beobachten, dass alle 2 Minuten die CPU-Nutzung von ips.exe hochschnellt, und es sich ca. 10 MByte mehr Speicher nimmt, die es aber nicht mehr freigibt …

Ich habe den Verdacht, dass der Auslöser ein Script ist, welches von meiner Viessmann-Heizung aktuelle Werte holt (OpenV) … dies geschieht in eine RegisterVariable … muss das aber noch mal beobachten und verifizieren …

Bis später …

Hallo paresy,

ich lade Dir noch weitere 3 Mini Dumps hoch. Vielleicht hilfts ja zum finden des Problems.

Die Dumps sind oben…

Grüsse,
MaLu

Hallo paresy,

ich habe das Verhalten nochmals mir angeschaut … immer kurz bevor der Dienst sich beendet, sieht man im Tankmanager einen Speicherverbrauch Peak … z.B. 170MB auf 490MB … danach geht der Speicher wieder runter und der Dienst beendet sich dann.

Grüsse,
MaLu

Hi paresy,

die Vermutung hat sich bestätigt … ich habe die automatische Ausführung des verdächtigen Scripts gestoppt, danach war kein Speicheranstieg mehr zu beobachten. Sobald ich das Script manuell ausführe, werden anschließend 10 MByte mehr Speicher vom ips.exe-Prozess benutzt. In Version 3.4 war dies nicht so … hast Du eine Idee, woran das liegen kann? Muss ich den RegVar-Buffer nach Scriptausführung wieder freigeben? Ich habe allerdings keinen Befehl dafür in der Doku gefunden …

Danke und viele Grüße …

Magst du mir das Skript hier reinkopieren?

Am RegVar Buffer kann es eigentlich nicht liegen… Der würde in den Meldungen sehr stark meckern, wenn du mehr als 8kb reintust.

paresy

Geht los:

Das hier ist das Script, welches alle 2 Minuten ausgeführt wird

<?
 include("_functionstemp.ips.php");
 
 //Zeitstempel Minute holen und letzte Ziffer auswerten, Prioritäten setzen
 $minute = strval(date("i"));
 if($minute[1] == "1" or $minute[1] == "5") $p2 = true; else $p2 = false;
 if($minute[1] == "3" or $minute[1] == "7") $p4 = true; else $p4 = false;
 if($minute[1] == "9") $p3 = true; else $p3 = false;
 
 //Interface Heizung öffnen
 VIESSMANN_Open(true);
 //P1-Werte holen, Peaks entfernen und Variablen schreiben
 $power = VIESSMANN_GetData("Brennerleistung");
 $pump = VIESSMANN_GetData("Heizkreispumpe");
 SetValue(15273 /*[Gewerke\Energie\Heizung\Brenner\Brennerleistung]*/,$power);
 SetValue(10024 /*[Gewerke\Energie\Heizung\Anlage\Heizkreispumpe]*/,$pump);
 //P2-Werte holen, Peaks entfernen und Variablen schreiben
 if($p2)
 {
  $boilTemp = VIESSMANN_GetData("Kesseltemperatur");
  $preTemp = VIESSMANN_GetData("Vorlauftemperatur");
  $postTemp = VIESSMANN_GetData("Ruecklauftemperatur");
  $wwTemp = VIESSMANN_GetData("Speichertemperatur");
  if($boilTemp > 90) $boilTemp = GetValue(12340 /*[Gewerke\Energie\Heizung\Anlage\Kesseltemperatur]*/);
  if($preTemp > 90) $preTemp = GetValue(30933 /*[Gewerke\Energie\Heizung\Anlage\Vorlauftemperatur]*/);
  if($postTemp > 90) $postTemp = GetValue(56945 /*[Gewerke\Energie\Heizung\Anlage\Rücklauftemperatur]*/);
  if($wwTemp > 90) $wwTemp = GetValue(31278 /*[Gewerke\Energie\Heizung\Warmwasser\Speichertemperatur]*/);
  SetValue(12340 /*[Gewerke\Energie\Heizung\Anlage\Kesseltemperatur]*/,$boilTemp);
  SetValue(30933 /*[Gewerke\Energie\Heizung\Anlage\Vorlauftemperatur]*/,$preTemp);
  SetValue(56945 /*[Gewerke\Energie\Heizung\Anlage\Rücklauftemperatur]*/,$postTemp);
  SetValue(31278 /*[Gewerke\Energie\Heizung\Warmwasser\Speichertemperatur]*/,$wwTemp);
 }
 
 //P3-Werte holen, Peaks entfernen und Variablen schreiben
 if($p3)
 {
  $setTempComfort = VIESSMANN_GetData("SolltemperaturTag");
  $setTempLower = VIESSMANN_GetData("SolltemperaturNacht");
  $setTempWW = VIESSMANN_GetData("Speichersolltemperatur");
  $error = VIESSMANN_GetData("Stoerung");
  if($setTempComfort < 12 or $setTempLower < 12)
  {
     $setTempComfort = GetValue(18290 /*[Gewerke\Energie\Heizung\Heizung\Raumsolltemperatur]*/);
     $setTempLower = GetValue(45548 /*[Gewerke\Energie\Heizung\Heizung\Raumsolltemperatur Nacht]*/);
     $error = GetValue(13614 /*[Gewerke\Energie\Heizung\Anlage\Betriebszustand]*/);
     $setTempWW = GetValue(17229 /*[Gewerke\Energie\Heizung\Warmwasser\Solltemperatur]*/);
  }
     
  SetValue(18290 /*[Gewerke\Energie\Heizung\Heizung\Raumsolltemperatur]*/,$setTempComfort);
  SetValue(45548 /*[Gewerke\Energie\Heizung\Heizung\Raumsolltemperatur Nacht]*/,$setTempLower);
  SetValue(17229 /*[Gewerke\Energie\Heizung\Warmwasser\Solltemperatur]*/,$setTempWW);
  SetValue(13614 /*[Gewerke\Energie\Heizung\Anlage\Betriebszustand]*/,$error);
 }
 //P4-Werte holen, Peaks entfernen und Variablen schreiben
 if($p4)
 {
  $outTemp = VIESSMANN_GetData("AussentemperaturIst");
  $outIterativeTemp = VIESSMANN_GetData("AussentemperaturIterativ");
  $hrs = VIESSMANN_GetData("Betriebssekunden") / 3600;
  $starts = VIESSMANN_GetData("Brennerstarts");
  $mode = VIESSMANN_GetData("Betriebsart");
  //if($hrs > (GetValue(39605 /*[Gewerke\Energie\Heizung\Anlage\Betriebsstunden]*/) + 20)) $hrs = GetValue(39605 /*[Gewerke\Energie\Heizung\Anlage\Betriebsstunden]*/);
  //if($hrs < (GetValue(39605 /*[Gewerke\Energie\Heizung\Anlage\Betriebsstunden]*/))) $hrs = GetValue(39605 /*[Gewerke\Energie\Heizung\Anlage\Betriebsstunden]*/);
  //if($starts > (GetValue(56512 /*[Gewerke\Energie\Heizung\Brenner\Brennerstarts]*/) + 2000)) $starts = GetValue(56512 /*[Gewerke\Energie\Heizung\Brenner\Brennerstarts]*/);
  //if($starts < (GetValue(56512 /*[Gewerke\Energie\Heizung\Brenner\Brennerstarts]*/))) $starts = GetValue(56512 /*[Gewerke\Energie\Heizung\Brenner\Brennerstarts]*/);
  if($outTemp > 40) $outTemp = GetValue(37190 /*[Gewerke\Energie\Heizung\Heizung\Aussentemperatur Ist]*/);
  if($outIterativeTemp > 40) $outIterativeTemp = GetValue(49318 /*[Gewerke\Energie\Heizung\Heizung\Aussentemperatur]*/);
  SetValue(37190 /*[Gewerke\Energie\Heizung\Heizung\Aussentemperatur Ist]*/,$outTemp);
  SetValue(49318 /*[Gewerke\Energie\Heizung\Heizung\Aussentemperatur]*/,$outIterativeTemp);
  SetValue(39605 /*[Gewerke\Energie\Heizung\Anlage\Betriebsstunden]*/,$hrs);
  SetValue(56512 /*[Gewerke\Energie\Heizung\Brenner\Brennerstarts]*/,$starts);
  SetValue(42076 /*[Gewerke\Energie\Heizung\Betrieb\Betrieb]*/,$mode);
 }
 //Interface Heizung schliessen
 IPS_Sleep(500);
 VIESSMANN_Open(false);
?>

Das Include-File:

<?
 function VIESSMANN_Open($state)
 //Öffnet das serielle Interface zum Viessmann Brennwertkessel
 //$state{bool} = true{öffnen}, false{schliessen}
 {
  //Variablen
  $interfaceID = 21971 /*[Serial Port Viessmann VComm (sxkgn001.kugelmann.net)]*/;
  
  //Interface öffnen, falls noch nicht geöffnet
  if($state and (!COMPort_GetOpen($interfaceID)))
  {
     COMPort_SetOpen($interfaceID,true);
     IPS_ApplyChanges($interfaceID);
  }
  //Interface schliessen, falls noch nicht geschlossen
  elseif(!$state and (COMPort_GetOpen($interfaceID)))
  {
     COMPort_SetOpen($interfaceID,false);
     IPS_ApplyChanges($interfaceID);
  }
 }

 function VIESSMANN_ResultToHex($result)
 //Konvertiert zeichenbasierte Ergebnisdaten in hexadezimales Format
 {
    $resultConvert = "";
  for($x = 0; $x < strlen($result); $x++)
  {
       if(ord($result[$x]) < 16) $resultConvert .= "0";
   $resultConvert .= strtoupper(dechex(ord($result[$x])));
     }
  return $resultConvert;
 }
 
 function VIESSMANN_ConvertData($parameter,$data)
 //Konvertiert Rohdaten in typisierte Daten
 //$parameter{string} = Parameter im Klartext laut _definitionsviessmann.ips.php, $data{string} = Rohdaten, die von Viessmann übergeben wurden
 {
    global $viessmannCommand;
 
  //Datentyp bestimmen
  foreach($viessmannCommand as $row)
  {
     if($row["name"] == $parameter) $format = $row["format"];
  }
  //Parameter existierte?
  if(!isset($format)) return false;
  //Je nach Format werden unterschiedliche Berechnungen durchgeführt
  switch($format)
  {
   //Format Boolean
   case "bool":
    if(isset($data[0]))
    {
     if(ord($data[0]) == 0) return false; else return true;
    }
    else
    {
       return false;
    }
    
        break;
        
   //Format Temperatur / 1
   case "t1":
    if(isset($data[0])) $lo = ord($data[0]); else $lo = 0;
    if(isset($data[1])) $hi = ord($data[1]); else $hi = 0;
    return (($hi * 256) + $lo);
    break;
   //Format Temperatur / 10
   case "t10":
    if(isset($data[0])) $lo = ord($data[0]); else $lo = 0;
    if(isset($data[1])) $hi = ord($data[1]); else $hi = 0;
    return (($hi * 256) + $lo) / 10;
    break;
    
   //Format Temperatur / 10 Negativ
   case "t10n":
    if(isset($data[0])) $lo = ord($data[0]); else $lo = 0;
    if(isset($data[1])) $hi = ord($data[1]); else $hi = 0;
          if($hi == 255)
    {
            return ((65536 - (($hi * 256 ) + $lo)) / 10) * -1;
           }
    else
    {
            return (($hi * 256 ) + $lo) / 10;
          }
          break;
   //Format Temperatur / 100
     case "t100":
    if(isset($data[0])) $lo = ord($data[0]); else $lo = 0;
    if(isset($data[1])) $hi = ord($data[1]); else $hi = 0;
      return (($hi * 256 ) + $lo ) / 100;
      break;
   //Format Zähler
     case "cnt":
    if(!isset($data)) $data = 0;
    
    $count = 0;
      $hexString = VIESSMANN_ResultToHex($data);
      
      //print($hexString."
");
      
          for($x = 0; $x < strlen($hexString); $x = $x + 2)
      {
     $hex = substr($hexString,$x,2);
      $dec = hexdec($hex);
      switch ($x)
      {
      case 0:
         $count = $count + $dec;
         break;
      case 2:
         $count = $count + ($dec * 256);
         break;
      case 4:
         $count = $count + ($dec * 65536);
         break;
      case 6:
         $count = $count + ($dec * 16777216);
         break;
      default:
         break;
        }
    }
    return $count;
    break;
    
   //Format Mode
   case "mode":
    return ord($data[0]);
    break;
   //Format Prozent/Boolean, es wird NUR Prozent zurückgegeben, woraus Boolean aber abgeleitet werden kann (Prozent > 0)
   case "pctbool":
    if(isset($data[0])) $lo = ord($data[0]); else $lo = 0;
    if(isset($data[1])) $hi = ord($data[1]); else $hi = 0;
    if($lo > 100) $lo = 100;
    if($hi) $hi = true; else $hi = false;
      return $lo;
      break;
   //Format Boolean/Prozent, es wird NUR Prozent zurückgegeben, woraus Boolean aber abgeleitet werden kann (Prozent > 0)
   case "boolpct":
    if(isset($data[0])) $lo = ord($data[0]); else $lo = 0;
    if(isset($data[1])) $hi = ord($data[1]); else $hi = 0;
    if($hi > 100) $hi = 100;
    if($lo) $lo = true; else $lo = false;
      return $hi;
      break;
   //Format CommandID
     case "cid":
      $result = "";
    for($x = 0; $x < strlen($data); $x++)
            {
             if(ord($data[$x]) < 16 ) $result .= "0";
              $result .= strtoupper(dechex(ord($data[$x])));
          }
            return $result;
          break;
          
   //Kein bekanntes Format
       default:
    return false;
      break;
  }
 }
 
 function VIESSMANN_GetData($parameter)
 //Holt einen bestimmten Wert und gibt ihn formatiert zurück, benötigt _definitionsviessmann.ips.php
 //$parameter{string} = Parameter im Klartext laut _definitionsviessmann.ips.php
 {
    global $viessmannCommand;
    //Variablen
    $sendID = 34183 /*[System\Viessmann VComm\Senden]*/;
    $recvID = 34549 /*[System\Viessmann VComm\Empfangen]*/;
  // Maximale Überprüfungszeit, bis ein Viessmann-Ping erfolgt (0x05)
  $run = 1;
  //Befehlsdaten holen
  foreach($viessmannCommand as $row)
  {
     if($row["name"] == $parameter)
     {
    $address = $row["address"];
    $length = $row["length"];
   }
  }
  
  //Parameter existiert?
  if(!isset($address) or !isset($length)) return false;
  //Viessmann Kommando aufbereiten, senden und Rückgabewert abwarten
  do
  {
   //Alter Rückgabewert löschen
     SetValueString($recvID,"");
     //Command String erzeugen
   $commandString = "R:KW:".$address.":".$length.": ";
   $startTime = microtime();
   $runTime = 0;
   //Command String in Variable legen
   SetValueString($sendID,$commandString);
     //Auf Ausführung warten
       $status = GetValue($sendID);
   while($status and $runTime < 1)
   {
      $status = GetValue($sendID);
      $runTime = microtime() - $startTime;
   }
   //Ergebnis holen
       $result = GetValue($recvID);
   if($result != chr(0x05)) $run = -1;
   $run--;
  }
  while($run > 0);
  
  //print($result."
");
  return VIESSMANN_ConvertData($parameter,$result);
 }
 function VIESSMANN_SetData($parameter,$data)
 //Schreibt einen bestimmten Wert in einen Parameter, benötigt _definitionsviessmann.ips.php
 //$parameter{string} = Parameter im Klartext laut _definitionsviessmann.ips.php
 {
    global $viessmannCommand;
    //Variablen
    $sendID = 34183 /*[System\Viessmann VComm\Senden]*/;
    $recvID = 34549 /*[System\Viessmann VComm\Empfangen]*/;
  //Befehlsdaten holen
  foreach($viessmannCommand as $row)
  {
     if($row["name"] == $parameter)
     {
    $address = $row["address"];
    $length = $row["length"];
    $type = $row["type"];
   }
  }
  
  //Parameter existiert?
  if(!isset($address) or !isset($length)) return false;
  //Ist der Paramter nicht beschreibbar, abbrechen
  if(!isset($type) or ($type != "RW" and $type != "W")) return false;
  //Alter Rückgabewert löschen
    SetValueString($recvID,"");
  //Command String erzeugen
     $commandString = "W:KW:".$address.":".$length.":".$data;
  //Command String in Variable legen
  SetValueString($sendID,$commandString);
    //Auf Ausführung warten
    $status = GetValueString($sendID);
  while($status)
  {
     $status = GetValueString($sendID);
  }
  //Ergebnis holen
    $result = GetValueString($recvID);
    return $result;
  }
?>

Und schließlich noch das Aktionsscript der RegisterVariable

<?
 include("_definitionsviessmann.ips.php");
 //Variablen
 $viessmannPing = chr(0x05);
 $viessmannReadPrefix = chr(0x01).chr(0xF7);
 $viessmannWritePrefix = chr(0x01).chr(0xF4);
 
 $instanceID = 38308 /*[System\Viessmann VComm]*/;
 $sendID = 34183 /*[System\Viessmann VComm\Senden]*/;
   $recvID = 34549 /*[System\Viessmann VComm\Empfangen]*/;
   $comPortID = 21971 /*[Serial Port Viessmann VComm (sxkgn001.kugelmann.net)]*/;
 $currentAction = "";
 $currentProtocol = "";
 $currentCommand = "";
 $currentLength = "";
 $currentSetValue = "";
 
 //Falls Werte-Variable undefiniert, mit Leerstring füllen
   if (!isset($_IPS["VALUE"])) $_IPS["VALUE"] = "";
   //Aktueller Command auslesen
   $command = GetValueString($sendID);
 //Falls Command vorhanden, dann aufsplitten
 if($command)
   {
    $commandArray = explode(":",$command);
    $parts = count($commandArray);
  if($parts > 0) $currentAction = $commandArray[0];
     if($parts > 1) $currentProtocol = $commandArray[1];
  if($parts > 2) $currentAddress = $commandArray[2];
  if($parts > 3) $currentLength = $commandArray[3];
  if($parts > 4) $currentSetValue = $commandArray[4];
 }
 //Restliche Daten aus dem Buffer holen
   $commandData = RegVar_GetBuffer($instanceID);
 //Übertragene Daten mit Buffer zusammenführen
 $commandData .= $_IPS["VALUE"];
 //Rausnehmen?
 //echo $CurrentAction."-";
 //if ($ComData == VIESSMANN_PING ) echo "Ping"; else echo strlen( $ComData );
 //Wenn Command vorliegt, dann verarbeiten
 if($commandData == $viessmannPing and ($currentAction == "R" or $currentAction == "W"))
 {
  //Command und Länge vorbereiten
  $address = chr(hexdec(substr($currentAddress,0,2)));
  $address .= chr(hexdec(substr($currentAddress,2,2)));
  //Lesen oder Schreiben?
  switch($currentAction)
    {
   //Lesen
       case "R":
    $commandString = $viessmannReadPrefix.$address.chr($currentLength);
    //Command als ausgeführt markieren
    $command[0] = "E";
    break;
    
   //Schreiben
   case "W":
    $commandString = $viessmannWritePrefix.$address.chr($currentLength).$currentSetValue;
    //Command leeren
    $command = "";
    break;
    
   //Standard
   default:
    //Ganze Command Zeichenkette leeren
    $commandString = "";
    break;
  }
  //Falls Command vorliegt
  if($commandString)
  {
   //Command in Variable ablegen
   SetValueString($sendID,$command);
   //Receive Variable leeren
   SetValueString($recvID,"");
   //Command String an Schnittstelle senden
   COMPort_SendText($comPortID,$commandString);
     }
 }
 //Command wurde abgesetzt, Werte werden empfangen
 else
 {
  //Empfangener Wert ist gleich oder länger als benötigt
  if($currentAction == "E" and strlen($commandData) >= $currentLength)
  {
   //Rückgabe extrahieren
   $result = substr($commandData,0,$currentLength);
   //Rückgabe in Variable ablegen
   SetValueString($recvID,$result);
   //Command und verbleibender Buffer leeren
   SetValueString($sendID,"");
   RegVar_SetBuffer($instanceID,"");
  }
  //Empfangener Wert ist ein Restfragment, dann Buffer zurückschreiben
  else
  {
   if($command and $currentAction == "E")
         {
    RegVar_SetBuffer($instanceID,$commandData);
   }
   else
   {
    RegVar_SetBuffer($instanceID,"");
   }
  }
 }
?>

Ach so, und dann gibt es noch dieses Include hier (_definitionsviessmann.ips.php):

<?
 //Viessmann Steuerungstyp VDensHO1
 $viessmannControlType = "20C2";
 //Mögliche Commands
 $viessmannCommand = array();
 array_push($viessmannCommand,array("name" => "Betriebsart", "type" => "RW", "address" => "2323", "length" => 1, "format" => "mode"));
 array_push($viessmannCommand,array("name" => "Betriebssekunden", "type" => "R", "address" => "08A7", "length" => 4, "format" => "cnt"));
 array_push($viessmannCommand,array("name" => "Brennerleistung", "type" => "R", "address" => "A38F", "length" => 2, "format" => "pctbool"));
 array_push($viessmannCommand,array("name" => "Brennerstarts", "type" => "R", "address" => "088A", "length" => 4, "format" => "cnt"));
 array_push($viessmannCommand,array("name" => "Heizkreispumpe", "type" => "R", "address" => "7660", "length" => 2, "format" => "boolpct"));
 array_push($viessmannCommand,array("name" => "Kesseltemperatur", "type" => "R", "address" => "0810", "length" => 2, "format" => "t10"));
 array_push($viessmannCommand,array("name" => "Kesselsolltemperatur", "type" => "R", "address" => "555A", "length" => 2, "format" => "t10"));
 array_push($viessmannCommand,array("name" => "Vorlauftemperatur", "type" => "R", "address" => "2900", "length" => 2, "format" => "t10"));
 array_push($viessmannCommand,array("name" => "Ruecklauftemperatur", "type" => "R", "address" => "0808", "length" => 2, "format" => "t10"));
 array_push($viessmannCommand,array("name" => "SolltemperaturTag", "type" => "RW", "address" => "2306", "length" => 1, "format" => "t1"));
 array_push($viessmannCommand,array("name" => "SolltemperaturNacht", "type" => "RW", "address" => "2307", "length" => 1, "format" => "t1"));
 array_push($viessmannCommand,array("name" => "Speichertemperatur", "type" => "R", "address" => "0812", "length" => 2, "format" => "t10"));
 array_push($viessmannCommand,array("name" => "Speichersolltemperatur", "type" => "RW", "address" => "6300", "length" => 2, "format" => "t1"));
 array_push($viessmannCommand,array("name" => "AussentemperaturIst", "type" => "R", "address" => "5525", "length" => 2, "format" => "t10"));
 array_push($viessmannCommand,array("name" => "AussentemperaturIterativ", "type" => "R", "address" => "5527", "length" => 2, "format" => "t10"));
 array_push($viessmannCommand,array("name" => "Stoerung", "type" => "R", "address" => "0A82", "length" => 1, "format" => "bool"));
 //Beispiele für schreibende Commands
 //VIESSMANN_SetData("Betriebsart",chr(0)); //Schaltet Betriebsart auf Aus
 //VIESSMANN_SetData("Betriebsart",chr(1)); //Schaltet Betriebsart auf Nur Warmwasser
 //VIESSMANN_SetData("Betriebsart",chr(2)); //Schaltet Betriebsart auf Heizung und Warmwasser
  //VIESSMANN_SetData("SolltemperaturTag",chr(22)); //Stellt die Komfort-Solltemperatur auf 22 Grad
  //VIESSMANN_SetData("SolltemperaturNacht",chr(18)); //Stellt die Absenk-Solltemperatur auf 18 Grad
 //VIESSMANN_SetData("Speichersolltemperatur",chr(45).chr(0))); //Stellt die Warmwasser-Solltemperatur auf 45 Grad. Das zweite Byte muss immer 0 sein
 
 //Beispiele für lesende Commands
 //$a = VIESSMANN_GetData("Speichertemperatur"); //Aktuelle Warmwassertemperatur in Grad
 //$a = VIESSMANN_GetData("Heizkreispumpe"); //Status der Pumpe in Prozent
 //$a = VIESSMANN_GetData("Brennerleistung"); //Status des Brenners in Prozent
 //$a = VIESSMANN_GetData("Betriebsart"); //Betriebsart, 0 = Aus, 1 = Warmwasser, 2 = Heizung und Warmwasser
 
 //Port öffnen und schließen
 //VIESSMANN_Open(true);
 //VIESSMANN_Open(false);
?>

Viel Zeug, bei Fragen bitte Bescheid sagen :wink: