2021-08-24

Anlass für diesen Artikel ist mein Projekt Zisternenmessungen. Mein zu obigem Datum aktuelles Messsystem basiert auf einem ESP32 Entwicklungsboard und Tasmota32. Die Möglichkeiten von Tasmota32 und der eingebetteten Programmiersprache Berry hat diesem Projekt eine starken Schub gegeben. Die Möglichkeiten gegenüber einem ESP8266 mit Tasmota sind riesig.

  1. Einleitung, Projektbedingungen
  2. Messungen des Füllstandes per Ultraschall - spezielle Herausforderungen
  3. Gewinnung eines gemittelten Abstandsrohwertes ohne Verfälschung durch Ausreißer
  4. Einsatz des Zeitreihen-Datenbanksystems InfluxDB
  5. KI zur Erfassung bzw. Abschätzung eines Starkregens - zunächst ausschließlich hypothetisch betrachtet

Da o.a. Artikel inzwischen zu umfangreich wurde, habe ich hierher einige Grundlagen zur Implementation des Messsystems ausgelagert. Struktur und Inhalt des hier vorliegenden Artikels wird sich noch verändern können.

1. Einleitung, Projektbedingungen

Das Messen des Füllstandes einer Zisterne stellte mich vor besondere Herausforderungen. Das von mir neu entwickelte Messsystem löst ein zuvor verwendetes Selbstbau-Messsystem auf der Basis eines Arduino Uno und eines Banana Pi ab. Das neue System ist leistungsfähiger, anpassungsfähiger und verlässlicher als das alte. Es erfüllt folgende Bedingungen.

  • Als Leitung zur Zisterne soll ausschließlich eine Niederspannungsleitung mit 5V zur Versorgung des Systems erforderlich sein.
  • Die Sensorik soll kostengünstig sein. Sensoren für über 100,- € sind für dieses Projekt inakzeptabel. Der kostspieligste eingesetzte Sensor ist für 10,- € bis 20,- € zu bekommen.
  • Die Messwerte sollen verlässlich sein, Fehlmessungen (Ausreißer) sollen sich nicht bemerkbar machen.
  • Die Messwerte sollen per Funk, hier WLAN, übertragen werden.
  • Das System soll in unterschiedlichen Umgebungen einsetzbar sein.
  • Das System soll robust sein. Es soll sich bspw. neu starten, wenn aus irgendwelchen Gründen keine Messwerte geliefert werden.
  • Das System soll weitreichende Wartungsarbeiten und Fehleranalysen unterstützen.
  • Die Messwerte sollen als Nutzdaten geliefert werden.
  • Das System soll durch Parametrierung an Anwenderwünsche und -bedarfe anpassbar sein.
  • Die Messwerte sollen per App auf einem Smartphone oder Tablet dargestellt werden können.
  • Die Messwerte sollen auf einem Serversystem gespeichert werden können.
  • Für einen geeigneten Überblick soll der Verlauf des Füllstandes per Grafiken zur Verfügung gestellt werden.
  • Die Messwerte sollen für automatisierte Abläufe verwendbar sein.

Die meisten dieser Bedingungen erfordern eine weitgehende Programmierung des eingesetzten µC-Systems über das zugrunde liegende Tasmota32 hinaus. Insbesondere das unvermeidbare Auftreten von Fehlmessungen erfordert systematische Analysen der Abstandsrohwerte. Diese Analysen liefern Informationen, an Hand derer ich sukzessive geeignete Algorithmen entwickeln bzw. verbessern konnte. Das Messsystem arbeitet inzwischen seit einigen Wochen zuverlässig. Die Rohwertverarbeitung erfolgt auf relativ hohem Niveau.

An dieser Stelle sei erwähnt, dass ich während der Entwicklungsphase einige Ideen kreierte - eine, nicht implementierte, und interessante Idee kam von meiner Frau. Davon habe ich einige Ideen verworfen, sie gaben aber oftmals Anstöße für weitere Ideen. Alles war durchforstet mit Versuchen, im Rahmen von Tasmota32 funktionalen Code zu entwickeln. Für meine Zwecke geeignete, fertige Codeschnipsel liefen mir nicht über den Weg. Tasmota32 ist noch sehr neu und in einer Beta-Phase.

2. Messungen des Füllstandes per Ultraschall - spezielle Herausforderungen

Prinzipiell ist die Füllstandsmessung per Ultraschall geeignet. Allerdings muss der Aktor/Sensor unempfindlich gegen die dauerhaft hohe Luftfeuchtigkeit in der Zisterne sein. Ultraschallaktoren/sensoren sind vergleichsweise kostengünstig gegenüber anderen zur Füllstandsmessung einsetzbaren Sensoren. Tasmota hält hierfür mindestens einen Treiber bereit, durch welchen die Abstandsrohwerte geliefert werden.

