UPDATE 29.6.18: Mein Skript bezieht nun die Daten von DarkSky und nicht mehr von OpenWeatherMap, da sich dieser als zuverlässiger herausgestellt hat.
UPDATE 10.7.18: Fehler bei Berechnung der Regenperioden im Skript behoben
Ich habe unterschiedliche Ansätze (Bodenfeuchte Sensor, eigene HM Wetterstation etc.; siehe auch Diskussion weiter unten) überlegt und nun folgende Lösung realisiert, die den Vorteil hat, dass ich keine Zusatz-Hardware benötige.
Die Niederschlagsdaten beziehe ich vom kostenlosen Dienst DarkSky. Dieser hat den
Vorteil, dass zuverlässig Angaben zu Regenmengen liefert. Wie man die Daten in die CCU bekommt, wurde für OpenWeathermap u.a. bereits hier besprochen. Bei DarkSky ist es änlich. Man legt einen Account an (hier) und bekommt dann einen API Key mit dem man gratis 1000mal Abfragen pro Tag tätigen kann, was weit mehr ist, als man braucht.
HINWEIS: Bei OpenWeatherMap gibt es jedoch nicht überall (und nicht immer) eine Anzeige der Regenmenge. Das muss man bei Regen für den eigenen Standort prüfen. WunderGround (siehe etwa hier) ist offenbar nicht mehr gratis. In Österreich könnte man auch hier verwenden oder die DAten von der eigenen HM Wetterstation besorgen.
Der Gardena Smart Sileno Rasenroboter kommuniziert mit dem mitgelieferten Gardena Smart Gateway, welches über WLAN mit einem Server bei Gardena bzw. beim Mutterkonzern Husqvarna verbunden ist. Der Husqvarna Server hat ein API, das beschrieben ist z.B. hier.(Theoretisch wäre es zwar einfacher den Rasenroboter direkt anzusteuern, aber viel mehr als dass er über 868MHz via Lemonbeat Protokoll mit dem Gateway kommuniziert, habe ich nicht herausbekommen. Es gäbe auch als Erweiterung das RoboNect Modul, das setzt aber voraus, dass im gesamten Mähbereich WLAN Empfang gegeben ist)
Damit waren die wichtigsten Bestandteile der Lösung vorhanden. Nun stellte sich die Frage: Wie erkennt man denn anhand der Wetterdaten, ob es so viel regnet, dass sich Pfützen bilden können?
DarkSky liefert die Regenmengen der letzten Stunde. Nach Analyse historischer Wetterdaten habe ich mir in einem HomeMatic Skript eine Formel für Starkregen und eine für Dauerregen zusammengebastelt. Diese Formeln sind noch experimentell und sollen über die Zeit anhand praktischer Erfahrungen der Realität kalibriert werden. Schließlich hängt es nicht nur von der Regenmenge, sondern auch vom Boden ab, ob sich Pfützen bilden.
- Starkregen = mindestens 2 Regenstunden und ((mindistens 15mm Regen/3h) oder (Anstieg des 3h Wertes zur Vorperiode um mind. 10mm))
- Dauerregen = mindestens 5 ununterbrochene Regenstunden und akkumulierter Wert/Periode >= 2mm
Das ist gefühlt etwa doppelt so oft, als unbedingt nötig. Ich denke, es ist besser, er parkt einmal zu oft, als einmal zu wenig.
Was braucht man, um die Lösung umzusetzen?
- Gardena Smart Rasenroboter mit Gardena Smart Gateway verbunden (ein Gardena Account wurde bereits eingerichtet). Das Gateway muss sich nicht im gleichen LAN befinden wie die CCU.
- Einen Web-Server (aus Sicherheitsgründen vorzugsweise im eigenen LAN) z.B. Raspi, NAS, SCS etc. auf dem PHP-Skripte mit CURL Unterstützung laufen können.
- Einen API Key von https://darksky.net/dev/register
- CCU Systemvariablen
ganzzahlig:
Wetter_Regenmenge
Wetter_Regenmenge_Perioden
Wetter_Regenmenge_akkumuliert
Wetter_Trocken_Perioden
Werteliste:
RM_Anweisung: 0 keine, 1 parke außertourliche wegen Regens
Zeichenkette:
Trace, protokolliert, für das CCU Systemprotokoll
Es empfiehlt sich, alle Systemvariablen als protokolliert anzulegen. - Auf dem Webserver ein Verzeichnis "htdocs/gardena" anlegen und aus der beiliegenden gardena.zip die folgenden PHP Skripte hineinkopieren:
logindata.php
smart_mower.php
park.php
parkUntilTimer.php
start24h.php
(die anderen PHP Skripte werden nicht gebraucht, können aber für andere Projekte nützlich sein) - Im CCU E-Mail Addon (Einstellungen/Systemsteuerung/EMail) z.B. unter der Nummer 12 eine Mail-Vorlage mit folgendem Text anlegen:
Ereignisinformation:
- Wegen Starkregen wurde der Rasenroboter geparkt
Laut DarkSky.net ist es jetzt wieder trocken.
Was ist zu tun:
- Rasenroboter wieder nach Zeitplan mähen lassen. Über diese Links:
http://<server>/gardena/parkUntilTimer.php?userid=<id>&password=<pw>
http://<server>/gardena/start24h.php?userid=<id>&password=<pw>
oder über die Gardena App.
Dabei <server> durch die URL oder IP des Servers (z.B 192.168.175.2) einsetzen wo die php Skripte installiert wurden sowie für <id> und <pw> die id und Passwort des Gardena Accounts. - Das beiliegende HomeMatic Skript anpassen:
In der Zeile 11 Für <user> und <pw> die mail und Passwort des Gardena Accounts eingeben.
Code: Alles auswählen
! Wetter_Regenmenge aktualisieren und analysieren ! ! Benoetigte Systemvariable: ! Wetter_Regenmenge ! Wetter_Regenmenge_Perioden ! Wetter_Regenmenge_akkumuliert ! Wetter_Trocken_Perioden ! RM_Anweisung: 0 keine, 1 parken außertourliches parken wegen Regens , 2 mähen nach Zeitplan, start with next timer ! ! Das Script muss 1 x pro Stunde aufgerufen werden string userpw = "userid=<user>&password=<pw>"; string apikey = "<apikey>"; string ort = "<breitengrad>,<längengrad>"; string url = "https://api.darksky.net/forecast/"#apikey#"/"#ort#"?lang=de&units=si&exclude=hourly,daily"; string phpserver = "http://<ip-adresse>"; string stdout; string stderr; real rain_val; integer perioden; string antwort = ""; string rain_val = "0.00"; real akkum =0 ; integer data_pos = 0; system.Exec("killall -9 wget", &stdout, &stderr); stdout = ""; stderr = ""; ! wget parameter ! -b background. do not use here ! -q Quiet ! -O - output auf stdout ! -t 1 try once. default is 20 ! -T 10 try 10 seconds, default is 900 system.Exec("wget -q -T 10 --no-check-certificate -O - '"#url#"'",&stdout,&stderr); if ((stderr=="")&&(stdout>"")) { !WriteLine("OK:"#stdout#stderr); ! sammle Ergebnisse string antwort = antwort#stdout; if (antwort >"") { ! In der Antwort Eintrag zu Regenmengen suchen: "precipIntensity":1.695 data_pos = antwort.Find('"precipIntensity":'); if (data_pos > 0) { rain_val = antwort.Substr(data_pos+18,10); integer data_pos_end = rain_val.Find(',"'); rain_val = rain_val.Substr(0,data_pos_end); } } } else { ! WriteLine("NOK:"#stdout#stderr); dom.GetObject("Trace").State("T_Wetter_Regenmenge :"#stderr); } !WriteLine("Regen gelesen:"#rain_val ); if (rain_val.ToFloat() > 0.01) { ! if (1==1) { !WriteLine("Regen"); perioden = dom.GetObject("Wetter_Regenmenge_Perioden").Value()+1; real akkum = dom.GetObject("Wetter_Regenmenge_akkumuliert").Value(); ! WriteLine("Perioden:"#perioden#" Akkumulierter Regen:"#akkum); ! mindestens 3 Regenstunden und (mind. 15mm oder Anstieg des Wertes zur Vorperiode um mind. 10mm) if ((perioden>=3) && ((((rain_val+akkum) >= 15.0)||((rain_val-dom.GetObject("Wetter_Regenmenge").Value())>=10)))) { !if (1==1) { !WriteLine("Starkregen"); ! ueberregionaler Starkregen . Kurzer Platzregen hat nur Sinn im Umkreis der Wetterstation if (dom.GetObject("RM_Anweisung").Value()==0) { ! if (1==1) { !WriteLine("RM noch nicht geparkt"); dom.GetObject("RM_Anweisung").State(1); system.Exec("killall -9 wget", &stdout, &stderr); stderr=""; system.Exec("wget -q -T 10 -O - '"#phpserver#"/gardena/park.php?"#userpw#"'",&stdout,&stderr); if ((stderr=="")&&(stdout=="1")) { ! WriteLine("RM geparkt"); dom.GetObject("Trace").State("T_Wetter_Regenmenge: RM wurde wegen Regen bis auf weiteres geparkt"); } else { ! WriteLine("RM nicht geparkt: "#stdout#stderr); dom.GetObject("Trace").State("T_Wetter_Regenmenge: Fehler park.php "#stdout#stderr); } } } dom.GetObject("Wetter_Regenmenge").State(rain_val); akkum = akkum+rain_val; dom.GetObject("Wetter_Regenmenge_akkumuliert").State(akkum); ! Dauerregen: mindestens 5 ununterbrochene Regenstunden und akkumulierter Wert/Periode >= 2mm if ((perioden>=5)&&((akkum/perioden)>=2)) { !if (1==1) { !WriteLine("ergiebiger Dauerregen"); if (dom.GetObject("RM_Anweisung").Value()==0) { ! if (1==1) { ! WriteLine("RM noch nicht geparkt"); dom.GetObject("RM_Anweisung").State(1); ! RM parken system.Exec("killall -9 wget", &stdout, &stderr); stderr=""; system.Exec("wget -q -T 10 -O - '"#phpserver#"/gardena/park.php?"#userpw#"'",&stdout,&stderr); if ((stderr=="")&&(stdout=="1")) { ! WriteLine("RM geparkt"); dom.GetObject("Trace").State("T_Wetter_Regenmenge: RM wurde wegen Regen bis auf weiteres geparkt"); } else { ! WriteLine("RM nicht geparkt: "#stdout#stderr); dom.GetObject("Trace").State("T_Wetter_Regenmenge: Fehler park.php "#stdout#stderr); } } } dom.GetObject("Wetter_Trocken_Perioden").State(0); dom.GetObject("Wetter_Regenmenge_Perioden").State(perioden); } else { ! Es gibt keinen Regen oder es gibt keine Station, die einen 3h Weert Liefert !WriteLine("Kein Regen berichtet"); dom.GetObject("Wetter_Regenmenge").State(0); dom.GetObject("Wetter_Regenmenge_akkumuliert").State(0); dom.GetObject("Wetter_Regenmenge_Perioden").State(0); ! Trockenperioden zählen perioden = dom.GetObject("Wetter_Trocken_Perioden").Value()+1; if ((dom.GetObject("RM_Anweisung").State()==1)&&(perioden>=3)) { ! RM war parken geschickt worden, nun kann er wieder maehen, ! weil es in den letzten drei h keinen Regen mehr gab ! Aus Sicherheitsgründen nicht automatisch starten, sondern Mail an Benutzer senden dom.GetObject("RM_Anweisung").Value(0); system.Exec("/etc/config/addons/email/email 12", &stdout, &stderr); dom.GetObject("Trace").State("T_Wetter_Regenmenge: Mail zur Wiederinbetriebnahme des RM wurde versandt"); } dom.GetObject("Wetter_Trocken_Perioden").State(perioden); }
In der Zeile 12 bei APPID=<api-key> den zuvor besorgten API-Key einsetzen.
In der Zeile 13 mit Breiten und Längengrad einen Ort angeben (z.B. 45.67,12.34) . Dabei Dezimalpunkte verwenden.
In der Zeile 15: hdie URL oder IP des Servers (z.B http://192.168.175.2) einsetzen wo die php Skripte installiert wurden.
In Zeile 132 die Nummer des zuvor angelegten E-Mail Templates eintragen (z.B. 12) - WebUI Programm "T_Wetter_Regenmenge_setzen" anlegen und das Skript einfügen. Das Programm ruft einfach einmal pro Stunde das Skript auf.
Wie gesagt, das Ganze ist noch experimentell und muss sich erst noch über den Sommer im "Feldtest" praktisch bewähren.
gzi