From 6daeffcefda4f91eb1e0ee1e720073dce496068e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 31 Aug 2025 20:07:29 -0500 Subject: [PATCH] [bluetooth_proxy] Expose configured scanning mode in API responses (#10490) --- esphome/components/api/api.proto | 1 + esphome/components/api/api_pb2.cpp | 2 ++ esphome/components/api/api_pb2.h | 3 ++- esphome/components/api/api_pb2_dump.cpp | 1 + esphome/components/bluetooth_proxy/bluetooth_proxy.cpp | 6 ++++++ esphome/components/bluetooth_proxy/bluetooth_proxy.h | 3 ++- 6 files changed, 14 insertions(+), 2 deletions(-) diff --git a/esphome/components/api/api.proto b/esphome/components/api/api.proto index 6b19f2026a..9707e714e7 100644 --- a/esphome/components/api/api.proto +++ b/esphome/components/api/api.proto @@ -1712,6 +1712,7 @@ message BluetoothScannerStateResponse { BluetoothScannerState state = 1; BluetoothScannerMode mode = 2; + BluetoothScannerMode configured_mode = 3; } message BluetoothScannerSetModeRequest { diff --git a/esphome/components/api/api_pb2.cpp b/esphome/components/api/api_pb2.cpp index 476e3c88d0..de60ed3fdb 100644 --- a/esphome/components/api/api_pb2.cpp +++ b/esphome/components/api/api_pb2.cpp @@ -2153,10 +2153,12 @@ void BluetoothDeviceClearCacheResponse::calculate_size(ProtoSize &size) const { void BluetoothScannerStateResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_uint32(1, static_cast(this->state)); buffer.encode_uint32(2, static_cast(this->mode)); + buffer.encode_uint32(3, static_cast(this->configured_mode)); } void BluetoothScannerStateResponse::calculate_size(ProtoSize &size) const { size.add_uint32(1, static_cast(this->state)); size.add_uint32(1, static_cast(this->mode)); + size.add_uint32(1, static_cast(this->configured_mode)); } bool BluetoothScannerSetModeRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { diff --git a/esphome/components/api/api_pb2.h b/esphome/components/api/api_pb2.h index abdf0e6121..3f2c2ea763 100644 --- a/esphome/components/api/api_pb2.h +++ b/esphome/components/api/api_pb2.h @@ -2214,12 +2214,13 @@ class BluetoothDeviceClearCacheResponse final : public ProtoMessage { class BluetoothScannerStateResponse final : public ProtoMessage { public: static constexpr uint8_t MESSAGE_TYPE = 126; - static constexpr uint8_t ESTIMATED_SIZE = 4; + static constexpr uint8_t ESTIMATED_SIZE = 6; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "bluetooth_scanner_state_response"; } #endif enums::BluetoothScannerState state{}; enums::BluetoothScannerMode mode{}; + enums::BluetoothScannerMode configured_mode{}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP diff --git a/esphome/components/api/api_pb2_dump.cpp b/esphome/components/api/api_pb2_dump.cpp index 7af322f96d..3e7df9195b 100644 --- a/esphome/components/api/api_pb2_dump.cpp +++ b/esphome/components/api/api_pb2_dump.cpp @@ -1704,6 +1704,7 @@ void BluetoothScannerStateResponse::dump_to(std::string &out) const { MessageDumpHelper helper(out, "BluetoothScannerStateResponse"); dump_field(out, "state", static_cast(this->state)); dump_field(out, "mode", static_cast(this->mode)); + dump_field(out, "configured_mode", static_cast(this->configured_mode)); } void BluetoothScannerSetModeRequest::dump_to(std::string &out) const { MessageDumpHelper helper(out, "BluetoothScannerSetModeRequest"); diff --git a/esphome/components/bluetooth_proxy/bluetooth_proxy.cpp b/esphome/components/bluetooth_proxy/bluetooth_proxy.cpp index 80b7fbe960..532aff550e 100644 --- a/esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +++ b/esphome/components/bluetooth_proxy/bluetooth_proxy.cpp @@ -24,6 +24,9 @@ void BluetoothProxy::setup() { this->connections_free_response_.limit = BLUETOOTH_PROXY_MAX_CONNECTIONS; this->connections_free_response_.free = BLUETOOTH_PROXY_MAX_CONNECTIONS; + // Capture the configured scan mode from YAML before any API changes + this->configured_scan_active_ = this->parent_->get_scan_active(); + this->parent_->add_scanner_state_callback([this](esp32_ble_tracker::ScannerState state) { if (this->api_connection_ != nullptr) { this->send_bluetooth_scanner_state_(state); @@ -36,6 +39,9 @@ void BluetoothProxy::send_bluetooth_scanner_state_(esp32_ble_tracker::ScannerSta resp.state = static_cast(state); resp.mode = this->parent_->get_scan_active() ? api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_ACTIVE : api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_PASSIVE; + resp.configured_mode = this->configured_scan_active_ + ? api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_ACTIVE + : api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_PASSIVE; this->api_connection_->send_message(resp, api::BluetoothScannerStateResponse::MESSAGE_TYPE); } diff --git a/esphome/components/bluetooth_proxy/bluetooth_proxy.h b/esphome/components/bluetooth_proxy/bluetooth_proxy.h index c81c8c9532..4b262dbe86 100644 --- a/esphome/components/bluetooth_proxy/bluetooth_proxy.h +++ b/esphome/components/bluetooth_proxy/bluetooth_proxy.h @@ -161,7 +161,8 @@ class BluetoothProxy final : public esp32_ble_tracker::ESPBTDeviceListener, publ // Group 4: 1-byte types grouped together bool active_; uint8_t connection_count_{0}; - // 2 bytes used, 2 bytes padding + bool configured_scan_active_{false}; // Configured scan mode from YAML + // 3 bytes used, 1 byte padding }; extern BluetoothProxy *global_bluetooth_proxy; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)