Regen, Regen, immer nur Regen

Passend zum 24-Stunden-Minimax gibt es einen Regenzähler für die vergangenen Stunden

Nachdem ich für den alten Kombisensor an seinem neuen Standort ein neues Minimax-Programm für die Temperatur geklöppelt hatte, habe ich natürlich kurz danach auch ein Pendant für den Niederschlag programmiert. Damit habe ich dann so gut wie fast alles abgedeckt, was der Sensor noch an sinnvollen Daten liefert.

Variablen in HomeMatic-Scripten

Die CCU hatte früher ein Limit von maximal 200 Variablen, das mit Firmware-Version 2.29.18 aufgehoben wurde. Dieses Limit bezog sich auf alle Variablen, die in allen Scripten verwendet werden. Gemeint sind Variablen, die direkt im Script definiert werden: object x; object y; var z;

Wenn Scripte nicht mehr funktionieren und bei der Prüfung unerklärliche Syntax-Fehler auftreten, sollte versuchsweise dieses Programm wieder gelöscht oder deaktiviert werden – oder, noch besser, auf die aktuelle Firmware-Version aktualisiert werden.

Strings in HomeMatic-Scripten

Durch String-Verwendung in HomeMatic-Scripten kann die CCU fehlerhaft arbeiten, instabil werden oder sogar abstürzen. Grundsätzlich gilt: Je öfter mit Strings hantiert wird, desto eher führt dies zu Problemen.

Ich empfehle daher, nach Umsetzung dieser Anleitung die CCU unter Beobachtung zu halten.

String-Verlängerung

In den Scripten auf dieser Seite werden Strings verlängert (x = x # y). Dies führt oft zu Störungen bei der Ausführung von Programmen:

  • Scripte in Programmen werden nicht mehr ausgeführt
  • bei der Fehlerprüfung erscheinen unerklärliche Syntax-Fehler

Durch einen Neustart werden diese Probleme (vorübergehend) behoben. Auch hier hängt die Dauer, bis es zu Störungen kommt, davon ab, wie häufig diese Programmschritte ausgeführt werden.

Benennung von Systemvariablen

Prinzipiell kann man Systemvariablen – so wie allen Objekten in der CCU – beliebige Namen geben, also z. B. auch Umlaute und Sonderzeichen verwenden. Ich empfehle jedoch, sich auf reguläre Buchstaben (a-z, A-Z) zu beschränken: Bei Umlauten und Sonderzeichen besteht die Gefahr, dass Systemvariablen in Scripten nicht überall gefunden werden.

Planung

Wie beim 24-Stunden-Minimax ist auch beim 24-Stunden-Regen die Herausforderung, Daten aus einem Verlauf zu extrahieren, ohne eine Datenbank zu verwenden. Auch für den Regen werde ich daher die Niederschlagswerte in einer Systemvariablen speichern, die die letzten 24 Stunden abdeckt und ständig aktualisiert wird.

Ebenfalls wie bei der Temperatur sind es dann auch diesmal eigentlich nur 22 bis 23 Stunden, aber auch beim Regen ist das für mich völlig ausreichend.

Systemvariablen

Wie immer bilden die Systemvariablen den Anfang.

Die Systemvariable Regen 24h ist die Zeichenkette, die ich als Array missbrauchen werde. Regenmenge wird dann die 24-Stunden-Summe aufnehmen – ich habe sie dem Gerät Kombisensor zugeordnet, damit der Wert in der WebUI leidlich elegant angezeigt wird.

Programm und Script

Das WebUI-Programm ist ähnlich einfach wie beim Temperatur-Minimax.

Sobald der Kombisensor irgendeine Regenmenge meldet, wird das Script ausgeführt. Der Wertebereich größer oder gleich 0.00 mm sowie die Auswahl bei Aktualisierung auslösen sorgen dafür, dass das Script entsprechend der Logik von WebUI-Programmen bei jeder Meldung des Kombisensors ausgeführt wird, egal ob es frischen Regen gibt oder nicht.

Für das Script habe ich eine Verzögerung von 10 Sekunden eingestellt, weil ich es gleichzeitig für die Aktualisierung meiner PHP-DB verwende. So ganz verzichte ich also auch diesmal nicht auf eine Datenbank-Anbindung, aber das ist wie beim Minimax optional und hat keine Auswirkung auf die Berechnung des 24-Stunden-Niederschlags. Wer keine PHP-DB hat, braucht eigentlich auch keine Verzögerung.

Das Script ist wieder hübsch mittellang.

! HomeMatic-Script
! REGEN, REGEN, IMMER NUR REGEN
! http://www.christian-luetgens.de/homematic/programmierung/garten/niederschlag/Regen.htm

object o_raincount = dom.GetObject ("$src$");

if (o_raincount) {

  real r_raincount = o_raincount.Value() - o_raincount.LastValue();
  if (r_raincount < 0.0) {
    r_raincount = r_raincount + o_raincount.ValueMax();
  }

  if (r_raincount < 50.0) {

    object o_verlauf = dom.GetObject ("Regen 24h");
    string s_verlauf_alt = o_verlauf.Value();
    string s_verlauf_neu = "";

    integer i_now = system.Date ("%H").ToInteger();

    string s_delimiter = "";
    integer i = 0;
    real r_tag = 0.0;
    real r_stunde;
    string s;

    while (i < 24) {
      if (i == ((i_now + 1) % 24)) {
        s = "0";
      } else {
        r_stunde = s_verlauf_alt.StrValueByIndex (";", i).ToFloat();
        if (i == i_now) {
          r_stunde = r_stunde + r_raincount;
        }
        s = r_stunde.ToString (1);
        r_tag = r_tag + r_stunde;
      }
      s_verlauf_neu = s_verlauf_neu # s_delimiter # s;
      s_delimiter = ";";
      i = i + 1;
    }

    o_verlauf.State (s_verlauf_neu);
    dom.GetObject ("Regenmenge").State (r_tag);

  }

}

!  Ende des Scripts

Das Script ermittelt zunächst den Datenpunkt, über den es ausgelöst wurde. Wenn es keinen auslösenden Datenpunkt gibt, weil das Programm zum Beispiel beim Neustart der CCU ausgeführt wird, passiert nichts weiter.

Gibt es einen Datenpunkt, werden aktueller und vorheriger Wert für den Regenmengenzähler ausgelesen. Ist der aktuelle Wert niedriger als der vorherige, geht das Script von einem Zähler-Überlauf aus. Wenn am Ende kein sinnvoller Wert von maximal 50 mm seit der letzten Meldung herauskommt, wird der Rest des Scripts übersprungen.

Anderenfalls wird die Zeichenkette s_verlauf_alt für den Verlauf der letzten 24 Stunden initialisiert und die Stunde der aktuellen Uhrzeit als Index ermittelt. Danach geht das Script – wie beim Temperatur-Minimax – alle 24 Stunden durch: Für die aktuelle Stunde wird der aktuelle Regenwert zum Wert aus s_verlauf_alt addiert und in s_verlauf_neu geschrieben, für die folgende Stunde wird der Wert in s_verlauf_neu auf 0 gesetzt, alle anderen Stundenwerte werden unverändert übernommen.

Die neu zusammengesetzte Zeichenkette s_verlauf_neu wird dann wieder in Regen 24h zurückgeschrieben.

Nebenbei wurde in der Schleife noch r_tag aufaddiert – das ist dann die Gesamtmenge der letzten Stunden, die ganz am Ende in die Systemvariable Regenmenge geschrieben wird. Damit hat das Script seine eigentliche Aufgabe erfüllt.

Jetzt heißt es: Auf Regen warten. Genug Zeit für eine Alternative-Rock-Ballade.

Erweiterung: PHP-DB

Wie bereits angedeutet, lasse ich im Script auch gleich meine PHP-DB aktualisieren. Das geschieht einfach mit zwei zusätzlichen Zeilen am Ende.

   [...]
   dom.GetObject ("Regenmenge").State (r_tag);

    dom.GetObject ("PHP-DB Table").State ("Regen");
    dom.GetObject ("PHP-DB Value").State (r_raincount);

  }

Die Tabelle Regen wird mit dem Wert in r_raincount gefüllt – also nicht das 24-Stunden-Endergebnis, das ich in meinem Script mühsam ausrechne, sondern einfach die Niederschlagsmenge seit der letzten Meldung des Kombisensors.

utc_time min_val avg_val max_val sum_val
2021-04-27 0.00 0.00 0.00 0.00
2021-04-28 0.00 0.00 0.00 0.00
2021-04-29 0.00 0.00 0.00 0.00
2021-04-30 0.00 0.00 0.00 0.00
2021-05-01 0.00 0.00 0.00 0.00
2021-05-02 0.00 0.00 0.30 0.30
2021-05-03 0.00 0.00 0.00 0.00
2021-05-04 0.00 0.00 0.00 0.00
2021-05-05 0.00 0.00 0.30 0.90
2021-05-06 0.00 0.00 0.00 0.00
2021-05-07 0.00 0.00 0.30 1.80
2021-05-08 0.00 0.00 0.00 0.00
2021-05-09 0.00 0.00 0.00 0.00

Wie man sieht, manchmal regnet es auch hier – am 07. Mai ganze 1,8 mm. Wow!

Für einen Screenshot des Kombisensors muss ich freilich wieder warten. Zeit für die Dire Straits.

Kombisensor

Um die Sache mal abzukürzen: Meine Systemvariable Regenmenge, die ich zu Anfang dem Kombisensor zugeordnet hatte, wird wie geplant in der WebUI angezeigt.

Ich habe den Screenshot etwas zusammengeschnitten, aber gut zu erkennen: Der Regenmengenzähler des Kombisensors – oben – zeigt 4,13 mm Niederschlag, seit ich das Gerät hier aufgestellt habe. Die Regenmenge aus der Systemvariable, die ebenfalls als „Regenmenge“ angezeigt wird – unten –, steht stramm bei 0.

Es wird wohl Sommer.

Navigation