ESPHome configs
  • C++ 88.4%
  • Python 11.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-11-14 23:04:15 +01:00
home_assistant_configs docs: document passkey pairing setup and git component loading 2026-11-14 23:04:15 +01:00
README.md docs: document passkey pairing setup and git component loading 2026-11-14 23:04:15 +01:00

esphome

ESPHome configs for Home Assistant. Everything in home_assistant_configs/ belongs in Home Assistant's /config/esphome/ folder.

Config Device
bluetooth_proxy.yaml bt2tcp (Lolin C3 mini): Bluetooth proxy
meshtastic_bridge.yaml meshtastic-bridge (Lolin C3 mini v2.1.0): Meshtastic Bluetooth → TCP bridge
schuurlamp.yaml schuurlamp (BK72xx, WB3S)

Meshtastic Bluetooth → TCP bridge

meshtastic_bridge.yaml keeps a Bluetooth connection to a Meshtastic node and serves the node's client API on TCP port 4403, like a Wi-Fi Meshtastic node does. The Home Assistant Meshtastic integration can then connect over TCP to a node that only has Bluetooth. The bridge itself is the custom component in home_assistant_configs/components/meshtastic_ble_bridge/.

Setup

  1. On the Meshtastic node, set the Bluetooth pairing mode to No PIN or Fixed PIN (Random PIN can't work, since the bridge has no screen; Fixed PIN needs the passkey feature, see Passkey pairing below), and disconnect the phone app: the node takes one Bluetooth connection at a time.
  2. Copy meshtastic_bridge.yaml and the whole components/ folder to /config/esphome/ in Home Assistant, or let ESPHome fetch the component from git (see Optional: load the component from git below). The config uses the secrets wifi_ssid, wifi_password, wifi_ap_password and api_encryption_key, plus bluetooth_pin_meshtastic (the node's Fixed PIN) as long as the passkey: block is in the YAML. With No PIN that secret can hold any 6 digits, or you can leave the block out.
  3. If the node changes, update radio_mac at the top of the YAML.
  4. Install it from the ESPHome Device Builder (the first time over USB).
  5. In Home Assistant, add the Meshtastic integration with connection type TCP, host meshtastic-bridge.lan, port 4403. Remove any Meshtastic gateway that connects over Bluetooth, since it would compete for the node's single Bluetooth connection.

To check the bridge without Home Assistant, use the Meshtastic Python CLI: meshtastic --host meshtastic-bridge.lan --info.

Passkey pairing (optional)

Pairing with a node on Fixed PIN is optional. meshtastic_bridge.yaml ships with it available but switched off, and you can also leave it out.

Passkey off, feature left out (node on No PIN): no esp32_ble: block, no passkey: block, no PIN secret and no switch in Home Assistant. Everything else stays the same:

esp32_ble_tracker:

ble_client:
  - mac_address: ${radio_mac}
    id: meshtastic_radio

meshtastic_ble_bridge:
  ble_client_id: meshtastic_radio
  port: 4403
  radio_connected:
    id: radio_connected
    name: Radio connected
    on_state:
      - script.execute: update_status_led
  client_connected:
    id: tcp_client_connected
    name: TCP client connected
    on_state:
      - script.execute: update_status_led
  client_address:
    name: TCP client

Passkey available (as shipped): add the esp32_ble: block, which lets the bridge enter the PIN, and the passkey: block. Home Assistant then gets a Passkey pairing switch that starts off. Leave it off for a node on No PIN, turn it on for a node on Fixed PIN. No reflashing needed.

esp32_ble:
  io_capability: keyboard_only

meshtastic_ble_bridge:
  ble_client_id: meshtastic_radio
  port: 4403
  passkey:
    name: Passkey pairing
    pin: !secret bluetooth_pin_meshtastic
  # radio_connected, client_connected and client_address as above

The config check refuses a passkey: block when io_capability: keyboard_only is missing.

Optional: load the component from git

Instead of copying the components/ folder, ESPHome can fetch the component from a git repository when it compiles. Replace the external_components: block in meshtastic_bridge.yaml (as shipped it reads the local components/ folder) with this one. Then only the YAML file has to be in /config/esphome/.

external_components:
  - source:
      type: git
      url: https://git.lan/watskebart/esphome.git
      ref: main
      path: home_assistant_configs/components
      # Private repository: account name and access token
      # username: watskebart
      # password: !secret git_password
    refresh: 1d
    components: [meshtastic_ble_bridge]
  • path is the folder in the repository that holds the component folders. It has to exist in the commit that ref points at, so commit and push the component first.
  • ref is a branch or a tag. Use a tag to keep installs on a known version.
  • refresh is how often ESPHome checks for updates (default 1d). always checks on every compile, handy while developing; never keeps the first clone.
  • Use an https:// URL that the ESPHome Device Builder add-on can reach and whose certificate it trusts. An ssh:// URL would need an SSH key inside the add-on.
  • The access token ends up in secrets.yaml, so give it read-only access to this one repository.

git.lan can't be used for this yet: on 2026-11-14 it served a self-signed HTTPS certificate and didn't answer on plain HTTP, so a clone from the add-on is expected to fail certificate verification. It works once git.lan has a certificate that Home Assistant trusts, or when the repository is mirrored to a host that has one, such as GitHub. Until then, copy the components/ folder as described in Setup.

Behaviour

  • One TCP client at a time. A new connection replaces the old one, as with Meshtastic firmware.
  • TCP connections are refused while the Bluetooth link to the node is down. A connected client is disconnected when the link drops, and reconnects once it is back.
  • While no client is connected, the bridge leaves packets on the node, which keeps a limited queue for its client and delivers it after the next connect.
  • The Radio link switch releases the node, for example to use the phone app over Bluetooth.
  • The Passkey pairing switch (when the passkey: block is in the YAML): off connects without pairing (node on No PIN); on pairs with the PIN once and reuses that bond afterwards (node on Fixed PIN). Flipping it reconnects to the node. After two failed pairings in a row (wrong PIN?) the bridge waits 60 s between attempts. The switch keeps its state across reboots and starts off.
  • Status LED: blue pulse means no Wi-Fi, red pulse no Bluetooth link to the node, orange pulse waiting for a TCP client; green, then off, means working.
  • Built against ESPHome 2026.10.2. Older releases may lack the socket API the component uses.