Understanding queued automatons

Hey all.

I have the following automation, which uses queued mode, but it’s not working the way I expect:

alias: Pet food vibration detected
description: ''
trigger:
  - platform: state
    entity_id:
      - binary_sensor.cat_food_ias_zone
    to: 'on'
  - platform: state
    entity_id:
      - binary_sensor.oakley_food_ias_zone
    to: 'on'
  - platform: state
    entity_id:
      - binary_sensor.daisy_food_ias_zone
    to: 'on'
condition: []
action:
  - service: pyscript.clear_pet_food_reminder
    data:
      entity_id: '{{ trigger.entity_id }}'
mode: queued

When multiple vibration sensors are triggered at once, I want the calls to the service to be queued. But instead, I’m finding that the service is getting invoked in parallel for the different sensors. Are actions queued only when the trigger is the same? If so, is there a way to get the behavior I’m seeking? Thank you!

Assume the automation is triggered and busy executing its action. Any subsequent trigger will queue the request to execute the action. When the automation has completed servicing its action, it proceeds to service the next request in the queue.

If it takes virtually no time at all to execute the action, there’ll be very little waiting time in the queue because the automation can process all requests rapidly.

What may be happening here is that when it executes the pyscript, it doesn’t wait for it to finish (i.e. non-blocking) before processing the next request in the queue. In effect, each instance of your pyscript is spawned as a separate task. Therefore it’s possible to have multiple concurrent instances of the pyscript executing.

FWIW, this behavior is known and documented for Home Assistant’s native scripts and depends on how the script is called (see Waiting for script to complete). I don’t use pyscript so you should check its documentation to confirm its behavior is similar to native scripts.

1 Like

Add small delay (wait to time pass) as last action.

Ahh, yes, you’re right. It takes several seconds for the script to execute so I tried adding another action after the service call to see if it would be delayed by a few seconds. It wasn’t; the second action started almost immediately. So that tells me the pyscript service call must be non-blocking.

In that case, @IgorZg’s suggestion to add a small delay as the last action should solve this as long as the delay is greater than the time to execute the script.

I tried it and it works! Thank you @123 and @IgorZg!

1 Like

Adding a delay statement is the last thing I would have ever suggested because it’s a kludge.

You should consider re-engineering your application to avoid relying on fixed time delays to force blocking behavior. Are you aware that a delay statement is unceremoniously terminated every time you Reload Automations? It has the potential to make parallel execution reappear but now it would be seemingly sporadic like an elusive bug.

Depending on what pyscript.clear_pet_food_reminder does, it might be possible to incorporate it directly into the existing automation or convert the automation entirely into pyscript (because pyscript also supports triggers natively).

Yes, I realize that. Simplicity wins over technical correctness in this case, though. The consequence if it does run in parallel is small, and I like to keep all of my automation entry points in the UI. (It’s not clear that putting the trigger in pyscript would change the non-blocking behavior anyway.)

I’ll just pretend it’s a timeout. :wink: