Skip to content

Functions not triggered in the order of events #704

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
attila123456 opened this issue Mar 5, 2025 · 3 comments
Closed

Functions not triggered in the order of events #704

attila123456 opened this issue Mar 5, 2025 · 3 comments

Comments

@attila123456
Copy link

I have a script that turns on a light when a person is detected and turns it off after a delay if detection stops.

The triggers are @state_trigger("binary_sensor.person_detected == 'on'") on one function and ...=='off' on the other, respectively.

Sometimes detections are very short, the sensor entity can change value within a second, and when that happens, my functions may be triggered in the wrong order even though the events are recorded in the correct order.

An example event straight from the events table of HA, with timestamps and formatted dates, first turning on then off:

on|1740940619.45155|2025-03-02 19:36:59|
off|1740940619.45191|2025-03-02 19:36:59|

And a snippet of the pyscript logs; the last two lines correspond to the above events, except the functions were called in the reverse order:

2025-03-02 19:36:49.551 INFO (MainThread) [custom_components.pyscript.file.lights.light_off] person detected OFF
2025-03-02 19:36:59.453 INFO (MainThread) [custom_components.pyscript.file.lights.light_off] person detected OFF
2025-03-02 19:36:59.456 INFO (MainThread) [custom_components.pyscript.file.lights.light_on] person detected ON

The result being that my light stays on indefinitely after such a "hiccup". Is this a bug or more like a fundamental system limitation where the order of triggers cannot be guaranteed at such short time intervals?

Thanks!

@craigbarratt
Copy link
Member

craigbarratt commented Mar 5, 2025

That's a very interesting issue - the functions run asynchronously when triggered, so even if one is started before the other, the subsequent execution of the rest of the trigger function could happen in any order if they are very close in time (0.36 msec in the case you show)

If the on -> off period might be very short, but off is expected to persist for some time, you could use state_hold=0.5 on the ...=='off' trigger. That will cause it to be called only when the sensor has remained off for at least 0.5 seconds. If the sensor gives another "on" during that period, the "on" function will still get called, but the "off" trigger will not be until there has been at least 0.5 seconds without an "on". So you need to be sure your logic handles the case where the "on" function could get called multiple times without the "off" trigger happening until later (they might not be called strictly in pairs anymore).

There are likely other solutions, but state_hold seems to be the simplest.

@craigbarratt
Copy link
Member

In fact, you could just set state_hold for the off trigger to be the time you want the lights to remain on after a motion detection. Then it will restart each time there is a subsequent motion event while the lights are still on. That setting will simplify the application logic.

@attila123456
Copy link
Author

In fact, you could just set state_hold for the off trigger to be the time you want the lights to remain on after a motion detection. Then it will restart each time there is a subsequent motion event while the lights are still on. That setting will simplify the application logic.

This, exactly - after your first reply I realized that I might have overthought this, I had used task.unique and task.sleep to mimic what state_hold actually does pretty nicely. So when the ON function ran after the OFF, task.unique killed the OFF function, so the light stayed on.
I've now removed all that logic and added state_hold=60 and had no issues so far... I think it should work.

Thanks for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants