How to prevent simultaneous execution of Rule?

I've got a trigger-less Rule named "Alarm Warning" setup that combines turning on lights and sounding an alarm, for 15 seconds.

This Rule is ran from another trigger (motion sensor)

This works fine so far, except that, when someone is actively moving in the room, it keeps triggering motion sensor , and in turn keeps running the Alarm Warning Rule every 3-5 seconds and it's causing some weird behaviour like the sound abruptly cutting out and turning back on again , sometimes it doesn't turn on again, sometimes it doesn't turn off..

basically this situation is messing up the flow.

The generic z-wave motion sensor doesn't have options for "motion rest" and similar. (unless im missing a way to set this even on generic z-wave motion sensors)

So I figured I could solve this by somehow, making the Rule run, only when it is not currently running.... is there a way to easily do that? I can't find the condition for it. And I'd hate to do variable stuff and I hope (expect) there's a more native way to do this, a hubitat setting like "Allow One instance of Rule only" or something similar?

I've used Private Booleans for this sort of thing a lot.

IF (PB True)
Set PB False
Do alarmy things
Set PB True
EndIf

3 Likes

I do the same.

One thing to remember when doing this is that if there are any waits in your rule, it (the rule) may be “cancelled” and the code setting your boolean to true may never end up running.

This was a problem that I ran into a lot until I learned how to use “Delays” vs “Waits”.

  • Delays will stop the code and continue when the condition is met.
  • Waits will stop the code and continue when the condition is met, unless the rule is triggered again, in which case the rule will be cancelled and re-ran.

In the second scenario with @rob9’s excellent example, PB will be False and the rule will not run again as the “Set PB True” code will never be run.

3 Likes

Tnx guys. I was hoping for a more direct (on rule) option.

is PB a based on a global variable accessible by all rules? or is it a variable local to a rule or device? because i tried exploring this option and the setting i get is just true or false


I can't seem to set the "variable" so im assuming you an only set 1 PB on the system and the state of that PB is shared? Thus i can't independently use this PB strategy for other rules?

Thanks Carl
as for my case, i needed a way to prevent Rules from executing their actions if already still in execution and i guess the closing thing to achieving that is using private boolean. But i'm confused about this. Is there only 1 global variable in the hub that holds this boolean? I was hoping i could set like variables RULE_1_is_true and assign the rule's condition to that..... then i can set variables for other rules as well. But if this boolean thing is just 1 variable globally then I can only use this strategy on 1 rule only because,obviously the boolean state is shared by all rules and other functions in the hub. :frowning:

Every rules has its own PB.

You can set/reset the PB of a rule from any other RM rule.

What you showed above using Predicate Conditions will work well for this, as it will prevent the rule from even being triggered when the Predicate is false. The choice you showed is simply the state you want PB to be in for the rule to run. So, make the Predicate be PB true, set PB to false as first action of rule, and set PB to true as last action, thus re-enabling the rule.

1 Like

If you use Predicate Conditions on Private Boolean this is not an issue. Once the Predicate Conditions are false (set PB false as first action), the rule will not be triggered, so Waits will not be cancelled. The rule can run to completion, and set Private Boolean to true as the last action.

4 Likes

Glad that every Rule has it's own PB , thanks for confirming!