Skip to content

Commit

Permalink
Refactoring and various optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
myhomeiot committed Dec 6, 2021
1 parent f6c837e commit 80b5ff3
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 108 deletions.
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ BLE Gateway component will allow you to forward BLE Advertising data packets for
If the heart of your Home Automation system is Home Assistant or another similar system and you use [ESPHome](https://esphome.io) devices to extend BLE coverage and process data from BLE sensors, you can dramatically decrease system complexity by remove all BLE data processing from ESPHome devices and forward raw BLE Advertising data to external components like [Passive BLE Monitor](https://github.com/custom-components/ble_monitor).

**Important note:** Currently in order to run BLE Gateway you need to make [some changes](https://github.com/esphome/esphome/pull/2854) in ESPHome `esp32_ble_tracker` component, I make PR and hopefully it will be accepted.
[Passive BLE Monitor](https://github.com/custom-components/ble_monitor) integration already has required support, thanks to [@Ernst79](https://github.com/Ernst79), please update it to version 6.2 or latest.
[Passive BLE Monitor](https://github.com/custom-components/ble_monitor) integration already has required support, thanks to [@Ernst79](https://github.com/Ernst79), please update it to version 6.2 or later.

#### ESPHome configuration example
Note: This example use [event](https://esphome.io/components/api.html#homeassistant-event-action), you can use direct `ble_monitor.parse_data` [service call](https://esphome.io/components/api.html#homeassistant-service-action)
Expand All @@ -44,10 +44,10 @@ ble_gateway:
- mac_address: !secret lywsd03mmc_mac
on_ble_advertise:
then:
- homeassistant.event:
event: esphome.on_ble_advertise
data:
packet: !lambda return packet;
homeassistant.event:
event: esphome.on_ble_advertise
data:
packet: !lambda return packet;
```

#### Home Assistant Passive BLE Monitor configuration example
Expand Down Expand Up @@ -86,10 +86,10 @@ ble_gateway:
id: blegateway
on_ble_advertise:
then:
- homeassistant.event:
event: esphome.on_ble_advertise
data:
packet: !lambda return packet;
homeassistant.event:
event: esphome.on_ble_advertise
data:
packet: !lambda return packet;
text_sensor:
- platform: homeassistant
Expand All @@ -98,7 +98,7 @@ text_sensor:
attribute: devices
on_value:
then:
- lambda: id(blegateway).set_devices(x);
lambda: id(blegateway).set_devices(x);
# Home Assistant
input_boolean:
Expand Down
4 changes: 2 additions & 2 deletions components/ble_gateway/ble_gateway.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#ifdef USE_ESP32

#include "ble_gateway.h"
#include "esphome/core/log.h"

#ifdef USE_ESP32

namespace esphome {
namespace ble_gateway {

Expand Down
7 changes: 3 additions & 4 deletions components/ble_gateway/ble_gateway.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
#pragma once

#include "esphome/core/component.h"
#include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h"

#ifdef USE_ESP32

#include "esphome/core/component.h"
#include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h"
#include "esphome/core/automation.h"

namespace esphome {
Expand All @@ -23,7 +22,7 @@ class BLEGateway : public Component, public esp32_ble_tracker::ESPBTDeviceListen
void set_devices(std::string devices);
protected:
std::vector<uint64_t> devices_{};
CallbackManager<void(const esp32_ble_tracker::ESPBTDevice &, std::string)> callback_;
CallbackManager<void(const esp32_ble_tracker::ESPBTDevice &, std::string)> callback_{};
};

class BLEGatewayBLEAdvertiseTrigger : public Trigger<const esp32_ble_tracker::ESPBTDevice &, std::string> {
Expand Down
3 changes: 2 additions & 1 deletion components/myhomeiot_ble_client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
MyHomeIOT_BLEClient = myhomeiot_ble_client_ns.class_(
"MyHomeIOT_BLEClient", cg.Component
)
MyHomeIOT_BLEClientConstRef = MyHomeIOT_BLEClient.operator("ref").operator("const")

# Triggers
MyHomeIOT_BLEClientValueTrigger = myhomeiot_ble_client_ns.class_(
Expand Down Expand Up @@ -76,4 +77,4 @@ async def to_code(config):

for conf in config.get(CONF_ON_VALUE, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
await automation.build_automation(trigger, [(cg.std_vector.template(cg.uint8), "x")], conf)
await automation.build_automation(trigger, [(cg.std_vector.template(cg.uint8), "x"), (MyHomeIOT_BLEClientConstRef, "xthis")], conf)
21 changes: 0 additions & 21 deletions components/myhomeiot_ble_client/automation.h

This file was deleted.

99 changes: 49 additions & 50 deletions components/myhomeiot_ble_client/myhomeiot_ble_client.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#include "myhomeiot_ble_client.h"
#include "esphome/core/log.h"

#ifdef ARDUINO_ARCH_ESP32

#include <esp_gap_ble_api.h>
#include "esphome/core/log.h"
#include "myhomeiot_ble_client.h"

namespace esphome {
namespace myhomeiot_ble_client {
Expand All @@ -16,7 +15,7 @@ void MyHomeIOT_BLEClient::setup() {

void MyHomeIOT_BLEClient::dump_config() {
ESP_LOGCONFIG(TAG, "MyHomeIOT BLE Client");
ESP_LOGCONFIG(TAG, " MAC address: %s", to_string(this->address).c_str());
ESP_LOGCONFIG(TAG, " MAC address: %s", to_string(this->address_).c_str());
ESP_LOGCONFIG(TAG, " Service UUID: %s", this->service_uuid_.to_string().c_str());
ESP_LOGCONFIG(TAG, " Characteristic UUID: %s", this->char_uuid_.to_string().c_str());
LOG_UPDATE_INTERVAL(this);
Expand All @@ -30,31 +29,31 @@ void MyHomeIOT_BLEClient::loop() {
}

void MyHomeIOT_BLEClient::connect() {
ESP_LOGI(TAG, "[%s] Connecting", to_string(this->address).c_str());
ESP_LOGI(TAG, "[%s] Connecting", to_string(this->address_).c_str());
this->state_ = MYHOMEIOT_CONNECTING;
if (auto status = esp_ble_gattc_open(ble_host_->gattc_if, this->remote_bda, BLE_ADDR_TYPE_PUBLIC, true))
if (auto status = esp_ble_gattc_open(ble_host_->gattc_if, this->remote_bda_, BLE_ADDR_TYPE_PUBLIC, true))
{
ESP_LOGW(TAG, "[%s] open error, status (%d)", to_string(this->address).c_str(), status);
ESP_LOGW(TAG, "[%s] open error, status (%d)", to_string(this->address_).c_str(), status);
report_error(MYHOMEIOT_IDLE);
}
}

void MyHomeIOT_BLEClient::disconnect() {
ESP_LOGI(TAG, "[%s] Disconnecting", to_string(this->address).c_str());
ESP_LOGI(TAG, "[%s] Disconnecting", to_string(this->address_).c_str());
this->state_ = MYHOMEIOT_IDLE;
if (auto status = esp_ble_gattc_close(ble_host_->gattc_if, this->conn_id))
ESP_LOGW(TAG, "[%s] close error, status (%d)", to_string(this->address).c_str(), status);
if (auto status = esp_ble_gattc_close(ble_host_->gattc_if, this->conn_id_))
ESP_LOGW(TAG, "[%s] close error, status (%d)", to_string(this->address_).c_str(), status);
}

void MyHomeIOT_BLEClient::update() {
this->is_update_requested = true;
this->is_update_requested_ = true;
}

void MyHomeIOT_BLEClient::report_results(uint8_t *data, uint16_t len) {
this->status_clear_warning();
std::vector<uint8_t> ret(data, data + len);
this->callback_.call(ret);
this->is_update_requested = false;
std::vector<uint8_t> value(data, data + len);
this->callback_.call(value, *this);
this->is_update_requested_ = false;
}

void MyHomeIOT_BLEClient::report_error(esp32_ble_tracker::ClientState state) {
Expand All @@ -63,12 +62,12 @@ void MyHomeIOT_BLEClient::report_error(esp32_ble_tracker::ClientState state) {
}

bool MyHomeIOT_BLEClient::parse_device(const esp32_ble_tracker::ESPBTDevice &device) {
if (!this->is_update_requested || this->state_ != MYHOMEIOT_IDLE
|| device.address_uint64() != this->address)
if (!this->is_update_requested_ || this->state_ != MYHOMEIOT_IDLE
|| device.address_uint64() != this->address_)
return false;

ESP_LOGD(TAG, "[%s] Found device", device.address_str().c_str());
memcpy(this->remote_bda, device.address(), sizeof(this->remote_bda));
memcpy(this->remote_bda_, device.address(), sizeof(this->remote_bda_));
this->state_ = MYHOMEIOT_DISCOVERED;
return true;
}
Expand All @@ -77,71 +76,71 @@ void MyHomeIOT_BLEClient::gattc_event_handler(esp_gattc_cb_event_t event, esp_ga
esp_ble_gattc_cb_param_t *param) {
switch (event) {
case ESP_GATTC_OPEN_EVT: {
if (memcmp(param->open.remote_bda, this->remote_bda, sizeof(this->remote_bda)) != 0)
if (memcmp(param->open.remote_bda, this->remote_bda_, sizeof(this->remote_bda_)) != 0)
break;
if (param->open.status != ESP_GATT_OK) {
ESP_LOGW(TAG, "[%s] OPEN_EVT failed, status (%d), app_id (%d)", to_string(this->address).c_str(),
ESP_LOGW(TAG, "[%s] OPEN_EVT failed, status (%d), app_id (%d)", to_string(this->address_).c_str(),
param->open.status, ble_host_->app_id);
report_error(MYHOMEIOT_IDLE);
break;
}
ESP_LOGI(TAG, "[%s] Connected successfully, app_id (%d)", to_string(this->address).c_str(), ble_host_->app_id);
this->conn_id = param->open.conn_id;
ESP_LOGI(TAG, "[%s] Connected successfully, app_id (%d)", to_string(this->address_).c_str(), ble_host_->app_id);
this->conn_id_ = param->open.conn_id;
if (auto status = esp_ble_gattc_send_mtu_req(ble_host_->gattc_if, param->open.conn_id))
{
ESP_LOGW(TAG, "[%s] send_mtu_req failed, status (%d)", to_string(this->address).c_str(), status);
ESP_LOGW(TAG, "[%s] send_mtu_req failed, status (%d)", to_string(this->address_).c_str(), status);
report_error();
break;
}
this->start_handle = this->end_handle = this->char_handle = ESP_GATT_ILLEGAL_HANDLE;
this->start_handle_ = this->end_handle_ = this->char_handle_ = ESP_GATT_ILLEGAL_HANDLE;
this->state_ = MYHOMEIOT_CONNECTED;
break;
}
case ESP_GATTC_CFG_MTU_EVT: {
if (param->cfg_mtu.conn_id != this->conn_id)
if (param->cfg_mtu.conn_id != this->conn_id_)
break;
if (param->cfg_mtu.status != ESP_GATT_OK) {
ESP_LOGW(TAG, "[%s] CFG_MTU_EVT failed, status (%d)", to_string(this->address).c_str(),
ESP_LOGW(TAG, "[%s] CFG_MTU_EVT failed, status (%d)", to_string(this->address_).c_str(),
param->cfg_mtu.status);
report_error();
break;
}
ESP_LOGV(TAG, "[%s] CFG_MTU_EVT, MTU (%d)", to_string(this->address).c_str(), param->cfg_mtu.mtu);
ESP_LOGV(TAG, "[%s] CFG_MTU_EVT, MTU (%d)", to_string(this->address_).c_str(), param->cfg_mtu.mtu);
if (auto status = esp_ble_gattc_search_service(esp_gattc_if, param->cfg_mtu.conn_id, nullptr)) {
ESP_LOGW(TAG, "[%s] search_service failed, status (%d)", to_string(this->address).c_str(), status);
ESP_LOGW(TAG, "[%s] search_service failed, status (%d)", to_string(this->address_).c_str(), status);
report_error();
}
break;
}
case ESP_GATTC_DISCONNECT_EVT: {
if (memcmp(param->disconnect.remote_bda, this->remote_bda, sizeof(this->remote_bda)) != 0)
if (memcmp(param->disconnect.remote_bda, this->remote_bda_, sizeof(this->remote_bda_)) != 0)
break;
ESP_LOGD(TAG, "[%s] DISCONNECT_EVT", to_string(this->address).c_str());
ESP_LOGD(TAG, "[%s] DISCONNECT_EVT", to_string(this->address_).c_str());
this->state_ = MYHOMEIOT_IDLE;
break;
}
case ESP_GATTC_SEARCH_RES_EVT: {
if (param->search_res.conn_id != this->conn_id)
if (param->search_res.conn_id != this->conn_id_)
break;
esp32_ble_tracker::ESPBTUUID uuid = param->search_res.srvc_id.uuid.len == ESP_UUID_LEN_16 ? esp32_ble_tracker::ESPBTUUID::from_uint16(param->search_res.srvc_id.uuid.uuid.uuid16)
: param->search_res.srvc_id.uuid.len == ESP_UUID_LEN_32 ? esp32_ble_tracker::ESPBTUUID::from_uint32(param->search_res.srvc_id.uuid.uuid.uuid32)
: esp32_ble_tracker::ESPBTUUID::from_raw(param->search_res.srvc_id.uuid.uuid.uuid128);
if (uuid == this->service_uuid_) {
ESP_LOGD(TAG, "[%s] SEARCH_RES_EVT service (%s) found", to_string(this->address).c_str(),
ESP_LOGD(TAG, "[%s] SEARCH_RES_EVT service (%s) found", to_string(this->address_).c_str(),
this->service_uuid_.to_string().c_str());
start_handle = param->search_res.start_handle;
end_handle = param->search_res.end_handle;
this->start_handle_ = param->search_res.start_handle;
this->end_handle_ = param->search_res.end_handle;
}
break;
}
case ESP_GATTC_SEARCH_CMPL_EVT: {
if (param->search_cmpl.conn_id != this->conn_id)
if (param->search_cmpl.conn_id != this->conn_id_)
break;
ESP_LOGV(TAG, "[%s] SEARCH_CMPL_EVT", to_string(this->address).c_str());
ESP_LOGV(TAG, "[%s] SEARCH_CMPL_EVT", to_string(this->address_).c_str());

if (this->start_handle == ESP_GATT_ILLEGAL_HANDLE)
if (this->start_handle_ == ESP_GATT_ILLEGAL_HANDLE)
{
ESP_LOGE(TAG, "[%s] SEARCH_CMPL_EVT service (%s) not found", to_string(this->address).c_str(),
ESP_LOGE(TAG, "[%s] SEARCH_CMPL_EVT service (%s) not found", to_string(this->address_).c_str(),
this->service_uuid_.to_string().c_str());
report_error();
break;
Expand All @@ -151,47 +150,47 @@ void MyHomeIOT_BLEClient::gattc_event_handler(esp_gattc_cb_event_t event, esp_ga
esp_gattc_char_elem_t result;
while (true) {
uint16_t count = 1;
auto status = esp_ble_gattc_get_all_char(ble_host_->gattc_if, this->conn_id,
this->start_handle, this->end_handle, &result, &count, offset);
auto status = esp_ble_gattc_get_all_char(ble_host_->gattc_if, this->conn_id_,
this->start_handle_, this->end_handle_, &result, &count, offset);
if (status != ESP_GATT_OK) {
if (status == ESP_GATT_INVALID_OFFSET || status == ESP_GATT_NOT_FOUND)
break;
ESP_LOGW(TAG, "[%s] get_all_char error, status (%d)", to_string(this->address).c_str(), status);
ESP_LOGW(TAG, "[%s] get_all_char error, status (%d)", to_string(this->address_).c_str(), status);
report_error();
break;
}
if (count == 0)
break;

if (this->char_uuid_ == esp32_ble_tracker::ESPBTUUID::from_uuid(result.uuid)) {
ESP_LOGD(TAG, "[%s] SEARCH_CMPL_EVT char (%s) found", to_string(this->address).c_str(),
ESP_LOGD(TAG, "[%s] SEARCH_CMPL_EVT char (%s) found", to_string(this->address_).c_str(),
this->char_uuid_.to_string().c_str());
this->char_handle = result.char_handle;
this->char_handle_ = result.char_handle;

if (auto status = esp_ble_gattc_read_char(ble_host_->gattc_if, this->conn_id,
this->char_handle, ESP_GATT_AUTH_REQ_NONE) != ESP_GATT_OK) {
if (auto status = esp_ble_gattc_read_char(ble_host_->gattc_if, this->conn_id_,
this->char_handle_, ESP_GATT_AUTH_REQ_NONE) != ESP_GATT_OK) {
ESP_LOGW(TAG, "[%s] read_char error sending read request, status (%d)",
to_string(this->address).c_str(), status);
this->char_handle = ESP_GATT_ILLEGAL_HANDLE;
to_string(this->address_).c_str(), status);
this->char_handle_ = ESP_GATT_ILLEGAL_HANDLE;
}
break;
}
offset++;
}
if (this->char_handle == ESP_GATT_ILLEGAL_HANDLE)
if (this->char_handle_ == ESP_GATT_ILLEGAL_HANDLE)
{
ESP_LOGE(TAG, "[%s] SEARCH_CMPL_EVT char (%s) not found", to_string(this->address).c_str(),
ESP_LOGE(TAG, "[%s] SEARCH_CMPL_EVT char (%s) not found", to_string(this->address_).c_str(),
this->char_uuid_.to_string().c_str());
report_error();
}
break;
}
case ESP_GATTC_READ_CHAR_EVT: {
if (param->read.conn_id != this->conn_id || param->read.handle != this->char_handle)
if (param->read.conn_id != this->conn_id_ || param->read.handle != this->char_handle_)
break;
if (param->read.status != ESP_GATT_OK)
{
ESP_LOGW(TAG, "[%s] READ_CHAR_EVT error reading char at handle (%d), status (%d)", to_string(this->address).c_str(),
ESP_LOGW(TAG, "[%s] READ_CHAR_EVT error reading char at handle (%d), status (%d)", to_string(this->address_).c_str(),
param->read.handle, param->read.status);
report_error();
break;
Expand Down
Loading

0 comments on commit 80b5ff3

Please sign in to comment.