From 93f9d4a1ad9776ed50d45bb173bef572d67c14b5 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 9 Aug 2026 03:13:06 -0500 Subject: [PATCH] Apply review: state before fan-out, refusal breadcrumbs, write status log --- esphome/components/ble_client/__init__.py | 2 ++ esphome/components/ble_client/automation_gatt.h | 4 ++++ esphome/components/ble_client/ble_client_gatt.cpp | 6 +++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/esphome/components/ble_client/__init__.py b/esphome/components/ble_client/__init__.py index 2c911921c5..cf07290ce6 100644 --- a/esphome/components/ble_client/__init__.py +++ b/esphome/components/ble_client/__init__.py @@ -56,6 +56,8 @@ FILTER_SOURCE_FILES = filter_source_files_from_platform( PlatformFramework.ESP32_ARDUINO, PlatformFramework.ESP32_IDF, }, + # Every framework of every bluetooth_connection.GATT_CLIENT_PLATFORMS + # entry except esp32; extend when the registry gains a platform. "ble_client_gatt.cpp": {PlatformFramework.RP2_ARDUINO}, } ) diff --git a/esphome/components/ble_client/automation_gatt.h b/esphome/components/ble_client/automation_gatt.h index 74826c7843..98f70401eb 100644 --- a/esphome/components/ble_client/automation_gatt.h +++ b/esphome/components/ble_client/automation_gatt.h @@ -149,6 +149,10 @@ template class BLEClientWriteAction final : public Action void on_write_result(uint16_t handle, int error) override { if (this->resolved_ && handle == this->char_handle_ && this->num_running_ != 0) { + if (error != 0) { + // Continue the chain (legacy parity) but leave a breadcrumb. + esph_log_w(Automation::TAG, "Write completed with status %d", error); + } this->ble_client_->run_later([this]() { this->play_next_tuple_(this->var_); }); } } diff --git a/esphome/components/ble_client/ble_client_gatt.cpp b/esphome/components/ble_client/ble_client_gatt.cpp index 40af81e506..2938fc899b 100644 --- a/esphome/components/ble_client/ble_client_gatt.cpp +++ b/esphome/components/ble_client/ble_client_gatt.cpp @@ -95,6 +95,8 @@ void BLEClient::on_connection_state(bool connected, uint16_t mtu, int error) { this->state_ = State::DISCOVERING; if (this->backend_->discover_services() != 0) { // Synchronous refusal: no discovery completion will follow. + ESP_LOGW(TAG, "[%s] Service discovery refused", this->address_str_); + this->register_failure_(); this->disconnect(); } return; @@ -130,12 +132,14 @@ void BLEClient::on_service_discovery_done(int error) { this->disconnect(); return; } + // CONNECTED before the fan-out so nodes may consult connected() from + // their own on_connected(). + this->state_ = State::CONNECTED; auto table = this->backend_->get_service_table(); for (auto *node : this->nodes_) { node->on_connected(table); } this->backend_->release_services(); - this->state_ = State::CONNECTED; this->consecutive_failures_ = 0; this->hold_off_ms_ = 0; ESP_LOGI(TAG, "[%s] Connected", this->address_str_);