From 341b22c7e45dbce5d9287d970c0d1db18e5baa3a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 21 Feb 2026 17:45:13 -0600 Subject: [PATCH] [socket] Include component details in platform lwIP log messages get_socket_counts() now returns component detail strings alongside counts so platforms can include them in their log messages. ESP32 INFO log now shows which components consume each socket type. Co-Authored-By: Claude Opus 4.6 --- esphome/components/esp32/__init__.py | 15 +++++++++-- esphome/components/libretiny/__init__.py | 2 +- esphome/components/socket/__init__.py | 33 +++++++++++++----------- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/esphome/components/esp32/__init__.py b/esphome/components/esp32/__init__.py index 6bfa8b9053..54cba78ae2 100644 --- a/esphome/components/esp32/__init__.py +++ b/esphome/components/esp32/__init__.py @@ -1265,7 +1265,14 @@ def _configure_lwip_max_sockets(conf: dict) -> None: # CONFIG_LWIP_MAX_SOCKETS is a single VFS socket pool shared by all socket # types (TCP clients, TCP listeners, and UDP). Include all three counts. - tcp_sockets, udp_sockets, tcp_listen = get_socket_counts() + ( + tcp_sockets, + udp_sockets, + tcp_listen, + tcp_details, + udp_details, + tcp_listen_details, + ) = get_socket_counts() total_sockets = tcp_sockets + udp_sockets + tcp_listen # User specified their own value - respect it but warn if insufficient @@ -1302,11 +1309,15 @@ def _configure_lwip_max_sockets(conf: dict) -> None: log_level = logging.INFO if max_sockets > DEFAULT_MAX_SOCKETS else logging.DEBUG _LOGGER.log( log_level, - "Setting CONFIG_LWIP_MAX_SOCKETS to %d (%d TCP + %d UDP + %d TCP_LISTEN)", + "Setting CONFIG_LWIP_MAX_SOCKETS to %d " + "(TCP=%d [%s], UDP=%d [%s], TCP_LISTEN=%d [%s])", max_sockets, tcp_sockets, + tcp_details, udp_sockets, + udp_details, tcp_listen, + tcp_listen_details, ) add_idf_sdkconfig_option("CONFIG_LWIP_MAX_SOCKETS", max_sockets) diff --git a/esphome/components/libretiny/__init__.py b/esphome/components/libretiny/__init__.py index 0daf9733b8..5f04c816fe 100644 --- a/esphome/components/libretiny/__init__.py +++ b/esphome/components/libretiny/__init__.py @@ -321,7 +321,7 @@ def _configure_lwip(config: dict) -> None: get_socket_counts, ) - raw_tcp, raw_udp, raw_tcp_listen = get_socket_counts() + raw_tcp, raw_udp, raw_tcp_listen, *_ = get_socket_counts() # Apply platform minimums — ensure headroom for ESPHome's needs tcp_sockets = max(MIN_TCP_SOCKETS, raw_tcp) udp_sockets = max(MIN_UDP_SOCKETS, raw_udp) diff --git a/esphome/components/socket/__init__.py b/esphome/components/socket/__init__.py index de5c6d2dd6..4d195634a9 100644 --- a/esphome/components/socket/__init__.py +++ b/esphome/components/socket/__init__.py @@ -68,8 +68,17 @@ def consume_sockets( return _consume_sockets -def get_socket_counts() -> tuple[int, int, int]: - """Return (tcp_count, udp_count, tcp_listen_count) of raw registered socket needs. +def _format_consumers(consumers: dict[str, int]) -> str: + """Format consumer dict as 'name=count, ...' or 'none'.""" + if not consumers: + return "none" + return ", ".join(f"{name}={count}" for name, count in sorted(consumers.items())) + + +def get_socket_counts() -> tuple[int, int, int, str, str, str]: + """Return socket counts and component details for platform configuration. + + Returns (tcp, udp, tcp_listen, tcp_details, udp_details, tcp_listen_details). Platforms call this during code generation to configure lwIP socket limits. All components will have registered their needs by then. @@ -83,25 +92,19 @@ def get_socket_counts() -> tuple[int, int, int]: udp = sum(udp_consumers.values()) tcp_listen = sum(tcp_listen_consumers.values()) - tcp_list = ", ".join( - f"{name}={count}" for name, count in sorted(tcp_consumers.items()) - ) - udp_list = ", ".join( - f"{name}={count}" for name, count in sorted(udp_consumers.items()) - ) - tcp_listen_list = ", ".join( - f"{name}={count}" for name, count in sorted(tcp_listen_consumers.items()) - ) + tcp_details = _format_consumers(tcp_consumers) + udp_details = _format_consumers(udp_consumers) + tcp_listen_details = _format_consumers(tcp_listen_consumers) _LOGGER.debug( "Socket counts: TCP=%d (%s), UDP=%d (%s), TCP_LISTEN=%d (%s)", tcp, - tcp_list or "none", + tcp_details, udp, - udp_list or "none", + udp_details, tcp_listen, - tcp_listen_list or "none", + tcp_listen_details, ) - return tcp, udp, tcp_listen + return tcp, udp, tcp_listen, tcp_details, udp_details, tcp_listen_details def require_wake_loop_threadsafe() -> None: