1
0
mirror of https://github.com/esphome/esphome.git synced 2026-02-08 00:31:58 +00:00

[event] Return StringRef from get_last_event_type() (#13104)

This commit is contained in:
J. Nick Koston
2026-01-11 17:52:54 -10:00
committed by GitHub
parent f1b11b1855
commit e1aac7601d
7 changed files with 32 additions and 18 deletions

View File

@@ -1415,14 +1415,15 @@ void APIConnection::on_water_heater_command_request(const WaterHeaterCommandRequ
#endif #endif
#ifdef USE_EVENT #ifdef USE_EVENT
void APIConnection::send_event(event::Event *event, const char *event_type) { void APIConnection::send_event(event::Event *event, StringRef event_type) {
this->send_message_smart_(event, MessageCreator(event_type), EventResponse::MESSAGE_TYPE, // get_last_event_type() returns StringRef pointing to null-terminated string literals from codegen
this->send_message_smart_(event, MessageCreator(event_type.c_str()), EventResponse::MESSAGE_TYPE,
EventResponse::ESTIMATED_SIZE); EventResponse::ESTIMATED_SIZE);
} }
uint16_t APIConnection::try_send_event_response(event::Event *event, const char *event_type, APIConnection *conn, uint16_t APIConnection::try_send_event_response(event::Event *event, StringRef event_type, APIConnection *conn,
uint32_t remaining_size, bool is_single) { uint32_t remaining_size, bool is_single) {
EventResponse resp; EventResponse resp;
resp.event_type = StringRef(event_type); resp.event_type = event_type;
return fill_and_encode_entity_state(event, resp, EventResponse::MESSAGE_TYPE, conn, remaining_size, is_single); return fill_and_encode_entity_state(event, resp, EventResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
} }
@@ -2056,7 +2057,7 @@ uint16_t APIConnection::MessageCreator::operator()(EntityBase *entity, APIConnec
// Special case: EventResponse uses const char * pointer // Special case: EventResponse uses const char * pointer
if (message_type == EventResponse::MESSAGE_TYPE) { if (message_type == EventResponse::MESSAGE_TYPE) {
auto *e = static_cast<event::Event *>(entity); auto *e = static_cast<event::Event *>(entity);
return APIConnection::try_send_event_response(e, data_.const_char_ptr, conn, remaining_size, is_single); return APIConnection::try_send_event_response(e, StringRef(data_.const_char_ptr), conn, remaining_size, is_single);
} }
#endif #endif

View File

@@ -173,7 +173,7 @@ class APIConnection final : public APIServerConnection {
#endif #endif
#ifdef USE_EVENT #ifdef USE_EVENT
void send_event(event::Event *event, const char *event_type); void send_event(event::Event *event, StringRef event_type);
#endif #endif
#ifdef USE_UPDATE #ifdef USE_UPDATE
@@ -469,7 +469,7 @@ class APIConnection final : public APIServerConnection {
bool is_single); bool is_single);
#endif #endif
#ifdef USE_EVENT #ifdef USE_EVENT
static uint16_t try_send_event_response(event::Event *event, const char *event_type, APIConnection *conn, static uint16_t try_send_event_response(event::Event *event, StringRef event_type, APIConnection *conn,
uint32_t remaining_size, bool is_single); uint32_t remaining_size, bool is_single);
static uint16_t try_send_event_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single); static uint16_t try_send_event_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
#endif #endif

View File

@@ -7,6 +7,7 @@
#include "esphome/core/component.h" #include "esphome/core/component.h"
#include "esphome/core/entity_base.h" #include "esphome/core/entity_base.h"
#include "esphome/core/helpers.h" #include "esphome/core/helpers.h"
#include "esphome/core/string_ref.h"
namespace esphome { namespace esphome {
namespace event { namespace event {
@@ -44,8 +45,11 @@ class Event : public EntityBase, public EntityBase_DeviceClass {
/// Return the event types supported by this event. /// Return the event types supported by this event.
const FixedVector<const char *> &get_event_types() const { return this->types_; } const FixedVector<const char *> &get_event_types() const { return this->types_; }
/// Return the last triggered event type (pointer to string in types_), or nullptr if no event triggered yet. /// Return the last triggered event type, or empty StringRef if no event triggered yet.
const char *get_last_event_type() const { return this->last_event_type_; } StringRef get_last_event_type() const { return StringRef::from_maybe_nullptr(this->last_event_type_); }
/// Check if an event has been triggered.
bool has_event() const { return this->last_event_type_ != nullptr; }
void add_on_event_callback(std::function<void(const std::string &event_type)> &&callback); void add_on_event_callback(std::function<void(const std::string &event_type)> &&callback);

View File

@@ -600,7 +600,7 @@ void PrometheusHandler::event_row_(AsyncResponseStream *stream, event::Event *ob
std::string &friendly_name) { std::string &friendly_name) {
if (obj->is_internal() && !this->include_internal_) if (obj->is_internal() && !this->include_internal_)
return; return;
if (obj->get_last_event_type() != nullptr) { if (obj->has_event()) {
// We have a valid event type, output this value // We have a valid event type, output this value
stream->print(ESPHOME_F("esphome_event_failed{id=\"")); stream->print(ESPHOME_F("esphome_event_failed{id=\""));
stream->print(relabel_id_(obj).c_str()); stream->print(relabel_id_(obj).c_str());
@@ -619,7 +619,8 @@ void PrometheusHandler::event_row_(AsyncResponseStream *stream, event::Event *ob
stream->print(ESPHOME_F("\",name=\"")); stream->print(ESPHOME_F("\",name=\""));
stream->print(relabel_name_(obj).c_str()); stream->print(relabel_name_(obj).c_str());
stream->print(ESPHOME_F("\",last_event_type=\"")); stream->print(ESPHOME_F("\",last_event_type=\""));
stream->print(obj->get_last_event_type()); // get_last_event_type() returns StringRef (null-terminated)
stream->print(obj->get_last_event_type().c_str());
stream->print(ESPHOME_F("\"} ")); stream->print(ESPHOME_F("\"} "));
stream->print(ESPHOME_F("1.0")); stream->print(ESPHOME_F("1.0"));
stream->print(ESPHOME_F("\n")); stream->print(ESPHOME_F("\n"));

View File

@@ -1958,7 +1958,7 @@ void WebServer::handle_event_request(AsyncWebServerRequest *request, const UrlMa
// Note: request->method() is always HTTP_GET here (canHandle ensures this) // Note: request->method() is always HTTP_GET here (canHandle ensures this)
if (entity_match.action_is_empty) { if (entity_match.action_is_empty) {
auto detail = get_request_detail(request); auto detail = get_request_detail(request);
std::string data = this->event_json_(obj, "", detail); std::string data = this->event_json_(obj, StringRef(), detail);
request->send(200, "application/json", data.c_str()); request->send(200, "application/json", data.c_str());
return; return;
} }
@@ -1966,10 +1966,7 @@ void WebServer::handle_event_request(AsyncWebServerRequest *request, const UrlMa
request->send(404); request->send(404);
} }
static std::string get_event_type(event::Event *event) { static StringRef get_event_type(event::Event *event) { return event ? event->get_last_event_type() : StringRef(); }
const char *last_type = event ? event->get_last_event_type() : nullptr;
return last_type ? last_type : "";
}
std::string WebServer::event_state_json_generator(WebServer *web_server, void *source) { std::string WebServer::event_state_json_generator(WebServer *web_server, void *source) {
auto *event = static_cast<event::Event *>(source); auto *event = static_cast<event::Event *>(source);
@@ -1980,7 +1977,7 @@ std::string WebServer::event_all_json_generator(WebServer *web_server, void *sou
auto *event = static_cast<event::Event *>(source); auto *event = static_cast<event::Event *>(source);
return web_server->event_json_(event, get_event_type(event), DETAIL_ALL); return web_server->event_json_(event, get_event_type(event), DETAIL_ALL);
} }
std::string WebServer::event_json_(event::Event *obj, const std::string &event_type, JsonDetail start_config) { std::string WebServer::event_json_(event::Event *obj, StringRef event_type, JsonDetail start_config) {
json::JsonBuilder builder; json::JsonBuilder builder;
JsonObject root = builder.root(); JsonObject root = builder.root();

View File

@@ -643,7 +643,7 @@ class WebServer : public Controller,
alarm_control_panel::AlarmControlPanelState value, JsonDetail start_config); alarm_control_panel::AlarmControlPanelState value, JsonDetail start_config);
#endif #endif
#ifdef USE_EVENT #ifdef USE_EVENT
std::string event_json_(event::Event *obj, const std::string &event_type, JsonDetail start_config); std::string event_json_(event::Event *obj, StringRef event_type, JsonDetail start_config);
#endif #endif
#ifdef USE_WATER_HEATER #ifdef USE_WATER_HEATER
std::string water_heater_json_(water_heater::WaterHeater *obj, JsonDetail start_config); std::string water_heater_json_(water_heater::WaterHeater *obj, JsonDetail start_config);

View File

@@ -7,3 +7,14 @@ event:
- template_event_type2 - template_event_type2
on_event: on_event:
- logger.log: Event fired - logger.log: Event fired
- lambda: |-
// Test get_last_event_type() returns StringRef
if (id(some_event).has_event()) {
auto event_type = id(some_event).get_last_event_type();
// Compare with string literal using ==
if (event_type == "template_event_type1") {
ESP_LOGD("test", "Event type is template_event_type1");
}
// Log using %.*s format for StringRef
ESP_LOGD("test", "Event type: %.*s", (int) event_type.size(), event_type.c_str());
}