Skip to content

BTHome Receiver

The BTHome Receiver component allows your ESP32 to receive and decode BTHome v2 BLE advertisements from external devices. This enables your ESPHome device to act as a BTHome gateway, collecting sensor data from multiple BTHome-compatible devices.

  • Receives BTHome v2 BLE advertisements from external devices
  • Supports 60+ sensor types (temperature, humidity, pressure, etc.)
  • Supports 28 binary sensor types (motion, door, window, etc.)
  • Supports text sensors for UTF-8 strings and raw binary data
  • AES-128-CCM encryption support with replay protection
  • Button and dimmer event triggers for automation
  • Multiple device support with individual configurations
  • Optional per-device encryption keys
  • Two BLE stack options: Bluedroid (default) or NimBLE (lightweight)
  • Periodic device dump: Log all detected BTHome devices at configurable intervals for discovery and debugging

The BTHome Receiver supports two different BLE stacks: Bluedroid (default) and NimBLE. The choice of stack affects memory usage, features, and compatibility.

The default BLE stack for ESP32. Use this when:

  • You need compatibility with other ESPHome BLE components (esp32_ble_tracker, bluetooth_proxy, etc.)
  • You want to use BLE for multiple purposes (scanning, connections, etc.)
  • You’re already using the esp32_ble component
esp32_ble_tracker:
scan_parameters:
active: false
bthome_receiver:
ble_stack: bluedroid # Default, can be omitted
devices:
- mac_address: "AA:BB:CC:DD:EE:FF"

A lightweight, standalone BLE stack optimized for observer-only scenarios. Choose NimBLE when:

  • Memory is limited - Saves approximately 253KB flash and 10KB RAM
  • Receiving only - Your device only needs to receive BTHome advertisements
  • No other BLE features needed - You don’t need BLE scanning for other purposes or connections
  • Battery-powered devices - Smaller footprint means less power consumption
bthome_receiver:
ble_stack: nimble
devices:
- mac_address: "AA:BB:CC:DD:EE:FF"

Actual measurements from BTHome receiver on ESP32-S3:

FeatureBluedroidNimBLESavings
Flash Usage1,151KB (62.7%)898KB (48.9%)~253KB
RAM Usage50KB (15.3%)40KB (12.3%)~10KB
BLE ScanningVia esp32_ble_trackerBuilt-in passive-
Compatible with esp32_bleYesNo-
Compatible with bluetooth_proxyYesNo-
Best ForMulti-function BLEReceive-only gateway-

Use the dump_interval option to periodically log all detected BTHome devices. This is useful for:

  • Finding MAC addresses of new devices
  • Identifying what sensor types a device broadcasts
  • Debugging encrypted devices (shows if encryption is enabled)
  • Monitoring device health and signal presence
bthome_receiver:
dump_interval: 10s # Log all devices every 10 seconds (0 = disabled)

At each interval, all detected BTHome devices are logged with their cached sensor data:

[I][bthome_receiver:396]: [A4:C1:38:12:34:56] | temperature=31.82 humidity=22.28 battery=100
[I][bthome_receiver:396]: [AA:BB:CC:DD:EE:FF] ENC | (encrypted data)
[I][bthome_receiver:476]: ^ (last seen 2s ago) [REGISTERED]

The output shows:

  • MAC address in standard format
  • ENC flag if device uses encryption
  • Parsed sensor values from the last received advertisement
  • Last seen time for monitoring device availability
  • [REGISTERED] tag for devices configured in your YAML

First, configure the BTHome receiver hub:

bthome_receiver:
devices:
- mac_address: "AA:BB:CC:DD:EE:FF"
name: "Living Room Sensor"

Configure sensors to receive data from a specific device:

sensor:
- platform: bthome_receiver
mac_address: "AA:BB:CC:DD:EE:FF"
temperature:
name: "Living Room Temperature"
humidity:
name: "Living Room Humidity"
battery:
name: "Living Room Battery"

Configure binary sensors for motion, door, window, etc.:

binary_sensor:
- platform: bthome_receiver
mac_address: "AA:BB:CC:DD:EE:FF"
motion:
name: "Living Room Motion"
door:
name: "Front Door"

Configure text sensors for UTF-8 text or raw binary data:

