1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-17 09:13:45 +01:00

store mdns values in flash

This commit is contained in:
J. Nick Koston
2025-10-07 21:19:35 -10:00
parent ec63247ae0
commit 55888b9bee
9 changed files with 94 additions and 51 deletions

View File

@@ -58,11 +58,21 @@ CONFIG_SCHEMA = cv.All(
)
def mdns_txt_record(key: str, value: str):
def mdns_txt_record_static(key: str, value: str):
"""Create a TXT record with a static (compile-time) value stored in flash."""
return cg.StructInitializer(
MDNSTXTRecord,
("key", cg.RawExpression(f"MDNS_STR({cg.safe_exp(key)})")),
("value", value),
("value", cg.RawExpression(f"MDNS_STR({cg.safe_exp(value)})")),
)
def mdns_txt_record_dynamic(key: str, value_expr: str):
"""Create a TXT record with a dynamic value (will be evaluated and stored in vector)."""
return cg.StructInitializer(
MDNSTXTRecord,
("key", cg.RawExpression(f"MDNS_STR({cg.safe_exp(key)})")),
("value", cg.RawExpression(f"MDNS_STR({value_expr})")),
)
@@ -107,23 +117,56 @@ async def to_code(config):
# Ensure at least 1 service (fallback service)
cg.add_define("MDNS_SERVICE_COUNT", max(1, service_count))
# Calculate compile-time dynamic TXT value count
# Dynamic values are those that cannot be stored in flash at compile time
dynamic_txt_count = 0
if "api" in CORE.config:
# Always: get_mac_address()
dynamic_txt_count += 1
# Conditional: friendly_name (if not empty, but we conservatively count it)
dynamic_txt_count += 1
# Conditional: dashboard_import_url
if "dashboard_import" in CORE.config:
dynamic_txt_count += 1
# User-provided templatable TXT values (only lambdas, not static strings)
dynamic_txt_count += sum(
1
for service in config[CONF_SERVICES]
for txt_value in service[CONF_TXT].values()
if cg.is_template(txt_value)
)
# Ensure at least 1 to avoid zero-size array
cg.add_define("MDNS_DYNAMIC_TXT_COUNT", max(1, dynamic_txt_count))
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
for service in config[CONF_SERVICES]:
txt = [
cg.StructInitializer(
MDNSTXTRecord,
("key", cg.RawExpression(f"MDNS_STR({cg.safe_exp(txt_key)})")),
("value", await cg.templatable(txt_value, [], cg.std_string)),
)
for txt_key, txt_value in service[CONF_TXT].items()
]
# Build the txt records list for the service
txt_records = []
for txt_key, txt_value in service[CONF_TXT].items():
if cg.is_template(txt_value):
# It's a lambda - evaluate and store using helper
templated_value = await cg.templatable(txt_value, [], cg.std_string)
txt_records.append(
cg.RawExpression(
f"{{MDNS_STR({cg.safe_exp(txt_key)}), MDNS_STR({var}->add_dynamic_txt_value(({templated_value})()))}}"
)
)
else:
# It's a static string - use directly in flash, no need to store in vector
txt_records.append(
cg.RawExpression(
f"{{MDNS_STR({cg.safe_exp(txt_key)}), MDNS_STR({cg.safe_exp(txt_value)})}}"
)
)
exp = mdns_service(
service[CONF_SERVICE],
service[CONF_PROTOCOL],
await cg.templatable(service[CONF_PORT], [], cg.uint16),
txt,
txt_records,
)
cg.add(var.add_extra_service(exp))