Here is my rule (this was my first ever rule in OpenHab when switching from Smarrthngs so I admit it could have been done better). I have rain sensor and Mi Flora sensor installed in the garden which is one of the conditions to check the start of the cyclus:
/*
* Irrigation rules
*/
import java.util.Date
//import java.time.ZonedDateTime
var int maxNoWtrDays = 4 // maximum No water days
var java.time.ZonedDateTime lastWtrDate // Date last watering or rain
var Number minimumReqRainfall = 5 // minimum required rainfall
var Number rainfallMm = 0.0 // Current day reain forecast
var Number missingRainfall = 0.0 // missing rainfall in mm
var isWatering = false // watering active
// Define watering timers
var Timer tmrIrrigationTerrace_Start
var Timer tmrIrrigationTerrace_Stop
var Timer tmrIrrigationGardenHouse_Start
var Timer tmrIrrigationGardenHouse_Stop
var Timer tmrIrrigationEntrance_Start
var Timer tmrIrrigationEntrance_Stop
var Timer tmrIrrigationFront_Start
var Timer tmrIrrigationFront_Stop
var Timer tmrIrrigationDripHose_Start
var Timer tmrIrrigationDripHose_Stop
var Timer tmrIrrigationPump_Stop
var Timer tmrIrrigation_Stop
var String FallbackStartTime = "01:00"
var Number FallbackDurationSprinklersGardenHouse = 5
var Number FallbackDurationSprinklersTerrace = 5
var Number FallbackDurationSprinklersEntrance = 3
var Number FallbackDurationSprinklersFront = 5
var Number FallbackDurationDripHose = 30
var Number FallbackDurationFilterFlush = 1
var Number FallbackScaleFactor = 100
var Number FallbackMinimumReqRainfallCfg = 5
var Number FallbackMinimumSoilHumidity = 22
// Define logic variables
val OnOffType ON_R
val OnOffType OFF_R
// Debug
val checkUserStartTime = true
val checkWtrRainSensor = true
// Initialise
rule "irrigation:initialise"
when
System started
then
logInfo( "irrigation:initialise","====================================================-Initialise-============================================")
ON_R = ON
OFF_R = OFF
isWatering = false
logInfo( "irrigation:initialise","Close valves")
itmIrrigationSprinklersTerraceCmd.sendCommand(OFF_R)
itmIrrigationSprinklersGardenHouseCmd.sendCommand(OFF_R)
itmIrrigationSprinklersEntranceCmd.sendCommand(OFF_R)
itmIrrigationSprinklersFrontCmd.sendCommand(OFF_R)
itmIrrigationDripHoseCmd.sendCommand(OFF_R)
itmIrrigationPumpCmd.sendCommand(OFF_R)
itmIrrigationRainwaterFilterFlushCmd.sendCommand(OFF_R)
if(itmIrrigationStartTime.state==NULL) {
itmIrrigationStartTime.sendCommand(FallbackStartTime)
logInfo( "irrigation:initialise","itmIrrigationStartTime SET TO " + FallbackStartTime )
} else {
logInfo( "irrigation:initialise","itmIrrigationStartTime " + itmIrrigationStartTime.state + " min")
}
if(itmIrrigationDurationSprinklersTerrace.state==NULL) {
itmIrrigationDurationSprinklersTerrace.sendCommand(FallbackDurationSprinklersTerrace)
logInfo( "irrigation:initialise","itmIrrigationDurationSprinklersTerrace SET TO "+ FallbackDurationSprinklersTerrace + " min")
} else {
logInfo( "irrigation:initialise","itmIrrigationDurationSprinklersTerrace " + itmIrrigationDurationSprinklersTerrace.state + " min")
}
if(itmIrrigationDurationSprinklersGardenHouse.state==NULL) {
itmIrrigationDurationSprinklersGardenHouse.sendCommand(FallbackDurationSprinklersGardenHouse)
logInfo( "irrigation:initialise","itmIrrigationDurationSprinklersGardenHouse SET TO "+ FallbackDurationSprinklersGardenHouse +" min")
} else {
logInfo( "irrigation:initialise","itmIrrigationDurationSprinklersGardenHouse " + itmIrrigationDurationSprinklersGardenHouse.state + " min")
}
if(itmIrrigationDurationSprinklersEntrance.state==NULL) {
itmIrrigationDurationSprinklersEntrance.sendCommand(FallbackDurationSprinklersEntrance)
logInfo( "irrigation:initialise","itmIrrigationDurationSprinklersEntrance SET TO " + FallbackDurationSprinklersEntrance + " min")
} else {
logInfo( "irrigation:initialise","itmIrrigationDurationSprinklersEntrance " + itmIrrigationDurationSprinklersEntrance.state + " min")
}
if(itmIrrigationDurationSprinklersFront.state==NULL) {
itmIrrigationDurationSprinklersFront.sendCommand(FallbackDurationSprinklersFront)
logInfo( "irrigation:initialise","itmIrrigationDurationSprinklersFront SET TO "+ FallbackDurationSprinklersFront +" min")
} else {
logInfo( "irrigation:initialise","itmIrrigationDurationSprinklersFront " + itmIrrigationDurationSprinklersFront.state + " min")
}
if(itmIrrigationDurationDripHose.state==NULL) {
itmIrrigationDurationDripHose.sendCommand(FallbackDurationDripHose)
logInfo( "irrigation:initialise","itmIrrigationDurationDripHose SET TO " + FallbackDurationDripHose +" min")
} else {
logInfo( "irrigation:initialise","itmIrrigationDurationDripHose " + itmIrrigationDurationDripHose.state + " min")
}
if(itmIrrigationDurationFilterFlush.state==NULL) {
itmIrrigationDurationFilterFlush.sendCommand(FallbackDurationFilterFlush)
logInfo( "FILE", "itmIrrigationDurationFilterFlush: itmIrrigationDurationDripHose SET TO " + FallbackDurationFilterFlush + " min")
} else {
logInfo( "irrigation:initialise","itmIrrigationDurationFilterFlush " + itmIrrigationDurationFilterFlush.state + " min")
}
if(itmIrrigationScaleFactor.state==NULL) {
itmIrrigationScaleFactor.sendCommand(FallbackScaleFactor)
logInfo( "irrigation:initialise","itmIrrigationScaleFactor SET TO " + FallbackScaleFactor + " %")
} else {
logInfo( "irrigation:initialise","itmIrrigationScaleFactor " + itmIrrigationScaleFactor.state + " %")
}
if(itmIrrigationMinimumReqRainfallCfg.state==NULL) {
itmIrrigationMinimumReqRainfallCfg.sendCommand(FallbackMinimumReqRainfallCfg)
logInfo( "irrigation:initialise","itmIrrigationMinimumReqRainfallCfg SET TO " + FallbackMinimumReqRainfallCfg + " mm")
} else {
logInfo( "irrigation:initialise","itmIrrigationMinimumReqRainfallCfg " + itmIrrigationMinimumReqRainfallCfg.state + " mm")
}
if(itmMinimumSoilMoisture.state==NULL) {
itmMinimumSoilMoisture.sendCommand(FallbackMinimumSoilHumidity)
logInfo( "irrigation:initialise","itmMinimumSoilMoisture SET TO " + FallbackMinimumSoilHumidity + " %")
} else {
logInfo( "irrigation:initialise","itmMinimumSoilMoisture " + itmMinimumSoilMoisture.state + " %")
}
logInfo( "irrigation:initialise","=========================== Irrigation parameters initialization =============================")
logInfo( "irrigation:initialise","itmIrrigationAuto " + itmIrrigationAuto.state )
logInfo( "irrigation:initialise","Rain Sensor " + WaterLeakDetectedRainSensor.state )
logInfo( "irrigation:initialise","checkWtrRainSensor " + checkWtrRainSensor )
logInfo( "irrigation:initialise","checkUserStartTime " + checkUserStartTime )
logInfo( "irrigation:initialise","isWatering " + isWatering )
logInfo( "irrigation:initialise","Water source is rain tank " + itmIrrigationFromRainTank.state )
end
rule "irrigation:Manual initialise"
when
Item test12 changed from OFF to ON
then
logInfo( "irrigation:Manual initialise","====================================================-Initialise-============================================")
itmIrrigationStartTime.sendCommand(FallbackStartTime)
logInfo( "irrigation:Manual initialise","itmIrrigationStartTime SET TO " + FallbackStartTime )
itmIrrigationDurationSprinklersTerrace.sendCommand(FallbackDurationSprinklersTerrace)
logInfo( "irrigation:Manual initialise","itmIrrigationDurationSprinklersTerrace SET TO "+ FallbackDurationSprinklersTerrace + " min")
itmIrrigationDurationSprinklersGardenHouse.sendCommand(FallbackDurationSprinklersGardenHouse)
logInfo( "irrigation:Manual initialise","itmIrrigationDurationSprinklersGardenHouse SET TO "+ FallbackDurationSprinklersGardenHouse +" min")
itmIrrigationDurationSprinklersEntrance.sendCommand(FallbackDurationSprinklersEntrance)
logInfo( "irrigation:Manual initialise","itmIrrigationDurationSprinklersEntrance SET TO " + FallbackDurationSprinklersEntrance + " min")
itmIrrigationDurationSprinklersFront.sendCommand(FallbackDurationSprinklersFront)
logInfo( "irrigation:Manual initialise","itmIrrigationDurationSprinklersFront SET TO "+ FallbackDurationSprinklersFront +" min")
itmIrrigationDurationDripHose.sendCommand(FallbackDurationDripHose)
logInfo( "irrigation:Manual initialise","itmIrrigationDurationDripHose SET TO " + FallbackDurationDripHose +" min")
itmIrrigationDurationFilterFlush.sendCommand(FallbackDurationFilterFlush)
logInfo( "FILE", "itmIrrigationDurationFilterFlush: itmIrrigationDurationDripHose SET TO " + FallbackDurationFilterFlush + " min")
itmIrrigationScaleFactor.sendCommand(FallbackScaleFactor)
logInfo( "irrigation:Manual initialise","itmIrrigationScaleFactor SET TO " + FallbackScaleFactor + " %")
itmIrrigationMinimumReqRainfallCfg.sendCommand(FallbackMinimumReqRainfallCfg)
logInfo( "irrigation:Manual initialise","itmIrrigationMinimumReqRainfallCfg SET TO " + FallbackMinimumReqRainfallCfg + " mm")
itmMinimumSoilMoisture.sendCommand(FallbackMinimumSoilHumidity)
logInfo( "irrigation:Manual initialise","itmMinimumSoilMoisture SET TO " + FallbackMinimumSoilHumidity + " %")
logInfo( "irrigation:Manual initialise","=========================== Irrigation parameters initialization =============================")
logInfo( "irrigation:Manual initialise","itmIrrigationAuto " + itmIrrigationAuto.state )
logInfo( "irrigation:Manual initialise","Rain Sensor " + WaterLeakDetectedRainSensor.state )
logInfo( "irrigation:Manual initialise","checkWtrRainSensor " + checkWtrRainSensor )
logInfo( "irrigation:Manual initialise","checkUserStartTime " + checkUserStartTime )
logInfo( "irrigation:Manual initialise","isWatering " + isWatering )
logInfo( "irrigation:Manual initialise","Water source is rain tank " + itmIrrigationFromRainTank.state )
end
rule "irrigation:Rain_sensor_rain_activated"
when
Item WaterLeakDetectedRainSensor changed to ON
then
logInfo( "irrigation:Rain_sensor_rain_activated","Rain detected, stopping watering if running")
EventHist.sendCommand("Rain sensor is wet")
itmIrrigationNotification_Proxy.sendCommand("STOP")
end
rule "irrigation:Rain_sensor_rain_deactivated"
when
Item WaterLeakDetectedRainSensor changed to OFF
then
logInfo( "irrigation:Rain_sensor_rain_deactivated","Rain sensor is dry")
EventHist.sendCommand("Rain sensor is dry")
end
// Sprinklers in auto
rule "irrigation:Auto_ON"
when
Item itmIrrigationAuto changed to ON
then
logInfo( "irrigation:auto_ON"," Automatic watering set")
EventHist.sendCommand("Sprinklers system set to auto")
itmIrrigationStartBtn.sendCommand(OFF)
end
// Sprinklers in manual
rule "irrigation:auto_OFF"
when
Item itmIrrigationAuto changed to OFF
then
logInfo( "irrigation:auto_ON"," Manual watering set")
EventHist.sendCommand("Sprinklers system set to auto")
itmIrrigationStartBtn.sendCommand(OFF)
end
// Manual watering
rule "irrigation:Manual"
when
Item itmIrrigationStartBtn received update
then
logInfo( "irrigation:manual"," isWatering[" +isWatering+ "]" )
// if watering is on, it stops, otherwise it turns on watering
if (( isWatering == false ) && (itmIrrigationStartBtn.state == ON) && (itmIrrigationAuto.state == OFF )) {
logInfo("irrigation:manual","Start watering, manual activation")
EventHist.sendCommand("Start watering, manual activation")
itmIrrigationNotification_Proxy.sendCommand("START")
} else if (( isWatering == true ) && (itmIrrigationStartBtn.state == OFF) && (itmIrrigationAuto.state == OFF )) {
logInfo("irrigation:manual","Stoping watering, manual activation")
EventHist.sendCommand("Stoping watering, manual activation")
itmIrrigationNotification_Proxy.sendCommand("STOP")
}
if (itmIrrigationAuto.state == ON ) {
logInfo("irrigation:manual","System is in AUTO mode, manual opration not possible")
}
end
// Controlling outputs
rule "irrigation:Commands"
when
Item itmIrrigationNotification_Proxy received update
then
logInfo( "irrigation:Commands", "============== Irrigation commands ==========")
var String msg = itmIrrigationNotification_Proxy.state.toString
logInfo( "irrigation:Commands","Stoping watering if already started")
logInfo( "irrigation:Commands","msg [" + msg + "]")
// reset timers
logInfo( "irrigation:Commands","WtrTimers")
if(tmrIrrigationTerrace_Start !== null) tmrIrrigationTerrace_Start.cancel
if(tmrIrrigationTerrace_Stop !== null) tmrIrrigationTerrace_Stop.cancel
if(tmrIrrigationGardenHouse_Start !== null) tmrIrrigationGardenHouse_Start.cancel
if(tmrIrrigationGardenHouse_Stop !== null) tmrIrrigationGardenHouse_Stop.cancel
if(tmrIrrigationEntrance_Start !== null) tmrIrrigationEntrance_Start.cancel
if(tmrIrrigationEntrance_Stop !== null) tmrIrrigationEntrance_Stop.cancel
if(tmrIrrigationFront_Start !== null) tmrIrrigationFront_Start.cancel
if(tmrIrrigationFront_Stop !== null) tmrIrrigationFront_Stop.cancel
if(tmrIrrigationDripHose_Start !== null) tmrIrrigationDripHose_Start.cancel
if(tmrIrrigationDripHose_Stop !== null) tmrIrrigationDripHose_Stop.cancel
if(tmrIrrigation_Stop !== null) tmrIrrigation_Stop.cancel
if(tmrIrrigationPump_Stop !== null) tmrIrrigationPump_Stop.cancel
ON_R = ON
OFF_R = OFF
// Set last watering date
var String WaterNowTime = String::format( "%1$tY-%1$tm-%1$tdT%1$tH:%1$tM:00.000+01:00[Europe/Brussels]", new Date() )
logInfo( "irrigation:Commands","WaterNowTime[" + WaterNowTime + "]")
if (msg == "STOP") {
logInfo( "irrigation:Commands","send OFF commands")
itmIrrigationSprinklersTerraceCmd.sendCommand(OFF_R)
itmIrrigationSprinklersGardenHouseCmd.sendCommand(OFF_R)
itmIrrigationSprinklersEntranceCmd.sendCommand(OFF_R)
itmIrrigationSprinklersFrontCmd.sendCommand(OFF_R)
itmIrrigationDripHoseCmd.sendCommand(OFF_R)
itmIrrigationPumpCmd.sendCommand(OFF_R)
itmIrrigationRainwaterFilterFlushCmd.sendCommand(OFF_R)
// Idle (not watering)
isWatering = false
sendNotification("xxxxx@gmail.com", "Garden watering stopped","rain","Info")
itmIrrigationLastDate.sendCommand(now.toLocalDateTime().toString() + "+01:00[Europe/Brussels]")
}
// Start watering
if (msg == "START") {
logInfo( "irrigation:Commands","starting watering")
sendNotification("xxxxx@gmail.com", "Garden watering started","rain","Info")
// set watering flag
isWatering = true
// Assign duration from items
var Number DurationSprinklersTerrace = itmIrrigationDurationSprinklersTerrace.state as DecimalType
var Number DurationSprinklersGardenHouse = itmIrrigationDurationSprinklersGardenHouse.state as DecimalType
var Number DurationSprinklersEntrance = itmIrrigationDurationSprinklersEntrance.state as DecimalType
var Number DurationSprinklersFront = itmIrrigationDurationSprinklersFront.state as DecimalType
var Number DurationDripHose = itmIrrigationDurationDripHose.state as DecimalType
var DateTimeType WateringStartTime = DateTimeType.valueOf(now.toLocalDateTime().toString())
var DateTimeType WateringEndTime = DateTimeType.valueOf(now.toLocalDateTime().toString())
// Set last watering date
itmIrrigationLastDate.sendCommand(now.toLocalDateTime().toString() + "+01:00[Europe/Brussels]")
// Aplying correction factor
var Number scaleFactor = itmIrrigationScaleFactor.state as DecimalType
var int wtrSprinklersTerraceTime = ((DurationSprinklersTerrace * scaleFactor) / 100).intValue
var int wtrSprinklersGardenHouseTime = ((DurationSprinklersGardenHouse * scaleFactor) / 100).intValue
var int wtrSprinklersEntranceTime = ((DurationSprinklersEntrance * scaleFactor) / 100).intValue
var int wtrSprinklersFrontTime = ((DurationSprinklersFront * scaleFactor) / 100).intValue
var int wtrDripHoseTime = ((DurationDripHose * scaleFactor) / 100).intValue
//Calculate start delays in seconds
var int DelayedStartSprinklersGardenHouse = wtrSprinklersTerraceTime * 60
var int DelayedStartSprinklersEntrance = DelayedStartSprinklersGardenHouse + wtrSprinklersGardenHouseTime * 60
var int DelayedStartSprinklersFront = DelayedStartSprinklersEntrance + wtrSprinklersEntranceTime * 60
var int DelayedStartDripHose = DelayedStartSprinklersFront + wtrSprinklersFrontTime * 60
//Check if the source is rain water tank
if (itmIrrigationFromRainTank.state == ON) DelayedStartDripHose = 0
//Calculate stop delays in seconds
var int DelayedStopSprinklersTerrace = DelayedStartSprinklersGardenHouse + 2
var int DelayedStopSprinklersGardenHouse = DelayedStartSprinklersEntrance +2
var int DelayedStopSprinklersEntrance = DelayedStartSprinklersFront + 2
var int DelayedStopSprinklersFront = DelayedStartDripHose + 2
var int DelayedStopDripHose = DelayedStartDripHose + wtrDripHoseTime * 60
var int DelayedStopPump = 0
//Check if the source is rain water tank
if (itmIrrigationFromRainTank.state == ON) {
DelayedStopSprinklersFront = DelayedStartSprinklersFront + wtrSprinklersFrontTime * 60
DelayedStopDripHose = DelayedStopSprinklersFront + wtrDripHoseTime * 60
DelayedStopPump = DelayedStopSprinklersFront
if (DelayedStopSprinklersFront == 0) {
DelayedStopPump = DelayedStopDripHose - 120
}
}
logInfo( "irrigation:Commands","DurationSprinklersTerrace " + DurationSprinklersTerrace + " minutes")
logInfo( "irrigation:Commands","DurationSprinklersGardenHouse " + DurationSprinklersGardenHouse+ " minutes")
logInfo( "irrigation:Commands","DurationSprinklersEntrance " + DurationSprinklersEntrance + " minutes")
logInfo( "irrigation:Commands","DurationSprinklersFront " + DurationSprinklersFront+ " minutes")
logInfo( "irrigation:Commands","DurationDripHose " + DurationDripHose + " minutes")
logInfo( "irrigation:Commands","scaleFactor " + scaleFactor + " %")
logInfo( "irrigation:Commands","wtrSprinklersTerraceTime " + wtrSprinklersTerraceTime + " minutes")
logInfo( "irrigation:Commands","wtrSprinklersGardenHouseTime " + wtrSprinklersGardenHouseTime + " minutes")
logInfo( "irrigation:Commands","wtrSprinklersEntranceTime " + wtrSprinklersEntranceTime + " minutes")
logInfo( "irrigation:Commands","wtrSprinklersFrontTime " + wtrSprinklersFrontTime + " minutes")
logInfo( "irrigation:Commands","wtrDripHoseTime " + wtrDripHoseTime + " minutes")
logInfo( "irrigation:Commands","Rain Sensor " + WaterLeakDetectedRainSensor.state )
logInfo( "irrigation:Commands","DelayedStartSprinklersGardenHouse in " + DelayedStartSprinklersGardenHouse/60 + " minutes")
logInfo( "irrigation:Commands","DelayedStartSprinklersEntrance in " + DelayedStartSprinklersEntrance/60 + " minutes")
logInfo( "irrigation:Commands","DelayedStartSprinklersFront in " + DelayedStartSprinklersFront /60 + " minutes")
logInfo( "irrigation:Commands","DelayedStartDripHose in " + DelayedStartDripHose /60 + " minutes")
logInfo( "irrigation:Commands","DelayedStopSprinklersTerrace in " + DelayedStopSprinklersTerrace /60 + " minutes")
logInfo( "irrigation:Commands","DelayedStopSprinklersGardenHouse in " + DelayedStopSprinklersGardenHouse /60 + " minutes")
logInfo( "irrigation:Commands","DelayedStopSprinklersEntrance in " + DelayedStopSprinklersEntrance /60 + " minutes")
logInfo( "irrigation:Commands","DelayedStopSprinklersFront in " + DelayedStopSprinklersFront /60 + " minutes")
logInfo( "irrigation:Commands","DelayedStopDripHose in " + DelayedStopDripHose /60 + " minutes")
logInfo( "irrigation:Commands","DelayedStopPump in " + DelayedStopPump /60 + " minutes")
logInfo( "irrigation:Commands","Water source is rain tank :" + itmIrrigationFromRainTank.state )
// Start sprinklers terrace
if (wtrSprinklersTerraceTime > 0) {
WateringEndTime = now.plusSeconds(DelayedStopSprinklersTerrace)
logInfo( "irrigation:Commands","Watering terrace starts " + WateringStartTime + ", finish " + WateringEndTime )
logInfo( "irrigation:Commands","itmIrrigationSprinklersTerraceCmd [ON_R]")
itmIrrigationSprinklersTerraceCmd.sendCommand(ON_R)
tmrIrrigationTerrace_Stop= createTimer( now.plusSeconds(DelayedStopSprinklersTerrace)) [|
logInfo( "irrigation:Commands","itmIrrigationSprinklersTerraceCmd[OFF_R]")
itmIrrigationSprinklersTerraceCmd.sendCommand(OFF_R)
]
}
// Start sprinklers garden house
if (wtrSprinklersGardenHouseTime > 0) {
WateringStartTime = now.plusSeconds(DelayedStartSprinklersGardenHouse)
WateringEndTime = now.plusSeconds(DelayedStopSprinklersGardenHouse)
logInfo( "irrigation:Commands","Watering garden house start " + WateringStartTime + ", finish " + WateringEndTime)
tmrIrrigationGardenHouse_Start= createTimer( now.plusSeconds(DelayedStartSprinklersGardenHouse)) [|
logInfo( "irrigation:Commands","itmIrrigationSprinklersGardenHouseCmd[ON_R]")
itmIrrigationSprinklersGardenHouseCmd.sendCommand(ON_R)
]
tmrIrrigationGardenHouse_Stop= createTimer( now.plusSeconds(DelayedStopSprinklersGardenHouse)) [|
logInfo( "irrigation:Commands","itmIrrigationSprinklersGardenHouseCmd[OFF_R]")
itmIrrigationSprinklersGardenHouseCmd.sendCommand(OFF_R)
]
}
// Start sprinklers entrance
if (wtrSprinklersEntranceTime > 0) {
WateringStartTime = now.plusSeconds(DelayedStartSprinklersEntrance)
WateringEndTime = now.plusSeconds(DelayedStopSprinklersEntrance)
logInfo( "irrigation:Commands","Watering entrance start " + WateringStartTime + ", finish " + WateringEndTime)
tmrIrrigationEntrance_Start= createTimer( now.plusSeconds(DelayedStartSprinklersEntrance)) [|
logInfo( "irrigation:Commands","itmIrrigationSprinklersEntranceCmd[ON_R]")
itmIrrigationSprinklersEntranceCmd.sendCommand(ON_R)
]
tmrIrrigationEntrance_Stop= createTimer( now.plusSeconds(DelayedStopSprinklersEntrance)) [|
logInfo( "irrigation:Commands","itmIrrigationSprinklersEntranceCmd[OFF_R]")
itmIrrigationSprinklersEntranceCmd.sendCommand(OFF_R)
]
}
// Start sprinklers front
if (wtrSprinklersFrontTime > 0) {
WateringStartTime = now.plusSeconds(DelayedStartSprinklersFront)
WateringEndTime = now.plusSeconds(DelayedStopSprinklersFront)
logInfo( "irrigation:Commands","Watering entrance start " + WateringStartTime + ", finish " + WateringEndTime)
tmrIrrigationFront_Start = createTimer( now.plusSeconds(DelayedStartSprinklersFront)) [|
logInfo( "irrigation:Commands","itmIrrigationSprinklersFrontCmd[ON_R]")
itmIrrigationSprinklersFrontCmd.sendCommand(ON_R)
]
tmrIrrigationFront_Stop = createTimer( now.plusSeconds(DelayedStopSprinklersFront)) [|
logInfo( "irrigation:Commands","itmIrrigationSprinklersFrontCmd[OFF_R]")
itmIrrigationSprinklersFrontCmd.sendCommand(OFF_R)
//itmIrrigationPumpCmd.sendCommand(OFF_R)
]
}
//Start & stop pump
if (DelayedStopPump > 0) {
logInfo( "irrigation:Commands","itmIrrigationPumpCmd [ON_R]")
itmIrrigationPumpCmd.sendCommand(ON_R)
tmrIrrigationPump_Stop = createTimer( now.plusSeconds(DelayedStopPump)) [|
logInfo( "irrigation:Commands","itmIrrigationPumpCmd[OFF_R]")
itmIrrigationPumpCmd.sendCommand(OFF_R)
]
}
// Start drip hose (and depresurise pipe)
if (DelayedStopDripHose > 0) {
WateringStartTime = now.plusSeconds(DelayedStartDripHose)
WateringEndTime = now.plusSeconds(DelayedStopDripHose)
logInfo( "irrigation:Commands","Watering drip hose start " + WateringStartTime + ", finish " + WateringEndTime)
tmrIrrigationDripHose_Start = createTimer( now.plusSeconds(DelayedStartDripHose)) [|
logInfo( "irrigation:Commands","itmIrrigationDripHoseCmd[ON_R]")
itmIrrigationDripHoseCmd.sendCommand(ON_R)
]
tmrIrrigationDripHose_Stop= createTimer( now.plusSeconds(DelayedStopDripHose)) [|
logInfo( "irrigation:Commands","itmIrrigationDripHoseCmd[OFF_R]")
itmIrrigationDripHoseCmd.sendCommand(OFF_R)
]
}
//sendPushoverMessage(pushoverBuilder("(2) Garden watering ended [" + WateringEndTime
//+ "]").withPriority(-2))
// End cyclus
tmrIrrigation_Stop = createTimer(WateringEndTime) [|
itmIrrigationLastDate.sendCommand(now.toLocalDateTime().toString() + "+01:00[Europe/Brussels]")
logInfo( "irrigation:Commands","==== Watering ended ====")
isWatering = false
EventHist.sendCommand("Garden watering ended")
sendNotification("xxxxx@gmail.com", "Garden watering ended","rain","Info")
]
logDebug( "irrigation:Commands"," tmrIrrigation_Stop[" + tmrIrrigation_Stop + "]")
}
end
// Main algorithm
rule "irrigation:irrigation:Main_algorithm"
when
Time cron "0 0 0/1 1/1 * ? *" //Run every hour
// Time cron "0 0/5 * 1/1 * ? *" // Test every 5 minutes
then
logInfo( "irrigation:Main_algorithm"," -START- ")
// Check that the current time is the watering time and that the system is set to automatic watering
// and whether to check the actual watering time (checkUserStartTime)
if(itmIrrigationStartTime.state==NULL) {
itmIrrigationStartTime.sendCommand(FallbackStartTime)
logInfo( "irrigation:Main_algorithm"," itmIrrigationStartTime SET TO " + FallbackStartTime )
}
if(itmIrrigationDurationSprinklersTerrace.state==NULL) {
itmIrrigationDurationSprinklersTerrace.sendCommand(FallbackDurationSprinklersTerrace)
logInfo( "irrigation:Main_algorithm"," itmIrrigationDurationSprinklersTerrace SET TO " + FallbackDurationSprinklersTerrace + " min")
}
if(itmIrrigationDurationSprinklersGardenHouse.state==NULL) {
itmIrrigationDurationSprinklersGardenHouse.sendCommand(FallbackDurationSprinklersGardenHouse)
logInfo( "irrigation:Main_algorithm"," itmIrrigationDurationSprinklersGardenHouse SET TO " + FallbackDurationSprinklersGardenHouse + " min")
}
if(itmIrrigationDurationSprinklersEntrance.state==NULL) {
itmIrrigationDurationSprinklersEntrance.sendCommand(FallbackDurationSprinklersEntrance)
logInfo( "irrigation:Main_algorithm"," itmIrrigationDurationSprinklersEntrance SET TO " + FallbackDurationSprinklersEntrance + " min")
}
if(itmIrrigationDurationSprinklersFront.state==NULL) {
itmIrrigationDurationSprinklersFront.sendCommand(FallbackDurationSprinklersFront)
logInfo( "irrigation:Main_algorithm"," itmIrrigationDurationSprinklersFront SET TO "+ FallbackDurationSprinklersFront +" min")
}
if(itmIrrigationDurationDripHose.state==NULL) {
itmIrrigationDurationDripHose.sendCommand(FallbackDurationDripHose)
logInfo( "irrigation:Main_algorithm"," itmIrrigationDurationDripHose SET TO " + FallbackDurationDripHose +" min")
}
if(itmIrrigationDurationFilterFlush.state==NULL) {
itmIrrigationDurationFilterFlush.sendCommand(FallbackDurationFilterFlush)
logInfo( "FILE", "itmIrrigationDurationFilterFlush: itmIrrigationDurationDripHose SET TO " + FallbackDurationFilterFlush + " min")
}
if(itmIrrigationScaleFactor.state==NULL) {
itmIrrigationScaleFactor.sendCommand(FallbackScaleFactor)
logInfo( "irrigation:Main_algorithm"," itmIrrigationScaleFactor SET TO " + FallbackScaleFactor + " %")
}
if(itmIrrigationMinimumReqRainfallCfg.state==NULL) {
itmIrrigationMinimumReqRainfallCfg.sendCommand(FallbackMinimumReqRainfallCfg)
logInfo( "irrigation:Main_algorithm"," itmIrrigationMinimumReqRainfallCfg SET TO " + FallbackMinimumReqRainfallCfg + " mm")
}
var NowMonth = now.getMonthValue()
var NowDay = now.getDayOfMonth()
if (NowMonth<10) {NowMonth = '0' + NowMonth}
if (NowDay<10) {NowDay = '0' + NowDay}
val userStartTime = parse(now.getYear() + "-" + NowMonth + "-" + NowDay + "T" + itmIrrigationStartTime.state + ":00.000+01:00[Europe/Brussels]").withZoneSameInstant(ZoneId.systemDefault())
logInfo( "irrigation:Main_algorithm"," userStartTime [" + userStartTime + "]")
logInfo( "irrigation:Main_algorithm"," checkUserStartTime [" + checkUserStartTime + "]")
logInfo( "irrigation:Main_algorithm"," isWatering [" + isWatering + "]")
logInfo( "irrigation:Main_algorithm"," itmIrrigationAuto.state [" + itmIrrigationAuto.state + "]")
logInfo( "FILE", "irrigation:Main_algorithm: itmIrrigationLastDate.state [" + itmIrrigationLastDate.state + "]")
//Check the time hour by hour minute by minute, whether we are checking the set time. If the system is already watering, it does not check the conditions and does not water.
if ( ( ( userStartTime.hour == now.getHour() && userStartTime.minute == now.getMinute() ) || checkUserStartTime == false )
&& itmIrrigationAuto.state == ON && (isWatering == false)
) {
if (itmIrrigationLastDate.state !== NULL) {
lastWtrDate = parse(itmIrrigationLastDate.state.toString).withZoneSameInstant(ZoneId.systemDefault())
}
if (itmIrrigationLastDate.state == NULL) {
lastWtrDate = null
}
logInfo( "irrigation:Main_algorithm"," Rain Sensor state [" + WaterLeakDetectedRainSensor.state + "]")
logInfo( "irrigation:Main_algorithm"," Soil Moisture [" + Miflora_Azalea_Moisture.state + "]")
logInfo( "irrigation:Main_algorithm"," lastWtrDate [" + lastWtrDate + "]")
logInfo( "irrigation:Main_algorithm"," maxNoWtrDays [" + maxNoWtrDays + "]")
logInfo( "irrigation:Main_algorithm"," checkWtrRainSensor [" + checkWtrRainSensor + "]")
logInfo( "irrigation:Main_algorithm"," checkUserStartTime [" + checkUserStartTime + "]")
//logInfo( "irrigation:Main_algorithm"," itmIrrigationMinimumReqRainfallCfg [" + (itmIrrigationMinimumReqRainfallCfg.state as DecimalType).intValue + "]")
/*
* Take the amount of water in mm that will potentially drop by the next morning in mm
*/
rainfallMm = localTodayRainVolume.state
logInfo( "irrigation:Main_algorithm"," Getting wheather forecast [" + localTodayRainVolume.state + "]")
if( (rainfallMm >= 0 )) {
//logInfo( "irrigation:Main_algorithm"," Getting wheather forecast [" + localTodayRainVolume.state + "]")
} else {
logInfo( "irrigation:Main_algorithm"," Cannot rain forecast - rainfallMm is 0 mm ")
rainfallMm = 0
}
minimumReqRainfall = (itmIrrigationMinimumReqRainfallCfg.state as DecimalType).intValue
logInfo( "irrigation:Main_algorithm","====================== Wheather forecast ============================ ")
logInfo( "irrigation:Main_algorithm"," rainfallMm [" + rainfallMm*1000 + "m]")
logInfo( "irrigation:Main_algorithm"," minimumReqRainfall in mm [" + minimumReqRainfall + "]")
// checking the condition of the rain sensor
if ( WaterLeakDetectedRainSensor.state == OFF || checkWtrRainSensor==false ) {
logInfo( "irrigation:Main_algorithm"," RainSensor is dry, check other conditions")
//checking whether the expected amount of precipitation will be sufficient (divide by 1000 since the value from OpenWeatherMap is in meters)
if (rainfallMm > minimumReqRainfall / 1000) {
// rainfall in the next 24 hours should be sufficient
// but I check how many days have not been watered, if more than maxNoWtrDays I water it
if(lastWtrDate===null) {
if (Miflora_Azalea_Moisture.state < itmMinimumSoilMoisture.state){
logInfo( "irrigation:Main_algorithm"," rainfall is sufficient but lastWtrDate is null, for safety starting watering")
EventHist.sendCommand("Automatic watering has been activated ")
itmIrrigationNotification_Proxy.sendCommand("START")
}
} else if(lastWtrDate.isBefore(now.minusDays(maxNoWtrDays))) {
if (Miflora_Azalea_Moisture.state < itmMinimumSoilMoisture.state){
logInfo( "irrigation:Main_algorithm"," last watering date is more than [" +maxNoWtrDays+ "] days ago, starting watering")
EventHist.sendCommand("Automatic watering has been activated ")
itmIrrigationNotification_Proxy.sendCommand("START")
}
} else {
sendNotification("xxxxx@gmail.com", "No automatic watering, expected rainfall " + rainfallMm + "mm within the next 24 hours","rain","Info")
logInfo( "irrigation:Main_algorithm","No automatic watering, expected rainfall " + rainfallMm + "mm within the next 24 hours")
}
} else {
// the expected amount of precipitation within 24 hours is insufficient
missingRainfall = minimumReqRainfall/1000 - rainfallMm //divide by 1000 since the value from OpenWeatherMap is in meters
logInfo( "irrigation:Main_algorithm"," Missing [" + missingRainfall*1000 + "] mm rainfall")
if(lastWtrDate===null) {
if (Miflora_Azalea_Moisture.state >= itmMinimumSoilMoisture.state){
logInfo( "irrigation:Main_algorithm"," lastWtrDate is null, for safety starting watering")
EventHist.sendCommand("Automatic watering has been activated")
itmIrrigationNotification_Proxy.sendCommand("START")
}
} else if(lastWtrDate.isAfter(now.minusHours(maxNoWtrDays*24-1))) {
if (Miflora_Azalea_Moisture.state >= itmMinimumSoilMoisture.state){
logInfo( "irrigation:Main_algorithm","last watering date is less than [" +maxNoWtrDays+ "] days ago and moisture is OK, postponing watering")
} else {
logInfo( "irrigation:Main_algorithm","last watering date is less than [" +maxNoWtrDays+ "] days ago but moisture is NOT OK, starting watering")
EventHist.sendCommand("Automatic watering has been activated")
itmIrrigationNotification_Proxy.sendCommand("START")
}
} else {
logInfo( "irrigation:Main_algorithm"," last watering date is more than [" +maxNoWtrDays+ "] days ago, starting watering")
EventHist.sendCommand("Automatic watering has been activated ")
itmIrrigationNotification_Proxy.sendCommand("START")
}
}
logInfo( "irrigation:Main_algorithm","======= End of Watering algorithm ======= ")
} else {
// the sunroof sensor is on it's raining or raining
itmIrrigationLastDate.sendCommand(now.toLocalDateTime().toString() + "+01:00[Europe/Brussels]") // set that there was rainfall / watering
logInfo( "irrigation:Main_algorithm"," watering not started, RainSensor is wet - watering is not needed")
sendNotification("xxxxx@gmail.com", "No automatic watering, rain sensor is wet","rain","Info")
}
} else {
logInfo( "irrigation:Main_algorithm"," not started. checkUserStartTime[" +checkUserStartTime+ "] itmIrrigationAuto.stat["
+itmIrrigationAuto.state + "] isWatering[" +isWatering+ "] WaterLeakDetectedRainSensor.state[" + WaterLeakDetectedRainSensor.state + "]"
)
}
end