ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
automation.h
Go to the documentation of this file.
1// Platform-neutral BLE advertisement triggers: ESPBTDeviceListener subclasses
2// registered on a BLEHub, exposed by each tracker under its own automation
3// names. parse_device()'s return feeds the "Found device" suppression.
4// Constructors are templated on the hub type so this header also builds with
5// no tracker present (host unit tests).
6
7#pragma once
8
9#include "ble_device.h"
10
13
15
17inline bool mac_in_table(const uint64_t *table, uint64_t address) {
18 for (; *table != 0; table++) {
19 if (*table == address)
20 return true;
21 }
22 return false;
23}
24
25// on_ble_advertise: fires on every BLE advertisement, optionally filtered to one or more MACs.
26class ESPBTAdvertiseTrigger final : public Trigger<const ESPBTDevice &>, public ESPBTDeviceListener {
27 public:
28 template<typename Hub> explicit ESPBTAdvertiseTrigger(Hub *parent) { parent->register_listener(this); }
29
31 void set_addresses(const uint64_t *addresses) { this->addresses_ = addresses; }
32
33 bool parse_device(const ESPBTDevice &device) override {
34 if (this->addresses_ != nullptr && !mac_in_table(this->addresses_, device.address_uint64()))
35 return false;
36 this->trigger(device);
37 return true;
38 }
39
40 protected:
41 const uint64_t *addresses_{nullptr};
42};
43
44// on_ble_service_data_advertise: fires when an advertisement contains service
45// data for the given UUID. Optional single-MAC filter.
46class BLEServiceDataAdvertiseTrigger final : public Trigger<const adv_data_t &>, public ESPBTDeviceListener {
47 public:
48 template<typename Hub> explicit BLEServiceDataAdvertiseTrigger(Hub *parent) { parent->register_listener(this); }
49
50 void set_service_uuid16(uint64_t uuid) { this->uuid_ = ESPBTUUID::from_uint16(static_cast<uint16_t>(uuid)); }
51 void set_service_uuid32(uint64_t uuid) { this->uuid_ = ESPBTUUID::from_uint32(static_cast<uint32_t>(uuid)); }
52 void set_service_uuid128(const uint8_t *uuid) { this->uuid_ = ESPBTUUID::from_raw(uuid); }
53
54 void set_address(uint64_t address) {
55 this->address_ = address;
56 this->has_address_ = true;
57 }
58
59 bool parse_device(const ESPBTDevice &device) override {
60 if (this->has_address_ && device.address_uint64() != this->address_) {
61 return false;
62 }
63 for (const auto &sd : device.get_service_datas()) {
64 if (sd.uuid == this->uuid_) {
65 this->trigger(sd.data);
66 return true;
67 }
68 }
69 return false;
70 }
71
72 protected:
74 uint64_t address_{0};
75 bool has_address_{false};
76};
77
78// on_ble_manufacturer_data_advertise: fires when an advertisement contains
79// manufacturer data for the given ID. Optional single-MAC filter.
80class BLEManufacturerDataAdvertiseTrigger final : public Trigger<const adv_data_t &>, public ESPBTDeviceListener {
81 public:
82 template<typename Hub> explicit BLEManufacturerDataAdvertiseTrigger(Hub *parent) { parent->register_listener(this); }
83
84 void set_manufacturer_uuid16(uint64_t uuid) { this->uuid_ = ESPBTUUID::from_uint16(static_cast<uint16_t>(uuid)); }
85 void set_manufacturer_uuid32(uint64_t uuid) { this->uuid_ = ESPBTUUID::from_uint32(static_cast<uint32_t>(uuid)); }
86 void set_manufacturer_uuid128(const uint8_t *uuid) { this->uuid_ = ESPBTUUID::from_raw(uuid); }
87
88 void set_address(uint64_t address) {
89 this->address_ = address;
90 this->has_address_ = true;
91 }
92
93 bool parse_device(const ESPBTDevice &device) override {
94 if (this->has_address_ && device.address_uint64() != this->address_) {
95 return false;
96 }
97 for (const auto &md : device.get_manufacturer_datas()) {
98 if (md.uuid == this->uuid_) {
99 this->trigger(md.data);
100 return true;
101 }
102 }
103 return false;
104 }
105
106 protected:
108 uint64_t address_{0};
109 bool has_address_{false};
110};
111
112// on_scan_end: fires whenever a scan period ends (duration elapsed or stop
113// requested). A listener whose on_scan_end() hook fires the trigger — never
114// claims devices (parse_device always returns false).
115class BLEEndOfScanTrigger final : public Trigger<>, public ESPBTDeviceListener {
116 public:
117 template<typename Hub> explicit BLEEndOfScanTrigger(Hub *parent) { parent->register_listener(this); }
118
119 bool parse_device(const ESPBTDevice &device) override { return false; }
120 void on_scan_end() override { this->trigger(); }
121};
122
123} // namespace esphome::ble_device_base
uint8_t address
Definition bl0906.h:4
void trigger(const Ts &...x) ESPHOME_ALWAYS_INLINE
Definition automation.h:533
bool parse_device(const ESPBTDevice &device) override
Definition automation.h:119
bool parse_device(const ESPBTDevice &device) override
Definition automation.h:93
bool parse_device(const ESPBTDevice &device) override
Definition automation.h:59
bool parse_device(const ESPBTDevice &device) override
Definition automation.h:33
void set_addresses(const uint64_t *addresses)
Table of MACs ended by 0; must outlive the trigger.
Definition automation.h:31
uint64_t address_uint64() const
Return MAC as packed uint64 (byte 0 in LSB — matches esp32's address_uint64).
const std::vector< ServiceData > & get_service_datas() const
Definition ble_device.h:225
const std::vector< ServiceData > & get_manufacturer_datas() const
Definition ble_device.h:224
static ESPBTUUID from_uint16(uint16_t uuid)
static ESPBTUUID from_raw(const uint8_t *data)
Construct from raw 16-byte little-endian UUID.
static ESPBTUUID from_uint32(uint32_t uuid)
bool mac_in_table(const uint64_t *table, uint64_t address)
True if address is in table, a list of MACs ended by 0.
Definition automation.h:17
static void uint32_t