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