# ESPHome Documentation ESPHome is an open-source system for controlling ESP8266, ESP32, and other microcontrollers through simple YAML configuration files. It generates custom firmware that can be remotely managed and integrates seamlessly with Home Assistant for home automation. ESPHome eliminates the need for complex C++ programming by providing a declarative YAML-based configuration system that handles WiFi connectivity, sensors, switches, lights, and hundreds of other components. The core functionality centers around creating device configurations in YAML that ESPHome compiles into optimized firmware. Once deployed, devices can communicate with Home Assistant via the native ESPHome API or MQTT, receive over-the-air (OTA) updates, and expose a local web interface for monitoring and control. The system supports advanced features like automations, templates (lambdas), and real-time state streaming via Server-Sent Events (SSE). ## Core Configuration Components ### ESPHome Base Configuration The fundamental configuration that defines the device name, platform, and board type. ```yaml esphome: name: living-room-sensor friendly_name: "Living Room Sensor" esp32: board: esp32dev framework: type: esp-idf # Default since 2026.1.0, use arduino if needed # Alternative for ESP8266 esp8266: board: nodemcuv2 ``` ### WiFi Configuration Sets up WiFi connectivity with optional static IP and fallback access point mode. ```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: 192.168.1.1 # Fallback hotspot when WiFi fails ap: ssid: "Living Room Fallback" password: "fallback123" # Post-connect roaming (enabled by default) post_connect_roaming: true # Connection triggers on_connect: - logger.log: "WiFi connected!" on_disconnect: - logger.log: "WiFi disconnected!" ``` ### Native API Configuration Configures the encrypted API for communication with Home Assistant and other clients. ```yaml api: encryption: key: "YOUR_32_BYTE_BASE64_KEY_HERE" port: 6053 reboot_timeout: 15min # User-defined actions callable from Home Assistant actions: - action: start_cleaning variables: duration: int mode: string then: - logger.log: format: "Starting cleaning for %d minutes in %s mode" args: ["duration", "mode.c_str()"] - switch.turn_on: vacuum_relay - delay: !lambda "return duration * 60000;" - switch.turn_off: vacuum_relay - api.respond: data: !lambda |- root["status"] = "completed"; root["duration"] = duration; on_client_connected: - logger.log: format: "Client %s connected from %s" args: ["client_info.c_str()", "client_address.c_str()"] ``` ### OTA Updates Configuration Enables over-the-air firmware updates with password protection. ```yaml ota: - platform: esphome password: !secret ota_password port: 3232 on_begin: - logger.log: "OTA update starting..." on_progress: - logger.log: format: "OTA progress: %0.1f%%" args: ["x"] on_end: - logger.log: "OTA update complete!" on_error: - logger.log: format: "OTA error: %d" args: ["x"] ``` ## Sensor Components ### DHT Temperature and Humidity Sensor Reads temperature and humidity from DHT11, DHT22, AM2302, and similar sensors. ```yaml sensor: - platform: dht pin: GPIO4 model: DHT22 # AUTO_DETECT, DHT11, DHT22, AM2302, SI7021 update_interval: 60s temperature: name: "Living Room Temperature" id: living_room_temp accuracy_decimals: 1 filters: - offset: -0.5 - sliding_window_moving_average: window_size: 5 send_every: 1 humidity: name: "Living Room Humidity" id: living_room_humidity accuracy_decimals: 1 ``` ### GPIO Binary Sensor Monitors digital input pins for state changes (buttons, door sensors, motion detectors). ```yaml binary_sensor: - platform: gpio pin: number: GPIO16 mode: input: true pullup: true inverted: true name: "Living Room Motion" device_class: motion filters: - delayed_on: 100ms - delayed_off: 5s on_press: - light.turn_on: ceiling_light on_release: - delay: 5min - light.turn_off: ceiling_light ``` ## Output Components ### GPIO Switch Controls digital output pins for relays, LEDs, and other actuators. ```yaml switch: - platform: gpio pin: GPIO5 name: "Living Room Dehumidifier" id: dehumidifier restore_mode: RESTORE_DEFAULT_OFF # Momentary switch (button press simulation) on_turn_on: - delay: 500ms - switch.turn_off: dehumidifier # Interlocked switches (prevent simultaneous activation) - platform: gpio pin: GPIO12 name: "Motor Forward" id: motor_forward interlock: [motor_reverse] interlock_wait_time: 200ms - platform: gpio pin: GPIO13 name: "Motor Reverse" id: motor_reverse interlock: [motor_forward] interlock_wait_time: 200ms ``` ### Light Control Controls various types of lights including RGB, RGBW, and addressable LED strips. ```yaml light: - platform: rgb name: "Desk Light" id: desk_light red: output_red green: output_green blue: output_blue effects: - random: name: "Random Colors" transition_length: 2s update_interval: 3s - strobe: name: "Strobe" colors: - state: true brightness: 100% red: 100% duration: 500ms - state: false duration: 500ms output: - platform: ledc pin: GPIO19 id: output_red - platform: ledc pin: GPIO18 id: output_green - platform: ledc pin: GPIO17 id: output_blue ``` ## Automation and Templates ### Lambda Templates Execute C++ code for complex logic and calculations. ```yaml sensor: - platform: template name: "Calculated Value" lambda: |- float temp = id(living_room_temp).state; float humidity = id(living_room_humidity).state; // Calculate heat index if (isnan(temp) || isnan(humidity)) { return NAN; } return temp + 0.5555 * (6.11 * exp(5417.7530 * (1/273.16 - 1/(273.15 + temp))) * humidity / 100 - 10); unit_of_measurement: "°C" update_interval: 60s ``` ### Automations with Conditions Execute actions based on triggers and conditions. ```yaml binary_sensor: - platform: gpio pin: GPIO0 name: "Button" on_multi_click: - timing: - ON for at most 1s - OFF for at most 0.5s - ON for at most 1s then: - logger.log: "Double click detected" - light.toggle: desk_light - timing: - ON for 1s to 3s then: - logger.log: "Long press detected" - if: condition: wifi.connected: then: - homeassistant.action: action: script.emergency_lights else: - light.turn_on: id: desk_light brightness: 100% red: 100% green: 0% blue: 0% ``` ### Script Component Define reusable action sequences. ```yaml script: - id: blink_warning mode: restart then: - repeat: count: 5 then: - light.turn_on: id: status_led brightness: 100% - delay: 200ms - light.turn_off: status_led - delay: 200ms - id: gradual_wakeup mode: single then: - light.turn_on: id: bedroom_light brightness: 0% - repeat: count: 100 then: - light.control: id: bedroom_light brightness: !lambda "return id(bedroom_light).current_values.get_brightness() + 0.01;" - delay: 600ms # 1 minute total ``` ## Web Server API ### REST API Endpoints The built-in web server exposes REST endpoints for all entities. ```bash # Get sensor state curl http://192.168.1.100/sensor/Living%20Room%20Temperature # Response: {"id":"sensor/Living Room Temperature","state":"22.5 °C","value":22.5} # Get binary sensor state curl http://192.168.1.100/binary_sensor/Living%20Room%20Motion # Response: {"id":"binary_sensor/Living Room Motion","state":"ON","value":true} # Turn on a switch curl -X POST http://192.168.1.100/switch/Dehumidifier/turn_on # Response: HTTP 200 OK # Turn off a switch curl -X POST http://192.168.1.100/switch/Dehumidifier/turn_off # Toggle a switch curl -X POST http://192.168.1.100/switch/Dehumidifier/toggle # Control light with parameters curl -X POST "http://192.168.1.100/light/Desk%20Light/turn_on?brightness=128&r=255&g=100&b=50&transition=2" # Set number value curl -X POST "http://192.168.1.100/number/Target%20Temperature/set?value=22.5" # Set select option curl -X POST "http://192.168.1.100/select/Fan%20Mode/set?option=auto" # Press a button curl -X POST http://192.168.1.100/button/Restart/press ``` ### Event Source API (Server-Sent Events) Subscribe to real-time state updates via SSE. ```javascript // JavaScript example for SSE connection const eventSource = new EventSource('http://192.168.1.100/events'); eventSource.addEventListener('state', function(event) { const data = JSON.parse(event.data); console.log(`Entity: ${data.id}, State: ${data.state}`); // Example output: Entity: sensor/Living Room Temperature, State: 22.5 °C }); eventSource.addEventListener('log', function(event) { const data = JSON.parse(event.data); console.log(`[${data.level}] ${data.message}`); }); eventSource.addEventListener('ping', function(event) { console.log('Connection alive'); }); eventSource.onerror = function(error) { console.error('SSE connection error:', error); }; ``` ### Web Server Configuration Enable and configure the built-in web server. ```yaml web_server: port: 80 version: 3 local: true # Use local assets instead of CDN auth: username: admin password: !secret web_password ota: true # Enable OTA updates via web interface ``` ## Home Assistant Integration ### Calling Home Assistant Actions Execute Home Assistant actions from ESPHome automations. ```yaml on_press: - homeassistant.action: action: light.turn_on data: entity_id: light.living_room brightness_pct: 100 color_temp: 350 on_success: - logger.log: "Light turned on successfully" on_error: - logger.log: "Failed to turn on light" # With response capture - homeassistant.action: action: weather.get_forecasts data: entity_id: weather.home type: hourly capture_response: true on_success: - lambda: |- JsonObjectConst forecast = response["response"]["weather.home"]["forecast"][0]; float temp = forecast["temperature"].as(); ESP_LOGI("weather", "Next hour: %.1f°C", temp); ``` ### Firing Home Assistant Events Send custom events to Home Assistant event bus. ```yaml on_press: - homeassistant.event: event: esphome.button_pressed data: device: "living_room_controller" button: "main" data_template: timestamp: "{{ now().isoformat() }}" variables: press_count: |- static int count = 0; return ++count; ``` ### Home Assistant Sensor Integration Subscribe to Home Assistant entity states. ```yaml sensor: - platform: homeassistant name: "Outside Temperature" entity_id: sensor.outdoor_thermometer on_value: - if: condition: lambda: 'return x > 30;' then: - switch.turn_on: cooling_fan text_sensor: - platform: homeassistant name: "Weather Condition" entity_id: weather.home attribute: condition ``` ## CLI Commands ### ESPHome Command Line Interface Common commands for managing ESPHome devices. ```bash # Create new configuration with wizard esphome wizard my_device.yaml # Validate configuration esphome config my_device.yaml # Compile firmware esphome compile my_device.yaml # Upload firmware via USB esphome upload my_device.yaml # Upload firmware via OTA (wireless) esphome upload my_device.yaml --device 192.168.1.100 # Compile and upload in one step esphome run my_device.yaml # View device logs via USB esphome logs my_device.yaml # View device logs via network esphome logs my_device.yaml --device 192.168.1.100 # Start the ESPHome dashboard esphome dashboard config/ # Clean build files esphome clean my_device.yaml # Docker usage docker run --rm -v "${PWD}":/config -it ghcr.io/esphome/esphome run my_device.yaml docker run --rm -v "${PWD}":/config --device=/dev/ttyUSB0 -it ghcr.io/esphome/esphome run my_device.yaml ``` ESPHome is designed for makers, hobbyists, and professional integrators who want to create custom firmware for ESP-based devices without deep embedded programming knowledge. The YAML-based configuration system enables rapid prototyping and deployment of IoT devices, while the native Home Assistant integration provides seamless smart home control. Common use cases include temperature/humidity monitoring, smart switches and relays, RGB lighting control, garage door openers, and custom sensor platforms. The system excels in environments where reliability, over-the-air updates, and Home Assistant integration are priorities. Advanced users can leverage lambda templates to implement custom logic, while the REST API and SSE event source enable integration with external applications and custom dashboards. The modular component architecture supports hundreds of sensors, displays, and output devices, making ESPHome suitable for projects ranging from simple button controllers to complex multi-sensor environmental monitoring stations.