From 26e78c840ce4e35589245279e7d39f27039af851 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Tue, 24 Mar 2026 20:21:04 -0400 Subject: [PATCH] [wifi] Filter fast_connect by band_mode and use background scan for roaming (#15152) --- esphome/components/wifi/wifi_component.cpp | 8 ++++++++ esphome/components/wifi/wifi_component.h | 2 ++ esphome/components/wifi/wifi_component_esp_idf.cpp | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 2ed4b32a7a..620d1a083d 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -2222,6 +2222,14 @@ bool WiFiComponent::load_fast_connect_settings_(WiFiAP ¶ms) { params.set_hidden(false); ESP_LOGD(TAG, "Loaded fast_connect settings"); +#if defined(USE_ESP32) && defined(SOC_WIFI_SUPPORT_5G) + if ((this->band_mode_ == WIFI_BAND_MODE_5G_ONLY && fast_connect_save.channel < FIRST_5GHZ_CHANNEL) || + (this->band_mode_ == WIFI_BAND_MODE_2G_ONLY && fast_connect_save.channel >= FIRST_5GHZ_CHANNEL)) { + ESP_LOGW(TAG, "Saved channel %u not allowed by band mode, ignoring fast_connect", fast_connect_save.channel); + this->selected_sta_index_ = -1; + return false; + } +#endif return true; } diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index 99b23436f7..55e532c37d 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -774,6 +774,8 @@ class WiFiComponent final : public Component { SemaphoreHandle_t high_performance_semaphore_{nullptr}; #endif + static constexpr uint8_t FIRST_5GHZ_CHANNEL = 36; + // Post-connect roaming constants static constexpr uint32_t ROAMING_CHECK_INTERVAL = 5 * 60 * 1000; // 5 minutes static constexpr int8_t ROAMING_MIN_IMPROVEMENT = 10; // dB diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index 2866ec1513..1b80adc82e 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -987,6 +987,11 @@ bool WiFiComponent::wifi_scan_start_(bool passive) { config.scan_time.active.min = 100; config.scan_time.active.max = 300; } + // When scanning while connected (roaming), return to home channel between + // each scanned channel to maintain the connection (helps with BLE/WiFi coexistence) + if (this->roaming_state_ == RoamingState::SCANNING) { + config.coex_background_scan = true; + } esp_err_t err = esp_wifi_scan_start(&config, false); if (err != ESP_OK) {