RM Efficiency

I am in a middle of cleaning my rules in RM
My goals are to create most efficient but easy to maintain codes (rules).
Here is example of one of my rule in RM (Window Shade Control):

The above code has multiple Trigger Events and as a result relatively
complex IF-THEN-ELSE action decoder.
But this way a single rule coves multiple events and condition.

Another way will be to use a single Trigger Event per rule.
The above example will be split into 3 individual rules.
This way the action decoder(s) will be very simple.
It may not need even a single IF Statement, just list of actions.
However with this approach many physically independent but logically
tied together rules will be needed.
Since there is no way to combine set of related rules under
one hierarchical entity (say folder or whatever else, something like
Rooms) the readability and maintainability will be significantly impacted.

So, my main question is:
Which way is more efficient (one rule with multiple triggers or
single trigger per one rule)?

My preference will be efficiency.
I guess, I will be able to maintain some sort of hierarchy.

I would like to hear professional response (Bruce Ravenel)
before I will go too far with RM modifications.

What I learned, the most efficient way will be to write a
custom application for each specific case.
Maybe in a future, but I am not yet there.

It may be helpful to first explain what you want the rule to do. I have an idea from what you wrote, of course, but I suspect that what you wrote isn't exactly what you want (more on that later). Because it appears you basically want to do three different things in response to three different triggers, I would write three separate rules.

The total number of apps/rules should have minimal impact, especially if they all have different triggers (it's probably best to make each app subscribe to the minimum number of events it really needs and for each device event to be in use by the minimum number of apps, but in regular usage I still can't see this making too big of a difference either way). With Rule Machine, Bruce's recommendation is generally that smaller rules (multiple rules if necessary) are better than one large rule. As a benefit to you, they are also generally easier to edit and "debug."

In your case, perhaps you want something like:

Rule 1

Trigger: When time is sunset-20 minutes

Actions to run:

IF (Lr Curtains Auto/Manual is on) THEN
  On: Lr window Shade Switch
  open() on Lr Window Shade Control
END-IF

Rule 2

Trigger: When time is 1:30 PM

Actions to run:

IF (Lr Curtains Auto/Manual is on) THEN
  Off: Lr window Shade Switch
  close() on Lr Window Shade Control
END-IF

Rule 3

Trigger: Lr Window Shade Switch turns *changed*

Actions to run:

IF (Lr Window Shade Switch is on) THEN
  close() on Lr Window Shade Control
ELSE
  open() on Lr Window Shade Control
END-IF

If you're super-concerned about efficiency, you may consider re-writing that third rule as:

Trigger: Lr Window Shade Switch turns on

Actions to run:

close() on Lr Window Shade Control
Wait for event: Lr Window Shade Switch turns off
open() on Lr Window Shade control

