diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index f2fabb9080..8c7f219e0b 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -664,11 +664,22 @@ bool WiFiComponent::wifi_scan_start_(bool passive) { config.show_hidden = 1; #if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 4, 0) config.scan_type = passive ? WIFI_SCAN_TYPE_PASSIVE : WIFI_SCAN_TYPE_ACTIVE; + // Use shorter dwell times for roaming scans - we only need to detect strong + // nearby APs, not do a thorough survey. This also reduces off-channel time + // which can cause Beacon Timeout disconnects on some APs. + // Roaming times match the ESP32 IDF scan defaults. + static constexpr uint32_t SCAN_PASSIVE_DEFAULT = 500; + static constexpr uint32_t SCAN_PASSIVE_ROAMING = 300; + static constexpr uint32_t SCAN_ACTIVE_MIN_DEFAULT = 400; + static constexpr uint32_t SCAN_ACTIVE_MAX_DEFAULT = 500; + static constexpr uint32_t SCAN_ACTIVE_MIN_ROAMING = 100; + static constexpr uint32_t SCAN_ACTIVE_MAX_ROAMING = 300; + bool roaming = this->roaming_state_ == RoamingState::SCANNING; if (passive) { - config.scan_time.passive = 500; + config.scan_time.passive = roaming ? SCAN_PASSIVE_ROAMING : SCAN_PASSIVE_DEFAULT; } else { - config.scan_time.active.min = 400; - config.scan_time.active.max = 500; + config.scan_time.active.min = roaming ? SCAN_ACTIVE_MIN_ROAMING : SCAN_ACTIVE_MIN_DEFAULT; + config.scan_time.active.max = roaming ? SCAN_ACTIVE_MAX_ROAMING : SCAN_ACTIVE_MAX_DEFAULT; } #endif bool ret = wifi_station_scan(&config, &WiFiComponent::s_wifi_scan_done_callback);