Hey all, I’m quite new to Home Assistant, just set it up yesterday. I’m trying to figure out how to structure my automations to reliably match desired behavior.
Example automation + problem
As an example, one simple automation is to turn on some lights a bit before sunset and turn them off at 11pm. This is straightforward to do with two automations, one that turns them on with the sun trigger, and another that turns them off with the time trigger. However, this solution has some imperfections that bug me:
- If there is a power outage or persistent network glitch, such time triggers can get skipped. This forum comment suggests that you would also need to have triggers for HA start - what a laborious pain! And it is very hard to tell if you got it right because these circumstances are hard to test.
- You need to keep the automations in sync - if I add a new light I need to remember to add it to both.
- There is no concise definition of how a given entity will behave, instead it is spread across the effects of all your automations that act on it. I read somewhere that one thing people like about node-red is that it makes it clear when there are cross-automation interactions.
- When initially configuring this light behavior, and it is in the time interval the light is on, it would be reassuring if the lights came on. Of course, they do not with the trigger-based scheme, as something has gotten lost in translating the desired behavior of “the lights are on between these two times”
Solution sketch
What I want to be able to write is simply:
switch.light_socket_1 = now_is_between('sunset - 00:30:00', '23:00:00')
The system would then ensure that the light’s state matches this. A simple way to do this might be to trigger frequently, say every minute, and run turn_on
or turn_off
.
Question: is it ok to spam off / on?
Are there any bad effects of spamming turn_on
/ turn_off
all the time, say every second? Do they always turn into commands sent to the device, or are they no-ops if the device’s state already matches?
Listening to the state_changed
event in developer tools seems to suggest that this might actually be ok to do, even though I have AppDaemon running a turn_on
every second.
Misc thoughts on Efficiency
For efficiency, we might look at approaches like in the popular React JS library, which is used for making applications for the browser. With React, components define what state they depend on, and when this changes, their rendering function gets run. After rendering, React cleverly figures out the minimum change needed in the browser to make it match the function’s output, leading to huge efficiency gains. My question above is related - I’m essentially wondering if HA implements this sort of optimization.
If it is ok to spam turn_on
/ turn_off
and similar state change actions, then I’m not sure if it matters if I poll every second and run all the logic. The logic for my house’s automations should be able to run in a few milliseconds.
Inspiration for nice ways to write efficient declarative behaviors for devices might also be taken from various FRP (functional reactive programming) libraries like reflex-frp.
Manual override
I can think of one thing this paradigm does not handle so gracefully - manual override from the dashboard / cellphone. A literal implementation of “The system would then ensure that the light’s state matches” such as the polling described above would immediately switch the light back after it is manually set by some other system.
One approach might be to ask the user for a time interval to apply the override.
Another approach might be to store the original value at the time of the override. Once the behavior computes a different value than this old value, the override is cleared.
I see from this discussion (https://community.home-assistant.io/t/person-entity-how-to-use-user-id/324935/2
) that it is possible to use the user_id
from the context
to check if the originator of a state or event is a human user. So, I think it should be feasible to implement this override semantics.
Question: Does a solution to this already exist?
Generally curious if this post makes you think “oh that reminds me of X”.
If a solution to this doesn’t exist I might try to make one. Probably just a few functions in AppDaemon.
End
I realize this is a weird and long first post. A bit of sweet and salty to end it:
Salty: I think lack of alternatives to the trigger paradigm is leading to lots of mostly-working automations which are tricky to maintain, and this problem extends far beyond Home Assistant.
Sweet: Overall I’ve been impressed by Home Assistant, it seems really awesome!
I hope some of you found this interesting! I’m curious to hear y’alls thoughts.