IPS 4.0 AC_GetAggregatedValues - Duration fehlt im Array

Hallo,

bei IPS 4.0 ist ja auch bei AC_GetAggregatedValues „Duration“ im Array wohl weggefallen … hat jemand ne Idee für mich was als Alternative herhalten könnte.Ich benutze es um die AN/AUS Dauer einer Boolean zu ermitteln.

Grüsse,
MaLu

Moin!

Kann es grad nicht überprüfen, aber spontan würde ich sagen > Einfach die Timestamp-Differenz zwischen den beiden Einträgen (an/aus) berechnen. Aktuell Wert minus Wert davor = Differenz/Duration.

Hat Paresy auch hier geschrieben:
genaue Definition und Berechnungslogik der Array-Werte aus AC_GetAggregatedValues
> Letzter Satz im Post

Grüße,
Chris

Hallo Chris,

bin nicht sicher ob ich es verstehe was Du meinst … ich meinte ich möchte die Gesamt-An-Zeit „AN“ Zeit einer Boolean in Sekunden, Minuten, Stunden, Tagen für einen freien wählbaren Zeitraum (innerhalb dieses Zeitraumes). z.B. gestern, heute, Monat, Woche, et.ermitteln. Wie schon geschrieben bisher habe ich Duration genutzt.

Danke und Grüsse,
Marcus

Du meinst du hast Avg * Duration genutzt? Duration ist sehr leicht selber zu berechnen. Für Stunde 3600, für Tag 24 * 3600 :wink:

paresy

Lol, wenn das so einfach ist … wieso haste Duration net dringelassen … mal ernst … :smiley:

Basierend auf,

Auswertung auf geloggte Variable: wielange AN? - Seite 2

wie muss ich denn - was multiplizieren… um die Duration zu ersetzen?

Als basierend auf dem AGG Level, oder?

Update: - War es net so das eigentlich … --> (TimeStamp - LastTime) sollte im Normalfall Duration ergeben.

Update 2: Innerhalb eines aktiven / „laufenden“ Zeitraums wie heute, woche, monat. Ist ja Duration als Wert nicht fix.

Grüsse,
Marcus

So, ich lach mich schlapp … .da war ja ein Fehler in der Duration … für meine Zwecke ist es net ganz so einfach … habe mal was zusammengemurkst … :smiley: Ma schauen

Hallo,

ich komme da nicht weiter, wie muss das Script denn jetzt richtig aussehen?

So ist es bisher:

       $start1    = mktime(00,00,0, date("m"), date("d") -1, date("Y")); //Startzeit - 1 Tage
       $ende1    = mktime(24,00,0, date("m"), date("d")    , date("Y")); //Endzeit

    $buffer1 = AC_GetAggregatedValues($archivID, $objectID,1,$start1, $ende1,0);

    $Gesamtlaufzeit1 = 0;
    foreach($buffer1 as $tag1 )
       {
//      echo "
" .  date('d.m.Y H:i:s',$tag1['TimeStamp']);

       $TagesAVG1 = ($tag1['Avg']);
        $Duration1 = ($tag1['Duration']/60/60);
        $Tageslaufzeit1 = ($TagesAVG1 * $Duration1);
//        echo " - " .$Tageslaufzeit1." Stunden " ;
      $Gesamtlaufzeit1 = $Gesamtlaufzeit1 + $Tageslaufzeit1;
       }

Hallo,

ich habe meinen Ansatz verworfen und nicht weitergemacht (da bei mir noch mehr net läuft unter 4.0) … da …

  1. Duration für eine „nicht abgeschlossene“ Periode z.B. den laufenden Tag - nicht Fix ist d.h. Stunden Basis Multiplizieren eigentlich berechnen wäre

  2. Das Werte bei „reiner“ Multiplizierung - eigentlich falsch sind / sein können - falls in dieser Zeit das System aus ist - da ja die ursprüngliche Duration ja diese Zeiten korrekt mitberücksichtigt hat d.h. Teilzeitraume die z.B. in einem Jahr erfasst wurden werden dann falsch berechnet z.B. wenn keine Daten erfasst wurden oder System aus ist. Für solche Zeiträume müsste man ja manuelle Korrekturen berücksichtigen oder Funktionen schreiben die das können - da habe ich aber keine Vorstellung im Moment wie.

:banghead:

Ich habe da schon Stunden reingehängt und immer mit den „vorherigen“ Werte verglichen - so bin ich draufgekommen - somit ist leider net so einfach - einfach multiplizieren. Mit geht es nicht darum irgendeinen Mist anzuzeigen - sondern das ich wenigstens selber glaube die Daten sind korrekt. :D:D:D

Ich bleibe dabei …

Bestandsfunktionen sind Bestandsfunktionen für Bestandskunden oder man liefert Ersatzfunktionen in php Form.

Grüsse,
MaLu

Also ich werde hier verrückt, ich verstehe es einfach nicht.

Ich will einfach nur ermitteln wie viele Stunden in Summe eine Boolean Variable heute auf auf True war.
Das kann doch nicht so schwer sein. Ich habe das mit AC_GetAggregatedValues versucht, aber irgendwie komme ich nicht zum Ziel.

Kann mir wieder jemand auf die Sprünge helfen?

Vor deinem Problem stand ich auch. Ich wollte die Laufzeit von diversen Geräten loggen.
Ob das mit AC_GetAggregatedValues klappt, kann ich dir nicht sagen. Wenn ich dich richtig verstehe, hat es vor 4.0 bei dir funktioniert und jetzt nicht mehr? Damit wäre ich jedenfalls out of PHP Kenntnis.
Mein bäuerlicher Workaround würde dann, frei gedacht, so aussehen, dass man mit einem Scripttrigger bei Variableänderung auf true eine Hilfsvariable mit dem Zeitstempel füllt und wiederrum ein Trigger beim Wechsel auf false hat, der aus dem Zeitpunkt die Zeit subtrahiert und die gelaufenen Sekunden oder Minuten in eine Variable wegspeichert, die als Zähler gepolt ist.

Ich habe das Problem am Pokeys mit PoBlocks gelöst. Wenn true, zählt ein SharedSlot die Sekunden hoch, die in IPS wandern - hier nochmal vielen Dank an Helmut, der mir dabei geholfen hat, bzw mir die fertige Lösung baute.

Ich bin aber blutiger Anfänger - also mag es sicher Lösungen für dein Problem geben, die mir fern sind;)

Gruß

Gibt es hier schon eine Lösung, ich brauche auch die Duration (gesamte Laufzeit von heute) von einer Pumpe. Warum schmeißt man solche Dinge wieder raus ?

Auch hier was zu dem Thema … Grüsse, MaLu

Das habe ich schon gesehen, da gibt es aber auch keine Lösung :slight_smile:

Funktionen löschen, ist aber kein Fortschritt für IPS.:cool:

Genau, deswegen bin ich auf 3.4 und warte seitdem auf die Rückkehr dieser Funktion. Grüsse, MaLu

Geht mir gleich…

Hallo,
anbei mein Codeschnipsel. Ich berechne mir die durchschnittliche Laufzeit des letzten Zeitabschnitts „dt“.

Wenn du verschiedene Laufzeiten brauchst (z.B. pro Stunde, pro Tag, pro Monat, etc.) musst du die Berechnung für jede Laufzeit (dt) explizit durchführen.

Ich lasse das Skript alle 15min durchlaufen und betrachte die Laufzeit der letzten 5h.

Viele Grüße
Wickie

		$wert = AC_GetAggregatedValues($ID_Archieve_Handler, $ID_Pin_FBH, $Agg_Stufe, time()-$dt,time(), 0);
		$anzahl = count($wert);
		if ($anzahl >1)
			{
			$wert_Sum = 0;
			for($j=0; $j < $anzahl; $j++)
			   {
					$wert_i =$wert[$j]['Avg'];
					$wert_Sum = $wert_Sum + $wert_i;
					//echo "
",$i," wert_i: ",$wert_i,"   wert_Sum: ",$wert_Sum, "
";
				}
			$wert_Avg = $wert_Sum / $anzahl;
			//echo "
"," anzahl: ",$anzahl,"   wert_Avg: ",$wert_Avg, "
";
			}

Die Variable Duration wurde entfernt, da sie keine zusätzlichen Informationen enthält und aus den existierenden Daten hergeleitet werden kann. Da diese Herleitung allerdings manchmal ein bisschen mühselig ist, habe ich zwei Skripte vorbereitet, die sich die aggregierten bzw. geloggten Daten einsammeln und um die ehemalige Duration erweitern:


function GetAggregatedValuesWithDuration($InstanceID, $VariableID, $AggregationSpan, $StartTime, $EndTime, $Limit){
 	$values = AC_GetAggregatedValues($InstanceID, $VariableID, $AggregationSpan, $StartTime, $EndTime, $Limit);
	foreach ($values as &$value){
		$start = new DateTime();
		$start->setTimestamp($value["TimeStamp"]);
		$end = new DateTime();
		
		//First, we round down the end time to the beginning of the interval
		//(The intervall will be added in a second step)
		$end->setTimestamp($value["TimeStamp"]);
		$end->modify("-" . $start->format("s") . " seconds"); //Set seconds to 0 for every aggregation
		//We use switch without break here, so every aggregation does everything below
		switch ($AggregationSpan){
			case 4: //Yearly
				$end->modify("-" . (intval($end->format("n")) - 1) . " months"); //Set month to January
			case 3: //Monthly
				$end->modify("-" . (intval($end->format("j")) - 1) . " days"); //Set day to first of month
			case 2: // Weekly
				if ($AggregationSpan == 2){ //Ensure that this only happens for weekly aggregation but not for yearly or monthly
					$end->modify("-" . (intval($end->format("N")) - 1) . " days"); //Set day to previous monday
				}
			case 1: // Daily
				$end->modify("-" . $end->format("G") . " hours"); //Set hours to 0
			case 0: //Hourly
				$end->modify("-" . $end->format("i") . " minutes"); //Set minutes to 0
			case 5: //Five minutes
				//Set minutes to previous full five minutes
				//Does nothing if minutes were already set to 0 as 0 is full five minutes 
				$end->modify("-" . (intval($end->format("i")) % 5) . " minutes"); 
		}
		
		switch ($AggregationSpan){
			case 0: //Hourly
				$end->modify("next hour");
				break;
			case 1: //Daily
				$end->modify("next day");
				break;
			case 2: //Weekly
				$end->modify("next week");
				break;	
			case 3: //Monthly
				$end->modify("next month");
				break;	
			case 4: //Yearly
				$end->modify("next year");
				break;	
			case 5: //Every five minutes
				$end->modify("+5 minutes");
				break;	
			case 6: //Minutely
				$end->modify("next minute");
				break;	
		}
		
		if ($end->getTimestamp() > time()){
			$end->setTimestamp(time());
		}
		
		$value["Duration"] = $end->getTimestamp() - $start->getTimestamp();
	}
	return $values;
 }


 
 function GetLoggedValuesWithDuration($InstanceID, $VariableID, $StartTime, $EndTime, $Limit){
 	$values = AC_GetLoggedValues($InstanceID, $VariableID, $StartTime, $EndTime, $Limit);
	//Loop over all except the last element, which needs special handling
	for ($i = 0; $i < sizeof($values) - 1; $i++){
		$values[$i]["Duration"] = $values[$i]["TimeStamp"] - $values[$i + 1]["TimeStamp"];
	}
	
	if (sizeof($values) > 0){
		$previous = AC_GetLoggedValues($InstanceID, $VariableID, 0, $StartTime - 1, 1);
		
		if (sizeof($previous) == 0){ //No previous value exists
			$values[sizeof($values) - 1]["Duration"] = 0;
		} else {
			$values[sizeof($values) - 1]["Duration"] = $values[sizeof($values) - 1]["TimeStamp"] - $previous[0]["TimeStamp"];
		}
	}
	return $values;
 }

Die beiden Funktionen GetAggregatedValuesWithDuration und GetLoggedValuesWithDuration benutzen das gleiche Interface wie die entsprechenden AC_-Gegenstücke. Mit den Skripten kann also die alte Funktionalität der Duration weiter genutzt werden ohne im Normalfall diese als Ballast mitzuschleppen.

Ich sollte abschließend noch erwähnen, dass die Funktionen nur grundlegende Tests hinter sich haben. Es ist also möglich, dass sie in komplexeren Edge-Cases wie z.B. Zeitumstellung nicht funktionieren. In solchen Fällen freue ich mich über Feedback und passe das Skript gerne an.

Ich wünsche viel Spaß damit!

Wieso als Ballast mitzuschleppen. ?

Jetzt muß der User den Ballast mitschleppen, in dem er eine weiter Variable loggen muß.

Warum lässt man nicht einfach solche Funktion in IPS drin. ?
Oder muß der IPS User auch damit rechnen das IPS irgendwann mal ganz gelöscht wird weil es Ballast ist ! :smiley:

Auch in der aktuellen Version musst du überhaupt nichts loggen um an die Duration zu kommen. Die wird zwar nicht explizit abgespeichert, ist aber aus den geloggten Daten herleitbar. Daher ist es „Ballast“. Die Duration bietet keine zusätzlichen Informationen, die nicht sowieso schon vorhanden sind. Es ist halt nur komplizierter die Duration zu ermitteln.

Aber dafür hast du ja jetzt die zwei Skripte, die dir diese Aufgabe abnehmen und die du benutzen kannst um wie in alten Versionen auf die Duration zuzugreifen. Und das ganz ohne zusätzliches Logging einer weiteren „Duration“-Variablen.

Hallo Dr. Niels,

Danke für die „Skripte“ - stellst Du mir nun mein System komplett kostenlos mit Deiner Zeit um? Prüfst Du dann auch vorher / nachher - ob alles auch passt und keine Edge Cases drin sind. Wieso sollen eigentlich immer die User den Zeitaufwand haben?

Soso, „grundlegende Tests“ … alle bisher zur Verfügung gestellten Lösungen (auch die von paresy) haben in den verschiedenen Situation - falsche Werte ermittelt - Nein, keine exotischen „Corner Cases“ - echte Variablen - mit echten Daten - gewachsen halt in der Hausautomation - siehe andere Threads. Sorry, wenn ich was Anzeige sollte es auch passen - net nur ein bisschen oder halt ab und zu oder je nach Variable.

Nu echt? Ich soll nochmal sicherstellen das die Daten die ich so Anzeige und benutze korrekt sind - also jeder soll sein System validieren - :smiley: - Ihr seid echt lustig.

Der letzte Versuch auf eine 4.x - wie paresy - ja noch sicher gut in Erinnerung hat - war ein Desaster - ungeachtet der Duration. Mehr als 20 Stunden Tests (immer und immer Backup, Upgrade mit Datenbankkonvertierung, Test, Downgrade, Restore) inklusive Duration investiert um dann doch zu erkennen das es net funktioniert.

Egal, bleibe dabei - das Duration war ja kein Feature Request - sondern Ihr habt eine Bestandsfunktion entfernt.

Danke und Grüsse,
MaLu