ESPHome 2025.10.0-dev
Loading...
Searching...
No Matches
ble_server_automations.cpp
Go to the documentation of this file.
2
3#ifdef USE_ESP32
4
5namespace esphome {
6namespace esp32_ble_server {
7// Interface to interact with ESPHome automations and triggers
8namespace esp32_ble_server_automations {
9
10using namespace esp32_ble;
11
12#ifdef USE_ESP32_BLE_SERVER_CHARACTERISTIC_ON_WRITE
14 BLECharacteristic *characteristic) {
15 Trigger<std::vector<uint8_t>, uint16_t> *on_write_trigger = // NOLINT(cppcoreguidelines-owning-memory)
16 new Trigger<std::vector<uint8_t>, uint16_t>();
17 characteristic->EventEmitter<BLECharacteristicEvt::VectorEvt, std::vector<uint8_t>, uint16_t>::on(
19 [on_write_trigger](const std::vector<uint8_t> &data, uint16_t id) { on_write_trigger->trigger(data, id); });
20 return on_write_trigger;
21}
22#endif
23
24#ifdef USE_ESP32_BLE_SERVER_DESCRIPTOR_ON_WRITE
26 Trigger<std::vector<uint8_t>, uint16_t> *on_write_trigger = // NOLINT(cppcoreguidelines-owning-memory)
27 new Trigger<std::vector<uint8_t>, uint16_t>();
28 descriptor->on(
30 [on_write_trigger](const std::vector<uint8_t> &data, uint16_t id) { on_write_trigger->trigger(data, id); });
31 return on_write_trigger;
32}
33#endif
34
35#ifdef USE_ESP32_BLE_SERVER_ON_CONNECT
37 Trigger<uint16_t> *on_connect_trigger = new Trigger<uint16_t>(); // NOLINT(cppcoreguidelines-owning-memory)
39 [on_connect_trigger](uint16_t conn_id) { on_connect_trigger->trigger(conn_id); });
40 return on_connect_trigger;
41}
42#endif
43
44#ifdef USE_ESP32_BLE_SERVER_ON_DISCONNECT
46 Trigger<uint16_t> *on_disconnect_trigger = new Trigger<uint16_t>(); // NOLINT(cppcoreguidelines-owning-memory)
48 [on_disconnect_trigger](uint16_t conn_id) { on_disconnect_trigger->trigger(conn_id); });
49 return on_disconnect_trigger;
50}
51#endif
52
53#ifdef USE_ESP32_BLE_SERVER_SET_VALUE_ACTION
55 EventEmitterListenerID listener_id,
56 const std::function<void()> &pre_notify_listener) {
57 // Find and remove existing listener for this characteristic
58 auto *existing = this->find_listener_(characteristic);
59 if (existing != nullptr) {
60 // Remove the previous listener
61 characteristic->EventEmitter<BLECharacteristicEvt::EmptyEvt, uint16_t>::off(BLECharacteristicEvt::EmptyEvt::ON_READ,
62 existing->listener_id);
63 // Remove the pre-notify listener
64 this->off(BLECharacteristicSetValueActionEvt::PRE_NOTIFY, existing->pre_notify_listener_id);
65 // Remove from vector
66 this->remove_listener_(characteristic);
67 }
68 // Create a new listener for the pre-notify event
69 EventEmitterListenerID pre_notify_listener_id =
71 [pre_notify_listener, characteristic](const BLECharacteristic *evt_characteristic) {
72 // Only call the pre-notify listener if the characteristic is the one we are interested in
73 if (characteristic == evt_characteristic) {
74 pre_notify_listener();
75 }
76 });
77 // Save the entry to the vector
78 this->listeners_.push_back({characteristic, listener_id, pre_notify_listener_id});
79}
80
81BLECharacteristicSetValueActionManager::ListenerEntry *BLECharacteristicSetValueActionManager::find_listener_(
82 BLECharacteristic *characteristic) {
83 for (auto &entry : this->listeners_) {
84 if (entry.characteristic == characteristic) {
85 return &entry;
86 }
87 }
88 return nullptr;
89}
90
91void BLECharacteristicSetValueActionManager::remove_listener_(BLECharacteristic *characteristic) {
92 // Since we typically have very few listeners, optimize by swapping with back and popping
93 for (size_t i = 0; i < this->listeners_.size(); i++) {
94 if (this->listeners_[i].characteristic == characteristic) {
95 // Swap with last element and pop (safe even when i is the last element)
96 this->listeners_[i] = this->listeners_.back();
97 this->listeners_.pop_back();
98 return;
99 }
100 }
101}
102#endif
103
104} // namespace esp32_ble_server_automations
105} // namespace esp32_ble_server
106} // namespace esphome
107
108#endif
void trigger(Ts... x)
Inform the parent automation that the event has triggered.
Definition automation.h:145
void set_listener(BLECharacteristic *characteristic, EventEmitterListenerID listener_id, const std::function< void()> &pre_notify_listener)
static Trigger< std::vector< uint8_t >, uint16_t > * create_characteristic_on_write_trigger(BLECharacteristic *characteristic)
static Trigger< uint16_t > * create_server_on_disconnect_trigger(BLEServer *server)
static Trigger< uint16_t > * create_server_on_connect_trigger(BLEServer *server)
static Trigger< std::vector< uint8_t >, uint16_t > * create_descriptor_on_write_trigger(BLEDescriptor *descriptor)
EventEmitterListenerID on(EvtType event, std::function< void(Args...)> listener)
void off(BLECharacteristicSetValueActionEvt event, EventEmitterListenerID id)
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7