mirror of
https://github.com/esphome/esphome.git
synced 2025-11-16 06:45:48 +00:00
Merge remote-tracking branch 'upstream/dev' into controller_registry
This commit is contained in:
@@ -2147,7 +2147,7 @@ message ListEntitiesEventResponse {
|
|||||||
EntityCategory entity_category = 7;
|
EntityCategory entity_category = 7;
|
||||||
string device_class = 8;
|
string device_class = 8;
|
||||||
|
|
||||||
repeated string event_types = 9;
|
repeated string event_types = 9 [(container_pointer_no_template) = "FixedVector<const char *>"];
|
||||||
uint32 device_id = 10 [(field_ifdef) = "USE_DEVICES"];
|
uint32 device_id = 10 [(field_ifdef) = "USE_DEVICES"];
|
||||||
}
|
}
|
||||||
message EventResponse {
|
message EventResponse {
|
||||||
|
|||||||
@@ -1310,8 +1310,7 @@ uint16_t APIConnection::try_send_event_info(EntityBase *entity, APIConnection *c
|
|||||||
auto *event = static_cast<event::Event *>(entity);
|
auto *event = static_cast<event::Event *>(entity);
|
||||||
ListEntitiesEventResponse msg;
|
ListEntitiesEventResponse msg;
|
||||||
msg.set_device_class(event->get_device_class_ref());
|
msg.set_device_class(event->get_device_class_ref());
|
||||||
for (const auto &event_type : event->get_event_types())
|
msg.event_types = &event->get_event_types();
|
||||||
msg.event_types.push_back(event_type);
|
|
||||||
return fill_and_encode_entity_info(event, msg, ListEntitiesEventResponse::MESSAGE_TYPE, conn, remaining_size,
|
return fill_and_encode_entity_info(event, msg, ListEntitiesEventResponse::MESSAGE_TYPE, conn, remaining_size,
|
||||||
is_single);
|
is_single);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2877,8 +2877,8 @@ void ListEntitiesEventResponse::encode(ProtoWriteBuffer buffer) const {
|
|||||||
buffer.encode_bool(6, this->disabled_by_default);
|
buffer.encode_bool(6, this->disabled_by_default);
|
||||||
buffer.encode_uint32(7, static_cast<uint32_t>(this->entity_category));
|
buffer.encode_uint32(7, static_cast<uint32_t>(this->entity_category));
|
||||||
buffer.encode_string(8, this->device_class_ref_);
|
buffer.encode_string(8, this->device_class_ref_);
|
||||||
for (auto &it : this->event_types) {
|
for (const char *it : *this->event_types) {
|
||||||
buffer.encode_string(9, it, true);
|
buffer.encode_string(9, it, strlen(it), true);
|
||||||
}
|
}
|
||||||
#ifdef USE_DEVICES
|
#ifdef USE_DEVICES
|
||||||
buffer.encode_uint32(10, this->device_id);
|
buffer.encode_uint32(10, this->device_id);
|
||||||
@@ -2894,9 +2894,9 @@ void ListEntitiesEventResponse::calculate_size(ProtoSize &size) const {
|
|||||||
size.add_bool(1, this->disabled_by_default);
|
size.add_bool(1, this->disabled_by_default);
|
||||||
size.add_uint32(1, static_cast<uint32_t>(this->entity_category));
|
size.add_uint32(1, static_cast<uint32_t>(this->entity_category));
|
||||||
size.add_length(1, this->device_class_ref_.size());
|
size.add_length(1, this->device_class_ref_.size());
|
||||||
if (!this->event_types.empty()) {
|
if (!this->event_types->empty()) {
|
||||||
for (const auto &it : this->event_types) {
|
for (const char *it : *this->event_types) {
|
||||||
size.add_length_force(1, it.size());
|
size.add_length_force(1, strlen(it));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef USE_DEVICES
|
#ifdef USE_DEVICES
|
||||||
|
|||||||
@@ -2788,7 +2788,7 @@ class ListEntitiesEventResponse final : public InfoResponseProtoMessage {
|
|||||||
#endif
|
#endif
|
||||||
StringRef device_class_ref_{};
|
StringRef device_class_ref_{};
|
||||||
void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; }
|
void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; }
|
||||||
std::vector<std::string> event_types{};
|
const FixedVector<const char *> *event_types{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(ProtoSize &size) const override;
|
void calculate_size(ProtoSize &size) const override;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
|||||||
@@ -2053,7 +2053,7 @@ void ListEntitiesEventResponse::dump_to(std::string &out) const {
|
|||||||
dump_field(out, "disabled_by_default", this->disabled_by_default);
|
dump_field(out, "disabled_by_default", this->disabled_by_default);
|
||||||
dump_field(out, "entity_category", static_cast<enums::EntityCategory>(this->entity_category));
|
dump_field(out, "entity_category", static_cast<enums::EntityCategory>(this->entity_category));
|
||||||
dump_field(out, "device_class", this->device_class_ref_);
|
dump_field(out, "device_class", this->device_class_ref_);
|
||||||
for (const auto &it : this->event_types) {
|
for (const auto &it : *this->event_types) {
|
||||||
dump_field(out, "event_types", it, 4);
|
dump_field(out, "event_types", it, 4);
|
||||||
}
|
}
|
||||||
#ifdef USE_DEVICES
|
#ifdef USE_DEVICES
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ namespace event {
|
|||||||
static const char *const TAG = "event";
|
static const char *const TAG = "event";
|
||||||
|
|
||||||
void Event::trigger(const std::string &event_type) {
|
void Event::trigger(const std::string &event_type) {
|
||||||
// Linear search - faster than std::set for small datasets (1-5 items typical)
|
// Linear search with strcmp - faster than std::set for small datasets (1-5 items typical)
|
||||||
const std::string *found = nullptr;
|
const char *found = nullptr;
|
||||||
for (const auto &type : this->types_) {
|
for (const char *type : this->types_) {
|
||||||
if (type == event_type) {
|
if (strcmp(type, event_type.c_str()) == 0) {
|
||||||
found = &type;
|
found = type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,12 +20,28 @@ void Event::trigger(const std::string &event_type) {
|
|||||||
ESP_LOGE(TAG, "'%s': invalid event type for trigger(): %s", this->get_name().c_str(), event_type.c_str());
|
ESP_LOGE(TAG, "'%s': invalid event type for trigger(): %s", this->get_name().c_str(), event_type.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
last_event_type = found;
|
this->last_event_type_ = found;
|
||||||
ESP_LOGD(TAG, "'%s' Triggered event '%s'", this->get_name().c_str(), last_event_type->c_str());
|
ESP_LOGD(TAG, "'%s' Triggered event '%s'", this->get_name().c_str(), this->last_event_type_);
|
||||||
this->event_callback_.call(event_type);
|
this->event_callback_.call(event_type);
|
||||||
ControllerRegistry::notify_event(this);
|
ControllerRegistry::notify_event(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Event::set_event_types(const FixedVector<const char *> &event_types) {
|
||||||
|
this->types_.init(event_types.size());
|
||||||
|
for (const char *type : event_types) {
|
||||||
|
this->types_.push_back(type);
|
||||||
|
}
|
||||||
|
this->last_event_type_ = nullptr; // Reset when types change
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event::set_event_types(const std::vector<const char *> &event_types) {
|
||||||
|
this->types_.init(event_types.size());
|
||||||
|
for (const char *type : event_types) {
|
||||||
|
this->types_.push_back(type);
|
||||||
|
}
|
||||||
|
this->last_event_type_ = nullptr; // Reset when types change
|
||||||
|
}
|
||||||
|
|
||||||
void Event::add_on_event_callback(std::function<void(const std::string &event_type)> &&callback) {
|
void Event::add_on_event_callback(std::function<void(const std::string &event_type)> &&callback) {
|
||||||
this->event_callback_.add(std::move(callback));
|
this->event_callback_.add(std::move(callback));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/core/entity_base.h"
|
#include "esphome/core/entity_base.h"
|
||||||
@@ -22,16 +24,39 @@ namespace event {
|
|||||||
|
|
||||||
class Event : public EntityBase, public EntityBase_DeviceClass {
|
class Event : public EntityBase, public EntityBase_DeviceClass {
|
||||||
public:
|
public:
|
||||||
const std::string *last_event_type;
|
|
||||||
|
|
||||||
void trigger(const std::string &event_type);
|
void trigger(const std::string &event_type);
|
||||||
void set_event_types(const std::initializer_list<std::string> &event_types) { this->types_ = event_types; }
|
|
||||||
const FixedVector<std::string> &get_event_types() const { return this->types_; }
|
/// Set the event types supported by this event (from initializer list).
|
||||||
|
void set_event_types(std::initializer_list<const char *> event_types) {
|
||||||
|
this->types_ = event_types;
|
||||||
|
this->last_event_type_ = nullptr; // Reset when types change
|
||||||
|
}
|
||||||
|
/// Set the event types supported by this event (from FixedVector).
|
||||||
|
void set_event_types(const FixedVector<const char *> &event_types);
|
||||||
|
/// Set the event types supported by this event (from vector).
|
||||||
|
void set_event_types(const std::vector<const char *> &event_types);
|
||||||
|
|
||||||
|
// Deleted overloads to catch incorrect std::string usage at compile time with clear error messages
|
||||||
|
void set_event_types(std::initializer_list<std::string> event_types) = delete;
|
||||||
|
void set_event_types(const FixedVector<std::string> &event_types) = delete;
|
||||||
|
void set_event_types(const std::vector<std::string> &event_types) = delete;
|
||||||
|
|
||||||
|
/// Return the event types supported by this event.
|
||||||
|
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.
|
||||||
|
const char *get_last_event_type() const { return this->last_event_type_; }
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CallbackManager<void(const std::string &event_type)> event_callback_;
|
CallbackManager<void(const std::string &event_type)> event_callback_;
|
||||||
FixedVector<std::string> types_;
|
FixedVector<const char *> types_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Last triggered event type - must point to entry in types_ to ensure valid lifetime.
|
||||||
|
/// Set by trigger() after validation, reset to nullptr when types_ changes.
|
||||||
|
const char *last_event_type_{nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace event
|
} // namespace event
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ void MQTTEventComponent::setup() {
|
|||||||
void MQTTEventComponent::dump_config() {
|
void MQTTEventComponent::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, "MQTT Event '%s': ", this->event_->get_name().c_str());
|
ESP_LOGCONFIG(TAG, "MQTT Event '%s': ", this->event_->get_name().c_str());
|
||||||
ESP_LOGCONFIG(TAG, "Event Types: ");
|
ESP_LOGCONFIG(TAG, "Event Types: ");
|
||||||
for (const auto &event_type : this->event_->get_event_types()) {
|
for (const char *event_type : this->event_->get_event_types()) {
|
||||||
ESP_LOGCONFIG(TAG, "- %s", event_type.c_str());
|
ESP_LOGCONFIG(TAG, "- %s", event_type);
|
||||||
}
|
}
|
||||||
LOG_MQTT_COMPONENT(true, true);
|
LOG_MQTT_COMPONENT(true, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1663,7 +1663,8 @@ void WebServer::handle_event_request(AsyncWebServerRequest *request, const UrlMa
|
|||||||
}
|
}
|
||||||
|
|
||||||
static std::string get_event_type(event::Event *event) {
|
static std::string get_event_type(event::Event *event) {
|
||||||
return (event && event->last_event_type) ? *event->last_event_type : "";
|
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) {
|
||||||
@@ -1684,7 +1685,7 @@ std::string WebServer::event_json(event::Event *obj, const std::string &event_ty
|
|||||||
}
|
}
|
||||||
if (start_config == DETAIL_ALL) {
|
if (start_config == DETAIL_ALL) {
|
||||||
JsonArray event_types = root["event_types"].to<JsonArray>();
|
JsonArray event_types = root["event_types"].to<JsonArray>();
|
||||||
for (auto const &event_type : obj->get_event_types()) {
|
for (const char *event_type : obj->get_event_types()) {
|
||||||
event_types.add(event_type);
|
event_types.add(event_type);
|
||||||
}
|
}
|
||||||
root["device_class"] = obj->get_device_class_ref();
|
root["device_class"] = obj->get_device_class_ref();
|
||||||
|
|||||||
Reference in New Issue
Block a user