From 8390a98614b65ace4c5333764006e66214006b28 Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Mon, 16 Feb 2026 12:36:22 +0100 Subject: [PATCH 01/10] [ethernet, network, openthread, wifi] centralize esp32 netif intialization --- .../components/espnow/espnow_component.cpp | 13 ++++---- .../ethernet/ethernet_component.cpp | 12 ++++--- esphome/components/network/esp_utils.cpp | 33 +++++++++++++++++++ esphome/components/network/esp_utils.h | 15 +++++++++ .../components/openthread/openthread_esp.cpp | 9 +++-- .../wifi/wifi_component_esp_idf.cpp | 16 ++++----- 6 files changed, 77 insertions(+), 21 deletions(-) create mode 100644 esphome/components/network/esp_utils.cpp create mode 100644 esphome/components/network/esp_utils.h diff --git a/esphome/components/espnow/espnow_component.cpp b/esphome/components/espnow/espnow_component.cpp index 991803d8703..d2e53d64d8a 100644 --- a/esphome/components/espnow/espnow_component.cpp +++ b/esphome/components/espnow/espnow_component.cpp @@ -21,6 +21,7 @@ #ifdef USE_WIFI #include "esphome/components/wifi/wifi_component.h" #endif +#include "esphome/components/network/esp_utils.h" namespace esphome::espnow { @@ -149,11 +150,13 @@ bool ESPNowComponent::is_wifi_enabled() { } void ESPNowComponent::setup() { -#ifndef USE_WIFI // Initialize LwIP stack for wake_loop_threadsafe() socket support - // When WiFi component is present, it handles esp_netif_init() - ESP_ERROR_CHECK(esp_netif_init()); -#endif + bool success = network::esp_init(); + if (!success) { + ESP_LOGE(TAG, "Failed to initialize network interface"); + this->mark_failed(); + return; + } if (this->enable_on_boot_) { this->enable_(); @@ -174,8 +177,6 @@ void ESPNowComponent::enable() { void ESPNowComponent::enable_() { if (!this->is_wifi_enabled()) { - esp_event_loop_create_default(); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); diff --git a/esphome/components/ethernet/ethernet_component.cpp b/esphome/components/ethernet/ethernet_component.cpp index f9d98ad51b6..061c3106c85 100644 --- a/esphome/components/ethernet/ethernet_component.cpp +++ b/esphome/components/ethernet/ethernet_component.cpp @@ -19,6 +19,8 @@ #include #endif +#include "esphome/components/network/esp_utils.h" + namespace esphome { namespace ethernet { @@ -102,10 +104,12 @@ void EthernetComponent::setup() { ESPHL_ERROR_CHECK(err, "SPI bus initialize error"); #endif - err = esp_netif_init(); - ESPHL_ERROR_CHECK(err, "ETH netif init error"); - err = esp_event_loop_create_default(); - ESPHL_ERROR_CHECK(err, "ETH event loop error"); + bool success = network::esp_init(); + if (!success) { + ESP_LOGE(TAG, "Failed to initialize network interface"); + this->mark_failed(); + return; + } esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH(); this->eth_netif_ = esp_netif_new(&cfg); diff --git a/esphome/components/network/esp_utils.cpp b/esphome/components/network/esp_utils.cpp new file mode 100644 index 00000000000..c04dd09d567 --- /dev/null +++ b/esphome/components/network/esp_utils.cpp @@ -0,0 +1,33 @@ +#include "esp_utils.h" + +#include "esphome/core/defines.h" +#if defined(USE_NETWORK) && defined(USE_ESP32) +#include "esphome/core/log.h" +#include "esp_err.h" +#include "esp_netif.h" +#include "esp_event.h" +namespace esphome { +namespace network { + +static const char *const TAG = "network_esp"; + +bool esp_init() { + esp_err_t err; + err = esp_netif_init(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "esp_netif_init failed: (%d) %s", err, esp_err_to_name(err)); + return false; + } + err = esp_event_loop_create_default(); + // ESP_ERR_INVALID_STATE is returned if the default loop already exists, + // which is fine since we just want to make sure it exists + if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { + ESP_LOGE(TAG, "esp_event_loop_create_default failed: (%d) %s", err, esp_err_to_name(err)); + return false; + } + return true; +} + +} // namespace network +} // namespace esphome +#endif diff --git a/esphome/components/network/esp_utils.h b/esphome/components/network/esp_utils.h new file mode 100644 index 00000000000..37e9da46b0f --- /dev/null +++ b/esphome/components/network/esp_utils.h @@ -0,0 +1,15 @@ +#pragma once +#include "esphome/core/defines.h" +#if defined(USE_NETWORK) && defined(USE_ESP32) +#include "esp_netif.h" +#include "esp_event.h" +namespace esphome { +namespace network { + +/// Initialize ESP-IDF network interfaces and ensure the default event loop exists. +/// Returns true on success; logs and returns false on failure. +bool esp_init(); + +} // namespace network +} // namespace esphome +#endif diff --git a/esphome/components/openthread/openthread_esp.cpp b/esphome/components/openthread/openthread_esp.cpp index 79cd8098093..be59ad7a757 100644 --- a/esphome/components/openthread/openthread_esp.cpp +++ b/esphome/components/openthread/openthread_esp.cpp @@ -10,6 +10,7 @@ #include "esp_task_wdt.h" #include "esphome/core/helpers.h" #include "esphome/core/log.h" +#include "esphome/components/network/esp_utils.h" #include "esp_err.h" #include "esp_event.h" @@ -35,8 +36,12 @@ void OpenThreadComponent::setup() { .max_fds = 3, }; ESP_ERROR_CHECK(nvs_flash_init()); - ESP_ERROR_CHECK(esp_event_loop_create_default()); - ESP_ERROR_CHECK(esp_netif_init()); + bool success = network::esp_init(); + if (!success) { + ESP_LOGE(TAG, "Failed to initialize network interface"); + this->mark_failed(); + return; + } ESP_ERROR_CHECK(esp_vfs_eventfd_register(&eventfd_config)); xTaskCreate( diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index 52ee4821215..1a49efa831a 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -31,6 +31,7 @@ #ifdef USE_CAPTIVE_PORTAL #include "esphome/components/captive_portal/captive_portal.h" #endif +#include "esphome/components/network/esp_utils.h" #include "lwip/apps/sntp.h" #include "lwip/dns.h" @@ -138,9 +139,10 @@ void WiFiComponent::wifi_pre_setup_() { get_mac_address_raw(mac); set_mac_address(mac); } - esp_err_t err = esp_netif_init(); - if (err != ERR_OK) { - ESP_LOGE(TAG, "esp_netif_init failed: %s", esp_err_to_name(err)); + bool success = network::esp_init(); + if (!success) { + ESP_LOGE(TAG, "Failed to initialize network interface"); + this->mark_failed(); return; } s_wifi_event_group = xEventGroupCreate(); @@ -154,13 +156,9 @@ void WiFiComponent::wifi_pre_setup_() { ESP_LOGE(TAG, "xQueueCreate failed"); return; } - err = esp_event_loop_create_default(); - if (err != ERR_OK) { - ESP_LOGE(TAG, "esp_event_loop_create_default failed: %s", esp_err_to_name(err)); - return; - } esp_event_handler_instance_t instance_wifi_id, instance_ip_id; - err = esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, nullptr, &instance_wifi_id); + esp_err_t err = + esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, nullptr, &instance_wifi_id); if (err != ERR_OK) { ESP_LOGE(TAG, "esp_event_handler_instance_register failed: %s", esp_err_to_name(err)); return; From 8c7d2d984ea28a7d7ce724ac6686cc8e56a6eb7a Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Mon, 16 Feb 2026 12:47:14 +0100 Subject: [PATCH 02/10] Just store if it is initialized --- esphome/components/network/esp_utils.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/esphome/components/network/esp_utils.cpp b/esphome/components/network/esp_utils.cpp index c04dd09d567..d66dc27b9bc 100644 --- a/esphome/components/network/esp_utils.cpp +++ b/esphome/components/network/esp_utils.cpp @@ -11,7 +11,12 @@ namespace network { static const char *const TAG = "network_esp"; +static bool initialized = false; + bool esp_init() { + if (initialized) { + return true; + } esp_err_t err; err = esp_netif_init(); if (err != ESP_OK) { @@ -19,12 +24,11 @@ bool esp_init() { return false; } err = esp_event_loop_create_default(); - // ESP_ERR_INVALID_STATE is returned if the default loop already exists, - // which is fine since we just want to make sure it exists - if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { + if (err != ESP_OK) { ESP_LOGE(TAG, "esp_event_loop_create_default failed: (%d) %s", err, esp_err_to_name(err)); return false; } + initialized = true; return true; } From 0a518c1e4c97d782cf3f6dd36cc8508cb0b8c1d0 Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Mon, 16 Feb 2026 13:13:23 +0100 Subject: [PATCH 03/10] Switch to a network component --- esphome/components/espnow/__init__.py | 2 +- .../components/espnow/espnow_component.cpp | 8 +----- .../ethernet/ethernet_component.cpp | 10 +------ esphome/components/network/__init__.py | 12 +++++++- esphome/components/network/esp_utils.h | 15 ---------- .../{esp_utils.cpp => network_component.cpp} | 28 +++++++++---------- .../components/network/network_component.h | 18 ++++++++++++ .../components/openthread/openthread_esp.cpp | 8 +----- .../wifi/wifi_component_esp_idf.cpp | 8 +----- 9 files changed, 47 insertions(+), 62 deletions(-) delete mode 100644 esphome/components/network/esp_utils.h rename esphome/components/network/{esp_utils.cpp => network_component.cpp} (62%) create mode 100644 esphome/components/network/network_component.h diff --git a/esphome/components/espnow/__init__.py b/esphome/components/espnow/__init__.py index faeccd910e0..e01b84cb575 100644 --- a/esphome/components/espnow/__init__.py +++ b/esphome/components/espnow/__init__.py @@ -17,7 +17,7 @@ from esphome.core import HexInt from esphome.types import ConfigType CODEOWNERS = ["@jesserockz"] -AUTO_LOAD = ["socket"] +AUTO_LOAD = ["socket", "network"] byte_vector = cg.std_vector.template(cg.uint8) peer_address_t = cg.std_ns.class_("array").template(cg.uint8, 6) diff --git a/esphome/components/espnow/espnow_component.cpp b/esphome/components/espnow/espnow_component.cpp index d2e53d64d8a..c7b6aa500b4 100644 --- a/esphome/components/espnow/espnow_component.cpp +++ b/esphome/components/espnow/espnow_component.cpp @@ -21,7 +21,6 @@ #ifdef USE_WIFI #include "esphome/components/wifi/wifi_component.h" #endif -#include "esphome/components/network/esp_utils.h" namespace esphome::espnow { @@ -151,12 +150,7 @@ bool ESPNowComponent::is_wifi_enabled() { void ESPNowComponent::setup() { // Initialize LwIP stack for wake_loop_threadsafe() socket support - bool success = network::esp_init(); - if (!success) { - ESP_LOGE(TAG, "Failed to initialize network interface"); - this->mark_failed(); - return; - } + // Network interface setup handled by network component if (this->enable_on_boot_) { this->enable_(); diff --git a/esphome/components/ethernet/ethernet_component.cpp b/esphome/components/ethernet/ethernet_component.cpp index 061c3106c85..c651a7d50af 100644 --- a/esphome/components/ethernet/ethernet_component.cpp +++ b/esphome/components/ethernet/ethernet_component.cpp @@ -19,8 +19,6 @@ #include #endif -#include "esphome/components/network/esp_utils.h" - namespace esphome { namespace ethernet { @@ -103,13 +101,7 @@ void EthernetComponent::setup() { err = spi_bus_initialize(host, &buscfg, SPI_DMA_CH_AUTO); ESPHL_ERROR_CHECK(err, "SPI bus initialize error"); #endif - - bool success = network::esp_init(); - if (!success) { - ESP_LOGE(TAG, "Failed to initialize network interface"); - this->mark_failed(); - return; - } + // Network interface setup handled by network component esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH(); this->eth_netif_ = esp_netif_new(&cfg); diff --git a/esphome/components/network/__init__.py b/esphome/components/network/__init__.py index 1f75b12178a..3c78ea681ca 100644 --- a/esphome/components/network/__init__.py +++ b/esphome/components/network/__init__.py @@ -5,7 +5,7 @@ import esphome.codegen as cg from esphome.components.esp32 import add_idf_sdkconfig_option from esphome.components.psram import is_guaranteed as psram_is_guaranteed import esphome.config_validation as cv -from esphome.const import CONF_ENABLE_IPV6, CONF_MIN_IPV6_ADDR_COUNT +from esphome.const import CONF_ENABLE_IPV6, CONF_ID, CONF_MIN_IPV6_ADDR_COUNT from esphome.core import CORE, CoroPriority, coroutine_with_priority CODEOWNERS = ["@esphome/core"] @@ -19,6 +19,7 @@ KEY_HIGH_PERFORMANCE_NETWORKING = "high_performance_networking" CONF_ENABLE_HIGH_PERFORMANCE = "enable_high_performance" network_ns = cg.esphome_ns.namespace("network") +NetworkComponent = network_ns.class_("NetworkComponent", cg.Component) IPAddress = network_ns.class_("IPAddress") @@ -107,6 +108,7 @@ def has_high_performance_networking() -> bool: CONFIG_SCHEMA = cv.Schema( { + cv.GenerateID(): cv.declare_id(NetworkComponent), cv.SplitDefault( CONF_ENABLE_IPV6, esp8266=False, @@ -224,3 +226,11 @@ async def to_code(config): cg.add_build_flag("-DPIO_FRAMEWORK_ARDUINO_LWIP2_IPV6_LOW_MEMORY") if CORE.is_bk72xx: cg.add_build_flag("-DCONFIG_IPV6") + + CORE.add_job(network_component_to_code, config) + + +@coroutine_with_priority(CoroPriority.NETWORK_SERVICES) +async def network_component_to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await cg.register_component(var, config) diff --git a/esphome/components/network/esp_utils.h b/esphome/components/network/esp_utils.h deleted file mode 100644 index 37e9da46b0f..00000000000 --- a/esphome/components/network/esp_utils.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include "esphome/core/defines.h" -#if defined(USE_NETWORK) && defined(USE_ESP32) -#include "esp_netif.h" -#include "esp_event.h" -namespace esphome { -namespace network { - -/// Initialize ESP-IDF network interfaces and ensure the default event loop exists. -/// Returns true on success; logs and returns false on failure. -bool esp_init(); - -} // namespace network -} // namespace esphome -#endif diff --git a/esphome/components/network/esp_utils.cpp b/esphome/components/network/network_component.cpp similarity index 62% rename from esphome/components/network/esp_utils.cpp rename to esphome/components/network/network_component.cpp index d66dc27b9bc..e9c4dcd7464 100644 --- a/esphome/components/network/esp_utils.cpp +++ b/esphome/components/network/network_component.cpp @@ -1,37 +1,35 @@ -#include "esp_utils.h" +#include "network_component.h" #include "esphome/core/defines.h" -#if defined(USE_NETWORK) && defined(USE_ESP32) +#ifdef USE_NETWORK #include "esphome/core/log.h" +#ifdef USE_ESP32 #include "esp_err.h" #include "esp_netif.h" #include "esp_event.h" +#endif namespace esphome { namespace network { -static const char *const TAG = "network_esp"; +static const char *const TAG = "network"; -static bool initialized = false; - -bool esp_init() { - if (initialized) { - return true; - } +void NetworkComponent::setup() { + // Initialize ESP-IDF network interfaces and ensure the default event loop exists. +#ifdef USE_ESP32 esp_err_t err; err = esp_netif_init(); if (err != ESP_OK) { ESP_LOGE(TAG, "esp_netif_init failed: (%d) %s", err, esp_err_to_name(err)); - return false; + this->mark_failed(); + return; } err = esp_event_loop_create_default(); if (err != ESP_OK) { ESP_LOGE(TAG, "esp_event_loop_create_default failed: (%d) %s", err, esp_err_to_name(err)); - return false; + this->mark_failed(); + return; } - initialized = true; - return true; -} - +#endif } // namespace network } // namespace esphome #endif diff --git a/esphome/components/network/network_component.h b/esphome/components/network/network_component.h new file mode 100644 index 00000000000..9530668a06e --- /dev/null +++ b/esphome/components/network/network_component.h @@ -0,0 +1,18 @@ +#pragma once +#include "esphome/core/defines.h" +#ifdef USE_NETWORK + +#ifdef USE_ESP32 +#include "esp_netif.h" +#include "esp_event.h" +#endif +namespace esphome { +namespace network { +class NetworkComponent : public Component { + public: + void setup() override; + float get_setup_priority() const override { return setup_priority::AFTER_BLUETOOTH; } +}; +} // namespace network +} // namespace esphome +#endif diff --git a/esphome/components/openthread/openthread_esp.cpp b/esphome/components/openthread/openthread_esp.cpp index be59ad7a757..451ff025e02 100644 --- a/esphome/components/openthread/openthread_esp.cpp +++ b/esphome/components/openthread/openthread_esp.cpp @@ -10,7 +10,6 @@ #include "esp_task_wdt.h" #include "esphome/core/helpers.h" #include "esphome/core/log.h" -#include "esphome/components/network/esp_utils.h" #include "esp_err.h" #include "esp_event.h" @@ -35,13 +34,8 @@ void OpenThreadComponent::setup() { esp_vfs_eventfd_config_t eventfd_config = { .max_fds = 3, }; + // Network interface setup handled by network component ESP_ERROR_CHECK(nvs_flash_init()); - bool success = network::esp_init(); - if (!success) { - ESP_LOGE(TAG, "Failed to initialize network interface"); - this->mark_failed(); - return; - } ESP_ERROR_CHECK(esp_vfs_eventfd_register(&eventfd_config)); xTaskCreate( diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index 1a49efa831a..39537b2cffa 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -31,7 +31,6 @@ #ifdef USE_CAPTIVE_PORTAL #include "esphome/components/captive_portal/captive_portal.h" #endif -#include "esphome/components/network/esp_utils.h" #include "lwip/apps/sntp.h" #include "lwip/dns.h" @@ -139,12 +138,7 @@ void WiFiComponent::wifi_pre_setup_() { get_mac_address_raw(mac); set_mac_address(mac); } - bool success = network::esp_init(); - if (!success) { - ESP_LOGE(TAG, "Failed to initialize network interface"); - this->mark_failed(); - return; - } + // Network interface setup handled by network component s_wifi_event_group = xEventGroupCreate(); if (s_wifi_event_group == nullptr) { ESP_LOGE(TAG, "xEventGroupCreate failed"); From cde89212fc7e1c1fd06fef201c5525113f0e5aa0 Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Mon, 16 Feb 2026 13:17:00 +0100 Subject: [PATCH 04/10] Typo --- esphome/components/network/network_component.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/network/network_component.cpp b/esphome/components/network/network_component.cpp index e9c4dcd7464..ae0da48b617 100644 --- a/esphome/components/network/network_component.cpp +++ b/esphome/components/network/network_component.cpp @@ -28,8 +28,8 @@ void NetworkComponent::setup() { ESP_LOGE(TAG, "esp_event_loop_create_default failed: (%d) %s", err, esp_err_to_name(err)); this->mark_failed(); return; - } #endif + } } // namespace network } // namespace esphome #endif From 8a1ddfb1ccc080ccbff88f46a66187c6bf5f490c Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Mon, 16 Feb 2026 13:21:13 +0100 Subject: [PATCH 05/10] Typo --- esphome/components/network/network_component.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/esphome/components/network/network_component.cpp b/esphome/components/network/network_component.cpp index ae0da48b617..9f23360875c 100644 --- a/esphome/components/network/network_component.cpp +++ b/esphome/components/network/network_component.cpp @@ -28,8 +28,9 @@ void NetworkComponent::setup() { ESP_LOGE(TAG, "esp_event_loop_create_default failed: (%d) %s", err, esp_err_to_name(err)); this->mark_failed(); return; -#endif } +#endif +} } // namespace network } // namespace esphome #endif From 47854ff9dee0169b30dd199b49d1489f94a96735 Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Mon, 16 Feb 2026 13:31:19 +0100 Subject: [PATCH 06/10] Add missing imports --- esphome/components/network/network_component.cpp | 6 ++++-- esphome/components/network/network_component.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/esphome/components/network/network_component.cpp b/esphome/components/network/network_component.cpp index 9f23360875c..1a4dd7c39b2 100644 --- a/esphome/components/network/network_component.cpp +++ b/esphome/components/network/network_component.cpp @@ -14,7 +14,7 @@ namespace network { static const char *const TAG = "network"; void NetworkComponent::setup() { - // Initialize ESP-IDF network interfaces and ensure the default event loop exists. + // Initialize ESP-IDF network interfaces and ensure the default event loop exists #ifdef USE_ESP32 esp_err_t err; err = esp_netif_init(); @@ -24,7 +24,9 @@ void NetworkComponent::setup() { return; } err = esp_event_loop_create_default(); - if (err != ESP_OK) { + // ESP_ERR_INVALID_STATE is returned if the default loop already exists, + // which is fine since we just want to make sure it exists + if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { ESP_LOGE(TAG, "esp_event_loop_create_default failed: (%d) %s", err, esp_err_to_name(err)); this->mark_failed(); return; diff --git a/esphome/components/network/network_component.h b/esphome/components/network/network_component.h index 9530668a06e..5de0ac6c89c 100644 --- a/esphome/components/network/network_component.h +++ b/esphome/components/network/network_component.h @@ -1,6 +1,7 @@ #pragma once #include "esphome/core/defines.h" #ifdef USE_NETWORK +#include "esphome/core/component.h" #ifdef USE_ESP32 #include "esp_netif.h" From de53e7a6b1e099011413ce41c4f096fc34397e0c Mon Sep 17 00:00:00 2001 From: kbx81 Date: Mon, 18 May 2026 18:24:54 -0500 Subject: [PATCH 07/10] preen --- esphome/components/espnow/espnow_component.cpp | 3 --- esphome/components/network/network_component.cpp | 7 +++---- esphome/components/network/network_component.h | 6 ++---- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/esphome/components/espnow/espnow_component.cpp b/esphome/components/espnow/espnow_component.cpp index 6c2d2c23db9..403e6f4944a 100644 --- a/esphome/components/espnow/espnow_component.cpp +++ b/esphome/components/espnow/espnow_component.cpp @@ -149,9 +149,6 @@ bool ESPNowComponent::is_wifi_enabled() { } void ESPNowComponent::setup() { - // Initialize LwIP stack for wake_loop_threadsafe() socket support - // Network interface setup handled by network component - if (this->enable_on_boot_) { this->enable_(); } else { diff --git a/esphome/components/network/network_component.cpp b/esphome/components/network/network_component.cpp index 1a4dd7c39b2..85dcd21c2be 100644 --- a/esphome/components/network/network_component.cpp +++ b/esphome/components/network/network_component.cpp @@ -8,8 +8,7 @@ #include "esp_netif.h" #include "esp_event.h" #endif -namespace esphome { -namespace network { +namespace esphome::network { static const char *const TAG = "network"; @@ -33,6 +32,6 @@ void NetworkComponent::setup() { } #endif } -} // namespace network -} // namespace esphome + +} // namespace esphome::network #endif diff --git a/esphome/components/network/network_component.h b/esphome/components/network/network_component.h index 5de0ac6c89c..dfb21699e31 100644 --- a/esphome/components/network/network_component.h +++ b/esphome/components/network/network_component.h @@ -7,13 +7,11 @@ #include "esp_netif.h" #include "esp_event.h" #endif -namespace esphome { -namespace network { +namespace esphome::network { class NetworkComponent : public Component { public: void setup() override; float get_setup_priority() const override { return setup_priority::AFTER_BLUETOOTH; } }; -} // namespace network -} // namespace esphome +} // namespace esphome::network #endif From 028a54422ed7e720c91a5eaad1c6c89db74ea1fd Mon Sep 17 00:00:00 2001 From: kbx81 Date: Mon, 18 May 2026 18:31:31 -0500 Subject: [PATCH 08/10] preen --- esphome/components/network/network_component.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/esphome/components/network/network_component.h b/esphome/components/network/network_component.h index dfb21699e31..59dc103ffbc 100644 --- a/esphome/components/network/network_component.h +++ b/esphome/components/network/network_component.h @@ -3,10 +3,6 @@ #ifdef USE_NETWORK #include "esphome/core/component.h" -#ifdef USE_ESP32 -#include "esp_netif.h" -#include "esp_event.h" -#endif namespace esphome::network { class NetworkComponent : public Component { public: From 1332ebe72992969ae9cd810160a0c7c16dd104db Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Tue, 19 May 2026 09:20:08 +0200 Subject: [PATCH 09/10] Exclude from non ESP32 devices --- esphome/components/network/__init__.py | 8 ++++++-- esphome/components/network/network_component.cpp | 6 +----- esphome/components/network/network_component.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/esphome/components/network/__init__.py b/esphome/components/network/__init__.py index 23de8f57ab0..44d9b8ff17a 100644 --- a/esphome/components/network/__init__.py +++ b/esphome/components/network/__init__.py @@ -226,8 +226,12 @@ async def to_code(config): cg.add_build_flag("-DPIO_FRAMEWORK_ARDUINO_LWIP2_IPV6_LOW_MEMORY") if CORE.is_rp2040: cg.add_build_flag("-DPIO_FRAMEWORK_ARDUINO_ENABLE_IPV6") - - CORE.add_job(network_component_to_code, config) + # Pvariable creation lives in a separate coroutine at NETWORK_SERVICES so it + # emits after wifi/ethernet at COMMUNICATION. This keeps compile-time config + # (above) separate from C++ object lifecycle and allows wiring in interface + # pointers via get_variable(). + if CORE.is_esp32: + CORE.add_job(network_component_to_code, config) @coroutine_with_priority(CoroPriority.NETWORK_SERVICES) diff --git a/esphome/components/network/network_component.cpp b/esphome/components/network/network_component.cpp index 85dcd21c2be..40cf64906c9 100644 --- a/esphome/components/network/network_component.cpp +++ b/esphome/components/network/network_component.cpp @@ -1,20 +1,17 @@ #include "network_component.h" #include "esphome/core/defines.h" -#ifdef USE_NETWORK +#if defined(USE_NETWORK) && defined(USE_ESP32) #include "esphome/core/log.h" -#ifdef USE_ESP32 #include "esp_err.h" #include "esp_netif.h" #include "esp_event.h" -#endif namespace esphome::network { static const char *const TAG = "network"; void NetworkComponent::setup() { // Initialize ESP-IDF network interfaces and ensure the default event loop exists -#ifdef USE_ESP32 esp_err_t err; err = esp_netif_init(); if (err != ESP_OK) { @@ -30,7 +27,6 @@ void NetworkComponent::setup() { this->mark_failed(); return; } -#endif } } // namespace esphome::network diff --git a/esphome/components/network/network_component.h b/esphome/components/network/network_component.h index 59dc103ffbc..d714138929f 100644 --- a/esphome/components/network/network_component.h +++ b/esphome/components/network/network_component.h @@ -1,6 +1,6 @@ #pragma once #include "esphome/core/defines.h" -#ifdef USE_NETWORK +#if defined(USE_NETWORK) && defined(USE_ESP32) #include "esphome/core/component.h" namespace esphome::network { From 73b8491936c02c411a4be4e149ab9692c8a51f50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Mart=C3=ADn?= Date: Tue, 19 May 2026 17:50:02 +0200 Subject: [PATCH 10/10] Update esphome/components/network/network_component.h Co-authored-by: Keith Burzinski --- esphome/components/network/network_component.h | 1 + 1 file changed, 1 insertion(+) diff --git a/esphome/components/network/network_component.h b/esphome/components/network/network_component.h index d714138929f..dde15940e40 100644 --- a/esphome/components/network/network_component.h +++ b/esphome/components/network/network_component.h @@ -7,6 +7,7 @@ namespace esphome::network { class NetworkComponent : public Component { public: void setup() override; + // AFTER_BLUETOOTH: BLE controller must initialize before esp_netif_init per IDF guidance. float get_setup_priority() const override { return setup_priority::AFTER_BLUETOOTH; } }; } // namespace esphome::network