Skip to content

esphome

tested on simulator

Tier Tier 1
Protocol ESPHome native API over TCP, plaintext or Noise encrypted
Covers ESP32, ESP8266, RP2040 and BK72xx boards running ESPHome, sensors, switches, lights, fans, numbers, selects and buttons defined in ESPHome YAML
Hazard default low
Conformance control
Tested with native API simulator over a local TCP socket, driven by the real aioesphomeapi client

Estimated reach. Every ESPHome node, hundreds of thousands of installs. ESPHome is the most common firmware for DIY ESP-based devices and is preinstalled on a growing set of commercial products under the Made for ESPHome program. Every node uses the same native API, and the driver maps the common entity types without per-device code.

The esphome driver connects to ESPHome devices over the native API through aioesphomeapi 46.22.0, MIT. Channels bind to entities by object id, buttons become actions, and describe() builds channels from the entity list.

Supports

EntityChannelTypeCommand
sensorreadnumber, converted from unit_of_measurement, or stringnone
text_sensorreadstring or enumnone
binary_sensorreadboolnone
switchwriteboolswitch_command
lightwrite <id>boollight_command with state
lightwrite <id>_brightnessnumber, percentlight_command with brightness 0 to 1
fanwrite <id>boolfan_command with state
fanwrite <id>_speednumber, percentfan_command with speed_level out of supported_speed_count
fanwrite <id>_presetenumfan_command with preset_mode
numberwritenumber, converted to unit_of_measurementnumber_command
selectwriteenumselect_command
buttonactionno argumentsbutton_command

A channel binds to the entity whose object id is the channel name, minus any _brightness, _speed or _preset suffix, or to map: { object_id: pump_seconds, attribute: state }. A missing entity fails the connect with the list of entities on the device. A write succeeds only when the device reports the new state within timeout, and fan speeds snap to the nearest level. match.esphome holds glob patterns for device info fields such as name and model.

Setup

  1. Install with uv tool install --compile-bytecode "halkit[esphome] @ git+https://github.com/sohan-bhat/OpenHAL".
  2. Add an api: block to the node. With encryption: key: ..., put the key in a variable such as PLANT_PSK and set noise_psk_env.
  3. Add node failsafes such as an on_turn_on pump timer or api: reboot_timeout, and list the failsafes in safe_state_note.
  4. Start from openhal/drivers/esphome/examples/plant-waterer.hal.yaml or describe().
KeyDefaultMeaning
hostrequiredHost name, .local name or address
port6053Native API port
noise_psk_envnoneVariable holding the API encryption key
password_envnoneVariable holding the legacy API password
timeout5 sHandshake deadline and write confirmation window

Known limitations

  • No covers, climate, locks, valves, media players, alarm panels or user-defined services yet.
  • Lights expose state and brightness only.
  • A deep-sleeping node reads as disconnected most of the time.
  • Home Assistant automations on the same node bypass OpenHAL's limits.

Hazard defaults

low, with safe_state from the device file only. A relay switching mains to a heater needs medium or high.

Sources