mirror of
https://github.com/esphome/esphome.git
synced 2024-12-01 13:13:54 +01:00
Set characteristic value previous to a notify action
This commit is contained in:
parent
30335eaf93
commit
63e5b31fe5
@ -19,14 +19,32 @@ Trigger<std::vector<uint8_t>> *BLETriggers::create_on_write_trigger(BLECharacter
|
||||
}
|
||||
|
||||
void BLECharacteristicSetValueActionManager::set_listener(BLECharacteristic *characteristic,
|
||||
EventEmitterListenerID listener_id) {
|
||||
EventEmitterListenerID listener_id,
|
||||
std::function<void()> pre_notify_listener) {
|
||||
// Check if there is already a listener for this characteristic
|
||||
if (this->listeners_.find(characteristic) != this->listeners_.end()) {
|
||||
if (this->listeners_.count(characteristic) > 0) {
|
||||
// Unpack the pair listener_id, pre_notify_listener_id
|
||||
auto listener_pairs = this->listeners_[characteristic];
|
||||
EventEmitterListenerID old_listener_id = listener_pairs.first;
|
||||
EventEmitterListenerID old_pre_notify_listener_id = listener_pairs.second;
|
||||
// Remove the previous listener
|
||||
characteristic->EventEmitter<BLECharacteristicEvt::EmptyEvt>::off(BLECharacteristicEvt::EmptyEvt::ON_READ,
|
||||
this->listeners_[characteristic]);
|
||||
old_listener_id);
|
||||
// Remove the pre-notify listener
|
||||
this->off(BLECharacteristicSetValueActionEvt::PRE_NOTIFY, old_pre_notify_listener_id);
|
||||
}
|
||||
this->listeners_[characteristic] = listener_id;
|
||||
// Create a new listener for the pre-notify event
|
||||
EventEmitterListenerID pre_notify_listener_id = this->on(
|
||||
BLECharacteristicSetValueActionEvt::PRE_NOTIFY,
|
||||
[pre_notify_listener, characteristic](const BLECharacteristic *evt_characteristic) {
|
||||
// Only call the pre-notify listener if the characteristic is the one we are interested in
|
||||
if (characteristic == evt_characteristic) {
|
||||
pre_notify_listener();
|
||||
}
|
||||
}
|
||||
);
|
||||
// Save the pair listener_id, pre_notify_listener_id to the map
|
||||
this->listeners_[characteristic] = std::make_pair(listener_id, pre_notify_listener_id);
|
||||
}
|
||||
|
||||
} // namespace esp32_ble_server_automations
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
@ -22,19 +23,24 @@ class BLETriggers {
|
||||
static Trigger<std::vector<uint8_t>> *create_on_write_trigger(BLECharacteristic *characteristic);
|
||||
};
|
||||
|
||||
enum BLECharacteristicSetValueActionEvt {
|
||||
PRE_NOTIFY,
|
||||
};
|
||||
|
||||
// Class to make sure only one BLECharacteristicSetValueAction is active at a time
|
||||
class BLECharacteristicSetValueActionManager {
|
||||
class BLECharacteristicSetValueActionManager : public EventEmitter<BLECharacteristicSetValueActionEvt, BLECharacteristic *> {
|
||||
public:
|
||||
// Singleton pattern
|
||||
static BLECharacteristicSetValueActionManager *get_instance() {
|
||||
static BLECharacteristicSetValueActionManager instance;
|
||||
return &instance;
|
||||
}
|
||||
void set_listener(BLECharacteristic *characteristic, EventEmitterListenerID listener_id);
|
||||
EventEmitterListenerID get_listener(BLECharacteristic *characteristic) { return this->listeners_[characteristic]; }
|
||||
void set_listener(BLECharacteristic *characteristic, EventEmitterListenerID listener_id, std::function<void()> pre_notify_listener);
|
||||
EventEmitterListenerID get_listener(BLECharacteristic *characteristic) { return this->listeners_[characteristic].first; }
|
||||
void emit_pre_notify(BLECharacteristic *characteristic) { this->emit_(BLECharacteristicSetValueActionEvt::PRE_NOTIFY, characteristic); }
|
||||
|
||||
private:
|
||||
std::unordered_map<BLECharacteristic *, EventEmitterListenerID> listeners_;
|
||||
std::unordered_map<BLECharacteristic *, std::pair<EventEmitterListenerID, EventEmitterListenerID>> listeners_;
|
||||
};
|
||||
|
||||
template<typename... Ts> class BLECharacteristicSetValueAction : public Action<Ts...> {
|
||||
@ -54,7 +60,10 @@ template<typename... Ts> class BLECharacteristicSetValueAction : public Action<T
|
||||
this->parent_->set_value(this->value_.value(x...));
|
||||
});
|
||||
// Set the listener in the global manager so only one BLECharacteristicSetValueAction is set for each characteristic
|
||||
BLECharacteristicSetValueActionManager::get_instance()->set_listener(this->parent_, this->listener_id_);
|
||||
BLECharacteristicSetValueActionManager::get_instance()->set_listener(
|
||||
this->parent_, this->listener_id_, [this, x...]() {
|
||||
this->parent_->set_value(this->value_.value(x...));
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -65,7 +74,12 @@ template<typename... Ts> class BLECharacteristicSetValueAction : public Action<T
|
||||
template<typename... Ts> class BLECharacteristicNotifyAction : public Action<Ts...> {
|
||||
public:
|
||||
BLECharacteristicNotifyAction(BLECharacteristic *characteristic) : parent_(characteristic) {}
|
||||
void play(Ts... x) override { this->parent_->notify(); }
|
||||
void play(Ts... x) override {
|
||||
// Call the pre-notify event
|
||||
BLECharacteristicSetValueActionManager::get_instance()->emit_pre_notify(this->parent_);
|
||||
// Notify the characteristic
|
||||
this->parent_->notify();
|
||||
}
|
||||
|
||||
protected:
|
||||
BLECharacteristic *parent_;
|
||||
|
Loading…
Reference in New Issue
Block a user