diff --git a/esphome/components/mdns/mdns_esp8266.cpp b/esphome/components/mdns/mdns_esp8266.cpp index 684c55c4bc8..d13aee5f1e8 100644 --- a/esphome/components/mdns/mdns_esp8266.cpp +++ b/esphome/components/mdns/mdns_esp8266.cpp @@ -89,7 +89,16 @@ static void register_esp8266(MDNSComponent *, StaticVectorset_interval(MDNS_POLL_ID, MDNS_UPDATE_INTERVAL_MS, []() { mdns_responder.update_guarded(); }); + this->set_interval(MDNS_POLL_ID, MDNS_UPDATE_INTERVAL_MS, []() { +#ifdef USE_MDNS_WIFI_LISTENER + // Every send fails while the radio is off channel or no interface is up, and each one + // spins sendTimeout() for 50 ms; skip the tick rather than stall the loop for nothing. + auto *wifi = wifi::global_wifi_component; + if (wifi->is_roaming_scan_active() || (!wifi->is_connected() && !wifi->is_ap_active())) + return; +#endif + mdns_responder.update_guarded(); + }); this->set_timeout(MDNS_POLL_STOP_ID, MDNS_POLL_WINDOW_MS, [this]() { this->cancel_interval(MDNS_POLL_ID); }); } #endif diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index 2b1bc62e131..94fdd9bc142 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -476,6 +476,10 @@ class WiFiComponent final : public Component { /// True while a post-connect roaming scan holds the radio off-channel. bool is_roaming_scan_active() const { return this->roaming_state_ == RoamingState::SCANNING; } + /// True while a post-connect roam is in progress (scanning off-channel, reassociating, + /// or recovering from a failed roam). + bool is_roaming() const { return this->roaming_state_ != RoamingState::IDLE; } + #ifdef USE_ESP32 /// esp_netif handle of the station interface, used by network for default-route /// arbitration. nullptr until wifi_lazy_init_() has run.