Verschiedenes > Projekte

Bewässerungssteuerung - Vorstellung und Ideensammlung

(1/28) > >>

funclass:
UPDATE: mittlerweile ist der Code umfangreich überarbeitet worden. Die aktuellste Version ist weiter hinten in diesem Thread zu finden.
https://forum.fhem.de/index.php/topic,59872.msg1064293.html#msg1064293


Da ich schon mit einigen Leuten zu meiner Umsetzung einer Bewässerungssteuerung gesprochen habe und diese immer auf reges Interesse stieß, möchte ich die Lösung hier vorstellen. Ich habe mal drüber nachgedacht das ganze in ein Modul zu "gießen", hierfür fehlen mir jedoch weiterführende Perl-Kenntnisse und die nötige Zeit. Für Anregungen, Fragen, neue Ideen und auch Kritik bin ich offen.

Allgemeines, Voraussetzungen und Anforderungen:


* Steuerung der Bewässerung anhand der vergangenen/aktuellen Wetterlage, keine Berücksichtigung der Vorhersage (nach meiner Erfahrung zu unzuverlässig) -> Info vor nächster Bewässerung ermöglicht manuelles Eingreifen
* Wetterdaten von eigener Wetterstation oder (wie in meinem Fall) aus online verfügbaren Wetterdiensten, die Wetterstation welche über wunderground.com verfügbar ist liegt ca. 300m von mir entfernt
* innerhalb eines frei einstellbaren Zeitraums muss eine Mindestmenge an Niederschlag gemessen/kummuliert werden, ansonsten startet der Bewässerungsvorgang, ggf. mit verringerter Intensität
* Bewässerungsautomatik lässt sich zentral (de-)aktivieren -> laufender Bewässerungsvorgang wird beim Deaktivieren unterbrochen
* die Intensität/Dauer der Bewässerung kann manuell verändert werden, hängt im Automatikmodus jedoch vom gemessenen Niederschlag ab
* einzelne Bewässerungskreise können unterschiedliche Durchflussmengen haben und daher unterschiedliche Bewässerungsdauern erfordern
* der Startzeitpunkt der automatischen Bewässerung lässt sich frei einstellen
* es ist Nachvollziehbar welcher Bewässerungskreis im Automatikmodus grad aktiv ist
* ein einzelner Bewässerungskreis lässt sich manuell aktivieren inkl. Auswahl der Intensität
* Aktoren zum Schalten der Magnetventile können beliebige Schalter sein, set-extensions erleichtern erheblich die Arbeit da on-for-timer für die Bewässerungsdauer genutzt werden kann
* einzelne Aktivitäten werden als Info per Pushover versendet
* einsetzender Niederschlag unterbricht einen laufenden Bewässerungsvorgang sofort
* ein kompletter Bewässerungszyklus lässt sich per Knopfdruck sofort mit wählbarer Intensität starten
* einzelne Bewässerungskreise lassen sich deaktivieren und werden im Automatikmodus "übersprungen"
* einzelne Bewässerungskreise lassen sich manuell starten und schalten nach der eingestellten "Intensität"/Dauer automatisch wieder ab
* automatische Erkennung aller definierten Bewässerungskreise/-aktoren z.B. anhand von userreadings inkl. einfacher Vorgabe der Einschaltreihenfolge -> mittlerweile lassen sich mehrer Aktoren/Ventile zu Kreisen zusammenfassen
* das Ganze in ein Modul implementieren -> wird wohl nie werden (mir fehlt einfach die Zeit)
Weiterhin gibt es mittlerweile auch eine "abgespeckte" Version, welche ich mit nur einem Kreis für meine Tropfbewässerung nutze. Diese aktiviert sich in Abhängigkeit der "großen" Rasenbewässerung, lässt sich jedoch unabhängig davon bedienen. Doku folgt...

Im Folgenden möchte ich die einzelnen Teile etwas genauer erläutern und meinen Quellcode zur Verfügung stellen...

funclass:
"Hauptschalter"

Zentrales (de-)aktivieren der Bewässerungsautomatik.


