ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
ble_server_automations.h
Go to the documentation of this file.
1#pragma once
2
3#include "ble_server.h"
5#include "ble_descriptor.h"
6
8
9#include <vector>
10#include <functional>
11
12#ifdef USE_ESP32
13
14// Interface to interact with ESPHome actions and triggers
16
17using namespace esp32_ble;
18
20// Not TemplatableBytes::visit, which would copy the lambda's vector instead of moving it into the value.
21template<typename T, typename V, typename... Xs> void apply_value(T *target, const V &value, Xs &&...x) {
22 if (value.is_static()) {
23 target->set_value(value.data(), value.size());
24 } else {
25 target->set_value(value.value(x...));
26 }
27}
28
30 public:
31#ifdef USE_ESP32_BLE_SERVER_CHARACTERISTIC_ON_WRITE
33 BLECharacteristic *characteristic);
34#endif
35#ifdef USE_ESP32_BLE_SERVER_DESCRIPTOR_ON_WRITE
37#endif
38#ifdef USE_ESP32_BLE_SERVER_ON_CONNECT
40#endif
41#ifdef USE_ESP32_BLE_SERVER_ON_DISCONNECT
43#endif
44};
45
46#ifdef USE_ESP32_BLE_SERVER_SET_VALUE_ACTION
47// Class to make sure only one BLECharacteristicSetValueAction is active at a time for each characteristic
49 public:
50 // Singleton pattern
53 return &instance;
54 }
55 void set_listener(BLECharacteristic *characteristic, const std::function<void()> &pre_notify_listener);
56 bool has_listener(BLECharacteristic *characteristic) { return this->find_listener_(characteristic) != nullptr; }
57 void emit_pre_notify(BLECharacteristic *characteristic) {
58 for (const auto &entry : this->listeners_) {
59 if (entry.characteristic == characteristic) {
60 entry.pre_notify_listener();
61 break;
62 }
63 }
64 }
65
66 private:
67 struct ListenerEntry {
68 BLECharacteristic *characteristic;
69 std::function<void()> pre_notify_listener;
70 };
71 std::vector<ListenerEntry> listeners_;
72
73 ListenerEntry *find_listener_(BLECharacteristic *characteristic);
74 void remove_listener_(BLECharacteristic *characteristic);
75};
76
77template<typename... Ts> class BLECharacteristicSetValueAction final : public Action<Ts...> {
78 public:
79 BLECharacteristicSetValueAction(BLECharacteristic *characteristic) : parent_(characteristic) {}
81 void play(const Ts &...x) override {
82 // If the listener is already set, do nothing
84 return;
85 // Set initial value
86 apply_value(this->parent_, this->buffer_, x...);
87 // Set the listener for read events
88 // ``mutable`` keeps by-copy captures non-const for triggers passing args by reference
89 // (e.g. climate on_control's ClimateCall&). See #17142.
90 this->parent_->on_read([this, x...](uint16_t id) mutable {
91 // Set the value of the characteristic every time it is read
92 apply_value(this->parent_, this->buffer_, x...);
93 });
94 // Set the listener in the global manager so only one BLECharacteristicSetValueAction is set for each characteristic
96 this->parent_, [this, x...]() mutable { apply_value(this->parent_, this->buffer_, x...); });
97 }
98
99 protected:
101};
102#endif // USE_ESP32_BLE_SERVER_SET_VALUE_ACTION
103
104#ifdef USE_ESP32_BLE_SERVER_NOTIFY_ACTION
105template<typename... Ts> class BLECharacteristicNotifyAction final : public Action<Ts...> {
106 public:
107 BLECharacteristicNotifyAction(BLECharacteristic *characteristic) : parent_(characteristic) {}
108 void play(const Ts &...x) override {
109#ifdef USE_ESP32_BLE_SERVER_SET_VALUE_ACTION
110 // Call the pre-notify event
112#endif
113 // Notify the characteristic
114 this->parent_->notify();
115 }
116
117 protected:
119};
120#endif // USE_ESP32_BLE_SERVER_NOTIFY_ACTION
121
122#ifdef USE_ESP32_BLE_SERVER_DESCRIPTOR_SET_VALUE_ACTION
123template<typename... Ts> class BLEDescriptorSetValueAction final : public Action<Ts...> {
124 public:
127 void play(const Ts &...x) override { apply_value(this->parent_, this->buffer_, x...); }
128
129 protected:
131};
132#endif // USE_ESP32_BLE_SERVER_DESCRIPTOR_SET_VALUE_ACTION
133
134} // namespace esphome::esp32_ble_server::esp32_ble_server_automations
135
136#endif
virtual void play(const Ts &...x)=0
void on_read(std::function< void(uint16_t)> &&callback)
void set_listener(BLECharacteristic *characteristic, 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)
uint32_t buffer
Definition gif.cpp:50
void apply_value(T *target, const V &value, Xs &&...x)
Sets a characteristic or descriptor value from a constant flash table or a lambda's vector.
uint16_t x
Definition tt21100.cpp:5