mirror of
https://github.com/esphome/esphome.git
synced 2025-11-01 07:31:51 +00:00
[network] Eliminate runtime string parsing for IP address initialization (#11561)
This commit is contained in:
@@ -14,7 +14,7 @@ from esphome.components.esp32.const import (
|
|||||||
VARIANT_ESP32S2,
|
VARIANT_ESP32S2,
|
||||||
VARIANT_ESP32S3,
|
VARIANT_ESP32S3,
|
||||||
)
|
)
|
||||||
from esphome.components.network import IPAddress
|
from esphome.components.network import ip_address_literal
|
||||||
from esphome.components.spi import CONF_INTERFACE_INDEX, get_spi_interface
|
from esphome.components.spi import CONF_INTERFACE_INDEX, get_spi_interface
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
@@ -320,11 +320,11 @@ def _final_validate_spi(config):
|
|||||||
def manual_ip(config):
|
def manual_ip(config):
|
||||||
return cg.StructInitializer(
|
return cg.StructInitializer(
|
||||||
ManualIP,
|
ManualIP,
|
||||||
("static_ip", IPAddress(str(config[CONF_STATIC_IP]))),
|
("static_ip", ip_address_literal(config[CONF_STATIC_IP])),
|
||||||
("gateway", IPAddress(str(config[CONF_GATEWAY]))),
|
("gateway", ip_address_literal(config[CONF_GATEWAY])),
|
||||||
("subnet", IPAddress(str(config[CONF_SUBNET]))),
|
("subnet", ip_address_literal(config[CONF_SUBNET])),
|
||||||
("dns1", IPAddress(str(config[CONF_DNS1]))),
|
("dns1", ip_address_literal(config[CONF_DNS1])),
|
||||||
("dns2", IPAddress(str(config[CONF_DNS2]))),
|
("dns2", ip_address_literal(config[CONF_DNS2])),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import ipaddress
|
||||||
|
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.components.esp32 import add_idf_sdkconfig_option
|
from esphome.components.esp32 import add_idf_sdkconfig_option
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
@@ -10,6 +12,41 @@ AUTO_LOAD = ["mdns"]
|
|||||||
network_ns = cg.esphome_ns.namespace("network")
|
network_ns = cg.esphome_ns.namespace("network")
|
||||||
IPAddress = network_ns.class_("IPAddress")
|
IPAddress = network_ns.class_("IPAddress")
|
||||||
|
|
||||||
|
|
||||||
|
def ip_address_literal(ip: str | int | None) -> cg.MockObj:
|
||||||
|
"""Generate an IPAddress with compile-time initialization instead of runtime parsing.
|
||||||
|
|
||||||
|
This function parses the IP address in Python during code generation and generates
|
||||||
|
a call to the 4-octet constructor (IPAddress(192, 168, 1, 1)) instead of the
|
||||||
|
string constructor (IPAddress("192.168.1.1")). This eliminates runtime string
|
||||||
|
parsing overhead and reduces flash usage on embedded systems.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
ip: IP address as string (e.g., "192.168.1.1"), ipaddress.IPv4Address, or None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
IPAddress expression that uses 4-octet constructor for efficiency
|
||||||
|
"""
|
||||||
|
if ip is None:
|
||||||
|
return IPAddress(0, 0, 0, 0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Parse using Python's ipaddress module
|
||||||
|
ip_obj = ipaddress.ip_address(ip)
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# Only support IPv4 for now
|
||||||
|
if isinstance(ip_obj, ipaddress.IPv4Address):
|
||||||
|
# Extract octets from the packed bytes representation
|
||||||
|
octets = ip_obj.packed
|
||||||
|
# Generate call to 4-octet constructor: IPAddress(192, 168, 1, 1)
|
||||||
|
return IPAddress(octets[0], octets[1], octets[2], octets[3])
|
||||||
|
|
||||||
|
# Fallback to string constructor if parsing fails
|
||||||
|
return IPAddress(str(ip))
|
||||||
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.Schema(
|
CONFIG_SCHEMA = cv.Schema(
|
||||||
{
|
{
|
||||||
cv.SplitDefault(
|
cv.SplitDefault(
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from esphome.automation import Condition
|
|||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.components.const import CONF_USE_PSRAM
|
from esphome.components.const import CONF_USE_PSRAM
|
||||||
from esphome.components.esp32 import add_idf_sdkconfig_option, const, get_esp32_variant
|
from esphome.components.esp32 import add_idf_sdkconfig_option, const, get_esp32_variant
|
||||||
from esphome.components.network import IPAddress
|
from esphome.components.network import ip_address_literal
|
||||||
from esphome.config_helpers import filter_source_files_from_platform
|
from esphome.config_helpers import filter_source_files_from_platform
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.config_validation import only_with_esp_idf
|
from esphome.config_validation import only_with_esp_idf
|
||||||
@@ -334,9 +334,7 @@ def eap_auth(config):
|
|||||||
|
|
||||||
|
|
||||||
def safe_ip(ip):
|
def safe_ip(ip):
|
||||||
if ip is None:
|
return ip_address_literal(ip)
|
||||||
return IPAddress(0, 0, 0, 0)
|
|
||||||
return IPAddress(str(ip))
|
|
||||||
|
|
||||||
|
|
||||||
def manual_ip(config):
|
def manual_ip(config):
|
||||||
|
|||||||
Reference in New Issue
Block a user