From 116ddbdd017347abdf6ada854e8658ecd39dad7c Mon Sep 17 00:00:00 2001 From: Ashton Kemerling Date: Tue, 8 Feb 2022 01:30:31 -0700 Subject: [PATCH] Add require response option for BLE binary output (#3091) --- esphome/components/ble_client/ble_client.cpp | 8 ++++++-- esphome/components/ble_client/ble_client.h | 1 + esphome/components/ble_client/output/__init__.py | 8 +++++--- .../components/ble_client/output/ble_binary_output.cpp | 6 +++++- esphome/components/ble_client/output/ble_binary_output.h | 2 ++ 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/esphome/components/ble_client/ble_client.cpp b/esphome/components/ble_client/ble_client.cpp index 89981e8174..5b2701d77a 100644 --- a/esphome/components/ble_client/ble_client.cpp +++ b/esphome/components/ble_client/ble_client.cpp @@ -395,15 +395,19 @@ BLEDescriptor *BLECharacteristic::get_descriptor(uint16_t uuid) { return this->get_descriptor(espbt::ESPBTUUID::from_uint16(uuid)); } -void BLECharacteristic::write_value(uint8_t *new_val, int16_t new_val_size) { +void BLECharacteristic::write_value(uint8_t *new_val, int16_t new_val_size, esp_gatt_write_type_t write_type) { auto *client = this->service->client; auto status = esp_ble_gattc_write_char(client->gattc_if, client->conn_id, this->handle, new_val_size, new_val, - ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE); + write_type, ESP_GATT_AUTH_REQ_NONE); if (status) { ESP_LOGW(TAG, "Error sending write value to BLE gattc server, status=%d", status); } } +void BLECharacteristic::write_value(uint8_t *new_val, int16_t new_val_size) { + write_value(new_val, new_val_size, ESP_GATT_WRITE_TYPE_NO_RSP); +} + } // namespace ble_client } // namespace esphome diff --git a/esphome/components/ble_client/ble_client.h b/esphome/components/ble_client/ble_client.h index c173f7a995..e0a1bf61b9 100644 --- a/esphome/components/ble_client/ble_client.h +++ b/esphome/components/ble_client/ble_client.h @@ -60,6 +60,7 @@ class BLECharacteristic { BLEDescriptor *get_descriptor(espbt::ESPBTUUID uuid); BLEDescriptor *get_descriptor(uint16_t uuid); void write_value(uint8_t *new_val, int16_t new_val_size); + void write_value(uint8_t *new_val, int16_t new_val_size, esp_gatt_write_type_t write_type); BLEService *service; }; diff --git a/esphome/components/ble_client/output/__init__.py b/esphome/components/ble_client/output/__init__.py index fe5835ca82..e28421d1a7 100644 --- a/esphome/components/ble_client/output/__init__.py +++ b/esphome/components/ble_client/output/__init__.py @@ -1,13 +1,14 @@ import esphome.codegen as cg import esphome.config_validation as cv -from esphome.components import output, ble_client, esp32_ble_tracker +from esphome.components import ble_client, esp32_ble_tracker, output from esphome.const import CONF_ID, CONF_SERVICE_UUID -from .. import ble_client_ns +from .. import ble_client_ns DEPENDENCIES = ["ble_client"] CONF_CHARACTERISTIC_UUID = "characteristic_uuid" +CONF_REQUIRE_RESPONSE = "require_response" BLEBinaryOutput = ble_client_ns.class_( "BLEBinaryOutput", output.BinaryOutput, ble_client.BLEClientNode, cg.Component @@ -19,6 +20,7 @@ CONFIG_SCHEMA = cv.All( cv.Required(CONF_ID): cv.declare_id(BLEBinaryOutput), cv.Required(CONF_SERVICE_UUID): esp32_ble_tracker.bt_uuid, cv.Required(CONF_CHARACTERISTIC_UUID): esp32_ble_tracker.bt_uuid, + cv.Optional(CONF_REQUIRE_RESPONSE, default=False): cv.boolean, } ) .extend(cv.COMPONENT_SCHEMA) @@ -61,7 +63,7 @@ def to_code(config): config[CONF_CHARACTERISTIC_UUID] ) cg.add(var.set_char_uuid128(uuid128)) - + cg.add(var.set_require_response(config[CONF_REQUIRE_RESPONSE])) yield output.register_output(var, config) yield ble_client.register_ble_node(var, config) yield cg.register_component(var, config) diff --git a/esphome/components/ble_client/output/ble_binary_output.cpp b/esphome/components/ble_client/output/ble_binary_output.cpp index 7bf5ea4ead..6709803936 100644 --- a/esphome/components/ble_client/output/ble_binary_output.cpp +++ b/esphome/components/ble_client/output/ble_binary_output.cpp @@ -63,7 +63,11 @@ void BLEBinaryOutput::write_state(bool state) { uint8_t state_as_uint = (uint8_t) state; ESP_LOGV(TAG, "[%s] Write State: %d", this->char_uuid_.to_string().c_str(), state_as_uint); - chr->write_value(&state_as_uint, sizeof(state_as_uint)); + if (this->require_response_) { + chr->write_value(&state_as_uint, sizeof(state_as_uint), ESP_GATT_WRITE_TYPE_RSP); + } else { + chr->write_value(&state_as_uint, sizeof(state_as_uint), ESP_GATT_WRITE_TYPE_NO_RSP); + } } } // namespace ble_client diff --git a/esphome/components/ble_client/output/ble_binary_output.h b/esphome/components/ble_client/output/ble_binary_output.h index e1d62a267b..83eabcf5f2 100644 --- a/esphome/components/ble_client/output/ble_binary_output.h +++ b/esphome/components/ble_client/output/ble_binary_output.h @@ -25,9 +25,11 @@ class BLEBinaryOutput : public output::BinaryOutput, public BLEClientNode, publi void set_char_uuid128(uint8_t *uuid) { this->char_uuid_ = espbt::ESPBTUUID::from_raw(uuid); } 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 set_require_response(bool response) { this->require_response_ = response; } protected: void write_state(bool state) override; + bool require_response_; espbt::ESPBTUUID service_uuid_; espbt::ESPBTUUID char_uuid_; espbt::ClientState client_state_;