I’ve got an HA system with 80-100 automations. About 10% of them are ‘headless’ – i.e., they have no trigger per se, but are run by pressing buttons which use the service automation.trigger to execute the routine. (I use custom:button-card in most cases, if that matters in this discussion.) Everything works fine.
I’ve read a ton of online discussions, and most of them end with something like, “If you have an automation that doesn’t require a trigger, you should use a script.” My question is, why??? It’s convenient to put all the routines for say, my bedroom remote card, in one place; rather than having to remember, “Oh right, that’s not an automation, that’s a script. No wonder I can’t find it!”
Other than arguments that boil down to ‘that’s what it’s intended for,’ I can’t find much discussion of why a headless automation driven by call-service is a bad thing. I’ve read that it “doesn’t work” or “causes errors,” but I’m not seeing this in the Q2/2025 version of HA. I know that a script can be stopped, and an automation cannot, but I’ve yet to create a function that needs this feature. So, are there performance or stability reasons to not create an automation without a trigger? Is there a problem when nesting functions?
Apart from the stop thing, scripts can take parameters and since they have no triggers they don’t listen for events so that’s a small overhead removed. Their main advantage as far as I can see is that they can be called by other automations and scripts and run in the background if you want them to - I’m a fan of modularity.
I’m working on a project where I’m basically using scripts for everything and automation only as event trigger handlers for. A very specific reason. But in doing so I cut those things into about six different methods of this goes there.
And for all of them I pretty much came to… Do what works. Keep consistent.
That is a hidden trigger. The nice way would be that this is an automation, using the event from the button as the trigger. If it were an automation reacting to an event, you could tell by reading the automation that this is when it runs.
You are not breaking things by calling the action from outside. But then again, automations require a trigger, which you are not using. When reading the automation it will not be clear if something other than the triggers could be starting it. It will also not be clear if the conditions are checked when actions run.
What will go wrong though is if the actions use trigger variables. They won’t be set. When reading the automation, it also will not be obvious that there are outside things that invoke the actions without the triggers being the cause. So it is more confusing than it is wrong. Many users on this forum ask questions about automations not working right when in the end the only problem is that they ran it by hand.
Scripts can be exposed to Google assistant to call by voice, automations can not. Automations can be turned off, scripts can not. I would not know what happens when you ask to execute an automation that is turned off.
I prefer to have complex behaviors as a script, and let automations call the script. That way I can have multiple automations do the same thing. I can turn off an automation, and still use the script in other ways.
I am not a developer, so I cannot say why it happens… but there are regular posts on these forums where users create an automation without a trigger, they complain that it does not work reliably, and these complaints disappear when they use a script instead.
There may be alternative solutions such as adding a trigger that will never fire… just so the automation is properly configured and doesn’t fail silently. But, since it’s not an issue that is reliably reproducible and there is an existing fix that seems to have 100% solution rate, I haven’t bothered trying to test it.
Thanks to everyone for their comments. Part of my issue is that I’m far from an ‘HA expert’ – and I have little desire to become one, other than over time. I just want a system that unifies my Z-Wave and WiFi pieces together; turns on my lights and HVAC in the background; and integrates my AV components into a pair of cohesive TV/audio remotes. HA has a lot of little quirks about indentation, use of quotation marks, function syntax, etc. that take enough of my time to understand and debug. In the future, I will probably use scripts. I’m just trying to figure if the set of automations that I have – which seem to work well – need to be scrapped to ‘do it right’ using scripts for some of them.
@jackjourneyman Yeah, I like modularity, too. But I haven’t found a lot of reusable functions to date in my specific code.
@NathanCu I have been a programmer for almost 60 years now, and I do try to be consistent. When programming, I like the flexibility to find a style that works for my brain, and then stick with it, documenting everything I do. I stumbled across examples using automations when I started, so there it is.
@Didgeridrew FWIW, I have yet to have any evidence that my triggerless automations failed. One thing that might be helping is that I tend to make automations that are fully self-contained, with limited use of outside helpers. So, I may not be depending on the automation being initialized properly. But I will watch out for reliability issues.
I would love to know why someone decided that this service [automation.trigger] was needed. All it achieves is “Hey look! I can dumb down an automation into a script!”
I get where you are coming from. But, as HA has evolved from a programmers’ domain to more of an everyman product, having multiple ways to accomplish the same thing aren’t necessarily a bad thing. I could make a similar case for C/C++ supporting if-then-else when there was already the switch command (case statements). Some people can get their head around case statements and jump tables; others prefer a ladder of if this/else this/else that/etc. Both accomplish the same thing. A triggerless automation explicitly called by another routine didn’t strike me as all that odd. YMMV.
You’re literally not using the automation’s core strength, the ability to independently monitor events and act on them.
Your reason appears to be because you find it simpler to only use automations to avoid having to recall what the button references (automation or script). If so, then certainly proceed with what makes it easier for you. However, should you ever need to pass variables, you will need to use a script and then you’ll have to forego your self-imposed “automations only” rule.
FWIW, for your stated application, I normally recommend using a script. The button’s syntax for calling the script is more concise and a script has the potential for accepting variables from the button.
Your reason appears to be because you find it simpler to only use automations to avoid having to recall what the button references (automation or script).
That’s only part of the decision. I was trying to explain how I got to where I am, not necessarily touting it as a better way. The bigger reason is that I already have working automations for the items: if I convert them to scripts, I will have to ‘fix something that isn’t broken,’ and maybe spend cycles debugging bad syntax, differences in operation, etc. Over time, I will likely migrate to scripts – especially if my approach proves to have errors – but I was trying to see if there was something crucial I was missing. So far, the reasons for scripts (and against triggerless automations) haven’t put me in that situation.
FTR, I am using automations for their core purpose and strength in my HVAC routines, and a few of the lighting ones. Just not in the TV remotes.
Could it be because the run actions button in the GUI automation editor?
That is this service call, and I would assume the reasoning to make it a service call is to make sure it follows some guidelines that buttons should have service calls underneath them?
To me that makes sense, but the service call does not.
Except if the above is true.