Bewässerungssteuerung - Vorstellung und Ideensammlung

Begonnen von funclass, 29 Oktober 2016, 22:22:41

Vorheriges Thema - Nächstes Thema

FunkOdyssey

Ich habe noch ein Verständnisproblem mit der Berücksichtigung des Regens.
Hat hier jemand ein Praxisbeispiel? Nutzt jemand dazu ein Wettermodul oder Ähnliches?
Danke für die Hilfe.

Stefan_Hvr

Zitat von: FunkOdyssey am 22 Juni 2020, 22:52:29
Ich habe noch ein Verständnisproblem mit der Berücksichtigung des Regens.
Hat hier jemand ein Praxisbeispiel? Nutzt jemand dazu ein Wettermodul oder Ähnliches?
Danke für die Hilfe.
Moin,
bisher noch nichts "schickes" gefunden. Die Wetterdaten bei uns in der Nähe weichen zu stark vom wirklichen Zustand ab. (Proplanta).
Über historische Daten habe ich mir aus zeitgründen noch keinen Kopf machen können.
Ich denke ich werde mich im Herbst mal damit beschäftigen  oder die Bodenfeuchte messen oder ne lokale Wetterstation einzubauen o.ä.
Zumindest die Meldung "israining" verspreche ich mir ab nächste Woche aus meinem Rasenmäher abfragen zu können.
BG Stefan
Viele Grüße aus Hannover
EnOcean, Zigbee, Shelly MQTT, Homebridge, Fritzbox, Harmonyhub, Alexa, Worx MQTT, Sonos MQTT, Tahoma, Telegram, Vorwerk,IRoomba MQTT, Buderus Km200,
seit 08/2019 Hausautomation mit FHEM

JHo

Zitat von: FunkOdyssey am 22 Juni 2020, 22:52:29
Ich habe noch ein Verständnisproblem mit der Berücksichtigung des Regens.
Hat hier jemand ein Praxisbeispiel? Nutzt jemand dazu ein Wettermodul oder Ähnliches?
Ich nutze für den Landroid das DWD-Modul und für die Bewässerung noch nach dem "alten" Code von den ersten Seiten meine eigene Wetterstation (also den Regenmesser der TFA Nexus --> weewx --> FHEM), und reingefrickelt für die Evapotranspiration und eine Regenprognose auch wieder das DWD-OpenData-Modul.
DWD liefert natürlich für den jeweiligen Ort recht schwankend zuverlässige Angaben, ist ja regional alles interpoliert. Je klarer die Wetterlage, umso besser sind die "Treffer" - Gewitter sind z.B. meist viel zu lokal, um mit mehreren Stunden Vorlauf recht zuverlässig für einen Ort angesagt zu werden. Das muss man immer im Hinterkopf behalten.

Zu deiner Frage: was ist denn genau unklar?
- Wenn es aktuell regnet und eine Bewässerung läuft, wird sie unterbrochen. Man weiß ja nicht, wie viel es noch regnen wird. Als Sensor habe ich aktuell meinen Regenmesser, der aber erst ab einer gewissen Menge anschlägt (hat eine Wippe, jeder Wechsel bedeuten 0,7 l/m²). Denkbar sind natürlich die Regenerkennung vom Rasenmäher (da der bei mir aber mit bewässert wird, kann ich ihn nicht nehmen) oder ein simpler Regenmelder z.B. über Jeelink.
- Wenn es bereits messbar geregnet hat, wird dieser natürliche Niederschlag von der zu bewässernden Menge abgezogen, d.h. entsprechend weniger bis nichts bewässert. Dafür ist der Regenmesser mit Wippe natürlich gut geeignet; Rasenmäher oder reinen Regenmelder kann man nicht gebrauchen.

