Runtime Datenreduktion / Datenkomprimierung - DBLog

Begonnen von charlie71, 03 Februar 2018, 19:43:22

Vorheriges Thema - Nächstes Thema

charlie71

Liebe FHEM Gemeinde,
ich möchte gerne einen Vorschlag über eine Runtime Datenreduktion diskutieren, der sich auf Messwerte bezieht, die in Form eines GNU-Plot dargestellt werden sollen. Bevor ich ins Detail gehe, möchte ich kurz meine Kritikpunkte der aktuell implementierten Datenreduktion darlegen (reduce log):

       
  • Hier wird die Reduktion der Daten im Nachhinein ausgeführt, also nicht Run-Time. Die DB wird durch das wiederkehrende Löschen auch nicht performanter, um die Tabellen performant zu halten, muss die Tabelle gelegentlich OPTIMZED werden.
  • Die Datenreduktion erfolgt – wenn ich es richtig verstanden habe – indem immer der erste Wert einer Stunde genommen wird, die restlichen Werte werden gelöscht. Das mag zwar einfach sein, aber es können damit wichtige Informationen verloren gehen, da diese nicht im Ersten, sondern im Zweiten oder einem anderen Messpunkt stecken. Der Reduktionsalgorithmus lässt sich hier auch nicht parametrisieren.
So nun zu meinem Vorschlag:
Wie eingangs bereits erwähnt, bezieht sich mein Vorschlag nur auf Messwerte, die in einem Graphen dargestellt werden sollen.
Viele Prozesse laufen weitgehend Linear ab, dh sie folgen einer Geraden. ZB der Füllstand einer Regenwasserzisterne, steigt und sinkt linear bei konstanter Befüllung/oder Entnahme.
Zur Beschreibung eines Teilstücks in einem Graphen, benötige ich bei linearen Vorgängen nur zwei Punkte (den Start und den Endpunkt), diese werden mit einer Linie verbunden. Alle anderen Punkte dazwischen sind irrelevant. Punkte die bereits in der Nähe der Geraden liegen, kann man weglassen wenn sie innerhalb eines Toleranzfensters liegen.

Zum Algorithmus im Detail:

       
  • Einlesen des Messwertes (1) (Startpunkt der Graden). (Dieser kann auch gleich gespeichert werden)
  • Einlesen des Messwertes (2) (potentieller Endpunkt)
  • Berechnung der Geraden zwischen den beiden Punkten.
  • Einlesen des Messwertes (3).
  • Liegt der Messwert innerhalb eines Toleranzfensters (+- Toleranzwert am Messzeitpunkt) auf der Geradengleichung, so ist dieser nicht relevant.
    {Siehe Bild 1}
    Es wird der Endpunkt der Geraden nachgezogen, und es wird auf den nächsten Messwert gewartet (-> Schritt 4){Siehe Bild 2}
  • Liegt der Messwert außerhalb des Toleranzfensters der Geradengleichung, so ist dieser offensichtlich wichtig {Siehe Bild 3}.
    Jetzt kann der Endpunkt der bisherigen Geraden gespeichert werden und dieser Punkt wird zum Startpunkt der neuen Geraden {Siehe Bild 4}. Und es geht wieder mit Schritt 4 weiter
Was soll der Algorithmus bringen?
Damit man besser abschätzen kann, habe ich den Algorithmus als Stored Procedure in meiner MYSQL Datenbank implementiert. Folgendes Ergebnis:










NamevorKompnachKompKompFaktorKompRateToleranzMinPunktZeitbereich
Zisterne Wasserstand2731811554,2%23,61-6Monate
Zisterne Wasserstand273181177   4,3%23,2124h6Monate
Helligkeit56779626219246,2%2,1524h2Jahre
Vorlauf01930637779040,3%2,50,524h2Jahre
Vorlauf11930636995436,2%2,8124h2Jahre
Vorlauf21930636039531,3%3,2224h2Jahre
Vorlauf41930635926130,7%3,3424h2Jahre


Spaltenlegende:
Name ... Sensorname. Wobei Vorlauf0, Vorlauf1, Vorlauf2, Vorlauf4 derselbe Sensor ist, die Komprimierung hat jedoch ein anderes Toleranzfenster (Vorlauf0 0.5, Vorlauf1 1, Vorlauf2 2, Vorlauf4 4) verwendet.
vorKomp ... Anzahl Datensätze vor Komprimierung
nachKomp ... Anzahl Datensätze nach Komprimierung
KompFaktor ... Komprimierungsfaktor
KompRate ... Komprimierungsrate
Toleranz ... Für die Komprimierung verwendetes Toleranzfenster
MinPunkt ... Komprimierung liefert alle x h auf jeden Fall einen Messpunkt.
Zeitbereich ... Für welchen Zeitbereich die Daten zur Verfügung standen

Sensorlegende:
Zisterne Wasserstand ... Wasserstand meiner Zisterne (wenig Dynamik in den Messdaten) (event-min-interval .*:600, event-on-change-reading:0.5)
Helligkeit ... Helligkeitssensor  (Spannungsteiler mit LDR) (event-min-interval .*:600, event-on-change-reading:5)
Vorlauf ... Vorlauftemperatur meiner Wärmepumpe (event-min-interval .*:1200, event-on-change-reading:0.5)


