Best practices for (more complex) rules?

I checked the forum for "best practices" posts, but most were fairly old or quite "specific".

As general background I can "code", so I understand all the underlying concepts in the Rule Machine (though I am new to Hubitat). I also understand the difference(s) between Events, Conditions etc. What I do not know is how the Hubitat Rule Machine functions "internally" and how it interfaces with drivers (and driver states and variables), and if and how different hierarchical/nesting structures might be affected by "best practices" (or not).

An example, to illustrate:

  1. A greenhouse has additional grow lights to compensate for "not sunny" conditions.
  2. In order to not affect the plants negatively, the "total daylight time" should not exceed a certain amount of time, which is basically a simple daily on-off timer.
  3. Grow lights are expensive, and should not be repeatedly turned on/off just because clouds sail by (covering the sun for a few minutes).
  4. In order to avoid "too much light", condition 3 should "err on the side of caution" (avoid "doubling" the amount of light, even for a shorter time).
  5. The daily timer needs to be manually set through-out the season, but the rest of the "system" should be "always automated" and "always on" (when the grow lights are set to be "on").
  6. The grow lights can also be turned on/off manually.

Hardware-wise all that is needed is a simple (light) switch (also connected to a manual button), an illuminance metering device and Hubitat's Rule Machine (C-8). Logically it is not all that complex, but at first glance the functionality can be accomplished in several different ways. The question is if there is a "best practice" how to hierarchically nest the above conditions and/or how to split them between different rules (linked by variables and/or switch/illuminance meter condition)?

"Best practice" is (in my world :slightly_smiling_face:) defined as logically functional, less complex, less taxing (on the system) and less prone to error (for instance from devices not updating their condition "in a timely manner"). If this was VBA, Python or some other "code", I could have the snippet up and running (and tested) in a few leisurely hours, but is there a "best way" to do it when using the Rule Machine? And if so, what is that "best practice"?

If the question above is too broad, then a bit more specific:
Since the Rule Machine is event driven, my logical (?) solution (as a Hubitat noob) would be to add all the involved events (timer on/off, manual on/off, "no sunlight/sunlight is back") as separate rules and have them communicate/interface with each other using a set of global variables ("states"/conditions and event time/timers). Because such a "de-structured nesting" intuitively feels more "robust". However, having read the Rule Machine manual (and a lot of comments) it seems the Rule Machine and the Hubitat OS is inherently built to explicitly handle some of those functions, and it might actually be a "better practice" to utilize it's inherent nesting to full extent.

I have about half of my hardware (quite a lot too :blush:) installed with functional drivers (though a lot of them are "generic Zigbee") and it is time to start "the automation", so the main goal of this fairly long question is getting that (most important) part off to the best possible start (and trial and error is NOT the answer... :grinning:).

Have you looked at Groovy and custom apps? It sounds like you might be more comfortable coding instead of using the RM interface.

1 Like

i see this as 2 different rules. 1 for the daily timer (regardless of sun), and the other to have it turn on conditionally.

first rule is straight forward, at X time turn on lights, at Y time turn off lights

for the second rule, that's where things may get a bit tricky. in my environment, i currently have a rule that gets triggered by something. then i wait some time, then check for that same trigger. if it's true, it does my task. if it changes, to where the initial trigger is no longer valid, i have it cancel the rule so it won't risk running multiple times. you could look to implement something like this with the light sensor. if the light sensor goes dim, and stays that way for X time, then turn on the grow lights. if the lights shouldn't be turned on/off within say 10 minutes, you could use a boolean (or some other variable) to signify the cooldown of the on/off cycle, and bypass the actions while that variable is set (used to use something like this when i first automated my blinds to prevent conflicting commands)

the thing with playing in someone else's rule machine is you may not always get "best practice", and may have to settle for best effort. there is definitely nothing stopping someone from writing an app/driver to satisfy their needs, but that takes time and knowledge. rule machine helps fill the knowledge gap for me to do what i need, just takes the time to fine tune and implement it. good thing with rule machine, you can use other devices (virtual switches or other lights) for testing before you push it "live" to the grow lights to help mitigate damaging them

Thanks, but I have no problem with RM or it's interface, and I can "see" several ways to achieve what I want to do. So I am just interested in doing stuff "the right way" off the bat, on the level of "is a myriad simple rules better than a few very complex ones" or "is it better to bounce functionality against global variables than using 'built-in' wait states/conditions" etc.

So: "best practice" :slightly_smiling_face:

There might not be one, or rather the differences in approach might be so small that they are insignificant and meaningless, from a practical point of view. I am trying to avoid the situation where I somewhere down the road find out that "I should have done everything this way instead".

Unfortunately I don't have the time to write code (or drivers), as fun as that is (when you get it to work).

