1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-06 13:22:19 +01:00

feat: Add ESP32 BLE enable/disable automations (#5616)

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
Rodrigo Martín
2023-11-06 03:54:39 +01:00
committed by GitHub
parent ff8b904097
commit d5aeb32ca6
17 changed files with 446 additions and 104 deletions

View File

@@ -212,6 +212,7 @@ async def to_code(config):
parent = await cg.get_variable(config[esp32_ble.CONF_BLE_ID])
cg.add(parent.register_gap_event_handler(var))
cg.add(parent.register_gattc_event_handler(var))
cg.add(parent.register_ble_status_event_handler(var))
cg.add(var.set_parent(parent))
params = config[CONF_SCAN_PARAMETERS]

View File

@@ -64,17 +64,19 @@ void ESP32BLETracker::setup() {
}
});
#endif
if (this->scan_continuous_) {
if (xSemaphoreTake(this->scan_end_lock_, 0L)) {
this->start_scan_(true);
} else {
ESP_LOGW(TAG, "Cannot start scan!");
}
}
}
void ESP32BLETracker::loop() {
if (!this->parent_->is_active()) {
this->ble_was_disabled_ = true;
return;
} else if (this->ble_was_disabled_) {
this->ble_was_disabled_ = false;
// If the BLE stack was disabled, we need to start the scan again.
if (this->scan_continuous_) {
this->start_scan();
}
}
int connecting = 0;
int discovered = 0;
int searching = 0;
@@ -182,8 +184,7 @@ void ESP32BLETracker::loop() {
xSemaphoreGive(this->scan_end_lock_);
} else {
ESP_LOGD(TAG, "Stopping scan after failure...");
esp_ble_gap_stop_scanning();
this->cancel_timeout("scan");
this->stop_scan_();
}
if (this->scan_start_failed_) {
ESP_LOGE(TAG, "Scan start failed: %d", this->scan_start_failed_);
@@ -212,8 +213,7 @@ void ESP32BLETracker::loop() {
client->set_state(ClientState::READY_TO_CONNECT);
} else {
ESP_LOGD(TAG, "Pausing scan to make connection...");
esp_ble_gap_stop_scanning();
this->cancel_timeout("scan");
this->stop_scan_();
}
break;
}
@@ -232,11 +232,31 @@ void ESP32BLETracker::start_scan() {
void ESP32BLETracker::stop_scan() {
ESP_LOGD(TAG, "Stopping scan.");
this->scan_continuous_ = false;
esp_ble_gap_stop_scanning();
this->stop_scan_();
}
void ESP32BLETracker::ble_before_disabled_event_handler() {
this->stop_scan_();
xSemaphoreGive(this->scan_end_lock_);
}
void ESP32BLETracker::stop_scan_() {
this->cancel_timeout("scan");
if (this->scanner_idle_) {
return;
}
esp_err_t err = esp_ble_gap_stop_scanning();
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ble_gap_stop_scanning failed: %d", err);
return;
}
}
void ESP32BLETracker::start_scan_(bool first) {
if (!this->parent_->is_active()) {
ESP_LOGW(TAG, "Cannot start scan while ESP32BLE is disabled.");
return;
}
// The lock must be held when calling this function.
if (xSemaphoreTake(this->scan_end_lock_, 0L)) {
ESP_LOGE(TAG, "start_scan called without holding scan_end_lock_");
@@ -249,15 +269,23 @@ void ESP32BLETracker::start_scan_(bool first) {
listener->on_scan_end();
}
this->already_discovered_.clear();
this->scanner_idle_ = false;
this->scan_params_.scan_type = this->scan_active_ ? BLE_SCAN_TYPE_ACTIVE : BLE_SCAN_TYPE_PASSIVE;
this->scan_params_.own_addr_type = BLE_ADDR_TYPE_PUBLIC;
this->scan_params_.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL;
this->scan_params_.scan_interval = this->scan_interval_;
this->scan_params_.scan_window = this->scan_window_;
esp_ble_gap_set_scan_params(&this->scan_params_);
esp_ble_gap_start_scanning(this->scan_duration_);
esp_err_t err = esp_ble_gap_set_scan_params(&this->scan_params_);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ble_gap_set_scan_params failed: %d", err);
return;
}
err = esp_ble_gap_start_scanning(this->scan_duration_);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ble_gap_start_scanning failed: %d", err);
return;
}
this->scanner_idle_ = false;
this->set_timeout("scan", this->scan_duration_ * 2000, []() {
ESP_LOGE(TAG, "ESP-IDF BLE scan never terminated, rebooting to restore BLE stack...");

View File

@@ -177,7 +177,11 @@ class ESPBTClient : public ESPBTDeviceListener {
ClientState state_;
};
class ESP32BLETracker : public Component, public GAPEventHandler, public GATTcEventHandler, public Parented<ESP32BLE> {
class ESP32BLETracker : public Component,
public GAPEventHandler,
public GATTcEventHandler,
public BLEStatusEventHandler,
public Parented<ESP32BLE> {
public:
void set_scan_duration(uint32_t scan_duration) { scan_duration_ = scan_duration; }
void set_scan_interval(uint32_t scan_interval) { scan_interval_ = scan_interval; }
@@ -204,8 +208,10 @@ class ESP32BLETracker : public Component, public GAPEventHandler, public GATTcEv
void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
esp_ble_gattc_cb_param_t *param) override;
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override;
void ble_before_disabled_event_handler() override;
protected:
void stop_scan_();
/// Start a single scan by setting up the parameters and doing some esp-idf calls.
void start_scan_(bool first);
/// Called when a scan ends
@@ -236,6 +242,7 @@ class ESP32BLETracker : public Component, public GAPEventHandler, public GATTcEv
bool scan_continuous_;
bool scan_active_;
bool scanner_idle_;
bool ble_was_disabled_{true};
bool raw_advertisements_{false};
bool parse_advertisements_{false};
SemaphoreHandle_t scan_result_lock_;