Wie wirkt sich das in der Anzeige aus?
Hier habe ich ein paar Vergleichsplots für die Vorlauftemperatur erstellt. Hier kann man auch gut den Unterschied mit unterschiedlichen Toleranzfenstern sehen:
Bild Vorlauf0_5 zeigt den Vergleich vom RAW Sensor Verlauf (rot) zum komprimierten Verlauf (grün) mit einem Toleranzfenster von +/- 0.5 (Kompressionsrate 2,5)
Bild Vorlauf4 zeigt den Vergleich vom RAW Sensor Verlauf (rot) zum komprimierten Verlauf (schwarz) mit einem Toleranzfenster +/- 4  (Kompressionsrate 3,2)

Bitte um Feedbank
lG
Charlie71

DS_Starter

Hallo Charlie,

im Grunde gibt es eine solche Datenminimierungsfunktion bereits im DbRep als "delSeqDoublets".
Eine Toleranzvariation für numerische Werte ist mit dem Attribut  "seqDoubletsVariance" auch eingebaut.
Lies dir mal die Commandref dazu durch.

Wichtig ist dabei, dass diese Routine alle unterstützden Datenbanken abdeckt, nicht nur MySQL die natürlich als ausgewachsenes DBMS mehr Möglichkeiten anbietet als z.B. eine SQLite. Deswegen wird bei den DbRep-Funktionen auch auf spezifische DB-Funktionalitäten verzichtet.

Grüße
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

charlie71

Hallo DS_Starter,

leider muss ich dir widersprechen:
1) das DBReb modul löscht Datensätze nachdem sie gespeichert wurden also nicht run-time. --> DB muss ausgeräumt werden (siehe Kritikpunkt im Posting)
2) mit dem Parameter seqDoubletsVariance kann man nur die Abweichungstoleranz zum letzen Datenwert einstellen. Mein Vorschlag verwendet jedoch eine Geradengleichung mit beliebiger Steigung. (Der Parameter seqDoubletsVariance macht aus meiner Sicht wenig Sinn, da er in diesem Zusammenhang ähnliche Funktion wie das Attribut event-on-change-reading hat).

lg
Charlie71

DS_Starter

Das hatte ich dann natürlich missverstanden.... du möchtest die Datensätze bewerten/behandeln bevor sie gespeichert werden.
Ok, das ist natürlich ein anderer Sachverhalt.

Hast du dazu schon einen konkreten Codierungs/Umsetzungsvorschlag ? Wenn ja, kann man das ja mal probieren.
Wie gesagt, es muss für alle DB's funktionieren und vom Handling her für einen User nutzbar sein. Die Supportfähigkeit muss auch gewährleistet sein.

Interressant wäre es sicherlich.

LG,
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

charlie71

Hallo DS_Starter,

ich stimme Dir vollkommen zu dass eine Lösung auf allen DBs funktioniert.
Las uns mal die Implementierungsebene einengen:
Wenn ich dein Modul richtig verstanden habe, können die Einträge zuerst in einem Cache landen bevor die in die DB geschrieben werden. Hier ist meiner Meinung nach der Ansatz dass nur jene Einträge im Cache landen die wirklich zu speichern sind.
Stimmst Du somit überein?
Anmerkung: Die Komprimierungsebene gibt nur jene Punkte weiter die mit Sicherheit zum Speichern sind. DH unklare Punkte werden nicht weitergegeben.

lg
Charlie71

DS_Starter

Hi Charlie,

ZitatWenn ich dein Modul richtig verstanden habe, können die Einträge zuerst in einem Cache landen bevor die in die DB geschrieben werden. Hier ist meiner Meinung nach der Ansatz dass nur jene Einträge im Cache landen die wirklich zu speichern sind.

Ich muss ein bisschen korrigieren ... es ist nicht mein Modul, sondern nur von mir seit ungefähr Dezember 2016 weiterentwickelt und um Funktionien erweitert. Verschiedene Funktionen wie auch ReduceLog wurde von anderen Entwicklerkollegen implementiert.

Die Verwendung des Cache ist aber auch nur auf den asynchronen Modus beschränkt, im Standard (synchronen) Mode gibt es keinen Cache und die Daten landen ohne Zeitverzug in der DB.

Also man müßte sich zunächst ein Konzept überlegen wie so etwas umgesetzt werden könnte. Auch unter dem Gesichtspunkt dass das Datenlogging die unterschiedlichsten Devices mit den unterschiedlichsten Datentypen der einzelnen Readings abdecken muss. So sind zum Beispiel sehr wahrscheinlich die einzelnen Readings mit einer individuellen Abweichungstoleranz zu behandeln und diese entsprechend vorzuhalten (Restart/ Reread-Festigkeit).
Also müsste das Konzept wahrscheinlich auf Attributen fussen die im jeweiligen Device liegen (ähnlich dem DbLogExclude/include).

Das sind nur ein paar Gedanken die mir AddHoc einfallen, es gibt mit Sicherheit noch vielmehr ... die Tücke steckt im Detail. Ich weiß wovon ich rede in Bezug auf DbLog.  ;)

Aber heute nicht mehr ... gute Nacht.

LG,
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter