I bet most folks have a bunch of mostly identical automations with mostly copy-pasted code, and I wanna show you intermediate and super advanced ways of reducing your automations down to 1.
I don’t think my methods are the end-all-be-all, but they’re better than what most folks have.
Simplest on-off lights example
Many folks simply wanna turn on and off lights with a smart button whether it be in the wall or on a counter:
- Press up: Turn on lights.
- Press down: Turn off lights.
I simplified this, and yet, it’s still hard it is to scale up even this simple of an automation.
What many regular folks do (the “intended” way)
Most people do automations the “intended” way, even if it’s the worst way. I think they’re right to think this is the way to do it because Home Assistant hides the better ways of managing automations from you.
Example
You need one automation for each action and each type of thing you wanna do for each room.
Automation for “lights on”
- Trigger: Every button press type from every device you want to turn on the lights in a single room.
- Action: Turn on the lights in one room.
Automation for “lights off”
- Trigger: Every button press type from every device you want to turn off the lights in a single room.
- Action: Turn off the lights in one room.
Nearly Identical?
Yes, those two automations are nearly identical, and yet you need to make one for each action or set of actions you wanna make.
How does this scale up?
You can combine all your “on” button presses into a single automation:
But this doesn’t scale up because if you have 10 rooms and 4 types of actions for each room (on, off, dim up, dim down): 4 button actions and 10 rooms means 40 mostly copy-pasted automations.
Adding more complexity
If you wanna change the brightness level based on a condition like daytime or nighttime, then you need two “on” automations for each room with the Condition applied to each and a nearly identical action.
With 2 conditions: 1 button action with 2 conditions, 3 button actions with no conditions, 10 rooms: 80 mostly copy-pasted automations.
As you can see, this doesn’t scale very well.
Maintance is a nightmare
With all these mostly copy-pasted automations, you will eventually need to change something.
If you change it in one, you’ll probably wanna keep it the same for all other rooms. Doing so means you have to add a new automation or modify an existing one for each and every room. Good luck!
For me, I did some quick math, and I’d have well over 1000 automations minimum for the amount of rooms, conditions, light actions at each switch, and other triggers I’d need.
Advanced Home Assistant (welcome to my house)
I’m far into the deep end with the way I’ve configured automations. I want to do as little management and copy-paste as possible, so I rely on scripts, action blocks, loops, and events.
For each room, you should only have a single automation. To achieve this lofty goal, use Trigger IDs:
A Trigger ID is a piece of text you can use to change which actions get executed.
You can add it by clicking “Edit ID”:
“Condition” is never used
When you use Trigger IDs, your “Condition” area of the automation will almost always be unused. I don’t use it in any of my 75 automations. You need to replace it with “Choose”, “If-Then”, or other selectors.
Then you use the “Triggered By” condtion:
Using “Choose” (god power action block)
I use at least one “Choose” block in every automation. Choose blocks let you choose from multiple “Option” blocks based on a different Condition of your choosing.
Example: Based on this Trigger ID, execute the actions in this option:
You can also nest an “If-Then” or “Choose” block inside the Option block if you need to add even more Conditions:
Using Scripts for repeated actions
Scripts allow you to take chunks of the “Actions” in your Automations and reuse them in other automations.
I use Scripts for both simple and complex actions that I want to standardize. I even have one for turning off the lights that comes with the transition time baked in.
Fields are a thing
While not exposed by default (because apparently everyone wants to waste time copy-pasting for life), you can use “Fields” to customize your scripts:
Fields let you pass values to your script like the lights you wanna modify. This way, you can have single script to turn on lights and which lights it turns on depends on what you pass into the lights field (in my example).
Expert level: Triggered loops
I have quite a few scripts with loops to keep them running over time. They’re able to respond to triggers without having to add those triggers to each automation.
A couple views of Scripts I use with a loop (from Traces):
Every time you run it, that arrow icon on the left will bump up with the number of times it’s looped.
I also have a shut-off (that hand icon) which kills the script if another one starts with the same ID. This ensures there are never 2 scripts floating out there controlling the same sets of lights.
Looping Example
Instead of adding these triggers to every automation:
At 7am, change the lighting to daylight mode and at 8pm, make it nighttime mode.
I instead added them to the script using a “Wait for Trigger” action:
But that’s just the “wait” part, so it doesn’t stop the script when it finishes. You need to wrap the whole thing in a “Repeat Until” action, so it loops when the script finishes:
And because of our “Wait for Trigger”, the script only finishes when the trigger occurs. If you kill off the script some other way, then it also stops repeating.
Stop a looping Script
To stop a looping script, you need to use the “Stop” action:
As you can see, I added it after a condition I set.
Using a Manual Event Trigger or Action
One way to trigger a stop is to listen for a specific event with a “Wait for Trigger” like so:
I fire this event off using the “Manual Event Action” when starting my script to stop any existing runs:
They look identical, but one’s a trigger (waiting for the event), and the other is the action which sends out the event.
Conclusion
Hopefully, this guide helps you build better automations!
The way I’m using script loops is exactly the way I code in TypeScript with RxJS at home. Lots of async tasks that need cancellation and the ability to run in the background concurrently.
I’ve been coding like this for nearly a decade, so I’m glad I found a way to make Home Assistant build automations with the same process.
Sadly, Home Assistant is lacking many of the debugging tools I’m used to. If you click “Run” (without running the script or automation), it at least shows you how many are currently running, but it doesn’t give you any insight into what they’re doing or what state they’re in:




















