Add wait_for_trigger script action (#14065)

This commit is contained in:
Phil Bruckner 2020-08-31 12:33:47 -05:00 committed by GitHub
parent 4703a0b1da
commit cc4e43ba81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -67,46 +67,53 @@ While executing a script you can add a condition to stop further execution. When
Delays are useful for temporarily suspending your script and start it at a later moment. We support different syntaxes for a delay as shown below.
{% raw %}
```yaml
# Seconds
# Waits 5 seconds
- delay: 5
```
```yaml
# HH:MM
# Waits 1 hour
- delay: '01:00'
```
```yaml
# Waits 1 minute, 30 seconds
# HH:MM:SS
# Waits 1.5 minutes
- delay: '00:01:30'
```
```yaml
# Supports milliseconds, seconds, minutes, hours, days
# Can be used in combination, at least one required
# Waits 1 minute
- delay:
# Supports milliseconds, seconds, minutes, hours, days
minutes: 1
```
{% raw %}
```yaml
# Waits however many seconds input_number.second_delay is set to
- delay:
# Supports milliseconds, seconds, minutes, hours, days
seconds: "{{ states('input_number.second_delay') | int }}"
```
{% endraw %}
All forms accept templates.
{% raw %}
```yaml
# Waits however many minutes input_number.minute_delay is set to
# Valid formats include HH:MM and HH:MM:SS
- delay: "{{ states('input_number.minute_delay') | multiply(60) | timestamp_custom('%H:%M:%S',False) }}"
- delay: "{{ states('input_number.minute_delay') | multiply(60) | int }}"
```
{% endraw %}
### Wait
Wait until some things are complete. We support at the moment `wait_template` for waiting until a condition is `true`, see also on [Template-Trigger](/docs/automation/trigger/#template-trigger).
These actions allow a script to wait for entities in the system to be in a certain state as specified by a template, or some event to happen as expressed by one or more triggers.
When used within an automation the `trigger` variable is available. See [Available-Trigger-Data](/docs/automation/templating/#available-trigger-data).
#### Wait Template
This action evaluates the template, and if true, the script will continue. If not, then it will wait until it is true.
{% raw %}
```yaml
# Wait until media player have stop the playing
@ -114,34 +121,61 @@ Wait until some things are complete. We support at the moment `wait_template` fo
```
{% endraw %}
When using `wait_template` within an automation `trigger.entity_id` is supported for `state`, `numeric_state` and `template` triggers, see also [Available-Trigger-Data](/docs/automation/templating/#available-trigger-data).
#### Wait for Trigger
This action can use the same triggers that are available in an automation's `trigger` section. See [Automation Trigger](/docs/automation/trigger). The script will continue whenever any of the triggers fires.
{% raw %}
```yaml
- wait_template: "{{ is_state(trigger.entity_id, 'on') }}"
# Wait for a custom event or light to turn on and stay on for 10 sec
- wait_for_trigger:
- platform: event
event_type: MY_EVENT
- platform: state
entity_id: light.LIGHT
to: 'on'
for: 10
```
{% endraw %}
It is also possible to use dummy variables, e.g., in scripts, when using `wait_template`.
#### Wait Timeout
With both types of waits it is possible to set a timeout after which the script will continue its execution if the condition/event is not satisfied. Timeout has the same syntax as `delay`, and like `delay`, also accepts templates.
{% raw %}
```yaml
# Service call, e.g., from an automation.
- service: script.do_something
data:
dummy: input_boolean.switch
# Inside the script
- wait_template: "{{ is_state(dummy, 'off') }}"
# Wait for sensor to change to 'on' up to 1 minute before continuing to execute.
- wait_template: "{{ is_state('binary_sensor.entrance', 'on') }}"
timeout: '00:01:00'
```
{% endraw %}
After each time the wait completes, either because the condition was met, or the timeout expired, the variable `wait` will be created/updated to indicate the result.
You can also get the script to abort after the timeout by using optional `continue_on_timeout`.
{% raw %}
```yaml
# Wait for IFTTT event or abort after specified timeout.
- wait_for_trigger:
- platform: event
event_type: ifttt_webhook_received
event_data:
action: connected_to_network
timeout:
minutes: "{{ timeout_minutes }}"
continue_on_timeout: false
```
{% endraw %}
Without `continue_on_timeout` the script will always continue.
#### Wait Variable
After each time a wait completes, either because the condition was met, the event happened, or the timeout expired, the variable `wait` will be created/updated to indicate the result.
Variable | Description
-|-
`wait.completed` | `true` if the condition was met, `false` otherwise
`wait.remaining` | timeout remaining, or `none` if a timeout was not specified
`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](/docs/automation/templating/#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
This can be used to take different actions based on whether or not the condition was met, or to use more than one wait sequentially while implementing a single timeout overall.
@ -157,7 +191,10 @@ This can be used to take different actions based on whether or not the condition
sequence:
- service: script.door_did_not_open
default:
- service: script.door_did_open
- service: script.turn_on
entity_id:
- script.door_did_open
- script.play_fanfare
# Wait a total of 10 seconds.
- wait_template: "{{ is_state('binary_sensor.door_1', 'on') }}"
@ -165,7 +202,11 @@ This can be used to take different actions based on whether or not the condition
continue_on_timeout: false
- service: switch.turn_on
entity_id: switch.some_light
- wait_template: "{{ is_state('binary_sensor.door_2', 'on') }}"
- wait_for_trigger:
- platform: state
entity_id: binary_sensor.door_2
to: 'on'
for: 2
timeout: "{{ wait.remaining }}"
continue_on_timeout: false
- service: switch.turn_off
@ -173,32 +214,6 @@ This can be used to take different actions based on whether or not the condition
```
{% endraw %}
#### Wait Timeout
It is possible to set a timeout after which the script will continue its execution if the condition is not satisfied. Timeout has the same syntax as `delay`, and like `delay`, also accepts templates.
{% raw %}
```yaml
# Wait for sensor to trigger or 1 minute before continuing to execute.
- wait_template: "{{ is_state('binary_sensor.entrance', 'on') }}"
timeout: '00:01:00'
```
{% endraw %}
You can also get the script to abort after the timeout by using optional `continue_on_timeout`
{% raw %}
```yaml
# Wait until a valve is < 10 or abort after specified timeout.
- wait_template: "{{ state_attr('climate.kitchen', 'valve')|int < 10 }}"
timeout:
minutes: "{{ timeout_minutes }}"
continue_on_timeout: false
```
{% endraw %}
Without `continue_on_timeout` the script will always continue.
### Fire an Event
This action allows you to fire an event. Events can be used for many things. It could trigger an automation or indicate to another integration that something is happening. For instance, in the below example it is used to create an entry in the logbook.