Tages u. Monatswerte aus dem Archiv für den tatsächlichen Stromverbrauch errechnen

Hallo,
ich möchte mir gerne aus den Archivdaten von Variablen meines Wechselrichters einige Tages und Monats Werte errechnen für den tatsächlichen Stromverbrauch. Der Wechselrichter hat Werte für den Ertrag, Einspeisung u. Netzverbrauch (Tag/Monat).

Die jetzigen Werte habe ich seit gestern folgender Maßen errechnet:

$idVariableErtag = 42753; //Variable Gesamt Ertrag am Tag
$idVariableEinspeisung = 41947; //Variable Einspeisung am Tag
$idVariableNetzverbrauch = 38959; //Variable Netzverbrauch am Tag
$result = (GetValue($idVariableErtag) - GetValue($idVariableEinspeisung) + GetValue($idVariableNetzverbrauch)) /1000; //Ergebnis des Gesamt Stromverbrauches am Tag in kWh

SetValue(56343, $result); //Errechneten Wert in die Variable schreiben

Jetzt komme ich aber nicht weiter wie das Skript aussehen muss um mir Tag X/Monat X aus meinen geloggten Werten zu errechnen.

Die einfache Sache für den Ertrag/Einspeisung etc. errechne ich mit dem Modul „Verbrauch in Zeitspanne“, aber damit kann ich ja nicht den tatsächlichen Stromverbrauch anzeigen lassen.

VG
Stefan

Vielleicht sowas hier:

$ArchiveList = IPS_GetInstanceListByModuleID("{43192F0B-135B-4CE7-A0A7-1475603F3060}"); // Archivinstanzen abrufen
$ArchiveID = $ArchiveList[0]; // !!! Es wird die erste gefundene Archivinstanz verwendet

//Alle gestrigen Datensätze abfragen
$werte = AC_GetLoggedValues($ArchiveID, IPS_GetParent($_IPS['SELF']), strtotime("yesterday 00:00"), strtotime("today 00:00")-1, 0); //55554 ist die ID der Variable, 12345 vom Archiv Control

//print_r($werte);

$anzahl = count($werte); // Anzahl an Werten im Archiv

echo "Werte gestern: ".$anzahl.PHP_EOL;

$ende = $werte[0]['Value']; // Letzer Tageswert
echo "Letzer Wert: ".$ende.PHP_EOL;

$start = $werte[$anzahl-1]['Value']; // Erster Tageswert
echo "Erster Wert: ".$start.PHP_EOL;

$diff = $ende - $start; // Differenz berechnen

echo "Differenz: ".$diff.PHP_EOL;

Für deine Rechnung musst du natürlich die drei Variablen im Archiv abfragen und genau so verrechnen, wie vorher.

Grüße
Stefan

Moin Moin,
Danke dir für das Skript. Habe schon mal den gestrigen Wert errechnet damit und funktioniert so. Wenn ich aber einen anderen Tag machen möchte wie passe ich das Skript an das er mir z.B. den 12.07.2022 errechnet. Das wird ja hier angegeben denke ich mal:

strtotime("yesterday 00:00"), strtotime("today 00:00")-1, 0)

Edit: Habe mal gerade wieder in der Doku geschaut und passe mal das Skript an und versuche es z.B. für ein Jahr.

