Q&A Highcharts - Multigraph V1.0

Ich bin aber mal sowas von beeindruckt!
Ich habe zwar noch diverse Anpassungen machen müssen, aber das war nur Kosmetik. Und über Geschmack lässt sich bekanntlich streiten.
FUNKTIONAL: TOPP! :smiley: :loveips:

vielleicht noch ein paar Worte zum konzeptionellen Ansatz (hätte ich vielleicht oben gleich mit reinpacken sollen):

mir ging es nicht um eine fertige plug-and-play-Lösung, sondern nur um einen Ansatz, wie man

[ul]
a) ausserhalb der IPS-DB Datensätze generiert und in einer HC-konformen Struktur ablegt, sowie

[li]b)um das anschließende Einbinden dieser Datensätze in HC.[/ul]
[/li]
Die Ablage der HC Data-Strings (HC-Data-String = ein komplettes Datensatz-Array für einen vollständigen Graphen im HC, beinhaltet jeweils die x- und y-Daten) habe ich deshalb in String-Variablen ausgelagert, weil sie sich so auch unabhängig vom eigentlichen HC-Config-Script manipulieren lassen (in diesem Beispiel z.B. tägliches Neuberechnen der PV Ertrags-Quote). Weiterhin sind diese Datastrings auch für beliebige andere Diagramme verfügbar.

Die eigentliche Darstellung im HC-Chart ist in der Tat Geschmackssache, das kann jeder nach eígenem Geschmack anpassen. Daher sind diese Parameter auch nicht Bestandteil der oben geposteten Codes.

Es gab eine Unschönheit; ich habe mir zwei Knöpfchen gebaut (DummyModul, Variable mit Profil) mit dem ich durch die Jahre springen kann. Die Jahreszahl gebe ich dann an das HC Script weiter und dieses wiederum zeichnet die Graphen nach Datum/Jahr sortiert. Mit der Quote und den Sollwerten war es aber so, das Soll zum 01.01. als String geschrieben wird mit dem dann aktuellen Jahr. Quote analog dazu, Zeitpunkt beliebig, mit dem dann aktuellen Jahr. Wenn ich nun im WFE das Jahr von 2012 auf 2011 gewechselt hatte, dann kam nur Quatsch heraus, da ja Sollwerte und Quote mit 2012 als Jahr abgelegt wurden.
Das habe ich jetzt so gelöst, dass ich bei Variablenänderung (Jahr) die Scripte Sollwerte und Quote gestartet werden, die sich dann wiederum das Jahr aus der Variable Jahr holen. Das klappt auch soweit (und ich bin mächtig stolz auf mich :wink: ).
Leider scheint es aber ein Bug im „HC-Data-String Ertragswerte“-Script zu geben. Ich hatte im Jahr 2011 nur in den Monaten 11 und 12 Ertrag. Ein

echo $PV_Quote_String;

wirft allerdings ein

[Date.UTC(2011,0, 1, 00, 00, 00),86], [Date.UTC(2011,1, 1, 00, 00, 00),53],
. Das sieht dann entsprechend so aus:

tja, so ist das nunmal, wenn die SPEC nachträglich angepasst oder erweitert wird :wink: Das Script war nicht dafür gedacht, in die Vergangenheit zu gehen. Daher habe ich keine Logik eingebaut, die auf den Zeitraum bezogen vorhandene Daten checkt. Die Array’s sortieren stumpf aufsteigend…:smiley:

Kann man das programatisch abfangen?
Ansonsten versuche ich mich an einer IF/ELSE Lösung. :wink:

EDIT: Toll wäre natürlich wenn man rückwirkend (Zeitstempel) in eine Variable schreiben könnte … LINK

Hallo Axel,
die Zeitauswahl funktioniert super, Danke!.
Um die Graphen bei Änderung der Zeitauswahl automatisch neu zu Zeichnen braucht man nur das Konfig-Script bei Änderung der Variablen HC_Endwert un HC_Zeitraum zu triggern.

Danke und Gruß,
Pierre

Config_trigger.JPG

Hi Pierre,

schon klar, aber ich hab halt knapp 25 Graphen und will das cleverer lösen.

Grüsse, Axel

Wo muss ich denn hier:

<?
/*
    Funktion: Berechnung der monatlichen (Ertrags-)Quote einer PV-Anlage in %.
    Quote = (100*Ertrag)/Soll

    Ertrag = von der PV-Anlage erzeugte elektr. Arbeit in Kwh
    Soll = erwartete elektr. Arbeit pro Monat
*/


// +++ Konfig / Vorgaben +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Auswertungszeitraum

    $year                  = GetValue(28289 /*[Scripte\Highcharts_V1.0005\PV-Anlage pro Monat\Dummy Module\Highcharts_Jahre]*/ ); // Berechnungen für welches Jahr? -> Wert ggf durch date("Y",time()) ersetzen
    $ts                    = mktime(0,0,0, 1,1, $year); // ab 01.01.$year 0:00:00 Uhr
    $te                    = mktime(23,59,59, 12, 31, $year); // bis 31.12.$year 23:59:59 Uhr

// Definition der Variablen-ID's
    $PV_Quote_monatlich_id = 23512 /*[Program\SMA Webbox\Quote]*/  ; // Ziel-Variable für HC-Data-String "Quote"
    $PV_Ertrag_id          = 57373 /*[Program\SMA Webbox\Ertrag täglich (Zähler)]*/ ; // Variablen-ID der geloggten PV Ertragsdaten
    $PV_Soll_array         = getValueString(57861 /*[Program\SMA Webbox\Sollwerte]*/ ); // Var-ID, in der die PV-Solldaten (HC-String) liegen

// +++ Konfig / Vorgaben  Ende +++++++++++++++++++++++++++++++++++++++++++++++++


// Archive Handler, geloggte Daten auslesen
    $archiveID             = IPS_GetInstanceIDByName("Archive Handler", 0);   // Archive-Handler-ID
    $PV_Ertrag_array       = AC_GetAggregatedValues($archiveID, $PV_Ertrag_id, 3, $ts, $te, 12);

// Array-Daten formatieren
    $PV_Ertrag_array       = array_reverse($PV_Ertrag_array); // Array-Reihenfolge umkehren
    $PV_Soll_array         = substr($PV_Soll_array, 1, -3); // HC-String formatieren und in verarbeitungsfähige Form bringen
    $PV_Soll_array         = explode("[ ]", $PV_Soll_array);
    $PV_Soll_array         = explode("], [", $PV_Soll_array[0]);

// Startdefinition Arbeitsvariablen

	 $i = 0;
    $PV_Soll = array();


// PV Soll-Werte aus HC-Sollwert-String extrahieren und in neues Array schreiben
    do
    {
       $temp_Soll_val      = substr(strrchr ($PV_Soll_array[$i], ","), 1);
       $PV_Soll[]          = $temp_Soll_val;
        $i++; // Schleifenzähler +1

    }
    while ($i < 12);

// Startvariablen neu definieren

	 $i                     = 0;
    $PV_Quote_String       = "";


// String PV Quote aufbauen und in STRING-Var schreiben
    do
    {
       if (isset($PV_Ertrag_array[$i]['Avg']))
       {
                $PV_Quote         = round((100*$PV_Ertrag_array[$i]['Avg'])/$PV_Soll[$i], 0);
                $PV_Quote_String .= "[Date.UTC(".$year.",".$i.", 1, 00, 00, 00),".$PV_Quote."], ";
                $i++; // Schleifenzähler +1
        }
        else
        {
           $i    = 12;
        }
    }
    while ($i < 12);

 echo $PV_Quote_String;

// String PV Ertrag Sollwert in String-Var schreiben
    setValueString($PV_Quote_monatlich_id , $PV_Quote_String);

?>

eine if/else Abfrage einbauen, um den String (wie in meinem Fall) erst ab Nov 2011 schreiben zu lassen. Ich weiß, es wäre dann recht statisch, aber damit kann ich gut leben.
Also; wenn $year = 2011, dann schreibe string ab ($year,10, 1, 00, 00, 00) ansonsten (2012,0, 1, 00, 00, 00). Gerne auch als Variablen ($year,$start_monat, 1, 00, 00, 00). :slight_smile:
Ich teste die ganze Zeit hier rum, komme aber nicht an die Lösung. Danke im Voraus.

Ich habe für jeden Graphen eine eigene „Zeitraum“ Leiste, die triggert dann nur den eigenen Graphen. Ist zwar ein wenig aufwendig, geht aber ohne Probleme.

Gruß, Pierre

@all: Keiner eine Idee?
Mit

// Startdefinition Arbeitsvariablen

	 if ($year == 2011)
	 {
	 $i = 10;
	 }
	 else
	 {
	 $i = 0;
    $PV_Soll = array();
    }

wird auf jeden Fall schon mal die richtige Quote berechnet. Aber leider für den String wird

[Date.UTC(2011,0, 1, 00, 00, 00),72.5], [Date.UTC(2011,1, 1, 00, 00, 00),108.9],
erstellt.

Changelog

[ul]
[li]FIX: Sortieren der eingelesen Daten da sonst die aktuellste Highcharts Version 2.2.0 Probleme macht[/li][li]NEU: Je Serie kann ein eigener Zeitbereich vorgeben werden („StartTime“ und „EndTime“)[/li][li]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[/li][li]NEU: von @Raketenschnecke: Je Serie kann optional über „RoundValue“ festgelegt werden auf wie viele Nachkommastellen gerundet werden soll[/li][li]NEU: von @axelp : Je Serie kann optional über „ScaleFactor“ ein Skalierungsfaktor definiert werden[/li][li]NEU: Konfigurationsmöglichkeiten für SubTitle („SubTitleDateTimeFormat“ und „SubTitleFormat“)[/li][li]NEU: von @Raketenschnecke: Je Serie kann optional über „AggValue“ definiert werden welcher Value (Min, Max oder Avg) im Chart angezeigt wird[/li][li]NEU: von @Raketenschnecke: Integration der Highcharts-PlotBands[/li][li]NEU: Möglichkeit des Aufrufs als WFCPopup und der Darstellung von Highcharts in diesem Fenster.[/li][li]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.[/li][*][/ul]

Changelog

[ul]
[li]FIX: Bugfix von V1.006 (AggType für Zählerwerte und AggregatedValues)
[/li][li]NEU: AggregatedValues können jetzt auch Weeks, Months und Years vorgegeben werden (Achtung! Die Parametrierungssystematik hat sich geändert (Beschreibung siehe Cfg-Script))
[/li][li]NEU: von @Raketenschnecke: Möglichkeit der Farbeinstellung für Achsen
[/li][*][/ul]

Am einfachsten habe ich folgende Vorgehensweise empfunden um die vorhandenen Charts mit der aktuellen Version zum laufen zu bringen.
Dadurch waren bei mir keine zusätzlichen Anpassungen in den Cfg Scripts der einzelnen Charts notwendig.

1.) Sicherheitskopie des aktuellen Highcharts-Scripts
2.) Source aus neuer Version Highcharts V1.0007 Script per Copy & Paste in das über Highcharts - Script kopieren. Dadurch muss nicht in den Cfg Scripten die Highcharts-Id angepasst werden.

Alle neuen Funktionen können ja dann bei Bedarf eingebaut werden.

Viel Spaß
KHC

Funktionieren bei Euch die PIEs noch?
Ich habe nicht verändert und trotzdem wird mir ein PIE nicht mehr angezeigt.

// PIE
	$CfgDaten["Series"][] = array("Id"=>array(52428,21925),
	"Name" =>array("Betriebsstunden","Wärmemenge kWh"),
	"Unit"=>array("h","kWh"),
	"ReplaceValues"=>false,
	"Param" =>"type:'pie',
	center: [200, 100],
	size: 300,
	showInLegend: true,
	shadow: true,
	lineWidth: 1,
	dataLabels: {enabled: false}");

Ja da hat sich wirklich ein Fehler mit den „Pies“ eingeschlichen… Werde heute nachmittag nochmals danach schauen und mich dann melden…

Danke KHC

Hier das Bugfix. Wird mit der nächsten Highcharts-Version veröffentlicht. Im Highcharts-Script in der Funktion „CreateTooltipString“ die Zeile

$offset .= "'".$Name."': ".$Serie['Offset']."',";

einfach auskommentieren. Dann sollten die Pies wieder laufen.

Das ganze sieht dann folgendermaßen aus:

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."',";
					//$offset .= "'".$Name."': ".$Serie['Offset']."',";
				}
			}
			else