Die Ultraschallgeschwindigkeit hängt von der Umgebungstemperatur ab. Tasmota stellt keine Verarbeitung der Temperatur zur Ermittlung des Abstandes zur Wasseroberfläche zur Verfügung. Wenn die Messgenauigkeit bei größeren Abweichungen von 20°C erhalten bleiben soll, muss zur Berechnung des Nutzwertes, hier Wasservorrat, die gemessene Temperatur eingesetzt werden.

Nach bisherigen Erkenntnissen gelingen per Ultraschall keine Messungen ohne sporadisch auftretende fehlerhafte Werte (Ausreißer). Solche Fehlmessungen müssen per Software weggefiltert werden. Zu diesem Zweck ist die Analyse der protokollierten Rohwerte erforderlich. Hierbei zeigte sich, dass alle Ausreißer unterhalb der "guten" Werte lagen. Auf Grund der umfangreich gespeicherten Rohwerte und der entsprechend umfangreichen Analysen ist zu erwarten, dass zu große Ausreißer nie auftreten werden - vermutlich nicht auftreten können. Dies ermöglichte die Entwicklung eines spezifischen, wenn auch relativ einfachen, Algorithmus zur Gewinnung eines mittleren Rohwertes ohne Verfälschung durch Ausreißer. Dieser gemittelte Rohwert bildet zusammen mit der leicht, ohne Ausreißer, zu messenden Temperatur und der Benutzer definierten Parameter die Grundlage zur Berechnung des Wasservorrats als Nutzwert.

3. Gewinnung eines gemittelten Abstandsrohwertes ohne Verfälschung durch Ausreißer

Nur der Vollständigkeit wegen erwähne ich an dieser Stelle, dass mein früherer, simpler Algorithmus aus 10 Rohwerten den größten und den kleinsten bei der Berechnung des arithmetischen Mittelwertes unberücksichtigt ließ. Ich nahm an, dass Ausreißer sowohl zu größeren als auch zu kleineren Werten vorkämen. Im Rahmen des fortschreitenden Projektes analysierte ich die Rohwerte erstmalig systematisch. Eine zusätzliche Recherche ergab, dass hier der mediane Mittelwert besser geeignet sein müsste.

Zum bilden des medianen Mittelwerts, kurz Median, müssen die einzelnen Rohwerte sortiert werden. Der Median ist der Wert in der Mitte der sortierten Liste, wenn die Anzahl an Rohwerten ungerade ist. Bei einer geraden Anzahl an Rohwerten wird das arithmetische Mittel aus dem Wert vor der Mitte und dem Wert nach der Mitte gebildet, in der Mitte liegt ja kein Wert. Der Median ist für die Zisternenmessungen bereits ein recht gut geeigneter Wert. Aber es geht noch besser, wenn die protokollierten Rohwerte analysiert werden.

Prinzipbeispiel: Rohwerte = 12, 14, 25, 26, 29, 41, 45 → medianer Mittelwert = 26

Der Median ist dann besonders gut geeignet, wenn die Abweichungen der einzelnen Messwerte von einem gedachten, wahren Messwert nach oben und nach unten etwa gleich verteilt sind. Dies liegt hier aber nicht vor. Es zeigt sich, dass (bisher) alle Ausreißer kleinere Werte sind. Ausreißer nach oben kommen nicht vor. Dieser Sachverhalt bietet die Möglichkeit zur Bildung eines "dynamischen arithmetischen Mittelwertes", kurz Md. Ich nenne diesen Mittelwert "dynamisch" weil er sich während der Mittelwertbildung zu einem vermuteten Optimum verändert. Dieses Optimum ist der Durchschnitt (= arithmetischer Mittelwert) aller "guten" Rohwerte. Auf diese Weise beeinflusst keiner der Ausreißer den Md Wert. Diese Mittelwertbildung erscheint mir besonders gut geeignet, wenn Ausreißer schlicht als gravierende Fehlmessungen eingestuft werden und nicht etwa als Werte mit größerer Abweichung vom gedachten, wahren Mittelwert.

Der Algorithmus zur Bildung des Md ist einfach. Zugrunde liegen

  • die bspw. aufsteigend sortierte Liste RS aller, während einer Messung erhaltenen Rohwerte R, inkl. Ausreißer,
  • die Toleranz T als Benutzer definierter Parameter zwecks Erkennung von Ausreißern.

RS wird vom letzten Rohwert R beginnend in Richtung erstem Rohwert iteriert.
Der erste Md ist der letzte Wert in der Liste RS und dient als Referenz, um mit T Ausreißer kategorisieren zu können.
Md wird mit dem nächsten Rohwert R verglichen. Ist  Md - R ≤ T, dann gilt R als "gut" und wird zur Bildung des neuen dynamischen Mittelwertes Md verwendet. Andernfalls wird R als Ausreißer kategorisiert und die Mittelwertbildung abgeschlossen, weil vor R kein "guter" Wert mehr liegen kann.

