Merge branch 'current' into next

This commit is contained in:
Jesse Hills 2024-06-27 17:19:03 +12:00
commit 48ab2916b4
No known key found for this signature in database
GPG Key ID: BEAAE804EFD8E83A
18 changed files with 1604 additions and 1033 deletions

421
all_automations.json Normal file
View File

@ -0,0 +1,421 @@
{
"actions": [
"ags10.new_i2c_address",
"ags10.set_zero_point",
"alarm_control_panel.arm_away",
"alarm_control_panel.arm_home",
"alarm_control_panel.arm_night",
"alarm_control_panel.chime",
"alarm_control_panel.disarm",
"alarm_control_panel.pending",
"alarm_control_panel.ready",
"alarm_control_panel.triggered",
"animation.next_frame",
"animation.prev_frame",
"animation.set_frame",
"at581x.reset",
"at581x.settings",
"binary_sensor.template.publish",
"ble.disable",
"ble.enable",
"ble_client.ble_write",
"ble_client.connect",
"ble_client.disconnect",
"ble_client.numeric_comparison_reply",
"ble_client.passkey_reply",
"ble_client.remove_bond",
"bluetooth_password.set",
"button.press",
"canbus.send",
"climate.control",
"climate.haier.beeper_off",
"climate.haier.beeper_on",
"climate.haier.display_off",
"climate.haier.display_on",
"climate.haier.health_off",
"climate.haier.health_on",
"climate.haier.power_off",
"climate.haier.power_on",
"climate.haier.power_toggle",
"climate.haier.set_horizontal_airflow",
"climate.haier.set_vertical_airflow",
"climate.haier.start_self_cleaning",
"climate.haier.start_steri_cleaning",
"climate.pid.autotune",
"climate.pid.reset_integral_term",
"climate.pid.set_control_parameters",
"component.resume",
"component.suspend",
"component.update",
"cover.close",
"cover.control",
"cover.open",
"cover.stop",
"cover.template.publish",
"cover.toggle",
"cs5460a.restart",
"datetime.date.set",
"datetime.datetime.set",
"datetime.time.set",
"deep_sleep.allow",
"deep_sleep.enter",
"deep_sleep.prevent",
"delay",
"dfplayer.pause",
"dfplayer.play",
"dfplayer.play_folder",
"dfplayer.play_mp3",
"dfplayer.play_next",
"dfplayer.play_previous",
"dfplayer.random",
"dfplayer.reset",
"dfplayer.set_device",
"dfplayer.set_eq",
"dfplayer.set_volume",
"dfplayer.sleep",
"dfplayer.start",
"dfplayer.stop",
"dfplayer.volume_down",
"dfplayer.volume_up",
"dfrobot_sen0395.reset",
"dfrobot_sen0395.settings",
"display.page.show",
"display.page.show_next",
"display.page.show_previous",
"display_menu.down",
"display_menu.enter",
"display_menu.hide",
"display_menu.left",
"display_menu.right",
"display_menu.show",
"display_menu.show_main",
"display_menu.up",
"ds1307.read_time",
"ds1307.write_time",
"esp32_ble_tracker.start_scan",
"esp32_ble_tracker.stop_scan",
"event.trigger",
"ezo_pmp.arbitrary_command",
"ezo_pmp.change_i2c_address",
"ezo_pmp.clear_calibration",
"ezo_pmp.clear_total_volume_dosed",
"ezo_pmp.dose_continuously",
"ezo_pmp.dose_volume",
"ezo_pmp.dose_volume_over_time",
"ezo_pmp.dose_with_constant_flow_rate",
"ezo_pmp.find",
"ezo_pmp.pause_dosing",
"ezo_pmp.set_calibration_volume",
"ezo_pmp.stop_dosing",
"fan.cycle_speed",
"fan.hbridge.brake",
"fan.toggle",
"fan.turn_off",
"fan.turn_on",
"fingerprint_grow.aura_led_control",
"fingerprint_grow.cancel_enroll",
"fingerprint_grow.delete",
"fingerprint_grow.delete_all",
"fingerprint_grow.enroll",
"fingerprint_grow.led_control",
"globals.set",
"grove_tb6612fng.break",
"grove_tb6612fng.change_address",
"grove_tb6612fng.no_standby",
"grove_tb6612fng.run",
"grove_tb6612fng.standby",
"grove_tb6612fng.stop",
"homeassistant.event",
"homeassistant.service",
"homeassistant.tag_scanned",
"http_request.get",
"http_request.post",
"http_request.send",
"htu21d.set_heater",
"htu21d.set_heater_level",
"if",
"lambda",
"light.addressable_set",
"light.control",
"light.dim_relative",
"light.toggle",
"light.turn_off",
"light.turn_on",
"lightwaverf.send_raw",
"lock.lock",
"lock.open",
"lock.template.publish",
"lock.unlock",
"logger.log",
"max6956.set_brightness_global",
"max6956.set_brightness_mode",
"media_player.pause",
"media_player.play",
"media_player.play_media",
"media_player.stop",
"media_player.toggle",
"media_player.volume_down",
"media_player.volume_set",
"media_player.volume_up",
"mhz19.abc_disable",
"mhz19.abc_enable",
"mhz19.calibrate_zero",
"micro_wake_word.start",
"micro_wake_word.stop",
"microphone.capture",
"microphone.stop_capture",
"midea_ac.beeper_off",
"midea_ac.beeper_on",
"midea_ac.display_toggle",
"midea_ac.follow_me",
"midea_ac.power_off",
"midea_ac.power_on",
"midea_ac.power_toggle",
"midea_ac.swing_step",
"mqtt.publish",
"mqtt.publish_json",
"number.decrement",
"number.increment",
"number.operation",
"number.set",
"number.to_max",
"number.to_min",
"ota.http_request.flash",
"output.esp8266_pwm.set_frequency",
"output.ledc.set_frequency",
"output.libretiny_pwm.set_frequency",
"output.pipsolar.set_level",
"output.rp2040_pwm.set_frequency",
"output.set_level",
"output.turn_off",
"output.turn_on",
"pcf85063.read_time",
"pcf85063.write_time",
"pcf8563.read_time",
"pcf8563.write_time",
"pmwcs3.air_calibration",
"pmwcs3.new_i2c_address",
"pmwcs3.water_calibration",
"pulse_counter.set_total_pulses",
"pulse_meter.set_total_pulses",
"pzemac.reset_energy",
"pzemdc.reset_energy",
"remote_transmitter.transmit_abbwelcome",
"remote_transmitter.transmit_aeha",
"remote_transmitter.transmit_byronsx",
"remote_transmitter.transmit_canalsat",
"remote_transmitter.transmit_canalsatld",
"remote_transmitter.transmit_coolix",
"remote_transmitter.transmit_dish",
"remote_transmitter.transmit_dooya",
"remote_transmitter.transmit_drayton",
"remote_transmitter.transmit_haier",
"remote_transmitter.transmit_jvc",
"remote_transmitter.transmit_keeloq",
"remote_transmitter.transmit_lg",
"remote_transmitter.transmit_magiquest",
"remote_transmitter.transmit_midea",
"remote_transmitter.transmit_mirage",
"remote_transmitter.transmit_nec",
"remote_transmitter.transmit_nexa",
"remote_transmitter.transmit_panasonic",
"remote_transmitter.transmit_pioneer",
"remote_transmitter.transmit_pronto",
"remote_transmitter.transmit_raw",
"remote_transmitter.transmit_rc5",
"remote_transmitter.transmit_rc6",
"remote_transmitter.transmit_rc_switch_raw",
"remote_transmitter.transmit_rc_switch_type_a",
"remote_transmitter.transmit_rc_switch_type_b",
"remote_transmitter.transmit_rc_switch_type_c",
"remote_transmitter.transmit_rc_switch_type_d",
"remote_transmitter.transmit_roomba",
"remote_transmitter.transmit_samsung",
"remote_transmitter.transmit_samsung36",
"remote_transmitter.transmit_sony",
"remote_transmitter.transmit_toshiba_ac",
"repeat",
"rf_bridge.beep",
"rf_bridge.learn",
"rf_bridge.send_advanced_code",
"rf_bridge.send_code",
"rf_bridge.send_raw",
"rf_bridge.start_advanced_sniffing",
"rf_bridge.start_bucket_sniffing",
"rf_bridge.stop_advanced_sniffing",
"rtttl.play",
"rtttl.stop",
"scd30.force_recalibration_with_reference",
"scd4x.factory_reset",
"scd4x.perform_forced_calibration",
"script.execute",
"script.stop",
"script.wait",
"select.first",
"select.last",
"select.next",
"select.operation",
"select.previous",
"select.set",
"select.set_index",
"sen5x.start_fan_autoclean",
"senseair.abc_disable",
"senseair.abc_enable",
"senseair.abc_get_period",
"senseair.background_calibration",
"senseair.background_calibration_result",
"sensor.duty_time.reset",
"sensor.duty_time.start",
"sensor.duty_time.stop",
"sensor.integration.reset",
"sensor.rotary_encoder.set_value",
"sensor.template.publish",
"servo.detach",
"servo.write",
"sim800l.connect",
"sim800l.dial",
"sim800l.disconnect",
"sim800l.send_sms",
"sim800l.send_ussd",
"speaker.play",
"speaker.stop",
"sprinkler.clear_queued_valves",
"sprinkler.next_valve",
"sprinkler.pause",
"sprinkler.previous_valve",
"sprinkler.queue_valve",
"sprinkler.resume",
"sprinkler.resume_or_start_full_cycle",
"sprinkler.set_divider",
"sprinkler.set_multiplier",
"sprinkler.set_repeat",
"sprinkler.set_valve_run_duration",
"sprinkler.shutdown",
"sprinkler.start_from_queue",
"sprinkler.start_full_cycle",
"sprinkler.start_single_valve",
"sps30.start_fan_autoclean",
"stepper.report_position",
"stepper.set_acceleration",
"stepper.set_deceleration",
"stepper.set_speed",
"stepper.set_target",
"switch.template.publish",
"switch.toggle",
"switch.turn_off",
"switch.turn_on",
"tag.emulation_off",
"tag.emulation_on",
"tag.polling_off",
"tag.polling_on",
"tag.set_clean_mode",
"tag.set_emulation_message",
"tag.set_format_mode",
"tag.set_read_mode",
"tag.set_write_message",
"tag.set_write_mode",
"text.set",
"text_sensor.template.publish",
"tm1651.set_brightness",
"tm1651.set_level",
"tm1651.set_level_percent",
"tm1651.turn_off",
"tm1651.turn_on",
"uart.write",
"ufire_ec.calibrate_probe",
"ufire_ec.reset",
"ufire_ise.calibrate_probe_high",
"ufire_ise.calibrate_probe_low",
"ufire_ise.reset",
"update.perform",
"valve.close",
"valve.control",
"valve.open",
"valve.stop",
"valve.template.publish",
"valve.toggle",
"voice_assistant.start",
"voice_assistant.start_continuous",
"voice_assistant.stop",
"wait_until",
"while",
"wifi.disable",
"wifi.enable",
"wireguard.disable",
"wireguard.enable"
],
"conditions": [
"alarm_control_panel.is_armed",
"alarm_control_panel.ready",
"and",
"api.connected",
"binary_sensor.is_off",
"binary_sensor.is_on",
"ble.enabled",
"dfplayer.is_playing",
"display.is_displaying_page",
"display_menu.is_active",
"fan.is_off",
"fan.is_on",
"for",
"lambda",
"light.is_off",
"light.is_on",
"lock.is_locked",
"lock.is_unlocked",
"media_player.is_idle",
"media_player.is_playing",
"micro_wake_word.is_running",
"microphone.is_capturing",
"mqtt.connected",
"not",
"number.in_range",
"or",
"pn532.is_writing",
"pn7150.is_writing",
"pn7160.is_writing",
"rtttl.is_playing",
"script.is_running",
"sensor.duty_time.is_not_running",
"sensor.duty_time.is_running",
"sensor.in_range",
"speaker.is_playing",
"sun.is_above_horizon",
"sun.is_below_horizon",
"switch.is_off",
"switch.is_on",
"text_sensor.state",
"time.has_time",
"update.is_available",
"voice_assistant.connected",
"voice_assistant.is_running",
"wifi.connected",
"wifi.enabled",
"wireguard.enabled",
"wireguard.peer_online",
"xor"
],
"pin_providers": [
"bk72xx",
"esp32",
"esp8266",
"host",
"max6956",
"mcp23016",
"mcp23xxx",
"mpr121",
"pca6416a",
"pca9554",
"pcf8574",
"rp2040",
"rtl87xx",
"sn74hc165",
"sn74hc595",
"sx1509",
"wk2168_i2c",
"wk2168_spi",
"wk2212_i2c",
"wk2212_spi",
"xl9535"
]
}

