mirror of
https://github.com/esphome/esphome-docs.git
synced 2024-12-25 17:17:54 +01:00
Merge branch 'current' into next
This commit is contained in:
commit
48ab2916b4
421
all_automations.json
Normal file
421
all_automations.json
Normal 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
558
automations/actions.rst
Normal 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`
|
76
automations/all_actions.rst
Normal file
76
automations/all_actions.rst
Normal 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``
|
||||
|
31
automations/all_conditions.rst
Normal file
31
automations/all_conditions.rst
Normal 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
32
automations/index.rst
Normal 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
117
automations/templates.rst
Normal 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`
|
45
build_automations_pages.py
Normal file
45
build_automations_pages.py
Normal 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)
|
@ -27,6 +27,6 @@ Configuration variables:
|
||||
See Also
|
||||
--------
|
||||
|
||||
- :doc:`/guides/automations`
|
||||
- :doc:`/automations/index`
|
||||
- :doc:`/components/button/index`
|
||||
- :ghedit:`Edit`
|
||||
|
@ -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
79
components/globals.rst
Normal 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
34
components/interval.rst
Normal 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`
|
@ -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
187
components/script.rst
Normal 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`
|
@ -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`
|
||||
|
@ -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
19
index.rst
19
index.rst
@ -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
|
||||
|
@ -89,7 +89,7 @@ PLATFORMS_TITLES = {
|
||||
}
|
||||
|
||||
CUSTOM_DOCS = {
|
||||
"guides/automations": {
|
||||
"components/globals": {
|
||||
"Global Variables": "globals.schemas.CONFIG_SCHEMA",
|
||||
},
|
||||
"guides/configuration-types": {
|
||||
|
Loading…
Reference in New Issue
Block a user