One of the reasons I am asking about best practices is that I "see" (or "feel" :grin:) that my "automation environment" needs another level of "states" (or conditions, if you will), to bounce the rules against. Like "someone is currently home" (or no-one is), "the sun is shining" (or it isn't), "it hasn't rained since X", "window(s) are open" (or not), "there is a fire in the fireplace" (or there isn't), "everyone is sleeping" (or "someone is awake" and/or "someone is still sleeping").

I can set the value of these global variables using built-in global variables (like "time", "sunrise") in combination with triggered events ("movement", "light") and some logic ( :crazy_face:) and then bounce other events against them ("if someone is home", "is the sun shining" etc.). It might be a background in coding, databases and IT in general, but this feels like a better design than running everything from (and within) singular events. On the other hand, RM and Hubitat are designed to handle such events (and does it very well, much better than a lot of too simplified solutions out there).

It is almost a philosophical question: is your home defined first and foremost by it's current "states", or is it defined by events triggering. When you start automating your home, you start with an "event". But then you add more and more (and more) events, and at some indeterminate point the mass of events becomes a reflection of how your home is functioning (or meant to function), but at the same time they are isolated from/not connected to each other.

I can feel this getting a bit obscure, but from experience I also know that this could be quite relevant (or not).

Another example: you work from home (the day in question) and walk through several rooms to get to your bathroom with home automation active in every room. If you use an event-driven automation environment, every single rule in every room will have to evaluate that someone is home (and moving around) and what to do within its own logical setting. If you use a "global state"-driven environment instead you would have the state "someone is home" set to [true] (maybe even "someone is working from home", with a presence sensor), set "someone is sleeping" to [false] and then all the events triggering along the way to the bathroom would bounce their actions against these global variables.

I am new to Hubitat but have some system (and software) design experience, and to me the second "global state"-driven design seems better. Partly because of the logical hierarchical design, where events are "slaved" to "global states" instead of having to think for themselves. And partly from a service/upkeep viewpoint, you can fix and change some parts of your system at the global level once, instead of having to "re-code" tens or hundreds of rules. But, again, Hubitat is geared for handling the events, as home automation is (atm, at least) quite "event focused".

So there might be some advantage/disadvantage to a design that kind of re-designs how the whole system should work. Or not. :slightly_smiling_face: Reading a lot of posts on the forum (I went through hundreds before deciding on Hubitat) I feel quite at home, as there are quite a few very knowledgeable Hubitat-/home automation nerds. And someone might know either that one "automated home"-design is better than another on Hubitat (and why), or that it makes no practical difference whichever way you go. It's not just about getting it to work and how, it also has to do with how Hubitat has changed and changes/evolves over time, under the hood.

And that is why I am asking.

Currently the only long-term problem my noob-Hubitat eyes can see is the overall reliance on user-made drivers, with nothing in-between "totally home-cooked" and "officially compatible" (on the compatibility list). If home automation (and Zigbee/Z-wave) continues to grow, the potential inherent problem will grow exponentially. As an enduser you really, really need to know if some hardware you buy (with real money) will work or not, and the answer "there might be a driver someone has made that you can download" is just not good enough (for a lot of potential users). There needs to be some sort of "beta-certing" system or equivalent, which gives a user access to a "semi-certed" functioning driver with one mouse-click (or even without). The core vision of Hubitat is "max control made easy", and an enduser sitting there with a Zigbee/Z-wave thingy that he/she just bought and realising A) that it isn't working, and B) that they have to write or find "a driver" to make it work is a lethal blow to that core concept. That you can find and incorporate such drivers fairly easily if you have a semi-nerd understanding of how everything works is just not enough. But that is another topic...

1 Like

I totally agree with this paragraph, and I've said the same thing in the past.

I contend this is exactly what scares off the lucrative market of home-automation noobs -- from their perspective, Hubitat's real-world dependency on community development looks an awful lot like Home Assistant's intimidating uphill climb.

Faced with having to dive in the deep end one way or another, why not just grit their teeth and go with Home Assistant to ultimately enjoy the wider compatibility it offers?

I don't know how to solve this, but I do think it's a real threat to Hubitat's potential to make bigger headway with that market in particular.

with RM5, i'd say both as the rule will trigger with the event trigger, but there are required expressions used to filter based on conditions

this is where my comment about the variable/boolean comes in as you can use that as a required expression to control the rule triggering

we're not looking for optimal big o notation, but efficient enough to achieve our goal :). i've always gone into it with the mindset of "how can i achieve my expected outcome", then after "how can i optimize it". i've had rules be 50 lines to start, then able to cut it down to like 26

A best practice that is often discussed is the KISS principle in RM. Rule are frees so the number doesn’t matter. Sometimes making really long complicated RMs can get a little convoluted and difficult to debug. Some of my larger automations have many individual RMs almost like functions.

Yes the use of global variables to enable or pass data between RMs.

Re: states or events. Yes to both. I have a time of day state (actually I use MODE for this and set it according to a lux sensor) and a presence state. These are referenced in many rules.

I also have a “bright day” state that is only active during, well in day MODE. Like one of your concerns, when first implement it, I had toggling lights happening every five minutes. Averaging my lux reading and modifying the threshold for a period of time after toggling settled things down.

That’s also the base of RM. only one trigger event occurs and the action typically depends on the state of other things.

Oh. Welcome to the community.

"Oh. Welcome to the community."

Thanks, I do feel completely at home. We are probably all a little nuts, but in a (very) good way. :crazy_face:

One could wonder what some arriving aliens might think about "the best and the brightest" focusing their efforts on "automating their homes", considering everything else that goes on, planetwise... :smiley:


And thanks to everyone for the quick answers. I got what I needed, some affirmation that I am not thinking about "RM automation" the completely wrong way.

2 Likes