From 0e31bc1a67f0ab57d8e89a6c05a16bb53683e776 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 19 Aug 2025 21:26:53 -0500 Subject: [PATCH] [api] Add zero-copy StringRef methods for compilation_time and effect_name (#10257) --- esphome/components/api/api_connection.cpp | 8 ++------ esphome/components/light/light_state.cpp | 14 ++++++++++++-- esphome/components/light/light_state.h | 3 +++ esphome/core/application.h | 3 +++ 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/esphome/components/api/api_connection.cpp b/esphome/components/api/api_connection.cpp index ced0f489be..4b3a3e2fc8 100644 --- a/esphome/components/api/api_connection.cpp +++ b/esphome/components/api/api_connection.cpp @@ -465,9 +465,7 @@ uint16_t APIConnection::try_send_light_state(EntityBase *entity, APIConnection * resp.cold_white = values.get_cold_white(); resp.warm_white = values.get_warm_white(); if (light->supports_effects()) { - // get_effect_name() returns temporary std::string - must store it - std::string effect_name = light->get_effect_name(); - resp.set_effect(StringRef(effect_name)); + resp.set_effect(light->get_effect_name_ref()); } return fill_and_encode_entity_state(light, resp, LightStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single); } @@ -1425,9 +1423,7 @@ bool APIConnection::send_device_info_response(const DeviceInfoRequest &msg) { static constexpr auto ESPHOME_VERSION_REF = StringRef::from_lit(ESPHOME_VERSION); resp.set_esphome_version(ESPHOME_VERSION_REF); - // get_compilation_time() returns temporary std::string - must store it - std::string compilation_time = App.get_compilation_time(); - resp.set_compilation_time(StringRef(compilation_time)); + resp.set_compilation_time(App.get_compilation_time_ref()); // Compile-time StringRef constants for manufacturers #if defined(USE_ESP8266) || defined(USE_ESP32) diff --git a/esphome/components/light/light_state.cpp b/esphome/components/light/light_state.cpp index 5b57707d6b..9e42b2f1e2 100644 --- a/esphome/components/light/light_state.cpp +++ b/esphome/components/light/light_state.cpp @@ -140,12 +140,22 @@ float LightState::get_setup_priority() const { return setup_priority::HARDWARE - void LightState::publish_state() { this->remote_values_callback_.call(); } LightOutput *LightState::get_output() const { return this->output_; } + +static constexpr const char *EFFECT_NONE = "None"; +static constexpr auto EFFECT_NONE_REF = StringRef::from_lit("None"); + std::string LightState::get_effect_name() { if (this->active_effect_index_ > 0) { return this->effects_[this->active_effect_index_ - 1]->get_name(); - } else { - return "None"; } + return EFFECT_NONE; +} + +StringRef LightState::get_effect_name_ref() { + if (this->active_effect_index_ > 0) { + return StringRef(this->effects_[this->active_effect_index_ - 1]->get_name()); + } + return EFFECT_NONE_REF; } void LightState::add_new_remote_values_callback(std::function &&send_callback) { diff --git a/esphome/components/light/light_state.h b/esphome/components/light/light_state.h index 72cb99223e..94b81dee61 100644 --- a/esphome/components/light/light_state.h +++ b/esphome/components/light/light_state.h @@ -4,6 +4,7 @@ #include "esphome/core/entity_base.h" #include "esphome/core/optional.h" #include "esphome/core/preferences.h" +#include "esphome/core/string_ref.h" #include "light_call.h" #include "light_color_values.h" #include "light_effect.h" @@ -116,6 +117,8 @@ class LightState : public EntityBase, public Component { /// Return the name of the current effect, or if no effect is active "None". std::string get_effect_name(); + /// Return the name of the current effect as StringRef (for API usage) + StringRef get_effect_name_ref(); /** * This lets front-end components subscribe to light change events. This callback is called once diff --git a/esphome/core/application.h b/esphome/core/application.h index 4120afff53..9cb2a4c638 100644 --- a/esphome/core/application.h +++ b/esphome/core/application.h @@ -10,6 +10,7 @@ #include "esphome/core/helpers.h" #include "esphome/core/preferences.h" #include "esphome/core/scheduler.h" +#include "esphome/core/string_ref.h" #ifdef USE_DEVICES #include "esphome/core/device.h" @@ -248,6 +249,8 @@ class Application { bool is_name_add_mac_suffix_enabled() const { return this->name_add_mac_suffix_; } std::string get_compilation_time() const { return this->compilation_time_; } + /// Get the compilation time as StringRef (for API usage) + StringRef get_compilation_time_ref() const { return StringRef(this->compilation_time_); } /// Get the cached time in milliseconds from when the current component started its loop execution inline uint32_t IRAM_ATTR HOT get_loop_component_start_time() const { return this->loop_component_start_time_; }