Wie erwähnt, habe ich mir in den alten Code noch zwei Erweiterungen auf Basis der DWD-Prognose gebaut:
- Ist für den Tag der Bewässerung Regen (Menge > definierter Sollwert) angesagt, wird die Bewässerung noch einen Tag verschoben. Dabei rechne ich simpel "Regenmenge laut Prognose = Niederschlagswahrscheinlichkeit * Vorhersagemenge". Hier bin ich ein manueller Stopper: wird zu viele Tage geschoben, und es regnet doch nicht, dann schalte ich halt per Hand ein. Könnte man auch automatisieren.
- Als zweiten Wert für die Bewässerungs-% habe ich die Verdunstung, genauer Evapotranspiration, ins Boot geholt. Das ist ein sehr theoretischer Wert, der für "idealtypisches Grünland" berechnet wird. Die Werte im Hausgarten werden in real sehr stark schwanken, aber so Pi mal Daumen...
Der Evap.-Prognosewert für den Tag wird mit dem Bewässerungs-Sollwert pro Tag verglichen. Liegt PEvap unter Soll pro Tag (d.h. die Pflanzen "verbrauchen" weniger, als "nachgefüllt" wird), wird die Bewässerungsdauer entsprechend verkürzt. Liegt PEvap höher (z.B. sehr heiß, oder sehr geringe Luftfeuchte plus Wind), wird die Bewässerungsdauer verlängert.
ich habe jeweils einen Faktor für positive und negative Änderungen der Gesamtbewässerungsdauer eingeführt, weil ich das Gefühl (!) hatte, das niedrigere PEvap-Werte (Bewässerung soll gekürzt werden) zu starken Einfluss auf die Menge nehmen, also für in meinem Ort zu arg übertrieben sind.
1: FHEM auf Ubuntu, MAX!Cube, Wand- und Heizkörperthermostate, Eco-Schalter, diverse LaCrosse-Sensoren, per remote angebundene DS18B20-Sensoren
2: FHEM auf Raspi 3, Max!Cube, Wand- und Heizkörperthermostate, Eco-Schalter, ht_pitiny-Adapter zu Junkers FW120

FunkOdyssey

Ich habe die Lösung immer noch im reinen Beobachtungsmodus.
Mir fiel auf, dass gar nicht täglich gewässert wird.
Ist das richtig, dass ich bei täglicher Bewässerung intervalDays auf 0 setzen muss?

funclass

Ja, der Wert gibt an wie viele Tage zwischen zwei automatischen Bewässerungszyklen liegen. Ein strapazierfähiger Rasen sollte z.B. nur alle 3 bis 5 Tage gewässert werden. Bei täglicher Bewässerung ist er zwar schön grün, hat aber keine tiefen Wurzeln. Somit würde er bei der ersten Trockenperiode ohne künstliche Bewässerung sofort leiden.

FunkOdyssey

Zitat von: funclass am 22 Juni 2020, 11:08:47
Grundsätzlich sollte das Ventil selbst erstmal unterstützen via set ventilname off auch einen laufenden Timer zu unterbrechen. Geht das nicht, müsste erstmal ergründet werden wie das Device selbst geschaltet werden kann.

Im Code wird bei jeder Änderung der aktiven Zone im Hauptdevice eigentlich dafür gesorgt, dass evtl. noch eingeschaltete Ventile ausgeschaltet werden.


...
# erstmal alle aktiven Ventile ausschalten
my $itemvalve = "";
foreach my $item (devspec2array('NAME=Beregnung_Zone.*')) {
$itemvalve = ReadingsVal($item,"valve","none").":FILTER=STATE=on";
fhem ("set $itemvalve off");
}


:) ich stelle grad fest, dass ich recht oft den Begriff ,,erstmal" verwende :)

Ich habe alle Notifys etc. geprüft und massenhaft Log3-Zeilen zum Debuggen ergänzt.
Ganz am Ende komme ich zu deinen Zeilen. Es scheitert wirklich genau an deiner Schleife.

Die Kombination mit deinem Filter macht mir Probleme:
$itemvalve = ReadingsVal($item,"valve","none").":FILTER=STATE=on";

Bei einem Dummy ist in STATE der Wert "on-for-timer" enthalten. Somit funktioniert der Filter nicht.
Ich bin nun auf Nummer sicher gegangen und haben den Filter entfernt. Es geht natürlich auch mit stateformat oder ähnlich, aber das ist mir auf Dauer auch zu gefährlich.

FunkOdyssey

#111
@funclass:
Wie weit bist du mit deiner neuen Überarbeitung? Ich weiß derzeit nicht, ob ich den alten Code vollumfänglich in Betrieb nehmen soll oder ob ich noch warten soll. Vielen Dank.




Beim Einarbeiten in diese Lösung habe ich diverse Logs angelegt.
Dabei wunderte ich mich, dass ich in den Readings neue Werte sehe, die aber im Filelog fehlten.
Ich weiß nicht, ob das wirklich stimmt. Aber im Forum habe ich etwas darüber gelesen, dass ein setreading, welches aus einem Notify getriggert wird, nicht ins Log schreiben kann.

Ich habe dein Skript nun vollständig auf readingsSingleUpdate umgestellt und beobachte das mal.




Nachtrag:
Das können wir wohl verwerfen. Das hat nicht geklappt.
Ich frage mich, warum die Funktion sub sprinkleChangeActiveZone($) zwar das Reading totalPrecipitation setzt, aber im Filelog dazu nichts ankommt.

In der CommandRef habe ich dazu folgendes gefunden:
ZitatAchtung: setreading generiert kein Event für ein Gerät X, falls es aus einem notify für Gerät X aufgerufen wurde. In so einem Fall könnte man auf "sleep 0.1; setreading X Y Z" ausweichen.

Außerdem auch diverse Threads wie https://forum.fhem.de/index.php/topic,28017.0.html.

Jedoch klappt es auch nicht, wenn ich in der Util ein sleep ergänze.

Hat jemand eine Idee?

funclass

Hallo,

die Umsetzung der Presetfunktion ist nun m.E. fertig. Habs ein wenig getestet und konnte nun keine Fehler mehr feststellen. Anpassungen gab es im Hauptdevice, im zugehörigen Notify und in der Utils-Datei. Ich werde den Code hier kurzfristig posten. Damit ist für mich alles Relevante erstmal umgesetzt. Die Integration weiterer Features schließe ich nicht aus, kann aufgrund der knappen ,,Freizeit" aber durchaus etwas länger dauern.

Bezüglich des Loggings hab ich mir ehrlich gesagt noch gar keine Gedanken gemacht. Durch die Benachrichtigung via Telegramm bin ich eigentlich immer gut informiert. Eine Option (wenn auch nicht sehr elegant) wäre sicherlich nach oder vor jedem setreading noch selbst einen Logeintrag zu schreiben. Das wäre mir aber zu viel Aufwand. Ich denke hier stoßen wir langsam an die Grenzen der ,,offenen Lösung" und bräuchten tatsächlich ein ,,echtes Modul".

FunkOdyssey

Ich versuche nun seit Tagen, die Readings ins Log zu bekommen.
Das ich ein sleep nutzen muss, hatte ich ja schnell herausgefunden.

Problem Nr.1
Ich habe leider ein Perl-Sleep und nicht ein FHEM-Sleep genutzt.

Problem Nr.2
Meine Syntax war falsch. Ich hatte immer zwei Semikolons genutzt. Dann hatte ich Fehler "Last parameter must be quiet" im FHEM-Log. Aber mit dem "sleep 0 quiet" hatte es auch nicht funktioniert. Der Grund lag in den Semikolons, da der Befehl nicht richtig erkannt wurde.

Lösung:
Könntest du deine setreading-Aufrufe bitte mit einem Sleep 0 erweitern?

fhem ("sleep 0;setreading Beregnung totalPrecipitation $precipitation");

Dann funktioniert alles perfekt.

Ich freue mich schon auf deine neue Version. Danke.

funclass

Also wenn das des Rätsels Lösung ist, sollte es kein Problem sein. Würde es in das Skript integrieren, bevor ich es hier hochlade.

networker

Ich hänge mich hier mal rein zum mitlesen, klingt interessant

laurello

@funclass: Erstmal danke für die reingesteckte Arbeit!

Ich hab das ganze bei mir jetzt auch am Laufen (noch im simulierten Betrieb) und hab mich durch die Beiträge und die Änderungen gearbeitet - läuft jetzt sehr gut.
Ich kann auch das "sleep 0" vor dem jeweilgien "setreading" bestätigen - wie von FunkOdyssey rausgefunden - das wäre wohl des Rätsels Lösung  ;) - prima!

Jetzt habe ich noch ein Problem bei der Ermittlung des "bisherigen Niederschlags". Ich hab mir schon den Kopf zerbrochen dazu und bräuchte jetzt bitte mal eure Gedanken/Meinungen, ob ich hier komplett falsch liege und ich einen groben Schnitzer im Denkansatz habe:
Der "bisherige Niederschlag" wird doch errechnet und dann in das Reading totalPrecipitation zurück geschrieben über die sub sprinkleChangeActiveZone() mit dieser Zeile:
Zitatmy $precipitation = (ReadingsVal("Beregnung", "totalPrecipitation", 0) + ((ReadingsVal("Beregnung", "pct", 100)) / (ReadingsVal("Beregnung", "defaultIntervalPrecipitation", 10))));

