From 7aef173e650da3bce3975be0f88dcfefb427f8ff Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 20 Jan 2026 20:19:35 -1000 Subject: [PATCH 01/11] [wifi] Filter scan results to only store matching networks --- esphome/components/wifi/wifi_component.cpp | 49 ++++++++++++++++++- esphome/components/wifi/wifi_component.h | 10 ++-- .../wifi/wifi_component_esp8266.cpp | 23 ++++++--- .../wifi/wifi_component_esp_idf.cpp | 26 +++++++--- .../wifi/wifi_component_libretiny.cpp | 35 +++++++++---- .../components/wifi/wifi_component_pico_w.cpp | 12 ++++- 6 files changed, 126 insertions(+), 29 deletions(-) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index ff6284c073..64abf03c51 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -39,6 +39,10 @@ #include "esphome/components/esp32_improv/esp32_improv_component.h" #endif +#ifdef USE_IMPROV_SERIAL +#include "esphome/components/improv_serial/improv_serial_component.h" +#endif + namespace esphome::wifi { static const char *const TAG = "wifi"; @@ -365,6 +369,49 @@ bool WiFiComponent::ssid_was_seen_in_scan_(const std::string &ssid) const { return false; } +bool WiFiComponent::needs_full_scan_results_() const { + // Listeners always need full results + if (this->keep_scan_results_) { + return true; + } + +#ifdef USE_CAPTIVE_PORTAL + // Captive portal needs full results when active (showing network list to user) + if (captive_portal::global_captive_portal != nullptr && captive_portal::global_captive_portal->is_active()) { + return true; + } +#endif + +#ifdef USE_IMPROV_SERIAL + // Improv serial needs results during provisioning (before connected) + if (improv_serial::global_improv_serial_component != nullptr && !this->is_connected()) { + return true; + } +#endif + +#ifdef USE_IMPROV + // BLE improv also needs results during provisioning + if (esp32_improv::global_improv_component != nullptr && esp32_improv::global_improv_component->is_active()) { + return true; + } +#endif + + return false; +} + +bool WiFiComponent::matches_configured_ssid_(const char *ssid) const { + // Hidden networks in scan results have empty SSIDs - skip them + if (ssid[0] == '\0') { + return false; + } + for (const auto &sta : this->sta_) { + if (!sta.get_hidden() && (sta.get_ssid().empty() || sta.get_ssid() == ssid)) { + return true; + } + } + return false; +} + int8_t WiFiComponent::find_next_hidden_sta_(int8_t start_index) { // Find next SSID to try in RETRY_HIDDEN phase. // @@ -2079,7 +2126,7 @@ void WiFiComponent::clear_roaming_state_() { void WiFiComponent::release_scan_results_() { if (!this->keep_scan_results_) { -#ifdef USE_RP2040 +#if defined(USE_RP2040) || defined(USE_ESP32) // std::vector - use swap trick since shrink_to_fit is non-binding decltype(this->scan_result_)().swap(this->scan_result_); #else diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index dfc91fb5da..3a6bf2994d 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -161,9 +161,9 @@ struct EAPAuth { using bssid_t = std::array; -// Use std::vector for RP2040 since scan count is unknown (callback-based) -// Use FixedVector for other platforms where count is queried first -#ifdef USE_RP2040 +// Use std::vector for RP2040 (callback-based) and ESP32 (destructive scan API) +// Use FixedVector for ESP8266 and LibreTiny where two-pass exact allocation is possible +#if defined(USE_RP2040) || defined(USE_ESP32) template using wifi_scan_vector_t = std::vector; #else template using wifi_scan_vector_t = FixedVector; @@ -539,6 +539,10 @@ class WiFiComponent : public Component { /// Check if an SSID was seen in the most recent scan results /// Used to skip hidden mode for SSIDs we know are visible bool ssid_was_seen_in_scan_(const std::string &ssid) const; + /// Check if full scan results are needed (captive portal active, improv, listeners) + bool needs_full_scan_results_() const; + /// Check if SSID matches any configured network (for scan result filtering) + bool matches_configured_ssid_(const char *ssid) const; /// Find next SSID that wasn't in scan results (might be hidden) /// Returns index of next potentially hidden SSID, or -1 if none found /// @param start_index Start searching from index after this (-1 to start from beginning) diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index de0600cf5b..dad899ff0b 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -756,19 +756,28 @@ void WiFiComponent::wifi_scan_done_callback_(void *arg, STATUS status) { return; } - // Count the number of results first auto *head = reinterpret_cast(arg); + bool needs_full = this->needs_full_scan_results_(); + + // First pass: count matching networks (linked list is non-destructive) size_t count = 0; for (bss_info *it = head; it != nullptr; it = STAILQ_NEXT(it, next)) { - count++; + const char *ssid_cstr = reinterpret_cast(it->ssid); + if (needs_full || this->matches_configured_ssid_(ssid_cstr)) { + count++; + } } - this->scan_result_.init(count); + this->scan_result_.init(count); // Exact allocation + + // Second pass: store matching networks for (bss_info *it = head; it != nullptr; it = STAILQ_NEXT(it, next)) { - this->scan_result_.emplace_back( - bssid_t{it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]}, - std::string(reinterpret_cast(it->ssid), it->ssid_len), it->channel, it->rssi, it->authmode != AUTH_OPEN, - it->is_hidden != 0); + const char *ssid_cstr = reinterpret_cast(it->ssid); + if (needs_full || this->matches_configured_ssid_(ssid_cstr)) { + this->scan_result_.emplace_back( + bssid_t{it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]}, + std::string(ssid_cstr, it->ssid_len), it->channel, it->rssi, it->authmode != AUTH_OPEN, it->is_hidden != 0); + } } this->scan_done_ = true; #ifdef USE_WIFI_SCAN_RESULTS_LISTENERS diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index 99474ac2f8..a8eef686d0 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -827,7 +827,14 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) { } uint16_t number = it.number; - scan_result_.init(number); + bool needs_full = this->needs_full_scan_results_(); + + // Smart reserve: full capacity if needed, small reserve otherwise + if (needs_full) { + this->scan_result_.reserve(number); + } else { + this->scan_result_.reserve(8); // Typical: 1-3 matching networks + } // Process one record at a time to avoid large buffer allocation wifi_ap_record_t record; @@ -838,11 +845,18 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) { esp_wifi_clear_ap_list(); // Free remaining records not yet retrieved break; } - bssid_t bssid; - std::copy(record.bssid, record.bssid + 6, bssid.begin()); - std::string ssid(reinterpret_cast(record.ssid)); - scan_result_.emplace_back(bssid, ssid, record.primary, record.rssi, record.authmode != WIFI_AUTH_OPEN, - ssid.empty()); + + // Check C string first - avoid std::string construction for non-matching networks + const char *ssid_cstr = reinterpret_cast(record.ssid); + + // Only construct std::string and store if needed + if (needs_full || this->matches_configured_ssid_(ssid_cstr)) { + bssid_t bssid; + std::copy(record.bssid, record.bssid + 6, bssid.begin()); + std::string ssid(ssid_cstr); + this->scan_result_.emplace_back(bssid, std::move(ssid), record.primary, record.rssi, + record.authmode != WIFI_AUTH_OPEN, ssid.empty()); + } } #ifdef USE_WIFI_SCAN_RESULTS_LISTENERS for (auto *listener : this->scan_results_listeners_) { diff --git a/esphome/components/wifi/wifi_component_libretiny.cpp b/esphome/components/wifi/wifi_component_libretiny.cpp index 162ed4e835..f0928603e1 100644 --- a/esphome/components/wifi/wifi_component_libretiny.cpp +++ b/esphome/components/wifi/wifi_component_libretiny.cpp @@ -664,17 +664,32 @@ void WiFiComponent::wifi_scan_done_callback_() { if (num < 0) return; - this->scan_result_.init(static_cast(num)); - for (int i = 0; i < num; i++) { - String ssid = WiFi.SSID(i); - wifi_auth_mode_t authmode = WiFi.encryptionType(i); - int32_t rssi = WiFi.RSSI(i); - uint8_t *bssid = WiFi.BSSID(i); - int32_t channel = WiFi.channel(i); + bool needs_full = this->needs_full_scan_results_(); - this->scan_result_.emplace_back(bssid_t{bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]}, - std::string(ssid.c_str()), channel, rssi, authmode != WIFI_AUTH_OPEN, - ssid.length() == 0); + // Access scan results directly via WiFi.scan struct to avoid Arduino String allocations + // WiFi.scan is public in LibreTiny for WiFiEvents & WiFiScan static handlers + auto *scan = WiFi.scan; + + // First pass: count matching networks + size_t count = 0; + for (int i = 0; i < num; i++) { + const char *ssid_cstr = scan->ap[i].ssid; + if (needs_full || this->matches_configured_ssid_(ssid_cstr)) { + count++; + } + } + + this->scan_result_.init(count); // Exact allocation + + // Second pass: store matching networks + for (int i = 0; i < num; i++) { + const char *ssid_cstr = scan->ap[i].ssid; + if (needs_full || this->matches_configured_ssid_(ssid_cstr)) { + auto &ap = scan->ap[i]; + this->scan_result_.emplace_back( + bssid_t{ap.bssid[0], ap.bssid[1], ap.bssid[2], ap.bssid[3], ap.bssid[4], ap.bssid[5]}, std::string(ssid_cstr), + ap.channel, ap.rssi, ap.auth != WIFI_AUTH_OPEN, ssid_cstr[0] == '\0'); + } } WiFi.scanDelete(); #ifdef USE_WIFI_SCAN_RESULTS_LISTENERS diff --git a/esphome/components/wifi/wifi_component_pico_w.cpp b/esphome/components/wifi/wifi_component_pico_w.cpp index 29ac096d94..0db2300b8f 100644 --- a/esphome/components/wifi/wifi_component_pico_w.cpp +++ b/esphome/components/wifi/wifi_component_pico_w.cpp @@ -137,10 +137,18 @@ int WiFiComponent::s_wifi_scan_result(void *env, const cyw43_ev_scan_result_t *r } void WiFiComponent::wifi_scan_result(void *env, const cyw43_ev_scan_result_t *result) { + const char *ssid_cstr = reinterpret_cast(result->ssid); + + // Skip networks that don't match any configured SSID (unless full results needed) + if (!this->needs_full_scan_results_() && !this->matches_configured_ssid_(ssid_cstr)) { + return; + } + bssid_t bssid; std::copy(result->bssid, result->bssid + 6, bssid.begin()); - std::string ssid(reinterpret_cast(result->ssid)); - WiFiScanResult res(bssid, ssid, result->channel, result->rssi, result->auth_mode != CYW43_AUTH_OPEN, ssid.empty()); + std::string ssid(ssid_cstr); + WiFiScanResult res(bssid, std::move(ssid), result->channel, result->rssi, result->auth_mode != CYW43_AUTH_OPEN, + ssid.empty()); if (std::find(this->scan_result_.begin(), this->scan_result_.end(), res) == this->scan_result_.end()) { this->scan_result_.push_back(res); } From 6f3a49e50970c4c6383fc692e4936df12a7768eb Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 20 Jan 2026 20:30:55 -1000 Subject: [PATCH 02/11] tweak loggig --- esphome/components/wifi/wifi_component.cpp | 31 ++++++------------- esphome/components/wifi/wifi_component.h | 2 ++ .../wifi/wifi_component_esp8266.cpp | 2 ++ .../wifi/wifi_component_esp_idf.cpp | 4 +++ .../wifi/wifi_component_libretiny.cpp | 3 ++ .../components/wifi/wifi_component_pico_w.cpp | 1 + 6 files changed, 21 insertions(+), 22 deletions(-) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 64abf03c51..0f5aff3ba1 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -412,6 +412,14 @@ bool WiFiComponent::matches_configured_ssid_(const char *ssid) const { return false; } +void WiFiComponent::log_discarded_scan_result_(const char *ssid, const uint8_t *bssid, int8_t rssi, uint8_t channel) { +#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE + char bssid_s[18]; + format_mac_addr_upper(bssid, bssid_s); + ESP_LOGV(TAG, "- " LOG_SECRET("'%s'") " " LOG_SECRET("(%s)") " %ddB Ch:%u", ssid, bssid_s, rssi, channel); +#endif +} + int8_t WiFiComponent::find_next_hidden_sta_(int8_t start_index) { // Find next SSID to try in RETRY_HIDDEN phase. // @@ -1234,18 +1242,6 @@ __attribute__((noinline)) static void log_scan_result(const WiFiScanResult &res) #endif } -#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE -// Helper function to log non-matching scan results at verbose level -__attribute__((noinline)) static void log_scan_result_non_matching(const WiFiScanResult &res) { - char bssid_s[18]; - auto bssid = res.get_bssid(); - format_mac_addr_upper(bssid.data(), bssid_s); - - ESP_LOGV(TAG, "- " LOG_SECRET("'%s'") " " LOG_SECRET("(%s) ") "%s", res.get_ssid().c_str(), bssid_s, - LOG_STR_ARG(get_signal_bars(res.get_rssi()))); -} -#endif - void WiFiComponent::check_scanning_finished() { if (!this->scan_done_) { if (millis() - this->action_started_ > WIFI_SCAN_TIMEOUT_MS) { @@ -1282,21 +1278,12 @@ void WiFiComponent::check_scanning_finished() { // Sort scan results using insertion sort for better memory efficiency insertion_sort_scan_results(this->scan_result_); - size_t non_matching_count = 0; + // Log matching networks (non-matching already logged at VERBOSE in scan callback) for (auto &res : this->scan_result_) { if (res.get_matches()) { log_scan_result(res); - } else { -#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE - log_scan_result_non_matching(res); -#else - non_matching_count++; -#endif } } - if (non_matching_count > 0) { - ESP_LOGD(TAG, "- %zu non-matching (VERBOSE to show)", non_matching_count); - } // SYNCHRONIZATION POINT: Establish link between scan_result_[0] and selected_sta_index_ // After sorting, scan_result_[0] contains the best network. Now find which sta_[i] config diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index 3a6bf2994d..33263bbdfe 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -543,6 +543,8 @@ class WiFiComponent : public Component { bool needs_full_scan_results_() const; /// Check if SSID matches any configured network (for scan result filtering) bool matches_configured_ssid_(const char *ssid) const; + /// Log a discarded scan result at VERBOSE level + static void log_discarded_scan_result_(const char *ssid, const uint8_t *bssid, int8_t rssi, uint8_t channel); /// Find next SSID that wasn't in scan results (might be hidden) /// Returns index of next potentially hidden SSID, or -1 if none found /// @param start_index Start searching from index after this (-1 to start from beginning) diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index dad899ff0b..fbfa423ef7 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -777,6 +777,8 @@ void WiFiComponent::wifi_scan_done_callback_(void *arg, STATUS status) { this->scan_result_.emplace_back( bssid_t{it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]}, std::string(ssid_cstr, it->ssid_len), it->channel, it->rssi, it->authmode != AUTH_OPEN, it->is_hidden != 0); + } else { + WiFiComponent::log_discarded_scan_result_(ssid_cstr, it->bssid, it->rssi, it->channel); } } this->scan_done_ = true; diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index a8eef686d0..5a7fbd35f0 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -856,8 +856,12 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) { std::string ssid(ssid_cstr); this->scan_result_.emplace_back(bssid, std::move(ssid), record.primary, record.rssi, record.authmode != WIFI_AUTH_OPEN, ssid.empty()); + } else { + WiFiComponent::log_discarded_scan_result_(ssid_cstr, record.bssid, record.rssi, record.primary); } } + ESP_LOGD(TAG, "Scan complete: %u found, %zu stored%s", number, this->scan_result_.size(), + needs_full ? "" : " (filtered)"); #ifdef USE_WIFI_SCAN_RESULTS_LISTENERS for (auto *listener : this->scan_results_listeners_) { listener->on_wifi_scan_results(this->scan_result_); diff --git a/esphome/components/wifi/wifi_component_libretiny.cpp b/esphome/components/wifi/wifi_component_libretiny.cpp index f0928603e1..5f8ef3a340 100644 --- a/esphome/components/wifi/wifi_component_libretiny.cpp +++ b/esphome/components/wifi/wifi_component_libretiny.cpp @@ -689,6 +689,9 @@ void WiFiComponent::wifi_scan_done_callback_() { this->scan_result_.emplace_back( bssid_t{ap.bssid[0], ap.bssid[1], ap.bssid[2], ap.bssid[3], ap.bssid[4], ap.bssid[5]}, std::string(ssid_cstr), ap.channel, ap.rssi, ap.auth != WIFI_AUTH_OPEN, ssid_cstr[0] == '\0'); + } else { + auto &ap = scan->ap[i]; + WiFiComponent::log_discarded_scan_result_(ssid_cstr, ap.bssid, ap.rssi, ap.channel); } } WiFi.scanDelete(); diff --git a/esphome/components/wifi/wifi_component_pico_w.cpp b/esphome/components/wifi/wifi_component_pico_w.cpp index 0db2300b8f..57fc89d36b 100644 --- a/esphome/components/wifi/wifi_component_pico_w.cpp +++ b/esphome/components/wifi/wifi_component_pico_w.cpp @@ -141,6 +141,7 @@ void WiFiComponent::wifi_scan_result(void *env, const cyw43_ev_scan_result_t *re // Skip networks that don't match any configured SSID (unless full results needed) if (!this->needs_full_scan_results_() && !this->matches_configured_ssid_(ssid_cstr)) { + WiFiComponent::log_discarded_scan_result_(ssid_cstr, result->bssid, result->rssi, result->channel); return; } From d7c3947ccc520ee5bb6a85a8068ba4075bea473b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 20 Jan 2026 20:31:38 -1000 Subject: [PATCH 03/11] tweak loggig --- esphome/components/wifi/wifi_component.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 0f5aff3ba1..4f7dfab561 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -414,7 +414,7 @@ bool WiFiComponent::matches_configured_ssid_(const char *ssid) const { void WiFiComponent::log_discarded_scan_result_(const char *ssid, const uint8_t *bssid, int8_t rssi, uint8_t channel) { #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE - char bssid_s[18]; + char bssid_s[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; format_mac_addr_upper(bssid, bssid_s); ESP_LOGV(TAG, "- " LOG_SECRET("'%s'") " " LOG_SECRET("(%s)") " %ddB Ch:%u", ssid, bssid_s, rssi, channel); #endif From bffe4a2e05ee1dcfdc613346beea1119bc3a4731 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 20 Jan 2026 20:34:53 -1000 Subject: [PATCH 04/11] tweaks --- esphome/components/wifi/wifi_component.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 4f7dfab561..0e5a2022b3 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -1226,7 +1226,7 @@ template static void insertion_sort_scan_results(VectorType // has overhead from UART transmission, so combining INFO+DEBUG into one line halves // the blocking time. Do NOT split this into separate ESP_LOGI/ESP_LOGD calls. __attribute__((noinline)) static void log_scan_result(const WiFiScanResult &res) { - char bssid_s[18]; + char bssid_s[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; auto bssid = res.get_bssid(); format_mac_addr_upper(bssid.data(), bssid_s); From d5d6936845cee31a72353dbf524146aba691746f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 20 Jan 2026 20:35:32 -1000 Subject: [PATCH 05/11] tweaks --- esphome/components/wifi/wifi_component.h | 3 +++ esphome/components/wifi/wifi_component_esp_idf.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index 33263bbdfe..514aabc249 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -161,6 +161,9 @@ struct EAPAuth { using bssid_t = std::array; +/// Initial reserve size for filtered scan results (typical: 1-3 matching networks per SSID) +static constexpr size_t WIFI_SCAN_RESULT_FILTERED_RESERVE = 8; + // Use std::vector for RP2040 (callback-based) and ESP32 (destructive scan API) // Use FixedVector for ESP8266 and LibreTiny where two-pass exact allocation is possible #if defined(USE_RP2040) || defined(USE_ESP32) diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index 5a7fbd35f0..cdc101b87c 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -833,7 +833,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) { if (needs_full) { this->scan_result_.reserve(number); } else { - this->scan_result_.reserve(8); // Typical: 1-3 matching networks + this->scan_result_.reserve(WIFI_SCAN_RESULT_FILTERED_RESERVE); } // Process one record at a time to avoid large buffer allocation From 692167341e3dee3002700343bbf788d23712d6af Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 20 Jan 2026 20:37:16 -1000 Subject: [PATCH 06/11] tweaks --- esphome/components/wifi/wifi_component_esp_idf.cpp | 2 +- esphome/components/wifi/wifi_component_pico_w.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index cdc101b87c..00890771bf 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -855,7 +855,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) { std::copy(record.bssid, record.bssid + 6, bssid.begin()); std::string ssid(ssid_cstr); this->scan_result_.emplace_back(bssid, std::move(ssid), record.primary, record.rssi, - record.authmode != WIFI_AUTH_OPEN, ssid.empty()); + record.authmode != WIFI_AUTH_OPEN, ssid_cstr[0] == '\0'); } else { WiFiComponent::log_discarded_scan_result_(ssid_cstr, record.bssid, record.rssi, record.primary); } diff --git a/esphome/components/wifi/wifi_component_pico_w.cpp b/esphome/components/wifi/wifi_component_pico_w.cpp index 57fc89d36b..d80ff87da6 100644 --- a/esphome/components/wifi/wifi_component_pico_w.cpp +++ b/esphome/components/wifi/wifi_component_pico_w.cpp @@ -149,7 +149,7 @@ void WiFiComponent::wifi_scan_result(void *env, const cyw43_ev_scan_result_t *re std::copy(result->bssid, result->bssid + 6, bssid.begin()); std::string ssid(ssid_cstr); WiFiScanResult res(bssid, std::move(ssid), result->channel, result->rssi, result->auth_mode != CYW43_AUTH_OPEN, - ssid.empty()); + ssid_cstr[0] == '\0'); if (std::find(this->scan_result_.begin(), this->scan_result_.end(), res) == this->scan_result_.end()) { this->scan_result_.push_back(res); } From acb22ed286acc947717b9e8457c2c2c329f2d0fc Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 20 Jan 2026 20:39:30 -1000 Subject: [PATCH 07/11] tweaks --- esphome/components/wifi/wifi_component.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 0e5a2022b3..002c11be5f 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -405,6 +405,9 @@ bool WiFiComponent::matches_configured_ssid_(const char *ssid) const { return false; } for (const auto &sta : this->sta_) { + // Skip hidden network configs (they don't appear in normal scans) + // For BSSID-only configs (empty SSID), match all networks since we can't filter by SSID + // Otherwise, match only the specific configured SSID if (!sta.get_hidden() && (sta.get_ssid().empty() || sta.get_ssid() == ssid)) { return true; } From 687f9a762d932ff39535b82c820eee6b77a2f5d0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 20 Jan 2026 20:44:28 -1000 Subject: [PATCH 08/11] fixes for libretiny --- esphome/components/wifi/wifi_component_libretiny.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/esphome/components/wifi/wifi_component_libretiny.cpp b/esphome/components/wifi/wifi_component_libretiny.cpp index 5f8ef3a340..f16d8b22a3 100644 --- a/esphome/components/wifi/wifi_component_libretiny.cpp +++ b/esphome/components/wifi/wifi_component_libretiny.cpp @@ -686,12 +686,13 @@ void WiFiComponent::wifi_scan_done_callback_() { const char *ssid_cstr = scan->ap[i].ssid; if (needs_full || this->matches_configured_ssid_(ssid_cstr)) { auto &ap = scan->ap[i]; - this->scan_result_.emplace_back( - bssid_t{ap.bssid[0], ap.bssid[1], ap.bssid[2], ap.bssid[3], ap.bssid[4], ap.bssid[5]}, std::string(ssid_cstr), - ap.channel, ap.rssi, ap.auth != WIFI_AUTH_OPEN, ssid_cstr[0] == '\0'); + this->scan_result_.emplace_back(bssid_t{ap.bssid.addr[0], ap.bssid.addr[1], ap.bssid.addr[2], ap.bssid.addr[3], + ap.bssid.addr[4], ap.bssid.addr[5]}, + std::string(ssid_cstr), ap.channel, ap.rssi, ap.auth != WIFI_AUTH_OPEN, + ssid_cstr[0] == '\0'); } else { auto &ap = scan->ap[i]; - WiFiComponent::log_discarded_scan_result_(ssid_cstr, ap.bssid, ap.rssi, ap.channel); + WiFiComponent::log_discarded_scan_result_(ssid_cstr, ap.bssid.addr, ap.rssi, ap.channel); } } WiFi.scanDelete(); From d610c3ae913ccb5d1a417592020262f25e719d43 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 20 Jan 2026 20:54:30 -1000 Subject: [PATCH 09/11] fix bssid only --- esphome/components/wifi/wifi_component.cpp | 17 +++++++++++++---- esphome/components/wifi/wifi_component.h | 5 +++-- .../components/wifi/wifi_component_esp8266.cpp | 4 ++-- .../components/wifi/wifi_component_esp_idf.cpp | 2 +- .../wifi/wifi_component_libretiny.cpp | 4 ++-- .../components/wifi/wifi_component_pico_w.cpp | 4 ++-- 6 files changed, 23 insertions(+), 13 deletions(-) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 002c11be5f..151dece9bb 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -399,16 +399,25 @@ bool WiFiComponent::needs_full_scan_results_() const { return false; } -bool WiFiComponent::matches_configured_ssid_(const char *ssid) const { +bool WiFiComponent::matches_configured_network_(const char *ssid, const uint8_t *bssid) const { // Hidden networks in scan results have empty SSIDs - skip them if (ssid[0] == '\0') { return false; } for (const auto &sta : this->sta_) { // Skip hidden network configs (they don't appear in normal scans) - // For BSSID-only configs (empty SSID), match all networks since we can't filter by SSID - // Otherwise, match only the specific configured SSID - if (!sta.get_hidden() && (sta.get_ssid().empty() || sta.get_ssid() == ssid)) { + if (sta.get_hidden()) { + continue; + } + // For BSSID-only configs (empty SSID), match by BSSID + if (sta.get_ssid().empty()) { + if (sta.has_bssid() && std::memcmp(sta.get_bssid().data(), bssid, 6) == 0) { + return true; + } + continue; + } + // Match by SSID + if (sta.get_ssid() == ssid) { return true; } } diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index 514aabc249..3ad404e6fc 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -544,8 +544,9 @@ class WiFiComponent : public Component { bool ssid_was_seen_in_scan_(const std::string &ssid) const; /// Check if full scan results are needed (captive portal active, improv, listeners) bool needs_full_scan_results_() const; - /// Check if SSID matches any configured network (for scan result filtering) - bool matches_configured_ssid_(const char *ssid) const; + /// Check if network matches any configured network (for scan result filtering) + /// Matches by SSID when configured, or by BSSID for BSSID-only configs + bool matches_configured_network_(const char *ssid, const uint8_t *bssid) const; /// Log a discarded scan result at VERBOSE level static void log_discarded_scan_result_(const char *ssid, const uint8_t *bssid, int8_t rssi, uint8_t channel); /// Find next SSID that wasn't in scan results (might be hidden) diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index fbfa423ef7..78a301cae7 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -763,7 +763,7 @@ void WiFiComponent::wifi_scan_done_callback_(void *arg, STATUS status) { size_t count = 0; for (bss_info *it = head; it != nullptr; it = STAILQ_NEXT(it, next)) { const char *ssid_cstr = reinterpret_cast(it->ssid); - if (needs_full || this->matches_configured_ssid_(ssid_cstr)) { + if (needs_full || this->matches_configured_network_(ssid_cstr, it->bssid)) { count++; } } @@ -773,7 +773,7 @@ void WiFiComponent::wifi_scan_done_callback_(void *arg, STATUS status) { // Second pass: store matching networks for (bss_info *it = head; it != nullptr; it = STAILQ_NEXT(it, next)) { const char *ssid_cstr = reinterpret_cast(it->ssid); - if (needs_full || this->matches_configured_ssid_(ssid_cstr)) { + if (needs_full || this->matches_configured_network_(ssid_cstr, it->bssid)) { this->scan_result_.emplace_back( bssid_t{it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]}, std::string(ssid_cstr, it->ssid_len), it->channel, it->rssi, it->authmode != AUTH_OPEN, it->is_hidden != 0); diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index 00890771bf..ef3aecc1a1 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -850,7 +850,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) { const char *ssid_cstr = reinterpret_cast(record.ssid); // Only construct std::string and store if needed - if (needs_full || this->matches_configured_ssid_(ssid_cstr)) { + if (needs_full || this->matches_configured_network_(ssid_cstr, record.bssid)) { bssid_t bssid; std::copy(record.bssid, record.bssid + 6, bssid.begin()); std::string ssid(ssid_cstr); diff --git a/esphome/components/wifi/wifi_component_libretiny.cpp b/esphome/components/wifi/wifi_component_libretiny.cpp index f16d8b22a3..d2ebf267b6 100644 --- a/esphome/components/wifi/wifi_component_libretiny.cpp +++ b/esphome/components/wifi/wifi_component_libretiny.cpp @@ -674,7 +674,7 @@ void WiFiComponent::wifi_scan_done_callback_() { size_t count = 0; for (int i = 0; i < num; i++) { const char *ssid_cstr = scan->ap[i].ssid; - if (needs_full || this->matches_configured_ssid_(ssid_cstr)) { + if (needs_full || this->matches_configured_network_(ssid_cstr, scan->ap[i].bssid.addr)) { count++; } } @@ -684,7 +684,7 @@ void WiFiComponent::wifi_scan_done_callback_() { // Second pass: store matching networks for (int i = 0; i < num; i++) { const char *ssid_cstr = scan->ap[i].ssid; - if (needs_full || this->matches_configured_ssid_(ssid_cstr)) { + if (needs_full || this->matches_configured_network_(ssid_cstr, scan->ap[i].bssid.addr)) { auto &ap = scan->ap[i]; this->scan_result_.emplace_back(bssid_t{ap.bssid.addr[0], ap.bssid.addr[1], ap.bssid.addr[2], ap.bssid.addr[3], ap.bssid.addr[4], ap.bssid.addr[5]}, diff --git a/esphome/components/wifi/wifi_component_pico_w.cpp b/esphome/components/wifi/wifi_component_pico_w.cpp index d80ff87da6..d6d2ce0948 100644 --- a/esphome/components/wifi/wifi_component_pico_w.cpp +++ b/esphome/components/wifi/wifi_component_pico_w.cpp @@ -139,8 +139,8 @@ int WiFiComponent::s_wifi_scan_result(void *env, const cyw43_ev_scan_result_t *r void WiFiComponent::wifi_scan_result(void *env, const cyw43_ev_scan_result_t *result) { const char *ssid_cstr = reinterpret_cast(result->ssid); - // Skip networks that don't match any configured SSID (unless full results needed) - if (!this->needs_full_scan_results_() && !this->matches_configured_ssid_(ssid_cstr)) { + // Skip networks that don't match any configured network (unless full results needed) + if (!this->needs_full_scan_results_() && !this->matches_configured_network_(ssid_cstr, result->bssid)) { WiFiComponent::log_discarded_scan_result_(ssid_cstr, result->bssid, result->rssi, result->channel); return; } From 09b42b778bbd3470e07f2c6540a5cb9f4c36dd34 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 20 Jan 2026 20:57:39 -1000 Subject: [PATCH 10/11] log scan complete --- esphome/components/wifi/wifi_component_esp8266.cpp | 4 ++++ esphome/components/wifi/wifi_component_libretiny.cpp | 2 ++ esphome/components/wifi/wifi_component_pico_w.cpp | 7 ++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index 78a301cae7..de07818f59 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -760,8 +760,10 @@ void WiFiComponent::wifi_scan_done_callback_(void *arg, STATUS status) { bool needs_full = this->needs_full_scan_results_(); // First pass: count matching networks (linked list is non-destructive) + size_t total = 0; size_t count = 0; for (bss_info *it = head; it != nullptr; it = STAILQ_NEXT(it, next)) { + total++; const char *ssid_cstr = reinterpret_cast(it->ssid); if (needs_full || this->matches_configured_network_(ssid_cstr, it->bssid)) { count++; @@ -781,6 +783,8 @@ void WiFiComponent::wifi_scan_done_callback_(void *arg, STATUS status) { WiFiComponent::log_discarded_scan_result_(ssid_cstr, it->bssid, it->rssi, it->channel); } } + ESP_LOGD(TAG, "Scan complete: %zu found, %zu stored%s", total, this->scan_result_.size(), + needs_full ? "" : " (filtered)"); this->scan_done_ = true; #ifdef USE_WIFI_SCAN_RESULTS_LISTENERS for (auto *listener : global_wifi_component->scan_results_listeners_) { diff --git a/esphome/components/wifi/wifi_component_libretiny.cpp b/esphome/components/wifi/wifi_component_libretiny.cpp index d2ebf267b6..dc89784de2 100644 --- a/esphome/components/wifi/wifi_component_libretiny.cpp +++ b/esphome/components/wifi/wifi_component_libretiny.cpp @@ -695,6 +695,8 @@ void WiFiComponent::wifi_scan_done_callback_() { WiFiComponent::log_discarded_scan_result_(ssid_cstr, ap.bssid.addr, ap.rssi, ap.channel); } } + ESP_LOGD(TAG, "Scan complete: %d found, %zu stored%s", num, this->scan_result_.size(), + needs_full ? "" : " (filtered)"); WiFi.scanDelete(); #ifdef USE_WIFI_SCAN_RESULTS_LISTENERS for (auto *listener : this->scan_results_listeners_) { diff --git a/esphome/components/wifi/wifi_component_pico_w.cpp b/esphome/components/wifi/wifi_component_pico_w.cpp index d6d2ce0948..a626e012a7 100644 --- a/esphome/components/wifi/wifi_component_pico_w.cpp +++ b/esphome/components/wifi/wifi_component_pico_w.cpp @@ -21,6 +21,7 @@ static const char *const TAG = "wifi_pico_w"; // Track previous state for detecting changes static bool s_sta_was_connected = false; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) static bool s_sta_had_ip = false; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +static size_t s_scan_result_count = 0; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) bool WiFiComponent::wifi_mode_(optional sta, optional ap) { if (sta.has_value()) { @@ -137,6 +138,7 @@ int WiFiComponent::s_wifi_scan_result(void *env, const cyw43_ev_scan_result_t *r } void WiFiComponent::wifi_scan_result(void *env, const cyw43_ev_scan_result_t *result) { + s_scan_result_count++; const char *ssid_cstr = reinterpret_cast(result->ssid); // Skip networks that don't match any configured network (unless full results needed) @@ -158,6 +160,7 @@ void WiFiComponent::wifi_scan_result(void *env, const cyw43_ev_scan_result_t *re bool WiFiComponent::wifi_scan_start_(bool passive) { this->scan_result_.clear(); this->scan_done_ = false; + s_scan_result_count = 0; cyw43_wifi_scan_options_t scan_options = {0}; scan_options.scan_type = passive ? 1 : 0; int err = cyw43_wifi_scan(&cyw43_state, &scan_options, nullptr, &s_wifi_scan_result); @@ -253,7 +256,9 @@ void WiFiComponent::wifi_loop_() { // Handle scan completion if (this->state_ == WIFI_COMPONENT_STATE_STA_SCANNING && !cyw43_wifi_scan_active(&cyw43_state)) { this->scan_done_ = true; - ESP_LOGV(TAG, "Scan done"); + bool needs_full = this->needs_full_scan_results_(); + ESP_LOGD(TAG, "Scan complete: %zu found, %zu stored%s", s_scan_result_count, this->scan_result_.size(), + needs_full ? "" : " (filtered)"); #ifdef USE_WIFI_SCAN_RESULTS_LISTENERS for (auto *listener : this->scan_results_listeners_) { listener->on_wifi_scan_results(this->scan_result_); From f0c7306ad517761219889a98c3f1b83db688590a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 20 Jan 2026 21:04:52 -1000 Subject: [PATCH 11/11] log scan complete --- esphome/components/wifi/wifi_component.cpp | 2 +- esphome/components/wifi/wifi_component.h | 2 +- esphome/components/wifi/wifi_component_esp8266.cpp | 2 +- esphome/components/wifi/wifi_component_esp_idf.cpp | 2 +- esphome/components/wifi/wifi_component_libretiny.cpp | 2 +- esphome/components/wifi/wifi_component_pico_w.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 151dece9bb..acd66e8ed4 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -424,7 +424,7 @@ bool WiFiComponent::matches_configured_network_(const char *ssid, const uint8_t return false; } -void WiFiComponent::log_discarded_scan_result_(const char *ssid, const uint8_t *bssid, int8_t rssi, uint8_t channel) { +void WiFiComponent::log_discarded_scan_result(const char *ssid, const uint8_t *bssid, int8_t rssi, uint8_t channel) { #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE char bssid_s[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; format_mac_addr_upper(bssid, bssid_s); diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index 3ad404e6fc..c4d2d3a494 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -548,7 +548,7 @@ class WiFiComponent : public Component { /// Matches by SSID when configured, or by BSSID for BSSID-only configs bool matches_configured_network_(const char *ssid, const uint8_t *bssid) const; /// Log a discarded scan result at VERBOSE level - static void log_discarded_scan_result_(const char *ssid, const uint8_t *bssid, int8_t rssi, uint8_t channel); + static void log_discarded_scan_result(const char *ssid, const uint8_t *bssid, int8_t rssi, uint8_t channel); /// Find next SSID that wasn't in scan results (might be hidden) /// Returns index of next potentially hidden SSID, or -1 if none found /// @param start_index Start searching from index after this (-1 to start from beginning) diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index de07818f59..2ceb755642 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -780,7 +780,7 @@ void WiFiComponent::wifi_scan_done_callback_(void *arg, STATUS status) { bssid_t{it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]}, std::string(ssid_cstr, it->ssid_len), it->channel, it->rssi, it->authmode != AUTH_OPEN, it->is_hidden != 0); } else { - WiFiComponent::log_discarded_scan_result_(ssid_cstr, it->bssid, it->rssi, it->channel); + WiFiComponent::log_discarded_scan_result(ssid_cstr, it->bssid, it->rssi, it->channel); } } ESP_LOGD(TAG, "Scan complete: %zu found, %zu stored%s", total, this->scan_result_.size(), diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index ef3aecc1a1..b5439122d8 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -857,7 +857,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) { this->scan_result_.emplace_back(bssid, std::move(ssid), record.primary, record.rssi, record.authmode != WIFI_AUTH_OPEN, ssid_cstr[0] == '\0'); } else { - WiFiComponent::log_discarded_scan_result_(ssid_cstr, record.bssid, record.rssi, record.primary); + WiFiComponent::log_discarded_scan_result(ssid_cstr, record.bssid, record.rssi, record.primary); } } ESP_LOGD(TAG, "Scan complete: %u found, %zu stored%s", number, this->scan_result_.size(), diff --git a/esphome/components/wifi/wifi_component_libretiny.cpp b/esphome/components/wifi/wifi_component_libretiny.cpp index dc89784de2..e94362d83f 100644 --- a/esphome/components/wifi/wifi_component_libretiny.cpp +++ b/esphome/components/wifi/wifi_component_libretiny.cpp @@ -692,7 +692,7 @@ void WiFiComponent::wifi_scan_done_callback_() { ssid_cstr[0] == '\0'); } else { auto &ap = scan->ap[i]; - WiFiComponent::log_discarded_scan_result_(ssid_cstr, ap.bssid.addr, ap.rssi, ap.channel); + WiFiComponent::log_discarded_scan_result(ssid_cstr, ap.bssid.addr, ap.rssi, ap.channel); } } ESP_LOGD(TAG, "Scan complete: %d found, %zu stored%s", num, this->scan_result_.size(), diff --git a/esphome/components/wifi/wifi_component_pico_w.cpp b/esphome/components/wifi/wifi_component_pico_w.cpp index a626e012a7..0c83f3eb87 100644 --- a/esphome/components/wifi/wifi_component_pico_w.cpp +++ b/esphome/components/wifi/wifi_component_pico_w.cpp @@ -143,7 +143,7 @@ void WiFiComponent::wifi_scan_result(void *env, const cyw43_ev_scan_result_t *re // Skip networks that don't match any configured network (unless full results needed) if (!this->needs_full_scan_results_() && !this->matches_configured_network_(ssid_cstr, result->bssid)) { - WiFiComponent::log_discarded_scan_result_(ssid_cstr, result->bssid, result->rssi, result->channel); + WiFiComponent::log_discarded_scan_result(ssid_cstr, result->bssid, result->rssi, result->channel); return; }