Try Live
Add Docs
Rankings
Pricing
Docs
Install
Install
Docs
Pricing
More...
More...
Try Live
Rankings
Enterprise
Create API Key
Add Docs
ESPHome
https://github.com/esphome/esphome-docs
Admin
Source for esphome.io documentation files.
Tokens:
739,866
Snippets:
6,874
Trust Score:
8.2
Update:
1 week ago
Context
Skills
Chat
Benchmark
40.5
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# ESPHome Documentation ESPHome is an open-source system for controlling ESP8266, ESP32, RP2040, and other microcontrollers through simple YAML configuration files. It transforms IoT devices into smart home components that seamlessly integrate with Home Assistant and other platforms, enabling users to create custom firmware without writing code. ESPHome provides a declarative approach to defining sensors, switches, lights, displays, and automations that run directly on the device. The documentation covers the complete ESPHome ecosystem including core configuration, component setup, automation triggers and actions, and integration patterns. ESPHome supports hundreds of sensors, actuators, and communication protocols through its modular component architecture. The YAML-based configuration compiles to optimized C++ firmware that can be flashed over-the-air (OTA) or via USB, making iterative development fast and accessible. ## Core Configuration - ESPHome Node Setup The `esphome` block defines the fundamental node configuration including device name, platform settings, and boot/shutdown automations. Every ESPHome configuration must include this core section. ```yaml esphome: name: living-room-controller friendly_name: "Living Room Controller" area: "Living Room" comment: "Controls lights and monitors temperature" # Boot automation with priority (higher = earlier execution) on_boot: - priority: 600 # After hardware init, before WiFi then: - switch.turn_off: relay_1 - logger.log: "Device booted successfully" # Shutdown automation on_shutdown: - priority: 700 then: - switch.turn_off: relay_1 # Advanced options platformio_options: upload_speed: 115200 board_build.f_flash: 80000000L # Platform-specific configuration esp32: board: esp32dev framework: type: arduino # Or for ESP8266 esp8266: board: nodemcuv2 ``` ## WiFi Component - Network Configuration The WiFi component establishes network connectivity with support for multiple networks, static IPs, access point mode, and power management. Static IP configuration dramatically improves connection times. ```yaml wifi: ssid: !secret wifi_ssid password: !secret wifi_password # Static IP for faster connections manual_ip: static_ip: 192.168.1.100 gateway: 192.168.1.1 subnet: 255.255.255.0 dns1: 8.8.8.8 dns2: 8.8.4.4 # Multiple network fallback networks: - ssid: "PrimaryNetwork" password: !secret primary_password priority: 10 - ssid: "BackupNetwork" password: !secret backup_password priority: 5 # Fallback Access Point ap: ssid: "ESP-Fallback" password: "fallback123" ap_timeout: 90s # Performance options fast_connect: true power_save_mode: none # LIGHT or HIGH for battery devices reboot_timeout: 15min # Connection automations on_connect: - logger.log: "WiFi connected!" on_disconnect: - logger.log: "WiFi disconnected!" ``` ## Native API Component - Home Assistant Integration The native API provides optimized communication with Home Assistant using protocol buffers. It supports encryption, custom actions, and real-time state synchronization. ```yaml api: port: 6053 # Encryption (required for production) encryption: key: "YOUR_32_BYTE_BASE64_KEY_HERE" # Connection settings reboot_timeout: 15min batch_delay: 50ms # Lower for real-time apps max_connections: 8 # Default for ESP32 # Custom user-defined actions callable from Home Assistant actions: - action: set_custom_value variables: target_value: int then: - logger.log: format: "Setting value to %d" args: [target_value] - globals.set: id: custom_value value: !lambda 'return target_value;' - action: ring_doorbell then: - rtttl.play: "two_short:d=4,o=5,b=100:c6,p,c6" # Connection triggers on_client_connected: - logger.log: "Client connected to API" on_client_disconnected: - logger.log: "Client disconnected from API" ``` ## MQTT Client Component - Broker Communication The MQTT component enables communication with MQTT brokers for integration with various home automation systems beyond Home Assistant. ```yaml mqtt: broker: 192.168.1.50 port: 1883 username: !secret mqtt_user password: !secret mqtt_password # Topic configuration topic_prefix: esphome/living_room discovery: true discovery_prefix: homeassistant # Birth and Last Will messages birth_message: topic: esphome/living_room/status payload: online retain: true will_message: topic: esphome/living_room/status payload: offline retain: true # Log forwarding to MQTT log_topic: topic: esphome/living_room/logs level: WARN # Message triggers on_message: - topic: esphome/living_room/command then: - logger.log: format: "Received: %s" args: ['x.c_str()'] on_json_message: topic: esphome/living_room/json then: - logger.log: format: "Got value: %d" args: ['x["value"].as<int>()'] ``` ## Sensor Component - Environmental Monitoring Sensors read physical measurements and expose them to Home Assistant. ESPHome supports hundreds of sensor types with configurable filters, units, and automations. ```yaml sensor: # DHT temperature and humidity sensor - platform: dht pin: GPIO4 model: DHT22 temperature: name: "Living Room Temperature" id: living_room_temp unit_of_measurement: "°C" device_class: temperature state_class: measurement accuracy_decimals: 1 filters: - sliding_window_moving_average: window_size: 10 send_every: 5 - lambda: return x * (9.0/5.0) + 32.0; # Convert to Fahrenheit on_value: then: - logger.log: format: "Temperature: %.1f" args: ['x'] on_value_range: - above: 30.0 then: - switch.turn_on: cooling_fan - below: 25.0 then: - switch.turn_off: cooling_fan humidity: name: "Living Room Humidity" filters: - exponential_moving_average: alpha: 0.1 send_every: 10 update_interval: 30s # ADC voltage sensor with calibration - platform: adc pin: GPIO34 name: "Battery Voltage" attenuation: 11db filters: - calibrate_linear: - 0.0 -> 0.0 - 1.0 -> 3.3 - multiply: 2 # Voltage divider compensation update_interval: 60s ``` ## Binary Sensor Component - Digital Input Detection Binary sensors detect on/off states from GPIO pins, buttons, motion sensors, and more. They support debouncing, filtering, and event-driven automations. ```yaml binary_sensor: # Push button with debounce and multiple triggers - platform: gpio pin: number: GPIO5 mode: input: true pullup: true inverted: true # Active low name: "Living Room Button" id: living_room_button filters: - delayed_on: 10ms # Debounce - delayed_off: 10ms on_press: then: - light.toggle: ceiling_light on_click: min_length: 50ms max_length: 350ms then: - switch.toggle: relay_1 on_double_click: min_length: 50ms max_length: 350ms then: - light.turn_on: id: ceiling_light brightness: 100% on_multi_click: - timing: - ON for at most 1s - OFF for at most 1s - ON for at most 1s then: - logger.log: "Triple click detected" # PIR motion sensor - platform: gpio pin: GPIO13 name: "Motion Sensor" device_class: motion on_press: then: - light.turn_on: hallway_light - delay: 5min - light.turn_off: hallway_light ``` ## Switch Component - Output Control Switches control GPIO outputs, relays, and virtual states. They support interlocking for safety, restore modes, and automation triggers. ```yaml switch: # Basic relay control - platform: gpio pin: GPIO16 name: "Relay 1" id: relay_1 restore_mode: RESTORE_DEFAULT_OFF on_turn_on: - logger.log: "Relay 1 turned ON" on_turn_off: - logger.log: "Relay 1 turned OFF" # Momentary switch (simulates button press) - platform: gpio pin: GPIO17 name: "Gate Remote" id: gate_remote on_turn_on: - delay: 500ms - switch.turn_off: gate_remote # Interlocked switches (prevents simultaneous activation) - platform: gpio pin: GPIO18 name: "Motor Forward" id: motor_forward interlock: [motor_reverse] interlock_wait_time: 500ms - platform: gpio pin: GPIO19 name: "Motor Reverse" id: motor_reverse interlock: [motor_forward] interlock_wait_time: 500ms # Template switch with lambda - platform: template name: "Smart Mode" id: smart_mode optimistic: true restore_mode: RESTORE_DEFAULT_OFF turn_on_action: - logger.log: "Smart mode enabled" turn_off_action: - logger.log: "Smart mode disabled" ``` ## Light Component - LED and Light Control The light component controls various light types including single-color, RGB, RGBW, and addressable LEDs with effects and transitions. ```yaml light: # Simple PWM light - platform: monochromatic name: "Desk Lamp" output: desk_lamp_pwm default_transition_length: 1s gamma_correct: 2.8 restore_mode: RESTORE_DEFAULT_OFF # RGB LED strip - platform: rgb name: "RGB Strip" id: rgb_strip red: red_pwm green: green_pwm blue: blue_pwm effects: - random: name: "Random Effect" transition_length: 2s update_interval: 3s - strobe: name: "Strobe" colors: - state: true brightness: 100% red: 100% duration: 500ms - state: false duration: 500ms - pulse: name: "Breathing" min_brightness: 20% max_brightness: 100% transition_length: 2s update_interval: 2s on_turn_on: - logger.log: "Light turned on" on_turn_off: - logger.log: "Light turned off" # Addressable LED strip (WS2812B) - platform: neopixelbus type: GRB variant: WS2812X pin: GPIO12 num_leds: 60 name: "LED Strip" effects: - addressable_rainbow: name: "Rainbow" speed: 10 width: 50 - addressable_color_wipe: name: "Color Wipe" colors: - red: 100% green: 0% blue: 0% num_leds: 10 - red: 0% green: 100% blue: 0% num_leds: 10 output: - platform: ledc pin: GPIO25 id: desk_lamp_pwm - platform: ledc pin: GPIO26 id: red_pwm - platform: ledc pin: GPIO27 id: green_pwm - platform: ledc pin: GPIO14 id: blue_pwm ``` ## Automations - Actions and Triggers ESPHome automations enable device-local logic without requiring a home automation server. Actions execute sequentially and support conditions, loops, and lambdas. ```yaml # Global variables for state tracking globals: - id: counter type: int initial_value: '0' restore_value: true # Timed automations interval: - interval: 1min then: - logger.log: "Minute tick" - lambda: 'id(counter) += 1;' # Reusable scripts script: - id: flash_light mode: restart # queued, single, parallel then: - light.turn_on: id: ceiling_light brightness: 100% - delay: 500ms - light.turn_off: ceiling_light - delay: 500ms - light.turn_on: id: ceiling_light brightness: 100% - delay: 500ms - light.turn_off: ceiling_light binary_sensor: - platform: gpio pin: GPIO5 name: "Main Button" on_press: then: # Conditional execution - if: condition: - switch.is_on: smart_mode then: - logger.log: "Smart mode is active" - script.execute: flash_light else: - light.toggle: ceiling_light # Loop execution - repeat: count: 3 then: - logger.log: format: "Repeat iteration %d" args: ['iteration'] - delay: 100ms # Wait for condition - wait_until: condition: - binary_sensor.is_off: motion_sensor timeout: 30s # Lambda for complex logic - lambda: |- if (id(living_room_temp).state > 25) { id(relay_1).turn_on(); } else { id(relay_1).turn_off(); } ``` ## Home Assistant Actions - Remote Control ESPHome can trigger Home Assistant actions and fire events, enabling bidirectional communication between the device and the home automation server. ```yaml api: encryption: key: !secret api_key binary_sensor: - platform: gpio pin: GPIO5 name: "Doorbell" on_press: then: # Fire custom event in Home Assistant - homeassistant.event: event: esphome.doorbell_pressed data: location: "front_door" timestamp: !lambda 'return id(sntp_time).now().timestamp;' # Call Home Assistant action - homeassistant.action: action: notify.mobile_app_phone data: title: "Doorbell" message: "Someone is at the front door" # Call action with template data - homeassistant.action: action: light.turn_on data: entity_id: light.porch data_template: brightness_pct: "{{ states('sensor.ambient_light') | int }}" variables: my_var: !lambda 'return id(some_sensor).state;' sensor: # Import Home Assistant entity state - platform: homeassistant name: "Outside Temperature" entity_id: sensor.outdoor_temperature id: outdoor_temp on_value: then: - logger.log: format: "Outdoor temp updated: %.1f" args: ['x'] ``` ## Templates and Lambdas - Custom Logic ESPHome supports C++ lambdas for complex logic that cannot be expressed in pure YAML, enabling access to component states, variables, and direct hardware control. ```yaml globals: - id: boot_count type: int initial_value: '0' restore_value: true sensor: - platform: template name: "Calculated Value" id: calculated_sensor unit_of_measurement: "units" accuracy_decimals: 2 lambda: |- // Access other sensor values float temp = id(temperature_sensor).state; float humidity = id(humidity_sensor).state; // Calculate heat index if (isnan(temp) || isnan(humidity)) { return NAN; } float hi = 0.5 * (temp + 61.0 + ((temp - 68.0) * 1.2) + (humidity * 0.094)); return hi; update_interval: 30s - platform: template name: "Boot Counter" lambda: 'return id(boot_count);' update_interval: never binary_sensor: - platform: template name: "High Temperature Alert" lambda: |- return id(temperature_sensor).state > 30.0; text_sensor: - platform: template name: "System Status" lambda: |- if (id(wifi_connected)) { return {"Online"}; } else { return {"Offline"}; } update_interval: 10s switch: - platform: template name: "Conditional Switch" lambda: 'return id(relay_1).state;' turn_on_action: - if: condition: lambda: 'return id(temperature_sensor).state < 35.0;' then: - switch.turn_on: relay_1 turn_off_action: - switch.turn_off: relay_1 esphome: on_boot: then: - lambda: 'id(boot_count) += 1;' - sensor.template.publish: id: calculated_sensor state: !lambda 'return id(boot_count);' ``` ## OTA Updates - Over-the-Air Firmware Updates The OTA component enables wireless firmware updates, eliminating the need for physical access to devices after initial deployment. ```yaml ota: - platform: esphome password: !secret ota_password # Safe mode configuration safe_mode: true num_attempts: 10 reboot_timeout: 5min # Update triggers on_begin: then: - logger.log: "OTA update starting..." - light.turn_on: id: status_led effect: "Strobe" on_progress: then: - logger.log: format: "OTA progress: %0.1f%%" args: ['x'] on_end: then: - logger.log: "OTA update completed!" on_error: then: - logger.log: format: "OTA error: %d" args: ['x'] # Web-based OTA fallback web_server: port: 80 auth: username: admin password: !secret web_password ota: true ``` ## Deep Sleep - Battery Power Management Deep sleep dramatically reduces power consumption for battery-powered devices by putting the microcontroller into a low-power state between measurements. ```yaml deep_sleep: id: deep_sleep_control run_duration: 30s sleep_duration: 5min # Wake on GPIO pin wakeup_pin: number: GPIO33 inverted: true wakeup_pin_mode: IGNORE sensor: - platform: adc pin: GPIO34 name: "Battery Voltage" id: battery_voltage update_interval: never # Manual update before sleep binary_sensor: - platform: gpio pin: GPIO33 name: "Wake Button" on_press: - deep_sleep.prevent: deep_sleep_control esphome: on_boot: priority: -100 then: # Take measurements - component.update: battery_voltage - delay: 5s # Enter sleep if battery is low - if: condition: lambda: 'return id(battery_voltage).state < 3.3;' then: - deep_sleep.enter: id: deep_sleep_control sleep_duration: 30min ``` ESPHome provides a comprehensive platform for creating smart home devices that prioritize local control and reliability. The YAML-based configuration makes firmware development accessible while the underlying C++ compilation ensures optimized performance on resource-constrained microcontrollers. Devices can operate fully autonomously or integrate seamlessly with Home Assistant through the native API or MQTT protocols. The modular component architecture supports an extensive ecosystem of sensors, actuators, displays, and communication protocols. From simple relay switches to complex environmental monitoring stations, ESPHome configurations can scale from basic GPIO control to sophisticated multi-sensor devices with custom automations. The over-the-air update capability combined with safe mode fallbacks ensures devices remain maintainable throughout their deployment lifecycle.