Problem: Variable aus Archiv auswerten

Hallo,

ich versuche eine Variable (Stromzähler Leistung Gesamt) auszuwerten.
Mich interressiert wann, wie lange, wie oft die Leistung über 12.000W lag, um die Kosten für einen Durchlauferhitzer auszurechnen. (die Last ist ansonsten von anderen Geräten nicht so hoch)

dazu habe ich folgendes Script aus der KI-Nase gezogen (leider wird solch ein Skript, bei mehrfacher Nachfrage, von der KI immer wieder an Stellen verändert nach denen ich gar nicht gefragt habe…)

im Moment sieht das Skript so aus:

<?php

// ID der zu überwachenden Variable
$variableID = 53769; // ID Ihrer Strom-Variablen

// Schwellenwert in Watt
$threshold = 12000;

// Zeitspanne die ausgewertet werden soll (Start- und Endzeitpunkt)
$startTime = strtotime("2024-04-29 00:00:00"); // Beispiel: Startzeit
$endTime = strtotime("2024-05-29 23:59:59"); // Beispiel: Endzeit

// Archive Control ID
$archiveID = 15951; // ID Ihrer Archiv-Instanz

// Kostenberechnung
$costPerKWh = 0.35; // Kosten pro kWh
$consumptionRate = 19; // Verbrauch in kWh pro Stunde bei Überschreiten des Schwellenwertes

// Lade alle geloggten Werte der Variablen innerhalb des Zeitraums
$logs = AC_GetLoggedValues($archiveID, $variableID, $startTime, $endTime, 0);

// Überprüfen, ob Logs korrekt geladen wurden
if ($logs === false || empty($logs)) {
    die("Fehler beim Laden der geloggten Daten oder keine Daten im angegebenen Zeitraum.\n");
}

// Variablen zur Zählung und zur Speicherung der Gesamtdauer
$overCount = 0;
$totalDuration = 0;
$overStart = 0;

// Durchlaufen aller geloggten Werte
foreach ($logs as $log) {
    $timestamp = $log['TimeStamp'];
    $value = $log['Value'];

    if ($value > $threshold) {
        if ($overStart == 0) {
            // Startzeit speichern, wenn der Schwellenwert überschritten wurde
            $overStart = $timestamp;
            $overCount++;
        }
    } else {
        if ($overStart != 0) {
            // Endzeit speichern und Dauer berechnen
            $totalDuration += $timestamp - $overStart;
            $overStart = 0;
        }
    }
}

// Falls am Ende der Log-Daten noch ein "über Schwellenwert"-Zustand ansteht, aktualisieren wir die Dauer
if ($overStart != 0) {
    $totalDuration += $endTime - $overStart;
}

// Konvertiere die Gesamtzeit in Stunden, Minuten und Sekunden (positive Werte)
$totalDurationHours = abs(floor($totalDuration / 3600));
$totalDurationMinutes = abs(floor(($totalDuration % 3600) / 60));
$totalDurationSeconds = abs($totalDuration % 60);

// Berechne die Stromkosten für die Zeit über dem Schwellenwert (positive Werte)
$totalDurationInHours = $totalDuration / 3600; // Gesamtdauer in Stunden
$totalCost = abs($totalDurationInHours * $consumptionRate * $costPerKWh);

echo "Der Wert lag $overCount Mal über dem Schwellenwert.\n";
echo "Die Gesamtzeit über dem Schwellenwert beträgt $totalDurationHours Stunden, $totalDurationMinutes Minuten und $totalDurationSeconds Sekunden.\n";
echo "Die geschätzten Stromkosten für diesen Zeitraum betragen: " . number_format($totalCost, 2) . " Euro.\n";

?>

die Auswertung so:
Der Wert lag 2 Mal über dem Schwellenwert.
Die Gesamtzeit über dem Schwellenwert beträgt 1 Stunden, 21 Minuten und 53 Sekunden.
Die geschätzten Stromkosten für diesen Zeitraum betragen: 2.31 Euro.

WERT stimmt nicht
Gesamtzeit stimmt nicht (die 1h kommt wohl vom UnixTimestamp, und 21min sind für 1 Monat viel zu wenig)
Kosten für 21min könnte passen (aber nur für die angegebenen 21min, welche ja nicht stimmen)

ich würde die KI gern mit dem Problem nerven aber oft kommt da viel Mist raus, deswegen muss ich euch nun fragen…

