After reading the documentation, I wasn’t completely sure about the asynchronous nature of scripts in ESPhome. And, I was too busy/lazy/stupid to track it down through the native code. Instead, I did a little experiment. Here it is. It’s nothing earth-shaking, but maybe it will save someone else a few minutes of pondering or experimenting.
The bottom line is that the scripts do run independently (or at least appear to do so to the extent that it probably matters for whatever you need to do).
At boot time, I launch 3 scripts. Each script is an infinite loop with a delay in the body of the loop. Each script uses a different delay value to make it clearer that they are not in lock-step with each other. (In actual usage, delay values are templatable, so they needn’t be constants.)
[11:51:33][D][main:236]: EVERY ---------------- 13
[11:51:46][D][main:236]: EVERY ---------------- 13
[11:51:53][D][main:257]: EVERY ----------------------- 23
[11:51:59][D][main:236]: EVERY ---------------- 13
[11:51:59][D][main:274]: EVERY ------------------------------------- 51
[11:52:12][D][main:236]: EVERY ---------------- 13
[11:52:16][D][main:257]: EVERY ----------------------- 23
[11:52:25][D][main:236]: EVERY ---------------- 13
[11:52:38][D][main:236]: EVERY ---------------- 13
[11:52:39][D][main:257]: EVERY ----------------------- 23
[11:52:50][D][main:274]: EVERY ------------------------------------- 51
[11:52:51][D][main:236]: EVERY ---------------- 13
[11:53:03][D][main:257]: EVERY ----------------------- 23
[11:53:04][D][main:236]: EVERY ---------------- 13
[11:53:17][D][main:236]: EVERY ---------------- 13
[11:53:26][D][main:257]: EVERY ----------------------- 23
[11:53:30][D][main:236]: EVERY ---------------- 13
[11:53:41][D][main:274]: EVERY ------------------------------------- 51
[11:53:43][D][main:236]: EVERY ---------------- 13
[11:53:49][D][main:257]: EVERY ----------------------- 23
[11:53:56][D][main:236]: EVERY ---------------- 13
[11:54:09][D][main:236]: EVERY ---------------- 13
[11:54:12][D][main:257]: EVERY ----------------------- 23
[11:54:22][D][main:236]: EVERY ---------------- 13
[11:54:32][D][main:274]: EVERY ------------------------------------- 51
[11:54:35][D][main:257]: EVERY ----------------------- 23
[11:54:35][D][main:236]: EVERY ---------------- 13
[11:54:48][D][main:236]: EVERY ---------------- 13
Here’s a variation of the above. In this case, it wasn’t really to see exactly how something works, since the documentation is pretty clear. It was more to work out the syntax (YAML can make me a little crazy). I’m planning to use something like this in a project I’m working on.
In this config, I’m launching the script blink from any one of the three original scripts, but I only want it to be running at most once at any given time. The original scripts check to see if it’s already running and only launch it if it isn’t. blink logs what it’s doing instead of blinking an actual LED. It turns out it’s tricky to copy and paste an LED blink into a forum posting. . As a bonus, the delay time in blink is templated and depends on which script launched it (every_13 causes a delay of 130ms, every_23 causes a delay of 230ms, and every_51 causes a delay of 510ms).
A similar test, but I took out the guard checks that prevented multiple runnings of the blink script. The outcome was pretty much as I expected (confusion about globals due to overlapped invocations), but I ran the test for completeness.
Ah, well, I see that esphome 1.15.x adds script modes. In addition to having built-in finer-grained control over how multiple script invocations interact, the mere presence of the feature provides clarification on what those interactions can be. Yay. https://github.com/esphome/esphome/pull/1168