Elegant way to have a rule not trigger?

Iā€™m looking for an elegant way not to trigger a rule.

I have tried the ā€œExit Ruleā€ command based on a condition, but I noticed that if the rule was triggered a second time when the first instance contained a delay that is still counting down, that delay will be exited as well and the expected action will not run.

The other option I have tried is to set a boolean variable and add an if condition at the beginning of my rule that will only execute the code if the value matches what I want it to be. The boolean can be turned off in the rule and turned on with a delay.

I would love to hear of a more elegant way to do this!

Your delay should still be in place if another instance fires and you have an Exit Rule. Only a "Cancel Delayed Actions" on a "cancelable" Delay (in the same rule) or a "Cancel Rule Timers" (in the same rule or called on this rule from any rule) will remove a delay. This is assuming you are actually using a "Delay" action or the "delay" option on an action. This does not apply to to "Wait" actions, where any trigger matching will cancel the wait.

So, if that's not what you're seeing, I suspect there is another problem. Sharing an example of a rule in question (or a minimal example that shows the same issue) might be a better way to get more targeted help.

Thanks! That is also how I expected it would run... Unfortunately RM seems to act differently... I had a simple RM which I overwrote with the 2nd case, but here is essentially the code I had:

Trigger - Window Open

Rule:
If ranAlready=true, Exit Rule
Set ranAlready to true
If Probability of Precipitation > 20, then
Echo Speak: Tell the user to watch for rain, and play the weather
End if
Set ranAlready to false ā€”> Delay 1 minute

I found that in that and another rule I had setup, the Exit Rule caused my variable never to change to false.

So I set an if condition instead at the beginning to only run if ranAlready was false.

Iā€™m thinking that there are much more elegant ways to do this!

Iā€™ll create another RM to test it again, just in case!

I have created a new RM on a different Hub. Here is the code:

Here is a hubigraph showing when the switch was turned on and off. It should toggle every minute, but oddly enough, it did a couple times, then stopped...

Both of your rules look correct to me, and something like this:

IF (Variable is True) Exit Rule
Set Variable True
//Do things
Set Variable False --> delay 0:01:00

...is basically the same as:

IF (Variable is False) THEN
  Set Variable True
 //Do things
END-IF
Set Variable False --> delay 0:01:00

...so the outcome should be the same either way: the rule actions (or at least the ones that actually mean something) run at most one time per minute, regardless of trigger. There are rare cases you can get into where a sensor sends duplicate events in a short time period, infamous examples being Z-Wave contact sensors that sent two "contact opened" reports within milliseconds of each other, which wasn't always enough time for the new rule instance to see the value of a variable set by the old one (local variables were suggested as being better/faster than Private Boolean here, presumably an implementation detail, but I see that's what you're already doing). With your "Every 10 seconds" trigger, I don't see any reason that should be an issue or any reason why your rule wouldn't keep working indefinitely unless you did a "Cancel rule timers" on this rule (which will also cancel periodic triggers) or have another automation that acts on the "test switch" that might affect its state in ways not apparent from the rule (you can turn on trigger logging and action logging in the rule to see what RM thinks it's doing in case that's helpful).

With both of these rules, as with yours, the delayed action should remain even if the rule gets triggered in the meantime, barring the above. You can verify this by looking at "Scheduled Jobs" on the status (gear icon) page for the app--something should be listed there corresponding to an execution time you'd expect from whenever the delay is up.

The only other thing I can think of is to leave HubiGraphs out of the picture for a second and jsut go to "Events" (the event history) on the device ("test switch" or whatever) page to look at its actual history. My assumption is it would match what you see in the graph, but it's worth checking out regardless in case there is a difference--the device event history is the real thing. :slight_smile:

Good luck!

Thanks! I created everything from scratch, so am certain nothing else is impacting the switch.

One thing that I had done initially was to manually run the rule a few times - I wonder if that might impact it somehow...

I re-ran the rule with all logging on, and everything seems to be running good... Iā€™ll do some further testing tomorrow... Itā€™s getting late and Iā€™m having problems thinking straight... :crazy_face:

I did some more quick testing, and it seems that manually running the rule is okay. However, Updating the rule breaks the delay (The event doesn't get executed as previously scheduled), as shown in the log below.

At times 54 and 57 seconds, I ran manually. After the 32 second mark, I updated the rule, and the variable doesn't reset.

I think that this is what had happened previously.

Probably normal if you are updating the rule that it stops previous instances of it...?

By "updating the rule," do you mean clicking the "Update Rule" button? There generally isn't a reason to do that unless you changed a trigger and want to test something with the rule still open (clicking "Done" should do the same and close the rule), but I'm not sure it should break anything, either...

One thing you could check: is there anything for "Scheduled Jobs" under the "App Status" (gear icon) page? If you're familiar with cron, you should see something that suggests it runs every 10 minutes (or whatever your trigger is). If you can find a way that makes it reliably disappear unexpectedly, you may have discovered a bug that I'm sure staff would be interested in fixing. Otherwise I can't think of what would be making this happen. :thinking:

Yup! And I typically use it if it is easier than waiting for the trigger... Ex.: when it needs a temperature change, or if it is easier than opening the door/window.

I have no idea what cron is, but there is an item that appears and disappears (delayedAct). I suspect it is the delay. The periodicHandler I assume is what triggers the rule itself every 10 seconds.

I can indeed reliably stop the ā€œDelayā€ action by clicking the ā€œUpdate Ruleā€ button.

The "perodicHandler" is your every-10-seconds periodic trigger (in English, that schedule means basically "every 10 seconds," technically at 0, 10, 20, etc. seconds after the minute), so seeing that always there is good. The "delayedAct" is the delay (I say this with such confidence...really, I'm just inferring based on the name and what I've seen in my own rules, haha). I did some testing and was able to replicate your findings, which is that "Update Rule" or "Done" cancel an in-progress delay. In your case, this is a problem and would explain why the bulk of your rule actions (including one to set it back to false) will never run.

I'll tag @bravenel to see if this is intentional behavior (tl;dr -- should clicking "Done" or "Update Rule" effectively cancel a delay?). I'm guessing they've probably thought this through and saw an advantage to this behavior, but I can't recall any previous discussion on this.

In your case, one workaround I can think of is using Private Boolean (or a virtual switch or any proxy you can think of for this state--just not a local variable since it isn't accessible outside that rule), then have a second rule set PB on the first rule. In the first/main rule, check PB as desired. That way, any updates you make to the "main" rule won't affect any scheduled job to effectively reset your timer/variable. The other, of course, is just not to edit the rule while you're in a state of delay. :smiley: There may also be a different way to approach the entire automation, which maybe someone else can suggest since I'm not thinking of anything else off the top of my head (to anyone looking at this: I'd suggest looking at the pseudo-code in post 3, not the screenshot, which is really just intended to demonstrate this behavior).

1 Like

Yes, it does. Both steps wipe clean all subscriptions and schedules, and rebuilds them. You can exit a rule by clicking on App List in the upper left, and that will not change subscriptions or schedules. Any changes you make to Actions become effective when they are made, not when Done is hit. Changes to Trigger Events only become effective when Done or Update Rule is hit (since Triggers require either a subscription or a schedule).

1 Like

Thanks @bertabcd1234 and @bravenel! This will help me with the development of my future rules, and updates to my current rules.

I like the idea of calling another rule! I may end up using it soon!

Another possibility is to Pause a rule. A rule can Pause itself, but then some other rule would have to Resume it. When Paused, it won't do anything, including delayed actions.

2 Likes

Yea, I was looking for the option to pause and unpause with delay... I found how to pause Ā« this rule Ā», but as you said, un-pausing with delay was not an available option...

As you say, I could probably setup a rule that when called would resume the other after a preset amount of time...

Thanks again for tour help!!! You are a big part of what makes Hubitat so awesome!!! (You too @bertabcd1234! :wink:)

1 Like