Add bthome component to CODEOWNERS file with @esphome/core ownership.
Fixed alphabetical ordering fumble: initially placed bthome between
bluetooth_proxy and bme280_base, but 'p' comes before 't' in the
alphabet, so bthome correctly belongs between bp5758d and button.
Add USE_ESP32_BLE_UUID compile-time define to enable UUID support in
the BTHome component, consistent with other BLE components like
esp32_ble_beacon and esp32_ble_server.
Replace custom CONF_SENSOR_TYPE constant with the standard CONF_TYPE
from esphome.const to follow ESPHome naming conventions where constant
names must match their values.
- Add StaticVector::clear() method for resetting container
- Add StaticVector::push_back(T&&) for move semantics support (unique_ptr)
- Use esp_bt_dev_get_address() instead of esp_read_mac for BLE MAC
- Include esp_bt_device.h for Bluetooth device functions
Fixes compilation errors with StaticVector clear() and unique_ptr push_back,
and uses correct API for retrieving Bluetooth MAC address.
Use disable_loop() and enable_loop() to avoid running loop() when there's
no immediate advertising work to do. The loop is disabled by default and
only enabled when a sensor with advertise_immediately triggers, then
disabled again after processing.
**dump_config efficiency:**
- Combine 6 separate ESP_LOGCONFIG calls into 1 with newlines
- Reduces network packets from 6 to 1 (83% reduction)
- Follows ESPHome logging best practices for configuration dumps
- Important when API clients connect frequently
**loop() optimization:**
- Remove regular data change handling from loop()
- Only handle immediate advertising requests in loop()
- Regular sensor updates wait for next advertising callback
- The on_advertise_() callback already rebuilds when data_changed_
**Benefits:**
- Less overhead in loop() - only runs when immediate advertising needed
- More predictable advertising timing tied to BLE intervals
- Cleaner separation: loop handles urgent, callback handles periodic
Switch from FixedVector (runtime-sized, heap allocated) to StaticVector
(compile-time sized, stack allocated) for better memory efficiency:
**Changes:**
- Replace FixedVector with StaticVector in bthome.h
- Use cg.add_define to set sizes at compile time before creating component
- Remove runtime init() calls (StaticVector doesn't need them)
- Add default defines to esphome/core/defines.h for static analysis
**Benefits:**
- All memory allocated on stack at compile time
- Zero runtime allocation overhead
- Better for embedded systems with limited heap
- StaticVector allocates all N slots upfront (no dynamic growth)
**Defines added:**
- BTHOME_MAX_MEASUREMENTS: Max number of sensor measurements
- BTHOME_MAX_BINARY_MEASUREMENTS: Max number of binary sensor measurements
- BTHOME_MAX_ADV_PACKETS: Max advertisement packets for cycling
Sizes are calculated from YAML config and set via cg.add_define before
component instantiation, ensuring compile-time type safety.
Major refactoring to address memory efficiency, advertisement cycling,
and immediate advertising support:
**Use FixedVector instead of std::vector:**
- Replace std::vector with FixedVector for measurements storage
- Initialize with exact sizes determined from configuration
- Eliminates STL reallocation overhead and reduces flash usage
- Uses runtime-sized FixedVector allocated once in setup()
**Config key changes:**
- Use `sensors` and `binary_sensors` (plurals) for consistency
- Matches ESPHome conventions for sensor arrays
**Advertisement size management and cycling:**
- Calculate max advertisement size (31 bytes total, minus overhead)
- Split measurements across multiple packets if they don't fit
- Automatically cycle through packets on each advertising interval
- Ensures all sensors get advertised even with many measurements
- Overhead: 8 bytes unencrypted, 16 bytes encrypted
**Immediate advertising support:**
- Add `advertise_immediately` option for sensors/binary_sensors
- When enabled, triggers immediate advertisement on state change
- Interrupts normal advertising cycle to send only that sensor
- Resumes normal cycle after immediate advertisement
- Perfect for motion sensors, door sensors, or critical alerts
**Implementation details:**
- Refactored encode functions to use raw pointers and calculate sizes
- Build multiple advertisement packets as needed
- Track current packet index for cycling
- Handle immediate advertising with separate packet building path
- Proper encryption handling with per-packet counters
Example configuration:
```yaml
bthome:
sensors:
- type: temperature
id: room_temp
- type: humidity
id: room_humidity
binary_sensors:
- type: motion
id: pir_sensor
advertise_immediately: true # Instant notification
- type: door
id: front_door
advertise_immediately: true
```
Refactored to use ESPHome's existing DEVICE_CLASS_* constants instead
of creating duplicate custom constants. This makes the component more
consistent with the rest of ESPHome and reduces code duplication.
Changes:
- Import DEVICE_CLASS_* constants from esphome.const
- Map device classes to BTHome object IDs in dictionaries
- Remove custom CONF_* duplicates (battery, temperature, motion, etc.)
- Use standard device class strings ("temperature", "humidity", etc.)
Implements native BTHome v2 protocol support for broadcasting sensor data
over BLE advertisements. This enables ESP32 devices to act as battery-powered
BLE sensors that are natively compatible with Home Assistant.
Features:
- Support for multiple sensor types (temperature, humidity, battery, etc.)
- Support for binary sensors (motion, door, window, etc.)
- AES-CCM encryption support with 16-byte keys
- Automatic packet encoding per BTHome v2 specification
- Dynamic advertisement updates when sensor values change
- Configurable advertising intervals and TX power
- Proper BTHome v2 device info byte and service UUID
Implementation:
- Python configuration for sensor/binary sensor mapping
- C++ component for BTHome packet encoding and BLE advertising
- mbedtls CCM encryption for secure advertisements
- Leverages existing esp32_ble infrastructure
Test coverage:
- Basic sensor/binary sensor configuration tests
- Encryption test configuration
- Multi-platform support (ESP32, ESP32-C3, ESP32-S3 with IDF)
Closes: https://github.com/orgs/esphome/discussions/3235