Simultaneously running multiple instances of the same script

I have a bunch of sensors for which I want to perform similar actions upon detecting a state change. I ended up making separate automations that trigger the same script with slightly different parameters. On occasion, it happens that these sensors update at the same time, trigger their respective automations, and then attempt to run the same script. In this situation, the script only ever runs for one of the sensors. I assume this is because the second attempt to run it detects that the script is already running.

Can I make this work, or am I doomed to have to copy and paste the YAML into a separate script for each sensor?

You can’t run the same script multiple times at the same time, but you can use yaml anchors to create multiple identical scripts with very few extra lines of code.

Interesting. I haven’t heard of YAML anchors before…Let me do some googling.

1 Like

Is this also true for automations? What if an automation is triggered by two entities which both have their state change at the same time. What happens?

Not sure if it helps you but I’ve used something like this for shell_commands:
the shell_command just starts a python script, in the python script I use this to avoid having interference when calling the same multiple times:

with ILock('ebus', timeout=200):
	#....

I don’t think that it’s interference between the two scripts, it’s just that HA won’t run it while it’s currently running. The second invocation just fails.

If there are no delays in the automation it should be instantaneous. If there are delays, then the second trigger will bump the action forward to the end. So yeah, you are still only really running it once at a time but in a slightly different way.

My experience is that trying to run a script a second time or triggering an automation again will jump past the delay, but not directly to the end of the script. I noticed this when I had an ‘on, delay, off’ sequence and the script would blow right past the delay and turn the device off if the script was executed again.

I often struggle with scripts not being able to run in parallel. I find myself using copious wait_templates to ensure 'script clash` doesn’t happen. Irritating but an HA design decision I can happily accept.

But…

Just to be clear, are you saying that if an automation has a delay, while it is ‘delayed’ it will still respond to it’s trigger(s)? And if triggered while delayed, it will then ignore the delay and continue processing to the end? (And will it then start again because of the second trigger?)

I know I have probably just repeated what you said, but I just want to be sure I have understood.

Because that just seems wrong to me. Surely it should respect the delay?

That’s what will happen. I think it’s a bug, I’m told it’s a feature. (and no, it won’t do it again for the second trigger)

What if, and yes I might be stretching the point a bit here, but what if that delay was critical?
Like, life threateningly critical.

I vote bug.

Ah, but how do you decide what to do with the delay?

So if I set a 1 hour delay and I trigger the automation at 1pm, and then again at 1.30pm, should the remaining actions fire at 2pm, 2.30 or both?

Whereas if I know that in that circumstance it will definitely continue the actions at 1.30pm I can work around it just as easily as I can with any of the other potential options.

Yes, that is true but I think you could also work around an automation triggering while it is delayed. It just feels right to me that the first automation that is actually active should have preference and anything that comes later should deal with what is going on ‘now’.

There is a decent argument for both cases. Which is why I only vote bug rather than scream bug. :stuck_out_tongue_winking_eye:

To be fair, actually I probably vote ‘wrong design choice’. :upside_down_face:

As an afterthought is this behaviour documented anywhere?

Don’t use Home Assistant for that?

But seriously, just use duplicate scripts…

With duplicate scripts you avoid many problems

Yeah… I did say I was stretching the point :wink:
And,

That is exactly what I do. (Or use wait_templates - if the scripts both want access to the same physical device then duplicate scripts may also not work as expected.)

After banging my head against this for a while, and remembering what was said before about automations being able to run simultaneously, I realized that if you don’t care that your scripts might get run simultaneously (or, in fact, you want this), then you can write it as an automation with a custom event trigger, and call it by firing that event. I’ve re-written several of my scripts like this, and it works very well.

Define your script as an automation:

automation:
  - alias: automation_name
    trigger:
      - platform: event
        event_type: automation_name  <--- I name the event after the automation
                                          to keep it simple.
    action:
      - service: whatevs
        data_template:
          foo: "{{ trigger.event.data.param_1 }}"
          bar: "{{ trigger.event.data.param_2 }}"

Then call it like this:

  action:
    - event: automation_name
      event_data_template:
        param_1: asdf
        param_2: qwer
2 Likes

Nope, I got all the above except Steve’s last post which is as clear as mud.
I get that the scripts are rewritten as automations but how he calls the automations is a mystery.
You need to dumb it down just a bit more and then some on top of that.
Thanks

Well, the easiest way to describe what I’m doing is to say that I’m creating my own event type with arbitrary data.

I’m listening for that event in the trigger for the automation, and firing an event of that type with some data to “call the script”. Then in the actions of the automation, you can access that data that was included with the event when it was fired.

Everything in HA is basically various types of events with particular data associated with it, and all automations listen for specific types of events with specific data on the event bus. So I’m just tying into that.

I hope that makes sense.

Sorry to hijack the thread (I’ve prolly done it before)

What you just explained was actually what I got from looking at the code.
What I don’t get is the actual implementation details (sorry if I’m being dumb again) the name of your event doesn’t match the action output data so I don’t see how the two link.
Can you (say) post an example where your automation is triggered by an input boolean to on. Which fires a second automation which turns it off ?
I’ll process it from there and maybe ask a follow-up
Cheers