558
automations/actions.rst Normal file
View File

@ -0,0 +1,558 @@
.. _actions-triggers:
Actions, Triggers, Conditions
=============================
.. seo::
:description: Guide for building automations in ESPHome
:image: auto-fix.svg
ESPHome *actions* are how we make an ESPHome device *do something.*
Let's begin with an example. Suppose you have a configuration file which contains:
.. code-block:: yaml
switch:
- platform: gpio
pin: GPIOXX
name: "Living Room Dehumidifier"
binary_sensor:
- platform: gpio
pin: GPIOXX
name: "Living Room Dehumidifier Toggle Button"
With this file you can already perform some basic tasks. You can control the ON/OFF state of the dehumidifier in your
living room from Home Assistant's front-end. But in many cases, controlling everything strictly from the frontend is
not desirable. That's why you've also installed a simple push button next to the dehumidifier wired to pin GPIOXX.
A simple push of this button should toggle the state of the dehumidifier.
You *could* write an automation to do this task in Home Assistant's automation engine, but IoT devices should not
depend on network connections to perform their jobs -- especially not for something as simple as switching on/off a
dehumidifier.
With ESPHome's automation engine, you can define automations using a syntax that is (hopefully) about as easy to use
as Home Assistant's. For example, this configuration would achieve your desired behavior for the dehumidifier:
.. code-block:: yaml
switch:
- platform: gpio
pin: GPIOXX
name: "Living Room Dehumidifier"
id: dehumidifier1
binary_sensor:
- platform: gpio
pin: GPIOXX
name: "Living Room Dehumidifier Toggle Button"
on_press:
then:
- switch.toggle: dehumidifier1
Let's step through what's happening here:
.. code-block:: yaml
switch:
- platform: gpio
# ...
id: dehumidifier1
First, we have to give the dehumidifier ``switch`` an :ref:`config-id` so that we can refer to it inside of our
automation.
.. _actions-trigger:
Triggers
--------
.. code-block:: yaml
binary_sensor:
- platform: gpio
# ...
on_press:
We now attach a special attribute ``on_press`` to the binary sensor (which represents the button). This part is called
a "trigger". In this example, the *automation* which follows on the next few lines will execute whenever someone
*begins* to press the button. Note the terminology follows what you would call these events on mouse buttons. A *press*
happens when you begin pressing the button. There are also other triggers like ``on_release``, ``on_click`` or
``on_double_click`` available.
.. code-block:: yaml
# ...
on_press:
then:
- switch.toggle: dehumidifier1
.. _actions-action:
Actions
-------
Now comes the actual automation block. With ``then``, you tell ESPHome what should happen when the press happens.
Within this block, you can define several "actions" that will be executed sequentially. For example, ``switch.toggle``
and the line after that form an action. Each action is separated by a dash and multiple actions can be executed in
sequence simply by adding another ``-`` like so:
.. code-block:: yaml
# ...
on_press:
then:
- switch.toggle: dehumidifier1
- delay: 2s
- switch.toggle: dehumidifier1
With this automation, a press of the push button would cause the dehumidifier to turn on/off for 2 seconds, and then
cycle back to its original state. You can also have a single trigger with multiple automations:
.. code-block:: yaml
# ...
on_press:
- then:
- switch.toggle: dehumidifier1
- then:
- light.toggle: dehumidifier_indicator_light
# Same as:
on_press:
then:
- switch.toggle: dehumidifier1
- light.toggle: dehumidifier_indicator_light
As a final example, let's make our dehumidifier "smart". Let's make it turn on automatically when
the humidity reported by a sensor is above 65% and make it turn off again when it falls below 50%:
.. code-block:: yaml
sensor:
- platform: dht
humidity:
name: "Living Room Humidity"
on_value_range:
- above: 65.0
then:
- switch.turn_on: dehumidifier1
- below: 50.0
then:
- switch.turn_off: dehumidifier1
temperature:
name: "Living Room Temperature"
That's a lot of indentation. 😉
``on_value_range`` is a special trigger for sensors that triggers when the value of the sensor is within/above/below
the specified range. In the first example, this range is defined as "any value above or including 65.0" and the second
range refers to any (humidity) value 50% or below.
Finally, for the cases where the "pure" YAML automations just don't quite reach far enough, ESPHome has another
extremely powerful tool to offer: :doc:`templates`.
Now that concludes the introduction to actions in ESPHome. They're a powerful tool to automate almost everything on
your device with an easy-to-use syntax. What follows below is an index of common actions which you're sure to find
useful (and even essential) for building all sorts of automations.
.. _common-actions:
Common Actions
--------------
.. _delay_action:
``delay`` Action
****************
This action delays the execution of the next action in the action list by a specified
time period.
.. code-block:: yaml
on_...:
then:
- switch.turn_on: relay_1
- delay: 2s
- switch.turn_off: relay_1
# Templated, waits for 1s (1000ms) only if a reed switch is active
- delay: !lambda "if (id(reed_switch).state) return 1000; else return 0;"
.. note::
This is a "smart" asynchronous delay - other code will still run in the background while
the delay is happening. When using a lambda call, you should return the delay value in milliseconds.
.. _if_action:
``if`` Action
*************
This action first evaluated a certain condition (``if:``) and then either
executes the ``then:`` branch or the ``else:`` branch depending on the output of the condition.
After the chosen branch (``then`` or ``else``) is done with execution, the next action is performed.
For example below you can see an automation that checks if a sensor value is below 30 and if so
turns on a light for 5 seconds. Otherwise, the light is turned off immediately.
.. code-block:: yaml
on_...:
then:
- if:
condition:
lambda: 'return id(some_sensor).state < 30;'
then:
- logger.log: "The sensor value is below 30!"
- light.turn_on: my_light
- delay: 5s
else:
- logger.log: "The sensor value is above 30!"
- light.turn_off: my_light
Configuration variables:
- **condition** (**Required**, :ref:`Condition <config-condition>`): The condition to check to determine which branch to take.
- **then** (*Optional*, :ref:`Action <config-action>`): The action to perform if the condition evaluates to true.
Defaults to doing nothing.
- **else** (*Optional*, :ref:`Action <config-action>`): The action to perform if the condition evaluates to false.
Defaults to doing nothing.
.. _lambda_action:
``lambda`` Action
*****************
This action executes an arbitrary piece of C++ code (see :ref:`Lambda <config-lambda>`).
.. code-block:: yaml
on_...:
then:
- lambda: |-
id(some_binary_sensor).publish_state(false);
.. _repeat_action:
``repeat`` Action
*****************
This action allows you to repeat a block a given number of times.
For example, the automation below will flash the light five times.
.. code-block:: yaml
on_...:
- repeat:
count: 5
then:
- light.turn_on: some_light
- delay: 1s
- light.turn_off: some_light
- delay: 10s
Configuration variables:
- **count** (**Required**, int): The number of times the action should be repeated.
- **then** (**Required**, :ref:`Action <config-action>`): The action to repeat.
.. _wait_until_action:
``wait_until`` Action
*********************
This action allows your automations to wait until a condition evaluates to true. (So this is just
a shorthand way of writing a ``while`` action with an empty ``then`` block.)
.. code-block:: yaml
# In a trigger:
on_...:
- logger.log: "Waiting for binary sensor"
- wait_until:
binary_sensor.is_on: some_binary_sensor
- logger.log: "Binary sensor is ready"
If you want to use a timeout, the term "condition" is required:
.. code-block:: yaml
# In a trigger:
on_...:
- logger.log: "Waiting for binary sensor"
- wait_until:
condition:
binary_sensor.is_on: some_binary_sensor
timeout: 8s
- logger.log: "Binary sensor might be ready"
Configuration variables:
- **condition** (**Required**, :ref:`Condition <config-condition>`): The condition to wait to become true.
- **timeout** (*Optional*, :ref:`config-time`): Time to wait before timing out. Defaults to never timing out.
.. _while_action:
``while`` Action
****************
This action is similar to the :ref:`if <if_action>` Action. The ``while`` action loops
through a block as long as the given condition is true.
.. code-block:: yaml
# In a trigger:
on_...:
- while:
condition:
binary_sensor.is_on: some_binary_sensor
then:
- logger.log: "Still executing"
- light.toggle: some_light
- delay: 5s
Configuration variables:
- **condition** (**Required**, :ref:`Condition <config-condition>`): The condition to check to determine whether or not to execute.
- **then** (**Required**, :ref:`Action <config-action>`): The action to perform until the condition evaluates to false.
.. _component-update_action:
``component.update`` Action
***************************
Using this action you can manually call the ``update()`` method of a component.
Please note that this only works with some component types and others will result in a
compile error.
.. code-block:: yaml
on_...:
then:
- component.update: my_component
# The same as:
- lambda: 'id(my_component).update();'
.. _component-suspend_action:
``component.suspend`` Action
****************************
Using this action you can manually call the ``stop_poller()`` method of a component.
After this action the component will stop being refreshed.
While the poller is suspendend, it's still possible to trigger on-demand updates by
using :ref:`component.update <component-update_action>`
Please note that this only works with PollingComponent types and others will result in a
compile error.
.. code-block:: yaml
on_...:
then:
- component.suspend: my_component
# The same as:
- lambda: 'id(my_component).stop_poller();'
.. _component-resume_action:
``component.resume`` Action
***************************
Using this action you can manually call the ``start_poller()`` method of a component.
After this action the component will refresh at the original update_interval rate
This will allow the component to resume automatic update at the defined interval.
This action also allows to change the update interval, calling it without suspend,
replace the poller directly.
Please note that this only works with PollingComponent types and others will result in a
compile error.
.. code-block:: yaml
on_...:
then:
- component.resume: my_component
# The same as:
- lambda: 'id(my_component).start_poller();'
# Change the poller interval
on_...:
then:
- component.resume:
id: my_component
update_interval: 15s
.. _common_conditions:
Common Conditions
-----------------
"Conditions" provide a way for your device to take an action only when a specific (set of) condition(s) is satisfied.
.. _and_condition:
.. _or_condition:
.. _xor_condition:
.. _not_condition:
``and`` / ``or`` / ``xor`` / ``not`` Condition
**********************************************
Check a combination of conditions
.. code-block:: yaml
on_...:
then:
- if:
condition:
# Same syntax for `and` as well as `xor` conditions
or:
- binary_sensor.is_on: some_binary_sensor
- binary_sensor.is_on: other_binary_sensor
# ...
- if:
condition:
not:
binary_sensor.is_off: some_binary_sensor
.. _for_condition:
``for`` Condition
*****************
Allows you to check if a given condition has been true for at least a given amount of time.
.. code-block:: yaml
on_...:
if:
condition:
for:
time: 5min
condition:
api.connected:
then:
- logger.log: API has stayed connected for at least 5 minutes!
Configuration variables:
- **time** (**Required**, :ref:`templatable <config-templatable>`, :ref:`config-time`):
The time for which the condition has to have been true.
- **condition** (**Required**, :ref:`condition<config-condition>`): The condition to check.
.. _lambda_condition:
``lambda`` Condition
********************
This condition performs an arbitrary piece of C++ code (see :ref:`Lambda <config-lambda>`)
and can be used to create conditional flow in actions.
.. code-block:: yaml
on_...:
then:
- if:
condition:
# Should return either true or false
lambda: |-
return id(some_sensor).state < 30;
# ...
.. _config-action:
All Actions
-----------
*See the respective component's page(s) for more detail.*
See also: :ref:`common-actions`.
.. include:: all_actions.rst
.. _config-condition:
All Conditions
--------------
*See the respective component's page(s) for more detail.*
See also: :ref:`common_conditions`.
.. include:: all_conditions.rst
.. _tips-and-tricks:
Tips and Tricks
---------------
.. _automation-networkless:
Do Automations Work Without a Network Connection
************************************************
This is a common question and the answer is **YES!** All automations you define in ESPHome are executed on the
microcontroller itself and will continue to work even if the Wi-Fi network is down or the MQTT server is not reachable.
There is one caveat though: ESPHome will automatically reboot periodically if no connection is made to its API. This
helps in the event that there is an issue in the device's network stack preventing it from being reachable on the
network. You can adjust this behavior (or even disable automatic rebooting) using the ``reboot_timeout`` option in any
of the following components:
- :doc:`/components/wifi`
- :doc:`/components/api`
- :doc:`/components/mqtt`
Beware, however, that disabling the reboot timeout(s) effectively disables the reboot watchdog, so you will need to
power-cycle the device if it proves to be/remain unreachable on the network.
.. _timers-timeouts:
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 different wall switches
- script.execute: hallway_light_script
Sometimes you'll also need a timer which does not perform any action; in this case, you can use a single ``delay``
action and then (in your automation) use the ``script.is_running`` condition to know if your "timer" is active or not.
See Also
--------
- :doc:`index`
- :doc:`templates`
- :ghedit:`Edit`

