diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 44c92fcaa4..8a60da9f44 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -1464,9 +1464,10 @@ void WiFiComponent::check_connecting_finished(uint32_t now) { this->release_scan_results_(); -#ifdef USE_WIFI_CONNECT_STATE_LISTENERS +#if defined(USE_WIFI_CONNECT_STATE_LISTENERS) && !defined(USE_ESP8266) // Notify listeners now that state machine has reached STA_CONNECTED // This ensures wifi.connected condition returns true in listener automations + // On ESP8266, this is handled by process_pending_callbacks_() instead. this->notify_connect_state_listeners_(); #endif @@ -2193,7 +2194,7 @@ void WiFiComponent::release_scan_results_() { } } -#ifdef USE_WIFI_CONNECT_STATE_LISTENERS +#if defined(USE_WIFI_CONNECT_STATE_LISTENERS) && !defined(USE_ESP8266) void WiFiComponent::notify_connect_state_listeners_() { if (!this->pending_.connect_state) return; @@ -2206,7 +2207,7 @@ void WiFiComponent::notify_connect_state_listeners_() { listener->on_wifi_connect_state(StringRef(ssid, strlen(ssid)), bssid); } } -#endif // USE_WIFI_CONNECT_STATE_LISTENERS +#endif // USE_WIFI_CONNECT_STATE_LISTENERS && !USE_ESP8266 void WiFiComponent::check_roaming_(uint32_t now) { // Guard: not for hidden networks (may not appear in scan) diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index e910da2cbb..e6499e9c58 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -641,8 +641,9 @@ class WiFiComponent : public Component { /// Free scan results memory unless a component needs them void release_scan_results_(); -#ifdef USE_WIFI_CONNECT_STATE_LISTENERS +#if defined(USE_WIFI_CONNECT_STATE_LISTENERS) && !defined(USE_ESP8266) /// Notify connect state listeners (called after state machine reaches STA_CONNECTED) + /// On ESP8266, this is handled by process_pending_callbacks_() instead. void notify_connect_state_listeners_(); #endif @@ -726,18 +727,22 @@ class WiFiComponent : public Component { // This serves as both the error flag and stores the reason for deferred logging uint8_t error_from_callback_{0}; -#ifdef USE_ESP8266 - // Pending listener callbacks from system context (ESP8266 only) - // ESP8266 callbacks run in SDK system context with ~2KB stack where - // calling arbitrary listener callbacks is unsafe. These flags defer - // listener notifications to wifi_loop_() which runs with full stack. + // Pending listener callbacks deferred from platform callbacks to main loop. struct { +#ifdef USE_ESP8266 + // ESP8266 callbacks run in SDK system context with ~2KB stack where + // calling arbitrary listener callbacks is unsafe. These flags defer + // listener notifications to wifi_loop_() which runs with full stack. bool connect : 1; // STA connected, notify listeners bool disconnect : 1; // STA disconnected, notify listeners bool got_ip : 1; // Got IP, notify listeners bool scan_complete : 1; // Scan complete, notify listeners - } pending_{}; +#elif defined(USE_WIFI_CONNECT_STATE_LISTENERS) + // Non-ESP8266 platforms: deferred until state machine reaches STA_CONNECTED + // so wifi.connected condition returns true in listener automations. + bool connect_state : 1; #endif + } pending_{}; // Group all boolean values together bool has_ap_{false}; @@ -769,16 +774,6 @@ class WiFiComponent : public Component { SemaphoreHandle_t high_performance_semaphore_{nullptr}; #endif -#ifdef USE_WIFI_CONNECT_STATE_LISTENERS - // Pending listener notifications deferred until state machine reaches appropriate state. - // Listeners are notified after state transitions complete so conditions like - // wifi.connected return correct values in automations. - // Uses bitfields to minimize memory; more flags may be added as needed. - struct { - bool connect_state : 1; // Notify connect state listeners after STA_CONNECTED - } pending_{}; -#endif - #ifdef USE_WIFI_CONNECT_TRIGGER Trigger<> connect_trigger_; #endif