esphome-docs/automations/templates.rst
Keith Burzinski 5c78504d97
Break apart automations doc (#3957)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2024-06-27 11:55:41 +12:00

118 lines
5.0 KiB
ReStructuredText

.. _config-lambda:
Templates
=========
.. seo::
:description: Guide for using templates in ESPHome
:image: auto-fix.svg
*Templates* (also known as *lambdas*) allow you to do almost *anything* in ESPHome. For example, if you want to only
perform a certain automation if a certain complex formula evaluates to true, you can do that with templates. Let's look
at an example first:
.. code-block:: yaml
binary_sensor:
- platform: gpio
name: "Cover End Stop"
id: top_end_stop
cover:
- platform: template
name: Living Room Cover
lambda: !lambda |-
if (id(top_end_stop).state) {
return COVER_OPEN;
} else {
return COVER_CLOSED;
}
What's happening here? First, we define a binary sensor (notably with ``id: top_end_stop``) and then a
:doc:`template cover </components/cover/template>`. (If you're new to Home Assistant, a 'cover' is something like a
window blind, a roller shutter, or a garage door.) The *state* of the template cover is controlled by a template, or
"lambda". In lambdas, you're just writing C++ code and therefore the name lambda is used instead of Home Assistant's
"template" lingo to avoid confusion. Regardless, don't let lambdas scare you just because you saw "C++" -- writing
lambdas is not that hard! Here's a bit of a primer:
First, you might have already wondered what the ``lambda: !lambda |-`` part is supposed to mean. ``!lambda`` tells
ESPHome that the following block is supposed to be interpreted as a lambda, or C++ code. Note that here, the
``lambda:`` key would actually implicitly make the following block a lambda, so in this context, you could also have
written ``lambda: |-``.
Next, there's the weird ``|-`` character combination. This tells the YAML parser to treat the following **indented**
block as plaintext. Without it, the YAML parser would attempt to read the following block as if it were made up of YAML
keys like ``cover:`` for example. (You may also have seen variations of this like ``>-`` or just ``|`` or ``>``. There
is a slight difference in how these different styles deal with whitespace, but for our purposes we can ignore that).
With ``if (...) { ... } else { ... }`` we create a *condition*. What this effectively says that if the thing inside the
first parentheses evaluates to ``true`` then execute the first block (in this case ``return COVER_OPEN;``, or else
evaluate the second block. ``return ...;`` makes the code block give back a value to the template. In this case, we're
either *returning* ``COVER_OPEN`` or ``COVER_CLOSED`` to indicate that the cover is closed or open.
Finally, ``id(...)`` is a helper function that makes ESPHome fetch an object with the supplied ID (which you defined
somewhere else, like ``top_end_stop``) and lets you call any of ESPHome's many APIs directly. For example, here we're
retrieving the current state of the end stop using ``.state`` and using it to construct our cover state.
.. note::
ESPHome does not check the validity of lambda expressions you enter and will blindly copy them into the generated
C++ code. If compilation fails or something else is not working as expected with lambdas, it's always best to look
at the generated C++ source file under ``<NODE_NAME>/src/main.cpp``.
.. tip::
To store local variables inside lambdas that retain their value across executions, you can create ``static``
variables as shown in the example below. Here, the variable ``num_executions`` is incremented by one each time the
lambda is executed and the current value is logged.
.. code-block:: yaml
lambda: |-
static int num_executions = 0;
ESP_LOGD("main", "I am at execution number %d", num_executions);
num_executions += 1;
.. _config-templatable:
Templating Actions
------------------
ESPHome allows you to template most parameters for actions used in automations. For example, if you have a light and
want to set it to a pre-defined color when a button is pressed, you can do this:
.. code-block:: yaml
on_press:
then:
- light.turn_on:
id: some_light_id
transition_length: 0.5s
red: 0.8
green: 1.0
blue: !lambda |-
// The sensor outputs values from 0 to 100. The blue
// part of the light color will be determined by the sensor value.
return id(some_sensor).state / 100.0;
When you see the label "templatable" in the documentation for a given action, it can be templated as in this example,
using the lambda syntax as described/shown above.
All Lambda Calls
----------------
- :ref:`Sensor <sensor-lambda_calls>`
- :ref:`Binary Sensor <binary_sensor-lambda_calls>`
- :ref:`Switch <switch-lambda_calls>`
- :ref:`Display <display-engine>`
- :ref:`Cover <cover-lambda_calls>`
- :ref:`Text Sensor <text_sensor-lambda_calls>`
- :ref:`Stepper <stepper-lambda_calls>`
- :ref:`Number <number-lambda_calls>`
See Also
--------
- :doc:`index`
- :doc:`actions`
- :ghedit:`Edit`