Es hat eine Weile gedauert, bis es so lief, wie ich mir das vorgestellt habe. Wer diese Steuerung für seine Beregnung im Garten nutzen möchte, kann das gern tun. Dabei lassen sich eigene Bewässerungskreise (auch zeitlich) sperren und auch die gesamte Bewässerung. Angesteuert wird in meinem Fall ein per KNX angebundener Schaltaktor, der die Magnetventile schaltet.
Einstellungen der KNX-Komponenten:
Ich habe, wie schon oben erwähnt einen KNX-Aktor angebunden. Dabei habe ich dort die Treppenlicht-Funktion aktiviert, sodass im Falle eines Falles die Bewässerung nach 30 Minuten beendet wird. Ich habe einen MDT-Schaltaktor verwendet und kann daher nicht für andere Aktoren sprechen. Ich kann die Beregnungsdauer direkt als Wert per Gruppenadresse an den Aktor übergeben. Wichtig ist hier auch die Einheit korrekt einzustellen. Bei mir habe ich Minuten eingestellt. Die Gruppenadresse für die globale Sperrfunktion der Beregnung habe ich auch auf eine Gruppenadresse gelegt. Das ist quasi die "harte" Sperre.
Installation in SmartHomeNG:
Anlage der Grundstruktur der Items in der struct.yaml:
Die neue "struct" ab SmartHomeNG 1.6 hat den immensen Vorteil, dass man nicht so viel schreiben muss. ;-) Es spart sich wiederholenden textzeilen und sorgt für eine echt viel bessere Übersicht.
Anlage der items in meiner Bewaesserung.yaml:
Exemplarisch habe ich hier nur 2 Bewässerrungskreise reingenommen. Diese können jedoch beliebig erweitert werden. In meinem Beispiel die GA 11/3/0 ist direkt mit den einzelnen Sperren der Aktorkanäle verbunden. 11/3/1 ist derzeit nicht an einem KNX-Teilnehmer verbunden, könnte theoretisch auch weggelassen werden.
11/0/x definiert hier die Schaltfunktion für den entsprechenden Aktor-Kanal, 11/1/x die Statusrückmeldung des Aktor-Kanals. 11/2/x gibt definiert die Dauer der "Einschaltung".
Ermittlung des Regens:
Ich habe eine Wetterstation und die ermittelt die Regendauer. Das Regen-Item wird einfach in die Datenbank geschrieben. Also mit
Wichtig ist aber, dass das database-plugin auch schon eingerichtet ist.
Dann noch die Logik bewaesserung.py:
Im Feld crontab wird eingtragen, dass die Logik zu jeder vollen Stunde aufgerufen wird
Auch hier habe ich wieder exemplarisch 2 Bewässerungskreise eingefügt. Die Konfiguration der Bewässerung erfolgt dann nur noch über die Logik. Die manuelle Steuerung ist auch mittels VISU über die Items möglich. DIe meisten Einstellungen erklären sich sicherlich von selbst, bzw. sind dort auch beschrieben. Eine Anmerkung noch zu den Pausen, wegen Regen. Dort muss nicht explizit eine "0" als Wert drin stehen, wenn man diese Pause gar nicht verwenden will. Man kann die Zeile dann auch einfach weg lassen. Ich habe es nur drin, weil ich da noch viel von den Zeiten ändere. Meine Rasen-Aussat ist frisch und deshalb beregne ich so oft. In der Realität muss man da aber seinen eigenen Weg finden.
Wichtig ist, dass hier das Regen-Item verwendet wird. Bei der Abfrage der Datenbank ganz oben im Code, muss dieses angepasst werden. Genauso auch ganz unten beim Aufruf der Bewässerungsfunktion. Denn es werden 2 Konstellationen betracht: "es regnet gerade", "es hat in einem Zeitraum x", geregnet.
Um weitere Bewässerungskreise hinzuzufügen, kopiert man zum einen die Einstellungen und zum anderen ganz unten noch mal den Aufruf der Bewässerungsfunktion.
Geplant ist auch noch den Wind mit reinzunehmen und die Bewässerung dann entsprechend zu schieben.
In meinem Beispiel wird die Bewässerung jeden Tag alle 4 Stunden ausgeführt. Dabei startet Nordost mit einer Dauer von 10 Minuten. Südost startet direkt, wenn Nordost beendet ist für eien Dauer von 10 Minuten.
Viel Spaß. Und hier mal noch ein Bild aus meiner SmartVISU.
Bewaesserung smartvisut.png
Einstellungen der KNX-Komponenten:
Ich habe, wie schon oben erwähnt einen KNX-Aktor angebunden. Dabei habe ich dort die Treppenlicht-Funktion aktiviert, sodass im Falle eines Falles die Bewässerung nach 30 Minuten beendet wird. Ich habe einen MDT-Schaltaktor verwendet und kann daher nicht für andere Aktoren sprechen. Ich kann die Beregnungsdauer direkt als Wert per Gruppenadresse an den Aktor übergeben. Wichtig ist hier auch die Einheit korrekt einzustellen. Bei mir habe ich Minuten eingestellt. Die Gruppenadresse für die globale Sperrfunktion der Beregnung habe ich auch auf eine Gruppenadresse gelegt. Das ist quasi die "harte" Sperre.
Installation in SmartHomeNG:
Anlage der Grundstruktur der Items in der struct.yaml:
Die neue "struct" ab SmartHomeNG 1.6 hat den immensen Vorteil, dass man nicht so viel schreiben muss. ;-) Es spart sich wiederholenden textzeilen und sorgt für eine echt viel bessere Übersicht.
Code:
# Bewässerung Bewaesserung: schalten: type: bool knx_dpt: 1 visu_acl: rw on_update: - .Dauer = 0 if not value else None # Beregnungsdauer in Minuten Dauer: type: num knx_dpt: 5 enforce_updates: yes visu_acl: rw sperren: type: bool cache: yes visu_acl: rw on_change: - .Dauer = 0 if not value else None # Sperrzeit in Stunden Dauer: type: num enforce_updates: yes cache: yes visu_acl: rw on_update: - ..self = True if value > 0 else False - ..self = sh...self.timer(value*60*60, False) if value > 0 else None
Exemplarisch habe ich hier nur 2 Bewässerrungskreise reingenommen. Diese können jedoch beliebig erweitert werden. In meinem Beispiel die GA 11/3/0 ist direkt mit den einzelnen Sperren der Aktorkanäle verbunden. 11/3/1 ist derzeit nicht an einem KNX-Teilnehmer verbunden, könnte theoretisch auch weggelassen werden.
11/0/x definiert hier die Schaltfunktion für den entsprechenden Aktor-Kanal, 11/1/x die Statusrückmeldung des Aktor-Kanals. 11/2/x gibt definiert die Dauer der "Einschaltung".
Code:
Aussen: Garten: Bewaesserung: sperren: type: bool knx_dpt: 1 knx_send: 11/3/0 knx_cache: 11/3/0 visu_acl: rw Dauer: type: num knx_dpt: 5 knx_send: 11/3/1 knx_reply: 11/3/1 enforce_updates: yes cache: yes visu_acl: rw on_update: - ..self = True if value > 0 else False - ..self = sh...self.timer(value*60*60, False) if value > 0 else None Nordost: struct: Bewaesserung schalten: knx_send: 11/0/0 knx_cache: 11/1/0 Dauer: knx_send: 11/2/0 knx_cache: 11/2/0 Suedost: struct: Bewaesserung schalten: knx_send: 11/0/1 knx_cache: 11/1/1 Dauer: knx_send: 11/2/1 knx_cache: 11/2/1
Ich habe eine Wetterstation und die ermittelt die Regendauer. Das Regen-Item wird einfach in die Datenbank geschrieben. Also mit
Code:
database: yes
Dann noch die Logik bewaesserung.py:
Im Feld crontab wird eingtragen, dass die Logik zu jeder vollen Stunde aufgerufen wird
Code:
0 * * *
Wichtig ist, dass hier das Regen-Item verwendet wird. Bei der Abfrage der Datenbank ganz oben im Code, muss dieses angepasst werden. Genauso auch ganz unten beim Aufruf der Bewässerungsfunktion. Denn es werden 2 Konstellationen betracht: "es regnet gerade", "es hat in einem Zeitraum x", geregnet.
Um weitere Bewässerungskreise hinzuzufügen, kopiert man zum einen die Einstellungen und zum anderen ganz unten noch mal den Aufruf der Bewässerungsfunktion.
Geplant ist auch noch den Wind mit reinzunehmen und die Bewässerung dann entsprechend zu schieben.
Code:
#!/usr/bin/env python3 # bewaesserung.py # Version 0.11 jetzt = sh.now() regendauer_48h = round((sh.Zentral.Wetter.Wetterstation.Regen.db('avg', '48h') or 0) * 2880) regendauer_24h = round((sh.Zentral.Wetter.Wetterstation.Regen.db('avg', '24h') or 0) * 1440) regendauer_12h = round((sh.Zentral.Wetter.Wetterstation.Regen.db('avg', '12h') or 0) * 720) regendauer_6h = round((sh.Zentral.Wetter.Wetterstation.Regen.db('avg', '6h') or 0) * 360) # NORDOST # Tage an denen bewässert werden soll Nordost_Tage = [1, 2, 3, 4, 5, 6, 7] # Stunden zu denen bewässert werden soll Nordost_Stunden = [2, 6, 10, 14, 18, 22] # Dauer der Bewässerung in Minuten Nordost_Dauer = 10 # Startvorwahl der Bewässerung in Minuten Nordost_Start = 0 # Bewässerungspause in Stunden, wenn es regnet oder regnete # Bewässerung wird ausgesetzt, wenn es innerhalb von 48 h min. 40 Minuten regnete # Bewässerung wird ausgesetzt, wenn es innerhalb von 24 h min. 20 Minuten regnete # Bewässerung wird ausgesetzt, wenn es innerhalb von 12 h min. 10 Minuten regnete # Aussetzung der Bewässerung bei Regen innerhalb von 6 h wird nicht überprüft Nordost_Regen_Pause = [ [regendauer_48h, 40], [regendauer_24h, 20], [regendauer_12h, 10], [regendauer_6h, 0] ] # SÜDOST Suedost_Tage = [1, 2, 3, 4, 5, 6, 7] Suedost_Stunden = [2, 6, 10, 14, 18, 22] Suedost_Dauer = 10 Suedost_Start = 10 Suedost_Regen_Pause = [ [regendauer_48h, 0], [regendauer_24h, 0], [regendauer_12h, 0], [regendauer_6h, 10] ] # Zeit = aktuelles Datum und Uhrzeit # itemDauer = item für die Bewässerungsdauer # itemSperren = item zum sperren der Bewässerung # Regen = True: es regnet; False: es regnet nicht # Bezeichnung = Bezeichnung der Bewässerung # Tage = Liste von Wochentagen an denen bewässert werden soll # Stunden = Liste von Stunden an denen bewässert werden soll # Dauer = Dauer der Bewässerung in Minuten # Startvorwahl = Start der Bewässerung in Minuten # Regenpause = Matrix als Regendauer und Regenpause -> wie lange wird ausgesetzt def Bewaesserung(Zeit, itemDauer, itemSperren, Bezeichnung, Regen, Tage, Stunden, Dauer, Startvorwahl, Regenpause): #heute = Zeit.date() #zeit = Zeit.time() stunde = Zeit.hour tag = Zeit.isoweekday() result = False resulttxt = None if tag in Tage and stunde in Stunden: if not itemSperren(): # es regnet derzeit nicht if not Regen: # ermitteln, ob eine bestimmte Zeit Regen, innerhalb konfigurierter Zeiträume, gefallen ist regenpause = False for row in Regenpause: regendauer = row[0] regenlimit = row[1] if regenlimit > 0 and regenlimit < regendauer: regenpause = True if not regenpause: if Dauer > 0: itemDauer.timer(Startvorwahl * 60, Dauer) result = True resulttxt = 'Bewässerung {} wird gestartet in {} Minuten für eine Dauer von {} Minuten.'.format(Bezeichnung, Startvorwahl, Dauer) else: resulttxt = 'Bewässerung {} wurde nicht gestartet, weil die Dauer auf 0 eingestellt ist.'.format(Bezeichnung) else: resulttxt = 'Bewässerung {} ist pausiert, weil es ausreichend regnete.'.format(Bezeichnung) else: resulttxt = 'Bewässerung {} ist pausiert, weil es gerade regnet.'.format(Bezeichnung) else: resulttxt = 'Bewässerung {} ist manuell gesperrt.'.format(Bezeichnung) return result, resulttxt if not sh.Aussen.Garten.Bewaesserung.sperren(): result_code, result_text = Bewaesserung(jetzt, sh.Aussen.Garten.Bewaesserung.Nordost.schalten.Dauer, sh.Aussen.Garten.Bewaesserung.Nordost.sperren, 'Nordost', sh.Zentral.Wetter.Wetterstation.Regen(), Nordost_Tage, Nordost_Stunden, Nordost_Dauer, Nordost_Start, Nordost_Regen_Pause) if result_text: logger.info(result_text) result_code, result_text = Bewaesserung(jetzt, sh.Aussen.Garten.Bewaesserung.Suedost.schalten.Dauer, sh.Aussen.Garten.Bewaesserung.Suedost.sperren, 'Südost', sh.Zentral.Wetter.Wetterstation.Regen(), Suedost_Tage, Suedost_Stunden, Suedost_Dauer, Suedost_Start, Suedost_Regen_Pause) if result_text: logger.info(result_text)
Viel Spaß. Und hier mal noch ein Bild aus meiner SmartVISU.
Bewaesserung smartvisut.png
Kommentar