Why won't this rule work

I'm stuck! I'm trying to use RM to update a variable according to active notifications. This is so I can I have single tile (in SharpTools) display that variable on my dashboard when one or more (up to 3) notifications are active. The crucial part is that when active, I want the variable to update every couple of seconds displaying the next notification, repeating continuously. Once there are none the repeat should stop.

If I turn all 3 switches on, the rule fires and the variable will update correctly for 1 cycle. But it will remain set at "hh:mm - Switch 3 On" When it repeats the actions, although the switches are all still on, RM ignores their status and does not update the variable on each pass.

If I trigger the rule again by switching a switch on or off, again it runs just once. When it runs again the %time% is changed on the notifications for the switches that are still on. It appears that %time% is not the time that the switch was turned on but is actually %now%

Seems that you might be missing an END-REP and perhaps some action before that at the end of the rule.

Or, perhaps you intended the WHILE ā€¦ REPEAT to be at the very beginning, with an END-REP at the very end, encapsulating your whole rule.

The Hubitat WHILE ā€¦ REPEAT ā€¦ END-REP idiom is similar, but not the same as the WHILE ā€¦ REPEAT idiom of other languages (C, for example).

I'm not convinced the END-REP is needed (but I'm happy to be corrected) The repeat is set for "repeat while variable notificationOn is True". As soon as all of the switches are turned off "notificationOn" goes false and the repeat ends successfully. It's just that the logs show the actions being repeated but ignoring the current on status of the switches.

I'll clone the rule and modify it like that with an end repeat to see if that makes a difference :+1:

Well, like you, Iā€™m happy to be corrected, because Iā€™ve never left a REPEAT unterminated. But there are two possibilities, one as you mention, and another where the WHILE does an implied ā€œend ruleā€, which falls off the end immediately. Iā€™ve never seen the ā€œmissing END-REPā€ behavior definitively defined.

1 Like

Everything between the WHILE and the END-REP will be repeated. In your example nothing is between the WHILE and the END-REP. Nothing will be repeated even if you add the end-rep.

1 Like

Thatā€™s my understanding, too. The last action is not the same as a wait for condition.

Here's an example... RM evaluates the condition at the time of the WHILE. If the condition is true it will repeat all actions until the END-REP. If not it skips the whole block. In this example it will attempt to send disarm commands to envisalink every 5 seconds up to 10 times as long as the status does not contain Ready.

1 Like

This is correct. See the Rule 5.1 docs for a couple examples of repeats:

https://docs.hubitat.com/index.php?title=Rule-5.1#Repeat

More to come, but the Repeat, including "While..." syntax, is documented. :smiley: You can also see this thread for some older examples, which let you do the same thing with a slightly different syntax (but it will still work): How to get Repeated Notifications using Rule Machine

1 Like

Also... @bertabcd1234 you may know better than I... but I think %time% is the time the trigger event occurred... ?

1 Like

Yes. %now% is current time.

2 Likes

@johnwill1 what you could do is put the WHILE statement at the beginning of the rule and the END-REP at the end... but in that case you need something to manipulate notificationOn... otherwise it will just loop forever every 10 seconds. Unless it's a hub variable manipulated outside of this rule.

OK. So I updated the rule like this:

That seems to sort it out so that the tile representing the variable "scrolls" through the switches that are on and it does now repeat though it doesn't seem quite right. Switches 1, 2 & 3 are all on and it is scrolling 1,2,1,3,1,2,1,3. Maybe altering a switch while the repeat is active is firing multiple instances - it's difficult to see from the logs. Perhaps there's a better way of achieving the same end result...

With regard to the time - I was hoping that %time% would give me the time that the specific switch was turned on and that the time would stick if another switch was turned on. However lets say I turn switch1 on at 19:15 - the variable will show that; However if I subsequently turn on switch2 at 19:25, the time for switch1 is also updated to 19:25. So it is displaying the time the rule was triggered last even if it is not that particular switch that triggered it. As such the %time% is unusable as it becomes "incorrect" as soon as the status of another switch changes. These virtual switches are intended to show the time the event happened that caused the virtual switch to operate.

One solution could be 3 rules, one for each switch.

It is - notificationOn goes false when all 3 switches are turned off via another RM url that also sets the votificationActive variable to null, so that I get a blank tile when nothing is active.

1 Like

Yes. Any change to any of the three switches will spin up a concurrent instance of the rule. This can be prevented with some logic involving the "private boolean" function if you want to go there.

And gotcha on the notificationOn!

1 Like

That seems to be the ethos of RM (at least in my limited experience). Why use 1 rule when you can do it with 3 :laughing:

LOL. Let me phrase it another way. Sometimes three simple rules is easier than one more complex rule.

I do! If I can get this to work how I want I can go to bed both smug AND drunk!

1 Like

Anything I can do to advance your cause I am happy to.

Private Boolean is - wait for it - a boolean variable private to the rule. By default it is true. But it can be used to prevent a rule repeating, as in the example below... if private boolean is false it means the rule is already running so abruptly exit the rule. Otherwise set it false so a second trigger will just exit harmlessly. And at the end don't forget to set it true again!

You can do some sneaky stuff with PB too - like turn on one rule's PB from another rule. But all you need for this is the basics.

BTW the rule above was written before "use required expressions" became a thing. So you can use that instead to make things a bit smoother.

2 Likes