From fa299eed588d48f785b4782decf1fb322f32ff33 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 23 Nov 2025 21:45:28 -0600 Subject: [PATCH] [mdns] Store MAC address in fixed buffer to reduce RAM usage --- esphome/components/mdns/__init__.py | 10 ++++----- esphome/components/mdns/mdns_component.cpp | 2 +- esphome/components/mdns/mdns_component.h | 24 ++++++++++++++++++++-- esphome/components/mdns/mdns_esp32.cpp | 3 ++- esphome/components/mdns/mdns_esp8266.cpp | 3 ++- esphome/components/mdns/mdns_host.cpp | 1 + esphome/components/mdns/mdns_libretiny.cpp | 3 ++- esphome/components/mdns/mdns_rp2040.cpp | 3 ++- esphome/core/defines.h | 3 ++- 9 files changed, 39 insertions(+), 13 deletions(-) diff --git a/esphome/components/mdns/__init__.py b/esphome/components/mdns/__init__.py index 4776bef22f..49ba00e5a6 100644 --- a/esphome/components/mdns/__init__.py +++ b/esphome/components/mdns/__init__.py @@ -184,10 +184,8 @@ async def to_code(config): # Calculate compile-time dynamic TXT value count # Dynamic values are those that cannot be stored in flash at compile time + # Note: MAC address is now stored in a fixed char[13] buffer, not dynamic storage dynamic_txt_count = 0 - if "api" in CORE.config: - # Always: get_mac_address() - dynamic_txt_count += 1 # User-provided templatable TXT values (only lambdas, not static strings) dynamic_txt_count += sum( 1 @@ -196,8 +194,10 @@ async def to_code(config): 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)) + # Only add define if we actually need dynamic storage + if dynamic_txt_count > 0: + cg.add_define("USE_MDNS_DYNAMIC_TXT") + cg.add_define("MDNS_DYNAMIC_TXT_COUNT", dynamic_txt_count) # Enable storage if verbose logging is enabled (for dump_config) if get_logger_level() in ("VERBOSE", "VERY_VERBOSE"): diff --git a/esphome/components/mdns/mdns_component.cpp b/esphome/components/mdns/mdns_component.cpp index c81defd19f..208f4e9cd4 100644 --- a/esphome/components/mdns/mdns_component.cpp +++ b/esphome/components/mdns/mdns_component.cpp @@ -86,7 +86,7 @@ void MDNSComponent::compile_records_(StaticVectoradd_dynamic_txt_value(get_mac_address()))}); + txt_records.push_back({MDNS_STR(TXT_MAC), MDNS_STR(this->mac_address_)}); #ifdef USE_ESP8266 MDNS_STATIC_CONST_CHAR(PLATFORM_ESP8266, "ESP8266"); diff --git a/esphome/components/mdns/mdns_component.h b/esphome/components/mdns/mdns_component.h index 691c45b7df..ce4f0e6817 100644 --- a/esphome/components/mdns/mdns_component.h +++ b/esphome/components/mdns/mdns_component.h @@ -60,18 +60,38 @@ class MDNSComponent : public Component { void on_shutdown() override; +#ifdef USE_MDNS_DYNAMIC_TXT /// Add a dynamic TXT value and return pointer to it for use in MDNSTXTRecord const char *add_dynamic_txt_value(const std::string &value) { this->dynamic_txt_values_.push_back(value); return this->dynamic_txt_values_[this->dynamic_txt_values_.size() - 1].c_str(); } +#endif - /// Storage for runtime-generated TXT values (MAC address, user lambdas) + protected: + /// Common setup logic called by all platform-specific setup() implementations + void on_setup() { +#ifdef USE_API + // Populate MAC address buffer once during setup + get_mac_address_into_buffer(std::span(this->mac_address_)); +#endif + +#ifdef USE_MDNS_STORE_SERVICES + this->compile_records_(this->services_); +#endif + } + +#ifdef USE_MDNS_DYNAMIC_TXT + /// Storage for runtime-generated TXT values from user lambdas /// Pre-sized at compile time via MDNS_DYNAMIC_TXT_COUNT to avoid heap allocations. /// Static/compile-time values (version, board, etc.) are stored directly in flash and don't use this. StaticVector dynamic_txt_values_; +#endif - protected: +#ifdef USE_API + /// Fixed buffer for MAC address (populated once in setup()) + char mac_address_[13]; // 12 hex chars + null terminator +#endif #ifdef USE_MDNS_STORE_SERVICES StaticVector services_{}; #endif diff --git a/esphome/components/mdns/mdns_esp32.cpp b/esphome/components/mdns/mdns_esp32.cpp index 5547a2524b..b96abb1b3f 100644 --- a/esphome/components/mdns/mdns_esp32.cpp +++ b/esphome/components/mdns/mdns_esp32.cpp @@ -12,8 +12,9 @@ namespace esphome::mdns { static const char *const TAG = "mdns"; void MDNSComponent::setup() { + this->on_setup(); + #ifdef USE_MDNS_STORE_SERVICES - this->compile_records_(this->services_); const auto &services = this->services_; #else StaticVector services; diff --git a/esphome/components/mdns/mdns_esp8266.cpp b/esphome/components/mdns/mdns_esp8266.cpp index 06f905884c..3388d1d9ab 100644 --- a/esphome/components/mdns/mdns_esp8266.cpp +++ b/esphome/components/mdns/mdns_esp8266.cpp @@ -12,8 +12,9 @@ namespace esphome::mdns { void MDNSComponent::setup() { + this->on_setup(); + #ifdef USE_MDNS_STORE_SERVICES - this->compile_records_(this->services_); const auto &services = this->services_; #else StaticVector services; diff --git a/esphome/components/mdns/mdns_host.cpp b/esphome/components/mdns/mdns_host.cpp index 64b8c8f54b..c46e170181 100644 --- a/esphome/components/mdns/mdns_host.cpp +++ b/esphome/components/mdns/mdns_host.cpp @@ -9,6 +9,7 @@ namespace esphome::mdns { void MDNSComponent::setup() { + this->on_setup(); // Host platform doesn't have actual mDNS implementation } diff --git a/esphome/components/mdns/mdns_libretiny.cpp b/esphome/components/mdns/mdns_libretiny.cpp index a049fe2109..945510e051 100644 --- a/esphome/components/mdns/mdns_libretiny.cpp +++ b/esphome/components/mdns/mdns_libretiny.cpp @@ -12,8 +12,9 @@ namespace esphome::mdns { void MDNSComponent::setup() { + this->on_setup(); + #ifdef USE_MDNS_STORE_SERVICES - this->compile_records_(this->services_); const auto &services = this->services_; #else StaticVector services; diff --git a/esphome/components/mdns/mdns_rp2040.cpp b/esphome/components/mdns/mdns_rp2040.cpp index a102e0b6c3..3b7c2e8254 100644 --- a/esphome/components/mdns/mdns_rp2040.cpp +++ b/esphome/components/mdns/mdns_rp2040.cpp @@ -12,8 +12,9 @@ namespace esphome::mdns { void MDNSComponent::setup() { + this->on_setup(); + #ifdef USE_MDNS_STORE_SERVICES - this->compile_records_(this->services_); const auto &services = this->services_; #else StaticVector services; diff --git a/esphome/core/defines.h b/esphome/core/defines.h index 03362ce07a..4ef8bc2b6f 100644 --- a/esphome/core/defines.h +++ b/esphome/core/defines.h @@ -88,7 +88,8 @@ #define USE_MDNS #define USE_MDNS_STORE_SERVICES #define MDNS_SERVICE_COUNT 3 -#define MDNS_DYNAMIC_TXT_COUNT 3 +#define USE_MDNS_DYNAMIC_TXT +#define MDNS_DYNAMIC_TXT_COUNT 2 #define SNTP_SERVER_COUNT 3 #define USE_MEDIA_PLAYER #define USE_NEXTION_TFT_UPLOAD