View File

@ -0,0 +1,76 @@
- **ags10:** ``new_i2c_address``, ``set_zero_point``
- **alarm_control_panel:** ``arm_away``, ``arm_home``, ``arm_night``, ``chime``, ``disarm``, ``pending``, ``ready``, ``triggered``
- **animation:** ``next_frame``, ``prev_frame``, ``set_frame``
- **at581x:** ``reset``, ``settings``
- **ble:** ``disable``, ``enable``
- **ble_client:** ``ble_write``, ``connect``, ``disconnect``, ``numeric_comparison_reply``, ``passkey_reply``, ``remove_bond``
- **bluetooth_password:** ``set``
- **button:** ``press``
- **canbus:** ``send``
- **climate:** ``control``
- **component:** ``resume``, ``suspend``, ``update``
- **cover:** ``close``, ``control``, ``open``, ``stop``, ``toggle``
- **cs5460a:** ``restart``
- **deep_sleep:** ``allow``, ``enter``, ``prevent``
- **dfplayer:** ``pause``, ``play``, ``play_folder``, ``play_mp3``, ``play_next``, ``play_previous``, ``random``, ``reset``, ``set_device``, ``set_eq``, ``set_volume``, ``sleep``, ``start``, ``stop``, ``volume_down``, ``volume_up``
- **dfrobot_sen0395:** ``reset``, ``settings``
- **display_menu:** ``down``, ``enter``, ``hide``, ``left``, ``right``, ``show``, ``show_main``, ``up``
- **ds1307:** ``read_time``, ``write_time``
- **esp32_ble_tracker:** ``start_scan``, ``stop_scan``
- **event:** ``trigger``
- **ezo_pmp:** ``arbitrary_command``, ``change_i2c_address``, ``clear_calibration``, ``clear_total_volume_dosed``, ``dose_continuously``, ``dose_volume``, ``dose_volume_over_time``, ``dose_with_constant_flow_rate``, ``find``, ``pause_dosing``, ``set_calibration_volume``, ``stop_dosing``
- **fan:** ``cycle_speed``, ``toggle``, ``turn_off``, ``turn_on``
- **fingerprint_grow:** ``aura_led_control``, ``cancel_enroll``, ``delete``, ``delete_all``, ``enroll``, ``led_control``
- **globals:** ``set``
- **grove_tb6612fng:** ``break``, ``change_address``, ``no_standby``, ``run``, ``standby``, ``stop``
- **homeassistant:** ``event``, ``service``, ``tag_scanned``
- **http_request:** ``get``, ``post``, ``send``
- **htu21d:** ``set_heater``, ``set_heater_level``
- **light:** ``addressable_set``, ``control``, ``dim_relative``, ``toggle``, ``turn_off``, ``turn_on``
- **lightwaverf:** ``send_raw``
- **lock:** ``lock``, ``open``, ``unlock``
- **logger:** ``log``
- **max6956:** ``set_brightness_global``, ``set_brightness_mode``
- **media_player:** ``pause``, ``play``, ``play_media``, ``stop``, ``toggle``, ``volume_down``, ``volume_set``, ``volume_up``
- **mhz19:** ``abc_disable``, ``abc_enable``, ``calibrate_zero``
- **micro_wake_word:** ``start``, ``stop``
- **microphone:** ``capture``, ``stop_capture``
- **midea_ac:** ``beeper_off``, ``beeper_on``, ``display_toggle``, ``follow_me``, ``power_off``, ``power_on``, ``power_toggle``, ``swing_step``
- **mqtt:** ``publish``, ``publish_json``
- **number:** ``decrement``, ``increment``, ``operation``, ``set``, ``to_max``, ``to_min``
- **output:** ``set_level``, ``turn_off``, ``turn_on``
- **pcf85063:** ``read_time``, ``write_time``
- **pcf8563:** ``read_time``, ``write_time``
- **pmwcs3:** ``air_calibration``, ``new_i2c_address``, ``water_calibration``
- **pulse_counter:** ``set_total_pulses``
- **pulse_meter:** ``set_total_pulses``
- **pzemac:** ``reset_energy``
- **pzemdc:** ``reset_energy``
- **remote_transmitter:** ``transmit_abbwelcome``, ``transmit_aeha``, ``transmit_byronsx``, ``transmit_canalsat``, ``transmit_canalsatld``, ``transmit_coolix``, ``transmit_dish``, ``transmit_dooya``, ``transmit_drayton``, ``transmit_haier``, ``transmit_jvc``, ``transmit_keeloq``, ``transmit_lg``, ``transmit_magiquest``, ``transmit_midea``, ``transmit_mirage``, ``transmit_nec``, ``transmit_nexa``, ``transmit_panasonic``, ``transmit_pioneer``, ``transmit_pronto``, ``transmit_raw``, ``transmit_rc5``, ``transmit_rc6``, ``transmit_rc_switch_raw``, ``transmit_rc_switch_type_a``, ``transmit_rc_switch_type_b``, ``transmit_rc_switch_type_c``, ``transmit_rc_switch_type_d``, ``transmit_roomba``, ``transmit_samsung``, ``transmit_samsung36``, ``transmit_sony``, ``transmit_toshiba_ac``
- **rf_bridge:** ``beep``, ``learn``, ``send_advanced_code``, ``send_code``, ``send_raw``, ``start_advanced_sniffing``, ``start_bucket_sniffing``, ``stop_advanced_sniffing``
- **rtttl:** ``play``, ``stop``
- **scd30:** ``force_recalibration_with_reference``
- **scd4x:** ``factory_reset``, ``perform_forced_calibration``
- **script:** ``execute``, ``stop``, ``wait``
- **select:** ``first``, ``last``, ``next``, ``operation``, ``previous``, ``set``, ``set_index``
- **sen5x:** ``start_fan_autoclean``
- **senseair:** ``abc_disable``, ``abc_enable``, ``abc_get_period``, ``background_calibration``, ``background_calibration_result``
- **servo:** ``detach``, ``write``
- **sim800l:** ``connect``, ``dial``, ``disconnect``, ``send_sms``, ``send_ussd``
- **speaker:** ``play``, ``stop``
- **sprinkler:** ``clear_queued_valves``, ``next_valve``, ``pause``, ``previous_valve``, ``queue_valve``, ``resume``, ``resume_or_start_full_cycle``, ``set_divider``, ``set_multiplier``, ``set_repeat``, ``set_valve_run_duration``, ``shutdown``, ``start_from_queue``, ``start_full_cycle``, ``start_single_valve``
- **sps30:** ``start_fan_autoclean``
- **stepper:** ``report_position``, ``set_acceleration``, ``set_deceleration``, ``set_speed``, ``set_target``
- **switch:** ``toggle``, ``turn_off``, ``turn_on``
- **tag:** ``emulation_off``, ``emulation_on``, ``polling_off``, ``polling_on``, ``set_clean_mode``, ``set_emulation_message``, ``set_format_mode``, ``set_read_mode``, ``set_write_message``, ``set_write_mode``
- **text:** ``set``
- **tm1651:** ``set_brightness``, ``set_level``, ``set_level_percent``, ``turn_off``, ``turn_on``
- **uart:** ``write``
- **ufire_ec:** ``calibrate_probe``, ``reset``
- **ufire_ise:** ``calibrate_probe_high``, ``calibrate_probe_low``, ``reset``
- **update:** ``perform``
- **valve:** ``close``, ``control``, ``open``, ``stop``, ``toggle``
- **voice_assistant:** ``start``, ``start_continuous``, ``stop``
- **wifi:** ``disable``, ``enable``
- **wireguard:** ``disable``, ``enable``

View File

@ -0,0 +1,31 @@
- **alarm_control_panel:** ``is_armed``, ``ready``
- **api:** ``connected``
- **binary_sensor:** ``is_off``, ``is_on``
- **ble:** ``enabled``
- **dfplayer:** ``is_playing``
- **display:** ``is_displaying_page``
- **display_menu:** ``is_active``
- **fan:** ``is_off``, ``is_on``
- **light:** ``is_off``, ``is_on``
- **lock:** ``is_locked``, ``is_unlocked``
- **media_player:** ``is_idle``, ``is_playing``
- **micro_wake_word:** ``is_running``
- **microphone:** ``is_capturing``
- **mqtt:** ``connected``
- **number:** ``in_range``
- **pn532:** ``is_writing``
- **pn7150:** ``is_writing``
- **pn7160:** ``is_writing``
- **rtttl:** ``is_playing``
- **script:** ``is_running``
- **sensor:** ``in_range``
- **speaker:** ``is_playing``
- **sun:** ``is_above_horizon``, ``is_below_horizon``
- **switch:** ``is_off``, ``is_on``
- **text_sensor:** ``state``
- **time:** ``has_time``
- **update:** ``is_available``
- **voice_assistant:** ``connected``, ``is_running``
- **wifi:** ``connected``, ``enabled``
- **wireguard:** ``enabled``, ``peer_online``

