Einschaltdauer aus geloggten Variablen berechnen

Hallo

ich logge in die interne DB die Statusvariablen von verschiedenen Schaltern.

jetzt möchte ich über einen definierten Zeitbereich gerne die kummulierte Einschaltdauer berechnen.

Hat da zufällig schon jemand etwas parat, oder muß ich mirs selbst zusammenstricken?

danke
bb

Folgende Funktion macht das, soweit ich mich erinnere. Habe ich irgendwann mal schnell runtergetippt und dann doch nicht benutzt ;).

function getLoggedValueDuration ($variableID, $tsStart, $tsEnd, $value)
{
    $duration = 0;

    $archiveHandlerID = IPS_GetInstanceListByModuleID('{43192F0B-135B-4CE7-A0A7-1475603F3060}');
    $archiveHandlerID = $archiveHandlerID[0];

    $data = AC_GetLoggedValues($archiveHandlerID, $variableID, time(), time(), 1);
    $openTs = count($data) > 0 ? $data[0]['TimeStamp'] : false;

    $data = AC_GetLoggedValues($archiveHandlerID, $variableID, $tsStart, $tsEnd, 100000);
    $isOpen = ($openTs !== false && count($data) > 0) ? ($openTs == $data[0]['TimeStamp']) : false;
    
    if (count($data) == 100000)
    {
        return false;
    }
    
    if (count($data) > 0)
    {
        if ($data[count($data) - 1]['TimeStamp'] < $tsStart)
        {
            $delta = $tsStart - $data[count($data) - 1]['TimeStamp'];
            $data[count($data) - 1]['TimeStamp'] = $tsStart;
            $data[count($data) - 1]['Duration'] = max(0, $data[count($data) - 1]['Duration'] - $delta);
        }

        if ($data[0]['TimeStamp'] + $data[0]['Duration'] > $tsEnd || $isOpen)
        {
            $data[0]['Duration'] = $tsEnd - $data[0]['TimeStamp'];
        }

        for ($i = 0, $j = count($data); $i < $j; $i++)
        {
            if ($data[$i]['Value'] == $value)
            {
                $duration += $data[$i]['Duration'];
            }
        }
    }

    return $duration;
}

PS: Ich garantiere nicht für Fehlerfreiheit ;).
PPS: Die Funktion bricht rein präventiv ab, wenn mehr als 100000 Datensätze für den Zeitraum vorhanden sind, und gibt dann false zurück. Wenn man solche Datenmengen verarbeiten will, sollte man sich ein geeigneteres Konzept überlegen.

Kann ich über einen ähnlichen Weg auch eine Tagessumme aus Float oder Integer bilden?

Tagessumme beim Counter? Da kannst Du doch direkt den Wert mit AC_GetAggregatedValues auslesen:

<?php
$variableID = 12345;

$archiveHandlerID = IPS_GetInstanceListByModuleID('{43192F0B-135B-4CE7-A0A7-1475603F3060}');
$archiveHandlerID = $archiveHandlerID[0];

$ts = mktime(0, 0, 0, 5, 20, 2011);

$data = AC_GetAggregatedValues($archiveHandlerID, $variableID, 1, $ts, $ts, 1);

if (count($data) == 1)
{
    print_r($data[0]);
}
?>

Hi Horst

danke für obiges Script, so in etwa hatte ich mir vorgestellt das ich es schreiben müßte. Wenn natürlich schon ein Draft da ist dann gehts leichter.

Werd heute Abend mal damit spielen.

Weil wir grad beim Thema sind:
Wie werden denn Boolsche Variablen aggregiert ? Vermutlich gar nicht, oder ?
Oder werden die wie Float betrachtet und es gibt einen Mittelwert über die Zeit ?

gruß
bb

Boolean, Integer und Float werden als Float-Mittelwert aggregiert. Dadurch kannst man dann schön sehen, dass die Pumpe das halbe Jahr lang gelaufen ist. Den Fall Boolean kann man deshalb auch effizienter Zeiträume lösen, indem man einfach AC_GetAggregatedValues benutzt und dann sum(Duration * Avg) für true und sum(Duration * (1 - Avg)) für false benutzt. Für Integer und Float wird das nichts, da man ja zwischen mehr als zwei Werten schwankt.

Da gab es doch mal ein ausgesprochen weit ausgeprägtes Script womit man Einschaltdauer, Energieverbrauch und so weiter darstellen konnte. Da konnte man die einzelnen AKtoren soweit konfigurieren dass man den Verbrauch entsprechend angezeigt bekam, die Einschalthäufigkeit gezählt wurde, Energieverbrauch und Kosten ebenfalls gleich mitgeloggt wurden. Trigger waren die entsprechenden Stati der Aktoren.

Ich hatte es mal laufen, es wurde aber irgendwann ersetzt. Klasse war es …weiss nur nicht mehr wo ich es hier gefunden hatte.

Gruss
B71

Da habe ich mich etwas unklar ausgedrückt. Min, Max und Avg sind irgendwie nicht die Tagessumme, oder?

    [Avg] => 7.35
    [Max] => 30
    [Min] => 0

Wie wird denn Avg berechnet?

Ich sammle ja gerade stündlich die Regenmenge (RR1) vom DWD ein. Den Tagesgesamtwert (RR24) würde ich dann gern auswerten.

Dann müsste ich nicht selber aufaddieren und nullen ;).

Ich weiß was du meinst, das Script war von mir :D:D:D
Läuft hier auch noch mehr oder weniger brav.
Liefert aber nur Endsummen und Events.

Als Plot Fan möchte ich die Daten nun aber zusätzlich hübsch grafisch darstellen.
Mit dem Highcharts Plot Modul müßte sich das einfach und optisch sehr ansprechend machen lassen.
Abgesehen von Balken und Torten soll auch noch der zeitlich kummulierte Verlauf von Verbräuchen während beliebiger Zeiträume dargestellt werden.

Mit meiner RRD Datenbank hatte ich da übrigens mal einen schönen Vorhersageplot gebaut. d.h. man sah optisch zu welchem Zeitpunkt ein bestimmter Schwellwert erreicht werden wird. Die RRD hat da nette eingebaute Funktionen für Vorhersagen.
Dafür ist sie leider für Events mit exakten Tiemstamp nicht so gut zu gebrauchen und bei weiterführenden Berechnungen der Daten recht sperrig.

Drum der Versuch mit der eingebauten DB.

gruß
bb

Hallo bbernhard,

magst Du uns noch einmal am Script teilhaben lassen. Ich suche eine Möglichkeit verschiedenen Leuchten und deren Nutzung mal zu visuallisieren.

Grüße, Stromer

Hi stromer

da ist das Post zum alten Script:
http://www.ip-symcon.de/forum/f53/betriebsstundenzaehler-mehr-8636/

Fürs neue rev 2.4 Webfront müßte man für gute Übersicht aber bisl was änderen, da sich die Kategorieen nicht mehr ausklappen lassen.

Weiters habe ich bemerkt das es zickig auf IPS Abstürze (Stromausfall) reagiert. Da stimmten dann die Summen von gerade aktiven Geräten nicht mehr.
Um dem vorzubeugen müßte irgendwie eine passende Resetlogik mit rein.
hatte aber keine Lust da noch mal hinzulangen.

gruß
bb

@ralf: Ich habe von einer Counter-Variable gesprochen. Dort ist Avg die Summe, Min der minimale Wert, der im Zeitraum geloggt worden ist und Max entsprechend der maximale Wert, der im Zeitraum geloggt worden ist. Da Du in Deinem Fall ja keine Zähler-Variable hast, musst Du entweder alles selbst zusammenzählen oder meine zuvor gepostete Funktion abwandeln und statt Duration dort Value addieren.

Habe ich inzwischen so gemacht.

Ich freue mich auf Sonntag, einige unbekannte Gesichter :cool:.