Hallo,

habe endlich Highcharts „zum laufen“ gebracht und zumindest teilweise verstanden wie es funktioniert.
Ein Frage stellt sich mir aber jetzt: Muss ich jedesmal das ganze „anlegen“ (Variable, Scripte,…) wenn ich eine Chartserie anzeigen lassen möchte? Beispiel: Cartserie 1 mit Ist- und Solltemperatur sowie Stellantriebsdaten (%) des Wohnzimmers. Das ganze möchte ich nun auch für das Esszimmer machen.

Ups, eine zweite Frage fällt mir noch ein: Ich möchte gerne den Stromverbrauch und gleichzeitig die Produktionswerte der PV-Anlage anzeigen lassen. Beide Werte sind vorhanden und werden geloggt. Mit Highcharts anzeigen lassen geht aber irgendwie nicht. Ich habe gelesen dass die Werte als Zähler geloggt sein müssen. Das habe ich umgestellt. Hat mir dazu jemand einen Tipp?

Viele Grüße

Michael

hier gibt es 2 Mögliche Ansätze:

  1. ja, du legst für jedes Diagramm je eine neue String-Var und ein HC-Config-Script an
  2. Du legst eine String-Var an, darunter für jedes Diagramm, welches Du designen möchtest, ein individuelles HC-Config-Script. Das macht dann Sinn, wenn man (2+) verschiedene Sichten in einem WFE-Fenster darstellen möchte. Das jeweilige Diagramm kann dann im WFE durch das unter dem Diagramm erscheindende Script angezeigt werden (das jeweils ausgelöste Script füllt die Variable)

hast Du die umgestellte Var auch neu aggregiert? wenn ja werden wohl weitere Fehler-Infos benötigt, um die Ursache einzugrenzen

Es gibt auch noch Probleme mit Boolean-Variablen in verbindung mit ReplaceValue …

// Warmwasser Zirkulationspumpe
	$CfgDaten["Series"][] = array("Id"=>53839,
	"Name" =>"WWZ",
	"Unit"=>NULL,
	"ReplaceValues"=>array(0=>0.2,1=>20),
	"Param" =>"type:'area',
	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}}}");

Das ist meine Warmwasserzirkulationspumpe; sie liefert 0 oder 1.
Funktioniert die Anzeige bei Euch?

nun, vielleicht hättest du auch dein Problem schildern sollen… dann hätte man mit dem Posting was Konkretes anfangen können.
Möglicherweise ist es dieses Problem(?):

Bool-Vars mit Replace Value werden bei mir mit max. 1-2 historischen Datensätzen angezeigt. Eine weiter zurückreichende Historie ist in den Daten nicht enthalten.

Hier mal ein Auszug aus einem meiner Diagramme (.tmp-File), „Niederschlag“ ist die Bool-Var mit Replace Value, vergleichend ist noch „Rohdaten“ enthalten (Datensatz gekürzt):


series: [
						{name: 'Niederschlag', type:'area', step:true, yAxis: 0, visible: false, color: '#818181', shadow: true,lineWidth: 1, states: {hover:{lineWidth: 2}},
			marker: { enabled: false, states: { hover: { enabled: true, radius: 4}}}, data: [[Date.UTC(2012,3,24,19,50,42), 4],[Date.UTC(2012,3,24,21,50,55), 4]]},
{name: 'Rohdaten', type:'spline', step:true, yAxis: 0, visible: true, color: '#2CAB61', shadow: true, dashStyle: 'shortdot', lineWidth: 1, states: {hover:{lineWidth: 2}},
			marker: { enabled: false, states: { hover: { enabled: true, radius: 4}}}, data: [[Date.UTC(2012,3,24,00,00,00), 4],[Date.UTC(2012,3,24,06,00,17), 4.012],[Date.UTC(2012,3,24,06,00,19), 4.009],[Date.UTC(2012,3,24,06,00,22), 4.005],[Date.UTC(2012,3,24,06,00,25), 4.002],[Date.UTC(2012,3,24,06,00,27), 4],[Date.UTC(2012,3,24,06,12,39), 4.009],[Date.UTC(2012,3,24,06,12,42), 4.005],[Date.UTC(2012,3,24,06,12,46), 4.001],