in den letzten Wochen hab ich mich intensiv mit meiner automatischen Gartenbewässerung / Beregnung beschäftigt und möchte nun die Ergebnisse mit euch teilen.
Als erstes mal jede Menge PE-HD Rohr unter die Erde bringen
Verbaut habe ich Rain Bird Regner und Hunter Magentventile (Empfehlung von Seppy )
Wer weitere Details zu den Komponenten der eingentlichen Bewässerung haben möchte, bitte PN an mich.
Steuerung:
Für die Steuerung der Beregnung habe ich folgende Komponenten verbaut:
Aktor(WIFI): Sonoff 4CH R2 (sehr günstige Alternative zum HomeMatic Funk-Schaltaktor 4-fach / Hutschiene)
Wichtig ist hier die PRO R2 Version!
Trafo(24VAC): Vemer vn318200 Trafo TMC 24/24
Auf den Sonoff habe ich selbstverständlich Tasmota geflashed
In der Unterverteilung sieht das Ganze dann so aus:
So nun kommen wir mal zum opemHAB-Teil des Projektes. Die ITEMS und Rules wurden unter openHAB 2.3 erstellt!
ITEMS:
Als erstes nutze ich das Wunderground-Binding und seine ITEMS
Wunderground-Items
irrigation.items
Code: Alles auswählen
/* ------------- BEREGNUNG --------------------
*/
//--------------- Magnetventilschalter Hutschiene (Sonoff 4CH Pro R2) ----------------
Group:Switch:OR(ON, OFF) gABBeregnung "Gartenbewässerung" <irrigation> (gGarten)
Switch ABBeregnungMGV1 "MGV1 - Beregnung Segment (vorne)" <irrigation> (gABBeregnung,gIrrigation,gInitializeOff) {mqtt=">[mosquitto:sonoff/ABBeregnung/cmnd/POWER1:command:*:default], <[mosquitto:sonoff/ABBeregnung/stat/POWER1:state:default]"}
Switch ABBeregnungMGV2 "MGV2 - Beregnung Segment (mitte)" <irrigation> (gABBeregnung,gIrrigation,gInitializeOff) {mqtt=">[mosquitto:sonoff/ABBeregnung/cmnd/POWER2:command:*:default], <[mosquitto:sonoff/ABBeregnung/stat/POWER2:state:default]"}
Switch ABBeregnungMGV3 "MGV3 - Beregnung Segment (hinten)" <irrigation> (gABBeregnung,gIrrigation,gInitializeOff) {mqtt=">[mosquitto:sonoff/ABBeregnung/cmnd/POWER3:command:*:default], <[mosquitto:sonoff/ABBeregnung/stat/POWER3:state:default]"}
Switch ABBeregnungMGV4 "MGV4 - Beregnung Segment (xxxx)" <irrigation> (gABBeregnung,gIrrigation,gInitializeOff) {mqtt=">[mosquitto:sonoff/ABBeregnung/cmnd/POWER4:command:*:default], <[mosquitto:sonoff/ABBeregnung/stat/POWER4:state:default]"}
Number ABBeregnung_RSSI "Magnetventilschalter RSSI [%d %%]" <network> (gSysRSSI) {mqtt="<[mosquitto:sonoff/ABBeregnung/tele/STATE:state:JSONPATH($.Wifi.RSSI)]"}
Switch ABBeregnung_Unreach "Magnetventilschalter unreachable" <siren> (gSysUnreach) {mqtt="<[mosquitto:sonoff/ABBeregnung/tele/LWT:state:MAP(unreach.map)]"}
String ABBeregnung_FW "Magnetventilschalter Firmware [%s]" <sonoff_4chpro> (gSysSonoff_Maintenance) {mqtt="<[mosquitto:stat/ABBeregnung/STATUS2:state:JSONPATH($.StatusFWR.Version)"}
/* ------------- GRUPPEN --------------------
*/
Group gProgramSettings "Einstellungen" (gIrrigation)
//Programm A
Group gProgramASettings "Programm A - Einstellungen" <settings> (gProgramSettings)
Group gProgramADuration "Laufzeit" (gProgramASettings)
Group gProgramADayOfWeek "Wochentag" (gProgramASettings)
//Programm B
Group gProgramBSettings "Programm B - Einstellungen" <settings> (gProgramSettings)
Group gProgramBDuration "Laufzeit" (gProgramBSettings)
Group gProgramBDayOfWeek "Wochentag" (gProgramBSettings)
/* ------------- ITEMS --------------------
*/
//MISC
Number ABBeregnung_Scale_Factor "Skalierungsfaktor (Rain, Temp., Humidity) [%d %%]" <water> (gIrrigation)
//Virtuelle Schalter Beregnung
Switch ABBeregnungMGV1_State "MGV1 - Beregnungssegment (vorne)" <irrigation> (gIrrigation,gInitializeOff)
Switch ABBeregnungMGV2_State "MGV2 - Beregnungssegment (mitte)" <irrigation> (gIrrigation,gInitializeOff)
Switch ABBeregnungMGV3_State "MGV3 - Beregnungssegment (hinten)" <irrigation> (gIrrigation,gInitializeOff)
Switch ABBeregnung_Disable "Deaktivierung der kompletten Beregnung" <irrigation> (gIrrigation,gInitializeOff)
//letzter Beregnungslauf
DateTime ABBeregnungMGV1_LastRun "Letzte Beregnung (vorne) [%1$td.%1$tm.%1$tY %1$tH:%1$tM]" <time> (gIrrigation)
DateTime ABBeregnungMGV2_LastRun "Letzte Beregnung (mitte) [%1$td.%1$tm.%1$tY %1$tH:%1$tM]" <time> (gIrrigation)
DateTime ABBeregnungMGV3_LastRun "Letzte Beregnung (hinten) [%1$td.%1$tm.%1$tY %1$tH:%1$tM]" <time> (gIrrigation)
// Programm A Master Einstellungen
Switch ProgramA_Master "Bewässerungsprogramm A" <irrigation> (gProgramASettings)
Switch ProgramA_Master_DayofWeek "Programm A Wochentag [%s]" <calendar> (gProgramASettings)
Switch ProgramA_Master_Weather "Regen im Forecast (Rain Delay) [%s]" <rain> (gProgramASettings)
Number ProgramA_ScaleFactor "Scale Factor [%d %%]" <water> (gProgramASettings)
String ProgramA_StartTime "nächste Startzeit [%s]" <calendar> (gProgramASettings)
Number ProgramA_StartTime_Hours "Startzeit - Stunden [%d]" <time> (gProgramASettings)
Number ProgramA_StartTime_Minutes "Startzeit - Minuten [%d]" <time> (gProgramASettings)
// Programm A Einstellungen
Number ABBeregnungMGV1_Duration_A "Laufzeit Beregnungssegment (vorne) [%d Min.]" <time> (gProgramASettings, gProgramADuration)
Number ABBeregnungMGV2_Duration_A "Laufzeit Beregnungssegment (mitte) [%d Min.]" <time> (gProgramASettings, gProgramADuration)
Number ABBeregnungMGV3_Duration_A "Laufzeit Beregnungssegment (hinten) [%d Min.]" <time> (gProgramASettings, gProgramADuration)
Number ABBeregnungMGV4_Duration_A "Laufzeit Beregnungssegment 4 [%d Min.]" <time> (gProgramASettings, gProgramADuration)
Switch Monday_ProgramA "Montag [%s]" <calendar> (gProgramASettings, gProgramADayOfWeek)
Switch Tuesday_ProgramA "Dienstag [%s]" <calendar> (gProgramASettings, gProgramADayOfWeek)
Switch Wednesday_ProgramA "Mittwoch [%s]" <calendar> (gProgramASettings, gProgramADayOfWeek)
Switch Thursday_ProgramA "Donnerstag [%s]" <calendar> (gProgramASettings, gProgramADayOfWeek)
Switch Friday_ProgramA "Freitag [%s]" <calendar> (gProgramASettings, gProgramADayOfWeek)
Switch Saturday_ProgramA "Samstag [%s]" <calendar> (gProgramASettings, gProgramADayOfWeek)
Switch Sunday_ProgramA "Sonntag [%s]" <calendar> (gProgramASettings, gProgramADayOfWeek)
// Programm B Master Einstellungen
Switch ProgramB_Master "Bewässerungsprogramm B" <irrigation> (gProgramBSettings)
Switch ProgramB_Master_DayofWeek "Programm B Wochentag [%s]" <calendar> (gProgramBSettings)
Switch ProgramB_Master_Weather "Programm B Rain Delay [%s]" <water> (gProgramBSettings)
Number ProgramB_ScaleFactor "Scale Factor [%d %%]" <water> (gProgramBSettings)
String ProgramB_StartTime "Startzeit [%s]" <calendar> (gProgramBSettings)
Number ProgramB_StartTime_Hours "Stunden [%d]" <time> (gProgramBSettings)
Number ProgramB_StartTime_Minutes "Minuten [%d]" <time> (gProgramBSettings)
// Programm B Einstellungen
Number ABBeregnungMGV1_Duration_B "Segment (vorne) Laufzeit[%d Min.]" <water> (gProgramBSettings)
Number ABBeregnungMGV2_Duration_B "Segment (mitte) Laufzeit[%d Min.]" <water> (gProgramBSettings)
Number ABBeregnungMGV3_Duration_B "Segment (hinten) Laufzeit[%d Min.]" <water> (gProgramBSettings)
Number ABBeregnungMGV4_Duration_B "Segment 4 Laufzeit[%d Min.]" <water> (gProgramBSettings)
Switch Monday_ProgramB "Montag [%s]" <calendar> (gProgramBSettings)
Switch Tuesday_ProgramB "Dienstag [%s]" <calendar> (gProgramBSettings)
Switch Wednesday_ProgramB "Mittwoch [%s]" <calendar> (gProgramBSettings)
Switch Thursday_ProgramB "Donnerstag [%s]" <calendar> (gProgramBSettings)
Switch Friday_ProgramB "Freitag [%s]" <calendar> (gProgramBSettings)
Switch Saturday_ProgramB "Samstag [%s]" <calendar> (gProgramBSettings)
Switch Sunday_ProgramB "Sonntag [%s]" <calendar> (gProgramBSettings)
irrigation.rules
Der nachfolgende Code steht in einem Rule File, aber der Übersicht halber splitte ich mal Rule für Rule und kommentiere ein bischen.
Los geht es mit den globalen Variablen.
Code: Alles auswählen
val String filename = "irrigation.rules" // Loggername
// Automatische Beregnungstimer
var Timer MGV1StartTimer = null
var Timer MGV1StopTimer = null
var Timer MGV2StartTimer = null
var Timer MGV2StopTimer = null
var Timer MGV3StartTimer = null
var Timer MGV3StopTimer = null
//var Timer WateringStopTimer = null
// Manuelle Beregnugstimer
var Timer IrrigationTimer = null
//
val int maxOffDays = 2 //nach 2 Tagen wird der ProgramA_Master_Weather OFF geschaltet
val int minPrecipPercent = 50 //die minimale Niederschlagswahrscheinlichkeit zum Einschalten des ProgramA_Master_Weather
val int minPrecip = 4 //die Mindestmenge an Regen in den letzten 24 Stunden zum Einschalten des ProgramA_Master_Weather
Code: Alles auswählen
rule "Irrigation startup"
when
System started
then
gABBeregnung?.allMembers.filter(x | x.state != OFF).forEach[ item |
logInfo(filename,"Beregnung: Beregnung wird deaktiviert")
item.sendCommand(OFF)
]
end
Code: Alles auswählen
rule "Rain Delay"
when
Time cron "5 15 23 ? * * *" //23:15:05
then
if (ProgramA_Master_Weather.lastUpdate.before(now.minusDays(maxOffDays))) {
ProgramA_Master_Weather.sendCommand(OFF)
}
else {
var boolean delay = false
//Es hat heute geregnet min. 4mm
if ((RainToday.state as QuantityType<Number>).doubleValue >= minPrecip) {
delay = true
}
//Regen im Forecast min. 50%
if ((ForecastProbaPrecip_day1.state as QuantityType<Number>).doubleValue >= minPrecipPercent) {
delay = true
}
if (delay) {
ProgramA_Master_Weather.sendCommand(ON)
logInfo(filename,"Beregnung: Es hat geregnet oder Regen im Forecast")
sendPushoverMessage(pushoverBuilder("Es hat geregnet heute geregnet oder die Regenwahrscheinlichkeit für morgen liegt über 50%. Die beregnung wird für 2 tage deaktiviert"))
}
else {
ProgramA_Master_Weather.sendCommand(OFF)
}
}
end
Code: Alles auswählen
rule "Update rain yesterday"
when
Time cron "0 59 23 * * ?" //23:59:00
then
if (RainToday.state !== null)
{
RainYesterday.postUpdate(RainToday)
}
end
Beispiel: Normale Laufzeit eines Regners sind 15Min.(100%). Wenn nun der Scale Factor bei 115% liegt, läuft der Regner 17,25Min.
Code: Alles auswählen
rule "Calculate irrigation scale factor"
when
Time cron "35 0/15 * * * ?" //alle 15Min und 15sek
then
// die Durchschnittswerte der letzten 24 Stunden via persistence ermitteln
// Luftfeuchtigkeit
var Number averageHumidity = 30.0
averageHumidity = Humidity.averageSince(now.minusHours(24), "influxdb")
// Temperatur
var Number averageTemp = 20.0
averageTemp = Temperature.averageSince(now.minusHours(24), "influxdb")
// Regen
var Number rainToday = 0
rainToday = RainToday.state
var Number rainYesterday = 0
if (RainYesterday.historicState(now.withTimeAtStartOfDay, "influxdb") !== null) {
rainYesterday = RainYesterday.historicState(now.withTimeAtStartOfDay, "influxdb").state as DecimalType
}
// Berechnung der verschiedenen Skalierungsfaktoren
var Number humidityFactor = (30.0 - averageHumidity) * 1
var Number tempFactor = (averageTemp - 21.0) * 4
var Number rainFactor = (rainToday * -10.0) + (rainYesterday * -6.0)
// Berechnung des Gesamtskalenfaktors
var Number scaleFactor = (100 + humidityFactor + tempFactor + rainFactor)
// apply limits (0 to 200%)
if (scaleFactor < 0)
scaleFactor = 0
else if (scaleFactor > 200)
scaleFactor = 200
// Update veröffentlichen, damit die Bewässerungsregeln es verwenden können.
ABBeregnung_Scale_Factor.postUpdate(scaleFactor.intValue)
// die berechneten Werte protokollieren
logInfo(filename,"Beregnung: Scale factor parameters: avgHumidity=" + String::format("%.2f", averageHumidity.floatValue) + ", avgTemp=" + String::format("%.2f", averageTemp.floatValue) + ", rainToday=" + String::format("%.1f", rainToday.floatValue) + ", rainYesterday=" + String::format("%.1f", rainYesterday.floatValue))
logInfo(filename,"Beregnung: Calculated scale factor is " + scaleFactor.intValue + "% (humidity=" + String::format("%.2f", humidityFactor.floatValue) + ", temp=" + String::format("%.2f", tempFactor.floatValue) + ", rain=" + String::format("%.2f", rainFactor.floatValue) + ")")
end
Code: Alles auswählen
rule "Set Program A Startime"
when
Item ProgramA_StartTime_Minutes received update or
Item ProgramA_StartTime_Hours received update
then
if (ProgramA_StartTime_Minutes.state == 60){
ProgramA_StartTime_Minutes.sendCommand(0)
}
if (ProgramA_StartTime_Hours.state == 24){
ProgramA_StartTime_Hours.sendCommand(0)
}
var int minutes = (ProgramA_StartTime_Minutes.state as DecimalType).intValue()
var int hours = (ProgramA_StartTime_Hours.state as DecimalType).intValue()
// Zeitpunkt des Programmstarts festlegen
var DateTime startTime = parse(now.getYear() + "-" + now.getMonthOfYear() + "-" + now.getDayOfMonth() + "T" + hours + ":" + minutes)
// update der Startzeit in der für Rules und Anzeige
ProgramA_StartTime.sendCommand(String::format("%02d:%02d", startTime.getHourOfDay(), startTime.getMinuteOfHour()))
end
Code: Alles auswählen
rule "Automatic Irrigation"
when
Item ProgramA_Master received update ON or
Time cron "15 30 5 ? * * *"
then
var dayOfWeekSetting = newArrayList(
Monday_ProgramA.state,
Tuesday_ProgramA.state,
Wednesday_ProgramA.state,
Thursday_ProgramA.state,
Friday_ProgramA.state,
Saturday_ProgramA.state,
Sunday_ProgramA.state
)
if (dayOfWeekSetting.get(now.getDayOfWeek-1) == OFF){
ProgramA_Master_DayofWeek.sendCommand(OFF)
return
} else {
ProgramA_Master_DayofWeek.sendCommand(ON)
}
if (ABBeregnung_Disable.state == ON) {
//Das gesamte Bewässerungssystem ist deaktiviert.
logInfo(filename,"Beregnung: Gesamte Beregnung deaktiviert!")
return
}
if (ProgramA_Master_Weather.state == ON) {
//Regen im Forecast.
logInfo(filename,"Beregnung: Es hat geregnet oder Regen im Forecast")
return
}
if (ABBeregnung_Scale_Factor.state < 10) {
//Scale Factor ist kleiner 10%..keine Beregnung nötig
logDebug(filename,"Beregnung: Der Boden ist feucht genug, Beregung nicht notwendig")
return
}
if (ProgramA_Master.state == ON) {
logInfo(filename,"Beregnung: Programm A wird geladen")
// liefert den Skalierungsfaktor - wird verwendet, um die Laufzeiten zu reduzieren
var Number scaleFactor = ABBeregnung_Scale_Factor.state as DecimalType
logInfo(filename,"Beregnung: Skalierungsfaktor " + scaleFactor)
// Startzeit in eine joda.time.DateTime für heute umwandeln
var int minutes = (ProgramA_StartTime_Minutes.state as DecimalType).intValue()
var int hours = (ProgramA_StartTime_Hours.state as DecimalType).intValue()
var DateTime startTime = parse(now.getYear() + "-" + now.getMonthOfYear() + "-" + now.getDayOfMonth() + "T" + hours + ":" + minutes)
logInfo(filename,"Beregnung: Startzeit Programm A: " + startTime)
var DateTime endTime
sendPushoverMessage(pushoverBuilder("Das Wetter sieht gut aus und die Beregnung wird für " + hours + ":" + minutes + " eingeplant"))
// liefert die Rohlaufzeiten für jede Zone (in mins)
var Number MGV1Mins = ABBeregnungMGV1_Duration_A.state as DecimalType
var Number MGV2Mins = ABBeregnungMGV2_Duration_A.state as DecimalType
var Number MGV3Mins = ABBeregnungMGV3_Duration_A.state as DecimalType
// in die tatsächlichen Laufzeiten umrechnen (durch Anwendung des Skalierungsfaktors)
var int MGV1Time = ((MGV1Mins * scaleFactor) / 100).intValue
var int MGV2Time = ((MGV2Mins * scaleFactor) / 100).intValue
var int MGV3Time = ((MGV3Mins * scaleFactor) / 100).intValue
// jede Zone nacheinander einschalten (mit einem Abstand von einer Minute zwischen jeder Zonenaktivierung)
if (startTime.isAfter(now)){
if (MGV1Time > 0) {
endTime = startTime.plusMinutes(MGV1Time)
MGV1StartTimer = createTimer(startTime) [|
//Prüfen ob der Automower in der Ladestation ist (laden oder warten)
if (Automower_StatusCode.state != 1014 && Automower_StatusCode.state != 1056 && Automower_StatusCode.state != 1016) {
logInfo(filename,"Beregnung: Automower fährt noch! Timer werden gestoppt.")
sendPushoverMessage(pushoverBuilder("Automower fährt noch! Timer werden gestoppt."))
MGV1StartTimer.cancel
MGV1StartTimer = null
MGV1StopTimer.cancel
MGV1StopTimer = null
}
if ((WindSpeed.state as QuantityType<Number>).doubleValue >= 4) {
//Prüfen der Windgeschwindigkeit
logInfo(filename,"Beregnung: Derzeit ist es zu windig! Timer werden gestoppt.")
sendPushoverMessage(pushoverBuilder("Derzeit zu windig! Timer werden gestoppt."))
MGV1StartTimer.cancel
MGV1StartTimer = null
MGV1StopTimer.cancel
MGV1StopTimer = null
} else {
ABBeregnungMGV1.sendCommand(ON)
ABBeregnungMGV1_State.postUpdate(ON)
}
]
MGV1StopTimer = createTimer(endTime) [|
ABBeregnungMGV1.sendCommand(OFF)
ABBeregnungMGV1_State.postUpdate(OFF)
ABBeregnungMGV1_LastRun.postUpdate(new DateTimeType())
]
logInfo(filename,"Beregnung: Beregnung für Segment (vorne) gestartet um ["+ startTime +"] und endet ["+ endTime +"]")
startTime = endTime.plusMinutes(1)
}
if (MGV2Time > 0) {
endTime = startTime.plusMinutes(MGV2Time)
MGV2StartTimer = createTimer(startTime) [|
//Prüfen ob der Automower in der Ladestation ist (laden oder warten)
if (Automower_StatusCode.state != 1014 && Automower_StatusCode.state != 1056 && Automower_StatusCode.state != 1016) {
logInfo(filename,"Beregnung: Automower fährt noch! Timer werden gestoppt.")
MGV2StartTimer.cancel
MGV2StartTimer = null
MGV2StopTimer.cancel
MGV3StopTimer = null
}
if ((WindSpeed.state as QuantityType<Number>).doubleValue >= 4) {
//Prüfen der Windgeschwindigkeit
logInfo(filename,"Beregnung: Derzeit ist es zu windig! Timer werden gestoppt.")
sendPushoverMessage(pushoverBuilder("Derzeit zu windig! Timer werden gestoppt."))
MGV1StartTimer.cancel
MGV1StartTimer = null
MGV1StopTimer.cancel
MGV1StopTimer = null
} else {
ABBeregnungMGV2.sendCommand(ON)
ABBeregnungMGV2_State.postUpdate(ON)
}
]
MGV2StopTimer = createTimer(endTime) [|
ABBeregnungMGV2.sendCommand(OFF)
ABBeregnungMGV2_State.postUpdate(OFF)
ABBeregnungMGV2_LastRun.postUpdate(new DateTimeType())
]
logInfo(filename,"Beregnung: Beregnung für Segment (mitte) gestartet um ["+ startTime +"] und endet ["+ endTime +"]")
startTime = endTime.plusMinutes(1)
}
if (MGV3Time > 0) {
endTime = startTime.plusMinutes(MGV3Time)
MGV3StartTimer = createTimer(startTime) [|
//Prüfen ob der Automower in der Ladestation ist (laden oder warten)
if (Automower_StatusCode.state != 1014 && Automower_StatusCode.state != 1056 && Automower_StatusCode.state != 1016) {
logInfo(filename,"Beregnung: Automower fährt noch! Timer werden gestoppt.")
MGV3StartTimer.cancel
MGV3StartTimer = null
MGV3StopTimer.cancel
MGV3StopTimer = null
}
if ((WindSpeed.state as QuantityType<Number>).doubleValue >= 4) {
//Prüfen der Windgeschwindigkeit
logInfo(filename,"Beregnung: Derzeit ist es zu windig! Timer werden gestoppt.")
sendPushoverMessage(pushoverBuilder("Derzeit zu windig! Timer werden gestoppt."))
MGV1StartTimer.cancel
MGV1StartTimer = null
MGV1StopTimer.cancel
MGV1StopTimer = null
} else {
ABBeregnungMGV3.sendCommand(ON)
ABBeregnungMGV3_State.postUpdate(ON)
}
]
MGV3StopTimer = createTimer(endTime) [|
ABBeregnungMGV3.sendCommand(OFF)
ABBeregnungMGV3_State.postUpdate(OFF)
ABBeregnungMGV3_LastRun.postUpdate(new DateTimeType())
]
logInfo(filename,"Beregnung: Beregnung für Segment (hinten) gestartet um ["+ startTime +"] und endet ["+ endTime +"]")
startTime = endTime.plusMinutes(1)
}
} else {
logInfo(filename,"Beregnung: Startzeit liegt in der Vergangenheit")
}
} else {
logInfo(filename,"Beregnung: Programm A nicht ausgeführt, Master Switch deaktiviert.")
sendPushoverMessage(pushoverBuilder("Bewässerungsprogramm A ist deaktiviert, es wird heute keine Bewässerung eingeplant"))
}
end
Code: Alles auswählen
rule "MGV1 manual Irrigation"
when
Item ABBeregnungMGV1_State received command
then
if (ABBeregnung_Disable.state == ON) {
//Das gesamte Bewässerungssystem ist deaktiviert
logInfo(filename,"Beregnung: Gesamte Beregnung deaktiviert!")
return
}
if (receivedCommand == ON) {
if (IrrigationTimer === null){
logInfo(filename,"Beregnung: Beregnung für \"Beregnungssegment (vorne)\" manuell aktiviert, starte Timer")
IrrigationTimer = createTimer(now.plusMinutes(Integer::parseInt(ABBeregnungMGV1_Duration_A.state.toString))) [|
ABBeregnungMGV1_State.sendCommand(OFF)
ABBeregnungMGV1_LastRun.postUpdate(new DateTimeType())
logInfo(filename,"Beregnung: Manuelle Bewässerung für \"Beregnungssegment (vorne)\" beendet")
sendPushoverMessage(pushoverBuilder("Manuelle Bewässerung für \"Beregnungssegment (vorne)\" nach einer Laufzeit von " + ABBeregnungMGV1_Duration_A.state.toString + " Minuten beendet"))
IrrigationTimer = null
]
}
ABBeregnungMGV1.sendCommand(ON)
logInfo(filename,"Beregnung: Magnetventil \"Beregnungssegment (vorne)\" geschaltet [ON]")
} else {
ABBeregnungMGV1.sendCommand(OFF)
ABBeregnungMGV1_LastRun.postUpdate(new DateTimeType())
if (IrrigationTimer !== null){
IrrigationTimer.cancel()
IrrigationTimer = null
}
logInfo(filename,"Beregnung: Magnetventil \"Beregnungssegment (vorne)\" geschaltet [OFF]")
}
end
rule "MGV2 manual Irrigation"
when
Item ABBeregnungMGV2_State received command
then
if (ABBeregnung_Disable.state == ON) {
//Das gesamte Bewässerungssystem ist deaktiviert
logInfo(filename,"Beregnung: Gesamte Beregnung deaktiviert!")
return
}
if (receivedCommand == ON) {
if (IrrigationTimer === null){
logInfo(filename,"Beregnung: Beregnung für \"Beregnungssegment (mitte)\" manuell aktiviert, starte Timer")
IrrigationTimer = createTimer(now.plusMinutes(Integer::parseInt(ABBeregnungMGV2_Duration_A.state.toString))) [|
ABBeregnungMGV2_State.sendCommand(OFF)
ABBeregnungMGV2_LastRun.postUpdate(new DateTimeType())
logInfo(filename,"Beregnung: Manuelle Bewässerung für \"Beregnungssegment (mitte)\" beendet")
sendPushoverMessage(pushoverBuilder("Manuelle Bewässerung für \"Beregnungssegment (mitte)\" nach einer Laufzeit von " + ABBeregnungMGV2_Duration_A.state.toString + " Minuten beendet"))
IrrigationTimer = null
]
}
ABBeregnungMGV2.sendCommand(ON)
logInfo(filename,"Beregnung: Magnetventil \"Beregnungssegment (mitte)\" geschaltet [ON]")
} else {
ABBeregnungMGV2.sendCommand(OFF)
ABBeregnungMGV2_LastRun.postUpdate(new DateTimeType())
if (IrrigationTimer !== null){
IrrigationTimer.cancel()
IrrigationTimer = null
}
logInfo(filename,"Beregnung: Magnetventil \"Beregnungssegment (mitte)\" geschaltet [OFF]")
}
end
rule "MGV3 manual Irrigation"
when
Item ABBeregnungMGV3_State received command
then
if (ABBeregnung_Disable.state == ON) {
//Das gesamte Bewässerungssystem ist deaktiviert
logInfo(filename,"Beregnung: Gesamte Beregnung deaktiviert!")
return
}
if (receivedCommand == ON) {
if (IrrigationTimer === null){
logInfo(filename,"Beregnung: Beregnung für \"Beregnungssegment (hinten)\" manuell aktiviert, starte Timer")
IrrigationTimer = createTimer(now.plusMinutes(Integer::parseInt(ABBeregnungMGV3_Duration_A.state.toString))) [|
ABBeregnungMGV3_State.sendCommand(OFF)
ABBeregnungMGV3_LastRun.postUpdate(new DateTimeType())
logInfo(filename,"Beregnung: Manuelle Bewässerung für \"Beregnungssegment (hinten)\" beendet")
sendPushoverMessage(pushoverBuilder("Manuelle Bewässerung für \"Beregnungssegment (hinten)\" nach einer Laufzeit von " + ABBeregnungMGV3_Duration_A.state.toString + " Minuten beendet"))
IrrigationTimer = null
]
}
ABBeregnungMGV3.sendCommand(ON)
logInfo(filename,"Beregnung: Magnetventil \"Beregnungssegment (hinten)\" geschaltet [ON]")
} else {
ABBeregnungMGV3.sendCommand(OFF)
ABBeregnungMGV3_LastRun.postUpdate(new DateTimeType())
if (IrrigationTimer !== null){
IrrigationTimer.cancel()
IrrigationTimer = null
}
logInfo(filename,"Beregnung: Magnetventil \"Beregnungssegment (hinten)\" geschaltet [OFF]")
}
end
Der Watchdog schaut alle 15Min. nach, ob ein Magnetventil fälschlicherweise geöffnet ist
Code: Alles auswählen
rule "Irrigation Watchdog"
when
Time cron "0 0/15 5-23 * * ?"
then
if (ABBeregnung_Disable.state == ON) {
//Das gesamte Bewässerungssystem ist deaktiviert
gABBeregnung?.allMembers.filter(x | x.state != OFF).forEach[ item |
logInfo(filename,"Beregnung: Beregnung wird deaktiviert")
item.sendCommand(OFF)
]
return
}
if (ABBeregnungMGV1.state == ON && ABBeregnungMGV1_State.state == OFF){
ABBeregnungMGV1.sendCommand(OFF)
logInfo(filename,"Beregnung: MGV1 per Watchdog abgeschaltet")
}
else if (ABBeregnungMGV2.state == ON && ABBeregnungMGV2_State.state == OFF){
ABBeregnungMGV2.sendCommand(OFF)
logInfo(filename,"Beregnung: MGV2 per Watchdog abgeschaltet")
}
else if (ABBeregnungMGV3.state == ON && ABBeregnungMGV3_State.state == OFF){
ABBeregnungMGV3.sendCommand(OFF)
logInfo(filename,"Beregnung: MGV3 per Watchdog abgeschaltet")
}
end
Code: Alles auswählen
rule "Abort Irrigation"
when
Item ABBeregnung_Disable received update ON
then
// Beregnung abbrechen, wenn sie gestartet wurde
if (MGV1StartTimer !== null) {
MGV1StartTimer.cancel
MGV1StartTimer = null
logInfo(filename, "Beregnung: MGV1StartTimer gestoped")
}
if (MGV1StopTimer !== null) {
MGV1StopTimer.cancel
MGV1StopTimer = null
logInfo(filename, "Beregnung: MGV1StopTimer gestoped")
}
if (MGV2StartTimer !== null) {
MGV2StartTimer.cancel
MGV2StartTimer = null
logInfo(filename, "Beregnung: MGV2StartTimer gestoped")
}
if (MGV2StopTimer !== null) {
MGV2StopTimer.cancel
MGV2StopTimer = null
logInfo(filename, "Beregnung: MGV2StopTimer gestoped")
}
if (MGV3StartTimer !== null) {
MGV3StartTimer.cancel
MGV3StartTimer = null
logInfo(filename, "Beregnung: MGV3StartTimer gestoped")
}
if (MGV3StopTimer !== null) {
MGV3StopTimer.cancel
MGV3StopTimer = null
logInfo(filename, "Beregnung: MGV3StopTimer gestoped")
}
/* if(WateringStopTimer !== null) {
WateringStopTimer.cancel
WateringStopTimer = null
logInfo(filename, "Watering_starting/stoping: WateringStopTimer stoped")
} */
ABBeregnungMGV1_State.sendCommand(OFF)
ABBeregnungMGV2_State.sendCommand(OFF)
ABBeregnungMGV3_State.sendCommand(OFF)
end
Natürlich ist das hier nicht alles auf meinem Mist gewachsen und deshalb möchte ich mich bei folgenden Leuten bedanken:
Seppy, Alexander H., ben_jones, udo1toni, Michal_Szymanski, Spilota und Joshua A,
Hoffe wie immer hilft es dem einen oder anderen von Euch weiter und bin für Verbesserungsvorschläge immer offen
CYA
Cyrelian