From 2830c7dab8b510dd520ab608a46d9342cc14b28c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 7 Jan 2026 08:27:39 -1000 Subject: [PATCH] [ld2410/ld2412/ld2450] Use index-based select publish_state to avoid heap allocations (#13051) --- esphome/components/ld2410/ld2410.cpp | 7 +++++-- esphome/components/ld2412/ld2412.cpp | 7 +++++-- esphome/components/ld2450/ld2450.cpp | 15 +++++++++------ esphome/components/ld24xx/ld24xx.h | 9 +++++++++ 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/esphome/components/ld2410/ld2410.cpp b/esphome/components/ld2410/ld2410.cpp index 5ea47d5084..c9b4333f7e 100644 --- a/esphome/components/ld2410/ld2410.cpp +++ b/esphome/components/ld2410/ld2410.cpp @@ -117,6 +117,8 @@ constexpr Uint8ToString OUT_PIN_LEVELS_BY_UINT[] = { {OUT_PIN_LEVEL_HIGH, "high"}, }; +constexpr uint32_t BAUD_RATES[] = {9600, 19200, 38400, 57600, 115200, 230400, 256000, 460800}; + // Helper functions for lookups template uint8_t find_uint8(const StringToUint8 (&arr)[N], const char *str) { for (const auto &entry : arr) { @@ -258,9 +260,10 @@ void LD2410Component::read_all_info() { this->query_parameters_(); this->set_config_mode_(false); #ifdef USE_SELECT - const auto baud_rate = std::to_string(this->parent_->get_baud_rate()); if (this->baud_rate_select_ != nullptr) { - this->baud_rate_select_->publish_state(baud_rate); + if (auto index = ld24xx::find_index(BAUD_RATES, this->parent_->get_baud_rate())) { + this->baud_rate_select_->publish_state(*index); + } } #endif } diff --git a/esphome/components/ld2412/ld2412.cpp b/esphome/components/ld2412/ld2412.cpp index 3d51800065..620ac9886b 100644 --- a/esphome/components/ld2412/ld2412.cpp +++ b/esphome/components/ld2412/ld2412.cpp @@ -128,6 +128,8 @@ constexpr Uint8ToString OUT_PIN_LEVELS_BY_UINT[] = { {OUT_PIN_LEVEL_HIGH, "high"}, }; +constexpr uint32_t BAUD_RATES[] = {9600, 19200, 38400, 57600, 115200, 230400, 256000, 460800}; + // Helper functions for lookups template uint8_t find_uint8(const StringToUint8 (&arr)[N], const char *str) { for (const auto &entry : arr) { @@ -293,9 +295,10 @@ void LD2412Component::read_all_info() { #endif this->set_config_mode_(false); #ifdef USE_SELECT - const auto baud_rate = std::to_string(this->parent_->get_baud_rate()); if (this->baud_rate_select_ != nullptr) { - this->baud_rate_select_->publish_state(baud_rate); + if (auto index = ld24xx::find_index(BAUD_RATES, this->parent_->get_baud_rate())) { + this->baud_rate_select_->publish_state(*index); + } } #endif } diff --git a/esphome/components/ld2450/ld2450.cpp b/esphome/components/ld2450/ld2450.cpp index 2c137c3578..3b85694bc0 100644 --- a/esphome/components/ld2450/ld2450.cpp +++ b/esphome/components/ld2450/ld2450.cpp @@ -88,6 +88,9 @@ constexpr StringToUint8 ZONE_TYPE_BY_STR[] = { {"Filter", ZONE_FILTER}, }; +// Baud rates in the same order as BAUD_RATES_BY_STR for index-based lookup +constexpr uint32_t BAUD_RATES[] = {9600, 19200, 38400, 57600, 115200, 230400, 256000, 460800}; + // Helper functions for lookups template uint8_t find_uint8(const StringToUint8 (&arr)[N], const std::string &str) { for (const auto &entry : arr) { @@ -376,9 +379,10 @@ void LD2450Component::read_all_info() { this->query_zone_(); this->set_config_mode_(false); #ifdef USE_SELECT - const auto baud_rate = std::to_string(this->parent_->get_baud_rate()); - if (this->baud_rate_select_ != nullptr && strcmp(this->baud_rate_select_->current_option(), baud_rate.c_str()) != 0) { - this->baud_rate_select_->publish_state(baud_rate); + if (this->baud_rate_select_ != nullptr) { + if (auto index = ld24xx::find_index(BAUD_RATES, this->parent_->get_baud_rate())) { + this->baud_rate_select_->publish_state(*index); + } } this->publish_zone_type(); #endif @@ -710,7 +714,7 @@ bool LD2450Component::handle_ack_data_() { case CMD_QUERY_ZONE: ESP_LOGV(TAG, "Query zone conf"); - this->zone_type_ = std::stoi(std::to_string(this->buffer_data_[10]), nullptr, 16); + this->zone_type_ = this->buffer_data_[10]; this->publish_zone_type(); #ifdef USE_SELECT if (this->zone_type_select_ != nullptr) { @@ -812,9 +816,8 @@ void LD2450Component::set_zone_type(const char *state) { // Publish Zone Type to Select component void LD2450Component::publish_zone_type() { #ifdef USE_SELECT - std::string zone_type = find_str(ZONE_TYPE_BY_UINT, this->zone_type_); if (this->zone_type_select_ != nullptr) { - this->zone_type_select_->publish_state(zone_type); + this->zone_type_select_->publish_state(find_str(ZONE_TYPE_BY_UINT, this->zone_type_)); } #endif } diff --git a/esphome/components/ld24xx/ld24xx.h b/esphome/components/ld24xx/ld24xx.h index cbd86e4e40..fd55167974 100644 --- a/esphome/components/ld24xx/ld24xx.h +++ b/esphome/components/ld24xx/ld24xx.h @@ -39,6 +39,15 @@ namespace esphome::ld24xx { +// Helper to find index of value in constexpr array +template optional find_index(const uint32_t (&arr)[N], uint32_t value) { + for (size_t i = 0; i < N; i++) { + if (arr[i] == value) + return i; + } + return {}; +} + static const char *const UNKNOWN_MAC = "unknown"; static const char *const VERSION_FMT = "%u.%02X.%02X%02X%02X%02X";