Im Grunde ist der Code identisch mit dem hier veröffentlichten.
Hier das Script „Config_Highcharts_V1.0004“:
<?php
// => ab V1.0004, damit kann der Script auch von anderen Scripten aufgerufen werden und bereits mit CfgDaten vorkonfiguriert werden
Global $CfgDaten; //$CfgDaten = array();
// Überschriften
$CfgDaten["Title"]= "Photothermie-Anlage";
$CfgDaten["SubTitle"]= ""; // "" = Automatisch über Zeitraum
// IPS Variablen ID´s
$CfgDaten["ArchiveHandlerId"]= 55645 /*[Objekt #55645 existiert nicht]*/; // Archive Handler
$CfgDaten["ContentVarableId"]= 27425 /*[Scripte\Highcharts_V1.0004\Highcharts_V1.0004]*/; // ID der Content-Variable
$CfgDaten["HighChartScriptId"]= 32230 /*[Scripte\Highcharts_V1.0004\Highcharts_V1.0004]*/; // ID des Highcharts Scripts
// Zeitraum welcher dargestellt werden soll
$CfgDaten["StartTime"] = mktime(0,0,0, date("m", time()), date("d",time())-6, date("Y",time())); // ab heute 00:00 Uhr
$CfgDaten["EndTime"] = mktime(23,59,59, date("m", time()), date("d",time()), date("Y",time())); // ab heute 23:59 Uhr, oder //$CfgDaten["EndTime"] = time(); // = bis jetzt
// => ab V1.0003
$CfgDaten["RunMode"]= "files"; //oder script
// => ab V1.0003
// Serienübergreifende Einstellung für das Laden von Werten
$CfgDaten["AggregatedValues"]["HourValues"] = 3; // ist der Zeitraum größer als X Tage werden Stundenwerte geladen
$CfgDaten["AggregatedValues"]["DayValues"] = 14; // ist der Zeitraum größer als X Tage werden Tageswerte geladen
$CfgDaten["AggregatedValues"]["NoLoggedValues"] = 60; // ist der Zeitraum größer als X Tage werden keine Boolean Werte mehr geladen, diese werden zuvor immer als Einzelwerte geladen
$CfgDaten["AggregatedValues"]["MixedMode"] = false; // alle Zeitraumbedingungen werden kombiniert
// Die Parameter für die einzelnen Chart Serien (Achtung! unbedingt auf Groß-Kleinschreibung achten)
// Name: Name der Kurve (Anzeige in Legende und Tooltip)
// Unit: NULL = Einheit wird aus Suffix des eingestellten Profils übernommen
// "string" = string wird als Einheit eingetragen
// array(0=>'String für 0',1=>'String für 1', usw.) = Ist der Wert 0 wird 'Strung für 0' im Tooltip angezeigt, usw
// ReplaceValues: false = Werte werden wie geloggt übernommen
// array(0=>0.2,1=>10, usw.) = der Wert 0 wird in 0.2 geändert, der Wert 1 wird in 10 geändert
// das macht für die Darstellung von Boolean Werte Sinn, oder für Drehgriffkontakte (Werte 0,1,2) Sinn
// Param: Einstellungen der Kurve (hier können werden exakt Einstellungen aus Higcharts.com eingegeben) hier ein paar Beispiele
// type: Art der Kurve: Sinn machen [area, areaspline, line, spline, pie], noch nicht sinnvoll dargestellt werden [scatter, bar, column]
// step: true oder false - jeder Werte bildet eine Stufe (sinnvoll für Heizungsteller, oder Sollwertvorgaben)
// yAxis: Nummer welche Y-Achse verwendet werden soll (ab 0)
// shadow: true oder false - Darstellung mit oder ohne Schatten
// lineWidth: Linienstärke
// alles weitere bitte aus der Higcharts-Referenz entnehmen -> http://www.highcharts.com/ref/
// und so könnte für eine Achse seperate Einstellungen für die AggregattedValues getroffen werden
//$AggregatedValuesForSeries["HourValues"] = 3;
//$AggregatedValuesForSeries["DayValues"] = 2;
//$AggregatedValuesForSeries["DayValues"] = 2;
//$AggregatedValuesForSeries["Combined"] = true;
//,"AggregatedValues"=>$AggregatedValuesForSeries
// => ab V1.0004, sind auch Pie-Charts möglich. Hierbei wird je Pie eine Serie definiert (Wichtig hierbei -> ID´s, Namen, Units als Array definieren)
// $CfgDaten["Series"][] = array( "Value"=>array(12,256,24.5,122), "Name" =>array("Wert1","Wert2", "Wert3", "Wert4"), "Unit"=>array("A","A","A","A"), "ReplaceValues"=>false,
// "Param" =>"type:'pie', center: [100, 80], size: 200, showInLegend: true, shadow: true,lineWidth: 1 , dataLabels: {enabled: false}");
$CfgDaten["Series"][] = array("Id"=>array(18866 /*[Scripte\Resol\untere Speichertemperatur in °C]*/,29563,58780 /*[Scripte\Resol\Kollektortemperatur in °C]*/), "Name" =>array("Kollektortemp.","Einstrahlung", "untere Speichertemp."), "Unit"=>array("°C","%","°F"), "ReplaceValues"=>false,
"Param" =>"type:'pie', center: [300, 180], size: 100, showInLegend: true, shadow: true,lineWidth: 1 , dataLabels: {enabled: false}");
$CfgDaten["Series"][] = array("Id"=>12431, "Name" =>"Kollektortemp.", "Unit"=>"°C", "ReplaceValues"=>false,
"Param" =>"type:'spline', step:false, yAxis: 1,showInLegend: true,shadow: true,lineWidth: 1 , states: {hover:{lineWidth: 2}}, marker: { enabled: false, states: { hover: { enabled: true, radius: 4}}}");
$CfgDaten["Series"][] = array("Id"=>12431, "Name" =>"Einstrahlung","Unit"=>NULL, "ReplaceValues"=>false,
"Param" =>"type:'spline', step:false, yAxis: 0, shadow: true,lineWidth: 1, states: {hover:{lineWidth: 2}}, marker: { enabled: false, states: { hover: { enabled: true, radius: 4}}}");
$CfgDaten["Series"][] = array("Id"=>12431, "Name" =>"untere Speichertemp.", "Unit"=>"°C","ReplaceValues"=>false,
"Param" =>"type:'line', step:true, yAxis: 0, shadow: true,lineWidth: 1, states: {hover:{lineWidth: 2}}, marker: { enabled: false, states: { hover: { enabled: true, radius: 4}}}");
$CfgDaten["Series"][] = array("Id"=>12431, "Name" =>"obere Speichertemp.","Unit"=>"%", "ReplaceValues"=>false,
"Param" =>"type:'spline', step:false, yAxis: 1, shadow: true,lineWidth: 1, states: {hover:{lineWidth: 2}}, marker: { enabled: false, states: { hover: { enabled: true, radius: 4}}}");
$CfgDaten["Series"][] = array("Id"=>12431, "Name" =>"Vorlauftemp.","Unit"=>NULL, "ReplaceValues"=>array(0=>0.2,1=>10),
"Param" =>"type:'area', step: true, yAxis: 1, shadow: true,lineWidth: 1, states: {hover:{lineWidth: 2}}, marker: { enabled: false, states: { hover: { enabled: true, symbol: 'circle', radius: 4, lineWidth: 1}}}");
$CfgDaten["Series"][] = array("Id"=>12431, "Name" =>"Drehgriffkontakt", "Unit"=>array(0=>'geschlossen',1=>'gekippt',2=>'geöffnet'), "ReplaceValues"=>array(0=>0.2,1=>7,2=>10),
"Param" =>"type:'area', step:true, yAxis: 1, shadow: true,lineWidth: 1, states: {hover:{lineWidth: 2}}, marker: { enabled: false, states: { hover: { enabled: true, radius: 4}}}");
$CfgDaten["Series"][] = array("Id"=>12431, "Name" =>"Heizungssteller", "Unit"=>"%","ReplaceValues"=>false,
"Param" =>"type:'line', step:true, yAxis: 1, shadow: true,lineWidth: 1, states: {hover:{lineWidth: 2}}, marker: { enabled: false, states: { hover: { enabled: true, radius: 4}}}");
/*
//oder
foreach(IPS_GetInstanceListByModuleID("{EE4A81C6-5C90-4DB7-AD2F-F6BBD521412E}") as $InstanceId)
{
if(IPS_StatusVariableExists($InstanceId, "TEMPERATURE"))
{
$var = IPS_GetStatusVariable($InstanceId, "TEMPERATURE");
// Float Variable (.... ist schon etwas wage sich auf den VariablenTyp zu verlassen)
if($var['VariableType'] == 2 )
{
//$V = GetVariableArray($InstanceId, "TEMPERATURE");
$Name = str_replace("Funk Devices\\", "", IPS_GetLocation($var["VariableID"]));
$Name = str_replace("\\", "/", $Name );
$CfgDaten["Series"][] = array("Id"=>$var["VariableID"], "Name" =>$Name, "Unit"=>"°C", "ReplaceValues"=>false,
"Param" =>"type:'spline', step:false, yAxis: 0, shadow: true,lineWidth: 1 , states: {hover:{lineWidth: 2}}, marker: { enabled: false, states: { hover: { enabled: true, radius: 4}}}");
}
}
}
*/
// Y-Achsen
$CfgDaten["yAxis"][] = array("Name" =>"Temperaturen", "Unit"=>"°C","Opposite"=>false,"TickInterval"=>5);
$CfgDaten["yAxis"][] = array("Name" =>"Heizungssteller / Luftfeuchte", "Unit"=>"%","Min"=>0, "Max"=>100,"TickInterval"=>25,"Opposite"=>true);
//oder direkt den String für die Achsen übergeben $CfgDaten["yAxis"][] = "title: { text: 'Heizungssteller / Luftfeuchte' }, min:0";
// X-Achse ist autom. Time-Format
// => ab V1.0002
// HighchartConfig String
$CfgDaten["HighChartCfg"]= false; // false = default String wird verwendet
// Beispiel für ein von extern übergebener CfgString. Dies entspricht exakt dem Highcrats ConfigString aus der Highcharts.com/ref
// zusätzlich können bzw. teilweise müssen folgenden Platzhalter verwendet werden.
// %title.text% = $CfgDaten["Title"]
// %subtitle.text% = CfgDaten["SubTitle"], oder bei "" der automatisch erzeugte Zeitraum
// %yAxis% = die genierten y-Achsen welche durch $CfgDaten["yAxis"] konfiguriert wurden
// %tooltip% = der generiert Tooltip
// %xAxis.min% und %xAxis.may% = der durch $CfgDaten["StartTime"] und $CfgDaten["EndTime"] festgelegte Zeitraum
// %data% = die aus der Datenbank gelesenen Daten, ohne diesen Platzhalter läuft gar nichts
/* $CfgDaten["HighChartCfg"]="
chart: {
renderTo: 'container'
},
title: {
text: '%title.text%',
x: -20
},
subtitle: {
text: '%subtitle.text%',
x: -20
},
xAxis: [{
type: 'datetime',
dateTimeLabelFormats: { second: '%H:%M:%S',
minute: '%H:%M',
hour: '%H:%M',
day: '%e. %b',
week: '%e. %b',
month: '%b \'%y',
year: '%Y'
}
}],
yAxis: [ %yAxis% ],
tooltip: { %tooltip% },
series: [ %data% ]
});";
*/
// Alle $CfgDaten["HighChart"] Parameter werden an das IP_Template übergeben
// Highcharts-Themes
// $CfgDaten["HighChart"]["Theme"]="gray.js"; // von Highcharts mitgeliefert: dark-green.js, dark-blue.js, gray.js, grid.js
$CfgDaten["HighChart"]["Theme"]="ips.js"; // von Highcharts mitgeliefert: dark-green.js, dark-blue.js, gray.js, grid.js
// Abmessungen des erzeugten Charts
$CfgDaten["HighChart"]["Width"] = 0; // in px, 0 = 100%
$CfgDaten["HighChart"]["Height"] = 600; // in px
// und jetzt los ......
$s=IPS_GetScript($CfgDaten["HighChartScriptId"]); // Id des Highcharts-Scripts
include($s['ScriptFile']);
// => ab V1.0003
// hier werden die CfgDaten geprüft und bei Bedarf vervollständigt
$CfgDaten = CheckCfgDaten($CfgDaten);
// => ab V1.0003
if (isset($CfgDaten["RunMode"]) && $CfgDaten["RunMode"] == "script")
{
// Variante1: Übergabe der ScriptId. Daten werden beim Aufruf der PHP Seite erzeugt und direakt übergeben. Dadurch kann eine autom. Aktualisierung der Anzeige erfolgen
if ($IPS_SENDER != "WebInterface")
{
WriteContentWithScriptId ($CfgDaten, $IPS_SELF); // und jetzt noch die ContentTextbox
return; // Ende, weil durch die Zuweisung des Script sowieso nochmals aufgerufen wird
}
$sConfig = CreateConfigString($CfgDaten); // erzeugen und zurückgeben des Config Strings
}
else
{
//Variante2: Übergabe des Textfiles. Daten werden in tmp-File gespeichert. Eine automatische Aktualisierung beim Anzigen der Content-Textbox erfolgt nicht
$sConfig = CreateConfigString($CfgDaten); // erzeugen und zurückgeben des Config Strings
$tmpFilename = CreateConfigFile($sConfig, $IPS_SELF); // und ab damit ins tmp-Files
if ($IPS_SENDER != "WebInterface")
{
WriteContentWithFilename ($CfgDaten, $tmpFilename); // und jetzt noch die ContentTextbox
}
}
?>
Und dann noch das Script „Highcharts_V1.0004“:
<?
//--------------------------------------------------------------------------------------------------------------------------------
// Für die Darstellung der Graphen wird das HTML5/JS Framework "Highcharts" der Fa. Highslide Software verwendet (www.highcharts.com)
// Alle Rechte dieses Frameworks liegen bei Highslide Software
// 'Highcharts' kann unter folgenden Bedinungen kostenlos eingesetzt werden:
// Namensnennung — Sie müssen den Namen des Autors/Rechteinhabers in der von ihm festgelegten Weise nennen.
// Keine kommerzielle Nutzung — Dieses Werk bzw. dieser Inhalt darf nicht für kommerzielle Zwecke verwendet werden.
// Download unter wwww.highcharts.com/download und die Dateien einfach in das Webfront
// Demos siehe http://www.highcharts.com/demo/
//--------------------------------------------------------------------------------------------------------------------------------
// Changelog: V1.0001
// 30.05.2011 KHC FIX Keine Darstellung im Firefox (embed -> iframe) und frameborder = 0 für Darstellung per iFrame
// 30.05.2011 KHC NEU Über Unit=NULL im Serien-Parmeter kann definiert werden, dass das VariableProfile von IPS als Tooltip verwendet wird
// 30.05.2011 KHC NEU CfgDaten: Width und Height werden in px eingegeben und nicht mehr als String, bei width = 0 für 100% möglich
// Changelog: V1.0002
// 30.05.2001 KHC FIX Wenn keine Series definiert sind - Fehler abgefangen (brauche ich noch später....)
// 31.05.2011 KHC NEU Möglichkeit der Übergabe des vollständigen HighchartConfigStrings (bei keiner Übergabe wird der aktuelle als Defaul genommen)
// 31.05.2011 KHC NEU "IPS_Template.php" - Format auf Deutsch (Tage, Monate)
// 31.05.2011 KHC NEU Im Tooltip wird jetzt zusätzlich der Wochentag angezeigt
// 03.06.2011 KHC NEU Möglichkeit dass beim Anzeigen der Textbox der Inhalt automatisch aktualisiert wird (siehe Bsp.) in Config Script
// 03.06.2011 KHC NEU und dadurch 2 Möglichkeiten der Nutzung: 1. über Textfile, 2. über ScriptId.
// Changelog: V1.0003
// 04.06.2011 KHC NEU RunMode [Script oder File] über Parameter in CfgDaten einstellbar
// 05.06.2011 KHC NEU CheckCfgDaten: Prüfen bestimmter notwendiger Parameter im CfgDaten und Korrektur
// 06.06.2011 KHC NEU Einstellung per Config wann Werte als Stunden bzw. Tageswerte herangezogen werden (AggregatedValues).
// 08.06.2011 KHC NEU AggregatedValues Einstellungen auch pro Serie möglich
// 08.06.2011 KHC NEU AggregatedValues.MixedMode zum Kombinieren der Einstellungen (z.B.: x Tage alle Werte und danach x Tage nur Stunden Werte, usw.)
// 08.06.2011 KHC FIX IPS_Template.php: Umlaut im 'März' wurde nicht richtig angezeigt
// 08.06.2011 KHC FIX Deutsche Tage im Zeitraum
// 08.06.2011 KHC NEU AggregatedValues.NoLoggedValues liest jetzt Werte bis zu diesem Zeitpunkt (zuvor wurden wenn der Zeitraum größer war gar keine Werte gelesen)
// Changelog: V1.0004
// 11.06.2011 KHC FIX MixedMode. Wenn Zeitraum durch Berechnung kleiner als Startwert war, wurden diese Werte ebenfalls geladen
// 22.06.2011 KHC NEU CfgDaten: Wenn "ContentVarableId" = -1 und der Script unter der Content Variable angeordnet wird wird die ContentID selbständig ermittelt.
// 06.07.2011 KHC NEU Integration Pie-Charts (Übergabe der Werte über IdArray dann wird der akt. Value verwendet, oder übergabe der Werte über Value-Array
//--------------------------------------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------
// WriteContentWithFilename
// Mit dieser Funktion wird der Content-String geschrieben.
// IN: $CfgDaten = ..
// IN: $tmpFilename = Der Dateiname welche die Config Daten enthält
// OUT: der erzeugte Config String
// ------------------------------------------------------------------------
function WriteContentWithFilename($CfgDaten, $tmpFilename)
{
// damit das Ding auch sauber dargestellt wird
$Height = $CfgDaten["HighChart"]["Height"] + 16;
if ($tmpFilename != "")
SetValue($CfgDaten["ContentVarableId"], '<iframe src="./User/Highcharts/IPS_Template.php?CfgFile='. $tmpFilename.'" width="100%" height="'. $Height .'" frameborder="0" scrolling="no"></iframe>');
else
SetValue($CfgDaten["ContentVarableId"], 'Falsche Parameter beim Funktionsaufruf "WriteContentTextbox"');
}
// ------------------------------------------------------------------------
// WriteContentWithScriptId
// Mit dieser Funktion wird der Content-String geschrieben.
// IN: $CfgDaten = ..
// IN: $scriptId = Die Script Id welche den ConfigString enthält.
// OUT: der erzeugte Config String
// ------------------------------------------------------------------------
function WriteContentWithScriptId($CfgDaten, $scriptId)
{
// damit das Ding auch sauber dargestellt wird
$Height = $CfgDaten["HighChart"]["Height"] + 16;
// => ab V1.0004, wenn ... dann wird versucht die Content Variable selbst zu ermitteln
if (!isset($CfgDaten["ContentVarableId"]) || $CfgDaten["ContentVarableId"] <= 0)
{
$ContentVariableId = IPS_GetParent($scriptId);
if (IPS_VariableExists($ContentVariableId))
$CfgDaten["ContentVarableId"] = $ContentVariableId;
else
echo "Script sollte unter der Content Variable angeordnet oder in CfgDaten definiert werden"; // das sollte nie passieren
}
if ($scriptId >= 0)
SetValue($CfgDaten["ContentVarableId"], '<iframe src="./User/Highcharts/IPS_Template.php?ScriptId='. $scriptId.'" width="100%" height="'. $Height .'" frameborder="0" scrolling="no"></iframe>');
else
SetValue($CfgDaten["ContentVarableId"], 'Falsche Parameter beim Funktionsaufruf "WriteContentTextbox"');
}
/* => obsolete ab V 1.0002
function WriteContentTextbox($CfgDaten, $tmpFilename = "", $scriptId = -1)
{
// damit das Ding auch sauber dargestellt wird
$Height = $CfgDaten["HighChart"]["Height"] + 16;
SetValue($CfgDaten["ContentVarableId"], '<iframe src="./User/Highcharts/IPS_Template.php?CfgFile='. $tmpFilename . '&ScriptId=$scriptId" width="100%" height="'. $Height .'" frameborder="0" scrolling="no"></iframe>');
}
*/
// ------------------------------------------------------------------------
// CreateConfigFile
// Erzeugt das tmp-Higcharts Config-File
// IN: $stringForCfgFile = String welcher in das File geschrieben wird
// ------------------------------------------------------------------------
function CreateConfigFile($stringForCfgFile, $id)
{
// Standarddateiname .....
$tmpFilename = IPS_GetKernelDir() . "webfront\user\Highcharts\HighChartsCfg$id.tmp"; // für jede ScriptID wird eine eigene Tmp-Datei erzeugt
// schreiben der Config Daten
$handle = fopen($tmpFilename,"w");
fwrite($handle, $stringForCfgFile);
fclose($handle);
return $tmpFilename;
}
// ------------------------------------------------------------------------
// CheckCfgDaten
// Prüft bestimmte Parameter der $CfgDaten
// IN: $CfgDaten = ..
// OUT: korrigierte CfgDaten
// ------------------------------------------------------------------------
function CheckCfgDaten($CfgDaten)
{
// HighChart
if (!isset($CfgDaten["HighChart"]))
$CfgDaten["HighChart"]["Theme"]="";
if (!isset($CfgDaten["HighChart"]["Theme"]))
$CfgDaten["HighChart"]["Theme"] = "";
if (!isset($CfgDaten["HighChart"]["Width"]))
$CfgDaten["HighChart"]["Width"] = 0;
if (!isset($CfgDaten["HighChart"]["Height"]))
$CfgDaten["HighChart"]["Height"] = 400;
// AggregatedValues
if (!isset($CfgDaten["AggregatedValues"]))
$CfgDaten["AggregatedValues"]["MixedMode"] = false;
if (!isset($CfgDaten["AggregatedValues"]["MixedMode"]))
$CfgDaten["AggregatedValues"]["MixedMode"] = false;
if (!isset($CfgDaten["AggregatedValues"]["HourValues"]))
$CfgDaten["AggregatedValues"]["HourValues"] = 7;
if (!isset($CfgDaten["AggregatedValues"]["DayValues"]))
$CfgDaten["AggregatedValues"]["DayValues"] = 30;
if (!isset($CfgDaten["AggregatedValues"]["NoLoggedValues"]))
$CfgDaten["AggregatedValues"]["NoLoggedValues"] = 90;
// Series
if (!isset($CfgDaten["Series"]))
$CfgDaten["Series"] = array();
// Series.AggregatedValues
$Count = count($CfgDaten["Series"]);
for ($i = 0; $i < $Count; $i++)
{
$Serie = $CfgDaten["Series"][$i];
// prüfen ob für die Serie Einstellungen für AggregatedValues vorhanden ist
if (isset($Serie["AggregatedValues"]))
{
if (!isset($Serie["AggregatedValues"]["MixedMode"]))
$CfgDaten["Series"][$i]["AggregatedValues"]["MixedMode"] = $CfgDaten["AggregatedValues"]["MixedMode"];
if (!isset($Serie["AggregatedValues"]["HourValues"]))
$CfgDaten["Series"][$i]["AggregatedValues"]["HourValues"] = $CfgDaten["AggregatedValues"]["HourValues"];
if (!isset($Serie["AggregatedValues"]["DayValues"]))
$CfgDaten["Series"][$i]["AggregatedValues"]["DayValues"] = $CfgDaten["AggregatedValues"]["DayValues"];
if (!isset($Serie["AggregatedValues"]["NoLoggedValues"]))
$CfgDaten["Series"][$i]["AggregatedValues"]["NoLoggedValues"] = $CfgDaten["AggregatedValues"]["NoLoggedValues"];
}
else // nein -> Daten übernehmen
$CfgDaten["Series"][$i]["AggregatedValues"] = $CfgDaten["AggregatedValues"];
// diverse Prüfungen bei PIE-Charts
if (strrpos($Serie["Param"],'pie') > 0)
{
// falls nicht als Array definiert -> erzeuge Array
if (!isset($Serie["Id"]))
$CfgDaten["Series"][$i]["Id"]=array();
else if (!is_array($Serie["Id"]))
$CfgDaten["Series"][$i]["Id"] = array($Serie["Id"]);
if (!isset($Serie["Name"]))
$CfgDaten["Series"][$i]["Name"]=array();
else if (!is_array($Serie["Name"]))
$CfgDaten["Series"][$i]["Name"] = array($Serie["Name"]);
if (!isset($Serie["Unit"]))
$CfgDaten["Series"][$i]["Unit"]=array();
else if (!is_array($Serie["Unit"]))
$CfgDaten["Series"][$i]["Unit"] = array($Serie["Unit"]);
if (!isset($Serie["Value"]))
$CfgDaten["Series"][$i]["Value"]=array();
else if (!is_array($Serie["Value"]))
$CfgDaten["Series"][$i]["Value"] = array($Serie["Value"]);
if (count($CfgDaten["Series"][$i]["Value"]) == 0)
{
foreach ($CfgDaten["Series"][$i]["Id"] as $Id)
{
$CfgDaten["Series"][$i]["Value"][] =GetValue($Id);
}
}
//$CountOfId = count($CfgDaten["Series"][$i]["Id"]);
$CountOfName = count($CfgDaten["Series"][$i]["Name"]);
$CountOfUnit = count($CfgDaten["Series"][$i]["Unit"]);
$CountOfValue = count($CfgDaten["Series"][$i]["Value"]);
//if ($CountOfId != $CountOfName)
// die("CountOfId != CountOfName");
if ($CountOfName != $CountOfUnit)
die("CountOfName != CountOfUnit");
if ($CountOfUnit != $CountOfValue)
die("CountOfUnit != CountOfValue");
}
}
return $CfgDaten;
}
// ------------------------------------------------------------------------
// CreateConfigString
// Erzeugt den für Higcharts benötigten Config String und gibt diesen als String zurück
// IN: $CfgDaten = ..
// OUT: der erzeugte Config String
// ------------------------------------------------------------------------
function CreateConfigString($CfgDaten)
{
// Subtitle aus Zeitraum
if ($CfgDaten["SubTitle"]=="")
$CfgDaten["SubTitle"] = date("(D) d.m.Y H:i",$CfgDaten["StartTime"]) ." - ". date("(D) d.m.Y H:i",$CfgDaten["EndTime"]);
$CfgDaten["SubTitle"] = ReplaceToGermanDate($CfgDaten["SubTitle"]);
// Breite und Höhe anpassen
if ($CfgDaten["HighChart"]["Width"] == 0)
$CfgDaten["HighChart"]["Width"] ="100%";
else
$CfgDaten["HighChart"]["Width"] .="px";
$CfgDaten["HighChart"]["Height"] .="px";
// Tooltip Formater
$TooltipString = CreateTooltipString($CfgDaten);
// Y-Achsen
$yAxisString = CreateYAxis($CfgDaten);
// Alle Daten aus DB lesen
$Data ="";
foreach ($CfgDaten["Series"] as $Serie )
{
if (strrpos($Serie["Param"],'pie') > 0) //JS-Parameter für Serie
$Data .= ReadPieDataAndCreateDataString($CfgDaten, $Serie);
else
$Data .= ReadDataFromDBAndCreateDataString($CfgDaten, $Serie);
}
$Data = trim($Data,',');
// kein Cfg String konfiguriert -> nimm den Eigenen
If (isset($CfgDaten["HighChartCfg"]) && $CfgDaten["HighChartCfg"] != false)
$StringForCfgFile = $CfgDaten["HighChartCfg"];
else
$StringForCfgFile = GetDefaultStringForCfgFile();
// ersetzen der Platzhalter
$StringForCfgFile = str_replace("%title.text%", $CfgDaten["Title"], $StringForCfgFile);
$StringForCfgFile = str_replace("%subtitle.text%", $CfgDaten["SubTitle"], $StringForCfgFile);
$StringForCfgFile = str_replace("%data%", $Data, $StringForCfgFile);
$StringForCfgFile = str_replace("%tooltip%", $TooltipString, $StringForCfgFile);
$StringForCfgFile = str_replace("%yAxis%", $yAxisString, $StringForCfgFile);
$StringForCfgFile = str_replace("%xAxis.min%", CreateDateUTC($CfgDaten["StartTime"] - 5*60) , $StringForCfgFile);
$StringForCfgFile = str_replace("%xAxis.max%", CreateDateUTC($CfgDaten["EndTime"] + 5*60), $StringForCfgFile);
// zusätzliche Daten für File (hat jetzt aber nichts mit den eigentlichen Highchart Config String zu tun
// z.B.: Breite und Höhe für Container
$AdditionalConfigData = trim(print_r($CfgDaten["HighChart"], true), "Array
()") ;
// Zusätzliche Config in Highchart Config hinzufügren
$StringForCfgFile = $AdditionalConfigData . "
|||
" . $StringForCfgFile;
return $StringForCfgFile;
}
// => ab V1.0004
// ------------------------------------------------------------------------
// ReadPieDataAndCreateDataString
// Liest die aktuellen Werte aus den übergebenen Variablen und erzeugt die Daten für das PIE
// IN: $CfgDaten, $Serie
// OUT: der Data String
// ------------------------------------------------------------------------
function ReadPieDataAndCreateDataString($CfgDaten, $Serie)
{
// Pie Charts müssen immer als Array definiert werden
if (!is_array($Serie["Id"])) // isset($Serie["Id"]) &&
return "";
$Data ="";
$Param = $Serie["Param"];
$CountOfSerie = count($Serie["Value"]);
for ($i=0; $i<$CountOfSerie; $i++)
{
// $VariableId = $Serie["Id"][$i];
// $CurrentValue = GetValue($VariableId);
$CurrentValue = $Serie["Value"][$i];
$Name = $Serie["Name"][$i];
$Data .= "['".$Name."',$CurrentValue],";
}
$Data = trim ($Data , ',');
$ResultString = "{name: 'pie', $Param, data: [$Data]},";
return $ResultString;
}
// ------------------------------------------------------------------------
// ReadDataFromDBAndCreateDataString
// Liest die Series-Daten aus der DB und schreibt sie in den DataString
// IN: $CfgDaten, $Serie
// OUT: der Data String
// ------------------------------------------------------------------------
function ReadDataFromDBAndCreateDataString($CfgDaten, $Serie)
{
// errechne die Zeitspanne
$Diff = $CfgDaten["EndTime"] - $CfgDaten["StartTime"];
if ($CfgDaten["EndTime"] > time())
$Diff = time() - $CfgDaten["StartTime"];
// Umrechnen der Tage in Sekunden ... für direktes addieren zum Timestamp
$HourValues = $Serie["AggregatedValues"]["HourValues"] * 24*60*60; // ab x Tagen werden Stundenwerte ausgelesen
$DayValues = $Serie["AggregatedValues"]["DayValues"] * 24*60*60; // ab x Tagen werden Tageswerte ausgelesen
$DoNotReadLoggedValues = $Serie["AggregatedValues"]["NoLoggedValues"] * 24*60*60; // ab x Tagen werden keine geloggten Werte mehr ausgelesen
$MixedMode = $Serie["AggregatedValues"]["MixedMode"];
$Id_AH = $CfgDaten["ArchiveHandlerId"];
$LoggedData = false;
$Data ="";
$VariableId = (int)$Serie["Id"];
$ValueKey ="Value";
// wenn ReplaceValues definiert wurden werden nur geloggte und keine Aggregated Werte gelesen
if ($Serie["ReplaceValues"] != false)
{
$t1 = $CfgDaten["EndTime"];
$t2 = $CfgDaten["StartTime"];
if ($Diff > $DoNotReadLoggedValues)
{
$t2 = $CfgDaten["EndTime"] - $DoNotReadLoggedValues;
}
// Alle Werte
$LoggedData = @AC_GetLoggedValues($Id_AH, $VariableId, $t2, $t1, 0);
$ValueKey ="Value";
}
else if ($MixedMode) // im MixedMode werden anfangs alle Werte, dann die Stunden- und zuletzt Tageswerte ausgelesen
{
$t1 = $CfgDaten["EndTime"];
$t2 = $CfgDaten["EndTime"] - $Serie["AggregatedValues"]["HourValues"] * 24*60*60;
$t3 = $CfgDaten["EndTime"] - $Serie["AggregatedValues"]["DayValues"] * 24*60*60;
$t4 = $CfgDaten["StartTime"];
if ($t3<$CfgDaten["StartTime"])
{
$t3 = $CfgDaten["StartTime"];
$t4 = false;
}
if ($t2<$CfgDaten["StartTime"])
{
$t2 = $CfgDaten["StartTime"];
$t3 = false;
$t4 = false;
}
// zuerst alle Werte
$LoggedData = @AC_GetLoggedValues($Id_AH, $VariableId, $t2, $t1, 0);
// danach die Stundenwerte
if ($t2 != false && $t3 != false)
{
$TempData = @AC_GetAggregatedValues($Id_AH, $VariableId, 0, $t3, $t2, 0);
foreach ($TempData as $AggValue)
{
$AggValue["Value"] = $AggValue["Avg"];
$LoggedData[] = $AggValue;
}
unset ($TempData);
}
// und zuletzt Tageswerte
if ($t3 != false && $t4 != false)
{
$TempData = @AC_GetAggregatedValues($Id_AH, $VariableId, 1, $t4, $t3, 0);
foreach ($TempData as $AggValue)
{
$AggValue["Value"] = $AggValue["Avg"];
$LoggedData[] = $AggValue;
}
unset ($TempData);
}
}
else
{
$Agg = -1; // -> AC_GetLoggedValues
if ($Diff > $DayValues)
$Agg = 1; // -> AC_GetAggregatedValues [0=Hour, 1=Day, 2=Week, 3=Month, 4=Year]
else if ($Diff > $HourValues)
$Agg = 0; // -> AC_GetAggregatedValues [0=Hour, 1=Day, 2=Week, 3=Month, 4=Year]
if ($Agg == -1)
{
$t1 = $CfgDaten["EndTime"];
$t2 = $CfgDaten["StartTime"];
// Zeitraum ist zu groß -> nur bis max. Zeitraum einlesen
if ($Diff > $DoNotReadLoggedValues)
$t2 = $CfgDaten["EndTime"] - $DoNotReadLoggedValues;
// Alle Werte
$LoggedData = @AC_GetLoggedValues($Id_AH, $VariableId, $t2, $t1, 0);
$ValueKey ="Value";
}
else
{
$LoggedData = @AC_GetAggregatedValues($Id_AH, $VariableId, $Agg, $CfgDaten["StartTime"], $CfgDaten["EndTime"], 0);
$ValueKey ="Avg";
}
}
// keine Daten ausgelesen -> Return
if (!is_array($LoggedData))
return "";
//sortieren, so , dass der aktuellste Wert zuletzt kommt
// krsort($LoggedData);
// aktuellen Wert der Variable noch in Array aufnehmen
$FullItem[$ValueKey]= GetValue($VariableId);
$FullItem["TimeStamp"] = time();
$FullItem["LastTime"] = $FullItem["TimeStamp"];
$FullItem["Duration"] = 0;
$LoggedData[] = $FullItem;
// Logged Daten in Higchart-Format umwandeln
if ($LoggedData != false)
$Data .= CreateSeriesData($LoggedData, $CfgDaten, $Serie) ;
// und Variable freigeben
unset($LoggedData);
$Data = trim ($Data , ',');
$ResultString = "{name: '".$Serie["Name"]."', ".$Serie["Param"].", data: [$Data]},
";
return $ResultString;
}
// ------------------------------------------------------------------------
// CreateSeriesData
// Auslesen von immer wieder benötigten Werten aus der Variable
// IN: $arr = Aus IPS-Datenbank ausgelesenen Daten
// $seriesName = Name der ChartSerie
// $CfgDaten = Alle Config Daten
// $CfgDatenSerie = Config Daten der aktuellen Serie
// OUT: Highcharts ConfigString für Series-Data
// ------------------------------------------------------------------------
function CreateSeriesData($arr, $CfgDaten, $CfgDatenSerie)
{
$Serie = $CfgDatenSerie;
$valStr = false;
$Data ="";
// Daten in Log -> auslesen
if (count($arr) > 0)
{
// den korrekten Variablennamen herausfunden, in welchen die Werte gespeichert wurden
if (isset($arr[0]['Value']))
$valStr = "Value"; // für AC_GetLoggedValues
else if (isset($arr[0]['Avg']))
$valStr = "Avg"; // für AC_GetAggregatedValues
// kein entsprechender Variablenname gefunden -> Ende
if (!$valStr)
return;
// eigentliches Auslesen der Daten
foreach ($arr as $value)
{
$dt = false;
//echo(date("r",$value["LastTime"]) ." - " . date("r",$value["TimeStamp"]) ." - $valStr = " . $value[$valStr]."
<br>");
if ($value["TimeStamp"] < $CfgDaten["StartTime"])
{
$dt = $CfgDaten["StartTime"] ;
}
//if ($value["LastTime"] > $CfgDaten["EndTime"])
//{
// $dt = $CfgDaten["EndTime"] ; // 03.06.2011 Bug Ich denke das das zu Fehlanzeigen führt, da wir den aktuellen Wert auch darstellen
//}
if ($dt == false)
{
$dt = $value["TimeStamp"] ;
}
// Variablenwert auslesen
$val = $value[$valStr];
// Werte ersetzten (sinnvoll für Boolean, oder Integer - z.B.: TürFenster Kontakt oder Dhregriffkontakt)
if ($Serie["ReplaceValues"] != false)
{
if (isset($Serie["ReplaceValues"][$val]))
$val = $Serie["ReplaceValues"][$val];
}
// z.B.: Date.UTC(2011,4,27,19,42,19),23.4
$dtUTC = CreateDateUTC($dt);
$Data .= "[$dtUTC,$val],";
}
}
return $Data;
}
// ------------------------------------------------------------------------
// CreateTooltipString
// Auslesen von immer wieder benötigten Werten aus der Variable
// IN: $CfgDaten = Alle Config Daten
// OUT: Highcharts ConfigString für Tooltip-Formatter (Interaktive Anzeige des Wertes)
// ------------------------------------------------------------------------
function CreateTooltipString($CfgDaten)
{
$s="";
foreach ($CfgDaten["Series"] as $Serie )
{
if (strrpos($Serie["Param"],'pie') > 0)
{
$CountOfSerie = count($Serie["Value"]);
for ($i=0; $i<$CountOfSerie; $i++)
{
$Name = $Serie["Name"][$i];
$Unit = $Serie["Unit"][$i];
$s .= "'".$Name."': this.y + ' ". $Unit."',
";
}
}
else
{
// hier wird das VariableCustomProfile aus IPS übernommen
if (is_null($Serie["Unit"]))
{
// hole das Variablen Profil
$IPSProfil = GetIPSVariableProfile($Serie["Id"]);
if ($IPSProfil != false)
{
if (array_key_exists("Associations",$IPSProfil) && count($IPSProfil["Associations"])>0)
{
$Arr = array();
foreach($IPSProfil["Associations"] as $Item)
{
$Arr[$Item["Value"]] = $Item["Name"];
}
if (!is_array($Serie["ReplaceValues"])) // erzeuge Tooltips vollständig aus VariablenProfil
$s .= "'".$Serie["Name"]."': ". CreateTooltipSubValues($Arr, array_keys($Arr));
else // oder nehme ReplaceValues zur Hilfe
$s .= "'".$Serie["Name"]."': ". CreateTooltipSubValues($Arr, $Serie["ReplaceValues"]);
}
else
{
// Suffix als Einheit übernehmen
$Serie["Unit"] = trim($IPSProfil["Suffix"], " ");
$s .= "'".$Serie["Name"]."': this.y + ' ". $Serie["Unit"]."',
";
}
}
}
// es wurden Unit und ReplaceValues übergeben
else if (is_array($Serie["Unit"]) && is_array($Serie["ReplaceValues"]))
{
$s .= "'".$Serie["Name"]."': ". CreateTooltipSubValues($Serie["Unit"],$Serie["ReplaceValues"]);
}
else // Einheit aus übergebenem Parmeter Unit
{
$s .= "'".$Serie["Name"]."': this.y + ' ". $Serie["Unit"]."',
";
}
}
}
$s = trim($s , "," );
$TooltipString = "formatter: function() {
if (this.point.name) // the pie chart
var Unit2=this.point.name;
else
var Unit2=this.series.name;
var unit = {".$s. "}[Unit2];
if (this.point.name) // the pie chart
return '<b>'+ this.point.name +': </b> '+ unit +'<br/>= ' + this.percentage.toFixed(1) + ' %';
return '<b>'+ this.series.name + ': </b> '+ unit + '<br/>'+Highcharts.dateFormat('%A %d.%m.%Y %H:%M', this.x) ;
}";
return $TooltipString;
}
// ------------------------------------------------------------------------
// CreateTooltipSubValues
// Erzeugt den Tooltip für Unter-Elemente
// IN: shownTooltipArr = Array der Werte (Synonyme) welche im Tooltip angezeigt werden sollen
// chartValueArr = Array der Werte welche im Chart eingetragen werden
// OUT: Tooltip String
// ------------------------------------------------------------------------
function CreateTooltipSubValues($shownTooltipArr, $chartValueArr)
{
$s="{";
$Count = count($shownTooltipArr);
for ($i = 0; $i < $Count ; $i++)
{
if (isset($chartValueArr[$i]) && isset($shownTooltipArr[$i]))
$s .= $chartValueArr[$i] .": '" . $shownTooltipArr[$i] ."'," ;
}
$s = trim($s, ",") . "}";
return $s ."[this.y],
";
}
// ------------------------------------------------------------------------
// GetIPSVariableProfile
// Liest das Variablen Profil der übergeben Variable aus
// Versucht zuerst das eigene und wenn nicht verfügbar das Standar Profil auszulesen
// IN: variableId = Id der Variablen
// OUT: Variablen Profil
// ------------------------------------------------------------------------
function GetIPSVariableProfile($variableId)
{
$Var = IPS_GetVariable($variableId);
$ProfilName = $Var['VariableCustomProfile']; // "Eigenes Profil"
if ($ProfilName == false) // "Standard" Profil
$ProfilName = $Var['VariableProfile'];
if ($ProfilName != false)
{
$IPSProfil = IPS_GetVariableProfile($ProfilName); // und jetzt die dazugehörigen Daten laden
return $IPSProfil;
}
else
return false;
}
// ------------------------------------------------------------------------
// CreateYAxis
// Erzeugen der Y-Achsen Strings für Highchart-Config
// IN: $CfgDaten
// es besteht die Möglichkeit den Achsen String bereits im Highchart Format zu hinterlegen
// oder die folgenden Parameter als Array einzustellen: Name, Min, Max, TickInterval, Opposite, Unit
// OUT: Highcharts String für die Achsen
// ------------------------------------------------------------------------
function CreateYAxis($CfgDaten)
{
if (!array_key_exists("yAxis", $CfgDaten)) // wenn keine Achse definiert wurde dann wenigstens eine automatisch erzeugte zurückgeben
return "{ title: {text: 'Autom. created yAxes'} }";
$sResult="";
foreach ($CfgDaten["yAxis"] as $Axis )
{
$s ="";
if (is_array($Axis))
{
if (array_key_exists ('Name', $Axis))
$s .=" title: { text: '".$Axis["Name"]."' },";
if (array_key_exists ('Min', $Axis))
$s .=" min:".$Axis["Min"].", ";
if (array_key_exists ('Max', $Axis))
$s .=" max: ".$Axis["Max"].",";
if (array_key_exists ('TickInterval', $Axis))
$s .=" tickInterval: ".$Axis["TickInterval"].",";
if (array_key_exists ('Opposite', $Axis))
{
if ($Axis["Opposite"])
$s .=" opposite: true ,";
else
$s .=" opposite: false ,";
}
if (array_key_exists ('Unit', $Axis))
$s .=" labels: { formatter: function() { return this.value +' " . $Axis["Unit"]."'; }},";
$s = trim($s , "," );
$s = "{" . $s ."},";
}
else
{
$s = "{" . $Axis ."},";
}
$sResult .= $s;
}
$sResult = trim($sResult , "," );
return $sResult;
}
// ------------------------------------------------------------------------
// CreateDateUTC
// Erzeugen des DateTime Strings für Highchart-Config
// IN: $timeStamp = Zeitstempel
// OUT: Highcharts DateTime-Format als UTC String ... Date.UTC(1970, 9, 27, )
// Achtung! Javascript Monat beginnt bei 0 = Januar
// ------------------------------------------------------------------------
function CreateDateUTC($timeStamp)
{
$MonthForJS = ((int)date("m", $timeStamp))-1 ; // Monat -1 !!!!!
return "Date.UTC(" . date("Y,", $timeStamp) .$MonthForJS. date(",j,H,i,s", $timeStamp) .")";
}
// ------------------------------------------------------------------------
// GetDefaultStringForCfgFile
// Falls nicht konfiguriert, wird dies als Default String genommen
// OUT: natürlich den String ....
// ------------------------------------------------------------------------
function GetDefaultStringForCfgFile()
{
return
"credits: {
enabled: false
},
exporting: {
buttons: {
printButton: {
enabled: false
}
}
},
chart: {
renderTo: 'container',
zoomType: 'xy'
},
title: {
text: '%title.text%',
x: -20
},
subtitle: {
text: 'Zeitraum: %subtitle.text%',
x: -20
},
xAxis: [{
type: 'datetime',
dateTimeLabelFormats: { second: '%H:%M:%S',
minute: '%H:%M',
hour: '%H:%M',
day: '%e. %b',
week: '%e. %b',
month: '%b \'%y',
year: '%Y'
},
min: %xAxis.min%,
max: %xAxis.max%,
allowDecimals: false
}],
yAxis: [ %yAxis% ],
tooltip: { %tooltip% },
series: [ %data% ]
});";
}
// ------------------------------------------------------------------------
// ReplaceToGermanDate
// Falls nicht konfiguriert, wird dies als Default String genommen
// IN: String mit englischen Wochentagen, bzw. Monaten
// OUT: der String übersetzt ins Deutsche
// ------------------------------------------------------------------------
function ReplaceToGermanDate($value)
{
$trans = array(
'Monday' => 'Montag',
'Tuesday' => 'Dienstag',
'Wednesday' => 'Mittwoch',
'Thursday' => 'Donnerstag',
'Friday' => 'Freitag',
'Saturday' => 'Samstag',
'Sunday' => 'Sonntag',
'Mon' => 'Mo',
'Tue' => 'Di',
'Wed' => 'Mi',
'Thu' => 'Do',
'Fri' => 'Fr',
'Sat' => 'Sa',
'Sun' => 'So',
'January' => 'Januar',
'February' => 'Februar',
'March' => 'März',
'May' => 'Mai',
'June' => 'Juni',
'July' => 'Juli',
'October' => 'Oktober',
'December' => 'Dezember',
);
return strtr($value, $trans);
}
function getmicrotime()
{
list($usec,$sec)=explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
?>