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