Home Assistant light automations

After a brief discussion in the HA-forums earlier this summer I decided to write up some more details about my take on automations in Home Assistant. I have been through many incarnations of the “lights on, lights off”-automations, and I guess these are what quite a lot of people begin with when they start thinking of home automaton. I don’t say that this is the perfect way, or that everyone should follow this approach, or that is is very unique, but I do think it is slightly different from what most people do, so it can at least maybe give you some ideas.

First of all, I have had some very, very complex automations. As described in earlier posts, after things work for a while, you realize that even the most trivial automations can have corner cases and room for improvements. Over time this grows to unmaintanable beasts of conditions and states you need to track. So after I gave up trying to figure out why a certain light did not behave as I expected, I decided to take a step back and try to build something that was much more maintainable and easy to debug. I try to follow “the unix philosophy”, and let all my automations do one thing, and to that thing well.

Some background

In all our rooms we have at least one motion sensor, and every light in the appartment is controlled by a physical “smart” switch or dimmer (Fibaro zwave), which I can operate from Home Assistant. That way al lights can be turned on and off both by the physical switch, and by HA. My goal is to “never” have to use the physical switches. They should only be used as “backup” in case an automation does not work correctly, or in situations that was impossible to predict, so no automation is written for it (yet). Lately, we have been pretty close to this goal. These days we usually only use one physical switch when we go to bed and another when we leave the house. I prefer to just push a button rather than some kind of voice-controlled “Hey Google, good night”, but that is just my choice.
If we don’t push the button, device trackers and motion sensors will still detect that it is night or that everyone is out anyway, but it takes a bit more time before those trigger.


Ok, so back to the automations. At the heart of every light automation, I have a couple of inputs.

Some input_numbers for brightness of the lights (one for each light)

And some input_datetimes to set the delay before the light is turned off again after the motion sensor has been turned off. Here I use one for each light — or room, depending a bit on the room. In some rooms I want individual timers for each lamp. In other rooms, I want the whole room to go dark.

This allows me to easily adjust the brightness and timeouts both from Lovelace and from automations.

Then I have four extremely simple automations for each light/room.

Two “trigger”-automations:

As you can see, the two automations does not do anything but send an event. And they do so unconditionally when motion is detected. The “motion off” automation uses the mentioned “input_datetime” in the trigger to decide when to fire. If I have more than one sensor in a room, I set up both sensors to send two events:

I could use a group, but I might want to know which one was triggered, so I just let them both send the same event “motion_on_kitchen”, and their own indiviual event.

For “motion off” I use a group because I want both sensors to be off before sending the off-event.

Again, I could use single automations for each sensor, and have the other one as a condition, but I want to avoid using conditions as much as possible.

Then I have two “hub”-automations that decides which lights are controlled by which sensors:

So the two “action” automations are listening for the events from the different “trigger” automations, and will just send another event, including the light they want to turn on or off.

Agian, there are no conditions. If one of the events are received, the automation will run and the event will be sent.

I also listen for a few more events than the “motion_on” and “motion_off”, so other automations can send other events. That make it easier to see what actually triggered the automaton to run, and to be able to easily add and change “trigger” automations without having to modify the “action” automations.

And finally, I have the actual “lights on” and “lights off” automations.

I only validate that the light is off (or on with a different brightness than the one I want) before turning it on, and that is it on before I turn it off. The conditions are not strictly neccesary, they just keep the logs a bit tidier, and you can add e.g. a “notify” or “system_log” as an action to do some debugging etc. without getting flooded with notifications each time the motion sensor is triggered if the lights are already on. The brightness for each light is read from the “input_number” described earlier.

So far, so good. For now this only seems like a few extra steps to get to the action, going through all that “event” sending instead of simply adding all the triggers to the “on” and “off” automations themselves. Someone once said “when in doubt, you can always add another layer of abstraction”, and this looks a bit like that…

