From d814b0fc771a982aeea15fc45d4c3c3ec968f5c1 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 18 Feb 2026 18:27:41 -0600 Subject: [PATCH 1/2] [udp] Register socket consumption for CONFIG_LWIP_MAX_SOCKETS The UDP component creates up to 2 sockets (broadcast + listen) but did not register them with the socket consumption API. This could cause CONFIG_LWIP_MAX_SOCKETS to be set too low on ESP32 IDF. Closes https://github.com/esphome/esphome/issues/14031 --- esphome/components/udp/__init__.py | 62 ++++++++++++++++++------------ 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/esphome/components/udp/__init__.py b/esphome/components/udp/__init__.py index bfaa5f2516..99a3dab868 100644 --- a/esphome/components/udp/__init__.py +++ b/esphome/components/udp/__init__.py @@ -65,33 +65,47 @@ RELOCATED = { ) } -CONFIG_SCHEMA = cv.COMPONENT_SCHEMA.extend( - { - cv.GenerateID(): cv.declare_id(UDPComponent), - cv.Optional(CONF_PORT, default=18511): cv.Any( - cv.port, - cv.Schema( + +def _consume_udp_sockets(config: cv.ConfigType) -> cv.ConfigType: + """Register socket needs for UDP component.""" + from esphome.components import socket + + # UDP uses up to 2 sockets: 1 broadcast + 1 listen + # Whether each is used depends on code generation, so register worst case + socket.consume_sockets(2, "udp")(config) + return config + + +CONFIG_SCHEMA = cv.All( + cv.COMPONENT_SCHEMA.extend( + { + cv.GenerateID(): cv.declare_id(UDPComponent), + cv.Optional(CONF_PORT, default=18511): cv.Any( + cv.port, + cv.Schema( + { + cv.Required(CONF_LISTEN_PORT): cv.port, + cv.Required(CONF_BROADCAST_PORT): cv.port, + } + ), + ), + cv.Optional( + CONF_LISTEN_ADDRESS, default="255.255.255.255" + ): cv.ipv4address_multi_broadcast, + cv.Optional(CONF_ADDRESSES, default=["255.255.255.255"]): cv.ensure_list( + cv.ipv4address, + ), + cv.Optional(CONF_ON_RECEIVE): automation.validate_automation( { - cv.Required(CONF_LISTEN_PORT): cv.port, - cv.Required(CONF_BROADCAST_PORT): cv.port, + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id( + Trigger.template(trigger_args) + ), } ), - ), - cv.Optional( - CONF_LISTEN_ADDRESS, default="255.255.255.255" - ): cv.ipv4address_multi_broadcast, - cv.Optional(CONF_ADDRESSES, default=["255.255.255.255"]): cv.ensure_list( - cv.ipv4address, - ), - cv.Optional(CONF_ON_RECEIVE): automation.validate_automation( - { - cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id( - Trigger.template(trigger_args) - ), - } - ), - } -).extend(RELOCATED) + } + ).extend(RELOCATED), + _consume_udp_sockets, +) async def register_udp_client(var, config): From 2ddf46ff0a5f5fa85fdb4fcf1294353852f51d80 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 18 Feb 2026 18:31:41 -0600 Subject: [PATCH 2/2] Fix ConfigType import --- esphome/components/udp/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/esphome/components/udp/__init__.py b/esphome/components/udp/__init__.py index 99a3dab868..c9586d0b95 100644 --- a/esphome/components/udp/__init__.py +++ b/esphome/components/udp/__init__.py @@ -14,6 +14,7 @@ import esphome.config_validation as cv from esphome.const import CONF_DATA, CONF_ID, CONF_PORT, CONF_TRIGGER_ID from esphome.core import ID from esphome.cpp_generator import MockObj +from esphome.types import ConfigType CODEOWNERS = ["@clydebarrow"] DEPENDENCIES = ["network"] @@ -66,7 +67,7 @@ RELOCATED = { } -def _consume_udp_sockets(config: cv.ConfigType) -> cv.ConfigType: +def _consume_udp_sockets(config: ConfigType) -> ConfigType: """Register socket needs for UDP component.""" from esphome.components import socket