text_sensor:
- platform: bthome_receiver
mac_address: "AA:BB:CC:DD:EE:FF"
text:
name: "Device Status Text"
raw:
name: "Raw Data"
OptionTypeRequiredDefaultDescription
ble_stackstringNobluedroidBLE stack to use: bluedroid or nimble
dump_intervaltimeNo0Interval for periodic device dump (e.g., 10s, 1min). Set to 0 to disable.
deviceslistNo[]List of known devices with optional encryption keys
OptionTypeRequiredDescription
mac_addressMACYesDevice MAC address in format AA:BB:CC:DD:EE:FF
namestringNoFriendly name for the device
encryption_keystringNo32 hex characters (16 bytes) for AES-128-CCM decryption
on_buttontriggerNoAutomation trigger for button events
on_dimmertriggerNoAutomation trigger for dimmer events
OptionTypeRequiredDescription
mac_addressMACYesDevice MAC address
encryption_keystringNo32 hex characters (16 bytes) for AES-128-CCM decryption
[sensor_type]sensorNoAny supported sensor type (see tables below)
OptionTypeRequiredDescription
mac_addressMACYesDevice MAC address
encryption_keystringNo32 hex characters (16 bytes) for AES-128-CCM decryption
[binary_sensor_type]binary_sensorNoAny supported binary sensor type (see table below)
OptionTypeRequiredDescription
mac_addressMACYesDevice MAC address
encryption_keystringNo32 hex characters (16 bytes) for AES-128-CCM decryption
texttext_sensorNoUTF-8 text string (object ID 0x53)
rawtext_sensorNoRaw binary data as hex string (object ID 0x54)

The BTHome receiver supports all 60+ sensor types from the BTHome v2 specification:

TypeObject IDResolutionUnitDescription
packet_id0x001-Packet identifier for deduplication
battery0x011%Battery level percentage
temperature0x020.01°CTemperature (signed)
humidity0x030.01%Relative humidity
pressure0x040.01hPaAtmospheric pressure
illuminance0x050.01luxLight intensity
mass_kg0x060.01kgMass in kilograms
mass_lb0x070.01lbMass in pounds
dewpoint0x080.01°CDew point temperature
count_uint80x091-8-bit counter (0-255)
energy0x0A0.001kWhEnergy consumption
power0x0B0.01WPower consumption
voltage0x0C0.001VVoltage
pm2_50x0D1µg/m³PM2.5 particulate matter
pm100x0E1µg/m³PM10 particulate matter
co20x121ppmCarbon dioxide level
tvoc0x131µg/m³Total volatile organic compounds
moisture0x140.01%Soil/material moisture
TypeObject IDResolutionUnitDescription
humidity_uint80x2E1%Humidity (8-bit)
moisture_uint80x2F1%Moisture (8-bit)
count_uint160x3D1-16-bit counter
count_uint320x3E1-32-bit counter
rotation0x3F0.1°Rotation angle
distance_mm0x401mmDistance in millimeters
distance_m0x410.1mDistance in meters
duration0x420.001sTime duration
current0x430.001ACurrent
speed0x440.01m/sSpeed
temperature_010x450.1°CTemperature (lower precision)
uv_index0x460.1-UV index
volume_l_010x470.1LVolume (liters)
volume_ml0x481mLVolume (milliliters)
volume_flow_rate0x490.001m³/hrFlow rate
voltage_010x4A0.1VVoltage (lower precision)
gas0x4B0.001Gas consumption
gas_uint320x4C0.001Gas consumption (32-bit)
energy_uint320x4D0.001kWhEnergy (32-bit)
volume_l0x4E0.001LVolume in liters
water0x4F0.001LWater consumption
timestamp0x501sUnix timestamp
acceleration0x510.001m/s²Acceleration
gyroscope0x520.001°/sAngular velocity
volume_storage0x550.001LStorage volume
conductivity0x561µS/cmElectrical conductivity
temperature_sint80x571°CTemperature (8-bit integer)
temperature_sint8_0350x580.35°CTemperature (8-bit, 0.35°C steps)
count_sint80x591-8-bit signed counter
count_sint160x5A1-16-bit signed counter
count_sint320x5B1-32-bit signed counter
power_sint320x5C0.01WPower (signed)
current_sint160x5D0.001ACurrent (signed)
direction0x5E0.01°Compass direction
precipitation0x5F0.1mmRainfall
channel0x601-Channel number
rotational_speed0x611rpmRotational speed

