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 // Changelog: V1.0005 // 08.07.2011 KHC NEU Pie-Charts: Automatisches Auslesen von AggValues, neuer Parameter: AggType und AggNameFormat // 24.07.2011 KHC NEU Automatisches Auslesen der Archive-Handler ID // 15.12.2011 KHC FIX Aktueller Wert wird bei Zählern nicht eingeblesen // Changelog: V1.0006 // xx.04.2012 KHC REFACT ein wenig aufgeräumt // 09.03.2012 KHC FIX Sortieren der eingelesen Daten da sonst die aktuellste Highcharts Version 2.2.0 Probleme macht // 14.04.2012 KHC NEU Je Serie kann ein eigener Zeitbereich vorgeben werden ("StartTime" und "EndTime") // 14.04.2012 KHC NEU von @Neon: "Offset" je Serie, in Verbindung mit eigenem Zeitbereich ist es dadurch möglich die ein und selbe Variable zb. für den akt. Monat und Vormonat gleichzeitig darzustellen // 15.04.2012 KHC NEU von @Raketenschnecke: Je Serie kann optional über "RoundValue" festgelegt werden auf wie viele Nachkommastellen gerundet werden soll // 15.04.2012 KHC NEU von @axelp : Je Serie kann optional über "ScaleFactor" ein Skalierungsfaktor definiert werden // 15.04.2012 KHC NEU Konfigurationsmöglichkeiten für SubTitle ("SubTitleDateTimeFormat" und "SubTitleFormat") // 15.04.2012 KHC NEU von @Raketenschnecke: Je Serie kann optional über "AggValue" definiert werden welcher Value (Min, Max oder Avg) im Chart angezeigt wird // 15.04.2012 KHC NEU von @Raketenschnecke: Integration der Highcharts-PlotBands // 16.04.2012 KHC NEU Möglichkeit des Aufrufs als WFCPopup und der Darstellung von Highcharts in diesem Fesnter. // 16.04.2012 KHC NEU Jeder Serie können über "Data" von extern Werte übergeben werden. Dann werden für diese Serie aber keine Werte aus der DB gelesen. // Changelog: V1.0007 // 16.04.2012 KHC FIX AggType für Zählerwerte hat nicht mehr funktioniert, // 16.04.2012 KHC NEU AggregatedValues können jetzt auch Weeks, Months und Years vorgegeben werden // Achtung! Die Parametrierungssystematik hat sich geändert (Beschreibung siehe Cfg-Script) // 16.04.2012 KHC NEU von @Raketenschnecke: Möglichkeit der Farbeinstellung für Achsen // Ideen fü die Zukunft: json_encode($CfgDaten) //-------------------------------------------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------ // WriteContentWithFilename // Mit dieser Funktion wird der Content-String geschrieben. // IN: $CfgDaten = .. // IN: $tmpFilename = Der Dateiname welche die Config Daten enthält // ------------------------------------------------------------------------ function WriteContentWithFilename($CfgDaten, $tmpFilename) { // damit das Ding auch sauber dargestellt wird $Height = $CfgDaten['HighChart']['Height'] + 16; if ($tmpFilename != "") SetValue($CfgDaten['ContentVarableId'], ""); 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. // ------------------------------------------------------------------------ function WriteContentWithScriptId($CfgDaten, $scriptId) { // => ab V1.0006, als WFC Popup anzeigen if ($CfgDaten["RunMode"] == "popup") { WFC_SendPopup($CfgDaten['WebFrontConfigId'], $CfgDaten['WFCPopupTitle'] , ""); } else { // damit das Ding auch sauber dargestellt wird $Height = $CfgDaten['HighChart']['Height'] + 16; SetValue($CfgDaten['ContentVarableId'], ""); } } // ------------------------------------------------------------------------ // CreateConfigFile // Erzeugt das tmp-Higcharts Config-File // IN: $stringForCfgFile = String welcher in das File geschrieben wird // ------------------------------------------------------------------------ function CreateConfigFile($stringForCfgFile, $id) { // Standard-Dateiname ..... $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 und vervollständigt diverse // IN: $CfgDaten = .. // OUT: korrigierte CfgDaten // ------------------------------------------------------------------------ // => ab V1.0006, hier wurde etwas aufgeräumt function CheckCfgDaten($CfgDaten) { global $IPS_SELF; global $IPS_SENDER; if ($IPS_SENDER != "WebInterface") // über WebInterface kommt der Aufruf wenn die Highcharts Variable aktualisiert wird. $CfgDaten = Check_ContentVariable($CfgDaten, $IPS_SELF); $CfgDaten = CheckCfg_Common($CfgDaten); $CfgDaten = CheckCfg_AreaHighChart($CfgDaten); $CfgDaten = CheckCfg_Axis($CfgDaten); $CfgDaten = CheckCfg_AggregatedValues($CfgDaten); $CfgDaten['Ips']['ChartType'] = 'Highstock'; $CfgDaten = CheckCfg_StartEndTime($CfgDaten); $CfgDaten = CheckCfg_AreaSeries($CfgDaten); $CfgDaten = CheckCfg_TitleAndSubtitle($CfgDaten); //print_r($CfgDaten); return $CfgDaten; } function CheckCfg_Common($CfgDaten) { if (!isset($CfgDaten['Series'])) $CfgDaten['Series'] = array(); $CfgDaten["ArchiveHandlerId"] = IPS_GetInstanceListByModuleID('{43192F0B-135B-4CE7-A0A7-1475603F3060}'); $CfgDaten["ArchiveHandlerId"] = $CfgDaten["ArchiveHandlerId"][0]; //if (!isset($CfgDaten['RunMode'])) -> autom als 'File' $CfgDaten = CheckCfg_CommonRunAsPopup($CfgDaten); return $CfgDaten; } function CheckCfg_CommonRunAsPopup($CfgDaten) { if ($CfgDaten['RunMode'] != "popup") return $CfgDaten; if (!isset($CfgDaten['WebFrontConfigId'])) die ("Konfiguration von 'WebFrontConfigId' fehlt."); $instance = IPS_GetInstance($CfgDaten['WebFrontConfigId']); if ($instance['ModuleInfo']['ModuleID'] != "{3565B1F2-8F7B-4311-A4B6-1BF1D868F39E}") die ("'WebFrontConfigId' ist keine WebFrontId"); if (!isset($CfgDaten['WFCPopupTitle'])) $CfgDaten['WFCPopupTitle'] = ""; return $CfgDaten; } function Check_ContentVariable($CfgDaten, $scriptId) { // => ab V1.0004, wenn ... dann wird versucht die Content Variable selbst zu ermitteln (es wird hierbei das Parent-Objekt herangezogen) if (!isset($CfgDaten['ContentVarableId']) || $CfgDaten['ContentVarableId'] <= 0) $CfgDaten['ContentVarableId'] = IPS_GetParent($scriptId); $contentVariable = @IPS_GetVariable($CfgDaten['ContentVarableId']); if ($contentVariable == false) die ("ContentVariable nicht gefunden."); if ($contentVariable['VariableValue']['ValueType'] != 3) die ("ContentVariable ist keine STRING-Variable."); if ($contentVariable['VariableCustomProfile'] != "~HTMLBox") die ("ContentVariable muss als Profil '~HTMLBox' verwenden."); return $CfgDaten; } function CheckCfg_AreaHighChart($CfgDaten) { 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; return $CfgDaten; } function CheckCfg_TitleAndSubtitle($CfgDaten) { // Subtitle aus Zeitraum if (!isset($CfgDaten['SubTitle']) || $CfgDaten['SubTitle'] == "") { if (!isset($CfgDaten['SubTitleDateTimeFormat']) || $CfgDaten['SubTitleDateTimeFormat'] == "") $CfgDaten['SubTitleDateTimeFormat'] = "(D) d.m.Y H:i"; if (!isset($CfgDaten['SubTitleFormat']) || $CfgDaten['SubTitleFormat'] == "") $CfgDaten['SubTitleFormat'] = "Zeitraum: %StartTime% - %EndTime%"; $s = $CfgDaten['SubTitleFormat']; $s = str_replace("%StartTime%", date($CfgDaten['SubTitleDateTimeFormat'], $CfgDaten['CorrectStartTime']), $s); $s = str_replace("%EndTime%", date($CfgDaten['SubTitleDateTimeFormat'], $CfgDaten['CorrectEndTime']), $s); $CfgDaten['SubTitle'] = $s; } $CfgDaten['SubTitle'] = ReplaceToGermanDate($CfgDaten['SubTitle']); return $CfgDaten; } function CheckCfg_Axis($CfgDaten) { // wenn keine Achse definiert wurde -> wird wenigstens eine angelegt if (!isset($CfgDaten['yAxis'])) $CfgDaten['yAxis'][]= array( "Name" => 'Autom. created yAxes' ); if (!isset($CfgDaten['xAxis'])) $CfgDaten['xAxis'] = ""; return $CfgDaten; } // hier wird jeder Serie der Anfangs- und Endzeitpunkt zugewiesen // und das gesamte Start-Endzeitpunkt definiert. function CheckCfg_StartEndTime($CfgDaten) { $CfgDaten['CorrectStartTime'] = $CfgDaten['StartTime']; $CfgDaten['CorrectEndTime'] = $CfgDaten['EndTime']; $offsetExistsAtSerie = false; $Count = count($CfgDaten['Series']); for ($i = 0; $i < $Count; $i++) { $Serie = $CfgDaten['Series'][$i]; // => ab V1.0006 (prüfen Start-End-Zeit, da je Serie eigene Zeit übergeben werden kann) // wenn für die Serie keine Start oder Endzeit übergeben würde wird der Standardwert genommen if (!isset($Serie['StartTime'])) $Serie['StartTime'] = $CfgDaten['StartTime']; if (!isset($Serie['EndTime'])) $Serie['EndTime'] = $CfgDaten['EndTime']; if ($Serie['StartTime'] < $CfgDaten['CorrectStartTime']) $CfgDaten['CorrectStartTime'] = $Serie['StartTime']; if ($Serie['EndTime'] > $CfgDaten['CorrectEndTime']) $CfgDaten['CorrectEndTime'] = $Serie['EndTime']; $CfgDaten['Series'][$i] = $Serie; if (isset($Serie['Offset'])) $offsetExistsAtSerie =true; } // wenn ein Offset definiert wurde gilt nur der global eingestellte Start und Endzeitpunkt if ($offsetExistsAtSerie =true) { $CfgDaten['CorrectStartTime'] = $CfgDaten['StartTime']; $CfgDaten['CorrectEndTime'] = $CfgDaten['EndTime']; } return $CfgDaten; } function CheckCfg_AreaSeries($CfgDaten) { $Count = count($CfgDaten['Series']); for ($i = 0; $i < $Count; $i++) { $Serie = $CfgDaten['Series'][$i]; $VariableId = @$Serie['Id']; // => ab V1.0005 (prüfen ob es eine Zählervariable ist $Serie['IsCounter'] = false; if ($VariableId !=false && @AC_GetAggregationType($CfgDaten['ArchiveHandlerId'], $VariableId) == 1) // 1 = Zähler, 0 = Standard { $Serie['IsCounter'] = true; // hier wird nur geprüft ob Wert von Eingabe passen könnte (wenn vorhanden) if (isset($Serie['AggType']) && ($Serie['AggType']<0 || $Serie['AggType']>4) ) // um noch abwärtskompatible zu bleiben Die ("'AggType' hat keinen korrekten Wert"); } // => ab V1.0006 Über AggValue kann Min/Max oder Avg vorgewählt werden if (!isset($Serie['AggValue'])) $Serie['AggValue'] = "Avg"; if ($Serie['AggValue'] != "Avg" && $Serie['AggValue'] != "Min" && $Serie['AggValue'] != "Max") Die ("'AggValue' hat keinen gültigen Wert"); // => ab V1.0006 Offset für Darstellung von z.B. Monate und Vormonat in einem Chart if (!isset($Serie['Offset'])) $Serie['Offset'] = 0; // prüfen ob für die Serie Einstellungen für AggregatedValues vorhanden ist if (isset($Serie['AggregatedValues'])) { if (!isset($Serie['AggregatedValues']['MixedMode'])) $Serie['AggregatedValues']['MixedMode'] = $CfgDaten['AggregatedValues']['MixedMode']; if (!isset($Serie['AggregatedValues']['HourValues'])) $Serie['AggregatedValues']['HourValues'] = $CfgDaten['AggregatedValues']['HourValues']; if (!isset($Serie['AggregatedValues']['DayValues'])) $Serie['AggregatedValues']['DayValues'] = $CfgDaten['AggregatedValues']['DayValues']; if (!isset($Serie['AggregatedValues']['WeekValues'])) $Serie['AggregatedValues']['WeekValues'] = $CfgDaten['AggregatedValues']['WeekValues']; if (!isset($Serie['AggregatedValues']['MonthValues'])) $Serie['AggregatedValues']['MonthValues'] = $CfgDaten['AggregatedValues']['MonthValues']; if (!isset($Serie['AggregatedValues']['YearValues'])) $Serie['AggregatedValues']['YearValues'] = $CfgDaten['AggregatedValues']['YearValues']; if (!isset($Serie['AggregatedValues']['NoLoggedValues'])) $Serie['AggregatedValues']['NoLoggedValues'] = $CfgDaten['AggregatedValues']['NoLoggedValues']; } else // nein -> Daten übernehmen $Serie['AggregatedValues'] = $CfgDaten['AggregatedValues']; //ToDo: das ist noch absolut besch..... gelöst // diverse Prüfungen bei PIE-Charts if (strrpos($Serie['Param'],'pie') > 0) { // falls nicht als Array definiert -> erzeuge Array if (!isset($Serie['Id'])) $Serie['Id']=array(); else if (!is_array($Serie['Id'])) $Serie['Id'] = array($Serie['Id']); if (!isset($Serie['Name'])) $Serie['Name']=array(); else if (!is_array($Serie['Name'])) $Serie['Name'] = array($Serie['Name']); if (!isset($Serie['Unit'])) $Serie['Unit']=array(); else if (!is_array($Serie['Unit'])) $Serie['Unit'] = array($Serie['Unit']); if (!isset($Serie['Value'])) $Serie['Value']=array(); else if (!is_array($Serie['Value'])) $Serie['Value'] = array($Serie['Value']); // ab V1.0005 (AggValues) if (isset($Serie['AggType']) && count($Serie['Id']) == 1 && count($Serie['Name']) == 0 && count($Serie['Value']) == 0) { $VariableId = $Serie['Id'][0]; $AggType = $Serie['AggType']; $Id_AH = $CfgDaten['ArchiveHandlerId']; //-> AC_GetAggregatedValues [0=Hour, 1=Day, 2=Week, 3=Month, 4=Year] if (isset($Serie['AggNameFormat'])) $AggNameFormat = $Serie['AggNameFormat']; else { //[0=Hour, 1=Day, 2=Week, 3=Month, 4=Year] if ($AggType == 0) //0=Hour $AggNameFormat="d.m.Y H:i"; else if ($AggType ==1) //1=Day $AggNameFormat="d.m.Y"; else if ($AggType ==2) //2=Week $AggNameFormat="\K\WW Y"; else if ($AggType ==3) //3=Month $AggNameFormat="M Y"; else if ($AggType ==4) //4=Year $AggNameFormat="Y"; } $LoggedData = @AC_GetAggregatedValues($Id_AH, $VariableId, $AggType, $Serie['StartTime'], $Serie['EndTime'], 0); krsort($LoggedData); foreach ($LoggedData as $ValueItem) { $Serie['Value'][] = $ValueItem[$Serie['AggValue']]; $Serie['Name'][] = ReplaceToGermanDate(date($AggNameFormat,$ValueItem['TimeStamp'])); } } else if (count($Serie['Value']) == 0) { foreach ($Serie['Id'] as $Id) { $Serie['Value'][] = GetValue($Id); } } } // geänderte Werte wieder zurückschreiben $CfgDaten['Series'][$i] = $Serie; } return $CfgDaten; } function CheckCfg_AggregatedValues($CfgDaten) { 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'] = -1; if (!isset($CfgDaten['AggregatedValues']['DayValues'])) $CfgDaten['AggregatedValues']['DayValues'] = -1; if (!isset($CfgDaten['AggregatedValues']['WeekValues'])) $CfgDaten['AggregatedValues']['WeekValues'] = -1; if (!isset($CfgDaten['AggregatedValues']['MonthValues'])) $CfgDaten['AggregatedValues']['MonthValues'] = -1; if (!isset($CfgDaten['AggregatedValues']['YearValues'])) $CfgDaten['AggregatedValues']['YearValues'] = -1; if (!isset($CfgDaten['AggregatedValues']['NoLoggedValues'])) $CfgDaten['AggregatedValues']['NoLoggedValues'] = 100; 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) { // Tooltip Formater $TooltipString = CreateTooltipString($CfgDaten); // Achsen $xAxisString = CreateXAxis($CfgDaten); $yAxisString = CreateYAxis($CfgDaten); // Daten für einzelne Serien erzeugen $Data =""; foreach ($CfgDaten['Series'] as $Serie) { if (isset($Serie['Data'])) // Daten wurden von extern übergeben { $Data .= ConvertDataFromConfig($CfgDaten, $Serie); } else { if (strrpos($Serie['Param'],'pie') > 0) //JS-Parameter für Serie $Data .= ReadPieDataAndCreateDataString($CfgDaten, $Serie); else $Data .= ReadDataFromDBAndCreateDataString($CfgDaten, $Serie); } } $Data = trim($Data,','); $StringForCfgFile = GetHighChartsCfgFile($CfgDaten); // 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("%xAxis%", $xAxisString, $StringForCfgFile); $StringForCfgFile = str_replace("%yAxis%", $yAxisString, $StringForCfgFile); // für Json $StringForCfgFile = str_replace('"%xAxis.min%"', CreateDateUTC($CfgDaten['CorrectStartTime'] - 5*60) , $StringForCfgFile); $StringForCfgFile = str_replace('"%xAxis.max%"', CreateDateUTC($CfgDaten['CorrectEndTime'] + 5*60), $StringForCfgFile); $StringForCfgFile = str_replace("%xAxis.min%", CreateDateUTC($CfgDaten['CorrectStartTime'] - 5*60) , $StringForCfgFile); $StringForCfgFile = str_replace("%xAxis.max%", CreateDateUTC($CfgDaten['CorrectEndTime'] + 5*60), $StringForCfgFile); // Zusätzliche Config in Highchart Config hinzufügen $StringForCfgFile = ReadAdditionalConfigData($CfgDaten) . "\n|||\n" . $StringForCfgFile; return $StringForCfgFile; } // zusätzliche Daten für File (hat jetzt aber nichts mit den eigentlichen Highchart Config String zu tun function ReadAdditionalConfigData($CfgDaten) { // z.B.: Breite und Höhe für Container // Breite und Höhe anpassen für HTML Ausgabe $s['Theme'] = $CfgDaten['HighChart']['Theme']; if ($CfgDaten['HighChart']['Width'] == 0) $s['Width'] = "100%"; else $s['Width'] = $CfgDaten['HighChart']['Width']. "px"; $s['Height'] = $CfgDaten['HighChart']['Height']. "px"; return trim(print_r($s, true), "Array\n()") ; } // => ab V1.0006 function ConvertDataFromConfig($CfgDaten, $Serie) { $data = ""; if ($Serie['Data'] != false) $data = CreateSeriesData($Serie['Data'], $Serie) ; $data = trim ($data , ','); return "{name: '".$Serie['Name']."', ".$Serie['Param'].", data: [$data]},\n"; } // => 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) { $Data =""; $Param = $Serie['Param']; $CountOfSerie = count($Serie['Value']); for ($i=0; $i<$CountOfSerie; $i++) { $val = $Serie['Value'][$i]; // => ab V1.0006 es kann das Skalieren von Loggingdaten definiert werden if (isset($Serie['ScaleFactor'])) $val = $val * $Serie['ScaleFactor']; // => ab V1.0006 es kann das Rounden von Nachkommastellen definiert werden if (isset($Serie['RoundValue'])) $val = round($val, $Serie['RoundValue']); $Name = $Serie['Name'][$i]; $Data .= "['".$Name."',$val],"; } $Data = trim ($Data , ','); $ResultString = "{name: 'pie', $Param, data: [$Data]},"; return $ResultString; } // ------------------------------------------------------------------------ // CalculateStartAndEndTimeForAggreagtedValues // Liest den Start- und Endzeitpunkt des angefragten Bereiches // IN: $Serie, $search : "" für alle Werte, "Hour", "Day", usw // OUT: Array(StartTime,EndTime) // ------------------------------------------------------------------------ function CalculateStartAndEndTimeForAggreagtedValues($Serie, $search ="") { $startDebug = ""; $endeDebug = ""; $start = -1; $ende = -1; $trap = false; $sum = 0; if ($search == "") { $search =="Values"; $start = 0; $trap = true; } foreach($Serie['AggregatedValues'] as $key => $value) { if (strrpos ($key, "Values") != false) { if ($value > 0) $sum += $value; if (strrpos ($key, $search) !== false) { $trap = true; if ($value == -1) return false; } if (!$trap) continue; if ($value < 0) continue; if ($start == -1) { $start = $sum; $startDebug = "$key . $value . $sum"; continue; } if ($start != -1 && $ende ==-1) { $ende = $sum; $endeDebug = "$key . $value . $sum"; break; } } } $result = false; if ($start != -1) { $result["EndTime"] = $Serie["EndTime"] - $start; if ($ende == -1) $result["StartTime"] = $Serie["StartTime"]; else $result["StartTime"] = $Serie["EndTime"] - $ende; if ($result["StartTime"] < $Serie["StartTime"]) $result["StartTime"] = $Serie["StartTime"]; if ($result["StartTime"] == $Serie["EndTime"]) $result = false; } return $result; //echo $endeDebug ." / ". $startDebug ."
"; //echo date("/r",$result["StartTime"]) ." / ". date("/r",$result["EndTime"]); } // ------------------------------------------------------------------------ // 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) { // => ab V1.0006 (Start-End Zeit je Serie möglich) // dadurch wurde $CfgDaten['StartTime'] und $CfgDaten['EndTime'] durch $Serie['StartTime'] und $Serie['EndTime'] ersetzt // errechne die Zeitspanne $Diff = $Serie['EndTime'] - $Serie['StartTime']; if ($Serie['EndTime'] > time()) $Diff = time() - $Serie['StartTime']; // Umrechnen der Tage in Sekunden ... für direktes addieren zum Timestamp $MinPerTag = 24*60*60; if ($Serie['AggregatedValues']['HourValues'] != -1) $Serie['AggregatedValues']['HourValues'] *= $MinPerTag; if ($Serie['AggregatedValues']['DayValues'] != -1) $Serie['AggregatedValues']['DayValues'] *= $MinPerTag; if ($Serie['AggregatedValues']['WeekValues'] != -1) $Serie['AggregatedValues']['WeekValues'] *= $MinPerTag; if ($Serie['AggregatedValues']['MonthValues'] != -1) $Serie['AggregatedValues']['MonthValues'] *= $MinPerTag; if ($Serie['AggregatedValues']['YearValues'] != -1) $Serie['AggregatedValues']['YearValues'] *= $MinPerTag; if ($Serie['AggregatedValues']['NoLoggedValues'] != -1) $Serie['AggregatedValues']['NoLoggedValues'] *= $MinPerTag; $Id_AH = $CfgDaten['ArchiveHandlerId']; $LoggedData = false; $VariableId = (int)$Serie['Id']; $Agg = -1; $ReadCurrentValue = true; // wenn ReplaceValues definiert wurden werden nur geloggte und keine Aggregated Werte gelesen if ($Serie['ReplaceValues'] != false) { if ($Diff > $Serie['AggregatedValues']['NoLoggedValues']); $Serie['StartTime'] = $Serie['EndTime'] - $Serie['AggregatedValues']['NoLoggedValues']; // Einzelwerte lesen $LoggedData = @AC_GetLoggedValues($Id_AH, $VariableId, $Serie['EndTime'], $Serie['StartTime'], 0); } else if ($Serie['AggregatedValues']['MixedMode']) // im MixedMode werden anfangs alle Werte, dann die Stunden- und zuletzt Tageswerte ausgelesen { // zuerst Einzelwerte $result = CalculateStartAndEndTimeForAggreagtedValues($Serie, ""); if ($result != false) { if ($Serie['IsCounter']) // wenn Zähler dann immer Agg.Values //$LoggedData = @AC_GetAggregatedValues($Id_AH, $VariableId, 0, $result["EndTime"], $result["EndTime"], 0); $LoggedData = ReadAndAddToLoggedData($LoggedData, $Id_AH, $VariableId, 0, $result["StartTime"], $result["EndTime"], $Serie['AggValue']); else $LoggedData = @AC_GetLoggedValues($Id_AH, $VariableId, $result["StartTime"], $result["EndTime"], 0 ); } // -> Stundenwerte $result = CalculateStartAndEndTimeForAggreagtedValues($Serie,"Hour"); if ($result != false) $LoggedData = ReadAndAddToLoggedData($LoggedData, $Id_AH, $VariableId, 0, $result["StartTime"], $result["EndTime"], $Serie['AggValue']); // -> Tageswerte $result = CalculateStartAndEndTimeForAggreagtedValues($Serie,"Day"); if ($result != false) $LoggedData = ReadAndAddToLoggedData($LoggedData, $Id_AH, $VariableId, 1, $result["StartTime"], $result["EndTime"], $Serie['AggValue']); // -> Wochenwerten $result = CalculateStartAndEndTimeForAggreagtedValues($Serie,"Week"); if ($result != false) $LoggedData = ReadAndAddToLoggedData($LoggedData, $Id_AH, $VariableId, 2, $result["StartTime"], $result["EndTime"], $Serie['AggValue']); // -> Monatswerte $result = CalculateStartAndEndTimeForAggreagtedValues($Serie,"Month"); if ($result != false) $LoggedData = ReadAndAddToLoggedData($LoggedData, $Id_AH, $VariableId, 3, $result["StartTime"], $result["EndTime"], $Serie['AggValue']); // -> Jahreswerte $result = CalculateStartAndEndTimeForAggreagtedValues($Serie,"Year"); if ($result != false) $LoggedData = ReadAndAddToLoggedData($LoggedData, $Id_AH, $VariableId, 4, $result["StartTime"], $result["EndTime"], $Serie['AggValue']); } else { $Agg = -1; // -> AC_GetLoggedValues if ($Serie['IsCounter']) // wenn Zähler dann Werte entsprechend AggType-Einstellung { if (!isset($Serie['AggType'])) // wenn nichts definiert -> 0 $Agg = 0; else $Agg = $Serie['AggType']; } elseif ($Serie['AggregatedValues']['YearValues']!= -1 && $Diff > $Serie['AggregatedValues']['YearValues']) $Agg = 4; // -> AC_GetAggregatedValues [0=Hour, 1=Day, 2=Week, 3=Month, 4=Year] elseif ($Serie['AggregatedValues']['MonthValues']!= -1 && $Diff > $Serie['AggregatedValues']['MonthValues']) $Agg = 3; // -> AC_GetAggregatedValues [0=Hour, 1=Day, 2=Week, 3=Month, 4=Year] elseif ($Serie['AggregatedValues']['WeekValues']!= -1 && $Diff > $Serie['AggregatedValues']['WeekValues']) $Agg = 2; // -> AC_GetAggregatedValues [0=Hour, 1=Day, 2=Week, 3=Month, 4=Year] elseif ($Serie['AggregatedValues']['DayValues']!= -1 && $Diff > $Serie['AggregatedValues']['DayValues']) $Agg = 1; // -> AC_GetAggregatedValues [0=Hour, 1=Day, 2=Week, 3=Month, 4=Year] else if ($Serie['AggregatedValues']['HourValues']!= -1 && $Diff > $Serie['AggregatedValues']['HourValues']) $Agg = 0; // -> AC_GetAggregatedValues [0=Hour, 1=Day, 2=Week, 3=Month, 4=Year] if ($Agg == -1) { // Zeitraum ist zu groß -> nur bis max. Zeitraum einlesen if ($Diff > $Serie['AggregatedValues']['NoLoggedValues']) $Serie['StartTime'] = $Serie['EndTime'] - $Serie['AggregatedValues']['NoLoggedValues']; // Alle Werte $LoggedData = @AC_GetLoggedValues($Id_AH, $VariableId, $Serie['StartTime'], $Serie['EndTime'], 0); } else { $LoggedData = @AC_GetAggregatedValues($Id_AH, $VariableId, $Agg, $Serie['StartTime'], $Serie['EndTime'], 0); $ReadCurrentValue = false; } } // keine Daten ausgelesen -> Return if (!is_array($LoggedData)) return ""; //sortieren, so , dass der aktuellste Wert zuletzt kommt // => ab V1.0006 da sonst Highcharts 2.2.0 Probleme macht krsort($LoggedData); // aktuellen Wert der Variable noch in Array aufnehmen if ($ReadCurrentValue && $Serie['EndTime'] >= time() // => ab V1.0006 (.... nicht wenn Endzeitpunkt vor NOW ist) && !$Serie['IsCounter']) // => ab V1.0005 (.... nicht bei Zählervariablen) { $LoggedData[] = ReadCurrentValue($VariableId); } $Data = ""; // Logged Daten in Higcharts-Format umwandeln if ($LoggedData != false) $Data .= CreateSeriesData($LoggedData, $Serie) ; // und Variable freigeben unset($LoggedData); $Data = trim ($Data , ','); $ResultString = "{name: '".$Serie['Name']."', ".$Serie['Param'].", data: [$Data]},\n"; return $ResultString; } // ------------------------------------------------------------------------ // ReadCurrentValue // IN: $VariableId // OUT: Aktueller Wert // ------------------------------------------------------------------------ function ReadCurrentValue($VariableId) { $currentVal['Value']= GetValue($VariableId); $currentVal['Avg']= $currentVal['Value']; $currentVal['Min']= $currentVal['Value']; $currentVal['Max']= $currentVal['Value']; $currentVal['TimeStamp'] = time(); $currentVal['LastTime'] = $currentVal['TimeStamp']; $currentVal['Duration'] = 0; return $currentVal; } // ------------------------------------------------------------------------ // ReadAndAddToLoggedData // IN: siehe Parameter // OUT: Vervollständigte Logged Data // ------------------------------------------------------------------------ function ReadAndAddToLoggedData($loggedData, $id_AH, $variableId, $aggType, $startTime, $endTime, $aggValueName ) { $TempData = @AC_GetAggregatedValues($id_AH, $variableId, $aggType, $startTime, $endTime, 0); foreach ($TempData as $Item) { $Item['Value'] = $Item[$aggValueName]; $loggedData[] = $Item; } unset ($TempData); return $loggedData; } // ------------------------------------------------------------------------ // CreateSeriesData // Erzeugen der Highcharts-JS Daten aus den IPS-Variablen-Daten // IN: $arr = Aus IPS-Datenbank ausgelesenen Daten (LoggedData) // $Serie = Config Daten der aktuellen Serie // OUT: Highcharts ConfigString für Series-Data // ------------------------------------------------------------------------ function CreateSeriesData($arr, $Serie) { $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 // => ab V1.0006 Min, Max oder Avg je Serie auswählbar else if (isset($arr[0]['Avg'])) $valStr = $Serie['AggValue']; else return; // kein entsprechender Variablenname gefunden -> Ende // eigentliches Auslesen der Daten foreach ($arr as $value) { $dt = false; if ($value['TimeStamp'] < $Serie['StartTime']) $dt = $Serie['StartTime'] ; else $dt = $value['TimeStamp'] ; // Variablenwert auslesen $val = $value[$valStr]; // Werte ersetzten (sinnvoll für Boolean, oder Integer - z.B.: Tür/Fenster-Kontakt oder Drehgriffkontakt) if ($Serie['ReplaceValues'] != false) { if (isset($Serie['ReplaceValues'][$val])) $val = $Serie['ReplaceValues'][$val]; } // => ab V1.0006 es kann das Skalieren von Loggingdaten definiert werden if (isset($Serie['ScaleFactor'])) $val = $val * $Serie['ScaleFactor']; // => ab V1.0006 es kann das Rounden von Nachkommastellen definiert werden if (isset($Serie['RoundValue'])) $val = round($val, $Serie['RoundValue']); // z.B.: Date.UTC(2011,4,27,19,42,19),23.4 $dtUTC = CreateDateUTC($dt + $Serie['Offset']); // => ab V1.0006 Offset $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 = ""; $offset = ""; // => ab V1.0006 Offset zum Darstellen von z.B.: Monat und Vormonat in einem Chart 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]; // => ab V1.0005 (somit muss nur mehr einmal die Einheit übergeben werden, falls alle identisch sind) if ($i < count($Serie['Unit'])) $Unit = $Serie['Unit'][$i]; $s .= "'".$Name."': this.y + ' ". $Unit."',\n"; $offset .= "'".$Name."': ".$Serie['Offset']."',\n"; } } 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']."',\n"; } } else // falls VariablenId nicht existiert { $s .= "'".$Serie['Name']."': this.y ,\n"; } } // 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']."',\n"; } $offset .= "'".$Serie['Name']."': ".$Serie['Offset'].",\n"; } } $s = trim($s , "," ); $offset = trim($offset , "," ); $TooltipString = "formatter: function() { if (this.point.name) // the pie chart var index =this.point.name; else var index = this.series.name; var unit = {".$s. "}[index]; var offset = {".$offset. "}[index] * 1000; if (offset != 0) offsetInfo = '
(Achtung Zeitwert hat ein Offset)'; else offsetInfo =''; if (this.point.name) // the pie chart return ''+ this.point.name +': '+ unit +'
= ' + this.percentage.toFixed(1) + ' %'; return ''+ this.series.name + ': '+ unit + '
' + Highcharts.dateFormat('%A %d.%m.%Y %H:%M', this.x - offset) + offsetInfo; }"; 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],\n"; } // ------------------------------------------------------------------------ // 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); if ($Var == false) // Variabel existiert nicht return false; $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; } // ------------------------------------------------------------------------ // CreateXAxis // Erzeugen dew X-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 CreateXAxis($CfgDaten) { $Axis = $CfgDaten['xAxis']; if (is_array($Axis)) { // Vorbereitung für V1.0008 - noch nicht richtig implementiert $s = json_encode($Axis, true); //$s = substr($s,1,-1); return $s; } else { /*Vorbereitung für V1.0008 $arr = array('type' => 'datetime', "dateTimeLabelFormats" => array("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); return json_encode($arr, true);; */ $s ="{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 }"; return $s; } } // ------------------------------------------------------------------------ // 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) { $sResult=""; $i = 0; foreach ($CfgDaten['yAxis'] as $Axis ) { $s =""; $i++; if (is_array($Axis)) { $Axis = array_change_key_case($Axis, CASE_LOWER); if (isset($Axis['name'])) $s .=" title: { text: '".$Axis['name']."' ,"; else if (isset($Axis['titletext'])) $s .=" title: { text: '".$Axis['name']."' ,"; else $s .=" title: { text: '".$i.". Axis' },"; // => ab V1.0007 if (isset($Axis['yaxiscolor'])) $s .=" style: {".$Axis['yaxiscolor']."},"; else if (isset($Axis['titlestyle'])) $s .=" style: {".$Axis['titlestyle']."},"; $s .="},"; if (isset($Axis['min'])) $s .=" min:".$Axis['min'].", "; if (isset($Axis['max'])) $s .=" max: ".$Axis['max'].","; if (isset($Axis['tickinterval'])) $s .=" tickInterval: ".$Axis['tickinterval'].","; if (isset($Axis['opposite']) && $Axis['opposite']) $s .=" opposite: true ,"; else $s .=" opposite: false ,"; // => ab V1.0006 Implementierung von @Raketenschneckes - PlotBands if (isset($Axis['plotbands'])) $s .=" plotBands: ".$Axis['plotbands'].","; if (isset($Axis['unit'])) $s .=" labels: { formatter: function() { return this.value +' " . $Axis['unit']."'; },"; // => ab V1.0007 if (isset($Axis['yaxiscolor'])) $s .=" style: {".$Axis["yaxiscolor"]."},"; if (isset($Axis['titlestyle'])) $s .=" style: {".$Axis["titlestyle"]."},"; $s .="},"; $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 (PHP->JS) return "Date.UTC(" . date("Y,", $timeStamp) .$monthForJS. date(",j,H,i,s", $timeStamp) .")"; } // ------------------------------------------------------------------------ // GetHighChartsCfgFile // Falls nicht konfiguriert, wird dies als Default String genommen // OUT: natürlich den String .... // ------------------------------------------------------------------------ function GetHighChartsCfgFile($CfgDaten) { // kein Cfg String konfiguriert -> nimm den Eigenen If (isset($CfgDaten['HighChartCfg']) && $CfgDaten['HighChartCfg'] != false) return $CfgDaten['HighChartCfg']; else { return "credits: { enabled: false }, exporting: { buttons: { printButton: { enabled: false } } }, chart: { renderTo: 'container', zoomType: 'xy' }, title: { text: '%title.text%', x: -20 }, subtitle: { text: '%subtitle.text%', x: -20 }, xAxis: [ %xAxis% ], 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', 'Mar' => 'Mär', 'May' => 'Mai', 'Oct' => 'Okt', 'Dec' => 'Dez', ); return strtr($value, $trans); } function getmicrotime() { list($usec,$sec)=explode(" ", microtime()); return ((float)$usec + (float)$sec); } ?>