(This is another difference that's unlikely to matter in real-world usage, but it's theoretically more efficient: in the original rule, you're triggering on change, then checking the current state. In the latter, you trigger on the specific event that causes that state, so you don't need to check--the trigger is enough. The "Wait" creates a subscription to the other event (switch = off) only when needed. It's also probably easier to write.)

Back to these three rules as a whole: together, they may look similar to what you wrote above, and I suspect it's what you want, but it's not exactly identical. First, with the original/big rule, if the "Lr Window Shade Switch" switch state changes and it happens to be 1:30 PM or sunset-20, that first set of actions will execute, not just your last IF. (I'm assuming you only want the last IF block to execute, though I suppose this is unlikely to matter in real life since it's likely the time-based blocks would have just run and already be in the desired states.) Similarly, when the time is 1:30 PM or sunset-20, one of the IFs inside your first IF will execute, but so will your last IF, the IF (Lr Window Shade Switch is off) THEN (or its ELSE).

Splitting the rule out into three like this solves all of these problems (and avoids you needing to so much work in the actions to figure out why the rule triggered). Each rule is also small and clear in purpose. I do understand that you may prefer everything to be under one "roof" to keep things more organized, but as you know, the UI does not provide any way to group rules manually. Since app names are sorted alphabetically by default, I would consider naming your rules in some sort of pattern as a workaround for this.

You could, of course, also write a custom app for this. From what you've written in other threads, I really think you would be happier that way in the long term. If you have an idea of what you want the app to do--maybe something like this rule?--I'm sure someone here (I'm kind of volunteering myself, but I'm sure there are others) could help you get started. But I don't think what you're doing is stretching the limits of Rule Machine at all (I've seen far worse :slight_smile: ) and wouldn't say that learning how to write an app is necessarily something you need to do just for this.

1 Like

What I am trying - is to create the most efficient rule(s) in the most maintainable
and organized way. These two requirements currently contradictive.
I know very well how to create a blocking or non-blocking logic.
IF-THEN-ELS IF ... THEN ... END IF is blocking logic. Only first true condition will
be executed. Replacing the above sequence with set of independent IF-THEN-END IF
statements will evaluate and execute every true condition. So, creating any kind of
logic is not a problem. BTW, for creating logic I don't have any problem at all.

My main question was about efficiency.
I assumed, single Trigger per one rule is the best approach for the efficiency.
However this approach is messy enough for maintainability and readability.
As you may notice I already using very structural names for Devices and Rules
(hierarchical prefixing). This way everything is very well sorted and naturally
grouped. The downside is - names are very long. I am trying to truncate names
downto minimal number of characters but still keep them readable and informative.
Sometime I have to rename Devices and Rules because first naming attempt was
not good enough.

Bottom line is;

  • Keeping small individual rules with single trigger is preferable for efficiency;
  • Good naming convention helps a lot for readability and maintainability;
  • Learning how to write custom applications and/or drivers is the best approach;

Of course, I may miss something else.

I don't disagree with any of your "bottom line" conclusions--they all seem like good ideas to me. I will say that I don't think you need to worry about a "single trigger" too much. If your rule needs multiple triggers to do what you need, then that's the way it is, but in your case, it seems like you were doing different things based on different triggers, so splitting them into individual rules with single triggers makes more sense. And again, I wouldn't say learning Groovy is best in general, but it sounds like you have the skills to handle it, so based on that plus what you have said in the past, it may be a good idea for you.

My point with mentioning the conditionals was not to doubt your knowledge (FWIW, I have a degree in computer science and you don't need to explain it to me, either :slight_smile: ). I just wanted to make sure you were aware that you do have two independent IF THEN blocks in your original rule, and it seems unlikely that you would want something from both to possibly run as a result of a single trigger--which, as I mentioned, is a possibility. Since we only have the rule and not an explanation of what you want it to do, this was just a guess on my part.

Good luck with whatever option you choose!

Apparently my example and a followed question was not clearly formulated.
Yes, some rules definitely will need multiple triggers.
I was trying to understand what impact on efficiency (if any at all) will be
if I put more than one naturally independent rules in one rule.
The reason for this move is nothing more than keeping together logically
(not physically) related rules. It looks like current platform is not design/capable
for maintaining hierarchy for rules. The partial solution is - very good naming
convention.

I see. I would recommend against this, and from what I can tell, Bruce normally does too. Part of this is just because it's likely easier for you, not more efficient for the platform (shorter rules are easier to manage and understand--especially when you come back a month later). However, in most cases, it's also more efficient from a platform perspective, though I'm not saying this difference would actually matter in real life.

Consider this rule:

Trigger: Time is X OR Time is Y

Actions:

IF (Time is X) THEN
  Do A
ELSE-IF (Time is Y) THEN
  Do B
END-IF

Here, you're triggering on an event (or two), then checking a condition in the actions. But if you did it like this with two rules instead:

Trigger: Time is X

Actions:

Do A

and

Trigger: Time is Y

Actions:

Do B

... then you eliminate the need to check a state, as the rule only fires when an event that would have caused that state happens. Everything else is the same, and skipping this step saves you that computation. This is a similar reason to why my second example for "Rule 3" above could be considered more efficient than the original, although in that case there are further gains due to the ability to simply the trigger also.

But again, for real-world use cases, I can't imagine any of this matters that much.

Well, if every rule will take a bit longer eventually this "a bit longer"
may/will accumulate and easily could become a big obstacle.
One rain drop is not a big deal but many rain drops could be a disaster.
That is why efficiency is my highest priority and readability and
maintainability are next on the list.