Set characteristic value previous to a notify action

This commit is contained in:
Rapsssito 2024-07-13 12:56:43 +02:00
parent 30335eaf93
commit 63e5b31fe5
2 changed files with 42 additions and 10 deletions

View file

@ -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

View file

@ -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_;