mirror of
https://github.com/esphome/esphome.git
synced 2026-09-22 04:28:43 +00:00
Merge remote-tracking branch 'origin/integration' into integration
This commit is contained in:
@@ -1265,15 +1265,8 @@ 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,
|
||||
tcp_details,
|
||||
udp_details,
|
||||
tcp_listen_details,
|
||||
) = get_socket_counts()
|
||||
total_sockets = tcp_sockets + udp_sockets + tcp_listen
|
||||
sc = get_socket_counts()
|
||||
total_sockets = sc.tcp + sc.udp + sc.tcp_listen
|
||||
|
||||
# User specified their own value - respect it but warn if insufficient
|
||||
if user_max_sockets is not None:
|
||||
@@ -1294,9 +1287,9 @@ def _configure_lwip_max_sockets(conf: dict) -> None:
|
||||
"at least %d.",
|
||||
user_sockets_int,
|
||||
total_sockets,
|
||||
tcp_sockets,
|
||||
udp_sockets,
|
||||
tcp_listen,
|
||||
sc.tcp,
|
||||
sc.udp,
|
||||
sc.tcp_listen,
|
||||
total_sockets,
|
||||
)
|
||||
# User's value already added via sdkconfig_options processing
|
||||
@@ -1314,12 +1307,12 @@ def _configure_lwip_max_sockets(conf: dict) -> None:
|
||||
"(TCP=%d [%s], UDP=%d [%s], TCP_LISTEN=%d [%s])",
|
||||
max_sockets,
|
||||
sock_min,
|
||||
tcp_sockets,
|
||||
tcp_details,
|
||||
udp_sockets,
|
||||
udp_details,
|
||||
tcp_listen,
|
||||
tcp_listen_details,
|
||||
sc.tcp,
|
||||
sc.tcp_details,
|
||||
sc.udp,
|
||||
sc.udp_details,
|
||||
sc.tcp_listen,
|
||||
sc.tcp_listen_details,
|
||||
)
|
||||
|
||||
add_idf_sdkconfig_option("CONFIG_LWIP_MAX_SOCKETS", max_sockets)
|
||||
|
||||
@@ -290,7 +290,7 @@ def _configure_lwip(config: dict) -> None:
|
||||
Setting ESP8266 ESP32 BK SDK RTL SDK LN SDK New
|
||||
────────────────────────────────────────────────────────────────────────────
|
||||
TCP_SND_BUF 2×MSS 4×MSS 10×MSS 5×MSS 7×MSS 4×MSS
|
||||
TCP_WND 4×MSS 4×MSS 10×MSS 2×MSS 3×MSS 4×MSS
|
||||
TCP_WND 4×MSS 4×MSS 3/10×MSS 2×MSS 3×MSS 4×MSS
|
||||
MEM_LIBC_MALLOC 1 1 0 0 1 1
|
||||
MEMP_MEM_MALLOC 1 1 0 0 0 1
|
||||
MEM_SIZE N/A* N/A* 16/32KB 5KB N/A* N/A* BK
|
||||
@@ -313,23 +313,22 @@ def _configure_lwip(config: dict) -> None:
|
||||
**** RTL/LN LT overlay overrides to flat 7.
|
||||
***** Not defined in RTL SDK — lwIP opt.h defaults shown.
|
||||
"dynamic" = auto-calculated from component socket registrations via
|
||||
socket.get_socket_counts() with minimums of 10 TCP / 8 UDP.
|
||||
socket.get_socket_counts() with minimums of 8 TCP / 6 UDP.
|
||||
"""
|
||||
from esphome.components.socket import (
|
||||
MIN_TCP_LISTEN_SOCKETS,
|
||||
MIN_TCP_SOCKETS,
|
||||
MIN_UDP_SOCKETS,
|
||||
get_socket_counts,
|
||||
)
|
||||
|
||||
raw_tcp, raw_udp, raw_tcp_listen, tcp_details, udp_details, tcp_listen_details = (
|
||||
get_socket_counts()
|
||||
)
|
||||
sc = 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)
|
||||
tcp_sockets = max(MIN_TCP_SOCKETS, sc.tcp)
|
||||
udp_sockets = max(MIN_UDP_SOCKETS, sc.udp)
|
||||
# Listening sockets — registered by components (api, ota, web_server_base, etc.)
|
||||
# Not all components register yet, so ensure a minimum of 2 (api + ota baseline).
|
||||
listening_tcp = max(raw_tcp_listen, 2)
|
||||
# Not all components register yet, so ensure a minimum for baseline operation.
|
||||
listening_tcp = max(MIN_TCP_LISTEN_SOCKETS, sc.tcp_listen)
|
||||
|
||||
# TCP_SND_BUF: ESPAsyncWebServer allocates malloc(tcp_sndbuf()) per
|
||||
# response chunk. At 10×MSS=14.6KB (BK default) this causes OOM (#14095).
|
||||
@@ -398,20 +397,20 @@ def _configure_lwip(config: dict) -> None:
|
||||
if CORE.is_bk72xx:
|
||||
lwip_opts.append("PBUF_POOL_SIZE=10")
|
||||
|
||||
tcp_min = " (min)" if tcp_sockets > raw_tcp else ""
|
||||
udp_min = " (min)" if udp_sockets > raw_udp else ""
|
||||
listen_min = " (min)" if listening_tcp > raw_tcp_listen else ""
|
||||
tcp_min = " (min)" if tcp_sockets > sc.tcp else ""
|
||||
udp_min = " (min)" if udp_sockets > sc.udp else ""
|
||||
listen_min = " (min)" if listening_tcp > sc.tcp_listen else ""
|
||||
_LOGGER.info(
|
||||
"Configuring lwIP: TCP=%d%s [%s], UDP=%d%s [%s], TCP_LISTEN=%d%s [%s]",
|
||||
tcp_sockets,
|
||||
tcp_min,
|
||||
tcp_details,
|
||||
sc.tcp_details,
|
||||
udp_sockets,
|
||||
udp_min,
|
||||
udp_details,
|
||||
sc.udp_details,
|
||||
listening_tcp,
|
||||
listen_min,
|
||||
tcp_listen_details,
|
||||
sc.tcp_listen_details,
|
||||
)
|
||||
cg.add_platformio_option("custom_options.lwip", lwip_opts)
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from collections.abc import Callable, MutableMapping
|
||||
from dataclasses import dataclass
|
||||
from enum import StrEnum
|
||||
import logging
|
||||
|
||||
@@ -21,12 +22,14 @@ KEY_SOCKET_CONSUMERS_TCP = "socket_consumers_tcp"
|
||||
KEY_SOCKET_CONSUMERS_UDP = "socket_consumers_udp"
|
||||
KEY_SOCKET_CONSUMERS_TCP_LISTEN = "socket_consumers_tcp_listen"
|
||||
|
||||
# Recommended minimum socket counts to ensure headroom.
|
||||
# Recommended minimum socket counts.
|
||||
# Platforms should apply these (or their own) on top of get_socket_counts().
|
||||
# TCP: api(3) = 3 base, +5 headroom for ota-transfer/web_server/other.
|
||||
# UDP: dhcp(1) + dns(1) + mdns(2) + wake_loop(1) = 5 base, +1 headroom.
|
||||
# These cover minimal configs (e.g. api-only without web_server).
|
||||
# When web_server is present, its 5 registered sockets push past the TCP minimum.
|
||||
MIN_TCP_SOCKETS = 8
|
||||
MIN_UDP_SOCKETS = 6
|
||||
# Minimum listening sockets — at least api + ota baseline.
|
||||
MIN_TCP_LISTEN_SOCKETS = 2
|
||||
|
||||
# Wake loop threadsafe support tracking
|
||||
KEY_WAKE_LOOP_THREADSAFE_REQUIRED = "wake_loop_threadsafe_required"
|
||||
@@ -75,10 +78,20 @@ def _format_consumers(consumers: dict[str, int]) -> str:
|
||||
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.
|
||||
@dataclass(frozen=True)
|
||||
class SocketCounts:
|
||||
"""Socket counts and component details for platform configuration."""
|
||||
|
||||
Returns (tcp, udp, tcp_listen, tcp_details, udp_details, tcp_listen_details).
|
||||
tcp: int
|
||||
udp: int
|
||||
tcp_listen: int
|
||||
tcp_details: str
|
||||
udp_details: str
|
||||
tcp_listen_details: str
|
||||
|
||||
|
||||
def get_socket_counts() -> SocketCounts:
|
||||
"""Return socket counts and component details for platform configuration.
|
||||
|
||||
Platforms call this during code generation to configure lwIP socket limits.
|
||||
All components will have registered their needs by then.
|
||||
@@ -104,7 +117,9 @@ def get_socket_counts() -> tuple[int, int, int, str, str, str]:
|
||||
tcp_listen,
|
||||
tcp_listen_details,
|
||||
)
|
||||
return tcp, udp, tcp_listen, tcp_details, udp_details, tcp_listen_details
|
||||
return SocketCounts(
|
||||
tcp, udp, tcp_listen, tcp_details, udp_details, tcp_listen_details
|
||||
)
|
||||
|
||||
|
||||
def require_wake_loop_threadsafe() -> None:
|
||||
|
||||
Reference in New Issue
Block a user