A smart home without automations is just a collection of sensors and switches with a fancy dashboard. Automations are what make it smart -- they let your home react to conditions without you lifting a finger. In this article, you will learn how to create Home Assistant automations that use your ESP32 sensor data as triggers and control your ESP32 actuators as actions.
🔗The Trigger-Condition-Action Model
Every Home Assistant automation follows a three-part structure:
graph LR
T[Trigger] --> C{Condition}
C -->|passes| A[Action]
C -->|fails| N[Nothing happens]- Trigger -- what starts the automation. "Temperature rises above 28 degrees," "motion detected," "time is 7:00 AM."
- Condition (optional) -- additional checks that must pass. "Only if it is a weekday," "only between sunset and sunrise."
- Action -- what happens. "Turn on the fan," "send a notification," "turn off the lights."
An automation can have multiple triggers (any one of them can start it), multiple conditions (all must be true), and multiple actions (they run in sequence).
🔗Creating Automations: UI vs. YAML
Home Assistant offers two ways to create automations:
🔗The Visual Editor (UI)
- Go to Settings > Automations & Scenes > Create Automation.
- Click Create new automation.
- Use the visual editor to select triggers, conditions, and actions from dropdown menus.
The UI editor is excellent for getting started. It shows all available options and validates your configuration as you build it.
🔗YAML
You can also write automations directly in YAML, either in the automation editor (click the three-dot menu and select Edit in YAML) or in your automations.yaml file.
YAML gives you more control and is easier to copy, share, and version-control. All the examples in this article show both approaches where practical.
🔗Example 1: Turn On Fan When Temperature Is High
This automation turns on a relay-controlled fan when the temperature from your ESP32 BME280 sensor exceeds $28\,\text{°C}$, and turns it off when it drops below $25\,\text{°C}$.
🔗UI Steps
- Trigger: Select Numeric state > Entity:
sensor.office_sensor_temperature> Above:28 - Action: Select Call service > Service:
switch.turn_on> Entity:switch.office_relay
Then create a second automation for turning it off:
- Trigger: Numeric state > Entity:
sensor.office_sensor_temperature> Below:25 - Action: Call service >
switch.turn_off> Entity:switch.office_relay
🔗YAML
- alias: "Turn on fan when temperature is high"
description: "Activates the fan relay when office temperature exceeds 28°C"
trigger:
- platform: numeric_state
entity_id: sensor.office_sensor_temperature
above: 28
action:
- service: switch.turn_on
target:
entity_id: switch.office_relay
- alias: "Turn off fan when temperature drops"
description: "Deactivates the fan relay when office temperature drops below 25°C"
trigger:
- platform: numeric_state
entity_id: sensor.office_sensor_temperature
below: 25
action:
- service: switch.turn_off
target:
entity_id: switch.office_relayWhy different thresholds (28 on, 25 off)? This creates a $3\,\text{°C}$ hysteresis band that prevents the fan from rapidly switching on and off when the temperature hovers around a single threshold. Without hysteresis, you would get annoying on-off-on-off cycling.
🔗Example 2: Motion-Activated Lights
This automation turns on a light when a PIR motion sensor detects movement, and turns it off 5 minutes after the last motion event.
🔗YAML
- alias: "Motion-activated hallway light"
description: "Turns on the hallway light on motion, off after 5 minutes of no motion"
trigger:
- platform: state
entity_id: binary_sensor.hallway_motion
to: "on"
condition:
- condition: sun
after: sunset
before: sunrise
action:
- service: light.turn_on
target:
entity_id: light.hallway_light
data:
brightness_pct: 80
- wait_for_trigger:
- platform: state
entity_id: binary_sensor.hallway_motion
to: "off"
for:
minutes: 5
- service: light.turn_off
target:
entity_id: light.hallway_lightThis automation uses several important concepts:
- Sun condition: The light only activates between sunset and sunrise. During the day, motion is ignored.
wait_for_trigger: Instead of a fixed timer, the automation waits for the motion sensor to stay "off" for 5 minutes. Every new motion event resets the timer.- Brightness: The
brightness_pctparameter sets the light to 80% brightness.
🔗Example 3: Soil Moisture Notification
Send a push notification to your phone when the garden soil moisture drops below 20%:
🔗YAML
- alias: "Low soil moisture alert"
description: "Sends a notification when garden soil is too dry"
trigger:
- platform: numeric_state
entity_id: sensor.garden_sensor_node_soil_moisture
below: 20
for:
minutes: 30
condition:
- condition: time
after: "08:00:00"
before: "22:00:00"
action:
- service: notify.mobile_app_your_phone
data:
title: "Garden needs water"
message: >
Soil moisture is {{ states('sensor.garden_sensor_node_soil_moisture') }}%.
Time to water the plants!
data:
tag: "soil-moisture"Key details:
for: minutes: 30-- the soil moisture must stay below 20% for 30 minutes before the automation triggers. This prevents false alerts from a single bad reading.- Time condition -- notifications are only sent between 8 AM and 10 PM. Nobody wants a plant watering alert at 3 AM.
tag-- the notification tag ensures that repeated alerts replace each other instead of stacking up on your phone.- Templates -- the
{{ states(...) }}syntax inserts the current sensor value into the message. Home Assistant uses Jinja2 templates for dynamic content.
🔗Example 4: Lights at Sunset
Turn on outdoor lights at sunset and off at sunrise:
🔗YAML
- alias: "Outdoor lights at sunset"
description: "Turns on garden lights at sunset"
trigger:
- platform: sun
event: sunset
offset: "-00:15:00"
action:
- service: switch.turn_on
target:
entity_id: switch.garden_lights
- alias: "Outdoor lights off at sunrise"
description: "Turns off garden lights at sunrise"
trigger:
- platform: sun
event: sunrise
offset: "00:15:00"
action:
- service: switch.turn_off
target:
entity_id: switch.garden_lightsThe offset field adjusts the trigger time relative to the sun event. "-00:15:00" means 15 minutes before sunset (so lights come on while it is still getting dark), and "00:15:00" means 15 minutes after sunrise (so lights stay on until it is fully light).
🔗Example 5: Time-Based Automation with Multiple Actions
Run a morning routine at 7:00 AM on weekdays:
🔗YAML
- alias: "Weekday morning routine"
description: "Activates morning settings on weekday mornings"
trigger:
- platform: time
at: "07:00:00"
condition:
- condition: time
weekday:
- mon
- tue
- wed
- thu
- fri
action:
- service: light.turn_on
target:
entity_id: light.kitchen_light
data:
brightness_pct: 100
color_temp_kelvin: 5000
- service: switch.turn_on
target:
entity_id: switch.coffee_maker
- delay:
minutes: 30
- service: switch.turn_off
target:
entity_id: switch.coffee_makerThis shows multiple sequential actions: turn on the kitchen light at full brightness (cool white for alertness), start the coffee maker, wait 30 minutes, then turn off the coffee maker.
🔗Scenes
A scene captures the state of multiple devices and lets you activate them all at once. Think of it as a snapshot of how you want things to look.
🔗Creating a Scene in the UI
- Go to Settings > Automations & Scenes > Scenes.
- Click Add Scene.
- Give it a name (e.g., "Movie Night").
- Add entities and set their desired states.
🔗Scene YAML Example
- name: "Movie Night"
entities:
light.living_room:
state: "on"
brightness: 30
color_temp_kelvin: 2700
light.kitchen_light:
state: "off"
switch.tv_backlight:
state: "on"
- name: "All Lights Off"
entities:
light.living_room:
state: "off"
light.kitchen_light:
state: "off"
light.bedroom:
state: "off"
switch.garden_lights:
state: "off"Activate a scene from an automation:
action:
- service: scene.turn_on
target:
entity_id: scene.movie_nightScenes are useful for creating presets that you can trigger manually from the dashboard, from an automation, or via voice commands.
🔗Notification Actions
Home Assistant can send notifications through several channels:
🔗Mobile Push Notifications
Requires the Home Assistant Companion App on your phone:
action:
- service: notify.mobile_app_your_phone
data:
title: "Alert Title"
message: "Alert message body"🔗Actionable Notifications
Push notifications with buttons that trigger automations:
action:
- service: notify.mobile_app_your_phone
data:
title: "Garden is dry"
message: "Soil moisture is low. Water the garden?"
data:
actions:
- action: "WATER_GARDEN"
title: "Water Now"
- action: "DISMISS"
title: "Dismiss"Then create a separate automation to handle the button press:
- alias: "Handle water garden notification action"
trigger:
- platform: event
event_type: mobile_app_notification_action
event_data:
action: "WATER_GARDEN"
action:
- service: switch.turn_on
target:
entity_id: switch.garden_pump
- delay:
minutes: 10
- service: switch.turn_off
target:
entity_id: switch.garden_pump🔗Telegram Notifications
For a free, self-hosted alternative to push notifications, you can use Telegram:
- Create a Telegram bot via @BotFather.
- Add the Telegram integration in Home Assistant.
- Use the
notify.telegramservice:
action:
- service: notify.telegram
data:
title: "Home Alert"
message: "Motion detected in the garden at {{ now().strftime('%H:%M') }}"🔗Debugging Automations
When an automation does not work as expected, Home Assistant provides tools to figure out why.
🔗Automation Traces
Every time an automation runs (or attempts to run), Home Assistant records a trace:
- Go to Settings > Automations & Scenes.
- Click on the automation.
- Click Traces (top right).
The trace shows:
- Whether the automation was triggered
- Which trigger fired
- Whether each condition passed or failed
- What actions were executed
- Any errors that occurred
This is the most valuable debugging tool. If a condition failed, the trace shows exactly which one and why.
🔗Developer Tools
Use Developer Tools > States to check the current state of any entity. This helps verify that your trigger entity has the value you expect.
Use Developer Tools > Services to test actions manually. You can call switch.turn_on on a specific entity to verify it works before putting it in an automation.
🔗Logbook
The Logbook (in the sidebar) shows a chronological list of all state changes and automation executions. Useful for verifying that events happened in the expected order.
🔗Common Debugging Issues
| Problem | Cause | Solution |
|---|---|---|
| Automation never triggers | Entity ID is wrong | Check the exact entity ID in Developer Tools > States |
| Automation triggers but action fails | Service name wrong or entity unavailable | Test the action manually in Developer Tools > Services |
| Numeric state trigger does not fire | Value type mismatch (string vs number) | Ensure the sensor reports a numeric value, not a string |
| Automation runs at wrong time | Time zone misconfigured | Check Settings > System > General for the correct time zone |
| Automation runs multiple times | Trigger fires repeatedly | Add a for duration to the trigger, or use a condition to check current state |
🔗Template Automations
For more advanced logic, Home Assistant supports Jinja2 templates in automations. Templates let you do calculations, format strings, and make conditional decisions.
🔗Temperature Difference Alert
Alert when the difference between indoor and outdoor temperature exceeds $10\,\text{°C}$:
- alias: "Large temperature difference alert"
trigger:
- platform: template
value_template: >
{{ (states('sensor.indoor_temperature') | float -
states('sensor.outdoor_temperature') | float) | abs > 10 }}
action:
- service: notify.mobile_app_your_phone
data:
message: >
Big temperature difference!
Indoor: {{ states('sensor.indoor_temperature') }}°C,
Outdoor: {{ states('sensor.outdoor_temperature') }}°CThe | float filter converts the string state to a number, and | abs takes the absolute value so the alert works regardless of which side is warmer.
🔗Best Practices
Start simple. Create basic automations first and add complexity gradually. A working automation with one trigger and one action is better than a complex one that does not work.
Use meaningful names. Name your automations descriptively: "Turn on fan when office temperature exceeds 28°C" is much more useful than "Automation 1" when you have 30 automations.
Add descriptions. The description field is optional but helpful for remembering why you created an automation six months later.
Use hysteresis for threshold-based triggers. If you turn something on at 28 degrees, turn it off at 25 degrees. This prevents rapid cycling.
Test with Developer Tools before automating. Make sure the action works manually before putting it in an automation.
Group related automations. Use labels or naming conventions (prefix with room name or function) to keep your automation list organized.
🔗What is Next?
Your ESP32 sensors are now triggering automations in Home Assistant. The final article in this section shows you how to add voice control -- ask Alexa or Google Home about your sensor readings and control your ESP32 relays with voice commands.