Multigraph, wie?

Hallo Hinti,

sorry, nix für ungut, aber was willst Du mit deinem Post jetzt sagen? :rolleyes:
Ich denke, viele User haben Wünsche. Und es dauert einfach, bis alles umgesetzt ist.

In diesem Sinne,
…auch bis dann :rolleyes:

sorry auch nix für ungut, aber dein kommentar ist auch nicht viel besser :cool:

Hallo,

ich wollte Webfront eigentlich zur Datenanalyse nehmen (z.B. Außentemperatur mit Windgeschwindigkeit und Vorlauftemperatur vergleichen). Aber ohne Multigraphen ist das etwas schwierig. :confused:

Vielleicht sehen die Macher ja eine Möglichkeit bei soviel Resonanz das Thema auf der Prio-Liste etwas nach oben zu schieben.

Ich würde mich freuen. :smiley:

Gruß Schwede

Hi,
Bin gerade dabei „Open Flash Chart“ einzubinden.
Ist an sich auch nicht so kompliziert, sodaß ich als absoluter PHP Anfänger mit etwas Hilfe schon meinen ersten Graphen darstelle :loveips:
Nun ist es so, daß ich die Werte der letzten 24 Stunden direkt aus der IPS SQLite DB auslese.
Diese Daten sind mit einem Zeitstempel versehen, der, wie wir hier festgestellt haben, nicht regelmäßig ist - Genau wie die Anzahl der Daten.
So wie ich es verstanden habe gibt es bei einer Änderung einen Eintrag in die DB und dazu den Zeitstempel der Änderung.
Die Daten werden also nicht alle 5 Minuten geloggt, sondern bei Bedarf.
Da sich die Temperatur mal schnell (Tür geöffnet) und mal langsam (Nachts alles geschlossen) ändert, sind auch die Zeitwerte unterschiedlich und nicht regelmäßig.
Ich bekomme z.B. folgende Werte:
10.02.2011 - 07:30:18
10.02.2011 - 07:32:19
10.02.2011 - 08:02:20

Man sieht also, daß die ersten beiden Werte 2 Minuten auseinander liegen, und die nächste Änderung erst wieder 30 Minuten später auftrat.
Open Flash Chart teilt die Zeitachse allerdings immer in gleichmäßige Abstände ein, sodaß die Grafik zeitlich nicht stimmt.
Kann mir jemand sagen wie ich mit dieser Datenbasis eine sinnvolle, regelmäßige Einteilung der Zeitachse vornehmen soll?

Danke Euch im Voraus !!!

Gruß
Michael

ich habe dieses Problem dadurch gelöst, das ich mir die Werte mit einem Scripttimer speicher und nicht bei Änderung. So habe ich , persönlich alle 5 min, einen Eintrag in der DB und meine Graphen haben eine gleichmäßige Einteilung

Grüße

Frank

Vielleicht gibt es ja doch Hoffnung für eine zeitnahe Implementierung :D:

Cebit 2011 (Beitrag von paresy)

Hab mal ein bischen mit RGraph gespielt.

Sind die Orginaldaten aus der Datenbank in einem Zeitraum von 24 Stunden.

Sieht doch gut aus.
Rechnest Du die Zeitstempel erst um oder macht das RGraph für Dich?

das ist der Originalzeitstempel.

$data3 = AC_GetAggregatedValues($archiveHandlerID, 49915 , 0, $starttime, $endtime, $limit);
foreach($data3 as $value3)
{
    $t3[] = strftime('%d.%m
%H:%M', intval($value3['TimeStamp']));
    $tr3 = array_reverse($t3);
    $v3[] = $value3['Max'];
    $vr3 = array_reverse($v3);
}
$valueString3 = "[".implode(",", $vr3)."]";
$timeString3 = "['".implode("','", $tr3)."']";
$toolTip3 = "['".implode("','", $vr3)."']";

Mir gefällt die neue Version von pChartsehr gut. Damit habe ich (und andere hier) früher Grafiken erzeugt. Nach dem PHP Versionwechsel lief die Library leider nicht mehr.

Aktuell bleibt abzuwarten, was vom IPS-Team kommt. Vielleicht ist dann unser eigener Integrationsaufwand eh’ erledigt.

Ein erster Versuch zur Info als Anhang :). Da geht noch deutlich mehr.

Aktuell bleibt abzuwarten, was vom IPS-Team kommt. Vielleicht ist dann unser eigener Integrationsaufwand eh’ erledigt.

Auch meine Meinung. Ich würde an Eurer Stelle da nicht ewig Zeit reinstecken. Externe Lösungen sind meist an PHP Versionen und Libs etc. gebunden. Ich warte lieber auf die IPS Lösung.

@ RWN

