diff --git a/esphome/components/api/api_connection.cpp b/esphome/components/api/api_connection.cpp index 04f38d17ce..4923d65431 100644 --- a/esphome/components/api/api_connection.cpp +++ b/esphome/components/api/api_connection.cpp @@ -1541,8 +1541,8 @@ void APIConnection::on_home_assistant_state_response(const HomeAssistantStateRes for (auto &it : this->parent_->get_state_subs()) { // Compare entity_id and attribute with message fields bool entity_match = (strcmp(it.entity_id_, msg.entity_id.c_str()) == 0); - bool attribute_match = - it.has_attribute_ ? (strcmp(it.attribute_, msg.attribute.c_str()) == 0) : msg.attribute.empty(); + bool attribute_match = (it.attribute_ != nullptr && strcmp(it.attribute_, msg.attribute.c_str()) == 0) || + (it.attribute_ == nullptr && msg.attribute.empty()); if (entity_match && attribute_match) { it.callback_(msg.state); @@ -1885,7 +1885,7 @@ void APIConnection::process_state_subscriptions_() { resp.set_entity_id(StringRef(it.entity_id_)); // Avoid string copy by using the const char* pointer if it exists - resp.set_attribute(it.has_attribute_ ? StringRef(it.attribute_) : StringRef("")); + resp.set_attribute(it.attribute_ != nullptr ? StringRef(it.attribute_) : StringRef("")); resp.once = it.once_; if (this->send_message(resp, SubscribeHomeAssistantStateResponse::MESSAGE_TYPE)) { diff --git a/esphome/components/api/api_server.cpp b/esphome/components/api/api_server.cpp index f41ab65c84..64954d2ea1 100644 --- a/esphome/components/api/api_server.cpp +++ b/esphome/components/api/api_server.cpp @@ -435,11 +435,7 @@ void APIServer::handle_action_response(uint32_t call_id, bool success, const std void APIServer::add_state_subscription_(const char *entity_id, const char *attribute, std::function f, bool once) { this->state_subs_.push_back(HomeAssistantStateSubscription{ - .entity_id_ = entity_id, - .attribute_ = attribute, - .callback_ = std::move(f), - .once_ = once, - .has_attribute_ = (attribute != nullptr), + .entity_id_ = entity_id, .attribute_ = attribute, .callback_ = std::move(f), .once_ = once, // entity_id_copy_ and attribute_copy_ remain nullptr (no heap allocation) }); } @@ -455,10 +451,8 @@ void APIServer::add_state_subscription_(std::string entity_id, optional(std::move(attribute.value())); sub.attribute_ = sub.attribute_copy_->c_str(); - sub.has_attribute_ = true; } else { sub.attribute_ = nullptr; - sub.has_attribute_ = false; } sub.callback_ = std::move(f); diff --git a/esphome/components/api/api_server.h b/esphome/components/api/api_server.h index b64cc4e4fc..48c6c1f3c4 100644 --- a/esphome/components/api/api_server.h +++ b/esphome/components/api/api_server.h @@ -155,10 +155,9 @@ class APIServer : public Component, public Controller { #ifdef USE_API_HOMEASSISTANT_STATES struct HomeAssistantStateSubscription { const char *entity_id_; // Pointer to flash (internal) or heap (external) - const char *attribute_; // Pointer to flash or nullptr + const char *attribute_; // Pointer to flash or nullptr (nullptr means no attribute) std::function callback_; bool once_; - bool has_attribute_; // Storage for external components using std::string API (custom_api_device.h) // These are only allocated when using the std::string overload