P.S.: eigentlich sollte parallel dazu noch ausgewertet werden ob zu dieser Zeit PV Überschuss vorhanden war, bzw. der Strom aus der Batterie kam… aber die Fragen hab ich erstmal gar nicht gestellt.

vllt hat jemand eine Idee oder es ist sogar noch viel einfacher umsetzbar… ich bin leider nur in der Lage, solche Skripte über eine KI zu erstellen bzw. mir helfen zu lassen

Ich habe mir gerade noch die Zeitpunkte der Schwellwertüberschreitung anzeigen lassen…

das kommt dabei raus:
Die Zeitpunkte des Überschreitens des Schwellenwerts waren:
2024-04-05 20:32:06
2024-04-05 20:28:35
2024-04-05 20:27:04
2024-04-05 20:25:48
2024-04-05 20:25:18
2024-04-05 07:05:00
2024-04-04 20:41:09

und das kann bei diesen Werten nicht sein:

$startTime = strtotime("2024-01-01 00:00:00"); // Beispiel: Startzeit
$endTime = strtotime("2024-04-05 23:59:59"); // Beispiel: Endzeit

wenn ich an den Werten rumspiele… kommen immer sowenig Überschreitungen… kann es sein, dass er nicht mehr Werte aus dem Archiv bekommt? (dann wären die angezeigten Werte wieder plausibel)

neuer Versuch:

$startTime = strtotime("2023-11-01 00:00:00"); // Beispiel: Startzeit
$endTime = strtotime("2024-03-05 23:59:59"); // Beispiel: Endzeit

Ergebnis:
Die Zeitpunkte des Überschreitens des Schwellenwerts waren:
2024-03-05 22:00:45
2024-03-05 09:57:26
2024-03-04 22:08:06
2024-03-04 21:58:17
2024-03-04 16:40:20
2024-03-04 12:50:59
2024-03-04 12:48:58
2024-03-04 12:06:06
2024-03-04 12:04:05
2024-03-04 11:59:48
2024-03-04 11:58:48
2024-03-04 10:44:31
2024-03-04 07:02:50
2024-03-04 06:36:55
2024-03-04 06:32:24

es scheint so, als wenn das Startdatum gar nicht beachtet wird, das Enddatum aber trotzdem ein Tag in die Vergangenheit zeigt :man_shrugging:

ich antworte mir nochmal selbst, zu Archivzwecken :grin:

ich hab hier mittlerweile ne Lösung, Perplexity war da wesentlich kompetenter als ChatGPT…

Das Script sucht im Archiv, von der ausgewählten Variablen (in diesem Fall der Hauptstromzähler), wann diese den Wert von 10000W überstiegen hat und wie lange. (2 Hilfsvariablen müssen angelegt werden Kosten & Zeit)

image

Script:

<?php

// ID der zu überwachenden Variable
$variableID = 53769;

// Schwellenwert in Watt
$threshold = 10000;

// Archiv-ID
$archiveID = 15951;

// Kostenparameter
$costPerKWh = 0.35;
$consumptionRate = 19;

// IDs der Zielgrößen zum Schreiben
$kostenVariableID = 27456; // float
$zeitVariableID = 24963;   // float (Zeit in Minuten)

// Berechnung des Vormonats-Zeitraums
$startTime = strtotime("first day of last month 00:00:00");
$endTime = strtotime("last day of last month 23:59:59");

// Gesamtergebnisse initialisieren
$gesamtDuration = 0;
$gesamtCount = 0;
$gesamtLogs = 0;

$aktStart = $startTime;

