Wie funktionier AC_GetLoggedValues?

Hi,
ich habe ein Verständnisproblem bei obiger Funktion.

Ich will Daten einiger Variablen säubern, d.h. Ausreißer entfernen. Ich lese die Variablen wie folgt ein:


$logData = AC_GetLoggedValues ($ArchiveID, $VariableID, time() - 25000,time(), 0);
$entries = count($logData);
print $entries.PHP_EOL;

Ich verstehe es so das die Werte der Variablen $VariableID, und nur die, der letzten 25000 Sekunden in das array LogData geschrieben werden. Ich habe jetzt folgende Probleme:

  1. In den letzten 25000 Sekunden gab es 7 Einträge aber print gibt nur 2 aus.
  2. Wenn ich die Zeit auf 43200 (12 Stunden) erhöhe bekomme ich die Meldung das der OutputBuffer von 1MByte überschritten wurde obwohl immer noch nur 7 Einträge kommen sollten.

Wo ist mein Verständnisfehler?

Ralf

Hi,
warum auch immer jetzt hat AC_GetLoggedValues so funktioniert wie ich es erwartet habe. Als Ergebnis habe ich ein Script geschrieben das meine Verbrauchswerte (Variablen als Zähler) quasi Median filtert. Quasi weil es ein spezieller Filter für Verbrauchswerte ist. Verbrauchswerte können nur größer werden. Ich beachte 3 Werte und wenn Wert1 < Wert2 < Wert3 ist alles OK. Ist Wert1 > Wert2 < Wert3 oder Wert1 < Wert2 > Wert3 stimmt was nicht. Ich benutze Differenzen und habe eine Toleranz von 0.1 Wh weil die Werte rauschen können.

Hier das Filterscript:


<?php
// Keller
$summeID = 18122 /* ID der Variablen im Archive */;
filter_variable(32968, $summeID) /* ID der Archive-Instanz */;

function filter_variable($ArchiveID, $VariableID) {

//Alle Datensätze der letzten Stunden abfragen
    $logData = AC_GetLoggedValues($ArchiveID, $VariableID,  strtotime("yesterday 00:00"), time(), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control

// Anzahl der Werte
    $entries = count($logData);

// Macht erst ab 3 Werten Sinn
    if ($entries < 2) return;

// Anzahl der Fehler protokolieren
    $changes = 0;
    for ($i = 2; $i < $entries; $i++){

// Differenz Wert2-Wert1
        $diff1 = $logData[$i - 1]['Value'] - $logData[$i - 2]['Value'];

// Differenz Wert3-Wert2
        $diff2 = $logData[$i]['Value'] - $logData[$i - 1]['Value'];

// Wenn der mittlere Wert entweder der größte oder kleinste Wert ist stimmt was nicht
        if ((($diff1 < -0.1) && ($diff2 > 0.1)) ||
            (($diff1 > 0.1) && ($diff2 < -0.1))){ 

// lösche mittleren Wert
            AC_DeleteVariableData ($ArchiveID, $VariableID, $logData[$i - 1]['TimeStamp'] - 1, $logData[$i - 1]['TimeStamp'] + 1);

// Fehler in Logfile eintragen
            IPS_LogMessage("Medianfilter", $VariableID.' '.$changes.'. diff1:'.$diff1.' $diff2:'.$diff2); 

// eine Änderung mehr
            $changes++;
        }
    }

// Wenn es Änderungen gab
    if ($changes > 0){
// Variable neu aggregieren
        AC_ReAggregateVariable ($ArchiveID, $VariableID);
// Anzahl der Fehler ins Logfile
        IPS_LogMessage("Medianfilter", $VariableID.': Fehlerhafte Werte:'.$changes); 
    }
    else{
        IPS_LogMessage("Medianfilter", $VariableID.': Alles OK'); 
    }
}
?>

vielleicht kann es ja jemand gebrauchen.

Ralf

Hallo Ralf,
vielen Dank für dein Skript.
Ein kleiner Fehler ist in

if ((($diff1 < -0.1) && ($$diff2 > 0.1)) ||

Das doppelte $ bei diff2.

Wenn der erste Wert des Tages ein falscher ist, funktioniert es nicht. Wenn Fehlerhafte Werte im Wechsel mit guten Werten auftreten auch nicht - aber ist ja auch so beschrieben.

Mal sehen, ob ich noch was erweitern kann.

Hab momentan ein Problem mit einem Z-Wave Gerät. Ob das Gerät falsche Werte schickt? Ich denke, hier wird einfach keine CRC-Kontrolle durchgeführt, was zu den fehlerhaften Werten führt…

Bei solchen Fehlern sollte von Symcon einfach mehr kommen - aber was solls, da hab ich schon länger resigniert und meine Subscription auslaufen lassen…

Grüße
Stefan

Hi,
stimmt bei dem $ haben meine alten Hände wohl gezittert:-)

Das mit dem ersten Wert sollte eigentlich nicht passieren da ich überlappend arbeite, d.h. der erste Wert von „yesterday 00:00“ wurde schon vorher geprüft. Ich vergaß zu schreiben das ich das Script immer um 3:00am laufen lasse und somit werden 27 Stunden überprüft. Der worst case kann natürlich nicht klappen. Das Script ist nur für vereinzelte Ausreißer gedacht.

Ich habe gestern noch ein wenig weiter nachgedacht. Ein richtiger Median kann für Zähler eher nicht genommen werden. Wenn man auch den Fall von mehrere Fehlern hintereinander hat muss man einfach die Werte +/-2 oder +/-3 statt +/- 1 auseinander vergleichen.

Ralf

HI,

ich verstehe das Skript nicht ganz. Ich habe nur ein Archiv was ich korrigieren möchte.

Was ist $summeID und was ist filter_variable?

Ich hatte gehofft ich könnte ein Variable eingeben und er korrigiert das alle Werte im Archiv die nicht fortlaufend sind (am besten die letzten Jahre)

danke.

Hi,
Du gibst ja eine Variable an aber bei IPS ist das immer die Objekt-ID, d.h. die Zahl vor dem Namen. In den Kern-Instanzen findest Du das Archive und davor steht dann die Objekt-ID für das Archive. filter_variable ist nur ein Unterprogramm das dann aufgerufen wird. Ich habe es in ein Unterprogramm gepackt weil ich täglich 9 oder 10 Variablen filtern lasse.

Ich vergaß noch zu erwähnen das ich eine Meldung um Log eintrage die heute z.B. so aussah:


03.06.2020 03:00:00 | 00000 | CUSTOM  | Medianfilter         | 30980 0. diff1:-1,28 $diff2:1,28
03.06.2020 03:00:00 | 00000 | CUSTOM  | Medianfilter         | 30980: Fehlerhafte Werte:1
03.06.2020 03:00:00 | 52442 | WARNING | ScriptEngine         | Result for Event 40805
30980 0. diff1:-1,28 $diff2:1,28
30980: Fehlerhafte Werte:1

das bedeutet das es bei der Variablen mit ID 30980 einmal -1.28 und dann +1.28 gab was nicht sein darf. Es gab einen Fehler in einer Variablen.

Dieser Filter ist nur für Variablen vom Typ „Zähler“ zu verwenden da diese immer nur hoch zählen. Für andere Typen müsste man einen „richtigen“ Medianfilter nehmen.

Ralf

Hi,
danke, das hab ich hinbekommen. Mit dem Hobby sollte man ggf. Programmierer werden und kein SysAdmin und Pilot.

Ich habe mal einen Float erstellt und da per Hand mist reingeschrieben. Die, die nicht in der Reihnfolge waren, waren dann weg.
Das ist ja eigentlich das was ich brauche.

Nun steht da aber „//Alle Datensätze der letzten Stunden abfragen“ und strotime „yesterday“.

Ich würde ich aber gerne komplett alles einmal durch laufen lassen, es kann ja sein das die fehlerhaften werde auch über Jahre da drin sind.

Kann man das Yesterday ändern? Wenn in was?

tausend dank euch!

Hi,
ich prüfe immer zeitgesteuert um 3:00 die letzten ca. 27 Stunden so das falsche Werte schnell wegfallen. Einmal eine „Grundreinigung“ ist aber auch möglich indem man Folgendes am Anfang der Funktion filter_variable ändert:


    $start = mktime(0, 0, 0, 1  , 1, 2019);
//    $logData = AC_GetLoggedValues($ArchiveID, $VariableID,  strtotime("yesterday 00:00"), time(), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control
    $logData = AC_GetLoggedValues($ArchiveID, $VariableID,  $start, time(), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control

bei $start gibt man einfach das gewünschte Startdatum an. Die 6 Werte bei mktime sind Stunde, Minute, Sekunde, Monat, Tag, Jahr. Ich habe es bei mir ausprobiert und es hat anscheinend geklappt. Was aber nicht geklappt hat war das Reaggrigieren bei mindestens einer Variablen. Ich habe im Mai noch einen Peak von 500KWh gehabt konnte diesen Wert aber nicht in den Daten sehen. Ich habe noch einmal manuell reaggrigiert und dann stimmte die Grafik.

Nach der „Grundreinigung“ sollte das Skript aber wieder nur täglich über die letzte Stunden laufen da es auch recht lange dauern kann und IPS dann vielleicht stört.

Ralf

Hi,
auch das hat super geklappt, vielen Dank!

Ich habe mal versucht die Variablen in ein array zu packen, aber da bleibt er leider bei „function filter_variable($ArchiveID, $VariableID)“


$archive_ID = array ();
array_push($archive_ID, 40572);
array_push($archive_ID, 20433);


foreach($archive_ID AS $summeID)
{
            echo "SummeID Variable: ".$summeID."
";
           
            filter_variable(10904, $summeID) /* ID der Archive-Instanz */;

            function filter_variable($ArchiveID, $VariableID) 
                {
                 //in dem Abschnitt hier nach nix geändert
                 }
}

Mit dem fehler:
SummeID Variable: 40572

Fatal error: Uncaught Error: Call to undefined function filter_variable() in C:\ProgramData\Symcon\scripts\23031.ips.php:15
Stack trace:
#0 {main}
thrown in C:\ProgramData\Symcon\scripts\23031.ips.php on line 15

Hi,
hast Du die Funktion denn in deinem Script drin gelassen?

Wenn ja poste mal dein ganzes Script.

Ralf

HI,

klar, gerne. ich hab aber alles drin gelassen :slight_smile:

Hier noch mal komplett.


<?php

//array	
    $archive_ID = array ();
    array_push($archive_ID, 40572);
	array_push($archive_ID, 20433);


foreach($archive_ID AS $summeID)
{
            echo "SummeID Variable: ".$summeID."
";
            
            filter_variable(10904, $summeID) /* ID der Archive-Instanz */;

            function filter_variable($ArchiveID, $VariableID) 
                {

                //Alle Datensätze der letzten Stunden abfragen
                //   $logData = AC_GetLoggedValues($ArchiveID, $VariableID,  strtotime("yesterday 00:00"), time(), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control
                    $start = mktime(0, 0, 0, 1  , 1, 2019);
                    $logData = AC_GetLoggedValues($ArchiveID, $VariableID,  $start, time(), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control

                // Anzahl der Werte
                    $entries = count($logData);

                // Macht erst ab 3 Werten Sinn
                    if ($entries < 2) return;

                // Anzahl der Fehler protokolieren
                    $changes = 0;
                    for ($i = 2; $i < $entries; $i++){

                // Differenz Wert2-Wert1
                        $diff1 = $logData[$i - 1]['Value'] - $logData[$i - 2]['Value'];

                // Differenz Wert3-Wert2
                        $diff2 = $logData[$i]['Value'] - $logData[$i - 1]['Value'];

                // Wenn der mittlere Wert entweder der größte oder kleinste Wert ist stimmt was nicht
                        if ((($diff1 < -0.1) && ($diff2 > 0.1)) ||
                            (($diff1 > 0.1) && ($diff2 < -0.1))){ 

                // lösche mittleren Wert
                            AC_DeleteVariableData ($ArchiveID, $VariableID, $logData[$i - 1]['TimeStamp'] - 1, $logData[$i - 1]['TimeStamp'] + 1);

                // Fehler in Logfile eintragen
                            IPS_LogMessage("Medianfilter", $VariableID.' '.$changes.'. diff1:'.$diff1.' $diff2:'.$diff2); 

                // eine Änderung mehr
                            $changes++;
                        }
                    }

                // Wenn es Änderungen gab
                    if ($changes > 0){
                // Variable neu aggregieren
                        AC_ReAggregateVariable ($ArchiveID, $VariableID);
                // Anzahl der Fehler ins Logfile
                        IPS_LogMessage("Medianfilter", $VariableID.': Fehlerhafte Werte:'.$changes); 
                    }
                    else{
                        IPS_LogMessage("Medianfilter", $VariableID.': Alles OK'); 
                    }
                }
 }
?>
    

Ergebnis:
SummeID Variable: 40572

Fatal error: Uncaught Error: Call to undefined function filter_variable() in C:\ProgramData\Symcon\scripts\23031.ips.php:14
Stack trace:
#0 {main}
thrown in C:\ProgramData\Symcon\scripts\23031.ips.php on line 14

(ZEILE 14: filter_variable(10904, $summeID) /* ID der Archive-Instanz */:wink:

Hi,
die Funktion muss außerhalb deiner Schleife stehen. Versuch mal (ungetestet):


 <?php

//array    
    $archive_ID = array ();
    array_push($archive_ID, 40572);
    array_push($archive_ID, 20433);


foreach($archive_ID AS $summeID)
{
    echo "SummeID Variable: ".$summeID."
";
            
    filter_variable(10904, $summeID) /* ID der Archive-Instanz */;

}

function filter_variable($ArchiveID, $VariableID) {

//Alle Datensätze der letzten Stunden abfragen
//   $logData = AC_GetLoggedValues($ArchiveID, $VariableID,  strtotime("yesterday 00:00"), time(), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control
    $start = mktime(0, 0, 0, 1  , 1, 2019);
    $logData = AC_GetLoggedValues($ArchiveID, $VariableID,  $start, time(), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control

// Anzahl der Werte
    $entries = count($logData);

// Macht erst ab 3 Werten Sinn
    if ($entries < 2) return;

// Anzahl der Fehler protokolieren
    $changes = 0;
    for ($i = 2; $i < $entries; $i++){

// Differenz Wert2-Wert1
        $diff1 = $logData[$i - 1]['Value'] - $logData[$i - 2]['Value'];

// Differenz Wert3-Wert2
        $diff2 = $logData[$i]['Value'] - $logData[$i - 1]['Value'];

// Wenn der mittlere Wert entweder der größte oder kleinste Wert ist stimmt was nicht
        if ((($diff1 < -0.1) && ($diff2 > 0.1)) ||
            (($diff1 > 0.1) && ($diff2 < -0.1))){ 

// lösche mittleren Wert
            AC_DeleteVariableData ($ArchiveID, $VariableID, $logData[$i - 1]['TimeStamp'] - 1, $logData[$i - 1]['TimeStamp'] + 1);

// Fehler in Logfile eintragen
            IPS_LogMessage("Zählerfilter", IPS_GetName(IPS_GetParent($VariableID)).'-'.IPS_GetName($VariableID).' Zeit:'.date("Y-m-d H:i:s",  $logData[$i - 1]['TimeStamp']).' diff1:'.$diff1.' $diff2:'.$diff2); 

// eine Änderung mehr
            $changes++;
        }
    }

// Wenn es Änderungen gab
    if ($changes > 0){
// Variable neu aggregieren
        AC_ReAggregateVariable ($ArchiveID, $VariableID);
// Anzahl der Fehler ins Logfile
        IPS_LogMessage("Zählerfilter", $VariableID.': Fehlerhafte Werte:'.$changes); 
    }
    else{
        IPS_LogMessage("Zählerfilter", $VariableID.': Alles OK'); 
    }
}
?>

Ralf

Moin,

hat direkt so funktioniert.

(hatte mich kurz gewundert warum kein Eintrag mehr im Log war, aber da hattest Du Median gegen Zähler getauscht, log eintrag also auch korrekt).

Ich hatte mir sowas schon gedacht und ähnliches versucht und im Internet gesucht wie function arbeitet, aber nix gefunden was ich verstanden habe - nun habe ich deutlich dazu gelernt. danke.

vielen Dank!

Hi,
ja ich habe Median umbenannt weil es nicht wirklich ein Median-Filter ist. Der Name vorher war nur son Schnellschuss. Eine Filtermöglichkeit sollte statt in den Store direkt ins Archive-Modul. Aus Erfahrung kann ich sagen das es kaum Sensoren gibt die immer fehlerfreie Signale liefern wenn man den professionellen Bereich (Industrieanlagen) verlässt.

Ralf

Hallo,

einen Fehler habe ich noch gefunden, da könnte man das Skript einfach umbauen (hab ich versucht, bekomme ich nur nicht hin).

Mein xcomfort sendet bei Temperaturen ganz oft 0.0 und dann wieder korrekte Werte. Davon habe ich 6 Sensoren die alles den gleichen Fehler haben.

Nun wäre meine Idee einfach den Wert 0 komplett raus zu löschen, dann hätte ich mehr Genugkeit wenn bei 0.1, 0.0. -0.1 die 0.0 fehlt als wenn im Sommer mal 0.0 zwischen drin ist.

Jetzt wäre nur die Frage wie ich den Auswertungsteil umbaue, das er nicht mehr die diff berechnet, sondern

if 0 = löschen :wink:

danke.

Hi,
wieder ohne Test:


        if (($logData[$i - 1]['Value'] < 0.1) ||
            (($diff1 < -0.1) && ($diff2 > 0.1)) ||
            (($diff1 > 0.1) && ($diff2 < -0.1))){ 


Floatwerte soll man nie auf Gleichheit wie (a = 0.0) vergleichen das es durch das Zahlenformat (IEEE) selten wirklich glatte Werte gibt. Also statt 1 gibt es dann vielleicht 1.0000000001 oder 0.99999999999.

Die 0 müsste aber so auch schon abgefangen worden sein denn die erste Differenz hätte negativ und die zweite positiv sein müssen.

Ralf

HI,
klappt leider nicht. Bei einigen Tests hat er das Gesamte Log in gelöscht, bei anderen test nur ein paar Sachen.
die 0 werte waren immer weg :wink: aber halt etwas zu viel - bzw viel zu viel.

In meinem Fall könnte man aber schon nach der 0 gehen, wenn der Wert falsch ist, dann ist das eine Glatte 0.

Hier siehst du mal die Temperatur unter der Erde und die nullen die mir den Durchschnitt versauen.

Hi,
wie schon gesagt der Spezialfall 0 ist eigentlich überflüssig. Bei mir lief das Script mit der Änderung heute Nacht für 8-10 Variablen und es hat nichts überflüssiges gelöscht. Bei einer Variablen lief aber die Neuberechnung nicht durch denn im WebFront waren die Ausreißer noch drin im ÜArchive aber nicht.

Ralf

HI,

sehr komisch.
Ich fülle eine Varieble mit ganz viel Müll, und dies Test Variable (Float, ID, 30457) ist danach komplett leer, es ist nur noch der letzte Wert da.
Das treue ich mich jetzt nicht an einer echten Messung auszuführen - würde aber so ja auch kein Unterschied machen?


SetValue(30457,	1	);
SetValue(30457,	0	);
SetValue(30457,	2	);
SetValue(30457,	0	);
SetValue(30457,	0	);
SetValue(30457,	2	);
SetValue(30457,	0	);
SetValue(30457,	0	);
SetValue(30457,	4	);
SetValue(30457,	4	);
SetValue(30457,	0	);
SetValue(30457,	5	);
SetValue(30457,	0	);
SetValue(30457,	0	);
SetValue(30457,	6	);
SetValue(30457,	6	);
SetValue(30457,	6	);
SetValue(30457,	0	);

(das geht noch ca. 50 Zeilen weiter…


<?php
// https://www.symcon.de/forum/threads/43652-Wie-funktionier-AC_GetLoggedValues?p=427016#post427016

//array    
$archive_ID = array ();
//GAS
array_push($archive_ID, 30457);
//array_push($archive_ID, 18799);
//array_push($archive_ID, 26323);




foreach($archive_ID AS $summeID)
{
    echo "SummeID Variable: ".$summeID."
";
    filter_variable(10904, $summeID) /* ID der Archive-Instanz */;

}

function filter_variable($ArchiveID, $VariableID) {
//Counter
$CountID = 58375;
$Count = GetValue(58375);

//Alle Datensätze der letzten Stunden abfragen
//   $logData = AC_GetLoggedValues($ArchiveID, $VariableID,  strtotime("yesterday 00:00"), time(), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control
    $start = mktime(0, 0, 0, 1  , 1, 2015);
    $logData = AC_GetLoggedValues($ArchiveID, $VariableID,  $start, time(), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control

// Anzahl der Werte
    $entries = count($logData);

// Macht erst ab 3 Werten Sinn
    if ($entries < 2) return;

// Anzahl der Fehler protokolieren
    $changes = 0;
    for ($i = 2; $i < $entries; $i++){

// Differenz Wert2-Wert1
        $diff1 = $logData[$i - 1]['Value'] - $logData[$i - 2]['Value'];

// Differenz Wert3-Wert2
        $diff2 = $logData[$i]['Value'] - $logData[$i - 1]['Value'];


    echo "diff1 Variable: ".$diff1."
";
	echo "diff2 Variable: ".$diff2."
";
    
// Wert 0 Löschen
          if (($logData[$i - 1]['Value'] < 0.1) ||
            (($diff1 < -0.1) && ($diff2 > 0.1)) ||
            (($diff1 > 0.1) && ($diff2 < -0.1))){



// lösche mittleren Wert
            AC_DeleteVariableData ($ArchiveID, $VariableID, $logData[$i - 1]['TimeStamp'] - 1, $logData[$i - 1]['TimeStamp'] + 1);
		
					// Fehler in Logfile eintragen
		            IPS_LogMessage("0 Filter", IPS_GetName(IPS_GetParent($VariableID)).'-'.IPS_GetName($VariableID).' Zeit:'.date("Y-m-d H:i:s",  $logData[$i - 1]['TimeStamp']).' diff1:'.$diff1.' $diff2:'.$diff2); 
					// eine Änderung mehr
		            $changes++;
		        	}
		    }

// Wenn es Änderungen gab
    if ($changes > 0){
// Variable neu aggregieren
        AC_ReAggregateVariable ($ArchiveID, $VariableID);
// Anzahl der Fehler ins Logfile
        IPS_LogMessage("0 Filter", $VariableID.': Fehlerhafte Werte:'.$changes); 
        SetValue ($CountID, $Count + 1);
    }
    else{
        IPS_LogMessage("0 Filter", $VariableID.': Alles OK'); 
    }
}
?>

Hi,
ich hatte es explizit für einzelne Ausreißer geschrieben. In deinem Fall gibt es öfter zwei Nullen hintereinander deswegen geht es nicht.

Für 2 Ausreißer hintereinander muss der Filter für das Script unten so aussehen:


function filter_variable($ArchiveID, $VariableID) {

//Alle Datensätze der letzten Stunden abfragen

    $logData = AC_GetLoggedValues($ArchiveID, $VariableID,  strtotime("yesterday 00:00"), time(), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control
//    $start = mktime(0, 0, 0, 1  , 1, 2019);
//    $logData = AC_GetLoggedValues($ArchiveID, $VariableID,  $start, time(), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control
    $entries = count($logData);
    if ($entries < 4) return;
    $changes = 0;
    for ($i = 4; $i < $entries; $i++){
        $diff1 = $logData[$i - 2]['Value'] - $logData[$i - 4]['Value'];
        $diff2 = $logData[$i]['Value'] - $logData[$i - 2]['Value'];

        if ((($diff1 < -0.1) && ($diff2 > 0.1)) ||
            (($diff1 > 0.1) && ($diff2 < -0.1))){ 
            AC_DeleteVariableData ($ArchiveID, $VariableID, $logData[$i - 2]['TimeStamp'] - 1, $logData[$i - 2]['TimeStamp'] + 1);
            IPS_LogMessage("Zählerfilter", IPS_GetName(IPS_GetParent($VariableID)).' - '.IPS_GetName($VariableID).' Zeit:'.date("Y-m-d H:i:s",  $logData[$i - 2]['TimeStamp']).' diff1:'.$diff1.' $diff2:'.$diff2); 
            $changes++;
        }
    }
    if ($changes > 0){
        AC_ReAggregateVariable ($ArchiveID, $VariableID);
        IPS_LogMessage("Zählerfilter", $VariableID.': Fehlerhafte Werte:'.$changes); 
        IPS_SetScriptTimer($_IPS['SELF'], 300);

    }
    else{
        IPS_LogMessage("Zählerfilter", IPS_GetName(IPS_GetParent($VariableID)).' - '.IPS_GetName($VariableID).' Alles OK'); 
        IPS_SetScriptTimer($_IPS['SELF'], 10);
    }
}

Wenn Du wirklich nur 0 weg haben willst sollte es so gehen:


function filter_variable($ArchiveID, $VariableID) {

//Alle Datensätze der letzten Stunden abfragen

    $logData = AC_GetLoggedValues($ArchiveID, $VariableID,  strtotime("yesterday 00:00"), time(), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control
//    $start = mktime(0, 0, 0, 1  , 1, 2019);
//    $logData = AC_GetLoggedValues($ArchiveID, $VariableID,  $start, time(), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control
    $entries = count($logData);
    $changes = 0;
    for ($i = 0; $i < $entries; $i++){

        if ($logData[$i]['Value'] < 0.1){ 
            AC_DeleteVariableData ($ArchiveID, $VariableID, $logData[$i]['TimeStamp'] - 1, $logData[$i]['TimeStamp'] + 1);
            IPS_LogMessage("Zählerfilter", IPS_GetName(IPS_GetParent($VariableID)).' - '.IPS_GetName($VariableID).' Zeit:'.date("Y-m-d H:i:s",  $logData[$i]['TimeStamp'])); 
            $changes++;
        }
    }
    if ($changes > 0){
        AC_ReAggregateVariable ($ArchiveID, $VariableID);
        IPS_LogMessage("Zählerfilter", $VariableID.': Fehlerhafte Werte:'.$changes); 
        IPS_SetScriptTimer($_IPS['SELF'], 300);

    }
    else{
        IPS_LogMessage("Zählerfilter", IPS_GetName(IPS_GetParent($VariableID)).' - '.IPS_GetName($VariableID).' Alles OK'); 
        IPS_SetScriptTimer($_IPS['SELF'], 10);
    }
}

Ich habe auch noch ein Problem gefunden. Wenn 2 Variablen reaggrigiert werden müssen klappt es bei der 2ten Variablen meist nicht. Die Doku erwähnt ja auch das es lange dauern kann und wenn die 2te Variable reaggrigiert werden soll läuft es noch für die 1te Variable und das wird dann nicht mehr ausgeführt.

Dieses Script lässt IPS 5 Minuten Zeit wenn eine Variable reaggrigiert werden muss:


<?php
$variablen = array( 18122, 
                    30980,
                    25391,
                    53556,
                    15741,
                    48510, 
                    32294,
                    48724,
                    14835,
                    22373
                    );

$CountID = IPS_GetObjectIDByIdent("Count", $_IPS['SELF']);
if ($CountID == false){
    $CountID = IPS_CreateVariable(1);
    IPS_SetName($CountID, "Count"); // Variable benennen
    IPS_SetParent($CountID, $_IPS['SELF']); 
    IPS_SetIdent($CountID, "Count"); 
}

$IndexID = IPS_GetObjectIDByIdent("Index", $_IPS['SELF']);
if ($IndexID == false){
    $IndexID = IPS_CreateVariable(1);
    IPS_SetName($IndexID, "Index"); // Variable benennen
    IPS_SetParent($IndexID, $_IPS['SELF']); 
    IPS_SetIdent($IndexID, "Index"); 
}

if($_IPS['SENDER'] == "TimerEvent"){
    if (IPS_GetName($_IPS['EVENT']) == 'ScriptTimer'){
        $Index = GetValue($IndexID);
        $Count = GetValue($CountID);
        filter_variable(32968, $variablen[$Index]);
        $Index++;
        SetValue($IndexID, $Index);
        if ($Index == $Count) IPS_SetScriptTimer($_IPS['SELF'], 0);
        return;
    }
}

if (IPS_GetScriptTimer($_IPS['SELF']) != 0) return;
SetValue($CountID, count($variablen));
SetValue($IndexID, 0);
IPS_SetScriptTimer($_IPS['SELF'], 10);

function filter_variable($ArchiveID, $VariableID) {

//Alle Datensätze der letzten Stunden abfragen

    $logData = AC_GetLoggedValues($ArchiveID, $VariableID,  strtotime("yesterday 00:00"), time(), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control
//    $start = mktime(0, 0, 0, 1  , 1, 2019);
//    $logData = AC_GetLoggedValues($ArchiveID, $VariableID,  $start, time(), 0); //55554 ist die ID der Variable, 12345 vom Archiv Control
    $entries = count($logData);
    if ($entries < 2) return;
    $changes = 0;
    for ($i = 2; $i < $entries; $i++){
        $diff1 = $logData[$i - 1]['Value'] - $logData[$i - 2]['Value'];
        $diff2 = $logData[$i]['Value'] - $logData[$i - 1]['Value'];

        if ((($diff1 < -0.1) && ($diff2 > 0.1)) ||
            (($diff1 > 0.1) && ($diff2 < -0.1))){ 
            AC_DeleteVariableData ($ArchiveID, $VariableID, $logData[$i - 1]['TimeStamp'] - 1, $logData[$i - 1]['TimeStamp'] + 1);
            IPS_LogMessage("Zählerfilter", IPS_GetName(IPS_GetParent($VariableID)).' - '.IPS_GetName($VariableID).' Zeit:'.date("Y-m-d H:i:s",  $logData[$i - 1]['TimeStamp']).' diff1:'.$diff1.' $diff2:'.$diff2); 
            $changes++;
        }
    }
    if ($changes > 0){
        AC_ReAggregateVariable ($ArchiveID, $VariableID);
        IPS_LogMessage("Zählerfilter", $VariableID.': Fehlerhafte Werte:'.$changes); 
        IPS_SetScriptTimer($_IPS['SELF'], 300);

    }
    else{
        IPS_LogMessage("Zählerfilter", IPS_GetName(IPS_GetParent($VariableID)).' - '.IPS_GetName($VariableID).' Alles OK'); 
        IPS_SetScriptTimer($_IPS['SELF'], 10);
    }
}

?>

Ralf