könntest du das script für deinen Graphen mal einstellen, schaut besser als meine bisherigen JGGraphen…
danke
ist das dann auch über die html box ifront tauglich?

Da gibt es nichts fertiges. Über eine HTMLBox ist auch nicht, ist eine eigene Seite.

Hi Rainer,

Danke für das Script.
Leider bin ich noch PHP Anfänfger und hatte schonmal die Frage gestellt was „AC_GetAggregatedValues“ macht - Ohne Antwort.

Ich nutze bei mir „AC_GetLoggedValues“.
Wo ist der Unterschied?

Wenn Du sagst „Das ist der orig Zeitstempel“ muss es ja heissen, daß RGraph die Zeiteinteilung für irregulare Daten selbst berechnet - Ist das so?

Michael

Hallo,

das Thema Multigraph hat auch mich bewegt, da nur so Informationen in einem sinnvollen Zusammenhang dargestellt und analysiert werden können. Ich habe mich schließlich für RRD entschieden, da RRD für Zeitreihen entwickelt wurde, sehr flexibel ist und vor allen Dingen sehr schnell. Da RRD in IPS (…leider) nicht weiter gepflegt wird, läuft das System außerhalb von IPS und wird über IPS_Execute() mit Daten versorgt. Der Nachteil der hohen Flexibilität von RRD ist die lange Lernkurve, welche man durchlaufen muß, um das System richtig zu nutzen. Das ist bei RRD jedoch nicht anders wie bei IPS selbst.

Die angehängten Dateien zeigen zwei Multigraph Beispiele (aktuelle Parameter meiner Viessmann Heizung und meiner Fotovoltaikanlage). Die Daten werden fortlaufend geloggt und alle 15 Sekunden in einer aktualisierten Grafik im IPS WebFront angezeigt. Auch wenn die Grafiken scheinbar überladen daherkommen, mir helfen die Darstellungen weiter :wink:

Für alle, die es interessiert, hier noch einige hilfreiche PHP Prozeduren zur Auswertung einer RRD Datenbank. Um auf die Daten zugreifen zu können verwende ich aus cacti die Funktion rrdtool_fetch() in einer etwas angepassten Form. Eine andere Funktion berechnet einige statistische Parameter und das Integral unter einer Kurve, z.B. zur Umrechnung der Sonneneinstrahlung in W/m2 über einen bestimmten Zeitraum in KWh/m2. Mit einer weiteren Funktion können RRD-Daten in eine CSV Datei zur weiteren Auswertung exportiert werden.

<?

/* Diverse RRD-Tools */ 

