Hi,
ich möchte gerne meine Werte aus einer Wh Zähler Variable, in eine andere kWh Variable schreiben und archivieren. Ich nutze dieses Skript dafür:
<?php
$debug = TRUE;
$SourceID = 51246 ; //Variable mit Zählerwert "Gesamt - PV Ertrag Eingänge A+B" vom Wechselrichter
$TargetID = 56722; //Zielvariable
$ArchiveList = IPS_GetInstanceListByModuleID("{43192F0B-135B-4CE7-A0A7-1475603F3060}"); //Archivinstanzen abrufen
$ArchiveID = $ArchiveList[0]; // !!! Es wird die erste gefundene Archivinstanz verwendet
$StartDate="24.03.2022";
$EndDate = "27.03.2022";
if ($debug){$beginn = microtime(true); };
$d = 0;
$timestamp = 0;
$end = new DateTimeImmutable($EndDate);
$endtime = strtotime($end->format('Y-m-d H:i:s'));
$start = new DateTimeImmutable($StartDate);
$starttime = strtotime($start->format('Y-m-d H:i:s'));
//AC_DeleteVariableData($ArchiveID, $TargetID, 0, 0); //bei Aktivierung kann man die Archiv Ziel Variable löschen
AC_SetLoggingStatus($ArchiveID , $TargetID, true);
while ($starttime < $endtime){
$datetime = $start->modify('+'.$d.' day');
$starttime = strtotime($datetime->format('Y-m-d H:i:s'));
$datetime = $datetime->modify('+1 day');
$endarchive = strtotime($datetime->format('Y-m-d H:i:s'));
if ($debug){echo "Starttime: ".date('d.m.Y H:i:s', $starttime).PHP_EOL;};
$logData = AC_GetLoggedValues($ArchiveID, $SourceID, $starttime, $endarchive, 0); //Datensätze abfragen
$entries = count($logData); //Anzahl der Werte
if ($debug){echo "Einträge: ".$entries.PHP_EOL;};
if ($entries >0) {
for ($i = $entries; $i > 0; $i--){
$value = $logData[$i-1]['Value']/1000;
$timestamp = $logData[$i-1]['TimeStamp'];
AC_AddLoggedValues ($ArchiveID, $TargetID, [['TimeStamp' => $timestamp,'Value' => $value]]);
}
}
$d++;
}
//AC_SetAggregationType ($ArchiveID, $TargetID, 1);
//AC_ReAggregateVariable ($ArchiveID, $TargetID);
if ($debug){
$dauer = round(microtime(true) - $beginn,2);
echo "Verarbeitung des Skripts: $dauer Sek.";
}
Es ist zwar mühselig diese Umwandlung da ich immer nur ein paar Tage schreiben kann, da es ziemlich das System belastet. Jetzt habe ich schon des Öfteren festgestellt das er mir plötzlich bei manchem umwandeln bzw. Skript ausführen die Daten doppelt archiviert. Muss dann immer wieder von vorne anfangen, was mir allmählich die Lust raubt.
Weiß auch nicht warum das so ist, bei dem letzten mal ist mir aufgefallen das der Bildschirm auf Ruhemodus geschaltet hat und wie ich ihn wieder aktiviert habe war auch die Pro Konsole neu gestartet, also konnte nicht mehr ablesen wie lange das Skript gebraucht hat. Vielleicht ist es auch nur Zufall und hat nichts damit zu tun.
Gibt es den nicht die Möglichkeit diese doppelten Einträge zu löschen oder auch die Tage die es betrifft und das ich nicht wieder von vorne anfangen muss?
Wenn ich mir das Skript so anschaue, dann könnte es sein, dass Werte, die exakt auf 00:00 Uhr liegen doppelt geschrieben werden können, da du diese Zeit je einmal als Start- und einmal als Endzeit hast, da du immer von 00:00 Uhr bis 00:00 Uhr abfragst. Falls das zu deinem Fehler passt, dann müsstest du einfach die Endzeit auf 23:59:59 anpassen.
Darüber hinaus würde ich dir empfehlen, ein Array mit neuen Werten zu füllen und diese gebündelt als Eingabe von AC_AddLoggedValues zu verwenden. Führst du für jeden Wert einzeln die Funktion aus, treibt das die Ausführungszeit ungemein in die Höhe. Falls du mit sehr vielen Werten arbeitest, müsstest du vielleicht aber dennoch manches mal zwischendurch die Werte reinschieben, da der Speicher, den PHP nutzt nicht ausreichen könnte. Mehrere Tausend Werte sollten kein Problem darstellen, wenn du jetzt aber sekündlich geloggte Werte über mehrere Jahre übertragen möchtest, dann könnte es eng werden.
Hi,
Die Werte die er doppelt schreibt sind über die ganze Tageszeit verteilt und exakt immer zweimal vorhanden. Pro Tag sind es immer so ca. 3200 Werte.
@Dr.Niels
Das Skript ist jetzt abgeändert, aber ich bekomme jetzt die Memory Meldung wenn ich das Skript ausführe.
<?php
$debug = TRUE;
$SourceID = 51246 ; //Variable mit Zählerwert "Gesamt - PV Ertrag Eingänge A+B" vom Wechselrichter
$TargetID = 56722; //Zielvariable
$ArchiveList = IPS_GetInstanceListByModuleID("{43192F0B-135B-4CE7-A0A7-1475603F3060}"); //Archivinstanzen abrufen
$ArchiveID = $ArchiveList[0]; // !!! Es wird die erste gefundene Archivinstanz verwendet
$StartDate="23.04.2022";
$EndDate = "24.04.2022";
if ($debug){$beginn = microtime(true); };
$d = 0;
$timestamp = 0;
$end = new DateTimeImmutable($EndDate);
$endtime = strtotime($end->format('Y-m-d H:i:s'));
$start = new DateTimeImmutable($StartDate);
$starttime = strtotime($start->format('Y-m-d H:i:s'));
//AC_DeleteVariableData($ArchiveID, $TargetID, 0, 0); //bei Aktivierung kann man die Archiv Ziel Variable die Werte löschen
AC_SetLoggingStatus($ArchiveID , $TargetID, true);
while ($starttime < $endtime){
$datetime = $start->modify('+'.$d.' day');
$starttime = strtotime($datetime->format('Y-m-d H:i:s'));
$datetime = $datetime->modify('+1 day');
$endarchive = strtotime($datetime->format('Y-m-d H:i:s'));
if ($debug){echo "Starttime: ".date('d.m.Y H:i:s', $starttime).PHP_EOL;};
$logData = AC_GetLoggedValues($ArchiveID, $SourceID, $starttime, $endarchive, 0); //Datensätze abfragen
$entries = count($logData); //Anzahl der Werte
if ($debug){echo "Einträge: ".$entries.PHP_EOL;};
if ($entries >0) {
for ($i = $entries; $i > 0; $i--){
$value = $logData[$i-1]['Value']/1000;
$timestamp = $logData[$i-1]['TimeStamp'];
$data_array[] = ['TimeStamp' => $timestamp,'Value' => $value];
//AC_AddLoggedValues ($ArchiveID, $TargetID, [['TimeStamp' => $timestamp,'Value' => $value]]);
}
//print_r($data_array);
AC_AddLoggedValues ($ArchiveID, $TargetID, $data_array);
unset($data_array);
}
//break;
$d++;
}
//AC_SetAggregationType ($ArchiveID, $TargetID, 1);
//AC_ReAggregateVariable ($ArchiveID, $TargetID);
if ($debug){
$dauer = round(microtime(true) - $beginn,2);
echo "Verarbeitung des Skripts: $dauer Sek.";
}
Starttime: 23.04.2022 00:00:00
Einträge: 3932
Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 4194312 bytes) in /var/lib/symcon/scripts/57226.ips.php on line 45
Abort Processing during Fatal-Error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 4194312 bytes)
Error in Script /var/lib/symcon/scripts/57226.ips.php on Line 45
Ich habe in den Spezialschalter das Limit in ServerHardQueueBytesLimit schon um das doppelte erhöht.
Ne, hat leider nichts gebracht und bekomme jetzt die Meldung, dann ist das Skript so für die vielen Werte nicht zu gebrauchen:
Starttime: 23.04.2022 00:00:00
Einträge: 3932
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes) in /var/lib/symcon/scripts/57226.ips.php on line 45
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 12288 bytes) in /var/lib/symcon/scripts/IPSLibrary/app/core/IPSLogger/IPSLogger_Output.inc.php on line 28
Ok, es sind scheinbar zu viele Werte für ein einzelnes Array. Du könntest in deiner Schleife prüfen, ob du mittlerweile 5000 Werte (oder so) zusammen hast. Falls ja, schreibst du diese via AC_AddLoggedValues in die Datei und setzt dein Wertearray zurück auf ein leeres Array.