Add script modes and timers (#693)

Co-authored-by: Otto Winter <otto@otto-winter.com>
This commit is contained in:
Guillermo Ruffino 2020-07-25 09:20:58 -03:00 committed by GitHub
parent cf8f06752b
commit 2e85a4001f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -605,16 +605,11 @@ Configuration variables:
- **value** (**Required**, :ref:`templatable <config-templatable>`): The value to set the global
variable to.
.. _script-execute_action:
``script.execute`` Action
-------------------------
``script``
----------
This action allows code-reuse. For example if you have multiple triggers
that perform the same exact action, you would normally have to copy the YAML lines for all
triggers.
With the ``script`` component you can define these steps in a central place, and then
With the ``script:`` component you can define a list of steps in a central place, and then
execute the script with a single call.
.. code-block:: yaml
@ -627,6 +622,34 @@ execute the script with a single call.
- delay: 1s
- switch.turn_off: my_switch
Configuration options:
- **id** (**Required**, :ref:`config-id`): The :ref:`config-id` of the script. Use this
to interact with the script using the script actions.
- **mode** (*Optional*, string): Controls what happens when a script is
invoked while it is still running from one or more previous invocations. Default to ``single``.
- ``single``: Do not start a new run. Issue a warning.
- ``restart``: Start a new run after first stopping previous run.
- ``queued``: Start a new run after previous runs complete.
- ``parallel``: Start a new, independent run in parallel with previous runs.
- **max_runs** (*Optional*, integer): Allows limiting the maxiumun number of runs when using script
modes ``queued`` and ``parallel``, use value ``0`` for unlimited runs. Defaults to ``0``.
- **then** (**Required**, :ref:`config-action`): The action to perform.
.. _script-execute_action:
``script.execute`` Action
-------------------------
This action executes the script. The script **mode** dictates what will happen if the
script was already running.
.. code-block:: yaml
# in a trigger:
on_...:
then:
@ -639,7 +662,10 @@ execute the script with a single call.
This action allows you to stop a given script during execution. If the
script is not running, it does nothing.
Please note this is only useful right now if your script contains a ``delay`` action.
This is useful right now if your want to stop a script that contains a
``delay`` action, ``wait_until`` action, or is inside a ``while`` loop, etc.
You can also call this action from the script itself, and any subsequent action
will not be executed.
.. code-block:: yaml
@ -663,8 +689,8 @@ Please note this is only useful right now if your script contains a ``delay`` ac
This action suspends execution of the automation until a script has finished executing.
Note: If no script is executing, this will continue immediately. If multiple instances of the script
are running, this will block until all of them have terminated.
Note: If no script is executing, this will continue immediately. If multiple instances
of the script are running in parallel, this will block until all of them have terminated.
.. code-block:: yaml
@ -688,8 +714,8 @@ are running, this will block until all of them have terminated.
-------------------------------
This :ref:`condition <config-condition>` allows you to check if a given script is running.
Please note that multiple scripts can be running concurrently. This condition only tells
you if at least one script of the given type is running, not how many.
In case scripts are run in ``parallel``, this condition only tells you if at least one script
of the given id is running, not how many.
.. code-block:: yaml
@ -750,6 +776,33 @@ Configuration options:
- **interval** (**Required**, :ref:`config-time`): The interval to execute the action with.
- **then** (**Required**, :ref:`config-action`): The action to perform.
Timers and timeouts
-------------------
While ESPHome does not provide a construction for timers, you can easily implement them by
combining ``script`` and ``delay``. You can have an absolute timeout or sliding timeout by
using script modes ``single`` and ``restart`` respectively.
.. code-block:: yaml
script:
- id: hallway_light_script
mode: restart # Light will be kept on during 1 minute since
# the latest time the script is executed
then:
- light.turn_on: hallway_light
- delay: 1 min
- light.turn_off: hallway_light
...
on_...: # can be called from diffrent wall switches
- script.execute: hallway_light_script
Sometimes you'll also need a timer which does not perform any action, that is ok too, just
use a single ``delay`` action, then in your automation check ``script.is_running`` condition
to know if your *timer* is going or due.
See Also
--------