--- Code: ---define Beregnung dummy
attr Beregnung alias Bewässerung
attr Beregnung devStateIcon on:10px-kreis-gruen off:10px-kreis-rot
attr Beregnung eventMap on:on off:off
attr Beregnung group Bewässerung
attr Beregnung icon humidity
attr Beregnung room Außen
attr Beregnung sortby 0
attr Beregnung userReadings Automatik_Aktiv,Aktiver_Regner,Tage,Menge
attr Beregnung webCmd on:off

--- Ende Code ---

Die Userreadings haben folgende Bedeutung:
Automatik_Aktiv: automatischer Bewässerungszyklus läuft gerade
Aktiver_Regner: gibt an, welcher Bewässerungskreis gerade aktiv ist -> beim manuellen Setzen außerhalb des Automatikzykluses wird der einzelne, gewählte Bewässerungskreis mit der eingestellten Intensität gestartet
Tage: Anzahl der Tage seit der letzten Bewässerung bzw. seit Erreichen der gewünschten Niederschlagsmenge
Menge: Niederschlagsmenge im Zeitraum der o.g. Tage

Ich habe für meinen Anwendungsfall festgelegt, dass 10 Liter/qm die optimale Bewässerungsmenge ist. Das heißt, jeder Kreis soll bei voller Intensität (100%) diese Menge ausbringen. Sofern innerhalb von 5 Tagen mind. 10 Liter/qm an Niederschlag gemessen werden, so wird nicht bewässert sondern beide Zähler zurückgesetzt. Ist die Menge nach 5 Tagen geringer, so wird die Intensität gewählt um 10 Liter/qm zu "komplettieren" und der Bewässerungszyklus gestartet. Die minimale Intensität beträgt jedoch 35%. Nach erfolgreicher Bewässerung wird die Bewässerte Menge auf den aktuellen Wert im Reading Menge aufaddiert. Hierdurch wird der Tageszähler am Ende des Tages zurückgesetzt. Voraussetzung für das Starten der Bewässerung ist natürlich immer der aktivierte "Hauptschalter".

Beispiele:

* Tage = 2
Menge = 3
Bewässerungszyklus startet nicht, da der vorgegebene Zeitraum von 5 Tagen noch nicht abgelaufen ist.
* Tage = 6
Menge = 0
Bewässerungszyklus startet zur gewünschten Zeit mit 100%
* Tage = 6
Menge = 3
Bewässerungszyklus startet zur gewünschten Zeit mit 70%
* Tage = 6
Menge = 9
Bewässerungszyklus startet zur gewünschten Zeit mit 35% ->Mindestintensität
* Tage = 6
Menge = 12
Bewässerungszyklus startet nicht, da gewünschte Niederschlagsmenge bereits erreicht (z.B. bei starkem Regen in den frühen Morgenstunden). Beide Zähler werden am Ende des Tages zurückgesetzt.

funclass:
Intensität

Zur Einstellung der Bewässerungsmenge (Intensität) wird ein Dummy genutzt welcher sich einfach per Slider im Bereich zwischen 0 und 100% verstellen lässt.


--- Code: ---define Beregnungsmenge dummy
attr Beregnungsmenge alias Intensität
attr Beregnungsmenge group Bewässerung
attr Beregnungsmenge icon weather_rain_gauge
attr Beregnungsmenge room Außen
attr Beregnungsmenge setList state:slider,0,1,100
attr Beregnungsmenge sortby 1
attr Beregnungsmenge stateFormat state%</br>GR: Getrieberegner min</br>SR: Spruehregner min
attr Beregnungsmenge userReadings Getrieberegner {60/100*ReadingsVal("Beregnungsmenge","state",100)}, Spruehregner {20/100*ReadingsVal("Beregnungsmenge","state",100)}, Last
attr Beregnungsmenge webCmd state

--- Ende Code ---

Die Userreadings haben folgende Bedeutung:
Getrieberegner: Dauer für Beregnungskreise mit Getrieberegnern (GR) um die gewünschte Menge auszubringen
Last: Merker für manuelle Einstellung der Intensität
Spruehregner: Dauer für Beregnungskreise mit Sprühregnern (SR) um die gewünschte Menge auszubringen

Im Hintergrund berechnet der Dummy die jeweilige Bewässerungsdauer für einzelne Bewässerungskreise. In meinem Fall gibt es 2 unterschiedliche Varianten:

* Bewässerungskreise mit Getrieberegnern benötigen 60min um die gewünschte Menge (bei mir 10L/qm) auszubringen
* Bewässerungskreise mit Sprühregnern benötigen 20min um die gewünschte Menge auszubringen
Die (Maximal-)Dauer lässt sich individuell anpassen und hängt natürlich von den eingesetzten Regnern und den örtlichen Gegebenheiten wie z.B. dem Wasserdruck ab. Es lassen sich auch noch weitere Varianten ergänzen. Im Bewässerungszyklus muss dann auf die entsprechenden Werte zurückgegriffen werden um die gewünschte Dauer zu Bewässern.
Da die Intensität im Automatikzyklus von der Niederschlagsmenge abhängt und automatisch bestimmt wird, existiert noch ein "Merker" welcher die manuell gewählte Einstellung speichert um diese nach dem Bewässerungszyklus wiederherzustellen. Um sofort die Bewässerungsdauer für die einzelnen Kreise ablesen zu können wurde das Stateformat neben der Prozentangabe um die beiden Userreadings ergänzt.

funclass:
Niederschlagszähler

Täglich kurz vor Mitternacht wird die kumulierte Niederschlagsmenge des Tages auf die, der letzten Tage aufaddiert. Ist die Menge größer als der gewünschte Wert (bei mir 10L), dann wird der Zähler, als auch die Anzahl der Tage zurückgesetzt. Ein automatischer Bewässerungszyklus erhöht ebenfalls den Zähler, wodurch dieser ebenfalls am Abend wieder zurückgestellt wird. Die Niederschlagsdaten entnehme ich einer öffentlichen Wetterstation von wunderground.com, natürlich können auch andere öffentliche oder eigene Wetterstationen als Quelle dienen.


--- Code: ---define Niederschlag_schreiben at *23:59:30 {\
my $aktuell = ReadingsVal('Beregnung', 'Menge', '0');;\
my $niederschlag = ReadingsVal('wu_conditions', 'current_observation_precip_today_metric', '0') + $aktuell;;\
my $tage = ReadingsVal('Beregnung', 'Tage', '0') + 1;;\
# wenn Niederschlagsmenge >= 10, dann Werte zurücksetzen\
{if ($niederschlag >= 10) {\
$niederschlag = 0;;\
$tage = 1;;\
}}\
fhem "setReading Beregnung Menge $niederschlag";;\
fhem "setReading Beregnung Tage $tage";;\
}
attr Niederschlag_schreiben group Bewässerung
attr Niederschlag_schreiben icon weather_rain_meter
attr Niederschlag_schreiben room Außen

--- Ende Code ---

funclass:
Bewässerungskreissteuerung

Das Aktivieren der einzelnen Bewässerungskreise erfolgt über ein einzelnes Userreading (Aktiver_Regner) im "Hauptschalter". Damit lässt sich relativ einfach ein einzelner Kreis aktivieren oder eine individuelle Reihenfolge realisieren. Der Zugriff auf die Aktoren, welche die Magnetventile ansteuern geschieht gekapselt durch dieses Notify. In meinem Fall hängen alle Magnetventile an einem Relaisblock, welcher durch einen Arduino Nano mit FIRMATA angesteuert wird. Durch set-extensions kann ich den on-for-timer Befehl nutzen und somit muss ich mich nur ums Einschalten und die Zeitvorgabe kümmern. Einen direkten, manuellen Zugriff vermeide ich, da hierbei die Intensität und andere Mechanismen nicht berücksichtigt würden. Direktes Bedienen der Aktoren nutze ich lediglich für Testzwecke oder z.B. beim Einwintern der Bewässerungsanlage.