define("MAX_FETCH_CACHE_SIZE", 5);
$rrdtool = "c:/rrdtool/rrdtool.exe";
/* -----------------------------------------------------------------------------
   Funktion rrdtool_getStep...
   ermittelt die Schrittweite der Zeitintervalle einer RRD-Datenbank
----------------------------------------------------------------------------- */
function rrdtool_getStep ( $file ) {
	global $rrdtool;
	$debug = false;
   $para = "info $file";
	$result = IPS_Execute ( $rrdtool, $para, false, true );
	// print_r ( $result );
	$result_array = explode ( "
", $result );
	$step_array = explode ("=", $result_array[2] );
	// print_r ( $step_array[1] );
	return $step_array[1];
}

/* -----------------------------------------------------------------------------
	Funktion rrdtool_calculate...
	Die Funktion berechnet statistische Parameter für die Daten einer RRD bezogen
	auf die vorgegebene Startzeit, Endzeit und Auflösung. Das Ergebnis wird in
	einem Array zurückgegeben. Der Array enthält folgende Einzelwerte:
	"Minimum", "Maximum", "Durchschnitt", "Summe" und "Integral". Das Integral hat
	die Dimension Ds. Dabei steht "D" für die Dimension der gespeicherten Daten und
	"s" für Sekunden.
----------------------------------------------------------------------------- */
function rrdtool_calculate( $file, $dataname, $starttime, $endtime, $resolution = 0, $CF = "AVERAGE") {
	global $rrdtool;
	$debug = false;
	$fetch_array = rrdtool_fetch( $file, $starttime, $endtime, $resolution , $CF );
	$i = 0;
	foreach ($fetch_array as $array) {
		 // print_r($array);
	    if ($i == 0) { // Spaltenüberschriften
	      // finde Datenindex
	      $j = 0; $index = -1;
	      foreach($array as $data) {
	         if($data == $dataname) $index = $j;
	      	$j++;
	      }
	      if( $index == -1 ) return false;
	    }
	    // print_r ("Index: ".$index."
" );

		 if ($i == 2) {  // Daten-Array
		   // Breite der Zeitschritte für Integralberechnung ermitteln
		   $para = "info $file";
			$result = IPS_Execute ( $rrdtool, $para, false, true );
			$result_ar = explode ( "
", $result );
			$step_ar = explode ("=", $result_ar[2] );
			$timestep = $step_ar[1];
		   // print_r ("Timestep: ".$timestep."
" );
		   // Datenelemente der Spalte ermitteln und statistische Werte berechnen
			$j = 0; $integral = 0; $data_avg = 0; $data_sum = 0; $data_min = 0; $data_max = 0;
		   foreach($array[$index] as $data) {
		      // print_r ($data."
");
		      if ($j == 0) {
		      	$data_min = $data;
		      	$data_max = $data;
		      	$data_sum = $data;
		      	$data_prev = $data;
		      } else {
		         if ( $data_min > $data ) $data_min = $data;
		         if ( $data_max < $data ) $data_max = $data;
		         $data_sum += $data;
		         $integral +=( ( ( $data_prev + $data ) / 2 ) * $timestep );
		         $data_prev = $data;
		      }
		   	$j++;
		   }
		   // print_r ("Zähler: ".$j." - ".( $endtime - $starttime )."
" );
		   if ( $j > 0 ) $data_avg = $data_sum / $j;
		   return array( "Minimum" => $data_min, "Maximum" => $data_max, "Durchschnitt" => $data_avg,
							  "Summe" => $data_sum, "Integral" => $integral );
  		 }
		 $i++;
	}
} // end of rrdtool_calculate

/* -----------------------------------------------------------------------------
	Function rrdtool_fetch...
	rrdtool_function_fetch - given a data source, return all of its data in an array
   @arg $local_data_id - the data source to fetch data for
   @arg $start_time - the start time to use for the data calculation. this value can
     either be absolute (unix timestamp) or relative (to now)
   @arg $end_time - the end time to use for the data calculation. this value can
     either be absolute (unix timestamp) or relative (to now)
   @arg $resolution - the accuracy of the data measured in seconds
   @returns - (array) an array containing all data in this data source broken down
     by each data source item. the maximum of all data source items is included in
     an item called 'ninety_fifth_percentile_maximum'.
     Changes: In addition to "data_source_names" and "values" the array has been
     extended by "time_stamps" information.
----------------------------------------------------------------------------- */
function rrdtool_fetch($local_data_id, $start_time, $end_time, $resolution = 0, $CF = "AVERAGE") {
   //define("MAX_FETCH_CACHE_SIZE", 5);
	global $rrd_fetch_cache, $rrdtool;
	if (empty($local_data_id)) {
		return;
	}

	/* the cache hash is used to identify unique items in the cache */
	$current_hash_cache = md5($local_data_id . $start_time . $end_time . $resolution);

	/* return the cached entry if available */
	if (isset($rrd_fetch_cache[$current_hash_cache])) {
		return $rrd_fetch_cache[$current_hash_cache];
	}

	$regexps = array();
	$fetch_array = array();

	// $data_source_path = get_data_source_path($local_data_id, true);
	$data_source_path = $local_data_id;

	/* build and run the rrdtool fetch command with all of our data */
	$cmd_line = "fetch $data_source_path $CF -s $start_time -e $end_time";
	if ($resolution > 0) {
		$cmd_line .= " -r $resolution";
	}

	$output = IPS_Execute( $rrdtool, $cmd_line, false, true );
	// print_r( $output."
" );
	/* grab the first line of the output which contains a list of data sources
	in this .rrd file */
	$line_one = substr($output, 0, strpos($output, "
"));

	/* loop through each data source in this .rrd file ... */
	if (preg_match_all("/\S+/", $line_one, $data_source_names)) {
		/* version 1.0.49 changed the output slightly */
		if (preg_match("/^timestamp/", $line_one)) {
			array_shift($data_source_names[0]);
		}

	$fetch_array["data_source_names"] = $data_source_names[0];

   // BUG FIX: if datasource contains UNDEFINED values, rrdtool returns NaN:
   // example: NaN 8.0000000000e-02 1.3333333333e-02 NaN

   // Because of this, the following regexpressions will fail
   // FIX: replace all #IND with 0.0000000000e+000 before matching

   $output = preg_replace('/(NaN)/', '0.0000000000e+000', $output);
   
   // Because of this, the following regexpression will fail
   // FIX: replace all "," as in rrdtool 1.3.8 with "." for calculation
   
   $output = preg_replace('/,/', '.', $output);


		/* build a unique regexp to match each data source individually when
		passed to preg_match_all() */
		for ($i=0;$i<count($fetch_array["data_source_names"]);$i++) {
			$regexps[$i] = '/[0-9]+:\s+';

			for ($j=0;$j<count($fetch_array["data_source_names"]);$j++) {
				/* it seems that at least some versions of the Windows RRDTool binary pads
				the exponent to 3 digits, rather than 2 on every Unix version that I have
				ever seen */
				if ($j == $i) {
					$regexps[$i] .= '([\-]?[0-9]{1}\.[0-9]+)e([\+-][0-9]{2,3})';
				}else{
					$regexps[$i] .= '[\-]?[0-9]{1}\.[0-9]+e[\+-][0-9]{2,3}';
				}

				if ($j < count($fetch_array["data_source_names"])) {
					$regexps[$i] .= '\s+';
				}
			}
			$regexps[$i] .= '/';
		}
	}
	
	/* fetch all timestamps in the selected output ... */
	preg_match_all('/([0-9]+):\s+[\-]?[0-9]{1}\.[0-9]+e[\+-][0-9]{2,3}/', $output, $time_stamps);
	// print_r( $time_stamps );
	$fetch_array["time_stamps"] = $time_stamps[1];
	
	$max_array = array();

	/* loop through each regexp determined above (or each data source) */
	for ($i=0;$i<count($regexps);$i++) {
		$fetch_array["values"][$i] = array();

		/* match the regexp against the rrdtool fetch output to get a mantisa and
		exponent for each line */
		if (preg_match_all($regexps[$i], $output, $matches)) {
		// print_r( $matches ) ;

			//  every line returned from RRDtool is a match (should be a match!)
			//  next loop through all lines
			for ($j=0; ($j < count($matches[1])); $j++) {
				$line = ($matches[1][$j] * (pow(10,(float)$matches[2][$j])));

				array_push($fetch_array["values"][$i], ($line * 1));

				$max_array[$j][$i] = $line;
			}
		}
	}

	if (isset($fetch_array["data_source_names"])) {
		$next_index = count($fetch_array["data_source_names"]);

		$fetch_array["data_source_names"][$next_index] = "ninety_fifth_percentile_maximum";

		/* calculate the max for each row */
		for ($i=0; $i<count($max_array); $i++) {
			$fetch_array["values"][$next_index][$i] = max($max_array[$i]);
		}
	}

	/* clear the cache if it gets too big */
	if (sizeof($rrd_fetch_cache) >= MAX_FETCH_CACHE_SIZE) {
		$rrd_fetch_cache = array();
	}

	/* update the cache */
	if (MAX_FETCH_CACHE_SIZE > 0) {
		$rrd_fetch_cache[$current_hash_cache] = $fetch_array;
	}

	return $fetch_array;
} // end of rrdtool_fetch()

/* -----------------------------------------------------------------------------
	Funktion rrdtool_export2CSV...
	liest die Daten einer RRD-Datenbank und schreibt die Informationen in
	eine EXCEL lesbare CSV-Datei mit den vorgegebenen Parameter Startzeit, Endzeit
	und Auflösung.
----------------------------------------------------------------------------- */
function rrdtool_export2CSV( $file, $starttime, $endtime, $resolution = 0, $CF = "AVERAGE", $verbose = false) {
   $debug = false;
   $filename = preg_replace('/\.rrd/', '.csv', $file);
   if (file_exists($filename)) { unlink($filename); }
   $datei = fopen($filename,"a");

	// RRD-Daten einlesen
	$fetch_array = rrdtool_fetch( $file, $starttime, $endtime, $resolution , $CF );
	$Spalten = count( $fetch_array['data_source_names'] );
	$Zeilen = count( $fetch_array['time_stamps'] );
	//if ( $debug ) print_r( "Anzahl Spalten : ".$Spalten."
Anzahl Zeilen  : ".$Zeilen."

" );
	//if ( $debug ) print_r( $fetch_array );

   // Bezeichnungen der Messwerte als Zeile aufbereiten
	$line = "Zeit;";
	for ($j = 0; $j < $Spalten; $j++ ) {
		$line .= $fetch_array['data_source_names'][$j];
		if ( $j < ( $Spalten - 1 ) ) $line .= ";";
	}
	if ( $verbose ) print_r( $line."
" );
	flock($datei,2);
   fputs($datei,$line."
");
   flock($datei,3);

   // Messwert-Zeilen spaltenweise generieren
	for ($i=0;$i<$Zeilen;$i++) {
		$line = "";
	   for ($j=0;$j<$Spalten;$j++) {
			if ( $j == 0 ) {
				$timestamp = (integer)$fetch_array['time_stamps'][$i];
				$line .= date("d.m.Y", $timestamp )." ".date("H:i:s", $timestamp).";";
			}
			$line .= strtr( $fetch_array['values'][$j][$i], ".", "," );
			if ( $j < ( $Spalten - 1 ) ) $line .= ";";
		}
      if ( $verbose ) print_r( $line."
" );
      flock($datei,2);
   	fputs($datei,$line."
");
   	flock($datei,3);
	}
   fclose($datei);
} // end of rrdtool_export2CSV()

?>

Beste Grüsse PWC