From 6a5eb43454dcbbcf8d41338fc2a526f77373b6e2 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Tue, 12 Oct 2021 11:56:47 +1300 Subject: [PATCH] Update Airthings BLE (#2453) --- .../airthings_wave_mini.cpp | 19 ++----- .../airthings_wave_mini/airthings_wave_mini.h | 16 +++--- .../components/airthings_wave_mini/sensor.py | 8 +-- .../airthings_wave_plus.cpp | 19 ++----- .../airthings_wave_plus/airthings_wave_plus.h | 16 +++--- .../components/airthings_wave_plus/sensor.py | 8 +-- .../esp32_ble_tracker/esp32_ble_tracker.cpp | 57 +++++++++++++++++++ .../esp32_ble_tracker/esp32_ble_tracker.h | 2 + 8 files changed, 89 insertions(+), 56 deletions(-) diff --git a/esphome/components/airthings_wave_mini/airthings_wave_mini.cpp b/esphome/components/airthings_wave_mini/airthings_wave_mini.cpp index 0ab0e65148..6b6418f7e6 100644 --- a/esphome/components/airthings_wave_mini/airthings_wave_mini.cpp +++ b/esphome/components/airthings_wave_mini/airthings_wave_mini.cpp @@ -1,6 +1,6 @@ #include "airthings_wave_mini.h" -#ifdef USE_ESP32_FRAMEWORK_ARDUINO +#ifdef USE_ESP32 namespace esphome { namespace airthings_wave_mini { @@ -75,8 +75,6 @@ void AirthingsWaveMini::read_sensors_(uint8_t *raw_value, uint16_t value_len) { bool AirthingsWaveMini::is_valid_voc_value_(uint16_t voc) { return 0 <= voc && voc <= 16383; } -void AirthingsWaveMini::loop() {} - void AirthingsWaveMini::update() { if (this->node_state != esp32_ble_tracker::ClientState::ESTABLISHED) { if (!parent()->enabled) { @@ -104,17 +102,12 @@ void AirthingsWaveMini::dump_config() { LOG_SENSOR(" ", "TVOC", this->tvoc_sensor_); } -AirthingsWaveMini::AirthingsWaveMini() : PollingComponent(10000) { - auto service_bt = *BLEUUID::fromString(std::string("b42e3882-ade7-11e4-89d3-123b93f75cba")).getNative(); - auto characteristic_bt = *BLEUUID::fromString(std::string("b42e3b98-ade7-11e4-89d3-123b93f75cba")).getNative(); - - service_uuid_ = esp32_ble_tracker::ESPBTUUID::from_uuid(service_bt); - sensors_data_characteristic_uuid_ = esp32_ble_tracker::ESPBTUUID::from_uuid(characteristic_bt); -} - -void AirthingsWaveMini::setup() {} +AirthingsWaveMini::AirthingsWaveMini() + : PollingComponent(10000), + service_uuid_(esp32_ble_tracker::ESPBTUUID::from_raw(SERVICE_UUID)), + sensors_data_characteristic_uuid_(esp32_ble_tracker::ESPBTUUID::from_raw(CHARACTERISTIC_UUID)) {} } // namespace airthings_wave_mini } // namespace esphome -#endif // USE_ESP32_FRAMEWORK_ARDUINO +#endif // USE_ESP32 diff --git a/esphome/components/airthings_wave_mini/airthings_wave_mini.h b/esphome/components/airthings_wave_mini/airthings_wave_mini.h index 5d1964d559..128774f9cb 100644 --- a/esphome/components/airthings_wave_mini/airthings_wave_mini.h +++ b/esphome/components/airthings_wave_mini/airthings_wave_mini.h @@ -1,28 +1,28 @@ #pragma once -#ifdef USE_ESP32_FRAMEWORK_ARDUINO +#ifdef USE_ESP32 +#include #include #include -#include -#include -#include "esphome/core/component.h" -#include "esphome/core/log.h" #include "esphome/components/ble_client/ble_client.h" #include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h" #include "esphome/components/sensor/sensor.h" +#include "esphome/core/component.h" +#include "esphome/core/log.h" namespace esphome { namespace airthings_wave_mini { +static const char *const SERVICE_UUID = "b42e3882-ade7-11e4-89d3-123b93f75cba"; +static const char *const CHARACTERISTIC_UUID = "b42e3b98-ade7-11e4-89d3-123b93f75cba"; + class AirthingsWaveMini : public PollingComponent, public ble_client::BLEClientNode { public: AirthingsWaveMini(); - void setup() override; void dump_config() override; void update() override; - void loop() override; void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) override; @@ -62,4 +62,4 @@ class AirthingsWaveMini : public PollingComponent, public ble_client::BLEClientN } // namespace airthings_wave_mini } // namespace esphome -#endif // USE_ESP32_FRAMEWORK_ARDUINO +#endif // USE_ESP32 diff --git a/esphome/components/airthings_wave_mini/sensor.py b/esphome/components/airthings_wave_mini/sensor.py index 6a32cd8771..d38354fa84 100644 --- a/esphome/components/airthings_wave_mini/sensor.py +++ b/esphome/components/airthings_wave_mini/sensor.py @@ -1,7 +1,6 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome.components import sensor, ble_client -from esphome.core import CORE from esphome.const import ( DEVICE_CLASS_HUMIDITY, @@ -58,10 +57,8 @@ CONFIG_SCHEMA = cv.All( ), } ) - .extend(cv.polling_component_schema("5mins")) + .extend(cv.polling_component_schema("5min")) .extend(ble_client.BLE_CLIENT_SCHEMA), - # Until BLEUUID reference removed - cv.only_with_arduino, ) @@ -83,6 +80,3 @@ async def to_code(config): if CONF_TVOC in config: sens = await sensor.new_sensor(config[CONF_TVOC]) cg.add(var.set_tvoc(sens)) - - if CORE.is_esp32: - cg.add_library("ESP32 BLE Arduino", None) diff --git a/esphome/components/airthings_wave_plus/airthings_wave_plus.cpp b/esphome/components/airthings_wave_plus/airthings_wave_plus.cpp index 0eaffbd889..79f2cb7741 100644 --- a/esphome/components/airthings_wave_plus/airthings_wave_plus.cpp +++ b/esphome/components/airthings_wave_plus/airthings_wave_plus.cpp @@ -1,6 +1,6 @@ #include "airthings_wave_plus.h" -#ifdef USE_ESP32_FRAMEWORK_ARDUINO +#ifdef USE_ESP32 namespace esphome { namespace airthings_wave_plus { @@ -96,8 +96,6 @@ bool AirthingsWavePlus::is_valid_voc_value_(uint16_t voc) { return 0 <= voc && v bool AirthingsWavePlus::is_valid_co2_value_(uint16_t co2) { return 0 <= co2 && co2 <= 16383; } -void AirthingsWavePlus::loop() {} - void AirthingsWavePlus::update() { if (this->node_state != esp32_ble_tracker::ClientState::ESTABLISHED) { if (!parent()->enabled) { @@ -128,17 +126,12 @@ void AirthingsWavePlus::dump_config() { LOG_SENSOR(" ", "TVOC", this->tvoc_sensor_); } -AirthingsWavePlus::AirthingsWavePlus() : PollingComponent(10000) { - auto service_bt = *BLEUUID::fromString(std::string("b42e1c08-ade7-11e4-89d3-123b93f75cba")).getNative(); - auto characteristic_bt = *BLEUUID::fromString(std::string("b42e2a68-ade7-11e4-89d3-123b93f75cba")).getNative(); - - service_uuid_ = esp32_ble_tracker::ESPBTUUID::from_uuid(service_bt); - sensors_data_characteristic_uuid_ = esp32_ble_tracker::ESPBTUUID::from_uuid(characteristic_bt); -} - -void AirthingsWavePlus::setup() {} +AirthingsWavePlus::AirthingsWavePlus() + : PollingComponent(10000), + service_uuid_(esp32_ble_tracker::ESPBTUUID::from_raw(SERVICE_UUID)), + sensors_data_characteristic_uuid_(esp32_ble_tracker::ESPBTUUID::from_raw(CHARACTERISTIC_UUID)) {} } // namespace airthings_wave_plus } // namespace esphome -#endif // USE_ESP32_FRAMEWORK_ARDUINO +#endif // USE_ESP32 diff --git a/esphome/components/airthings_wave_plus/airthings_wave_plus.h b/esphome/components/airthings_wave_plus/airthings_wave_plus.h index 5677f05a62..9dd6ed92d5 100644 --- a/esphome/components/airthings_wave_plus/airthings_wave_plus.h +++ b/esphome/components/airthings_wave_plus/airthings_wave_plus.h @@ -1,28 +1,28 @@ #pragma once -#ifdef USE_ESP32_FRAMEWORK_ARDUINO +#ifdef USE_ESP32 +#include #include #include -#include -#include -#include "esphome/core/component.h" -#include "esphome/core/log.h" #include "esphome/components/ble_client/ble_client.h" #include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h" #include "esphome/components/sensor/sensor.h" +#include "esphome/core/component.h" +#include "esphome/core/log.h" namespace esphome { namespace airthings_wave_plus { +static const char *const SERVICE_UUID = "b42e1c08-ade7-11e4-89d3-123b93f75cba"; +static const char *const CHARACTERISTIC_UUID = "b42e2a68-ade7-11e4-89d3-123b93f75cba"; + class AirthingsWavePlus : public PollingComponent, public ble_client::BLEClientNode { public: AirthingsWavePlus(); - void setup() override; void dump_config() override; void update() override; - void loop() override; void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) override; @@ -72,4 +72,4 @@ class AirthingsWavePlus : public PollingComponent, public ble_client::BLEClientN } // namespace airthings_wave_plus } // namespace esphome -#endif // USE_ESP32_FRAMEWORK_ARDUINO +#endif // USE_ESP32 diff --git a/esphome/components/airthings_wave_plus/sensor.py b/esphome/components/airthings_wave_plus/sensor.py index 2100341536..727fbe15fb 100644 --- a/esphome/components/airthings_wave_plus/sensor.py +++ b/esphome/components/airthings_wave_plus/sensor.py @@ -1,7 +1,6 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome.components import sensor, ble_client -from esphome.core import CORE from esphome.const import ( DEVICE_CLASS_CARBON_DIOXIDE, @@ -83,10 +82,8 @@ CONFIG_SCHEMA = cv.All( ), } ) - .extend(cv.polling_component_schema("5mins")) + .extend(cv.polling_component_schema("5min")) .extend(ble_client.BLE_CLIENT_SCHEMA), - # Until BLEUUID reference removed - cv.only_with_arduino, ) @@ -117,6 +114,3 @@ async def to_code(config): if CONF_TVOC in config: sens = await sensor.new_sensor(config[CONF_TVOC]) cg.add(var.set_tvoc(sens)) - - if CORE.is_esp32: - cg.add_library("ESP32 BLE Arduino", None) diff --git a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp index 95176bb179..65749f5124 100644 --- a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +++ b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp @@ -317,6 +317,63 @@ ESPBTUUID ESPBTUUID::from_raw(const uint8_t *data) { ret.uuid_.uuid.uuid128[i] = data[i]; return ret; } +ESPBTUUID ESPBTUUID::from_raw(const std::string &data) { + ESPBTUUID ret; + if (data.length() == 4) { + ret.uuid_.len = ESP_UUID_LEN_16; + ret.uuid_.uuid.uuid16 = 0; + for (int i = 0; i < data.length();) { + uint8_t msb = data.c_str()[i]; + uint8_t lsb = data.c_str()[i + 1]; + + if (msb > '9') + msb -= 7; + if (lsb > '9') + lsb -= 7; + ret.uuid_.uuid.uuid16 += (((msb & 0x0F) << 4) | (lsb & 0x0F)) << (2 - i) * 4; + i += 2; + } + } else if (data.length() == 8) { + ret.uuid_.len = ESP_UUID_LEN_32; + ret.uuid_.uuid.uuid32 = 0; + for (int i = 0; i < data.length();) { + uint8_t msb = data.c_str()[i]; + uint8_t lsb = data.c_str()[i + 1]; + + if (msb > '9') + msb -= 7; + if (lsb > '9') + lsb -= 7; + ret.uuid_.uuid.uuid32 += (((msb & 0x0F) << 4) | (lsb & 0x0F)) << (6 - i) * 4; + i += 2; + } + } else if (data.length() == 16) { // how we can have 16 byte length string reprezenting 128 bit uuid??? needs to be + // investigated (lack of time) + ret.uuid_.len = ESP_UUID_LEN_128; + memcpy(ret.uuid_.uuid.uuid128, (uint8_t *) data.data(), 16); + } else if (data.length() == 36) { + // If the length of the string is 36 bytes then we will assume it is a long hex string in + // UUID format. + ret.uuid_.len = ESP_UUID_LEN_128; + int n = 0; + for (int i = 0; i < data.length();) { + if (data.c_str()[i] == '-') + i++; + uint8_t msb = data.c_str()[i]; + uint8_t lsb = data.c_str()[i + 1]; + + if (msb > '9') + msb -= 7; + if (lsb > '9') + lsb -= 7; + ret.uuid_.uuid.uuid128[15 - n++] = ((msb & 0x0F) << 4) | (lsb & 0x0F); + i += 2; + } + } else { + ESP_LOGE(TAG, "ERROR: UUID value not 2, 4, 16 or 36 bytes - %s", data.c_str()); + } + return ret; +} ESPBTUUID ESPBTUUID::from_uuid(esp_bt_uuid_t uuid) { ESPBTUUID ret; ret.uuid_.len = uuid.len; diff --git a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.h b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.h index 71885a564f..1308119df5 100644 --- a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +++ b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.h @@ -25,6 +25,8 @@ class ESPBTUUID { static ESPBTUUID from_raw(const uint8_t *data); + static ESPBTUUID from_raw(const std::string &data); + static ESPBTUUID from_uuid(esp_bt_uuid_t uuid); ESPBTUUID as_128bit() const;