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