But what I realized, was that I sometimes wanted other stuff to be triggered by the same motion sensors. And sometimes I wanted to turn the lights on and off from other automations, but I wanted consistency and easy logging, so my goal was really to have one and only one automation being triggered by any sensor. And have one and only one place to type in the entity_ids for the lights. And have one and only one automation actually turning lights on or off.

Now, that we are about to move to the new OpenZwave-stack I am very happy about that, as there is just very few places I would have to do changes to make all the automations work again, even with new entity_ids all over the place.


So how do I add conditions int this mix? I simply have some “meta” automations, that modifies the input_number and input_datetime, and also some that will enable and disable the “lights_on” and “lights_off” automations.

Pause and unpause automations

Again, these could easily be merged into one automation, but why make it complex by adding a lot of conditions and “choose”, when it is just as easy to have a few very simple automations instead.

Set timer and dimmer level

One thing you will notice is that I use a variable called “light_source” quite extensively. Because I have been very consistent in the naming of inputs, entities, automations etc. it means I only need to specify this one name, and can deduce the names of the sensors, input and lights from that.

So now, any other automation can do a simple


Or if I want to adjust the dimmer level to 30% and set a timeout of 2 minutes for the toilet lights:

And then I have a lot of simple, easy to understand automations that will do stuff like “pause_auto_on” for the bedroom lights at night and “upause” it at a reasonabe time in the morning. I “pause_auto_off” the bathroom lights when we are showering (high humidity detected), and unpause it again when the humidity is going below a certain threshold. One automation lowers the dimmer_level in the toilet in the evening, and another increases it again in the morning. The off-timer in the kitchen is increased and decreased based on whether it is dinner time or not beacuse we usually don’t trigger the motion sensors while we are sitting down eating…


I also use a bunch of other inputs as variables in my automations, so I can modify them in one place if I want to adjust some parameters to the scripts.
Here is a snippet of an automation that runs in the morning to adjust some timers and brightness-values:

If I realize that the “delay_medium” is a bit short, I can change the variable once, and all automations that turns the lights off after that amount of time will be adjusted to the new timeout.


And at any time, I can very easily see the current status in Lovelace:

Lovelace view of the office lights
  • The lighs are turned on (and has been so for 4 hours)
  • The input_number.brightness is set to 75% (and it was set to this value a day ago)
  • There is a 30 minute timeout after motion is detected before the lights are turned off (and this timeout was changed 2 days ago)
  • The “Lights on”-automation was turned on two hours ago
  • The “Lights off”-automation was turned off just now

So this means that even after 30 minutes of “no motion” in the office, the lights will not be turned off (the automation for that is disabled). But if they are turned off (maybe with the physical switch), they will turn back on (with 75% brightness level) when motion is detected.

I can very quickly find out from the logs what enabled the “lights on” automation two hours ago and what disabled the “lights off” automation 52 seconds ago.

And I never have to go back and try to figure out what the value and state of a bunch of different sensors that together form a long an complex nested list of conditions when I want to find out why the light was turned on (or not) at any time.

If the “turn on”-automation is enabled, the lights will turn on when motion is detected. If I don’t want the lights to be turned on for some reason, something must disable the automation.

And the value of the variables are asy to adjust

Varibale for brightness and timeouts used throughout the automations

To make life even easier, I have a set of other “meta”-automations, so I can do stuff like

Which will set another “input_datetime” to the specified time, and when we reach that time, the automation is enabled again.

Reenable time

So the auto_off on the bathroom is currently disabled, but will be reenabled automatically later.

All in all, this makes all my automations pretty short and easy to follow, while I still have all the flexibility I need ensure that lights turn on and off when I want and as I want.

And it can of course easily be extended to also set light colors etc. and to create complete scenes by adding similar automatons for covers and blinds and anything else.

Noe over gjennomsnittlig interessert. Kjentmann i IP- og nettverksjungelen, og jobber i nLogic AS.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store