Werte Ausschlag begrenzen um zB kurze Temperaturänderungen zu ignorieren

Servus,

leider hab ich nix gefunden weil ich schon nicht weiss nach was ich suchen soll :frowning:

Thema:
Ich regle eine Wärmepumpe eines kl. Pools u.a. abhängig von der Außentemperatur da es unter bestimmten Werten wenig effizient ist und ich sie dann lieber ausschalten lasse.
Derzeit hab ich eine Einschalt-Temp die ich Vorgebe und je eine Hysterese von 4 Kelvin die ich bei Änderung mit ausrechne. zB Wärmepumpe EIN wenn über 15 Grad, AUS wenn unter 11 Grad.
Problem:
Es kommt vor dass ich mal 6-10 Grad Temp Sprünge habe, weil eben grad ein kurzer eisiger Wind vorbei zieht etc. Daher kommt es immer wieder mal vor dass die WP AUS schaltet obwohl es 3 Min später wieder warm genug ist.
Ausreißer nach oben sind genauso doof wenn es mal für 2 Min zB 18 Grad hat, aber dann laufend 14 Grad, sprang die WP eigentlich ungewünscht an.
Gesucht:
Eine Möglichkeit wie ich Temperatur Ausreißer (nach oben und unten) limitieren kann.
Wie stellt man das am Schlauesten an um trotzdem noch mitzubekommen wenn es eben warm genug ist oder zu kalt wird?

Dankbar für ein paar Ideen bei überschaubarem Aufwand :slight_smile:

Cheers Seppm

Hallo Seppm,

du könntest einen Script-Timer setzen und den Schaltvorgang nach Scriptablauf (z.B. 3 Minuten) starten, wenn die Bedingungen weiterhin erfüllt sind.

Gruß, Peter

Mittelwert über die letzten x Messwerte bilden?

Hallo Seppm,

du könntest auch den Median der geloggten Variablenwerte heranziehen.
Der sollte nicht so starke Schwankungen aufweisen.

<?php

// Skript zur Ermittlung des Medians der Werte einer geloggten Variablen

// Archiv- und Variablen ID angeben
$archivID = 50305;
$variableID = 12075;

// Zeitspanne für die der Median bestimmt werden soll definieren.
// Länge des zu berücksichtigenden Zeitintervalls in Sekunden
$intervall = 1800; 
// Ende des Zeitintervalls. time() falls die zuletzt geloggten Werte berücksichtigt werden sollen,
// ansonsten Timestamp des gewünschten Endes.
$endTS = time();
// Startzeitpunkt berechnen
$startTS = $endTS - $intervall;

// Innerhalb des Zeitraums geloggte Werte ermitteln
$loggedValues = AC_GetLoggedValues($archivID,$variableID,$startTS,$endTS,0);

// Array der geloggten Werte nach dem Variablenwert sortieren
usort($loggedValues, build_sorter("Value"));

// Anzahl der geloggten Werte ermitteln
$nValues = count($loggedValues);

// Median der geloggten Werte bestimmen
if($nValues%2 == 0){
    $median = ($loggedValues[($nValues/2)-1]['Value'] + $loggedValues[$nValues/2]['Value']) / 2;
}else{
    $median = $loggedValues[floor($nValues/2)]['Value'];
}

// Kontrolle
//print $nValues."
";
//print ($nValues/2)."
";
print $median."
";
//print_r($loggedValues);

// Funktion von https://stackoverflow.com/questions/2699086/how-to-sort-multi-dimensional-array-by-value entliehen
function build_sorter($key) {
   return function ($a, $b) use ($key) {
      return strnatcmp($a[$key], $b[$key]);
   };
}

Die IDs und den gewünschten Zeitraum müsstest du natürlich anpassen.

Gruß,
Ralla

P.S.
Wäre es nicht schön, wenn AC_GetAggregatedValues den Median mit liefern würde?

Hi,
wenn AC_GetLoggedValues die Werte nicht vor der Rückgabe sortiert liefert deine Funktion nur den mittleren Wert aber nicht den Median. In diesem Fall wären weiterhin große Ausreißer möglich.

Bei Median müssen die Werte erst der Größe nach sortiert werden bevor der mittlere Wert zurückgeliefert wird.

Gleitender Mittelwert wäre einfacher und nicht so rechenintensiv.

Ralf

@HarmonyFan

Ja, wenn der Ausdruck usort($loggedValues, build_sorter(„Value“)) nicht dazu führen würde, dass das Array $loggedValues anschliessend nach Value sortiert vorläge, hättest du fast recht (vielleicht ein bisschen viel Konjunktiv), denn der Median ist nicht einfach der mittlere Wert der sortierten Liste.

Bei einer geraden Anzahl von Listenelementen gibt es ja schliesslich keinen mittleren Wert.

Daher berücksichtigt dieser Abschnitt

// Median der geloggten Werte bestimmen
if($nValues%2 == 0){
    $median = ($loggedValues[($nValues/2)-1]['Value'] + $loggedValues[$nValues/2]['Value']) / 2;
}else{
    $median = $loggedValues[floor($nValues/2)]['Value'];
}

den Unterschied zwischen einer geraden und ungeraden Anzahl von Listenelementen.

Die Verwendung des Medians hat halt den Vorteil, dass er im Gegensatz zum arithmetischen Mittel kaum von Ausreissern beeinflusst wird und um die Unterdrückung der Wirkung von Ausreissern ging es Seppm doch.

Wenn jemandem mein Vorschlag dazu zu kompliziert oder zu rechenintensiv erscheint, muss er ihn ja nicht verwenden.
War ja nur ein Vorschlag.

Gruß,
Ralla

Hi,
sorry hast recht. Ich habe das usort übersehen.

Bei gerader Anzahl nehme ich eher nur einen Wert denn der Median soll Kanten erhalten und das ich bei gerade Anzahl nicht gegeben.

Ralf

Hi HarmonyFan,

es gibt keinen Grund für ein „sorry“, alles gut.

Einen schönen Sonntagabend noch,

Gruß,
Ralla

P.S.
Entschuldigung an alle Anderen, für das Abgleiten ins off-topic.

Ui, Leute,
Danke Euch für die gleich mehrfachen Ideen!
Werde ich mir ansehen was ich am einfachsten einbauen kann!
Aber damit komm ich erstmal weiter!
:+1:
Cheers Seppm