All 28 binary sensor types from BTHome v2 are supported:

TypeObject IDDevice ClassDescription
generic_boolean0x0F-Generic on/off
power0x10powerPower state
opening0x11openingGeneric opening
battery_low0x15batteryBattery low warning
battery_charging0x16battery_chargingBattery charging status
carbon_monoxide0x17carbon_monoxideCO detector
cold0x18coldCold warning
connectivity0x19connectivityConnectivity status
door0x1AdoorDoor sensor
garage_door0x1Bgarage_doorGarage door sensor
gas0x1CgasGas detector
heat0x1DheatHeat warning
light0x1ElightLight detection
lock0x1FlockLock state
moisture_binary0x20moistureMoisture detection
motion0x21motionMotion detector
moving0x22movingMovement detection
occupancy0x23occupancyOccupancy sensor
plug0x24plugPlug state
presence0x25presencePresence detection
problem0x26problemProblem indicator
running0x27runningRunning state
safety0x28safetySafety status
smoke0x29smokeSmoke detector
sound0x2AsoundSound detection
tamper0x2BtamperTamper detection
vibration0x2CvibrationVibration detection
window0x2DwindowWindow sensor

To receive encrypted BTHome advertisements, specify the 16-byte AES-128 key as 32 hexadecimal characters.

Register the device and encryption key in the hub:

bthome_receiver:
devices:
- mac_address: "AA:BB:CC:DD:EE:FF"
name: "Secure Sensor"
encryption_key: "231d39c1d7cc1ab1aee224cd096db932"
sensor:
- platform: bthome_receiver
mac_address: "AA:BB:CC:DD:EE:FF"
temperature:
name: "Secure Temperature"

Specify the encryption key directly in each platform configuration:

sensor:
- platform: bthome_receiver
mac_address: "AA:BB:CC:DD:EE:FF"
encryption_key: "231d39c1d7cc1ab1aee224cd096db932"
temperature:
name: "Secure Temperature"
humidity:
name: "Secure Humidity"
binary_sensor:
- platform: bthome_receiver
mac_address: "AA:BB:CC:DD:EE:FF"
encryption_key: "231d39c1d7cc1ab1aee224cd096db932"
motion:
name: "Secure Motion"

The BTHome receiver supports automation triggers for button and dimmer events.

Button events support multiple press types:

bthome_receiver:
devices:
- mac_address: "AA:BB:CC:DD:EE:FF"
name: "Smart Button"
on_button:
- button_index: 0
event: "press"
then:
- light.toggle: living_room_light
- button_index: 0
event: "double_press"
then:
- scene.apply: movie_mode
- button_index: 0
event: "long_press"
then:
- light.turn_off: all_lights
  • none (0x00) - No event
  • press (0x01) - Single press
  • double_press (0x02) - Double press
  • triple_press (0x03) - Triple press
  • long_press (0x04) - Long press
  • long_double_press (0x05) - Long double press
  • long_triple_press (0x06) - Long triple press
  • hold_press (0x80) - Hold/continuous press

Dimmer events provide step values for brightness control:

bthome_receiver:
devices:
- mac_address: "AA:BB:CC:DD:EE:FF"
name: "Smart Dimmer"
on_dimmer:
- then:
- light.dim_relative:
id: living_room_light
relative_brightness: !lambda 'return steps * 0.05;'

The steps variable contains the dimmer step count (positive for increase, negative for decrease).

Use this configuration when you need compatibility with other ESPHome BLE components:

esphome:
name: bthome-receiver-bluedroid
esp32:
board: esp32dev
framework:
type: esp-idf
wifi:
ap:
ssid: "BTHome-Receiver"
captive_portal:
# Required for Bluedroid mode
esp32_ble_tracker:
scan_parameters:
active: false
# BTHome Receiver with Bluedroid (default)
bthome_receiver:
ble_stack: bluedroid # Can be omitted, this is the default
# dump_interval: 10s # Uncomment to discover devices
devices:
# Encrypted temperature sensor
- mac_address: "AA:BB:CC:DD:EE:FF"
name: "Living Room Sensor"
encryption_key: "231d39c1d7cc1ab1aee224cd096db932"
# Smart button with automation
- mac_address: "11:22:33:44:55:66"
name: "Bedroom Button"
on_button:
- button_index: 0
event: "press"
then:
- logger.log: "Button pressed!"
# Receive sensor data
sensor:
- platform: bthome_receiver
mac_address: "AA:BB:CC:DD:EE:FF"
temperature:
name: "Living Room Temperature"
humidity:
name: "Living Room Humidity"
battery:
name: "Living Room Sensor Battery"
# Receive binary sensor data
binary_sensor:
- platform: bthome_receiver
mac_address: "AA:BB:CC:DD:EE:FF"
motion:
name: "Living Room Motion"

