Hallo,
erstmal tolle Arbeit. Die Highgraphen sind echt super.
Aber trotzdem hab ich ein kleines Problem wo ich nicht mehr weiter weis.
Ich habe pro Raum einen Graphen. Alle verwenden das selbe Highcharts_V1.0004 Script. Hier der Auszug davon
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: $Filename = 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);
$StringForCfgFile = str_replace("%Legende%", $CfgDaten["Legende"], $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
},
exportButton: {
enabled: false
}
}
},
chart: {
renderTo: 'container',
zoomType: 'x'
},
title: {
text: '%title.text%',
x: -20
},
subtitle: {
text: '%subtitle.text%',
x: -20
},
legend: {
enabled: %Legende%
},
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);
}
?>
Pro Raum habe ich das Config_Highcharts_V1.0004 Script angepasst. Hier ein Beispiel
<?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"]= "Gang";
$CfgDaten["SubTitle"]= ""; // "" = Automatisch über Zeitraum
$CfgDaten["Legende"]= "true";
// IPS Variablen ID´s
$CfgDaten["ArchiveHandlerId"]= 26281 /*[Archive Handler]*/; // Archive Handler
$CfgDaten["ContentVarableId"]= 42001 /*[EG\Gang\Graph\Graph]*/; // ID der Content-Variable
$CfgDaten["HighChartScriptId"]= 24344 /*[HighCharts\Highcharts_V1.0004]*/; // ID des Highcharts Scripts
// Zeitraum welcher dargestellt werden soll
//$CfgDaten["StartTime"] = mktime(0,0,0, date("m", time()), date("d",time()), 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
$CfgDaten["EndTime"] = time();
$CfgDaten["StartTime"] = $CfgDaten["EndTime"] - 60 * 60 * 24;
// => ab V1.0003
$CfgDaten["RunMode"]= "script"; //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("Id"=>55548, "Name" =>"IST-Temperatur","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"=>45373, "Name" =>"Licht","Unit"=>NULL, "ReplaceValues"=>array(0=>11,1=>14),
"Param" =>"type:'line', step: true, yAxis: 0, 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"=>41358, "Name" =>"Dekosteckdose","Unit"=>NULL, "ReplaceValues"=>array(0=>16,1=>19),
"Param" =>"type:'line', step: true, yAxis: 0, 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"=>34850, "Name" =>"PC Visu","Unit"=>NULL, "ReplaceValues"=>array(0=>21,1=>24),
"Param" =>"type:'line', step: true, yAxis: 0, shadow: true,lineWidth: 1, states: {hover:{lineWidth: 2}}, marker: { enabled: false, states: { hover: { enabled: true, symbol: 'circle', radius: 4, lineWidth: 1}}}");
/*
//oder
foreach(IPS_GetInstanceListByModuleID("{D62B95D3-0C5E-406E-B1D9-8D102E50F64B}") as $InstanceId)
{
if(IPS_GetName($InstanceId) == "IST-Temperatur")
{
echo IPS_GetName($InstanceId);
$var = IPS_GetStatusVariable($InstanceId, "IST-Temperatur");
// 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" =>"Temperatur", "Unit"=>"°C","Min"=>10, "Max"=>30,"Opposite"=>false,"TickInterval"=>5);
//$CfgDaten["yAxis"][] = array("Name" =>"EIN/AUS", "Unit"=>NULL,"Min"=>0, "Max"=>1,"TickInterval"=>0.2,"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"] = 300; // 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
}
}
?>
Die Config Script lasse ich alle 5 Minuten ausführen.
So nun zum Problem
wenn gerade das WebFront den Gang anzeigt und das Script aufgerufen wird, ist die Darstellung I.O. Ist aber eine andere Seite aktiv, und das Script wird aufgerufen dann ist nur ein Teil sichtbar. Siehe Bilder im Anhang.
Irgendwas stimmt da mit der Scalierung nicht.
Hat da jemand eine Idee warum das so ist?
Gruß Alex