Wird das Reading "Aktiver_Regner" auf einen Wert zwischen 1 und 4 gesetzt, wird der entsprechende Bewässerungskreis für die eingestellte Dauer im Dummy "Intensität" eingeschaltet und eine Infomeldung per Pushover versendet. Das Setzen kann durch den Automatikzyklus oder auch manuell geschehen.

Wird das Reading "Aktiver_Regner" auf 0 gesetzt, werden alle Aktoren ausgeschaltet.
+ Sofern der Automatikzyklus aktiv ist wird dieser beendet. Sollten noch Zeitgeber vorhanden sein, so werden diese gelöscht. Außerdem wird die bewässerte Menge auf den Zähler aufaddiert und die zuletzt eingestellte Intensität wiederhergestellt.


--- Code: ---define notify_Beregnungskreis notify Beregnung:Aktiver_Regner:.* {\
# Prüfen welcher Beregnungskreis aktiviert werden soll...\
my $beregnungskreis = ReadingsVal('Beregnung', 'Aktiver_Regner', '0');;\
{if ($beregnungskreis eq '0') {\
# alles ausschalten und ggf. Zeitgeber löschen\
fhem ("set Relais01,Relais02,Relais03,Relais04 off");;\
{if (ReadingsVal('Beregnung', 'Automatik_Aktiv', '0') eq 'ja') {\
fhem ("setReading Beregnung Automatik_Aktiv nein");;\
fhem ("delete autoRegner.*");;\
fhem ("set pushmsg msg 'Beregnung' 'Automatikprogramm Rasenbewässerung beendet.' 'iPhone' -1 ''");;\
# Beregnungsmenge wieder zurücksetzen\
my $menge_aktuell = ReadingsVal('Beregnungsmenge', 'state', '0');;\
my $menge_last = ReadingsVal('Beregnungsmenge', 'Last', '0');;\
fhem ("set Beregnungsmenge $menge_last");;\
fhem ("setReading Beregnungsmenge Last $menge_aktuell");;\
# Tageszähler zurücksetzen\
my $menge = ReadingsVal('Beregnung', 'Menge', '0') + ($menge_aktuell / 10);;\
fhem ("setReading Beregnung Menge $menge_aktuell");;\
}}\
}}\
my $min_gr = ReadingsVal("Beregnungsmenge","Getrieberegner",'0');;\
my $sek_gr = $min_gr * 60 - 10;;\
my $min_sr = ReadingsVal("Beregnungsmenge","Spruehregner",'0');;\
my $sek_sr = $min_sr * 60 - 10;;\
\
{if ($beregnungskreis eq '1') {\
fhem ("set Relais01 on-for-timer $sek_gr");;\
fhem ("set pushmsg msg 'Beregnung' 'Regner Hinten für $min_gr Minuten eingeschaltet.' 'iPhone' -1 ''");;\
}}\
{if ($beregnungskreis eq '2') {\
fhem ("set Relais02 on-for-timer $sek_gr");;\
fhem ("set pushmsg msg 'Beregnung' 'Regner Terrasse für $min_gr Minuten eingeschaltet.' 'iPhone' -1 ''");;\
}}\
{if ($beregnungskreis eq '3') {\
fhem ("set Relais03 on-for-timer $sek_sr");;\
fhem ("set pushmsg msg 'Beregnung' 'Regner Vorn für $min_sr Minuten eingeschaltet.' 'iPhone' -1 ''");;\
}}\
{if ($beregnungskreis eq '4') {\
fhem ("set Relais04 on-for-timer $sek_sr");;\
fhem ("set pushmsg msg 'Beregnung' 'Regner Seite für $min_sr Minuten eingeschaltet.' 'iPhone' -1 ''");;\
}}\
}
attr notify_Beregnungskreis group Bewässerung
attr notify_Beregnungskreis icon control_arrow_rightward
attr notify_Beregnungskreis room Außen

--- Ende Code ---

Navigation

[0] Themen-Index

[#] Nächste Seite

Zur normalen Ansicht wechseln