mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Add optional lambda to BLESensor for raw data parsing (#1851)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
		| @@ -4,6 +4,7 @@ from esphome.components import sensor, ble_client, esp32_ble_tracker | |||||||
| from esphome.const import ( | from esphome.const import ( | ||||||
|     DEVICE_CLASS_EMPTY, |     DEVICE_CLASS_EMPTY, | ||||||
|     CONF_ID, |     CONF_ID, | ||||||
|  |     CONF_LAMBDA, | ||||||
|     UNIT_EMPTY, |     UNIT_EMPTY, | ||||||
|     ICON_EMPTY, |     ICON_EMPTY, | ||||||
|     CONF_TRIGGER_ID, |     CONF_TRIGGER_ID, | ||||||
| @@ -20,6 +21,9 @@ CONF_DESCRIPTOR_UUID = "descriptor_uuid" | |||||||
| CONF_NOTIFY = "notify" | CONF_NOTIFY = "notify" | ||||||
| CONF_ON_NOTIFY = "on_notify" | CONF_ON_NOTIFY = "on_notify" | ||||||
|  |  | ||||||
|  | adv_data_t = cg.std_vector.template(cg.uint8) | ||||||
|  | adv_data_t_const_ref = adv_data_t.operator("ref").operator("const") | ||||||
|  |  | ||||||
| BLESensor = ble_client_ns.class_( | BLESensor = ble_client_ns.class_( | ||||||
|     "BLESensor", sensor.Sensor, cg.PollingComponent, ble_client.BLEClientNode |     "BLESensor", sensor.Sensor, cg.PollingComponent, ble_client.BLEClientNode | ||||||
| ) | ) | ||||||
| @@ -35,6 +39,7 @@ CONFIG_SCHEMA = cv.All( | |||||||
|             cv.Required(CONF_SERVICE_UUID): esp32_ble_tracker.bt_uuid, |             cv.Required(CONF_SERVICE_UUID): esp32_ble_tracker.bt_uuid, | ||||||
|             cv.Required(CONF_CHARACTERISTIC_UUID): esp32_ble_tracker.bt_uuid, |             cv.Required(CONF_CHARACTERISTIC_UUID): esp32_ble_tracker.bt_uuid, | ||||||
|             cv.Optional(CONF_DESCRIPTOR_UUID): esp32_ble_tracker.bt_uuid, |             cv.Optional(CONF_DESCRIPTOR_UUID): esp32_ble_tracker.bt_uuid, | ||||||
|  |             cv.Optional(CONF_LAMBDA): cv.returning_lambda, | ||||||
|             cv.Optional(CONF_NOTIFY, default=False): cv.boolean, |             cv.Optional(CONF_NOTIFY, default=False): cv.boolean, | ||||||
|             cv.Optional(CONF_ON_NOTIFY): automation.validate_automation( |             cv.Optional(CONF_ON_NOTIFY): automation.validate_automation( | ||||||
|                 { |                 { | ||||||
| @@ -105,6 +110,12 @@ async def to_code(config): | |||||||
|             uuid128 = esp32_ble_tracker.as_hex_array(config[CONF_DESCRIPTOR_UUID]) |             uuid128 = esp32_ble_tracker.as_hex_array(config[CONF_DESCRIPTOR_UUID]) | ||||||
|             cg.add(var.set_descr_uuid128(uuid128)) |             cg.add(var.set_descr_uuid128(uuid128)) | ||||||
|  |  | ||||||
|  |     if CONF_LAMBDA in config: | ||||||
|  |         lambda_ = await cg.process_lambda( | ||||||
|  |             config[CONF_LAMBDA], [(adv_data_t_const_ref, "x")], return_type=cg.float_ | ||||||
|  |         ) | ||||||
|  |         cg.add(var.set_data_to_value(lambda_)) | ||||||
|  |  | ||||||
|     await cg.register_component(var, config) |     await cg.register_component(var, config) | ||||||
|     await ble_client.register_ble_node(var, config) |     await ble_client.register_ble_node(var, config) | ||||||
|     cg.add(var.set_enable_notify(config[CONF_NOTIFY])) |     cg.add(var.set_enable_notify(config[CONF_NOTIFY])) | ||||||
|   | |||||||
| @@ -84,7 +84,7 @@ void BLESensor::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t ga | |||||||
|       } |       } | ||||||
|       if (param->read.handle == this->handle) { |       if (param->read.handle == this->handle) { | ||||||
|         this->status_clear_warning(); |         this->status_clear_warning(); | ||||||
|         this->publish_state((float) param->read.value[0]); |         this->publish_state(this->parse_data(param->read.value, param->read.value_len)); | ||||||
|       } |       } | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
| @@ -93,7 +93,7 @@ void BLESensor::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t ga | |||||||
|         break; |         break; | ||||||
|       ESP_LOGV(TAG, "[%s] ESP_GATTC_NOTIFY_EVT: handle=0x%x, value=0x%x", this->get_name().c_str(), |       ESP_LOGV(TAG, "[%s] ESP_GATTC_NOTIFY_EVT: handle=0x%x, value=0x%x", this->get_name().c_str(), | ||||||
|                param->notify.handle, param->notify.value[0]); |                param->notify.handle, param->notify.value[0]); | ||||||
|       this->publish_state((float) param->notify.value[0]); |       this->publish_state(this->parse_data(param->notify.value, param->notify.value_len)); | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|     case ESP_GATTC_REG_FOR_NOTIFY_EVT: { |     case ESP_GATTC_REG_FOR_NOTIFY_EVT: { | ||||||
| @@ -105,6 +105,15 @@ void BLESensor::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t ga | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | float BLESensor::parse_data(uint8_t *value, uint16_t value_len) { | ||||||
|  |   if (this->data_to_value_func_.has_value()) { | ||||||
|  |     std::vector<uint8_t> data(value, value + value_len); | ||||||
|  |     return (*this->data_to_value_func_)(data); | ||||||
|  |   } else { | ||||||
|  |     return value[0]; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| void BLESensor::update() { | void BLESensor::update() { | ||||||
|   if (this->node_state != espbt::ClientState::Established) { |   if (this->node_state != espbt::ClientState::Established) { | ||||||
|     ESP_LOGW(TAG, "[%s] Cannot poll, not connected", this->get_name().c_str()); |     ESP_LOGW(TAG, "[%s] Cannot poll, not connected", this->get_name().c_str()); | ||||||
|   | |||||||
| @@ -13,6 +13,8 @@ namespace ble_client { | |||||||
|  |  | ||||||
| namespace espbt = esphome::esp32_ble_tracker; | namespace espbt = esphome::esp32_ble_tracker; | ||||||
|  |  | ||||||
|  | using data_to_value_t = std::function<float(std::vector<uint8_t>)>; | ||||||
|  |  | ||||||
| class BLESensor : public sensor::Sensor, public PollingComponent, public BLEClientNode { | class BLESensor : public sensor::Sensor, public PollingComponent, public BLEClientNode { | ||||||
|  public: |  public: | ||||||
|   void loop() override; |   void loop() override; | ||||||
| @@ -30,11 +32,14 @@ class BLESensor : public sensor::Sensor, public PollingComponent, public BLEClie | |||||||
|   void set_descr_uuid16(uint16_t uuid) { this->descr_uuid_ = espbt::ESPBTUUID::from_uint16(uuid); } |   void set_descr_uuid16(uint16_t uuid) { this->descr_uuid_ = espbt::ESPBTUUID::from_uint16(uuid); } | ||||||
|   void set_descr_uuid32(uint32_t uuid) { this->descr_uuid_ = espbt::ESPBTUUID::from_uint32(uuid); } |   void set_descr_uuid32(uint32_t uuid) { this->descr_uuid_ = espbt::ESPBTUUID::from_uint32(uuid); } | ||||||
|   void set_descr_uuid128(uint8_t *uuid) { this->descr_uuid_ = espbt::ESPBTUUID::from_raw(uuid); } |   void set_descr_uuid128(uint8_t *uuid) { this->descr_uuid_ = espbt::ESPBTUUID::from_raw(uuid); } | ||||||
|  |   void set_data_to_value(data_to_value_t &&lambda_) { this->data_to_value_func_ = lambda_; } | ||||||
|   void set_enable_notify(bool notify) { this->notify_ = notify; } |   void set_enable_notify(bool notify) { this->notify_ = notify; } | ||||||
|   uint16_t handle; |   uint16_t handle; | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   uint32_t hash_base() override; |   uint32_t hash_base() override; | ||||||
|  |   float parse_data(uint8_t *value, uint16_t value_len); | ||||||
|  |   optional<data_to_value_t> data_to_value_func_{}; | ||||||
|   bool notify_; |   bool notify_; | ||||||
|   espbt::ESPBTUUID service_uuid_; |   espbt::ESPBTUUID service_uuid_; | ||||||
|   espbt::ESPBTUUID char_uuid_; |   espbt::ESPBTUUID char_uuid_; | ||||||
|   | |||||||
| @@ -271,6 +271,9 @@ sensor: | |||||||
|     descriptor_uuid: 'ffe2' |     descriptor_uuid: 'ffe2' | ||||||
|     notify: true |     notify: true | ||||||
|     update_interval: never |     update_interval: never | ||||||
|  |     lambda: |- | ||||||
|  |       ESP_LOGD("main", "Length of data is %i", x.size()); | ||||||
|  |       return x[0]; | ||||||
|     on_notify: |     on_notify: | ||||||
|       then: |       then: | ||||||
|         - lambda: |- |         - lambda: |- | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user