$werte = AC_GetLoggedValues(12345, 55554, mktime(0, 0, 0, 1, 1, 2013), mktime(23, 59, 59, 1, 7, 2013), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control

Mit einer Zeile über ein Jahr wird es Probleme geben, da das Limit erreicht wird.
Da müsste man eher für den ersten Tag und für den letzten Tag die Werte holen und dann eben vom ersten Tag den ersten Wert und vom letzten Tag den letzten Wert verrechnen.
Um die Abfrage weniger belastend für das System zu machen könnte man die Zeit noch einschränken - da kommt es drauf an, wie oft neue Werte im Archiv aufkommen wenn z.B. Nachts kein neuer Ertragswert kommt.

Grüße
Stefan

Boah, jetzt haste mich liegen :fearful:

Was ich noch machen könnte das ich die Werte immer Monat für Monat nehme, was mir ja eigentlich reichen würde. Wer braucht schon den Verbrauch von jedem Tag.

Hier mal ein Beispiel für letztes Jahr:

$ArchiveList = IPS_GetInstanceListByModuleID("{43192F0B-135B-4CE7-A0A7-1475603F3060}"); // Archivinstanzen abrufen
$ArchiveID = $ArchiveList[0]; // !!! Es wird die erste gefundene Archivinstanz verwendet

//Alle gestrigen Datensätze abfragen
$werte_start = AC_GetLoggedValues($ArchiveID, IPS_GetParent($_IPS['SELF']), strtotime("2021-01-01 00:00:00"), strtotime("2021-01-01 23:59:59"), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control
$werte_ende = AC_GetLoggedValues($ArchiveID, IPS_GetParent($_IPS['SELF']), strtotime("2021-12-31 00:00:00"), strtotime("2021-12-31 23:59:59"), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control
//print_r($werte);

$anzahl_start = count($werte_start); // Anzahl an Werten im Archiv

echo "Werte Starttag: ".$anzahl_start.PHP_EOL;

$start = $werte_start[$anzahl_start-1]['Value']; // Erster Tageswert
echo "Erster Wert: ".$start.PHP_EOL;

$ende = $werte_ende[0]['Value']; // Letzer Tageswert
echo "Letzer Wert: ".$ende.PHP_EOL;

$diff = $ende - $start; // Differenz berechnen

echo "Differenz: ".$diff.PHP_EOL;

Soll es das aktuelle Jahr sein, muss beim Enddatum eben today drin stehen.

Das wäre das Ergebnis:

Werte Starttag: 0

Notice: Undefined offset: -1 in /var/lib/symcon/scripts/59704.ips.php on line 15

Notice: Trying to access array offset on value of type null in /var/lib/symcon/scripts/59704.ips.php on line 15
Erster Wert: 

Notice: Undefined offset: 0 in /var/lib/symcon/scripts/59704.ips.php on line 18

Notice: Trying to access array offset on value of type null in /var/lib/symcon/scripts/59704.ips.php on line 18
Letzer Wert: 
Differenz: 0

Dann sind für diesen Tag 1.Jan.2021 keine Werte im Archiv.

Ja, stimmt. Die Anlage läuft ja erst seit 10/2021, aber nimmt er dann nicht automatisch das nächstmögliche Datum das Werte enthält?

Habe es mal angepasst:

$werte_start = AC_GetLoggedValues(13449, 14939, strtotime("2022-07-01 00:00:00"), strtotime("2022-07-01 23:59:59"), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control
$werte_ende = AC_GetLoggedValues(13449, 14939, strtotime("2022-07-31 00:00:00"), strtotime("2022-07-31 23:59:59"), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control

Ergebnis:

Werte Starttag: 4728
Erster Wert: 5
Letzer Wert: 0
Differenz: -5

Es liegen also Tageswerte im Archiv und es ist kein Zähler, der den Gesamtertrag aufsummiert, sehe ich das richtig?

Das würde die Sache in diesem Fall VIEL einfacher machen :wink:

Hab vielleicht die falsche Variable gewählt. Habe jetzt mal die betroffene Variable eingefügt.

Die Gesamt Ertrag Variable wird als Zähler geloggt.
Die beiden anderen Gesamt Einspeisung und Gesamt Netzverbrauch werden nicht als Zähler geloggt. Alle liegen als Tageswerte vor.

Jetzt das Skript mit dem Gesamt Ertrag für den Monat Juli:

<?php

$ArchiveList = IPS_GetInstanceListByModuleID("{43192F0B-135B-4CE7-A0A7-1475603F3060}"); // Archivinstanzen abrufen
$ArchiveID = $ArchiveList[0]; // !!! Es wird die erste gefundene Archivinstanz verwendet

//Alle gestrigen Datensätze abfragen
$werte_start = AC_GetLoggedValues(13449, 51246, strtotime("2022-07-01 00:00:00"), strtotime("2022-07-01 23:59:59"), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control
$werte_ende = AC_GetLoggedValues(13449, 51246, strtotime("2022-07-31 00:00:00"), strtotime("2022-07-31 23:59:59"), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control
//print_r($werte);

$anzahl_start = count($werte_start); // Anzahl an Werten im Archiv

echo "Werte Starttag: ".$anzahl_start.PHP_EOL;

$start = $werte_start[$anzahl_start-1]['Value']; // Erster Tageswert
echo "Erster Wert: ".$start.PHP_EOL;

$ende = $werte_ende[0]['Value']; // Letzer Tageswert
echo "Letzer Wert: ".$ende.PHP_EOL;

$diff = $ende - $start; // Differenz berechnen

echo "Differenz: ".$diff.PHP_EOL;

$result = $diff /1000;


SetValue(42249, $diff);
SetValue(18413, $result);

Ergebnis:

Werte Starttag: 4315
Erster Wert: 5744940
Letzer Wert: 7444451
Differenz: 1699511

Dieser Wert stimmt bis auf die letzten drei stellen mit dem Ergebnis des „Zeitspanne“ Moduls überein.

Wenn Tageswerte vorhanden sind, kannst du mal folgendes testen:

// Achtung!!! Daten der Zielvariable werden beim ersten Durchlauf vollständig gelöscht! 
$debug = TRUE;

$ErtragID = 19810 ; 
$BezogenID = 37629;
$GeliefertID = 54990;
$TargetID = 45325; 

$StartDate="07.09.2022"; // Für den ersten Durchlauf

$ArchiveList = IPS_GetInstanceListByModuleID("{43192F0B-135B-4CE7-A0A7-1475603F3060}"); // Archivinstanzen abrufen
$ArchiveID = $ArchiveList[0]; // !!! Es wird die erste gefundene Archivinstanz verwendet


// -------------------------------- Ende Konfigurationsteil -----------------------------------------
if ($debug){$beginn = microtime(true); };
$d = 0;
$timestamp = 0;

$varID = @IPS_GetObjectIDByIdent('Timestamp', $_IPS['SELF']);

if ($varID == FALSE){
if ($debug){echo "Erster Durchlauf".PHP_EOL;}   

$start = new DateTimeImmutable($StartDate);
$starttime = strtotime($start->format('Y-m-d H:i:s'));

//AC_DeleteVariableData($ArchiveID, $TargetID, 0, 0);
//AC_SetLoggingStatus($ArchiveID , $TargetID, true);

while ($starttime < strtotime('today')){

    $datetime = $start->modify('+'.$d.' day');
    $starttime = strtotime($datetime->format('Y-m-d 00:00:00'));
    $endtime = strtotime($datetime->format('Y-m-d 23:59:59'));

    if ($debug){echo "Starttime: ".date('d.m.Y H:i:s', $starttime).PHP_EOL;};

    $logData = AC_GetLoggedValues($ArchiveID, $ErtragID,  $starttime, $endtime, 0); //Datensätze abfragen
    $entries = count($logData);// Anzahl der Werte
    if ($debug){echo "Einträge: ".$entries.PHP_EOL;};
    if ($entries >0) {
        $ertrag = $logData[$entries - 1]['Value']; 
        if ($debug){echo "Ertrag: ".$ertrag.PHP_EOL;}
        
        $logData = AC_GetLoggedValues($ArchiveID, $BezogenID,  $starttime, $endtime, 0); //Datensätze abfragen
        $entries = count($logData);// Anzahl der Werte
        if ($debug){echo "Einträge: ".$entries.PHP_EOL;};
        if ($entries >0) {
            $bezogen = $logData[$entries - 1]['Value'];
            if ($debug){echo "Bezogen: ".$bezogen.PHP_EOL;}
            
            $logData = AC_GetLoggedValues($ArchiveID, $GeliefertID,  $starttime, $endtime, 0); //Datensätze abfragen
            $entries = count($logData);// Anzahl der Werte
            if ($debug){echo "Einträge: ".$entries.PHP_EOL;};
            if ($entries >0) {
                $geliefert = $logData[$entries - 1]['Value']; 
                if ($debug){echo "Geliefert: ".$geliefert.PHP_EOL;}
                $verbrauch = $ertrag - $geliefert + $bezogen; //Ergebnis des Gesamt Stromverbrauches am Tag in kWh
                if ($debug){echo "Verbrauch: ".$verbrauch.PHP_EOL;}
            }
        }
    }

    
    $d++;
    if ($debug){echo "-------------------------------".PHP_EOL;};
}
    if ($debug){
        $dauer = round(microtime(true) - $beginn,2); 
        echo "Verarbeitung des Skripts: $dauer Sek.";
    }
}

Das Ergebnis:

Erster Durchlauf
Starttime: 07.09.2022 00:00:00
Einträge: 3587
Ertrag: 9061889
Einträge: 92
Bezogen: 624163
Einträge: 674
Geliefert: 5376874
Verbrauch: 4309178
-------------------------------
Starttime: 08.09.2022 00:00:00
Einträge: 3448
Ertrag: 9088108
Einträge: 74
Bezogen: 624255
Einträge: 774
Geliefert: 5385793
Verbrauch: 4326570
-------------------------------
Starttime: 09.09.2022 00:00:00
Einträge: 653
Ertrag: 9113748
Einträge: 23
Bezogen: 624329
Einträge: 5
Geliefert: 5395408
Verbrauch: 4342669
-------------------------------
Verarbeitung des Skripts: 0,03 Sek.

Also doch Zähler, die aufsummiert werden.
Einfach aber nicht recht sauber:

// Achtung!!! Daten der Zielvariable werden beim ersten Durchlauf vollständig gelöscht! 
$debug = TRUE;

$ErtragID = 19810 ; 
$BezogenID = 37629;
$GeliefertID = 54990;
$TargetID = 45325; 
$StartDate="07.09.2022"; // Für den ersten Durchlauf

$ArchiveList = IPS_GetInstanceListByModuleID("{43192F0B-135B-4CE7-A0A7-1475603F3060}"); // Archivinstanzen abrufen
$ArchiveID = $ArchiveList[0]; // !!! Es wird die erste gefundene Archivinstanz verwendet


// -------------------------------- Ende Konfigurationsteil -----------------------------------------
if ($debug){$beginn = microtime(true); };
$d = 0;
$timestamp = 0;

$varID = @IPS_GetObjectIDByIdent('Timestamp', $_IPS['SELF']);

if ($varID == FALSE){
if ($debug){echo "Erster Durchlauf".PHP_EOL;}   

$start = new DateTimeImmutable($StartDate);
$starttime = strtotime($start->format('Y-m-d H:i:s'));

//AC_DeleteVariableData($ArchiveID, $TargetID, 0, 0);
//AC_SetLoggingStatus($ArchiveID , $TargetID, true);

while ($starttime < strtotime('-2 day')){

    $datetime = $start->modify('+'.$d.' day');
    $starttime = strtotime($datetime->format('Y-m-d 00:00:00'));
    $endtime = strtotime($datetime->format('Y-m-d 23:59:59'));

    if ($debug){echo "Starttime: ".date('d.m.Y H:i:s', $starttime).PHP_EOL;};

    $logErtrag = AC_GetLoggedValues($ArchiveID, $ErtragID,  $starttime, $endtime, 0); //Datensätze abfragen
    $entriesErtrag = count($logErtrag);// Anzahl der Werte
    //if ($debug){echo "Einträge: ".$entriesErtrag.PHP_EOL;};
    if ($entriesErtrag >0) {
        $ertrag = $logErtrag[0]['Value']; 
        
        $logBezogen = AC_GetLoggedValues($ArchiveID, $BezogenID,  $starttime, $endtime, 0); //Datensätze abfragen
        $entriesBezogen = count($logBezogen);// Anzahl der Werte
        //if ($debug){echo "Einträge: ".$entriesBezogen.PHP_EOL;};
        if ($entriesBezogen >0) {
            $bezogen = $logBezogen[0]['Value'];
            
            
            $logGeliefert = AC_GetLoggedValues($ArchiveID, $GeliefertID,  $starttime, $endtime, 0); //Datensätze abfragen
            $entriesGeliefert = count($logGeliefert);// Anzahl der Werte
            //if ($debug){echo "Einträge: ".$entriesGeliefert.PHP_EOL;};
            if ($entriesGeliefert >0) {
                $geliefert = $logGeliefert[0]['Value']; 
                
                if (isset($geliefert_alt) === FALSE){
                    $ertrag_alt = $logErtrag[$entriesErtrag-1]['Value'];
                    $geliefert_alt = $logGeliefert[$entriesGeliefert-1]['Value'];
                    $bezogen_alt = $logBezogen[$entriesBezogen-1]['Value'];
                }
                $verbrauch = ($ertrag - $ertrag_alt) - ($geliefert - $geliefert_alt) + ($bezogen - $bezogen_alt); //Ergebnis des Gesamt Stromverbrauches am Tag in kWh
                if ($debug){echo "Ertrag: ".($ertrag - $ertrag_alt).PHP_EOL;}
                if ($debug){echo "Bezogen: ".($bezogen - $bezogen_alt).PHP_EOL;}
                if ($debug){echo "Geliefert: ".($geliefert - $geliefert_alt).PHP_EOL;}

                $ertrag_alt = $ertrag;
                $geliefert_alt = $geliefert;
                $bezogen_alt = $bezogen;
                if ($debug){echo "Verbrauch: ".$verbrauch.PHP_EOL;}
            }
        }
    }

    
    $d++;
    if ($debug){echo "-------------------------------".PHP_EOL;};
}
    if ($debug){
        $dauer = round(microtime(true) - $beginn,2); 
        echo "Verarbeitung des Skripts: $dauer Sek.";
    }
}


Die Archivierung der zwei Variablen steht auf Standard, außer wie schon erwähnt der Ertrag ist Zähler, es sei dann das RCT Modul macht die Summierung.

Von den Werten her sind es Zähler. Ich würde hier auch die Aggregation auf Zähler ändern, das geht jederzeit und kann auch rückgängig gemacht werden. Bei Aggregation Standard würde man ja ein Liniendiagramm bekommen, welches kontinuierlich ansteigt. Mit Zähler bekommt man Balkendiagramme mit denen man schon mal schön den Ertrag für Stunde/Tag/Woche, usw bekommt.

Ergebnis:

Erster Durchlauf
Starttime: 07.09.2022 00:00:00
Ertrag: 26218
Bezogen: 91
Geliefert: 8918
Verbrauch: 17391
-------------------------------
Starttime: 08.09.2022 00:00:00
Ertrag: 25640
Bezogen: 74
Geliefert: 9615
Verbrauch: 16099
-------------------------------
Verarbeitung des Skripts: 0,03 Sek.

Ok, stelle mal das Logging um.

Schaut nicht so schlecht aus das Ergebnis - die Einheiten stimmen wahrscheinlich noch nicht. Welche Einheiten haben die einzelnen Varialben?

Die Variablen sind alle in Wh