Prinzipbeispiel: Toleranz T = 7, Rohwerte = 12, 14, 25, 26, 28, 29 → Md = (29+28+26+25) / 4 = 27 (Iterative Schritte sind erforderlich, hier aber nicht dargestellt.)

Dieser Algorithmus sollte für alle Messungen per Sensor "SR04" und Kompatible geeignet sein, in denen die Erzeugung des Resultats eine längere Latenz haben darf, hier in der Größenordnung von 15 Sekunden.

4. Einsatz des Zeitreihen-Datenbanksystems InfluxDB

Das Datenbanksystem InfluxDB ist auf Zeitreihen spezialisiert. Da zu Messwerten typischerweise der Zeitpunkt der Messung wesentlich ist, kann eine InfluxDB Datenbank deren Speicherung unterstützen. Diese Speicherung liegt zwar etwas außerhalb des Fokus Zisternen-Messlösungen, die Optionen des Datenbanksystems tragen aber zu einer angemessenen Verbesserung des Messsystems bei. 

Beispiel

Angenommen es wird auf eine Lokalisierung Wert gelegt, d.h. bspw. die Namen der Messwerte sollen in der genutzten Muttersprache lauten. Mit InfluxQL, einer SQL ähnlichen Sprache, lassen sich Werte unter alias Namen abfragen. Damit ist eine Lokalisierung solcher Namen möglich. Zugleich habe ich im Messsystem auch eine solche Lokalisierung vorgesehen. Soll das Messsystem ohne Datenbank/Speicherung genutzt werden, ist die Lokalisierung im Messsystem zu verwenden. Bei Nutzung von InfluxDB kann die Lokalisierung dort eingesetzt werden.

Anwendung: SELECT time AS "Zeitpunkt", temperature AS "Temperatur", water_reserve AS "Wasservorrat" FROM "cistern" TZ('Europe/Berlin')

Hiermit werden alle Werte der Messreihe (measurement) "cistern" der genutzten Datenbank unter den Namen "Zeitpunkt", "Temperatur" und "Wasservorrat" geliefert. Außerdem wird die lokale Zeit (TZ=timezone) geliefert. Der Name der Messreihe "cistern" kann aber nicht per InfluxQL lokalisiert werden. Bei Bedarf muss dies an anderer Stelle, bspw. in einem Node Red Flow erfolgen. Dieses Beispiel soll verdeutlichen, dass ein Blick über den "Tellerrand des Messsystems" nützlich ist.

Weil in dieser Anwendung die zeitliche Auflösung von InfluxDB in Nanosekunden irrwitzig ist und der tatsächliche Startzeitpunkt einer Messung dem Messsystem bekannt ist, überträgt das Messsystem diesen Zeitstempel unter dem Namen "srctime", von source time. Dies vermeidet Konflikte mit der InfluxDB internen Benennung "time" für den Zeitstempel zum Zeitpunkt des Eintragens in die Datenbank. Dieses Datenbank Management System (DBMS) unterstützt die Analysen der vom Messsystem gelieferten Werte auf übersichtliche Weise. Ich werde es weiterhin einsetzen und vielleicht werde ich sogar meine bisherigen Speicherungen in Textdateien entfernen. Dazu hat u.a. Uwe Berger mit seinen Vorträgen auf der FrOSCon beigetragen. Er stellt seine Vorträge sehr gut zusammen.

Das Messsystem soll in jedem Fall auch weitgehend autark, d.h. hier ohne viele zusätzliche Server genutzt werden können. Prinzipiell genügen nach wie vor ein MQTT Broker und ein Smartphone zum Ablesen der Werte.

5. KI zur Erfassung bzw. Abschätzung eines Starkregens - zunächst ausschließlich hypothetisch betrachtet

Der Ursprungsgedanke zu einer solchen KI ergab sich aus der Erfassung von Rohwerten und der Beseitigung von darin enthaltenen Fehlmessungen, sog. Ausreißern. Ein Starkregen kann evtl. einen "guten" Rohwert als Ausreißer kategorisieren, da sich während einer Messphase die Rohwerte auf Grund des Zuflusses relativ stark ändern können. Im dem von mir implementierten Zisternen-Messsystem, kurz Messsystem, werden zu einem Nutzwert "Wasservorrat" in einer Messphase mehrere Rohwerte erfasst. Jede Rohwerterfassung dauert ca. 3s, bei bspw. 7 Rohwerten ca. 21s für eine Messphase. Verschiedene Rohwertespeicherungen und deren Analysen waren und sind die Grundlage für geeignete Mittelwertbildungen ohne Ausreißer.

