Inspired by a topic that I cannot seem to find back, I created the Proof of Concept below.
The PoC is a simplified test automation to understand the wait_for_trigger action and test the folder_watcher. It all seem to work as designed, however the wait_for_trigger is never actually triggered. The confusing part is that when watching the automation, the wait is triggered (coloring blue, see image below) and of course the script does create a snapshot.
It doesn’t matter how long I set the wait. The trigger is near instant there. I increased the wait time up to 30 second, but that just results in a longer wait before the persistent_notification is created. That’s also a confirmation that it’s not the choose-condition failing.
alias: Camera Snapshots PoC
description:
trigger:
- platform: state
entity_id: binary_sensor.front_motion_detected
to: 'on'
id: Camera Sensor
variables:
camera_id: camera.front
condition: []
action:
- service: script.camera_snapshot
data: {}
- wait_for_trigger:
- platform: event
event_type: folder_watcher
event_data:
event_type: created
id: Created while waiting
timeout: '00:00:05'
continue_on_timeout: true
- choose:
- conditions:
- condition: template
value_template: '{{ wait.completed }}'
sequence:
- service: persistent_notification.create
data:
message: Snapshot captured
title: Snapshot test
enabled: true
default:
- service: persistent_notification.create
data:
message: No snapshot
title: Snapshot test
enabled: true
mode: single
It feels like a bug, but maybe it’s me being the bug
Any ideas ?
Solution
The "mark as solution seems disappeared at the moment. The solution is using script.turn_on instead of just running it directly as a service_call cause then it waits for the script to complete. It doesn’t when you use script.turn_on.
It could very well be that the snapshot was written before the wait for trigger. Essentially the wait was waiting for the event to ‘change’ and it didn’t occur between the time it started and the time it began waiting. You’d need to listen for hte event and see when it actually occurred.
Have you verified the folder watcher event occurred during the wait time?
That’s a good tip. I have not and have to figure out how to do that. Meanwhile I added a one second delay to the script before it makes the snap, so it should be later than the start of the wait for trigger.
But I noticed that the automation waits for the script to complete!
Putting it in a parallel in the following scenario’s:
everything in, but then the choose triggers at the same time as the script and the wait
script and wait_for_trigger in parallel
But then it (logically) just doesn’t wait before it arrives at the choose
scenario 2 but added a wait (for the set wait.trigger.id) before the choose and changed the choose to the same condition, but that didn’t do anything good either.
You could use parallel, and then wrap the wait and snapshot in a sequence so they run in sequence. but remember the wait.trigger won’t be {{ wait.completed }} won’t be available in the outer code.
Thing is though is you’re chasing unicorns till you know the underlying problem. The folder watcher isn’t instant (at least I dont think it is! Im not 100% sure for that integration). I believe its 60 seconds by default? I can’t remember what the default for a sensor update is.
What I would try is instead of waiting on the event, you can do a while loop with a maximum number of repeats to check the new file exists before continuing. But i’d check the event before you start writing code you don’t need.
You could also use the service: homeassistant.update_entity to make sure it runs immediately on that watcher. I don’t think you can with watcher as it doesn’t create a sensor. Maybe it is fairly immediate.
Yes it does. Unless you put it in a script and call it with the script.turn_on. Then it won’t wait. Honestly, this is probably your issue. The snap completes before and there is no event change after that.
EDIT: Before you go any further, you need to verify the timing of the event using the develper tools events tab.
I thought the automation never waited for a script to end. That’s why I normally use script.turn_on in combination with a wait for {{ is_state('script.<name>', 'off') }}. So I use script.turn_on now and the wait_for_trigger is:
wait:
remaining: 3.08957884699339
So that’s a confirmation to me. I saw but never used events listener before, so there is a first time for everything. Very easy and straight forward
Unfortunately the wait.completed doesn’t return true (don’t know about false), but luckily wait.trigger does contain data to work with.
The wait.completed is only used after wait_template.
wait.completed
Exists only after wait_template. true if the condition was met, false otherwise
wait.trigger
Exists only after wait_for_trigger. Contains information about which trigger fired. (See Available-Trigger-Data.) Will be none if no trigger happened before timeout expired
wait.remaining
Timeout remaining, or none if a timeout was not specified