32
automations/index.rst Normal file
View File

@ -0,0 +1,32 @@
.. _automation:
Automation
==========
.. seo::
:description: Getting started guide for automations in ESPHome
:image: auto-fix.svg
Automations are a very powerful aspect of ESPHome; they allow you to easily perform actions given some condition(s).
When you want your ESPHome device to respond to its environment, you use an automation. Here are some examples:
- Switch on a light when the cover is opened
- Transmit an infrared (IR) code when I press this button
- Turn on the heat when the temperature drops
This page serves as an index which will walk to through the process of using ESPHome automations--actions, triggers,
templates, and more--to customize your ESPHome device just how you like it.
- :doc:`actions`
- :doc:`templates`
- :doc:`/components/globals`
- :doc:`/components/script`
- :doc:`/components/interval`
.. toctree::
:glob:
:maxdepth: 1
:hidden:
*

117
automations/templates.rst Normal file
View File

@ -0,0 +1,117 @@
.. _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`

View File

@ -0,0 +1,45 @@
#!/usr/bin/env python3
import argparse
import json
if __name__ == "__main__":
file_name = "all_automations.json"
arg_choices = ["actions", "conditions", "pin_providers"]
parser = argparse.ArgumentParser()
parser.add_argument(
"-t",
"--type",
choices=arg_choices,
help="Automation type to extract ('actions', 'conditions', 'pin_providers')",
)
args = parser.parse_args()
with open(file_name) as json_file:
raw_json = json.load(json_file)
if args.type not in arg_choices:
print("Unrecognized automation type")
exit()
automation_list = raw_json[args.type]
component_dict = {}
for item in automation_list:
parts = item.split(".")
if len(parts) == 2:
if parts[0] not in component_dict:
component_dict[parts[0]] = []
component_dict[parts[0]].append(parts[1])
out_str = ""
for comp, autos in component_dict.items():
out_str += f"- **{comp}:** "
for item in autos:
out_str += f"``{item}``, "
out_str = out_str[:-2] + "\n"
print(out_str)

View File

@ -27,6 +27,6 @@ Configuration variables:
See Also
--------
- :doc:`/guides/automations`
- :doc:`/automations/index`
- :doc:`/components/button/index`
- :ghedit:`Edit`

View File

@ -26,6 +26,6 @@ Configuration variables:
See Also
--------
- :doc:`/guides/automations`
- :doc:`/automations/index`
- :doc:`/components/event/index`
- :ghedit:`Edit`

79
components/globals.rst Normal file
View File

@ -0,0 +1,79 @@
.. _config-globals:
Global Variables
----------------
In some cases you might need to share a global variable across multiple lambdas. For example, global variables can be
used to store the state of a garage door.
.. code-block:: yaml
# Example configuration entry
globals:
- id: my_global_int
type: int
restore_value: no
initial_value: '0'
# Example for global string variable
- id: my_global_string
type: std::string
restore_value: yes
max_restore_data_length: 24
initial_value: '"Global value is"'
# In an automation
on_...:
then:
- lambda: |-
if (id(my_global_int) > 5) {
// global value is greater than 5
id(my_global_int) += 1;
} else {
id(my_global_int) += 10;
}
ESP_LOGD(TAG, "%s: %d", id(my_global_string).c_str(), id(my_global_int));
Configuration variables:
- **id** (**Required**, :ref:`config-id`): Give the global variable an ID so that you can refer
to it later in :ref:`lambdas <config-lambda>`.
- **type** (**Required**, string): The C++ type of the global variable, for example ``bool`` (for ``true``/``false``),
``int`` (for integers), ``float`` (for decimal numbers), ``int[50]`` for an array of 50 integers, etc.
- **restore_value** (*Optional*, boolean): Whether to try to restore the state on boot up.
Be careful: on the ESP8266, you only have a total of 96 bytes available for this! Defaults to ``no``.
This will use storage in "RTC memory", so it won't survive a power-cycle unless you use the ``esp8266_restore_from_flash`` option to save to flash. See :doc:`esp8266_restore_from_flash </components/esphome>` for details.
- **max_restore_data_length** (*Optional*, integer): Only applies to variables of type ``std::string``. ESPHome will allocate enough space for this many characters,
plus single character of overhead. Strings longer than this will not be saved. The max value of this variable is 254 characters, and the default is 63 characters.
- **initial_value** (*Optional*, string): The value with which to initialize this variable if the state
can not be restored or if state restoration is not enabled. This needs to be wrapped in quotes! Defaults to
the C++ default value for this type (for example ``0`` for integers).
.. _globals-set_action:
``globals.set`` Action
----------------------
This :ref:`Action <config-action>` allows you to change the value of a :ref:`global <config-globals>`
variable without having to use the lambda syntax.
.. code-block:: yaml
on_...:
- globals.set:
id: my_global_var
value: '10'
Configuration variables:
- **id** (**Required**, :ref:`config-id`): The :ref:`config-id` of the global variable to set.
- **value** (**Required**, :ref:`templatable <config-templatable>`): The value to set the global
variable to.
See Also
--------
- :doc:`index`
- :doc:`/automations/actions`
- :doc:`/automations/templates`
- :ghedit:`Edit`

34
components/interval.rst Normal file
View File

@ -0,0 +1,34 @@
.. _interval:
``interval`` Component
----------------------
This component allows you to run actions at fixed time intervals. For example, if you want to toggle a switch every
minute, you can use this component. Please note that it's possible to achieve the same thing with the
:ref:`time.on_time <time-on_time>` trigger, but this technique is more light-weight and user-friendly.
.. code-block:: yaml
# Example configuration entry
interval:
- interval: 1min
then:
- switch.toggle: relay_1
If a startup delay is configured, the first execution of the actions will not occur before at least that time after boot.
Configuration variables:
************************
- **interval** (**Required**, :ref:`config-time`): The interval to execute the action with.
- **startup_delay** (*Optional*, :ref:`config-time`): An optional startup delay - defaults to zero.
- **then** (**Required**, :ref:`Action <config-action>`): The action to perform.
See Also
--------
- :doc:`index`
- :doc:`/automations/actions`
- :doc:`/automations/templates`
- :ghedit:`Edit`

View File

@ -106,7 +106,7 @@ Configuration options:
See Also
--------
- :doc:`/guides/automations`
- :doc:`/automations/index`
- :doc:`/components/lock/index`
- :doc:`/components/binary_sensor/index`
- :apiref:`template/lock/template_lock.h`

187
components/script.rst Normal file
View File

@ -0,0 +1,187 @@
.. _scripts:
``script`` Component
--------------------
ESPHome's ``script`` component allows you to define a list of steps (actions) in a central place. You can then execute
the script from nearly anywhere in your device's configuration with a single call.
.. code-block:: yaml
# Example configuration entry
script:
- id: my_script
then:
- switch.turn_on: my_switch
- delay: 1s
- switch.turn_off: my_switch
Configuration variables:
- **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*, int): Allows limiting the maximum number of runs when using script modes ``queued`` and
``parallel``, use value ``0`` for unlimited runs. Defaults to ``0``.
- **parameters** (*Optional*, :ref:`Script Parameters <script-parameters>`): A script can define one or more parameters
that must be provided in order to execute. All parameters defined here are mandatory and must be given when calling
the script.
- **then** (**Required**, :ref:`Action <config-action>`): The action to perform.
.. _script-parameters:
Script Parameters
-----------------
Scripts can be defined with parameters. The arguments given when calling the script can be used within the script's
lambda actions. To define the parameters, add the parameter names under the ``parameters:`` key and specify the data
type for that parameter.
Supported data types:
* ``bool``: A boolean true/false. C++ type: ``bool``
* ``int``: An integer. C++ type: ``int32_t``
* ``float``: A floating point number. C++ type: ``float``
* ``string``: A string. C++ type: ``std::string``
Each of these also exist in array form:
* ``bool[]``: An array of boolean values. C++ type: ``std::vector<bool>``
* Same for other types.
.. code-block:: yaml
script:
- id: blink_light
parameters:
delay_ms: int
then:
- light.turn_on: status_light
# The param delay_ms is accessible using a lambda
- delay: !lambda return delay_ms;
- light.turn_off: status_light
.. _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:
- script.execute: my_script
# Calling a non-parameterised script in a lambda
- lambda: id(my_script).execute();
# Calling a script with parameters
- script.execute:
id: blink_light
delay_ms: 500
# Calling a parameterised script inside a lambda
- lambda: id(blink_light)->execute(1000);
.. _script-stop_action:
``script.stop`` Action
----------------------
This action allows you to stop a given script during execution. If the script is not running, it does nothing. This is
useful if you 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
# Example configuration entry
script:
- id: my_script
then:
- switch.turn_on: my_switch
- delay: 1s
- switch.turn_off: my_switch
# in a trigger:
on_...:
then:
- script.stop: my_script
...or as lambda:
.. code-block:: yaml
lambda: 'id(my_script).stop();'
.. _script-wait_action:
``script.wait`` Action
----------------------
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 in
parallel, this will block until all of them have terminated.
.. code-block:: yaml
# Example configuration entry
script:
- id: my_script
then:
- switch.turn_on: my_switch
- delay: 1s
- switch.turn_off: my_switch
# in a trigger:
on_...:
then:
- script.execute: my_script
- script.wait: my_script
This can't be used in a lambda as it would block all functioning of the device. The script wouldn't even get to run.
.. _script-is_running_condition:
``script.is_running`` Condition
-------------------------------
This :ref:`condition <config-condition>` allows you to check if a given script is running. 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. Not
designed for use with :ref:`while <while_action>`; instead try :ref:`script.wait <script-wait_action>`.
.. code-block:: yaml
on_...:
if:
condition:
- script.is_running: my_script
then:
- logger.log: Script is running!
...or as lambda:
.. code-block:: yaml
lambda: |-
if (id(my_script).is_running()) {
ESP_LOGI("main", "Script is running!");
}
See Also
--------
- :doc:`index`
- :doc:`/automations/actions`
- :doc:`/automations/templates`
- :ghedit:`Edit`

View File

@ -97,7 +97,7 @@ Configuration options:
See Also
--------
- :doc:`/guides/automations`
- :doc:`/automations/index`
- :doc:`/components/switch/index`
- :doc:`/components/binary_sensor/index`
- :apiref:`template/switch/template_switch.h`

View File

@ -44,7 +44,7 @@ for a short period of time, the close/open action begins.
See Also
--------
- :doc:`/guides/automations`
- :doc:`/automations/index`
- :doc:`/components/switch/gpio`
- :doc:`/components/cover/template`
- :ghedit:`Edit`

File diff suppressed because it is too large Load Diff

View File

@ -61,7 +61,7 @@ ESPHome is a system to control your microcontrollers by simple yet powerful conf
</a>
</li>
<li>
<a class="reference" href="/guides/automations.html">
<a class="reference" href="/automations/index.html">
Automations
</a>
</li>
@ -143,6 +143,19 @@ Peripherals which directly support the operation of the microcontroller's proces
PSRAM, components/psram, psram.svg
Deep Sleep, components/deep_sleep, hotel.svg, dark-invert
ESPHome Automations
-------------------
*"When this happens, I want it to do that..."*
Automations are how we customize ESPHome devices to respond/behave exactly how you want them to.
.. imgtable::
Overview, automations/index, description.svg, dark-invert
"Actions, Triggers, Conditions", automations/actions, description.svg, dark-invert
Templates, automations/templates, description.svg, dark-invert
ESPHome Components
------------------
@ -155,8 +168,11 @@ ESPHome-specific components or components supporting ESPHome device provisioning
Copy, components/copy, content-copy.svg, dark-invert
Demo, components/demo, description.svg, dark-invert
External Components, components/external_components, external_components.svg, dark-invert
Globals, components/globals, description.svg, dark-invert
Improv via BLE, components/esp32_improv, improv.svg, dark-invert
Improv via Serial, components/improv_serial, improv.svg, dark-invert
Interval, components/interval, description.svg, dark-invert
Scripts, components/scripts, description.svg, dark-invert
Network Hardware
----------------
@ -1109,6 +1125,7 @@ If you'd like to share configurations for specific devices, please contribute to
:hidden:
web-api/index
automations/index
components/index
cookbook/index
guides/index

View File

@ -89,7 +89,7 @@ PLATFORMS_TITLES = {
}
CUSTOM_DOCS = {
"guides/automations": {
"components/globals": {
"Global Variables": "globals.schemas.CONFIG_SCHEMA",
},
"guides/configuration-types": {