Idee dahinter ist, daß die bisherige Niederschlagsmenge & die Menge des Niederschlags durch die Bewässerung aufaddiert wird - korrekt soweit?

  • bisherige Niederschlagsmenge kommt aus dem reading totalPrecipitation aus dem Hauptdevice - klar! ✔
  • Niederschlagsmenge durch die Bewässerung kommt aus dem reading defaultIntervalPrecipitation aus dem Hauptdevice- also ausgebrachte Niederschlagsmenge (in l) bei 100% der definierten Zeit (maxDuration im Zonendevice) für die Zone - auch korrekt?

Müsste die Formel zur Berechnung des Niederschlags dann nicht eigentlich heißen:
my $precipitation = (ReadingsVal("Beregnung", "totalPrecipitation", 0) + ((ReadingsVal("Beregnung", "pct", 100)) * (ReadingsVal("Beregnung", "defaultIntervalPrecipitation", 10))) / 100 );
                                                                                                                                                             ^                                                                                        ^^^^
also bisherige Niederschlagsmenge + Liter Wasser aus der Bewässerung bezogen auf die momentane, prozentuale Laufzeit der Bewässerung?

Ich hoffe, ich konnte das verständlich in Worte fassen - ich hab schon einen Knoten im Hirn vom Durchdenken und Aufschreiben  ;D
Kann das jemand bitte bestätigen oder mir evtl. meinen Denkfehler erklären?

Viele Grüße,
laurello

funclass

Hallo laurello,

Hab grad ne ,,ellenlange" Beschreibung aufgeschrieben, nur um eben festzustellen, dass du Recht hast. Vielen Dank für den Hinweis. Bei mir hat die Berechnung zufällig funktioniert, da ich 10 Liter erwarte. Deine Formel ist aber genau das, was eigentlich passieren soll. Passe ich im Code an und poste es dann mit der letzten Version hier nochmal (die Presets sind im Grunde fertig, bin nur noch nicht zum exportieren gekommen).
Nun dennoch zur Sicherheit die schon aufgeschriebene Erläuterung.


Im Reading totalPrecipitation wird nach einem vollständigen (automatischen) Beregnungszyklus die beregnete Menge gespeichert.
Ebenso wird bei mir jede Nacht mittels einem eigenen at der Niederschlagswert des gesamten Tages aufaddiert. Dieses Reading speichert also die gesamte Wassermenge welche auf den Rasen fällt.
Das Reading defaultIntervalPrecipitation gibt an, welche Wassermenge im hinterlegten Zeitraum (intervalDays) gewünscht ist.
Wenn nun Nachts beim Addieren des täglichen Niederschlags (Regen) der Wert totalPrecipitation den gewünschten Wert Übersteigt, dann wird sowohl totalPrecipitation, als auch der Tageszähler zurückgesetzt.

Beispiel 1:

  • totalPrecipitation: 3 ; defaultIntervalPrecipitation: 10
  • noch 2 Tage bis bewässert werden soll
  • 8 Liter Niederschlag im Laufe des Tages
  • -> da Abends der gewünschte Wert von 10 Litern überschritten wird (3 + 8 ), wird die Zählung zurückgesetzt und von Vorn begonnen

Beispiel 2:

  • totalPrecipitation: 3 ; defaultIntervalPrecipitation: 10
  • heute wurde die Restliche Menge von 7 Litern bewässert
  • NACH dem Bewässerungszyklus addiert die Codezeile nun 7 Liter auf die bisherigen 3 Liter auf
  • -> da Abends der gewünschte Wert von 10 Litern erreicht wird, wird die Zählung zurückgesetzt und von Vorn begonnen

VG Christian

networker

Ich suche nach einer Möglichkeit einen Beregnungskreis 2x pro Tag zu starten.
Wie müsste ich dafür vorgehen?

FunkOdyssey

Könnte man in 99_sprinkleUtils.pm auch eine Lösung zum Ein- und Ausschalten der Gartenpumpe integrieren?
Ich will nach erfolgter Bewässerung die Pumpe gerne drucklos machen und schalte lieber den Strom ab.