Using Automation: Trigger literally (trigger, don't wait for it to execute/complete)

I’m having a lot of trouble fighting with the logic spaghetti of trying to parallelize triggers of automations (subroutines, as I’m using them), when triggered.

Originally, I read “automation.trigger” as being exactly that: it’ll trigger the automation and carry on the rest of the actions (no longer caring about what the triggered automation is doing), effectively parallelizing the tasks. Instead, I found it ends up waiting for the triggered automation to fully complete, before continuing on the original path.

This is bad. Really bad. There’s really no instance where I would use “automation.trigger” and would want it to “block” until it returns. If I did, I’d wait for a condition for the automation to be completed! Instead, I’m left creating spaghetti logic blocks - like grouping following tasks into a parallel/series group in order to bypass the “blocking” nature of an “automation.trigger” call.

The main reason being: one of my automation subroutines is to switch off a device, wait for it to cool (for 10 minutes), then switch it on/off rapidly in order to jostle it to turn its fan off (it’s an inverter). So, I would like it to function in place of a “device: turn off” call, but instead, I have to do logical gymnastics to get the rest of my script to proceed.

Example - I can’t do this because it skips the cooldown by toggling the outlet directly:
(“Sorry, new users can only insert one embedded media item per post” - welp, sorry guys, no screenshot for you)

So I have to do this:

I imagine the answer is “there’s no good way to do that today”, but I’m just throwing my voice in there in support of a way to tweak this behavior (trigger an automation without blocking). If there is a way to do that, I’d love to use it! :grin:

Depending on how you call a script, its behavior can be blocking or non-blocking. See: Waiting for script to complete.

Blocking:

- service: script.foo

Non-blocking:

- service: script.turn_on
  target:
    entity_id: script.foo

Restructure your application to take advantage of this feature.


NOTE

Try to avoid using an automation like if it were a script (that’s what you are effectively doing when you execute an automation using automation.trigger).

1 Like

What’s the difference between a script and an automation? From what I see there, “script.turn_on” ought to simply enable (but not trigger) the automation.

Maybe I need to restructure everything to use scripts, instead of automations… :no_mouth:

If I did that, would “script.turn_on” activate the script asynchronously, as I hoped? If so, it’ll definitely be worth digging in and re-tooling the whole routine.

In a nutshell, a script is merely a sequence of actions (that you choose when to execute) whereas an automation listens for a desired event to happen and then it executes its sequence of actions.

Script: Make breakfast consisting of pancakes and coffee.
Automation: At 08:00 on Saturday make breakfast consisting of pancakes and coffee.

Yes, an automation can call a script so it can be: At 08:00 on Saturday run the breakfast script.

Automation Basics
Script Syntax

From what I see there, “script.turn_on” ought to simply enable (but not trigger) the automation.

That service call will execute the specified script.

1 Like

A script is just some actions to perform, but no trigger and no conditions. (You can still use if/choose of course). As for the on/off behaviour, a script is on when it is running, an automation is on when it is able to respond to triggers (not disabled).

If you trigger an automation, the triggers and conditions are bypassed, effectively reducing it to what a script is meant to do. Especially when actions are complex, I write a script. Then if there are triggers that should start the script I create an automation with only one action: call the script.

1 Like

Probably. In your first post you used the expression “automation subroutine”. That concept is effectively a script. An automation (or a script) can call a script.

Here’s the behavioral difference between the two different ways to call a script.

Blocking
The kitchen light is turned on only after the script runs to completion. If it takes 30 seconds for script.foo to finish then that’s how much time will pass before the kitchen light is turned on.

action:
  - service: script.foo
  - service: light.turn_on
    target:
      entity_id: light.kitchen

Non-Blocking
The kitchen light is turned on immediately after the script is called. It doesn’t wait for the script to finish first.

action:
  - service: script.turn_on
    target:
      entity_id: script.foo
  - service: light.turn_on
    target:
      entity_id: light.kitchen

There’s one more concept and that’s a script’s mode. Basically, it lets you specify what should happen if a script is busy (executing its actions) and it’s called again.

  • Should it ignore the second request and finish what it’s currently doing? That’s single mode.
  • Should it immediately stop what it’s doing and start over? That’s restart mode.
  • Should it process the second request concurrently with the current one? That’s parallel mode.
  • Should it finish what it’s currently doing and then process the second request? That’s queued mode.
4 Likes

I actually had no idea there was a functional difference between script.turn_on and script.foo. TIL!

1 Like