Asynchronous automation steps

I have an automation that fires when somebody rings my doorbell, and it does two things: (A) it sends us a mobile notification, and (B) it starts a doorbell sound MP3 playing on our Google Homes, waits 15 seconds (to give them plenty of time for the playback to have completed), then turns the Google Homes back off again.

I recently upgraded to a video doorbell and I want to change part (A) to add a video snapshot to the notification. Reading through the forums it sounds like the way to do this is to grab a snapshot, wait a few seconds to give it time to save to disk, then send the notification including the URL of the saved image.

This is all great except now both parts of my automation will include a delay. Ideally I’d like both parts to start at the same time and run asynchronously instead of one waiting for the other, so instead of the automation working like this:
(A)--------->(B)----------------->

I want it to work like this:
(A)--------->
(B)----------------->

What’s the best way to achieve this? If I create a couple of scripts (one for A and one for B) and have the automation start the scripts, will that achieve what I want? Or should this actually be two separate automatons instead of one?

Thanks!

Perhaps have a single automation trigger Script A and the first step of Script A is to trigger Script B.

Not entirely sure how HA processes scripts and if it’ll just light the fuse and move on, or wait for it to finish prior to executing next step.

Safest way is two automations w/ the same trigger(s), but perhaps others will know more intimately the inner-workings / timings.

If an automation or script calls another script “directly” (i.e., using service script.NAME), then it will wait for the called script to “return” before going to the next step.

Scripts (for now) can either return when they are done, or when they execute a delay or wait_template step (that actually waits.)

So, if script.A does:

- service: # start snapshot
- delay: N1
- service: # send notification

and script.B does:

- service: # play doorbell sound
- delay: N2
- service: # turn Google Homes off

Then if they are called like this:

- service: script.A
- service: script.B

script.A will start the snapshot and start its delay, at which time it will “return.” Then script.B will start playing the doorbell and start its delay, at which time it will “return.” At that point the next step of the automation/script will run, or finish if there’s nothing else. The two scripts will effectively continue asynchronously.

But this behavior is being deprecated. In the future scripts will not return until they are done. (Don’t panic! The current behavior will be maintained for a while.) Having said that, both now and in the future, if the other script is instead called via the script.turn_on service, then the caller will not wait for the called script to finish. The called script will get started and run asynchronously. Furthermore, if you call multiple scripts via one script.turn_on service call, all the called scripts will be started and run asynchronously.

So:

- service: script.turn_on
  entity_id:
  - script.A
  - script.B

will guarantee that both scripts are run asynchronously to the caller and each other.

7 Likes

Appreciate the detailed response, thanks @pnbruckner!

1 Like