OH3 Rule check for improvement

Hi All,

i created a rule to run my garden watering. I want to run this rule past you to see if there is an area of improvement that you guys see.

What the rule should do ( and does ) is:

  1. comparing a set next date vs now, once it is < the watering starts and immediately sets a new date based on the intervall and run-time i set in the UI
  2. reschedule for one day in case it rained or the automatic watering is disabled
  3. send the handling of the timer to the accumulator with the sendHttpGetRequest
  • My concerns: is cron the best way to permanent check the startdate vs. now? i saw some rules with icalendar that does the same, so i adapted it.
  • what happens with a system restart? The times are persisted but i am not sure if this works every time. Add an IF for time UNDEF?

I appreciate your feedbacks…

rule "Start Scheduled - Blumen"
when
	  Time cron "0 * * * * ?"			// Sytemstart noch abfangen 
then 

 val Number currenttime = now.toInstant().toEpochMilli()
 val Number startdate = (Zeit_Bewaesserung_Blumen.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli 	
 
 if (currenttime < startdate) { return;	} 
 
 if (currenttime > startdate) 		// was bei UNDEF? 
 
	{
 
 if (Blumen_zu_Nass.state ==ON)  {
 
 	val lastblumen = (Zeit_Bewaesserung_Blumen.state as DateTimeType).getZonedDateTime() 
	val nextdayblumen = lastblumen.plusDays(1) 
	logInfo("Blumen","Bewaesserung: " + nextdayblumen + " naechste Bewaesserung")
	Zeit_Bewaesserung_Blumen.postUpdate(nextdayblumen.toString())
 
 		}
		
 if ((Blumen_zu_Nass.state ==OFF) && (GATEWAYEXTRAS_Autobewaesserung.state ==OFF)) {
 
 	val lastblumen = (Zeit_Bewaesserung_Blumen.state as DateTimeType).getZonedDateTime() 
	val nextdayblumen = lastblumen.plusDays(1) 
	logInfo("Blumen","Bewaesserung: " + nextdayblumen + " naechste Bewaesserung")
	Zeit_Bewaesserung_Blumen.postUpdate(nextdayblumen.toString())
 
 		}

 if ((Blumen_zu_Nass.state ==OFF) && (GATEWAYEXTRAS_Autobewaesserung.state ==ON)) {    
 
	val timeinsec = (Timer_Blumen.state as Number * 60)
	val int intervall = (Intervall_Tage_Blumen.state as DecimalType).intValue()
	val lastblumen = (Zeit_Bewaesserung_Blumen.state as DateTimeType).getZonedDateTime() 
	val futureblumen = lastblumen.plusDays(intervall)
	
		logInfo("Bewaesserung-Blumen","Auto Timer Blumen: " + timeinsec + " sek.") 
		sendHttpGetRequest("http://192.168.178.40:8181/x.exe?state=dom.GetObject(%22BidCos-RF.PEQ0085660:4.ON_TIME%22).State("+timeinsec+".00)")
		Thread::sleep(2000)
		sendCommand(HutschieneGarage_Blumen, ON) 
//		sendCommand(HutschieneGarage_State_Rasen, ON) // Pumpe noch einbauen

		logInfo("Bewaesserung-Blumen","Time Update: " + futureblumen + " naechste Bewaesserung")
		Zeit_Bewaesserung_Blumen.postUpdate(futureblumen.toString())
                
  		}
	}
 end

Typically running a rule once per second is not going to be the best approach. It’s called a “busy wait” because the rule is really busy consuming CPU and memory and energy doing nothing.

The way I would implement it is to use a timer and maybe split the rule up a bit. You have a DateTime Item that stores the start time. So trigger a rule at midnight to advance that DateTime to today. Note, if you just add 24 hours, it will become off by an hour when DST changes. You can see a some examples of managing that sort of calculation at Design Pattern: Time Of Day.

In another rule that triggers when the DateTime Item changes, and when openHAB restarts create a timer to run at that DateTime. In that Timer’s function do the work. If the timer already exists, cancel it before creating a new one.

In OH 3, the System started rule is not guaranteed to run when you just change the .rules file. In that case you may need to run that rule manually which you can do from MainUI. Just navigate to the rule and click the play button.

Thanks Rich for your guidance. I will dive deeper into your suggestions.

For the cron and as immediate action, i have set the cron to run every minute which reduces the load and 59times less triggering per minute for the rule. But this is only a temp. I have to figure it out and learn by doing to bring the puzzle with Time of Day together with this one. If i stuck, i let you know.

For DST, yes i am aware. Good point to find a permanent solution.

Just one idea (I am doing it this way).

I use the Astro binding and know, when the sun goes down.
On sunset I start my irrigation unless:

  1. The soil is too wet1
  2. Weather forecast predicts rain for the night / next day
  3. It’s already raining
  4. It’s below 0°C

Specifically in northern Europe the variance of sunset / sunrise are compensated very well using the astro binding.

thanks, could be an alternative although at the moment i prefer to set a fixed date for it. For the exceptions i will go pretty much the same…