Run Rule Actions and Loops

I'm having an issue with "Rule Rule Actions", I have dumbed it down to find the issue. I have Rule 1 which "runs" the "Rule Actions" in Rule 2. Rule 2 has a loop in it. What is happening is when the first loop completes, the control is returned to Rule 1, but Rule 2 is still running.

Comments and where I went wrong are welcome.

Below are the 2 rules and the log from running it.

Rule 1

image

Rule 2

image

Log

app:332020-07-16 07:29:48.906 pm infoReceived event from server/Follow Me: Family Room Motion Zone: [motion, active ]
app:7232020-07-16 07:29:30.220 pm info*** Rule 2 Ended
app:7232020-07-16 07:29:30.199 pm infoAction: Log: *** Rule 2 Ended
app:7232020-07-16 07:29:30.187 pm infoAction: END-REP
app:7232020-07-16 07:29:30.178 pm info*** Rule 2 Loop
app:7232020-07-16 07:29:30.164 pm infoAction: Log: *** Rule 2 Loop
app:7232020-07-16 07:29:30.110 pm infoRule 2: Repeating Actions 1 time
app:7242020-07-16 07:29:20.925 pm info*** Rule 2 returned, Rule 1 ended
app:7242020-07-16 07:29:20.908 pm infoAction: Log: *** Rule 2 returned, Rule 1 ended
app:7232020-07-16 07:29:20.818 pm infoAction: END-REP (waiting for next)
app:7232020-07-16 07:29:20.792 pm info*** Rule 2 Loop
app:7232020-07-16 07:29:20.775 pm infoAction: Log: *** Rule 2 Loop
app:7232020-07-16 07:29:20.707 pm infoRule 2: Repeating Actions 2 times
app:7232020-07-16 07:29:20.645 pm info*** Rule 2 Started
app:7232020-07-16 07:29:20.640 pm infoAction: Log: *** Rule 2 Started
app:7232020-07-16 07:29:20.561 pm infoRule 2: Actions run by Rule 1
app:7242020-07-16 07:29:19.940 pm infoAction: Run Actions: Rule 2
app:7242020-07-16 07:29:19.495 pm info*** Rule 1 started calling Rule 2
app:7242020-07-16 07:29:19.489 pm infoAction: Log: *** Rule 1 started calling Rule 2
app:7232020-07-16 07:29:15.003 pm infoAction: END-REP (waiting for next)
app:7232020-07-16 07:29:14.965 pm info*** Rule 2 Loop
app:7232020-07-16 07:29:14.959 pm infoAction: Log: *** Rule 2 Loop
app:7232020-07-16 07:29:14.904 pm infoRule 2: Repeating Actions 2 times

Running another rule is not like calling a method, that does its thing and then "returns". What that does is start the other rule's actions, and then continues immediately.

So you'd expect to see Rule 1 do its three actions in quick succession. Rule 1 completes long before the second iteration of the repeat in Rule 2.

BTW, when posting logs, use a screenshot instead of copy/paste.

1 Like

I understand what you are saying, but if I remove the loop, it works as I would expect. Also what you are saying is that we can't count on rule 2 to complete before rule 1 continues, Is this correct?

I read other messages about this and there are comments about using "Run Rule Actions" to reduce the length of rules. If we can't count on how it returns control to the calling rule, we really can't use this feature to reduce the complexity of rules.

Thanks in advance,
Alan

It doesn't "return", as I said. More accurately, it is "launched", and the rule that launched it continues with other tasks. The hub is multi-threaded. That means that multiple things are happening at the same time. With respect to the relative timing between things going on simultaneously, you can't make any assumptions, it is non-deterministic in that sense.

But, that doesn't me that you can't use multiple rules and call actions in one rule from another. If you wanted to get the effect of something in a second rule completing before the "calling" rule continued, this could be communicated between the two rules with a global variable, or with Private Boolean, and possibly a Wait for Condition in the calling rule.

Another way to use a second rule to be run, is for it to be something that multiple rules might all use, might all want to do. This avoids putting that same logic in several rules, and allows adjustments to be made in one place instead of several. And whatever it does would ideally have no timing or sequence relationship with the rules that use it. For example, you could have a rule that turns off a set of lights, closes a shade, and checks for open doors. That might be used by any number of separate rules, all of which have reason to take that set of actions. Those rules wouldn't care about the timing of those actions, they just want them to be done. They aren't waiting for it to be done: Rule 2, please take care of these things.

Another use for a second rule is for something that you want to explicitly control the "triggering" of. Instead of that rule having a trigger, it is only invoked by another rule. An example would be a Goodbye rule, that does certain things only after everyone has left -- perhaps notify if a garage door was left open. You wouldn't want that to run every time a garage door is open, only in the specific circumstance that everyone has just left, and only once. This sort of problem can sometimes also be solved using a Wait. Often, there are multiple ways to get things done.

Thank you for the explanation. I like the use of the wait for condition to enable what I want to do. Should have thought of that!

Alan

I'm new to HE and the Rule Machine.
I'm writing a rule to turn on lights and notify me there was motion detected when a motion sensor on my screen room is activated between sunset and sunrise only if the screen door is closed. Got that part to work ok BUT I'd like to have the rule NOT trigger if the screen door has been opened and closed within the past x amount of time.
I'm thinking I might have to have the contact sensor set a global variable every time the door opened. How can I compare that variable with the time NOW in the rule? Thanks for any help

First, welcome. RM is daunting the first time you open it up.

You canā€™t have a rule ā€œnot triggerā€ if the screen door has not opened within a past period of time. The rule will trigger whenever a selected event (e.g., door contact sensor open/close) occurs. You can have multiple triggers.

Hereā€™s one way to do it, using two rules and a Global Variable. You were on the right track, though. The reason to do it this way is to capture the ā€œDoor Openedā€ event.

First, define a Global Variable, doorOpenedTime, a decimal.

Then create the following simple rule:

Then, in your existing rule, define two Local Variables, triggerTime and elapsedTime, both decimal.

Then, insert the actions of the following rule at the start of your rule. I used a constant of 5 seconds for the certain time, change as desired.

That should do it, unless I misunderstood your problem statement.

1 Like

Thanks. I see how you are using the variables and rules to set them which should help me with future rules. This looks like what you wrote should do the trick. I'll play with it and see. Thanks for you guidance.

1 Like

You are welcome. You may want to look at my similar rule to reset the Litter Robot if the litter drawer has been open for 30 seconds.

I didnā€™t use WAIT or similar for your rule because your problem statement said you wanted not to enter (trigger) the rule unless the door had been opened more than a certain time ago and was now closed, but the Litter Robot rule is a variant where you stay in the rule while the drawer is open.

Again, thanks for the help. I think I have this set up correctly. The only thing I wanted to add was this should only activate between sunset and sunrise, at least until I setup my modes and have this only work at night or in away mode.
Here is what I came up with. I think I'm supposed to have another End-If statement in there before "On: Screen Room" to close out the first If statement (sunset to sunrise) but I don't know how to add that.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.