diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index adcf2365a7..598e09e741 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -280,7 +280,9 @@ int8_t WiFiComponent::find_next_hidden_sta_(int8_t start_index) { } } - if (!this->ssid_was_seen_in_scan_(sta.get_ssid())) { + // If we didn't scan this cycle, treat all networks as potentially hidden + // Otherwise, only retry networks that weren't seen in the scan + if (!this->did_scan_this_cycle_ || !this->ssid_was_seen_in_scan_(sta.get_ssid())) { ESP_LOGD(TAG, "Hidden candidate " LOG_SECRET("'%s'") " at index %d", sta.get_ssid().c_str(), static_cast(i)); return static_cast(i); } @@ -986,6 +988,7 @@ void WiFiComponent::check_scanning_finished() { return; } this->scan_done_ = false; + this->did_scan_this_cycle_ = true; if (this->scan_result_.empty()) { ESP_LOGW(TAG, "No networks found"); @@ -1351,6 +1354,8 @@ bool WiFiComponent::transition_to_phase_(WiFiRetryPhase new_phase) { if (!this->is_captive_portal_active_() && !this->is_esp32_improv_active_()) { this->restart_adapter(); } + // Clear scan flag - we're starting a new retry cycle + this->did_scan_this_cycle_ = false; // Always enter cooldown after restart (or skip-restart) to allow stabilization // Use extended cooldown when AP is active to avoid constant scanning that blocks DNS this->state_ = WIFI_COMPONENT_STATE_COOLDOWN; diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index f5d21af99d..c12f32c052 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -533,6 +533,7 @@ class WiFiComponent : public Component { bool got_ipv4_address_{false}; bool keep_scan_results_{false}; bool force_scan_after_provision_{false}; + bool did_scan_this_cycle_{false}; // Pointers at the end (naturally aligned) Trigger<> *connect_trigger_{new Trigger<>()};