Hallo Zusammen,
hier mal meine komplette Rule Sammlung zu dem Thema. Als Anregung ...
Rules:
Code: Alles auswählen
import org.joda.time.DateTime
// Variablen für Rule "AutomaticIrrigation"
var int duration
var int interval
var SwitchItem mgv
var SwitchItem state
var DateTimeItem lastrun
var DateTimeItem nextrun
var Timer IrrigationTimer
/**
* Vollautomatische Gartenbewässerung
*
* ACHTUNG: Magnetventile werden über separate Regel geschaltet!
*/
rule "AutomaticIrrigation"
when
Time cron "0 0/15 8-21 * * ?" or
Item sysStarted changed to ON
then
if (GlobalAutoIrrigation.state == ON){
logDebug("Homebox.GardenRules:AutomaticIrrigation", "Starte automatische Beregnungssteuerung, prüfe auf Jobs")
gAussenBeregnungSegments?.members.forEach[segments |
if (gAussenBeregnungState.state == ON && IrrigationTimer !== null){
gAussenBeregnungState?.members.forEach[x|
if (x.state == ON){
logInfo("Homebox.GardenRules:AutomaticIrrigation", "Laufende Bewässerung in Segment \"" + transform("MAP","devices.map",x.name) + "\" gefunden")
}
]
} else {
logDebug("Homebox.GardenRules:AutomaticIrrigation", "Setze Parameter für " + transform("MAP","devices.map",segments.name) + ":")
(segments as GroupItem)?.members.forEach[el |
if (el.name.contains("Duration")){
duration = Integer::parseInt(el.state.toString)
logDebug("Homebox.GardenRules:AutomaticIrrigation", " " + el.name + ": \"" + duration + "\"")
} else if (el.name.contains("Interval")) {
interval = Integer::parseInt(el.state.toString)
logDebug("Homebox.GardenRules:AutomaticIrrigation", " " + el.name + ": \"" + interval + "\"")
} else if (el.name.contains("MGV")){
mgv = el as SwitchItem
logDebug("Homebox.GardenRules:AutomaticIrrigation", " " + el.name + ": \"" + mgv + "\"")
} else if(el.name.contains("State")){
state = el as SwitchItem
logDebug("Homebox.GardenRules:AutomaticIrrigation", " " + el.name + ": \"" + state + "\"")
} else if (el.name.contains("LastRun")){
lastrun = el as DateTimeItem
logDebug("Homebox.GardenRules:AutomaticIrrigation", " " + el.name + ": \"" + lastrun + "\"")
} else if (el.name.contains("NextRun")){
nextrun = el as DateTimeItem
logDebug("Homebox.GardenRules:AutomaticIrrigation", " " + el.name + ": \"" + nextrun + "\"")
} else{
logDebug("Homebox.GardenRules:AutomaticIrrigation", "Parameter unbekannt, bitte prüfen")
}
]
logDebug("Homebox.GardenRules:AutomaticIrrigation", "Prüfe Segement \"" + transform("MAP","devices.map",segments.name) + "\"")
var Integer hour = now.getHourOfDay
/**
* Keine weitere Prüfung auf Bedingungen wenn
*
* Die Bodenfeuchtigkeit ausreichen
*/
if (AussenBodenfeuchtesensor.state == CLOSED){
logDebug("Homebox.GardenRules:AutomaticIrrigation", "Der Boden ist feucht genug, Beregung nicht notwendig")
}
/**
* Das Segment auf Handbetrieb steht
*/
else if (interval == -1){
logDebug("Homebox.GardenRules:AutomaticIrrigation", "Das Segment \"" + transform("MAP","devices.map",segments.name) + "\" steht auf Handbetrieb")
}
/**
* Der letzte Bewässerungslauf innerhalb des angegebenen Intervalls gelegen hat
*/
else if (state.changedSince(now.minusHours(interval)) == true){
logDebug("Homebox.GardenRules:AutomaticIrrigation", "Segment " + transform("MAP","devices.map",segments.name) + " innherhalb der letzten " + interval.toString + " Stunden gelaufen")
}
/**
* Zeitfenster zwischen 8:00 - 11.00 oder 17:00 - 21:00 Uhr
*/
else if (hour < 8 || (hour > 11 && hour < 17) || hour > 21){
logDebug("Homebox.GardenRules:AutomaticIrrigation", "Nicht im Beregnungszeitfenster, keine weitere Aktion")
}
/**
* Regen letzte 30 Min > 0 = Es regent
*/
else if (NetatmoRainCurr.state >= 0.1){
logInfo("Homebox.GardenRules:AutomaticIrrigation", "Es regnet, keine weitere Aktion")
}
/**
* Der Wind zu stark ist
*/
else if (NetatmoWindStrength.state >= 5){
logInfo("Homebox.GardenRules:AutomaticIrrigation", "Es stürmt, keine weitere Aktion")
}
/**
* Regen vorhergesagt ist
*/
else if (WeatherRainForecast1_MM.state >= 5 || WeatherRainForecast0_MM.state >= 5){
logInfo("Homebox.GardenRules:AutomaticIrrigation", "Es soll regnen, keine weitere Aktion")
}
/**
* Zu wenig Wasser in der Zisterne
*/
else if (AussenZisterneFillingLevel.state < 20){
logInfo("Homebox.GardenRules:AutomaticIrrigation", "Zu wenig Wasser in de Zisterne, keine weitere Aktion")
}
/**
* Sonst Beregnungsprogram starten
*/
else {
state.sendCommand(ON)
logInfo("Homebox.GardenRules:AutomaticIrrigation", "Bewässerung für " + transform("MAP","devices.map",segments.name) + " mit Laufzeit " + duration.toString + " Minuten gestartet")
pushover("Automatische Bewässerung für " + transform("MAP","devices.map",segments.name) + " mit Laufzeit " + duration.toString + " Minuten gestartet")
/**
* Wenn Timer vorhanden, diesen beenden
*/
if (IrrigationTimer !== null){
IrrigationTimer.cancel()
logInfo("Homebox.GardenRules:AutomaticIrrigation", "Laufenden Timer beendet")
}
logInfo("Homebox.GardenRules:AutomaticIrrigation", "Starte neuen Timer")
IrrigationTimer = createTimer(now.plusMinutes(duration)) [|
state.sendCommand(OFF)
lastrun.postUpdate(new DateTimeType())
logInfo("Homebox.GardenRules:AutomaticIrrigation", "Bewässerung für " + segments.name + " beendet")
pushover("Automatische Bewässerung für " + transform("MAP","devices.map",segments.name) + " nach Laufzeit " + duration.toString + " Minuten beendet")
IrrigationTimer = null
]
}
}
]
}
end
rule "ControlMGV1"
when
Item AussenBeregnungSegment1State received command
then
if (receivedCommand == ON) {
if (IrrigationTimer === null){
logInfo("Homebox.GardenRules:ControlMGV1", "Beregnung für Segement \"Beregnungssegment 1 (Vorgarten)\" manuell aktiviert, starte Timer")
IrrigationTimer = createTimer(now.plusMinutes(Integer::parseInt(AussenBeregnungSegment1Duration.state.toString))) [|
AussenBeregnungSegment1State.sendCommand(OFF)
AussenBeregnungSegment1LastRun.postUpdate(new DateTimeType())
logInfo("Homebox.GardenRules:ControlMGV1", "Manuelle Bewässerung für Segement \"Beregnungssegment 1 (Vorgarten)\" beendet")
pushover("Manuelle Bewässerung für Segement \"Beregnungssegment 1 (Vorgarten)\" nach Laufzeit " + AussenBeregnungSegment1Duration.state.toString + " Minuten beendet")
IrrigationTimer = null
]
}
AussenBeregnungSegment1MGV.sendCommand(ON)
logInfo("Homebox.GardenRules:ControlMGV1", "Magnetventil \"AussenBeregnungSegment1MGV\" geschaltet [ON]")
} else {
AussenBeregnungSegment1MGV.sendCommand(OFF)
AussenBeregnungSegment1LastRun.postUpdate(new DateTimeType())
if (IrrigationTimer !== null){
IrrigationTimer.cancel()
IrrigationTimer = null
}
logInfo("Homebox.GardenRules:ControlMGV1", "Magnetventil \"AussenBeregnungSegment1MGV\" geschaltet [OFF]")
}
end
rule "ControlMGV2"
when
Item AussenBeregnungSegment2State received command
then
if (receivedCommand == ON) {
if (IrrigationTimer === null){
logInfo("Homebox.GardenRules:ControlMGV2", "Beregnung für Segement \"Beregnungssegment 2 (Garten)\" manuell aktiviert, starte Timer")
IrrigationTimer = createTimer(now.plusMinutes(Integer::parseInt(AussenBeregnungSegment2Duration.state.toString))) [|
AussenBeregnungSegment2State.sendCommand(OFF)
AussenBeregnungSegment2LastRun.postUpdate(new DateTimeType())
logInfo("Homebox.GardenRules:ControlMGV2", "Manuelle Bewässerung für Segement \"Beregnungssegment 2 (Garten)\" beendet")
pushover("Manuelle Bewässerung für Segement \"Beregnungssegment 2 (Garten)\" nach Laufzeit " + AussenBeregnungSegment2Duration.state.toString + " Minuten beendet")
IrrigationTimer = null
]
}
AussenBeregnungSegment2MGV.sendCommand(ON)
logInfo("Homebox.GardenRules:ControlMGV2", "Magnetventil \"AussenBeregnungSegment2MGV\" geschaltet [ON]")
} else {
AussenBeregnungSegment2MGV.sendCommand(OFF)
AussenBeregnungSegment2LastRun.postUpdate(new DateTimeType())
if (IrrigationTimer !== null){
IrrigationTimer.cancel()
IrrigationTimer = null
}
logInfo("Homebox.GardenRules:ControlMGV2", "Magnetventil \"AussenBeregnungSegment2MGV\" geschaltet [OFF]")
}
end
rule "MGV_Watchdog"
when
Time cron "0 0/15 8-21 * * ?"
then
if (AussenBeregnungSegment1MGV.state == ON && AussenBeregnungSegment1State.state == OFF){
AussenBeregnungSegment1MGV.sendCommand(OFF)
logInfo("Homebox.GardenRules:MGV_Watchdog", "MGV1 per Watchdog abgeschaltet")
}
else if (AussenBeregnungSegment2MGV.state == ON && AussenBeregnungSegment2State.state == OFF){
AussenBeregnungSegment2MGV.sendCommand(OFF)
logInfo("Homebox.GardenRules:MGV_Watchdog", "MGV2 per Watchdog abgeschaltet")
}
end
rule "ControlPump"
when
Item AussenBeregnungSegment1State received command or
Item AussenBeregnungSegment2State received command
then
if (receivedCommand == ON){
AussenGartenBewaesserungPumpeState.sendCommand(ON)
} else {
AussenGartenBewaesserungPumpeState.sendCommand(OFF)
}
end
rule "MonitorIrrigationConditions"
when
Item NetatmoRain30Min received update or
Item NetatmoWindStrength received update
then
var Boolean stop = false
if (gAussenBeregnungState.state == ON){
// Regen
if (NetatmoRainCurr.state >= 0.1){
logInfo("Homebox.GardenRules:MonitorIrrigationConditions", "Beregnungsbedigungen ungünstig (Regen), wird abgeschaltet ...")
pushover("Beregnungsbedigungen ungünstig (Regen), wird abgeschaltet ...",1)
stop = true
}
// Wind
else if (NetatmoWindStrength.state >= 5){
logInfo("Homebox.GardenRules:MonitorIrrigationConditions", "Beregnungsbedigungen ungünstig (Wind), wird abgeschaltet ...")
pushover("Beregnungsbedigungen ungünstig (Wind), wird abgeschaltet ...",1)
stop = true
}
if (stop == true){
gAussenBeregnungState?.members.forEach[el |
if (el.state == ON){
el.sendCommand(OFF)
logInfo("Homebox.GardenRules:MonitorIrrigationConditions", "Segment \"" + transform("MAP","devices.map",el.name) + "\" abgeschaltet")
pushover("Segment \"" + transform("MAP","devices.map",el.name) + "\" abgeschaltet",1)
}
]
}
}
end
rule "SetNextIrrigationRun"
when
Item AussenBeregnungSegment1Interval changed or
Item AussenBeregnungSegment1LastRun changed or
Item AussenBeregnungSegment2Interval changed or
Item AussenBeregnungSegment2LastRun changed
//Time cron "0 0/15 8-22 * 3-10 ?"
then
gAussenBeregnungSegments?.members.forEach[segments |
logDebug("Homebox.GardenRules:SetNextIrrigationRun", "Aktualisiere Infos für Segment \"" + transform("MAP","devices.map",segments.name) + "\"")
(segments as GroupItem)?.members.forEach[el |
if (el.name.contains("Interval")) {
interval = Integer::parseInt(el.state.toString)
logDebug("Homebox.GardenRules:SetNextIrrigationRun", " " + el.name + ": \"" + interval + "\"")
} else if (el.name.contains("LastRun")){
lastrun = el as DateTimeItem
logDebug("Homebox.GardenRules:SetNextIrrigationRun", " " + el.name + ": \"" + lastrun + "\"")
} else if (el.name.contains("NextRun")){
nextrun = el as DateTimeItem
logDebug("Homebox.GardenRules:SetNextIrrigationRun", " " + el.name + ": \"" + nextrun + "\"")
}
]
//Wenn ohne Wert, Default heute setzen
if (lastrun.state === null){
logDebug("Homebox.GardenRules:SetNextIrrigationRun", " LastRun \"null\" setze default \"now\"")
lastrun.postUpdate(new DateTimeType())
}
if (nextrun.state === null){
logDebug("Homebox.GardenRules:SetNextIrrigationRun", " NextRun \"null\" setze default \"now\"")
nextrun.postUpdate(new DateTimeType())
}
//Nächsten Lauf nur berechnen, wenn nicht auf Handbetrieb
if (interval > 0){
logDebug("Homebox.GardenRules:SetNextIrrigationRun"," --> Intervallbetrieb")
val DateTime next = new DateTime((nextrun.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)
logDebug("Homebox.GardenRules:SetNextIrrigationRun", " next.getDayOfMonth:" + next.getDayOfMonth)
logDebug("Homebox.GardenRules:SetNextIrrigationRun", " now.getDayOfMonth:" + now.getDayOfMonth)
/**
* Wenn ein Lauf ausgelassen, oder nach Neustart, aktualisiere Daten
*/
if (next.getDayOfMonth < now.getDayOfMonth || (next.getDayOfMonth == now.getDayOfMonth && next.getHourOfDay <= now.getHourOfDay)){
logDebug("Homebox.GardenRules:SetNextIrrigationRun", " Lauf ausgelassen aktualisiere NextRun")
var DateTime last = now
//var DateTime next = new DateTime(last.plusHours(Integer::parseInt(AussenBeregnungSegment2Interval.state.toString)).calendar.timeInMillis)
var String nYear = last.plusHours(interval).getYear.toString
var String nMonth = last.plusHours(interval).getMonthOfYear.toString
var String nDay = last.plusHours(interval).getDayOfMonth.toString
var String nHour = last.plusHours(interval).getHourOfDay.toString
var String nMinute = last.plusHours(interval).getMinuteOfHour.toString
if (Integer::parseInt(nHour) < 8) {
nMinute = "0"
nHour = "8"
} else if (Integer::parseInt(nHour) > 11 && Integer::parseInt(nHour) < 17) {
nMinute = "0"
nHour = "17"
} else if (Integer::parseInt(nHour) > 21) {
var Integer tmp = Integer::parseInt(nDay) + 1
nMinute = "0"
nHour = "8"
nDay = tmp.toString
}
var String nextStr = nYear + "-" + nMonth + "-" + nDay + "T" + nHour + ":" + nMinute + ":00"
logDebug("Homebox.GardenRules:SetNextIrrigationRun", " nextStr: " + nextStr)
nextrun.postUpdate(new DateTimeType(nextStr))
} else {
var DateTime last = new DateTime((lastrun.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)
//var DateTime next = new DateTime(last.plusHours(Integer::parseInt(AussenBeregnungSegment2Interval.state.toString)).calendar.timeInMillis)
var String nYear = last.plusHours(interval).getYear.toString
var String nMonth = last.plusHours(interval).getMonthOfYear.toString
var String nDay = last.plusHours(interval).getDayOfMonth.toString
var String nHour = last.plusHours(interval).getHourOfDay.toString
var String nMinute = last.plusHours(interval).getMinuteOfHour.toString
if (Integer::parseInt(nHour) < 8) {
nMinute = "0"
nHour = "8"
} else if (Integer::parseInt(nHour) > 21) {
var Integer tmp = Integer::parseInt(nDay) + 1
nMinute = "0"
nHour = "8"
nDay = tmp.toString
}
var String nextStr = nYear + "-" + nMonth + "-" + nDay + "T" + nHour + ":" + nMinute + ":00"
nextrun.postUpdate(new DateTimeType(nextStr))
}
logDebug("Homebox.GardenRules:SetNextIrrigationRun", " Neuer Plantermin " + nextrun.state.toString)
} else {
logDebug("Homebox.GardenRules:SetNextIrrigationRun"," --> Handbetrieb")
}
]
end
Sitemap:
Code: Alles auswählen
Text label="Beregnung" icon="watering" visibility=[GlobalAutoIrrigation==ON] {
Text item=AussenBodenfeuchtesensor valuecolor=[CLOSED="green",OPEN="red"]
Text item=AussenBodenfeuchtesensorLastUpdate
Text label="Beregnungssteuerung" icon="watering_config" {
Frame label="Beregnungssegment 1 (Vorgarten)" {
Text item=AussenBeregnungSegment1LastRun
Text item=AussenBeregnungSegment1NextRun visibility=[AussenBeregnungSegment1Interval>0]
Switch item=AussenBeregnungSegment1State
Selection item=AussenBeregnungSegment1Duration mappings=[1="1 Min.", 2="2 Min.", 3="3 Min.", 4="4 Min.", 5="5 Min.", 6="6 Min.", 7="7 Min.", 8="8 Min.", 9="9 Min.", 10="10 Min.", 11="11 Min.", 12="12 Min.", 13="13 Min.", 14="14 Min.", 15="15 Min.", 20="20 Min."]
Selection item=AussenBeregnungSegment1Interval mappings=["-1"="Manuell",1="1 Std.", 2="2 Std.", 3="3 Std.", 4="4 Std.", 5="5 Std.", 10="10 Std.", 11="11 Std.", 12="12 Std.", 13="13 Std.", 14="14 Std.", 15="15 Std.", 16="16 Std.", 17="17 Std.", 18="18 Std.", 19="19 Std.", 20="20 Std.", 21="21 Std.", 22="22 Std.", 23="23 Std.", 24="24 Std.", 36="36 Std.", 48="48 Std."]
Switch item=AussenBeregnungSegment1MGV
}
Frame label="Beregnungssegment 2 (Garten 1)" {
Text item=AussenBeregnungSegment2LastRun
Text item=AussenBeregnungSegment2NextRun visibility=[AussenBeregnungSegment2Interval>0]
Switch item=AussenBeregnungSegment2State
Selection item=AussenBeregnungSegment2Duration mappings=[1="1 Min.", 2="2 Min.", 3="3 Min.", 4="4 Min.", 5="5 Min.", 6="6 Min.", 7="7 Min.", 8="8 Min.", 9="9 Min.", 10="10 Min.", 11="11 Min.", 12="12 Min.", 13="13 Min.", 14="14 Min.", 15="15 Min.", 20="20 Min."]
Selection item=AussenBeregnungSegment2Interval mappings=["-1"="Manuell",1="1 Std.", 2="2 Std.", 3="3 Std.", 4="4 Std.", 5="5 Std.", 10="10 Std.", 11="11 Std.", 12="12 Std.", 13="13 Std.", 14="14 Std.", 15="15 Std.", 16="16 Std.", 17="17 Std.", 18="18 Std.", 19="19 Std.", 20="20 Std.", 21="21 Std.", 22="22 Std.", 23="23 Std.", 24="24 Std.", 36="36 Std.", 48="48 Std."]
Switch item=AussenBeregnungSegment2MGV
}
}
Text item=AussenZisterneFillingLiter icon="cistern"
Switch item=AussenZisterneFillingLevelChartPeriod icon="cistern-graph" label="Verlauf Füllstand" mappings=[0="Tag", 1="Woche", 2="Monat", 3="4-Monate", 4="Jahr"]
Image url="http://localhost/rrdchart.png?items=AussenZisterneFillingLevel&period=D&w=1024" refresh=6000 visibility=[AussenZisterneFillingLevelChartPeriod==0, AussenZisterneFillingLevelChartPeriod=="Uninitialized"]
Image url="http://localhost/rrdchart.png?items=AussenZisterneFillingLevel&period=W&w=1024" refresh=300000 visibility=[AussenZisterneFillingLevelChartPeriod==1]
Image url="http://localhost/rrdchart.png?items=AussenZisterneFillingLevel&period=M&w=1024" refresh=300000 visibility=[AussenZisterneFillingLevelChartPeriod==2]
Image url="http://localhost/rrdchart.png?items=AussenZisterneFillingLevel&period=4M&w=1024" refresh=300000 visibility=[AussenZisterneFillingLevelChartPeriod==3]
Image url="http://localhost/rrdchart.png?items=AussenZisterneFillingLevel&period=Y&w=1024" refresh=300000 visibility=[AussenZisterneFillingLevelChartPeriod==4]
Switch item=AussenZisterneRefill icon="tap" label="Zisternen Nachfüllung aktivieren (10 Min.)" visibility=[AussenZisterneFillingLevel<20]
}
Viel Spaß
