How to wait in a rule?


I I have a rule that reminds me to clean our cat litter. Now I want to get re reminded if I haven´t reacted. So I wnat sth like this:

while (cat litter not cleaned){
send notification
sleep 2 hours}

How can I achieve the “sleep” or “wait” part?

Thread::sleep(1000) or Timer

Generally speaking you would need to set up a timer for this, there are plenty of examples for light switches and garage doors in this forum.
Just for reference, there is a Thread::sleep command that can be used to make a rule wait, but its purpose is only for very short waits, it should never be used for more than, say, a few hundred milliseconds.

please don’t let a rule “WAIT” for more than a few (really!) seconds. This has to do with CPU-threads and stuff - read: it’s bad, if you do it for a longer period - and hours are VERY Long, considering CPUs calculate in nanoseconds and less… :wink:

What I do with those kinds of tasks (no persistence):

  • create an status item for it
  • create a rule which will fire every xx min if the Status is ON
Switch		catlitter 		"clean cat litter"
rule "Cat litter"
	Time cron "0 * */2 * * ?" // every two hours
	if (catlitter.state == ON) {
		// do something
1 Like

unless you need the rule to stop while stuff runs first

If you keep a few rules waiting through thread::sleep for more than that, you are very likely to run out of threads, and incur other problems…timers can do the same job without the risks

so why would you even use thread:sleep

It is actually not that common, but most frequently it is used if you need a 100ms for the OH2 bus and persistence to catch up so that you have the right values in case there were some actions triggered; or if you need bridges to communicate with your devices and OH2 pushes out a series of commands faster than the bridge can handle it (my hue lights have occasional random dropouts if I send too many commands in a row); an extra 10ms pause in between commands can do wonders in these cases

But the risk is that you use up threads (and OH2 does not have too many of them) with rules; and thread::sleeps will eat up too many resources if used for a long period

ok thanks for that

i try not to use it myself there was a case where kodi cracshed because of sending too many commands this was solved by a thread:sleep i do try not too use it myself

It is ALWAYS a bad idea to have long waits.

If the wait is very short or if you understand your Rules well enough to know with certainty that you will not have Thread::sleeps piling up upon each other causing you to run out of execution threads. Those users who know and understand their rules well enough to use long Thread:sleeps are experienced enough and knowledgeable enough to understand the risks they are taking and how to recognize and solve problems when they arise. For the rest of us (myself included because I would rather avoid the potential problem in the first place) we should be using Timers.

This is a good case where Thread::sleep is appropriate. I even wrote a design pattern (Design Pattern: Gate Keeper) on that problem and I do use Thread:sleep. But it needs to be short.

You should be able to do something like this which uses Design Pattern: Expire Binding Based Timers and Design Pattern: Recursive Timers.

Switch LitterCleaned
Switch LitterTimer { expire="2h,command=OFF" }
rule "Litter reminder"
    Time cron "..." or
    Item LitterTimer received command OFF
    if(LitterCleaned.state != ON)){
        // send notification

rule "Litter cleaned"
    Item LitterCleaned received command ON

rule "Reset LitterCleaned"
    Time midnight
1 Like

Thanks for that again rich yes i remember you saying last time i explained my rules too you and you said it was fine but avoid using them if you remember i was getting processor threads confused

I remember, but often my replies are as much if not more so directed at the future readers of the forum than the OP or what I’m replying to.

This is exactly what I was looking for. Many thanks!