Kennzeichnend für diese Messungen ist, dass alle Rohwerte einer Messungenauigkeit unterliegen und jeder "gute" Rohwert eine quasi zufällige Abweichung vom tatsächlichen, unbekannten Rohwert aufweist. Diese Messungen sind also mit einer Messunsicherheit oder zufälligen Messungenauigkeit behaftet.

Ich definiere in diesem Kontext einen Starkregen als einen Niederschlag, der die Grenzen der Zuführung zur Zisterne erreicht oder überschreitet. Ob ein Regen als solchermaßen definierter Starkregen gilt, hängt somit von der Zisternenanlage und deren Dimensionierung ab. Dies habe ich derzeit noch im o.a. Artikel beschrieben. Mit einem Regen gewisser Stärke ist eine Zuflussgeschwindigkeit verbunden. Bei konstanter Regenstärke ist diese Geschwindigkeit als konstant anzunehmen. Messtechnisch ist diese eine Transformation in die Höhenänderungsgeschwindigkeit vdh einer Wassersäule ohne Abfluss während einer Messphase. Genau diese vdh soll von der KI erfasst und ggf. einem Starkregen zugeordnet werden.

vdh = Geschwindigkeit v einer Höhenänderung dh

Die KI soll auf Grund der "guten" Rohwerte einer Messphase vdh bestimmen. Da jeder Rohwert seinen eigenen zufälligen Fehler beinhaltet, ist dies nicht ganz trivial. Ein vielleicht geeignetes Verfahren soll gelegentlich zu einer implementierten KI führen. Da es viel zu aufwändig wäre, einen Starkregen laborgerecht nachzubilden, muss ich mich auf die theoretischen Grundlagen und die Analysen der gespeicherten Rohwerte stützen.

Ziel: Bestimmung der vdh per linearer Approximation

Die implementierte Mittelwertbildung benötigt alle Rohwerte in einem ansteigend sortierten Datensatz. Mit der Sortierung geht ein Verlust der Historie einer Messphase einher. Deshalb wähle ich für die KI einen zweiten Datensatz.

Definitionen:

  • RS = sortierter Datensatz aller Rohwerte einer Messphase
  • MS = Mittelwert aller "guten" Rohwerte in Rs - dieser ist nicht gezwungenermaßen identisch mit dem oben beschriebenen Mittelwert Md, darf es aber sein.
  • RH = unsortierter Datensatz aller Rohwerte einer Messphase in der Reihenfolge ihrer Erfassung (Historie)
  • T = Toleranz, an Hand derer "schlechte" Rohwerte erkannt werden. Das ist ein einstellbarer Parameter des Messsystems.
  • vdh.max = maximale Geschwindigkeit der Höhenänderung. Das ist ein neuer, einstellbarer Parameter des Messsystems. Dieser ergibt sich irgendwie aus dem vorliegenden Zisternensystem.

Die Phasen der KI

  1. RH beinhaltet zunächst alle Rohwerte. Die KI entfernt die "schlechten" Rohwerte (Ausreißer) aus RH. Dazu werden der Mittelwert MS als Referenz und die Toleranz T benötigt.
  2. An Hand der in RH verbliebenen Rohwerte wird die lineare Approximation einer Zeitfunktion, genau genommen nur deren Steigung a=dh/dt, versucht. Dies erscheint mir gegenwärtig nicht trivial.
  3. Ein Vergleich von a mit vdh.max soll die Stärke des Regens abschätzen und möglichst einen (Zisterne spezifischen) Starkregen erkennen lassen.

Unter 3. schreibe ich "abschätzen", weil ein Filter in der Zuführung zur Zisterne eine Berechnung als unmöglich erscheinen lässt. Die angestrebte KI kann also ausschließlich grob kategorisieren. Es ist noch völlig unklar, ob diese KI für ein Feintuning bei der Erkennung von Ausreißern vs. Starkregen geeignet ist. Zudem müssten die Ausreißer nach der Arbeit der KI noch einmal ermittelt werden. Hierfür muss die KI zwei Toleranzschwellen bereitstellen, eine unter Schwelle Tu und eine ober Schwelle To.

Nach-gedacht:

Die zu jedem Rohwert eingesetzte Toleranz ist zweckmäßigerweise nicht konstant, sondern hängt von der Position des Rohwertes in RH ab.

Diese Toleranz muss sich aus der Toleranz T, dem linearen Steigungsfaktor m und der Position des Rohwertes in RH ergeben. Die letzteren beiden ergeben das Feintuning der positionsgebundenen Toleranz gegenüber einer festen Toleranz.

Ob ich versuchen werde, diese KI zu implementieren, weiß ich noch nicht. Man sollte nach sorgfältiger Prüfung auch ein Nichthandeln als Option erkennen. wink