while ($aktStart < $endTime) {
    $aktEnde = strtotime('+1 day', $aktStart);
    if ($aktEnde > $endTime) {
        $aktEnde = $endTime;
    }

    $logs = AC_GetLoggedValues($archiveID, $variableID, $aktStart, $aktEnde, 0);

    $anzahlLogs = is_array($logs) ? count($logs) : 0;
    echo "Analyse Zeitraum: " . date('Y-m-d H:i', $aktStart) . " bis " . date('Y-m-d H:i', $aktEnde) . "\n";
    echo "Geladene Werte: $anzahlLogs\n";

    if ($anzahlLogs < 2) {
        echo "Wenig oder keine Daten, überspringe Zeitraum.\n\n";
        $aktStart = $aktEnde;
        continue;
    }

    usort($logs, function($a, $b) {
        return $a['TimeStamp'] <=> $b['TimeStamp'];
    });

    $totalDuration = 0;
    $overCount = 0;
    $wasOver = false;

    for ($i = 0; $i < $anzahlLogs -1; $i++) {
        $currentValue = $logs[$i]['Value'];
        $currentTime = $logs[$i]['TimeStamp'];
        $nextValue = $logs[$i+1]['Value'];
        $nextTime = $logs[$i+1]['TimeStamp'];

        $diff = $nextTime - $currentTime;
        if ($diff <= 0) continue;

        if ($currentValue > $threshold) {
            if (!$wasOver) {
                $overCount++;
                $wasOver = true;
            }
            $totalDuration += $diff;

            if ($nextValue <= $threshold) {
                $wasOver = false;
            }
        } else {
            $wasOver = false;
        }
    }

    $lastValue = $logs[$anzahlLogs - 1]['Value'];
    $lastTime = $logs[$anzahlLogs - 1]['TimeStamp'];

    if ($lastValue > $threshold && $aktEnde > $lastTime) {
        $totalDuration += $aktEnde - $lastTime;
    }

    $totalHours = $totalDuration / 3600;
    $hours = floor($totalDuration / 3600);
    $minutes = floor(($totalDuration % 3600) / 60);
    $seconds = $totalDuration % 60;
    $cost = $totalHours * $consumptionRate * $costPerKWh;

    echo "Anzahl Überschreitungen: $overCount\n";
    echo "Gesamtzeit über Schwellenwert: {$hours}h {$minutes}m {$seconds}s\n";
    echo "Geschätzte Kosten: " . number_format($cost, 2) . " Euro\n\n";

    $gesamtDuration += $totalDuration;
    $gesamtCount += $overCount;
    $gesamtLogs += $anzahlLogs;

    $aktStart = $aktEnde;
}

// Gesamtauswertung
$gesamtHours = floor($gesamtDuration / 3600);
$gesamtMinutes = floor(($gesamtDuration % 3600) / 60);
$gesamtSeconds = $gesamtDuration % 60;
$gesamtCost = ($gesamtDuration / 3600) * $consumptionRate * $costPerKWh;

// Zeit in Minuten als Float für die Variable
$gesamtDurationInMinutes = $gesamtDuration / 60;

echo "=== Gesamtauswertung ===\n";
echo "Gesamtzahl geladener Werte: $gesamtLogs\n";
echo "Gesamtanzahl Überschreitungen: $gesamtCount\n";
echo "Gesamtzeit über Schwellenwert: {$gesamtHours}h {$gesamtMinutes}m {$gesamtSeconds}s\n";
echo "Gesamtkosten: " . number_format($gesamtCost, 2) . " Euro\n";
echo "Gesamtzeit (Minuten als Float): " . number_format($gesamtDurationInMinutes, 2) . " min\n";

// Schreiben in IP-Symcon Variablen
SetValueFloat($kostenVariableID, $gesamtCost);
SetValueFloat($zeitVariableID, $gesamtDurationInMinutes);

?>

Ein Problem war das loggen der Variablen, wenn diese verdichtet wird… also das Script im Nachhinein über eine verdichteten Zeitraum laufen lassen wird nur Mist als Ergebnis bringen.

Wenn ich es aber Zeitnah laufen lasse und das Ergebnis in eine andere Variable schreibe, dann klappt es super.

Anhand der vielen Datensätze, Teilt das Script die Berechnungen auf und summiert es dann am Schluss. (der rpi hat wg. php Speicherproblemen immer abgebrochen)

das Ergebnis vom Durchlauferhitzer (August) sieht dann etwa so aus:

=== Gesamtauswertung ===
Gesamtzahl geladener Werte: 165600
Gesamtanzahl Überschreitungen: 125
Gesamtzeit über Schwellenwert: 1h 28m 18s
Gesamtkosten: 9.79 Euro
Gesamtzeit (Minuten als Float): 88.30 min

und Nein, wir stinken nicht es war Urlaubszeit :rofl:

ich möchte damit eigentlich nur abschätzen, ob es sich lohnt mal eine Brauchwasserwärmepumpe zu installieren oder nicht… im Moment scheint es wirtschaftlich nicht so sinnvoll…