Use this configuration for memory-constrained devices or receive-only gateways:

esphome:
name: bthome-receiver-nimble
esp32:
board: seeed_xiao_esp32s3
framework:
type: esp-idf # Required for NimBLE
wifi:
ap:
ssid: "BTHome-Receiver"
captive_portal:
# BTHome Receiver with NimBLE (lightweight, standalone)
# Note: Cannot coexist with esp32_ble_tracker or bluetooth_proxy
bthome_receiver:
ble_stack: nimble
# dump_interval: 10s # Uncomment to discover devices
devices:
# Encrypted temperature sensor
- mac_address: "AA:BB:CC:DD:EE:FF"
name: "Living Room Sensor"
encryption_key: "231d39c1d7cc1ab1aee224cd096db932"
# Smart button with automation
- mac_address: "11:22:33:44:55:66"
name: "Bedroom Button"
on_button:
- button_index: 0
event: "press"
then:
- logger.log: "Button pressed!"
# Receive sensor data
sensor:
- platform: bthome_receiver
mac_address: "AA:BB:CC:DD:EE:FF"
temperature:
name: "Living Room Temperature"
humidity:
name: "Living Room Humidity"
battery:
name: "Living Room Sensor Battery"
# Receive binary sensor data
binary_sensor:
- platform: bthome_receiver
mac_address: "AA:BB:CC:DD:EE:FF"
motion:
name: "Living Room Motion"

You can receive data from multiple BTHome devices by configuring multiple sensor/binary_sensor platforms:

sensor:
# Device 1
- platform: bthome_receiver
mac_address: "AA:BB:CC:DD:EE:FF"
temperature:
name: "Sensor 1 Temperature"
# Device 2
- platform: bthome_receiver
mac_address: "11:22:33:44:55:66"
temperature:
name: "Sensor 2 Temperature"
# Device 3 (encrypted)
- platform: bthome_receiver
mac_address: "77:88:99:AA:BB:CC"
encryption_key: "231d39c1d7cc1ab1aee224cd096db932"
temperature:
name: "Sensor 3 Temperature"
  1. Use discovery mode first - Set dump_interval: 10s to find devices and see their sensor types before configuring
  2. Use encryption for sensitive data or devices accessible in public areas
  3. Register devices in the hub when using event triggers or hub-level encryption
  4. Monitor battery levels by including the battery sensor for battery-powered devices
  5. BLE Scanner range - Keep devices within 10-30 meters depending on environment
  6. Scan parameters - Use active: false in esp32_ble_tracker for better compatibility
  7. Packet deduplication - The receiver automatically handles duplicate packets using packet IDs
  8. Disable discovery mode after configuring devices by removing dump_interval to reduce log output
  • Enable discovery mode by setting dump_interval: 10s to see all BTHome devices in range
  • Verify the MAC address is correct (check the dump output or use a BLE scanner app)
  • Ensure the device is within BLE range (typically 10-30 meters)
  • For Bluedroid: Check that esp32_ble_tracker is configured and running
  • Verify the device is broadcasting BTHome v2 advertisements (UUID 0xFCD2)
  • Set dump_interval: 10s to confirm the device is encrypted (look for “ENC” flag)
  • Verify the encryption key matches the broadcasting device (32 hex characters)
  • Check that the key is correctly formatted (no spaces or dashes)
  • Ensure the device is broadcasting with encryption enabled (device info byte should be 0x41)
  • Set dump_interval: 10s to see exactly what sensor types the device broadcasts
  • Verify the sensor type name matches what the device is broadcasting (check the object ID)
  • Check the ESPHome logs for decoding errors
  • Ensure the object ID in the advertisement matches the configured sensor type