mirror of
https://github.com/esphome/esphome.git
synced 2025-06-15 14:56:59 +02:00
Replace API deferred queue with efficient message batching system (#9012)
This commit is contained in:
parent
1467b704b8
commit
2ed5611a08
@ -49,6 +49,7 @@ SERVICE_ARG_NATIVE_TYPES = {
|
|||||||
"string[]": cg.std_vector.template(cg.std_string),
|
"string[]": cg.std_vector.template(cg.std_string),
|
||||||
}
|
}
|
||||||
CONF_ENCRYPTION = "encryption"
|
CONF_ENCRYPTION = "encryption"
|
||||||
|
CONF_BATCH_DELAY = "batch_delay"
|
||||||
|
|
||||||
|
|
||||||
def validate_encryption_key(value):
|
def validate_encryption_key(value):
|
||||||
@ -109,6 +110,9 @@ CONFIG_SCHEMA = cv.All(
|
|||||||
): ACTIONS_SCHEMA,
|
): ACTIONS_SCHEMA,
|
||||||
cv.Exclusive(CONF_ACTIONS, group_of_exclusion=CONF_ACTIONS): ACTIONS_SCHEMA,
|
cv.Exclusive(CONF_ACTIONS, group_of_exclusion=CONF_ACTIONS): ACTIONS_SCHEMA,
|
||||||
cv.Optional(CONF_ENCRYPTION): _encryption_schema,
|
cv.Optional(CONF_ENCRYPTION): _encryption_schema,
|
||||||
|
cv.Optional(
|
||||||
|
CONF_BATCH_DELAY, default="100ms"
|
||||||
|
): cv.positive_time_period_milliseconds,
|
||||||
cv.Optional(CONF_ON_CLIENT_CONNECTED): automation.validate_automation(
|
cv.Optional(CONF_ON_CLIENT_CONNECTED): automation.validate_automation(
|
||||||
single=True
|
single=True
|
||||||
),
|
),
|
||||||
@ -129,6 +133,7 @@ async def to_code(config):
|
|||||||
cg.add(var.set_port(config[CONF_PORT]))
|
cg.add(var.set_port(config[CONF_PORT]))
|
||||||
cg.add(var.set_password(config[CONF_PASSWORD]))
|
cg.add(var.set_password(config[CONF_PASSWORD]))
|
||||||
cg.add(var.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT]))
|
cg.add(var.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT]))
|
||||||
|
cg.add(var.set_batch_delay(config[CONF_BATCH_DELAY]))
|
||||||
|
|
||||||
for conf in config.get(CONF_ACTIONS, []):
|
for conf in config.get(CONF_ACTIONS, []):
|
||||||
template_args = []
|
template_args = []
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <functional>
|
||||||
|
#include <limits>
|
||||||
#include "esphome/components/network/util.h"
|
#include "esphome/components/network/util.h"
|
||||||
#include "esphome/core/application.h"
|
#include "esphome/core/application.h"
|
||||||
#include "esphome/core/entity_base.h"
|
#include "esphome/core/entity_base.h"
|
||||||
@ -29,40 +31,8 @@ namespace api {
|
|||||||
static const char *const TAG = "api.connection";
|
static const char *const TAG = "api.connection";
|
||||||
static const int ESP32_CAMERA_STOP_STREAM = 5000;
|
static const int ESP32_CAMERA_STOP_STREAM = 5000;
|
||||||
|
|
||||||
// helper for allowing only unique entries in the queue
|
|
||||||
void DeferredMessageQueue::dmq_push_back_with_dedup_(void *source, send_message_t send_message) {
|
|
||||||
DeferredMessage item(source, send_message);
|
|
||||||
|
|
||||||
auto iter = std::find_if(this->deferred_queue_.begin(), this->deferred_queue_.end(),
|
|
||||||
[&item](const DeferredMessage &test) -> bool { return test == item; });
|
|
||||||
|
|
||||||
if (iter != this->deferred_queue_.end()) {
|
|
||||||
(*iter) = item;
|
|
||||||
} else {
|
|
||||||
this->deferred_queue_.push_back(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeferredMessageQueue::process_queue() {
|
|
||||||
while (!deferred_queue_.empty()) {
|
|
||||||
DeferredMessage &de = deferred_queue_.front();
|
|
||||||
if ((this->api_connection_->*(de.send_message_))(de.source_)) {
|
|
||||||
// O(n) but memory efficiency is more important than speed here which is why std::vector was chosen
|
|
||||||
deferred_queue_.erase(deferred_queue_.begin());
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeferredMessageQueue::defer(void *source, send_message_t send_message) {
|
|
||||||
this->dmq_push_back_with_dedup_(source, send_message);
|
|
||||||
}
|
|
||||||
|
|
||||||
APIConnection::APIConnection(std::unique_ptr<socket::Socket> sock, APIServer *parent)
|
APIConnection::APIConnection(std::unique_ptr<socket::Socket> sock, APIServer *parent)
|
||||||
: parent_(parent), deferred_message_queue_(this), initial_state_iterator_(this), list_entities_iterator_(this) {
|
: parent_(parent), initial_state_iterator_(this), list_entities_iterator_(this) {
|
||||||
this->proto_write_buffer_.reserve(64);
|
|
||||||
|
|
||||||
#if defined(USE_API_PLAINTEXT) && defined(USE_API_NOISE)
|
#if defined(USE_API_PLAINTEXT) && defined(USE_API_NOISE)
|
||||||
auto noise_ctx = parent->get_noise_ctx();
|
auto noise_ctx = parent->get_noise_ctx();
|
||||||
if (noise_ctx->has_psk()) {
|
if (noise_ctx->has_psk()) {
|
||||||
@ -78,6 +48,9 @@ APIConnection::APIConnection(std::unique_ptr<socket::Socket> sock, APIServer *pa
|
|||||||
#error "No frame helper defined"
|
#error "No frame helper defined"
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t APIConnection::get_batch_delay_ms_() const { return this->parent_->get_batch_delay(); }
|
||||||
|
|
||||||
void APIConnection::start() {
|
void APIConnection::start() {
|
||||||
this->last_traffic_ = App.get_loop_component_start_time();
|
this->last_traffic_ = App.get_loop_component_start_time();
|
||||||
|
|
||||||
@ -166,8 +139,10 @@ void APIConnection::loop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->deferred_message_queue_.empty() && this->helper_->can_write_without_blocking()) {
|
// Process deferred batch if scheduled
|
||||||
this->deferred_message_queue_.process_queue();
|
if (this->deferred_batch_.batch_scheduled &&
|
||||||
|
App.get_loop_component_start_time() - this->deferred_batch_.batch_start_time >= this->get_batch_delay_ms_()) {
|
||||||
|
this->process_batch_();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->list_entities_iterator_.completed())
|
if (!this->list_entities_iterator_.completed())
|
||||||
@ -186,7 +161,7 @@ void APIConnection::loop() {
|
|||||||
}
|
}
|
||||||
} else if (now - this->last_traffic_ > KEEPALIVE_TIMEOUT_MS && now > this->next_ping_retry_) {
|
} else if (now - this->last_traffic_ > KEEPALIVE_TIMEOUT_MS && now > this->next_ping_retry_) {
|
||||||
ESP_LOGVV(TAG, "Sending keepalive PING");
|
ESP_LOGVV(TAG, "Sending keepalive PING");
|
||||||
this->sent_ping_ = this->send_ping_request(PingRequest());
|
this->sent_ping_ = this->send_message(PingRequest());
|
||||||
if (!this->sent_ping_) {
|
if (!this->sent_ping_) {
|
||||||
this->next_ping_retry_ = now + ping_retry_interval;
|
this->next_ping_retry_ = now + ping_retry_interval;
|
||||||
this->ping_retries_++;
|
this->ping_retries_++;
|
||||||
@ -205,18 +180,7 @@ void APIConnection::loop() {
|
|||||||
|
|
||||||
#ifdef USE_ESP32_CAMERA
|
#ifdef USE_ESP32_CAMERA
|
||||||
if (this->image_reader_.available() && this->helper_->can_write_without_blocking()) {
|
if (this->image_reader_.available() && this->helper_->can_write_without_blocking()) {
|
||||||
// Message will use 8 more bytes than the minimum size, and typical
|
uint32_t to_send = std::min((size_t) MAX_PACKET_SIZE, this->image_reader_.available());
|
||||||
// MTU is 1500. Sometimes users will see as low as 1460 MTU.
|
|
||||||
// If its IPv6 the header is 40 bytes, and if its IPv4
|
|
||||||
// the header is 20 bytes. So we have 1460 - 40 = 1420 bytes
|
|
||||||
// available for the payload. But we also need to add the size of
|
|
||||||
// the protobuf overhead, which is 8 bytes.
|
|
||||||
//
|
|
||||||
// To be safe we pick 1390 bytes as the maximum size
|
|
||||||
// to send in one go. This is the maximum size of a single packet
|
|
||||||
// that can be sent over the network.
|
|
||||||
// This is to avoid fragmentation of the packet.
|
|
||||||
uint32_t to_send = std::min((size_t) 1390, this->image_reader_.available());
|
|
||||||
bool done = this->image_reader_.available() == to_send;
|
bool done = this->image_reader_.available() == to_send;
|
||||||
uint32_t msg_size = 0;
|
uint32_t msg_size = 0;
|
||||||
ProtoSize::add_fixed_field<4>(msg_size, 1, true);
|
ProtoSize::add_fixed_field<4>(msg_size, 1, true);
|
||||||
@ -254,7 +218,7 @@ void APIConnection::loop() {
|
|||||||
resp.entity_id = it.entity_id;
|
resp.entity_id = it.entity_id;
|
||||||
resp.attribute = it.attribute.value();
|
resp.attribute = it.attribute.value();
|
||||||
resp.once = it.once;
|
resp.once = it.once;
|
||||||
if (this->send_subscribe_home_assistant_state_response(resp)) {
|
if (this->send_message(resp)) {
|
||||||
state_subs_at_++;
|
state_subs_at_++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -279,45 +243,74 @@ void APIConnection::on_disconnect_response(const DisconnectResponse &value) {
|
|||||||
this->remove_ = true;
|
this->remove_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encodes a message to the buffer and returns the total number of bytes used,
|
||||||
|
// including header and footer overhead. Returns 0 if the message doesn't fit.
|
||||||
|
uint16_t APIConnection::encode_message_to_buffer(ProtoMessage &msg, uint16_t message_type, APIConnection *conn,
|
||||||
|
uint32_t remaining_size, bool is_single) {
|
||||||
|
// Calculate size
|
||||||
|
uint32_t size = 0;
|
||||||
|
msg.calculate_size(size);
|
||||||
|
|
||||||
|
// Calculate total size with padding for buffer allocation
|
||||||
|
uint16_t total_size =
|
||||||
|
static_cast<uint16_t>(size) + conn->helper_->frame_header_padding() + conn->helper_->frame_footer_size();
|
||||||
|
|
||||||
|
// Check if it fits
|
||||||
|
if (total_size > remaining_size) {
|
||||||
|
return 0; // Doesn't fit
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate exact buffer space needed (just the payload, not the overhead)
|
||||||
|
ProtoWriteBuffer buffer =
|
||||||
|
is_single ? conn->allocate_single_message_buffer(size) : conn->allocate_batch_message_buffer(size);
|
||||||
|
|
||||||
|
// Encode directly into buffer
|
||||||
|
msg.encode(buffer);
|
||||||
|
return total_size;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_BINARY_SENSOR
|
#ifdef USE_BINARY_SENSOR
|
||||||
bool APIConnection::send_binary_sensor_state(binary_sensor::BinarySensor *binary_sensor, bool state) {
|
bool APIConnection::send_binary_sensor_state(binary_sensor::BinarySensor *binary_sensor) {
|
||||||
return this->send_state_with_value_(binary_sensor, &APIConnection::try_send_binary_sensor_state_,
|
return this->schedule_message_(binary_sensor, &APIConnection::try_send_binary_sensor_state,
|
||||||
&APIConnection::try_send_binary_sensor_state_, state);
|
BinarySensorStateResponse::MESSAGE_TYPE);
|
||||||
}
|
}
|
||||||
void APIConnection::send_binary_sensor_info(binary_sensor::BinarySensor *binary_sensor) {
|
void APIConnection::send_binary_sensor_info(binary_sensor::BinarySensor *binary_sensor) {
|
||||||
this->send_info_(static_cast<EntityBase *>(binary_sensor),
|
this->schedule_message_(binary_sensor, &APIConnection::try_send_binary_sensor_info,
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_binary_sensor_info_));
|
ListEntitiesBinarySensorResponse::MESSAGE_TYPE);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_binary_sensor_state_(binary_sensor::BinarySensor *binary_sensor) {
|
|
||||||
return this->try_send_binary_sensor_state_(binary_sensor, binary_sensor->state);
|
uint16_t APIConnection::try_send_binary_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *binary_sensor = static_cast<binary_sensor::BinarySensor *>(entity);
|
||||||
|
BinarySensorStateResponse resp;
|
||||||
|
resp.state = binary_sensor->state;
|
||||||
|
resp.missing_state = !binary_sensor->has_state();
|
||||||
|
resp.key = binary_sensor->get_object_id_hash();
|
||||||
|
return encode_message_to_buffer(resp, BinarySensorStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_binary_sensor_state_(binary_sensor::BinarySensor *binary_sensor, bool state) {
|
|
||||||
BinarySensorStateResponse msg;
|
uint16_t APIConnection::try_send_binary_sensor_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
msg.state = state;
|
bool is_single) {
|
||||||
msg.missing_state = !binary_sensor->has_state();
|
auto *binary_sensor = static_cast<binary_sensor::BinarySensor *>(entity);
|
||||||
msg.key = binary_sensor->get_object_id_hash();
|
|
||||||
return this->send_binary_sensor_state_response(msg);
|
|
||||||
}
|
|
||||||
bool APIConnection::try_send_binary_sensor_info_(binary_sensor::BinarySensor *binary_sensor) {
|
|
||||||
ListEntitiesBinarySensorResponse msg;
|
ListEntitiesBinarySensorResponse msg;
|
||||||
msg.device_class = binary_sensor->get_device_class();
|
msg.device_class = binary_sensor->get_device_class();
|
||||||
msg.is_status_binary_sensor = binary_sensor->is_status_binary_sensor();
|
msg.is_status_binary_sensor = binary_sensor->is_status_binary_sensor();
|
||||||
msg.unique_id = get_default_unique_id("binary_sensor", binary_sensor);
|
msg.unique_id = get_default_unique_id("binary_sensor", binary_sensor);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(binary_sensor), msg,
|
fill_entity_info_base(binary_sensor, msg);
|
||||||
&APIConnection::send_list_entities_binary_sensor_response);
|
return encode_message_to_buffer(msg, ListEntitiesBinarySensorResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_COVER
|
#ifdef USE_COVER
|
||||||
bool APIConnection::send_cover_state(cover::Cover *cover) {
|
bool APIConnection::send_cover_state(cover::Cover *cover) {
|
||||||
return this->send_state_(static_cast<EntityBase *>(cover),
|
return this->schedule_message_(cover, &APIConnection::try_send_cover_state, CoverStateResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_cover_state_));
|
|
||||||
}
|
}
|
||||||
void APIConnection::send_cover_info(cover::Cover *cover) {
|
void APIConnection::send_cover_info(cover::Cover *cover) {
|
||||||
this->send_info_(static_cast<EntityBase *>(cover),
|
this->schedule_message_(cover, &APIConnection::try_send_cover_info, ListEntitiesCoverResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_cover_info_));
|
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_cover_state_(cover::Cover *cover) {
|
uint16_t APIConnection::try_send_cover_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *cover = static_cast<cover::Cover *>(entity);
|
||||||
CoverStateResponse msg;
|
CoverStateResponse msg;
|
||||||
auto traits = cover->get_traits();
|
auto traits = cover->get_traits();
|
||||||
msg.legacy_state =
|
msg.legacy_state =
|
||||||
@ -327,9 +320,11 @@ bool APIConnection::try_send_cover_state_(cover::Cover *cover) {
|
|||||||
msg.tilt = cover->tilt;
|
msg.tilt = cover->tilt;
|
||||||
msg.current_operation = static_cast<enums::CoverOperation>(cover->current_operation);
|
msg.current_operation = static_cast<enums::CoverOperation>(cover->current_operation);
|
||||||
msg.key = cover->get_object_id_hash();
|
msg.key = cover->get_object_id_hash();
|
||||||
return this->send_cover_state_response(msg);
|
return encode_message_to_buffer(msg, CoverStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_cover_info_(cover::Cover *cover) {
|
uint16_t APIConnection::try_send_cover_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *cover = static_cast<cover::Cover *>(entity);
|
||||||
ListEntitiesCoverResponse msg;
|
ListEntitiesCoverResponse msg;
|
||||||
auto traits = cover->get_traits();
|
auto traits = cover->get_traits();
|
||||||
msg.assumed_state = traits.get_is_assumed_state();
|
msg.assumed_state = traits.get_is_assumed_state();
|
||||||
@ -338,8 +333,8 @@ bool APIConnection::try_send_cover_info_(cover::Cover *cover) {
|
|||||||
msg.supports_stop = traits.get_supports_stop();
|
msg.supports_stop = traits.get_supports_stop();
|
||||||
msg.device_class = cover->get_device_class();
|
msg.device_class = cover->get_device_class();
|
||||||
msg.unique_id = get_default_unique_id("cover", cover);
|
msg.unique_id = get_default_unique_id("cover", cover);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(cover), msg,
|
fill_entity_info_base(cover, msg);
|
||||||
&APIConnection::send_list_entities_cover_response);
|
return encode_message_to_buffer(msg, ListEntitiesCoverResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
void APIConnection::cover_command(const CoverCommandRequest &msg) {
|
void APIConnection::cover_command(const CoverCommandRequest &msg) {
|
||||||
cover::Cover *cover = App.get_cover_by_key(msg.key);
|
cover::Cover *cover = App.get_cover_by_key(msg.key);
|
||||||
@ -372,14 +367,14 @@ void APIConnection::cover_command(const CoverCommandRequest &msg) {
|
|||||||
|
|
||||||
#ifdef USE_FAN
|
#ifdef USE_FAN
|
||||||
bool APIConnection::send_fan_state(fan::Fan *fan) {
|
bool APIConnection::send_fan_state(fan::Fan *fan) {
|
||||||
return this->send_state_(static_cast<EntityBase *>(fan),
|
return this->schedule_message_(fan, &APIConnection::try_send_fan_state, FanStateResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_fan_state_));
|
|
||||||
}
|
}
|
||||||
void APIConnection::send_fan_info(fan::Fan *fan) {
|
void APIConnection::send_fan_info(fan::Fan *fan) {
|
||||||
this->send_info_(static_cast<EntityBase *>(fan),
|
this->schedule_message_(fan, &APIConnection::try_send_fan_info, ListEntitiesFanResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_fan_info_));
|
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_fan_state_(fan::Fan *fan) {
|
uint16_t APIConnection::try_send_fan_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *fan = static_cast<fan::Fan *>(entity);
|
||||||
FanStateResponse msg;
|
FanStateResponse msg;
|
||||||
auto traits = fan->get_traits();
|
auto traits = fan->get_traits();
|
||||||
msg.state = fan->state;
|
msg.state = fan->state;
|
||||||
@ -393,9 +388,11 @@ bool APIConnection::try_send_fan_state_(fan::Fan *fan) {
|
|||||||
if (traits.supports_preset_modes())
|
if (traits.supports_preset_modes())
|
||||||
msg.preset_mode = fan->preset_mode;
|
msg.preset_mode = fan->preset_mode;
|
||||||
msg.key = fan->get_object_id_hash();
|
msg.key = fan->get_object_id_hash();
|
||||||
return this->send_fan_state_response(msg);
|
return encode_message_to_buffer(msg, FanStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_fan_info_(fan::Fan *fan) {
|
uint16_t APIConnection::try_send_fan_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *fan = static_cast<fan::Fan *>(entity);
|
||||||
ListEntitiesFanResponse msg;
|
ListEntitiesFanResponse msg;
|
||||||
auto traits = fan->get_traits();
|
auto traits = fan->get_traits();
|
||||||
msg.supports_oscillation = traits.supports_oscillation();
|
msg.supports_oscillation = traits.supports_oscillation();
|
||||||
@ -405,8 +402,8 @@ bool APIConnection::try_send_fan_info_(fan::Fan *fan) {
|
|||||||
for (auto const &preset : traits.supported_preset_modes())
|
for (auto const &preset : traits.supported_preset_modes())
|
||||||
msg.supported_preset_modes.push_back(preset);
|
msg.supported_preset_modes.push_back(preset);
|
||||||
msg.unique_id = get_default_unique_id("fan", fan);
|
msg.unique_id = get_default_unique_id("fan", fan);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(fan), msg,
|
fill_entity_info_base(fan, msg);
|
||||||
&APIConnection::send_list_entities_fan_response);
|
return encode_message_to_buffer(msg, ListEntitiesFanResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
void APIConnection::fan_command(const FanCommandRequest &msg) {
|
void APIConnection::fan_command(const FanCommandRequest &msg) {
|
||||||
fan::Fan *fan = App.get_fan_by_key(msg.key);
|
fan::Fan *fan = App.get_fan_by_key(msg.key);
|
||||||
@ -432,14 +429,14 @@ void APIConnection::fan_command(const FanCommandRequest &msg) {
|
|||||||
|
|
||||||
#ifdef USE_LIGHT
|
#ifdef USE_LIGHT
|
||||||
bool APIConnection::send_light_state(light::LightState *light) {
|
bool APIConnection::send_light_state(light::LightState *light) {
|
||||||
return this->send_state_(static_cast<EntityBase *>(light),
|
return this->schedule_message_(light, &APIConnection::try_send_light_state, LightStateResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_light_state_));
|
|
||||||
}
|
}
|
||||||
void APIConnection::send_light_info(light::LightState *light) {
|
void APIConnection::send_light_info(light::LightState *light) {
|
||||||
this->send_info_(static_cast<EntityBase *>(light),
|
this->schedule_message_(light, &APIConnection::try_send_light_info, ListEntitiesLightResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_light_info_));
|
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_light_state_(light::LightState *light) {
|
uint16_t APIConnection::try_send_light_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *light = static_cast<light::LightState *>(entity);
|
||||||
LightStateResponse resp;
|
LightStateResponse resp;
|
||||||
auto traits = light->get_traits();
|
auto traits = light->get_traits();
|
||||||
auto values = light->remote_values;
|
auto values = light->remote_values;
|
||||||
@ -458,9 +455,11 @@ bool APIConnection::try_send_light_state_(light::LightState *light) {
|
|||||||
if (light->supports_effects())
|
if (light->supports_effects())
|
||||||
resp.effect = light->get_effect_name();
|
resp.effect = light->get_effect_name();
|
||||||
resp.key = light->get_object_id_hash();
|
resp.key = light->get_object_id_hash();
|
||||||
return this->send_light_state_response(resp);
|
return encode_message_to_buffer(resp, LightStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_light_info_(light::LightState *light) {
|
uint16_t APIConnection::try_send_light_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *light = static_cast<light::LightState *>(entity);
|
||||||
ListEntitiesLightResponse msg;
|
ListEntitiesLightResponse msg;
|
||||||
auto traits = light->get_traits();
|
auto traits = light->get_traits();
|
||||||
for (auto mode : traits.get_supported_color_modes())
|
for (auto mode : traits.get_supported_color_modes())
|
||||||
@ -483,8 +482,8 @@ bool APIConnection::try_send_light_info_(light::LightState *light) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
msg.unique_id = get_default_unique_id("light", light);
|
msg.unique_id = get_default_unique_id("light", light);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(light), msg,
|
fill_entity_info_base(light, msg);
|
||||||
&APIConnection::send_list_entities_light_response);
|
return encode_message_to_buffer(msg, ListEntitiesLightResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
void APIConnection::light_command(const LightCommandRequest &msg) {
|
void APIConnection::light_command(const LightCommandRequest &msg) {
|
||||||
light::LightState *light = App.get_light_by_key(msg.key);
|
light::LightState *light = App.get_light_by_key(msg.key);
|
||||||
@ -524,26 +523,26 @@ void APIConnection::light_command(const LightCommandRequest &msg) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
bool APIConnection::send_sensor_state(sensor::Sensor *sensor, float state) {
|
bool APIConnection::send_sensor_state(sensor::Sensor *sensor) {
|
||||||
return this->send_state_with_value_(sensor, &APIConnection::try_send_sensor_state_,
|
return this->schedule_message_(sensor, &APIConnection::try_send_sensor_state, SensorStateResponse::MESSAGE_TYPE);
|
||||||
&APIConnection::try_send_sensor_state_, state);
|
|
||||||
}
|
}
|
||||||
void APIConnection::send_sensor_info(sensor::Sensor *sensor) {
|
void APIConnection::send_sensor_info(sensor::Sensor *sensor) {
|
||||||
this->send_info_(static_cast<EntityBase *>(sensor),
|
this->schedule_message_(sensor, &APIConnection::try_send_sensor_info, ListEntitiesSensorResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_sensor_info_));
|
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_sensor_state_(sensor::Sensor *sensor) {
|
|
||||||
return this->try_send_sensor_state_(sensor, sensor->state);
|
|
||||||
}
|
|
||||||
bool APIConnection::try_send_sensor_state_(sensor::Sensor *sensor, float state) {
|
|
||||||
SensorStateResponse resp;
|
|
||||||
resp.state = state;
|
|
||||||
resp.missing_state = !sensor->has_state();
|
|
||||||
|
|
||||||
|
uint16_t APIConnection::try_send_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *sensor = static_cast<sensor::Sensor *>(entity);
|
||||||
|
SensorStateResponse resp;
|
||||||
|
resp.state = sensor->state;
|
||||||
|
resp.missing_state = !sensor->has_state();
|
||||||
resp.key = sensor->get_object_id_hash();
|
resp.key = sensor->get_object_id_hash();
|
||||||
return this->send_sensor_state_response(resp);
|
return encode_message_to_buffer(resp, SensorStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_sensor_info_(sensor::Sensor *sensor) {
|
|
||||||
|
uint16_t APIConnection::try_send_sensor_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *sensor = static_cast<sensor::Sensor *>(entity);
|
||||||
ListEntitiesSensorResponse msg;
|
ListEntitiesSensorResponse msg;
|
||||||
msg.unit_of_measurement = sensor->get_unit_of_measurement();
|
msg.unit_of_measurement = sensor->get_unit_of_measurement();
|
||||||
msg.accuracy_decimals = sensor->get_accuracy_decimals();
|
msg.accuracy_decimals = sensor->get_accuracy_decimals();
|
||||||
@ -553,37 +552,37 @@ bool APIConnection::try_send_sensor_info_(sensor::Sensor *sensor) {
|
|||||||
msg.unique_id = sensor->unique_id();
|
msg.unique_id = sensor->unique_id();
|
||||||
if (msg.unique_id.empty())
|
if (msg.unique_id.empty())
|
||||||
msg.unique_id = get_default_unique_id("sensor", sensor);
|
msg.unique_id = get_default_unique_id("sensor", sensor);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(sensor), msg,
|
fill_entity_info_base(sensor, msg);
|
||||||
&APIConnection::send_list_entities_sensor_response);
|
return encode_message_to_buffer(msg, ListEntitiesSensorResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SWITCH
|
#ifdef USE_SWITCH
|
||||||
bool APIConnection::send_switch_state(switch_::Switch *a_switch, bool state) {
|
bool APIConnection::send_switch_state(switch_::Switch *a_switch) {
|
||||||
return this->send_state_with_value_(a_switch, &APIConnection::try_send_switch_state_,
|
return this->schedule_message_(a_switch, &APIConnection::try_send_switch_state, SwitchStateResponse::MESSAGE_TYPE);
|
||||||
&APIConnection::try_send_switch_state_, state);
|
|
||||||
}
|
}
|
||||||
void APIConnection::send_switch_info(switch_::Switch *a_switch) {
|
void APIConnection::send_switch_info(switch_::Switch *a_switch) {
|
||||||
this->send_info_(static_cast<EntityBase *>(a_switch),
|
this->schedule_message_(a_switch, &APIConnection::try_send_switch_info, ListEntitiesSwitchResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_switch_info_));
|
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_switch_state_(switch_::Switch *a_switch) {
|
|
||||||
return this->try_send_switch_state_(a_switch, a_switch->state);
|
|
||||||
}
|
|
||||||
bool APIConnection::try_send_switch_state_(switch_::Switch *a_switch, bool state) {
|
|
||||||
SwitchStateResponse resp;
|
|
||||||
resp.state = state;
|
|
||||||
|
|
||||||
|
uint16_t APIConnection::try_send_switch_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *a_switch = static_cast<switch_::Switch *>(entity);
|
||||||
|
SwitchStateResponse resp;
|
||||||
|
resp.state = a_switch->state;
|
||||||
resp.key = a_switch->get_object_id_hash();
|
resp.key = a_switch->get_object_id_hash();
|
||||||
return this->send_switch_state_response(resp);
|
return encode_message_to_buffer(resp, SwitchStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_switch_info_(switch_::Switch *a_switch) {
|
|
||||||
|
uint16_t APIConnection::try_send_switch_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *a_switch = static_cast<switch_::Switch *>(entity);
|
||||||
ListEntitiesSwitchResponse msg;
|
ListEntitiesSwitchResponse msg;
|
||||||
msg.assumed_state = a_switch->assumed_state();
|
msg.assumed_state = a_switch->assumed_state();
|
||||||
msg.device_class = a_switch->get_device_class();
|
msg.device_class = a_switch->get_device_class();
|
||||||
msg.unique_id = get_default_unique_id("switch", a_switch);
|
msg.unique_id = get_default_unique_id("switch", a_switch);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(a_switch), msg,
|
fill_entity_info_base(a_switch, msg);
|
||||||
&APIConnection::send_list_entities_switch_response);
|
return encode_message_to_buffer(msg, ListEntitiesSwitchResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
void APIConnection::switch_command(const SwitchCommandRequest &msg) {
|
void APIConnection::switch_command(const SwitchCommandRequest &msg) {
|
||||||
switch_::Switch *a_switch = App.get_switch_by_key(msg.key);
|
switch_::Switch *a_switch = App.get_switch_by_key(msg.key);
|
||||||
@ -599,46 +598,44 @@ void APIConnection::switch_command(const SwitchCommandRequest &msg) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_TEXT_SENSOR
|
#ifdef USE_TEXT_SENSOR
|
||||||
bool APIConnection::send_text_sensor_state(text_sensor::TextSensor *text_sensor, std::string state) {
|
bool APIConnection::send_text_sensor_state(text_sensor::TextSensor *text_sensor) {
|
||||||
return this->send_state_with_value_(text_sensor, &APIConnection::try_send_text_sensor_state_,
|
return this->schedule_message_(text_sensor, &APIConnection::try_send_text_sensor_state,
|
||||||
&APIConnection::try_send_text_sensor_state_, std::move(state));
|
TextSensorStateResponse::MESSAGE_TYPE);
|
||||||
}
|
}
|
||||||
void APIConnection::send_text_sensor_info(text_sensor::TextSensor *text_sensor) {
|
void APIConnection::send_text_sensor_info(text_sensor::TextSensor *text_sensor) {
|
||||||
this->send_info_(static_cast<EntityBase *>(text_sensor),
|
this->schedule_message_(text_sensor, &APIConnection::try_send_text_sensor_info,
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_text_sensor_info_));
|
ListEntitiesTextSensorResponse::MESSAGE_TYPE);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_text_sensor_state_(text_sensor::TextSensor *text_sensor) {
|
|
||||||
return this->try_send_text_sensor_state_(text_sensor, text_sensor->state);
|
|
||||||
}
|
|
||||||
bool APIConnection::try_send_text_sensor_state_(text_sensor::TextSensor *text_sensor, std::string state) {
|
|
||||||
TextSensorStateResponse resp;
|
|
||||||
resp.state = std::move(state);
|
|
||||||
resp.missing_state = !text_sensor->has_state();
|
|
||||||
|
|
||||||
|
uint16_t APIConnection::try_send_text_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *text_sensor = static_cast<text_sensor::TextSensor *>(entity);
|
||||||
|
TextSensorStateResponse resp;
|
||||||
|
resp.state = text_sensor->state;
|
||||||
|
resp.missing_state = !text_sensor->has_state();
|
||||||
resp.key = text_sensor->get_object_id_hash();
|
resp.key = text_sensor->get_object_id_hash();
|
||||||
return this->send_text_sensor_state_response(resp);
|
return encode_message_to_buffer(resp, TextSensorStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_text_sensor_info_(text_sensor::TextSensor *text_sensor) {
|
uint16_t APIConnection::try_send_text_sensor_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *text_sensor = static_cast<text_sensor::TextSensor *>(entity);
|
||||||
ListEntitiesTextSensorResponse msg;
|
ListEntitiesTextSensorResponse msg;
|
||||||
msg.device_class = text_sensor->get_device_class();
|
msg.device_class = text_sensor->get_device_class();
|
||||||
msg.unique_id = text_sensor->unique_id();
|
msg.unique_id = text_sensor->unique_id();
|
||||||
if (msg.unique_id.empty())
|
if (msg.unique_id.empty())
|
||||||
msg.unique_id = get_default_unique_id("text_sensor", text_sensor);
|
msg.unique_id = get_default_unique_id("text_sensor", text_sensor);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(text_sensor), msg,
|
fill_entity_info_base(text_sensor, msg);
|
||||||
&APIConnection::send_list_entities_text_sensor_response);
|
return encode_message_to_buffer(msg, ListEntitiesTextSensorResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_CLIMATE
|
#ifdef USE_CLIMATE
|
||||||
bool APIConnection::send_climate_state(climate::Climate *climate) {
|
bool APIConnection::send_climate_state(climate::Climate *climate) {
|
||||||
return this->send_state_(static_cast<EntityBase *>(climate),
|
return this->schedule_message_(climate, &APIConnection::try_send_climate_state, ClimateStateResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_climate_state_));
|
|
||||||
}
|
}
|
||||||
void APIConnection::send_climate_info(climate::Climate *climate) {
|
uint16_t APIConnection::try_send_climate_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
this->send_info_(static_cast<EntityBase *>(climate),
|
bool is_single) {
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_climate_info_));
|
auto *climate = static_cast<climate::Climate *>(entity);
|
||||||
}
|
|
||||||
bool APIConnection::try_send_climate_state_(climate::Climate *climate) {
|
|
||||||
ClimateStateResponse resp;
|
ClimateStateResponse resp;
|
||||||
resp.key = climate->get_object_id_hash();
|
resp.key = climate->get_object_id_hash();
|
||||||
auto traits = climate->get_traits();
|
auto traits = climate->get_traits();
|
||||||
@ -667,9 +664,14 @@ bool APIConnection::try_send_climate_state_(climate::Climate *climate) {
|
|||||||
resp.current_humidity = climate->current_humidity;
|
resp.current_humidity = climate->current_humidity;
|
||||||
if (traits.get_supports_target_humidity())
|
if (traits.get_supports_target_humidity())
|
||||||
resp.target_humidity = climate->target_humidity;
|
resp.target_humidity = climate->target_humidity;
|
||||||
return this->send_climate_state_response(resp);
|
return encode_message_to_buffer(resp, ClimateStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_climate_info_(climate::Climate *climate) {
|
void APIConnection::send_climate_info(climate::Climate *climate) {
|
||||||
|
this->schedule_message_(climate, &APIConnection::try_send_climate_info, ListEntitiesClimateResponse::MESSAGE_TYPE);
|
||||||
|
}
|
||||||
|
uint16_t APIConnection::try_send_climate_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *climate = static_cast<climate::Climate *>(entity);
|
||||||
ListEntitiesClimateResponse msg;
|
ListEntitiesClimateResponse msg;
|
||||||
auto traits = climate->get_traits();
|
auto traits = climate->get_traits();
|
||||||
msg.supports_current_temperature = traits.get_supports_current_temperature();
|
msg.supports_current_temperature = traits.get_supports_current_temperature();
|
||||||
@ -697,8 +699,8 @@ bool APIConnection::try_send_climate_info_(climate::Climate *climate) {
|
|||||||
for (auto swing_mode : traits.get_supported_swing_modes())
|
for (auto swing_mode : traits.get_supported_swing_modes())
|
||||||
msg.supported_swing_modes.push_back(static_cast<enums::ClimateSwingMode>(swing_mode));
|
msg.supported_swing_modes.push_back(static_cast<enums::ClimateSwingMode>(swing_mode));
|
||||||
msg.unique_id = get_default_unique_id("climate", climate);
|
msg.unique_id = get_default_unique_id("climate", climate);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(climate), msg,
|
fill_entity_info_base(climate, msg);
|
||||||
&APIConnection::send_list_entities_climate_response);
|
return encode_message_to_buffer(msg, ListEntitiesClimateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
void APIConnection::climate_command(const ClimateCommandRequest &msg) {
|
void APIConnection::climate_command(const ClimateCommandRequest &msg) {
|
||||||
climate::Climate *climate = App.get_climate_by_key(msg.key);
|
climate::Climate *climate = App.get_climate_by_key(msg.key);
|
||||||
@ -731,26 +733,26 @@ void APIConnection::climate_command(const ClimateCommandRequest &msg) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_NUMBER
|
#ifdef USE_NUMBER
|
||||||
bool APIConnection::send_number_state(number::Number *number, float state) {
|
bool APIConnection::send_number_state(number::Number *number) {
|
||||||
return this->send_state_with_value_(number, &APIConnection::try_send_number_state_,
|
return this->schedule_message_(number, &APIConnection::try_send_number_state, NumberStateResponse::MESSAGE_TYPE);
|
||||||
&APIConnection::try_send_number_state_, state);
|
|
||||||
}
|
}
|
||||||
void APIConnection::send_number_info(number::Number *number) {
|
void APIConnection::send_number_info(number::Number *number) {
|
||||||
this->send_info_(static_cast<EntityBase *>(number),
|
this->schedule_message_(number, &APIConnection::try_send_number_info, ListEntitiesNumberResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_number_info_));
|
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_number_state_(number::Number *number) {
|
|
||||||
return this->try_send_number_state_(number, number->state);
|
|
||||||
}
|
|
||||||
bool APIConnection::try_send_number_state_(number::Number *number, float state) {
|
|
||||||
NumberStateResponse resp;
|
|
||||||
resp.state = state;
|
|
||||||
resp.missing_state = !number->has_state();
|
|
||||||
|
|
||||||
|
uint16_t APIConnection::try_send_number_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *number = static_cast<number::Number *>(entity);
|
||||||
|
NumberStateResponse resp;
|
||||||
|
resp.state = number->state;
|
||||||
|
resp.missing_state = !number->has_state();
|
||||||
resp.key = number->get_object_id_hash();
|
resp.key = number->get_object_id_hash();
|
||||||
return this->send_number_state_response(resp);
|
return encode_message_to_buffer(resp, NumberStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_number_info_(number::Number *number) {
|
|
||||||
|
uint16_t APIConnection::try_send_number_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *number = static_cast<number::Number *>(entity);
|
||||||
ListEntitiesNumberResponse msg;
|
ListEntitiesNumberResponse msg;
|
||||||
msg.unit_of_measurement = number->traits.get_unit_of_measurement();
|
msg.unit_of_measurement = number->traits.get_unit_of_measurement();
|
||||||
msg.mode = static_cast<enums::NumberMode>(number->traits.get_mode());
|
msg.mode = static_cast<enums::NumberMode>(number->traits.get_mode());
|
||||||
@ -759,8 +761,8 @@ bool APIConnection::try_send_number_info_(number::Number *number) {
|
|||||||
msg.max_value = number->traits.get_max_value();
|
msg.max_value = number->traits.get_max_value();
|
||||||
msg.step = number->traits.get_step();
|
msg.step = number->traits.get_step();
|
||||||
msg.unique_id = get_default_unique_id("number", number);
|
msg.unique_id = get_default_unique_id("number", number);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(number), msg,
|
fill_entity_info_base(number, msg);
|
||||||
&APIConnection::send_list_entities_number_response);
|
return encode_message_to_buffer(msg, ListEntitiesNumberResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
void APIConnection::number_command(const NumberCommandRequest &msg) {
|
void APIConnection::number_command(const NumberCommandRequest &msg) {
|
||||||
number::Number *number = App.get_number_by_key(msg.key);
|
number::Number *number = App.get_number_by_key(msg.key);
|
||||||
@ -775,28 +777,29 @@ void APIConnection::number_command(const NumberCommandRequest &msg) {
|
|||||||
|
|
||||||
#ifdef USE_DATETIME_DATE
|
#ifdef USE_DATETIME_DATE
|
||||||
bool APIConnection::send_date_state(datetime::DateEntity *date) {
|
bool APIConnection::send_date_state(datetime::DateEntity *date) {
|
||||||
return this->send_state_(static_cast<EntityBase *>(date),
|
return this->schedule_message_(date, &APIConnection::try_send_date_state, DateStateResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_date_state_));
|
|
||||||
}
|
}
|
||||||
void APIConnection::send_date_info(datetime::DateEntity *date) {
|
uint16_t APIConnection::try_send_date_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
this->send_info_(static_cast<EntityBase *>(date),
|
bool is_single) {
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_date_info_));
|
auto *date = static_cast<datetime::DateEntity *>(entity);
|
||||||
}
|
|
||||||
bool APIConnection::try_send_date_state_(datetime::DateEntity *date) {
|
|
||||||
DateStateResponse resp;
|
DateStateResponse resp;
|
||||||
resp.missing_state = !date->has_state();
|
resp.missing_state = !date->has_state();
|
||||||
resp.year = date->year;
|
resp.year = date->year;
|
||||||
resp.month = date->month;
|
resp.month = date->month;
|
||||||
resp.day = date->day;
|
resp.day = date->day;
|
||||||
|
|
||||||
resp.key = date->get_object_id_hash();
|
resp.key = date->get_object_id_hash();
|
||||||
return this->send_date_state_response(resp);
|
return encode_message_to_buffer(resp, DateStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_date_info_(datetime::DateEntity *date) {
|
void APIConnection::send_date_info(datetime::DateEntity *date) {
|
||||||
|
this->schedule_message_(date, &APIConnection::try_send_date_info, ListEntitiesDateResponse::MESSAGE_TYPE);
|
||||||
|
}
|
||||||
|
uint16_t APIConnection::try_send_date_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *date = static_cast<datetime::DateEntity *>(entity);
|
||||||
ListEntitiesDateResponse msg;
|
ListEntitiesDateResponse msg;
|
||||||
msg.unique_id = get_default_unique_id("date", date);
|
msg.unique_id = get_default_unique_id("date", date);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(date), msg,
|
fill_entity_info_base(date, msg);
|
||||||
&APIConnection::send_list_entities_date_response);
|
return encode_message_to_buffer(msg, ListEntitiesDateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
void APIConnection::date_command(const DateCommandRequest &msg) {
|
void APIConnection::date_command(const DateCommandRequest &msg) {
|
||||||
datetime::DateEntity *date = App.get_date_by_key(msg.key);
|
datetime::DateEntity *date = App.get_date_by_key(msg.key);
|
||||||
@ -811,28 +814,29 @@ void APIConnection::date_command(const DateCommandRequest &msg) {
|
|||||||
|
|
||||||
#ifdef USE_DATETIME_TIME
|
#ifdef USE_DATETIME_TIME
|
||||||
bool APIConnection::send_time_state(datetime::TimeEntity *time) {
|
bool APIConnection::send_time_state(datetime::TimeEntity *time) {
|
||||||
return this->send_state_(static_cast<EntityBase *>(time),
|
return this->schedule_message_(time, &APIConnection::try_send_time_state, TimeStateResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_time_state_));
|
|
||||||
}
|
}
|
||||||
void APIConnection::send_time_info(datetime::TimeEntity *time) {
|
uint16_t APIConnection::try_send_time_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
this->send_info_(static_cast<EntityBase *>(time),
|
bool is_single) {
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_time_info_));
|
auto *time = static_cast<datetime::TimeEntity *>(entity);
|
||||||
}
|
|
||||||
bool APIConnection::try_send_time_state_(datetime::TimeEntity *time) {
|
|
||||||
TimeStateResponse resp;
|
TimeStateResponse resp;
|
||||||
resp.missing_state = !time->has_state();
|
resp.missing_state = !time->has_state();
|
||||||
resp.hour = time->hour;
|
resp.hour = time->hour;
|
||||||
resp.minute = time->minute;
|
resp.minute = time->minute;
|
||||||
resp.second = time->second;
|
resp.second = time->second;
|
||||||
|
|
||||||
resp.key = time->get_object_id_hash();
|
resp.key = time->get_object_id_hash();
|
||||||
return this->send_time_state_response(resp);
|
return encode_message_to_buffer(resp, TimeStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_time_info_(datetime::TimeEntity *time) {
|
void APIConnection::send_time_info(datetime::TimeEntity *time) {
|
||||||
|
this->schedule_message_(time, &APIConnection::try_send_time_info, ListEntitiesTimeResponse::MESSAGE_TYPE);
|
||||||
|
}
|
||||||
|
uint16_t APIConnection::try_send_time_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *time = static_cast<datetime::TimeEntity *>(entity);
|
||||||
ListEntitiesTimeResponse msg;
|
ListEntitiesTimeResponse msg;
|
||||||
msg.unique_id = get_default_unique_id("time", time);
|
msg.unique_id = get_default_unique_id("time", time);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(time), msg,
|
fill_entity_info_base(time, msg);
|
||||||
&APIConnection::send_list_entities_time_response);
|
return encode_message_to_buffer(msg, ListEntitiesTimeResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
void APIConnection::time_command(const TimeCommandRequest &msg) {
|
void APIConnection::time_command(const TimeCommandRequest &msg) {
|
||||||
datetime::TimeEntity *time = App.get_time_by_key(msg.key);
|
datetime::TimeEntity *time = App.get_time_by_key(msg.key);
|
||||||
@ -847,29 +851,31 @@ void APIConnection::time_command(const TimeCommandRequest &msg) {
|
|||||||
|
|
||||||
#ifdef USE_DATETIME_DATETIME
|
#ifdef USE_DATETIME_DATETIME
|
||||||
bool APIConnection::send_datetime_state(datetime::DateTimeEntity *datetime) {
|
bool APIConnection::send_datetime_state(datetime::DateTimeEntity *datetime) {
|
||||||
return this->send_state_(static_cast<EntityBase *>(datetime),
|
return this->schedule_message_(datetime, &APIConnection::try_send_datetime_state,
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_datetime_state_));
|
DateTimeStateResponse::MESSAGE_TYPE);
|
||||||
}
|
}
|
||||||
void APIConnection::send_datetime_info(datetime::DateTimeEntity *datetime) {
|
uint16_t APIConnection::try_send_datetime_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
this->send_info_(static_cast<EntityBase *>(datetime),
|
bool is_single) {
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_datetime_info_));
|
auto *datetime = static_cast<datetime::DateTimeEntity *>(entity);
|
||||||
}
|
|
||||||
bool APIConnection::try_send_datetime_state_(datetime::DateTimeEntity *datetime) {
|
|
||||||
DateTimeStateResponse resp;
|
DateTimeStateResponse resp;
|
||||||
resp.missing_state = !datetime->has_state();
|
resp.missing_state = !datetime->has_state();
|
||||||
if (datetime->has_state()) {
|
if (datetime->has_state()) {
|
||||||
ESPTime state = datetime->state_as_esptime();
|
ESPTime state = datetime->state_as_esptime();
|
||||||
resp.epoch_seconds = state.timestamp;
|
resp.epoch_seconds = state.timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.key = datetime->get_object_id_hash();
|
resp.key = datetime->get_object_id_hash();
|
||||||
return this->send_date_time_state_response(resp);
|
return encode_message_to_buffer(resp, DateTimeStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_datetime_info_(datetime::DateTimeEntity *datetime) {
|
void APIConnection::send_datetime_info(datetime::DateTimeEntity *datetime) {
|
||||||
|
this->schedule_message_(datetime, &APIConnection::try_send_datetime_info, ListEntitiesDateTimeResponse::MESSAGE_TYPE);
|
||||||
|
}
|
||||||
|
uint16_t APIConnection::try_send_datetime_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *datetime = static_cast<datetime::DateTimeEntity *>(entity);
|
||||||
ListEntitiesDateTimeResponse msg;
|
ListEntitiesDateTimeResponse msg;
|
||||||
msg.unique_id = get_default_unique_id("datetime", datetime);
|
msg.unique_id = get_default_unique_id("datetime", datetime);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(datetime), msg,
|
fill_entity_info_base(datetime, msg);
|
||||||
&APIConnection::send_list_entities_date_time_response);
|
return encode_message_to_buffer(msg, ListEntitiesDateTimeResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
void APIConnection::datetime_command(const DateTimeCommandRequest &msg) {
|
void APIConnection::datetime_command(const DateTimeCommandRequest &msg) {
|
||||||
datetime::DateTimeEntity *datetime = App.get_datetime_by_key(msg.key);
|
datetime::DateTimeEntity *datetime = App.get_datetime_by_key(msg.key);
|
||||||
@ -883,32 +889,34 @@ void APIConnection::datetime_command(const DateTimeCommandRequest &msg) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_TEXT
|
#ifdef USE_TEXT
|
||||||
bool APIConnection::send_text_state(text::Text *text, std::string state) {
|
bool APIConnection::send_text_state(text::Text *text) {
|
||||||
return this->send_state_with_value_(text, &APIConnection::try_send_text_state_, &APIConnection::try_send_text_state_,
|
return this->schedule_message_(text, &APIConnection::try_send_text_state, TextStateResponse::MESSAGE_TYPE);
|
||||||
std::move(state));
|
|
||||||
}
|
}
|
||||||
void APIConnection::send_text_info(text::Text *text) {
|
void APIConnection::send_text_info(text::Text *text) {
|
||||||
this->send_info_(static_cast<EntityBase *>(text),
|
this->schedule_message_(text, &APIConnection::try_send_text_info, ListEntitiesTextResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_text_info_));
|
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_text_state_(text::Text *text) { return this->try_send_text_state_(text, text->state); }
|
|
||||||
bool APIConnection::try_send_text_state_(text::Text *text, std::string state) {
|
|
||||||
TextStateResponse resp;
|
|
||||||
resp.state = std::move(state);
|
|
||||||
resp.missing_state = !text->has_state();
|
|
||||||
|
|
||||||
|
uint16_t APIConnection::try_send_text_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *text = static_cast<text::Text *>(entity);
|
||||||
|
TextStateResponse resp;
|
||||||
|
resp.state = text->state;
|
||||||
|
resp.missing_state = !text->has_state();
|
||||||
resp.key = text->get_object_id_hash();
|
resp.key = text->get_object_id_hash();
|
||||||
return this->send_text_state_response(resp);
|
return encode_message_to_buffer(resp, TextStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_text_info_(text::Text *text) {
|
|
||||||
|
uint16_t APIConnection::try_send_text_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *text = static_cast<text::Text *>(entity);
|
||||||
ListEntitiesTextResponse msg;
|
ListEntitiesTextResponse msg;
|
||||||
msg.mode = static_cast<enums::TextMode>(text->traits.get_mode());
|
msg.mode = static_cast<enums::TextMode>(text->traits.get_mode());
|
||||||
msg.min_length = text->traits.get_min_length();
|
msg.min_length = text->traits.get_min_length();
|
||||||
msg.max_length = text->traits.get_max_length();
|
msg.max_length = text->traits.get_max_length();
|
||||||
msg.pattern = text->traits.get_pattern();
|
msg.pattern = text->traits.get_pattern();
|
||||||
msg.unique_id = get_default_unique_id("text", text);
|
msg.unique_id = get_default_unique_id("text", text);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(text), msg,
|
fill_entity_info_base(text, msg);
|
||||||
&APIConnection::send_list_entities_text_response);
|
return encode_message_to_buffer(msg, ListEntitiesTextResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
void APIConnection::text_command(const TextCommandRequest &msg) {
|
void APIConnection::text_command(const TextCommandRequest &msg) {
|
||||||
text::Text *text = App.get_text_by_key(msg.key);
|
text::Text *text = App.get_text_by_key(msg.key);
|
||||||
@ -922,32 +930,32 @@ void APIConnection::text_command(const TextCommandRequest &msg) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SELECT
|
#ifdef USE_SELECT
|
||||||
bool APIConnection::send_select_state(select::Select *select, std::string state) {
|
bool APIConnection::send_select_state(select::Select *select) {
|
||||||
return this->send_state_with_value_(select, &APIConnection::try_send_select_state_,
|
return this->schedule_message_(select, &APIConnection::try_send_select_state, SelectStateResponse::MESSAGE_TYPE);
|
||||||
&APIConnection::try_send_select_state_, std::move(state));
|
|
||||||
}
|
}
|
||||||
void APIConnection::send_select_info(select::Select *select) {
|
void APIConnection::send_select_info(select::Select *select) {
|
||||||
this->send_info_(static_cast<EntityBase *>(select),
|
this->schedule_message_(select, &APIConnection::try_send_select_info, ListEntitiesSelectResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_select_info_));
|
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_select_state_(select::Select *select) {
|
|
||||||
return this->try_send_select_state_(select, select->state);
|
|
||||||
}
|
|
||||||
bool APIConnection::try_send_select_state_(select::Select *select, std::string state) {
|
|
||||||
SelectStateResponse resp;
|
|
||||||
resp.state = std::move(state);
|
|
||||||
resp.missing_state = !select->has_state();
|
|
||||||
|
|
||||||
|
uint16_t APIConnection::try_send_select_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *select = static_cast<select::Select *>(entity);
|
||||||
|
SelectStateResponse resp;
|
||||||
|
resp.state = select->state;
|
||||||
|
resp.missing_state = !select->has_state();
|
||||||
resp.key = select->get_object_id_hash();
|
resp.key = select->get_object_id_hash();
|
||||||
return this->send_select_state_response(resp);
|
return encode_message_to_buffer(resp, SelectStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_select_info_(select::Select *select) {
|
|
||||||
|
uint16_t APIConnection::try_send_select_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *select = static_cast<select::Select *>(entity);
|
||||||
ListEntitiesSelectResponse msg;
|
ListEntitiesSelectResponse msg;
|
||||||
for (const auto &option : select->traits.get_options())
|
for (const auto &option : select->traits.get_options())
|
||||||
msg.options.push_back(option);
|
msg.options.push_back(option);
|
||||||
msg.unique_id = get_default_unique_id("select", select);
|
msg.unique_id = get_default_unique_id("select", select);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(select), msg,
|
fill_entity_info_base(select, msg);
|
||||||
&APIConnection::send_list_entities_select_response);
|
return encode_message_to_buffer(msg, ListEntitiesSelectResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
void APIConnection::select_command(const SelectCommandRequest &msg) {
|
void APIConnection::select_command(const SelectCommandRequest &msg) {
|
||||||
select::Select *select = App.get_select_by_key(msg.key);
|
select::Select *select = App.get_select_by_key(msg.key);
|
||||||
@ -962,15 +970,16 @@ void APIConnection::select_command(const SelectCommandRequest &msg) {
|
|||||||
|
|
||||||
#ifdef USE_BUTTON
|
#ifdef USE_BUTTON
|
||||||
void esphome::api::APIConnection::send_button_info(button::Button *button) {
|
void esphome::api::APIConnection::send_button_info(button::Button *button) {
|
||||||
this->send_info_(static_cast<EntityBase *>(button),
|
this->schedule_message_(button, &APIConnection::try_send_button_info, ListEntitiesButtonResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_button_info_));
|
|
||||||
}
|
}
|
||||||
bool esphome::api::APIConnection::try_send_button_info_(button::Button *button) {
|
uint16_t APIConnection::try_send_button_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *button = static_cast<button::Button *>(entity);
|
||||||
ListEntitiesButtonResponse msg;
|
ListEntitiesButtonResponse msg;
|
||||||
msg.device_class = button->get_device_class();
|
msg.device_class = button->get_device_class();
|
||||||
msg.unique_id = get_default_unique_id("button", button);
|
msg.unique_id = get_default_unique_id("button", button);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(button), msg,
|
fill_entity_info_base(button, msg);
|
||||||
&APIConnection::send_list_entities_button_response);
|
return encode_message_to_buffer(msg, ListEntitiesButtonResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
void esphome::api::APIConnection::button_command(const ButtonCommandRequest &msg) {
|
void esphome::api::APIConnection::button_command(const ButtonCommandRequest &msg) {
|
||||||
button::Button *button = App.get_button_by_key(msg.key);
|
button::Button *button = App.get_button_by_key(msg.key);
|
||||||
@ -982,32 +991,32 @@ void esphome::api::APIConnection::button_command(const ButtonCommandRequest &msg
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_LOCK
|
#ifdef USE_LOCK
|
||||||
bool APIConnection::send_lock_state(lock::Lock *a_lock, lock::LockState state) {
|
bool APIConnection::send_lock_state(lock::Lock *a_lock) {
|
||||||
return this->send_state_with_value_(a_lock, &APIConnection::try_send_lock_state_,
|
return this->schedule_message_(a_lock, &APIConnection::try_send_lock_state, LockStateResponse::MESSAGE_TYPE);
|
||||||
&APIConnection::try_send_lock_state_, state);
|
|
||||||
}
|
}
|
||||||
void APIConnection::send_lock_info(lock::Lock *a_lock) {
|
void APIConnection::send_lock_info(lock::Lock *a_lock) {
|
||||||
this->send_info_(static_cast<EntityBase *>(a_lock),
|
this->schedule_message_(a_lock, &APIConnection::try_send_lock_info, ListEntitiesLockResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_lock_info_));
|
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_lock_state_(lock::Lock *a_lock) {
|
|
||||||
return this->try_send_lock_state_(a_lock, a_lock->state);
|
|
||||||
}
|
|
||||||
bool APIConnection::try_send_lock_state_(lock::Lock *a_lock, lock::LockState state) {
|
|
||||||
LockStateResponse resp;
|
|
||||||
resp.state = static_cast<enums::LockState>(state);
|
|
||||||
|
|
||||||
|
uint16_t APIConnection::try_send_lock_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *a_lock = static_cast<lock::Lock *>(entity);
|
||||||
|
LockStateResponse resp;
|
||||||
|
resp.state = static_cast<enums::LockState>(a_lock->state);
|
||||||
resp.key = a_lock->get_object_id_hash();
|
resp.key = a_lock->get_object_id_hash();
|
||||||
return this->send_lock_state_response(resp);
|
return encode_message_to_buffer(resp, LockStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_lock_info_(lock::Lock *a_lock) {
|
|
||||||
|
uint16_t APIConnection::try_send_lock_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *a_lock = static_cast<lock::Lock *>(entity);
|
||||||
ListEntitiesLockResponse msg;
|
ListEntitiesLockResponse msg;
|
||||||
msg.assumed_state = a_lock->traits.get_assumed_state();
|
msg.assumed_state = a_lock->traits.get_assumed_state();
|
||||||
msg.supports_open = a_lock->traits.get_supports_open();
|
msg.supports_open = a_lock->traits.get_supports_open();
|
||||||
msg.requires_code = a_lock->traits.get_requires_code();
|
msg.requires_code = a_lock->traits.get_requires_code();
|
||||||
msg.unique_id = get_default_unique_id("lock", a_lock);
|
msg.unique_id = get_default_unique_id("lock", a_lock);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(a_lock), msg,
|
fill_entity_info_base(a_lock, msg);
|
||||||
&APIConnection::send_list_entities_lock_response);
|
return encode_message_to_buffer(msg, ListEntitiesLockResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
void APIConnection::lock_command(const LockCommandRequest &msg) {
|
void APIConnection::lock_command(const LockCommandRequest &msg) {
|
||||||
lock::Lock *a_lock = App.get_lock_by_key(msg.key);
|
lock::Lock *a_lock = App.get_lock_by_key(msg.key);
|
||||||
@ -1030,22 +1039,23 @@ void APIConnection::lock_command(const LockCommandRequest &msg) {
|
|||||||
|
|
||||||
#ifdef USE_VALVE
|
#ifdef USE_VALVE
|
||||||
bool APIConnection::send_valve_state(valve::Valve *valve) {
|
bool APIConnection::send_valve_state(valve::Valve *valve) {
|
||||||
return this->send_state_(static_cast<EntityBase *>(valve),
|
return this->schedule_message_(valve, &APIConnection::try_send_valve_state, ValveStateResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_valve_state_));
|
|
||||||
}
|
}
|
||||||
void APIConnection::send_valve_info(valve::Valve *valve) {
|
uint16_t APIConnection::try_send_valve_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
this->send_info_(static_cast<EntityBase *>(valve),
|
bool is_single) {
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_valve_info_));
|
auto *valve = static_cast<valve::Valve *>(entity);
|
||||||
}
|
|
||||||
bool APIConnection::try_send_valve_state_(valve::Valve *valve) {
|
|
||||||
ValveStateResponse resp;
|
ValveStateResponse resp;
|
||||||
resp.position = valve->position;
|
resp.position = valve->position;
|
||||||
resp.current_operation = static_cast<enums::ValveOperation>(valve->current_operation);
|
resp.current_operation = static_cast<enums::ValveOperation>(valve->current_operation);
|
||||||
|
|
||||||
resp.key = valve->get_object_id_hash();
|
resp.key = valve->get_object_id_hash();
|
||||||
return this->send_valve_state_response(resp);
|
return encode_message_to_buffer(resp, ValveStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_valve_info_(valve::Valve *valve) {
|
void APIConnection::send_valve_info(valve::Valve *valve) {
|
||||||
|
this->schedule_message_(valve, &APIConnection::try_send_valve_info, ListEntitiesValveResponse::MESSAGE_TYPE);
|
||||||
|
}
|
||||||
|
uint16_t APIConnection::try_send_valve_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *valve = static_cast<valve::Valve *>(entity);
|
||||||
ListEntitiesValveResponse msg;
|
ListEntitiesValveResponse msg;
|
||||||
auto traits = valve->get_traits();
|
auto traits = valve->get_traits();
|
||||||
msg.device_class = valve->get_device_class();
|
msg.device_class = valve->get_device_class();
|
||||||
@ -1053,8 +1063,8 @@ bool APIConnection::try_send_valve_info_(valve::Valve *valve) {
|
|||||||
msg.supports_position = traits.get_supports_position();
|
msg.supports_position = traits.get_supports_position();
|
||||||
msg.supports_stop = traits.get_supports_stop();
|
msg.supports_stop = traits.get_supports_stop();
|
||||||
msg.unique_id = get_default_unique_id("valve", valve);
|
msg.unique_id = get_default_unique_id("valve", valve);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(valve), msg,
|
fill_entity_info_base(valve, msg);
|
||||||
&APIConnection::send_list_entities_valve_response);
|
return encode_message_to_buffer(msg, ListEntitiesValveResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
void APIConnection::valve_command(const ValveCommandRequest &msg) {
|
void APIConnection::valve_command(const ValveCommandRequest &msg) {
|
||||||
valve::Valve *valve = App.get_valve_by_key(msg.key);
|
valve::Valve *valve = App.get_valve_by_key(msg.key);
|
||||||
@ -1072,14 +1082,12 @@ void APIConnection::valve_command(const ValveCommandRequest &msg) {
|
|||||||
|
|
||||||
#ifdef USE_MEDIA_PLAYER
|
#ifdef USE_MEDIA_PLAYER
|
||||||
bool APIConnection::send_media_player_state(media_player::MediaPlayer *media_player) {
|
bool APIConnection::send_media_player_state(media_player::MediaPlayer *media_player) {
|
||||||
return this->send_state_(static_cast<EntityBase *>(media_player),
|
return this->schedule_message_(media_player, &APIConnection::try_send_media_player_state,
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_media_player_state_));
|
MediaPlayerStateResponse::MESSAGE_TYPE);
|
||||||
}
|
}
|
||||||
void APIConnection::send_media_player_info(media_player::MediaPlayer *media_player) {
|
uint16_t APIConnection::try_send_media_player_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
this->send_info_(static_cast<EntityBase *>(media_player),
|
bool is_single) {
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_media_player_info_));
|
auto *media_player = static_cast<media_player::MediaPlayer *>(entity);
|
||||||
}
|
|
||||||
bool APIConnection::try_send_media_player_state_(media_player::MediaPlayer *media_player) {
|
|
||||||
MediaPlayerStateResponse resp;
|
MediaPlayerStateResponse resp;
|
||||||
media_player::MediaPlayerState report_state = media_player->state == media_player::MEDIA_PLAYER_STATE_ANNOUNCING
|
media_player::MediaPlayerState report_state = media_player->state == media_player::MEDIA_PLAYER_STATE_ANNOUNCING
|
||||||
? media_player::MEDIA_PLAYER_STATE_PLAYING
|
? media_player::MEDIA_PLAYER_STATE_PLAYING
|
||||||
@ -1087,11 +1095,16 @@ bool APIConnection::try_send_media_player_state_(media_player::MediaPlayer *medi
|
|||||||
resp.state = static_cast<enums::MediaPlayerState>(report_state);
|
resp.state = static_cast<enums::MediaPlayerState>(report_state);
|
||||||
resp.volume = media_player->volume;
|
resp.volume = media_player->volume;
|
||||||
resp.muted = media_player->is_muted();
|
resp.muted = media_player->is_muted();
|
||||||
|
|
||||||
resp.key = media_player->get_object_id_hash();
|
resp.key = media_player->get_object_id_hash();
|
||||||
return this->send_media_player_state_response(resp);
|
return encode_message_to_buffer(resp, MediaPlayerStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_media_player_info_(media_player::MediaPlayer *media_player) {
|
void APIConnection::send_media_player_info(media_player::MediaPlayer *media_player) {
|
||||||
|
this->schedule_message_(media_player, &APIConnection::try_send_media_player_info,
|
||||||
|
ListEntitiesMediaPlayerResponse::MESSAGE_TYPE);
|
||||||
|
}
|
||||||
|
uint16_t APIConnection::try_send_media_player_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *media_player = static_cast<media_player::MediaPlayer *>(entity);
|
||||||
ListEntitiesMediaPlayerResponse msg;
|
ListEntitiesMediaPlayerResponse msg;
|
||||||
auto traits = media_player->get_traits();
|
auto traits = media_player->get_traits();
|
||||||
msg.supports_pause = traits.get_supports_pause();
|
msg.supports_pause = traits.get_supports_pause();
|
||||||
@ -1105,8 +1118,8 @@ bool APIConnection::try_send_media_player_info_(media_player::MediaPlayer *media
|
|||||||
msg.supported_formats.push_back(media_format);
|
msg.supported_formats.push_back(media_format);
|
||||||
}
|
}
|
||||||
msg.unique_id = get_default_unique_id("media_player", media_player);
|
msg.unique_id = get_default_unique_id("media_player", media_player);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(media_player), msg,
|
fill_entity_info_base(media_player, msg);
|
||||||
&APIConnection::send_list_entities_media_player_response);
|
return encode_message_to_buffer(msg, ListEntitiesMediaPlayerResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
void APIConnection::media_player_command(const MediaPlayerCommandRequest &msg) {
|
void APIConnection::media_player_command(const MediaPlayerCommandRequest &msg) {
|
||||||
media_player::MediaPlayer *media_player = App.get_media_player_by_key(msg.key);
|
media_player::MediaPlayer *media_player = App.get_media_player_by_key(msg.key);
|
||||||
@ -1141,14 +1154,15 @@ void APIConnection::set_camera_state(std::shared_ptr<esp32_camera::CameraImage>
|
|||||||
this->image_reader_.set_image(std::move(image));
|
this->image_reader_.set_image(std::move(image));
|
||||||
}
|
}
|
||||||
void APIConnection::send_camera_info(esp32_camera::ESP32Camera *camera) {
|
void APIConnection::send_camera_info(esp32_camera::ESP32Camera *camera) {
|
||||||
this->send_info_(static_cast<EntityBase *>(camera),
|
this->schedule_message_(camera, &APIConnection::try_send_camera_info, ListEntitiesCameraResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_camera_info_));
|
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_camera_info_(esp32_camera::ESP32Camera *camera) {
|
uint16_t APIConnection::try_send_camera_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *camera = static_cast<esp32_camera::ESP32Camera *>(entity);
|
||||||
ListEntitiesCameraResponse msg;
|
ListEntitiesCameraResponse msg;
|
||||||
msg.unique_id = get_default_unique_id("camera", camera);
|
msg.unique_id = get_default_unique_id("camera", camera);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(camera), msg,
|
fill_entity_info_base(camera, msg);
|
||||||
&APIConnection::send_list_entities_camera_response);
|
return encode_message_to_buffer(msg, ListEntitiesCameraResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
void APIConnection::camera_image(const CameraImageRequest &msg) {
|
void APIConnection::camera_image(const CameraImageRequest &msg) {
|
||||||
if (esp32_camera::global_esp32_camera == nullptr)
|
if (esp32_camera::global_esp32_camera == nullptr)
|
||||||
@ -1191,9 +1205,9 @@ bool APIConnection::send_bluetooth_le_advertisement(const BluetoothLEAdvertiseme
|
|||||||
manufacturer_data.legacy_data.assign(manufacturer_data.data.begin(), manufacturer_data.data.end());
|
manufacturer_data.legacy_data.assign(manufacturer_data.data.begin(), manufacturer_data.data.end());
|
||||||
manufacturer_data.data.clear();
|
manufacturer_data.data.clear();
|
||||||
}
|
}
|
||||||
return this->send_bluetooth_le_advertisement_response(resp);
|
return this->send_message(resp);
|
||||||
}
|
}
|
||||||
return this->send_bluetooth_le_advertisement_response(msg);
|
return this->send_message(msg);
|
||||||
}
|
}
|
||||||
void APIConnection::bluetooth_device_request(const BluetoothDeviceRequest &msg) {
|
void APIConnection::bluetooth_device_request(const BluetoothDeviceRequest &msg) {
|
||||||
bluetooth_proxy::global_bluetooth_proxy->bluetooth_device_request(msg);
|
bluetooth_proxy::global_bluetooth_proxy->bluetooth_device_request(msg);
|
||||||
@ -1337,28 +1351,32 @@ void APIConnection::voice_assistant_set_configuration(const VoiceAssistantSetCon
|
|||||||
|
|
||||||
#ifdef USE_ALARM_CONTROL_PANEL
|
#ifdef USE_ALARM_CONTROL_PANEL
|
||||||
bool APIConnection::send_alarm_control_panel_state(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
|
bool APIConnection::send_alarm_control_panel_state(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
|
||||||
return this->send_state_(static_cast<EntityBase *>(a_alarm_control_panel),
|
return this->schedule_message_(a_alarm_control_panel, &APIConnection::try_send_alarm_control_panel_state,
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_alarm_control_panel_state_));
|
AlarmControlPanelStateResponse::MESSAGE_TYPE);
|
||||||
}
|
}
|
||||||
void APIConnection::send_alarm_control_panel_info(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
|
uint16_t APIConnection::try_send_alarm_control_panel_state(EntityBase *entity, APIConnection *conn,
|
||||||
this->send_info_(static_cast<EntityBase *>(a_alarm_control_panel),
|
uint32_t remaining_size, bool is_single) {
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_alarm_control_panel_info_));
|
auto *a_alarm_control_panel = static_cast<alarm_control_panel::AlarmControlPanel *>(entity);
|
||||||
}
|
|
||||||
bool APIConnection::try_send_alarm_control_panel_state_(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
|
|
||||||
AlarmControlPanelStateResponse resp;
|
AlarmControlPanelStateResponse resp;
|
||||||
resp.state = static_cast<enums::AlarmControlPanelState>(a_alarm_control_panel->get_state());
|
resp.state = static_cast<enums::AlarmControlPanelState>(a_alarm_control_panel->get_state());
|
||||||
|
|
||||||
resp.key = a_alarm_control_panel->get_object_id_hash();
|
resp.key = a_alarm_control_panel->get_object_id_hash();
|
||||||
return this->send_alarm_control_panel_state_response(resp);
|
return encode_message_to_buffer(resp, AlarmControlPanelStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_alarm_control_panel_info_(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
|
void APIConnection::send_alarm_control_panel_info(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
|
||||||
|
this->schedule_message_(a_alarm_control_panel, &APIConnection::try_send_alarm_control_panel_info,
|
||||||
|
ListEntitiesAlarmControlPanelResponse::MESSAGE_TYPE);
|
||||||
|
}
|
||||||
|
uint16_t APIConnection::try_send_alarm_control_panel_info(EntityBase *entity, APIConnection *conn,
|
||||||
|
uint32_t remaining_size, bool is_single) {
|
||||||
|
auto *a_alarm_control_panel = static_cast<alarm_control_panel::AlarmControlPanel *>(entity);
|
||||||
ListEntitiesAlarmControlPanelResponse msg;
|
ListEntitiesAlarmControlPanelResponse msg;
|
||||||
msg.supported_features = a_alarm_control_panel->get_supported_features();
|
msg.supported_features = a_alarm_control_panel->get_supported_features();
|
||||||
msg.requires_code = a_alarm_control_panel->get_requires_code();
|
msg.requires_code = a_alarm_control_panel->get_requires_code();
|
||||||
msg.requires_code_to_arm = a_alarm_control_panel->get_requires_code_to_arm();
|
msg.requires_code_to_arm = a_alarm_control_panel->get_requires_code_to_arm();
|
||||||
msg.unique_id = get_default_unique_id("alarm_control_panel", a_alarm_control_panel);
|
msg.unique_id = get_default_unique_id("alarm_control_panel", a_alarm_control_panel);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(a_alarm_control_panel), msg,
|
fill_entity_info_base(a_alarm_control_panel, msg);
|
||||||
&APIConnection::send_list_entities_alarm_control_panel_response);
|
return encode_message_to_buffer(msg, ListEntitiesAlarmControlPanelResponse::MESSAGE_TYPE, conn, remaining_size,
|
||||||
|
is_single);
|
||||||
}
|
}
|
||||||
void APIConnection::alarm_control_panel_command(const AlarmControlPanelCommandRequest &msg) {
|
void APIConnection::alarm_control_panel_command(const AlarmControlPanelCommandRequest &msg) {
|
||||||
alarm_control_panel::AlarmControlPanel *a_alarm_control_panel = App.get_alarm_control_panel_by_key(msg.key);
|
alarm_control_panel::AlarmControlPanel *a_alarm_control_panel = App.get_alarm_control_panel_by_key(msg.key);
|
||||||
@ -1395,45 +1413,40 @@ void APIConnection::alarm_control_panel_command(const AlarmControlPanelCommandRe
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_EVENT
|
#ifdef USE_EVENT
|
||||||
void APIConnection::send_event(event::Event *event, std::string event_type) {
|
void APIConnection::send_event(event::Event *event, const std::string &event_type) {
|
||||||
this->send_state_with_value_(event, &APIConnection::try_send_event_, &APIConnection::try_send_event_,
|
this->schedule_message_(event, MessageCreator(event_type, EventResponse::MESSAGE_TYPE), EventResponse::MESSAGE_TYPE);
|
||||||
std::move(event_type));
|
|
||||||
}
|
}
|
||||||
void APIConnection::send_event_info(event::Event *event) {
|
void APIConnection::send_event_info(event::Event *event) {
|
||||||
this->send_info_(static_cast<EntityBase *>(event),
|
this->schedule_message_(event, &APIConnection::try_send_event_info, ListEntitiesEventResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_event_info_));
|
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_event_(event::Event *event) {
|
uint16_t APIConnection::try_send_event_response(event::Event *event, const std::string &event_type, APIConnection *conn,
|
||||||
return this->try_send_event_(event, *(event->last_event_type));
|
uint32_t remaining_size, bool is_single) {
|
||||||
}
|
|
||||||
bool APIConnection::try_send_event_(event::Event *event, std::string event_type) {
|
|
||||||
EventResponse resp;
|
EventResponse resp;
|
||||||
resp.event_type = std::move(event_type);
|
resp.event_type = event_type;
|
||||||
|
|
||||||
resp.key = event->get_object_id_hash();
|
resp.key = event->get_object_id_hash();
|
||||||
return this->send_event_response(resp);
|
return encode_message_to_buffer(resp, EventResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_event_info_(event::Event *event) {
|
|
||||||
|
uint16_t APIConnection::try_send_event_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *event = static_cast<event::Event *>(entity);
|
||||||
ListEntitiesEventResponse msg;
|
ListEntitiesEventResponse msg;
|
||||||
msg.device_class = event->get_device_class();
|
msg.device_class = event->get_device_class();
|
||||||
for (const auto &event_type : event->get_event_types())
|
for (const auto &event_type : event->get_event_types())
|
||||||
msg.event_types.push_back(event_type);
|
msg.event_types.push_back(event_type);
|
||||||
msg.unique_id = get_default_unique_id("event", event);
|
msg.unique_id = get_default_unique_id("event", event);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(event), msg,
|
fill_entity_info_base(event, msg);
|
||||||
&APIConnection::send_list_entities_event_response);
|
return encode_message_to_buffer(msg, ListEntitiesEventResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_UPDATE
|
#ifdef USE_UPDATE
|
||||||
bool APIConnection::send_update_state(update::UpdateEntity *update) {
|
bool APIConnection::send_update_state(update::UpdateEntity *update) {
|
||||||
return this->send_state_(static_cast<EntityBase *>(update),
|
return this->schedule_message_(update, &APIConnection::try_send_update_state, UpdateStateResponse::MESSAGE_TYPE);
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_update_state_));
|
|
||||||
}
|
}
|
||||||
void APIConnection::send_update_info(update::UpdateEntity *update) {
|
uint16_t APIConnection::try_send_update_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
this->send_info_(static_cast<EntityBase *>(update),
|
bool is_single) {
|
||||||
reinterpret_cast<send_message_t>(&APIConnection::try_send_update_info_));
|
auto *update = static_cast<update::UpdateEntity *>(entity);
|
||||||
}
|
|
||||||
bool APIConnection::try_send_update_state_(update::UpdateEntity *update) {
|
|
||||||
UpdateStateResponse resp;
|
UpdateStateResponse resp;
|
||||||
resp.missing_state = !update->has_state();
|
resp.missing_state = !update->has_state();
|
||||||
if (update->has_state()) {
|
if (update->has_state()) {
|
||||||
@ -1448,16 +1461,20 @@ bool APIConnection::try_send_update_state_(update::UpdateEntity *update) {
|
|||||||
resp.release_summary = update->update_info.summary;
|
resp.release_summary = update->update_info.summary;
|
||||||
resp.release_url = update->update_info.release_url;
|
resp.release_url = update->update_info.release_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.key = update->get_object_id_hash();
|
resp.key = update->get_object_id_hash();
|
||||||
return this->send_update_state_response(resp);
|
return encode_message_to_buffer(resp, UpdateStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
bool APIConnection::try_send_update_info_(update::UpdateEntity *update) {
|
void APIConnection::send_update_info(update::UpdateEntity *update) {
|
||||||
|
this->schedule_message_(update, &APIConnection::try_send_update_info, ListEntitiesUpdateResponse::MESSAGE_TYPE);
|
||||||
|
}
|
||||||
|
uint16_t APIConnection::try_send_update_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
auto *update = static_cast<update::UpdateEntity *>(entity);
|
||||||
ListEntitiesUpdateResponse msg;
|
ListEntitiesUpdateResponse msg;
|
||||||
msg.device_class = update->get_device_class();
|
msg.device_class = update->get_device_class();
|
||||||
msg.unique_id = get_default_unique_id("update", update);
|
msg.unique_id = get_default_unique_id("update", update);
|
||||||
return this->try_send_entity_info_(static_cast<EntityBase *>(update), msg,
|
fill_entity_info_base(update, msg);
|
||||||
&APIConnection::send_list_entities_update_response);
|
return encode_message_to_buffer(msg, ListEntitiesUpdateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
void APIConnection::update_command(const UpdateCommandRequest &msg) {
|
void APIConnection::update_command(const UpdateCommandRequest &msg) {
|
||||||
update::UpdateEntity *update = App.get_update_by_key(msg.key);
|
update::UpdateEntity *update = App.get_update_by_key(msg.key);
|
||||||
@ -1651,7 +1668,7 @@ bool APIConnection::try_to_clear_buffer(bool log_out_of_space) {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint32_t message_type) {
|
bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint16_t message_type) {
|
||||||
if (!this->try_to_clear_buffer(message_type != 29)) { // SubscribeLogsResponse
|
if (!this->try_to_clear_buffer(message_type != 29)) { // SubscribeLogsResponse
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1685,6 +1702,331 @@ void APIConnection::on_fatal_error() {
|
|||||||
this->remove_ = true;
|
this->remove_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void APIConnection::DeferredBatch::add_item(EntityBase *entity, MessageCreator creator, uint16_t message_type) {
|
||||||
|
// Check if we already have a message of this type for this entity
|
||||||
|
// This provides deduplication per entity/message_type combination
|
||||||
|
// O(n) but optimized for RAM and not performance.
|
||||||
|
for (auto &item : items) {
|
||||||
|
if (item.entity == entity && item.message_type == message_type) {
|
||||||
|
// Update the existing item with the new creator
|
||||||
|
item.creator = std::move(creator);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No existing item found, add new one
|
||||||
|
items.emplace_back(entity, std::move(creator), message_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool APIConnection::schedule_batch_() {
|
||||||
|
if (!this->deferred_batch_.batch_scheduled) {
|
||||||
|
this->deferred_batch_.batch_scheduled = true;
|
||||||
|
this->deferred_batch_.batch_start_time = App.get_loop_component_start_time();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProtoWriteBuffer APIConnection::allocate_single_message_buffer(uint16_t size) { return this->create_buffer(size); }
|
||||||
|
|
||||||
|
ProtoWriteBuffer APIConnection::allocate_batch_message_buffer(uint16_t size) {
|
||||||
|
ProtoWriteBuffer result = this->prepare_message_buffer(size, this->batch_first_message_);
|
||||||
|
this->batch_first_message_ = false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void APIConnection::process_batch_() {
|
||||||
|
if (this->deferred_batch_.empty()) {
|
||||||
|
this->deferred_batch_.batch_scheduled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to clear buffer first
|
||||||
|
if (!this->try_to_clear_buffer(true)) {
|
||||||
|
// Can't write now, we'll try again later
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t num_items = this->deferred_batch_.items.size();
|
||||||
|
|
||||||
|
// Fast path for single message - allocate exact size needed
|
||||||
|
if (num_items == 1) {
|
||||||
|
const auto &item = this->deferred_batch_.items[0];
|
||||||
|
|
||||||
|
// Let the creator calculate size and encode if it fits
|
||||||
|
uint16_t payload_size = item.creator(item.entity, this, std::numeric_limits<uint16_t>::max(), true);
|
||||||
|
|
||||||
|
if (payload_size > 0 &&
|
||||||
|
this->send_buffer(ProtoWriteBuffer{&this->parent_->get_shared_buffer_ref()}, item.message_type)) {
|
||||||
|
this->deferred_batch_.clear();
|
||||||
|
} else if (payload_size == 0) {
|
||||||
|
// Message too large
|
||||||
|
ESP_LOGW(TAG, "Message too large to send: type=%u", item.message_type);
|
||||||
|
this->deferred_batch_.clear();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pre-allocate storage for packet info
|
||||||
|
std::vector<PacketInfo> packet_info;
|
||||||
|
packet_info.reserve(num_items);
|
||||||
|
|
||||||
|
// Cache these values to avoid repeated virtual calls
|
||||||
|
const uint8_t header_padding = this->helper_->frame_header_padding();
|
||||||
|
const uint8_t footer_size = this->helper_->frame_footer_size();
|
||||||
|
|
||||||
|
// Initialize buffer and tracking variables
|
||||||
|
this->parent_->get_shared_buffer_ref().clear();
|
||||||
|
|
||||||
|
// Pre-calculate exact buffer size needed based on message types
|
||||||
|
uint32_t total_estimated_size = 0;
|
||||||
|
for (const auto &item : this->deferred_batch_.items) {
|
||||||
|
total_estimated_size += get_estimated_message_size(item.message_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate total overhead for all messages
|
||||||
|
uint32_t total_overhead = (header_padding + footer_size) * num_items;
|
||||||
|
|
||||||
|
// Reserve based on estimated size (much more accurate than 24-byte worst-case)
|
||||||
|
this->parent_->get_shared_buffer_ref().reserve(total_estimated_size + total_overhead);
|
||||||
|
this->batch_first_message_ = true;
|
||||||
|
|
||||||
|
size_t items_processed = 0;
|
||||||
|
uint32_t remaining_size = MAX_PACKET_SIZE;
|
||||||
|
|
||||||
|
// Track where each message's header padding begins in the buffer
|
||||||
|
// For plaintext: this is where the 6-byte header padding starts
|
||||||
|
// For noise: this is where the 7-byte header padding starts
|
||||||
|
// The actual message data follows after the header padding
|
||||||
|
uint32_t current_offset = 0;
|
||||||
|
|
||||||
|
// Process items and encode directly to buffer
|
||||||
|
for (const auto &item : this->deferred_batch_.items) {
|
||||||
|
// Try to encode message
|
||||||
|
// The creator will calculate overhead to determine if the message fits
|
||||||
|
uint16_t payload_size = item.creator(item.entity, this, remaining_size, false);
|
||||||
|
|
||||||
|
if (payload_size == 0) {
|
||||||
|
// Message won't fit, stop processing
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message was encoded successfully
|
||||||
|
// payload_size is header_padding + actual payload size + footer_size
|
||||||
|
uint16_t proto_payload_size = payload_size - header_padding - footer_size;
|
||||||
|
packet_info.emplace_back(item.message_type, current_offset, proto_payload_size);
|
||||||
|
|
||||||
|
// Update tracking variables
|
||||||
|
remaining_size -= payload_size;
|
||||||
|
// Calculate where the next message's header padding will start
|
||||||
|
// Current buffer size + footer space (that prepare_message_buffer will add for this message)
|
||||||
|
current_offset = this->parent_->get_shared_buffer_ref().size() + footer_size;
|
||||||
|
items_processed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (items_processed == 0) {
|
||||||
|
this->deferred_batch_.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add footer space for the last message (for Noise protocol MAC)
|
||||||
|
if (footer_size > 0) {
|
||||||
|
auto &shared_buf = this->parent_->get_shared_buffer_ref();
|
||||||
|
shared_buf.resize(shared_buf.size() + footer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send all collected packets
|
||||||
|
APIError err =
|
||||||
|
this->helper_->write_protobuf_packets(ProtoWriteBuffer{&this->parent_->get_shared_buffer_ref()}, packet_info);
|
||||||
|
if (err != APIError::OK && err != APIError::WOULD_BLOCK) {
|
||||||
|
on_fatal_error();
|
||||||
|
if (err == APIError::SOCKET_WRITE_FAILED && errno == ECONNRESET) {
|
||||||
|
ESP_LOGW(TAG, "%s: Connection reset during batch write", this->client_combined_info_.c_str());
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "%s: Batch write failed %s errno=%d", this->client_combined_info_.c_str(), api_error_to_str(err),
|
||||||
|
errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle remaining items more efficiently
|
||||||
|
if (items_processed < this->deferred_batch_.items.size()) {
|
||||||
|
// Remove processed items from the beginning
|
||||||
|
this->deferred_batch_.items.erase(this->deferred_batch_.items.begin(),
|
||||||
|
this->deferred_batch_.items.begin() + items_processed);
|
||||||
|
|
||||||
|
// Reschedule for remaining items
|
||||||
|
this->schedule_batch_();
|
||||||
|
} else {
|
||||||
|
// All items processed
|
||||||
|
this->deferred_batch_.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t APIConnection::MessageCreator::operator()(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) const {
|
||||||
|
switch (message_type_) {
|
||||||
|
case 0: // Function pointer
|
||||||
|
return data_.ptr(entity, conn, remaining_size, is_single);
|
||||||
|
|
||||||
|
#ifdef USE_EVENT
|
||||||
|
case EventResponse::MESSAGE_TYPE: {
|
||||||
|
auto *e = static_cast<event::Event *>(entity);
|
||||||
|
return APIConnection::try_send_event_response(e, *data_.string_ptr, conn, remaining_size, is_single);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Should not happen, return 0 to indicate no message
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t APIConnection::try_send_list_info_done(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
ListEntitiesDoneResponse resp;
|
||||||
|
return encode_message_to_buffer(resp, ListEntitiesDoneResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t APIConnection::get_estimated_message_size(uint16_t message_type) {
|
||||||
|
// Use generated ESTIMATED_SIZE constants from each message type
|
||||||
|
switch (message_type) {
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
case BinarySensorStateResponse::MESSAGE_TYPE:
|
||||||
|
return BinarySensorStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesBinarySensorResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesBinarySensorResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
case SensorStateResponse::MESSAGE_TYPE:
|
||||||
|
return SensorStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesSensorResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesSensorResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SWITCH
|
||||||
|
case SwitchStateResponse::MESSAGE_TYPE:
|
||||||
|
return SwitchStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesSwitchResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesSwitchResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TEXT_SENSOR
|
||||||
|
case TextSensorStateResponse::MESSAGE_TYPE:
|
||||||
|
return TextSensorStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesTextSensorResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesTextSensorResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_NUMBER
|
||||||
|
case NumberStateResponse::MESSAGE_TYPE:
|
||||||
|
return NumberStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesNumberResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesNumberResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TEXT
|
||||||
|
case TextStateResponse::MESSAGE_TYPE:
|
||||||
|
return TextStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesTextResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesTextResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SELECT
|
||||||
|
case SelectStateResponse::MESSAGE_TYPE:
|
||||||
|
return SelectStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesSelectResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesSelectResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_LOCK
|
||||||
|
case LockStateResponse::MESSAGE_TYPE:
|
||||||
|
return LockStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesLockResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesLockResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_EVENT
|
||||||
|
case EventResponse::MESSAGE_TYPE:
|
||||||
|
return EventResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesEventResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesEventResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_COVER
|
||||||
|
case CoverStateResponse::MESSAGE_TYPE:
|
||||||
|
return CoverStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesCoverResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesCoverResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_FAN
|
||||||
|
case FanStateResponse::MESSAGE_TYPE:
|
||||||
|
return FanStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesFanResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesFanResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_LIGHT
|
||||||
|
case LightStateResponse::MESSAGE_TYPE:
|
||||||
|
return LightStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesLightResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesLightResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_CLIMATE
|
||||||
|
case ClimateStateResponse::MESSAGE_TYPE:
|
||||||
|
return ClimateStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesClimateResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesClimateResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_ESP32_CAMERA
|
||||||
|
case ListEntitiesCameraResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesCameraResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
case ListEntitiesButtonResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesButtonResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_MEDIA_PLAYER
|
||||||
|
case MediaPlayerStateResponse::MESSAGE_TYPE:
|
||||||
|
return MediaPlayerStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesMediaPlayerResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesMediaPlayerResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_ALARM_CONTROL_PANEL
|
||||||
|
case AlarmControlPanelStateResponse::MESSAGE_TYPE:
|
||||||
|
return AlarmControlPanelStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesAlarmControlPanelResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesAlarmControlPanelResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_DATETIME_DATE
|
||||||
|
case DateStateResponse::MESSAGE_TYPE:
|
||||||
|
return DateStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesDateResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesDateResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_DATETIME_TIME
|
||||||
|
case TimeStateResponse::MESSAGE_TYPE:
|
||||||
|
return TimeStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesTimeResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesTimeResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_DATETIME_DATETIME
|
||||||
|
case DateTimeStateResponse::MESSAGE_TYPE:
|
||||||
|
return DateTimeStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesDateTimeResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesDateTimeResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_VALVE
|
||||||
|
case ValveStateResponse::MESSAGE_TYPE:
|
||||||
|
return ValveStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesValveResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesValveResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_UPDATE
|
||||||
|
case UpdateStateResponse::MESSAGE_TYPE:
|
||||||
|
return UpdateStateResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesUpdateResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesUpdateResponse::ESTIMATED_SIZE;
|
||||||
|
#endif
|
||||||
|
case ListEntitiesServicesResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesServicesResponse::ESTIMATED_SIZE;
|
||||||
|
case ListEntitiesDoneResponse::MESSAGE_TYPE:
|
||||||
|
return ListEntitiesDoneResponse::ESTIMATED_SIZE;
|
||||||
|
default:
|
||||||
|
// Fallback for unknown message types
|
||||||
|
return 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
#endif
|
#endif
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "esphome/core/entity_base.h"
|
#include "esphome/core/entity_base.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace api {
|
namespace api {
|
||||||
@ -18,49 +19,9 @@ namespace api {
|
|||||||
// Keepalive timeout in milliseconds
|
// Keepalive timeout in milliseconds
|
||||||
static constexpr uint32_t KEEPALIVE_TIMEOUT_MS = 60000;
|
static constexpr uint32_t KEEPALIVE_TIMEOUT_MS = 60000;
|
||||||
|
|
||||||
using send_message_t = bool (APIConnection::*)(void *);
|
|
||||||
|
|
||||||
/*
|
|
||||||
This class holds a pointer to the source component that wants to publish a message, and a pointer to a function that
|
|
||||||
will lazily publish that message. The two pointers allow dedup in the deferred queue if multiple publishes for the
|
|
||||||
same component are backed up, and take up only 8 bytes of memory. The entry in the deferred queue (a std::vector) is
|
|
||||||
the DeferredMessage instance itself (not a pointer to one elsewhere in heap) so still only 8 bytes per entry. Even
|
|
||||||
100 backed up messages (you'd have to have at least 100 sensors publishing because of dedup) would take up only 0.8
|
|
||||||
kB.
|
|
||||||
*/
|
|
||||||
class DeferredMessageQueue {
|
|
||||||
struct DeferredMessage {
|
|
||||||
friend class DeferredMessageQueue;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void *source_;
|
|
||||||
send_message_t send_message_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
DeferredMessage(void *source, send_message_t send_message) : source_(source), send_message_(send_message) {}
|
|
||||||
bool operator==(const DeferredMessage &test) const {
|
|
||||||
return (source_ == test.source_ && send_message_ == test.send_message_);
|
|
||||||
}
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// vector is used very specifically for its zero memory overhead even though items are popped from the front (memory
|
|
||||||
// footprint is more important than speed here)
|
|
||||||
std::vector<DeferredMessage> deferred_queue_;
|
|
||||||
APIConnection *api_connection_;
|
|
||||||
|
|
||||||
// helper for allowing only unique entries in the queue
|
|
||||||
void dmq_push_back_with_dedup_(void *source, send_message_t send_message);
|
|
||||||
|
|
||||||
public:
|
|
||||||
DeferredMessageQueue(APIConnection *api_connection) : api_connection_(api_connection) {}
|
|
||||||
void process_queue();
|
|
||||||
void defer(void *source, send_message_t send_message);
|
|
||||||
bool empty() const { return deferred_queue_.empty(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class APIConnection : public APIServerConnection {
|
class APIConnection : public APIServerConnection {
|
||||||
public:
|
public:
|
||||||
|
friend class APIServer;
|
||||||
APIConnection(std::unique_ptr<socket::Socket> socket, APIServer *parent);
|
APIConnection(std::unique_ptr<socket::Socket> socket, APIServer *parent);
|
||||||
virtual ~APIConnection();
|
virtual ~APIConnection();
|
||||||
|
|
||||||
@ -68,225 +29,105 @@ class APIConnection : public APIServerConnection {
|
|||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
bool send_list_info_done() {
|
bool send_list_info_done() {
|
||||||
ListEntitiesDoneResponse resp;
|
return this->schedule_message_(nullptr, &APIConnection::try_send_list_info_done,
|
||||||
return this->send_list_entities_done_response(resp);
|
ListEntitiesDoneResponse::MESSAGE_TYPE);
|
||||||
}
|
}
|
||||||
#ifdef USE_BINARY_SENSOR
|
#ifdef USE_BINARY_SENSOR
|
||||||
bool send_binary_sensor_state(binary_sensor::BinarySensor *binary_sensor, bool state);
|
bool send_binary_sensor_state(binary_sensor::BinarySensor *binary_sensor);
|
||||||
void send_binary_sensor_info(binary_sensor::BinarySensor *binary_sensor);
|
void send_binary_sensor_info(binary_sensor::BinarySensor *binary_sensor);
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_binary_sensor_state_(binary_sensor::BinarySensor *binary_sensor);
|
|
||||||
bool try_send_binary_sensor_state_(binary_sensor::BinarySensor *binary_sensor, bool state);
|
|
||||||
bool try_send_binary_sensor_info_(binary_sensor::BinarySensor *binary_sensor);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_COVER
|
#ifdef USE_COVER
|
||||||
bool send_cover_state(cover::Cover *cover);
|
bool send_cover_state(cover::Cover *cover);
|
||||||
void send_cover_info(cover::Cover *cover);
|
void send_cover_info(cover::Cover *cover);
|
||||||
void cover_command(const CoverCommandRequest &msg) override;
|
void cover_command(const CoverCommandRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_cover_state_(cover::Cover *cover);
|
|
||||||
bool try_send_cover_info_(cover::Cover *cover);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_FAN
|
#ifdef USE_FAN
|
||||||
bool send_fan_state(fan::Fan *fan);
|
bool send_fan_state(fan::Fan *fan);
|
||||||
void send_fan_info(fan::Fan *fan);
|
void send_fan_info(fan::Fan *fan);
|
||||||
void fan_command(const FanCommandRequest &msg) override;
|
void fan_command(const FanCommandRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_fan_state_(fan::Fan *fan);
|
|
||||||
bool try_send_fan_info_(fan::Fan *fan);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_LIGHT
|
#ifdef USE_LIGHT
|
||||||
bool send_light_state(light::LightState *light);
|
bool send_light_state(light::LightState *light);
|
||||||
void send_light_info(light::LightState *light);
|
void send_light_info(light::LightState *light);
|
||||||
void light_command(const LightCommandRequest &msg) override;
|
void light_command(const LightCommandRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_light_state_(light::LightState *light);
|
|
||||||
bool try_send_light_info_(light::LightState *light);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
bool send_sensor_state(sensor::Sensor *sensor, float state);
|
bool send_sensor_state(sensor::Sensor *sensor);
|
||||||
void send_sensor_info(sensor::Sensor *sensor);
|
void send_sensor_info(sensor::Sensor *sensor);
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_sensor_state_(sensor::Sensor *sensor);
|
|
||||||
bool try_send_sensor_state_(sensor::Sensor *sensor, float state);
|
|
||||||
bool try_send_sensor_info_(sensor::Sensor *sensor);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_SWITCH
|
#ifdef USE_SWITCH
|
||||||
bool send_switch_state(switch_::Switch *a_switch, bool state);
|
bool send_switch_state(switch_::Switch *a_switch);
|
||||||
void send_switch_info(switch_::Switch *a_switch);
|
void send_switch_info(switch_::Switch *a_switch);
|
||||||
void switch_command(const SwitchCommandRequest &msg) override;
|
void switch_command(const SwitchCommandRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_switch_state_(switch_::Switch *a_switch);
|
|
||||||
bool try_send_switch_state_(switch_::Switch *a_switch, bool state);
|
|
||||||
bool try_send_switch_info_(switch_::Switch *a_switch);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_TEXT_SENSOR
|
#ifdef USE_TEXT_SENSOR
|
||||||
bool send_text_sensor_state(text_sensor::TextSensor *text_sensor, std::string state);
|
bool send_text_sensor_state(text_sensor::TextSensor *text_sensor);
|
||||||
void send_text_sensor_info(text_sensor::TextSensor *text_sensor);
|
void send_text_sensor_info(text_sensor::TextSensor *text_sensor);
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_text_sensor_state_(text_sensor::TextSensor *text_sensor);
|
|
||||||
bool try_send_text_sensor_state_(text_sensor::TextSensor *text_sensor, std::string state);
|
|
||||||
bool try_send_text_sensor_info_(text_sensor::TextSensor *text_sensor);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_ESP32_CAMERA
|
#ifdef USE_ESP32_CAMERA
|
||||||
void set_camera_state(std::shared_ptr<esp32_camera::CameraImage> image);
|
void set_camera_state(std::shared_ptr<esp32_camera::CameraImage> image);
|
||||||
void send_camera_info(esp32_camera::ESP32Camera *camera);
|
void send_camera_info(esp32_camera::ESP32Camera *camera);
|
||||||
void camera_image(const CameraImageRequest &msg) override;
|
void camera_image(const CameraImageRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_camera_info_(esp32_camera::ESP32Camera *camera);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_CLIMATE
|
#ifdef USE_CLIMATE
|
||||||
bool send_climate_state(climate::Climate *climate);
|
bool send_climate_state(climate::Climate *climate);
|
||||||
void send_climate_info(climate::Climate *climate);
|
void send_climate_info(climate::Climate *climate);
|
||||||
void climate_command(const ClimateCommandRequest &msg) override;
|
void climate_command(const ClimateCommandRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_climate_state_(climate::Climate *climate);
|
|
||||||
bool try_send_climate_info_(climate::Climate *climate);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_NUMBER
|
#ifdef USE_NUMBER
|
||||||
bool send_number_state(number::Number *number, float state);
|
bool send_number_state(number::Number *number);
|
||||||
void send_number_info(number::Number *number);
|
void send_number_info(number::Number *number);
|
||||||
void number_command(const NumberCommandRequest &msg) override;
|
void number_command(const NumberCommandRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_number_state_(number::Number *number);
|
|
||||||
bool try_send_number_state_(number::Number *number, float state);
|
|
||||||
bool try_send_number_info_(number::Number *number);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_DATETIME_DATE
|
#ifdef USE_DATETIME_DATE
|
||||||
bool send_date_state(datetime::DateEntity *date);
|
bool send_date_state(datetime::DateEntity *date);
|
||||||
void send_date_info(datetime::DateEntity *date);
|
void send_date_info(datetime::DateEntity *date);
|
||||||
void date_command(const DateCommandRequest &msg) override;
|
void date_command(const DateCommandRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_date_state_(datetime::DateEntity *date);
|
|
||||||
bool try_send_date_info_(datetime::DateEntity *date);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_DATETIME_TIME
|
#ifdef USE_DATETIME_TIME
|
||||||
bool send_time_state(datetime::TimeEntity *time);
|
bool send_time_state(datetime::TimeEntity *time);
|
||||||
void send_time_info(datetime::TimeEntity *time);
|
void send_time_info(datetime::TimeEntity *time);
|
||||||
void time_command(const TimeCommandRequest &msg) override;
|
void time_command(const TimeCommandRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_time_state_(datetime::TimeEntity *time);
|
|
||||||
bool try_send_time_info_(datetime::TimeEntity *time);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_DATETIME_DATETIME
|
#ifdef USE_DATETIME_DATETIME
|
||||||
bool send_datetime_state(datetime::DateTimeEntity *datetime);
|
bool send_datetime_state(datetime::DateTimeEntity *datetime);
|
||||||
void send_datetime_info(datetime::DateTimeEntity *datetime);
|
void send_datetime_info(datetime::DateTimeEntity *datetime);
|
||||||
void datetime_command(const DateTimeCommandRequest &msg) override;
|
void datetime_command(const DateTimeCommandRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_datetime_state_(datetime::DateTimeEntity *datetime);
|
|
||||||
bool try_send_datetime_info_(datetime::DateTimeEntity *datetime);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_TEXT
|
#ifdef USE_TEXT
|
||||||
bool send_text_state(text::Text *text, std::string state);
|
bool send_text_state(text::Text *text);
|
||||||
void send_text_info(text::Text *text);
|
void send_text_info(text::Text *text);
|
||||||
void text_command(const TextCommandRequest &msg) override;
|
void text_command(const TextCommandRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_text_state_(text::Text *text);
|
|
||||||
bool try_send_text_state_(text::Text *text, std::string state);
|
|
||||||
bool try_send_text_info_(text::Text *text);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_SELECT
|
#ifdef USE_SELECT
|
||||||
bool send_select_state(select::Select *select, std::string state);
|
bool send_select_state(select::Select *select);
|
||||||
void send_select_info(select::Select *select);
|
void send_select_info(select::Select *select);
|
||||||
void select_command(const SelectCommandRequest &msg) override;
|
void select_command(const SelectCommandRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_select_state_(select::Select *select);
|
|
||||||
bool try_send_select_state_(select::Select *select, std::string state);
|
|
||||||
bool try_send_select_info_(select::Select *select);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_BUTTON
|
#ifdef USE_BUTTON
|
||||||
void send_button_info(button::Button *button);
|
void send_button_info(button::Button *button);
|
||||||
void button_command(const ButtonCommandRequest &msg) override;
|
void button_command(const ButtonCommandRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_button_info_(button::Button *button);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_LOCK
|
#ifdef USE_LOCK
|
||||||
bool send_lock_state(lock::Lock *a_lock, lock::LockState state);
|
bool send_lock_state(lock::Lock *a_lock);
|
||||||
void send_lock_info(lock::Lock *a_lock);
|
void send_lock_info(lock::Lock *a_lock);
|
||||||
void lock_command(const LockCommandRequest &msg) override;
|
void lock_command(const LockCommandRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_lock_state_(lock::Lock *a_lock);
|
|
||||||
bool try_send_lock_state_(lock::Lock *a_lock, lock::LockState state);
|
|
||||||
bool try_send_lock_info_(lock::Lock *a_lock);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_VALVE
|
#ifdef USE_VALVE
|
||||||
bool send_valve_state(valve::Valve *valve);
|
bool send_valve_state(valve::Valve *valve);
|
||||||
void send_valve_info(valve::Valve *valve);
|
void send_valve_info(valve::Valve *valve);
|
||||||
void valve_command(const ValveCommandRequest &msg) override;
|
void valve_command(const ValveCommandRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_valve_state_(valve::Valve *valve);
|
|
||||||
bool try_send_valve_info_(valve::Valve *valve);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_MEDIA_PLAYER
|
#ifdef USE_MEDIA_PLAYER
|
||||||
bool send_media_player_state(media_player::MediaPlayer *media_player);
|
bool send_media_player_state(media_player::MediaPlayer *media_player);
|
||||||
void send_media_player_info(media_player::MediaPlayer *media_player);
|
void send_media_player_info(media_player::MediaPlayer *media_player);
|
||||||
void media_player_command(const MediaPlayerCommandRequest &msg) override;
|
void media_player_command(const MediaPlayerCommandRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_media_player_state_(media_player::MediaPlayer *media_player);
|
|
||||||
bool try_send_media_player_info_(media_player::MediaPlayer *media_player);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
bool try_send_log_message(int level, const char *tag, const char *line);
|
bool try_send_log_message(int level, const char *tag, const char *line);
|
||||||
void send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
|
void send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
|
||||||
if (!this->service_call_subscription_)
|
if (!this->service_call_subscription_)
|
||||||
return;
|
return;
|
||||||
this->send_homeassistant_service_response(call);
|
this->send_message(call);
|
||||||
}
|
}
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) override;
|
void subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) override;
|
||||||
@ -308,7 +149,7 @@ class APIConnection : public APIServerConnection {
|
|||||||
#ifdef USE_HOMEASSISTANT_TIME
|
#ifdef USE_HOMEASSISTANT_TIME
|
||||||
void send_time_request() {
|
void send_time_request() {
|
||||||
GetTimeRequest req;
|
GetTimeRequest req;
|
||||||
this->send_get_time_request(req);
|
this->send_message(req);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -328,36 +169,17 @@ class APIConnection : public APIServerConnection {
|
|||||||
bool send_alarm_control_panel_state(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
|
bool send_alarm_control_panel_state(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
|
||||||
void send_alarm_control_panel_info(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
|
void send_alarm_control_panel_info(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
|
||||||
void alarm_control_panel_command(const AlarmControlPanelCommandRequest &msg) override;
|
void alarm_control_panel_command(const AlarmControlPanelCommandRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_alarm_control_panel_state_(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
|
|
||||||
bool try_send_alarm_control_panel_info_(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_EVENT
|
#ifdef USE_EVENT
|
||||||
void send_event(event::Event *event, std::string event_type);
|
void send_event(event::Event *event, const std::string &event_type);
|
||||||
void send_event_info(event::Event *event);
|
void send_event_info(event::Event *event);
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_event_(event::Event *event);
|
|
||||||
bool try_send_event_(event::Event *event, std::string event_type);
|
|
||||||
bool try_send_event_info_(event::Event *event);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_UPDATE
|
#ifdef USE_UPDATE
|
||||||
bool send_update_state(update::UpdateEntity *update);
|
bool send_update_state(update::UpdateEntity *update);
|
||||||
void send_update_info(update::UpdateEntity *update);
|
void send_update_info(update::UpdateEntity *update);
|
||||||
void update_command(const UpdateCommandRequest &msg) override;
|
void update_command(const UpdateCommandRequest &msg) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool try_send_update_state_(update::UpdateEntity *update);
|
|
||||||
bool try_send_update_info_(update::UpdateEntity *update);
|
|
||||||
|
|
||||||
public:
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void on_disconnect_response(const DisconnectResponse &value) override;
|
void on_disconnect_response(const DisconnectResponse &value) override;
|
||||||
@ -407,102 +229,67 @@ class APIConnection : public APIServerConnection {
|
|||||||
void on_no_setup_connection() override;
|
void on_no_setup_connection() override;
|
||||||
ProtoWriteBuffer create_buffer(uint32_t reserve_size) override {
|
ProtoWriteBuffer create_buffer(uint32_t reserve_size) override {
|
||||||
// FIXME: ensure no recursive writes can happen
|
// FIXME: ensure no recursive writes can happen
|
||||||
this->proto_write_buffer_.clear();
|
|
||||||
// Get header padding size - used for both reserve and insert
|
// Get header padding size - used for both reserve and insert
|
||||||
uint8_t header_padding = this->helper_->frame_header_padding();
|
uint8_t header_padding = this->helper_->frame_header_padding();
|
||||||
|
|
||||||
|
// Get shared buffer from parent server
|
||||||
|
std::vector<uint8_t> &shared_buf = this->parent_->get_shared_buffer_ref();
|
||||||
|
shared_buf.clear();
|
||||||
// Reserve space for header padding + message + footer
|
// Reserve space for header padding + message + footer
|
||||||
// - Header padding: space for protocol headers (7 bytes for Noise, 6 for Plaintext)
|
// - Header padding: space for protocol headers (7 bytes for Noise, 6 for Plaintext)
|
||||||
// - Footer: space for MAC (16 bytes for Noise, 0 for Plaintext)
|
// - Footer: space for MAC (16 bytes for Noise, 0 for Plaintext)
|
||||||
this->proto_write_buffer_.reserve(reserve_size + header_padding + this->helper_->frame_footer_size());
|
shared_buf.reserve(reserve_size + header_padding + this->helper_->frame_footer_size());
|
||||||
// Insert header padding bytes so message encoding starts at the correct position
|
// Insert header padding bytes so message encoding starts at the correct position
|
||||||
this->proto_write_buffer_.insert(this->proto_write_buffer_.begin(), header_padding, 0);
|
shared_buf.insert(shared_buf.begin(), header_padding, 0);
|
||||||
return {&this->proto_write_buffer_};
|
return {&shared_buf};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prepare buffer for next message in batch
|
||||||
|
ProtoWriteBuffer prepare_message_buffer(uint16_t message_size, bool is_first_message) {
|
||||||
|
// Get reference to shared buffer (it maintains state between batch messages)
|
||||||
|
std::vector<uint8_t> &shared_buf = this->parent_->get_shared_buffer_ref();
|
||||||
|
size_t current_size = shared_buf.size();
|
||||||
|
|
||||||
|
if (is_first_message) {
|
||||||
|
// For first message, initialize buffer with header padding
|
||||||
|
uint8_t header_padding = this->helper_->frame_header_padding();
|
||||||
|
shared_buf.clear();
|
||||||
|
shared_buf.reserve(message_size + header_padding);
|
||||||
|
shared_buf.resize(header_padding);
|
||||||
|
// Fill header padding with zeros
|
||||||
|
std::fill(shared_buf.begin(), shared_buf.end(), 0);
|
||||||
|
} else {
|
||||||
|
// For subsequent messages, add footer space for previous message and header for this message
|
||||||
|
uint8_t footer_size = this->helper_->frame_footer_size();
|
||||||
|
uint8_t header_padding = this->helper_->frame_header_padding();
|
||||||
|
|
||||||
|
// Reserve additional space for everything
|
||||||
|
shared_buf.reserve(current_size + footer_size + header_padding + message_size);
|
||||||
|
|
||||||
|
// Single resize to add both footer and header padding
|
||||||
|
size_t new_size = current_size + footer_size + header_padding;
|
||||||
|
shared_buf.resize(new_size);
|
||||||
|
|
||||||
|
// Fill the newly added bytes with zeros (footer + header padding)
|
||||||
|
std::fill(shared_buf.begin() + current_size, shared_buf.end(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {&shared_buf};
|
||||||
|
}
|
||||||
|
|
||||||
bool try_to_clear_buffer(bool log_out_of_space);
|
bool try_to_clear_buffer(bool log_out_of_space);
|
||||||
bool send_buffer(ProtoWriteBuffer buffer, uint32_t message_type) override;
|
bool send_buffer(ProtoWriteBuffer buffer, uint16_t message_type) override;
|
||||||
|
|
||||||
std::string get_client_combined_info() const { return this->client_combined_info_; }
|
std::string get_client_combined_info() const { return this->client_combined_info_; }
|
||||||
|
|
||||||
|
// Buffer allocator methods for batch processing
|
||||||
|
ProtoWriteBuffer allocate_single_message_buffer(uint16_t size);
|
||||||
|
ProtoWriteBuffer allocate_batch_message_buffer(uint16_t size);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend APIServer;
|
// Helper function to fill common entity fields
|
||||||
|
template<typename ResponseT> static void fill_entity_info_base(esphome::EntityBase *entity, ResponseT &response) {
|
||||||
/**
|
|
||||||
* Generic send entity state method to reduce code duplication.
|
|
||||||
* Only attempts to build and send the message if the transmit buffer is available.
|
|
||||||
*
|
|
||||||
* This is the base version for entities that use their current state.
|
|
||||||
*
|
|
||||||
* @param entity The entity to send state for
|
|
||||||
* @param try_send_func The function that tries to send the state
|
|
||||||
* @return True on success or message deferred, false if subscription check failed
|
|
||||||
*/
|
|
||||||
bool send_state_(esphome::EntityBase *entity, send_message_t try_send_func) {
|
|
||||||
if (!this->state_subscription_)
|
|
||||||
return false;
|
|
||||||
if (this->try_to_clear_buffer(true) && (this->*try_send_func)(entity)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
this->deferred_message_queue_.defer(entity, try_send_func);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send entity state method that handles explicit state values.
|
|
||||||
* Only attempts to build and send the message if the transmit buffer is available.
|
|
||||||
*
|
|
||||||
* This method accepts a state parameter to be used instead of the entity's current state.
|
|
||||||
* It attempts to send the state with the provided value first, and if that fails due to buffer constraints,
|
|
||||||
* it defers the entity for later processing using the entity-only function.
|
|
||||||
*
|
|
||||||
* @tparam EntityT The entity type
|
|
||||||
* @tparam StateT Type of the state parameter
|
|
||||||
* @tparam Args Additional argument types (if any)
|
|
||||||
* @param entity The entity to send state for
|
|
||||||
* @param try_send_entity_func The function that tries to send the state with entity pointer only
|
|
||||||
* @param try_send_state_func The function that tries to send the state with entity and state parameters
|
|
||||||
* @param state The state value to send
|
|
||||||
* @param args Additional arguments to pass to the try_send_state_func
|
|
||||||
* @return True on success or message deferred, false if subscription check failed
|
|
||||||
*/
|
|
||||||
template<typename EntityT, typename StateT, typename... Args>
|
|
||||||
bool send_state_with_value_(EntityT *entity, bool (APIConnection::*try_send_entity_func)(EntityT *),
|
|
||||||
bool (APIConnection::*try_send_state_func)(EntityT *, StateT, Args...), StateT state,
|
|
||||||
Args... args) {
|
|
||||||
if (!this->state_subscription_)
|
|
||||||
return false;
|
|
||||||
if (this->try_to_clear_buffer(true) && (this->*try_send_state_func)(entity, state, args...)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
this->deferred_message_queue_.defer(entity, reinterpret_cast<send_message_t>(try_send_entity_func));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generic send entity info method to reduce code duplication.
|
|
||||||
* Only attempts to build and send the message if the transmit buffer is available.
|
|
||||||
*
|
|
||||||
* @param entity The entity to send info for
|
|
||||||
* @param try_send_func The function that tries to send the info
|
|
||||||
*/
|
|
||||||
void send_info_(esphome::EntityBase *entity, send_message_t try_send_func) {
|
|
||||||
if (this->try_to_clear_buffer(true) && (this->*try_send_func)(entity)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this->deferred_message_queue_.defer(entity, try_send_func);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generic function for generating entity info response messages.
|
|
||||||
* This is used to reduce duplication in the try_send_*_info functions.
|
|
||||||
*
|
|
||||||
* @param entity The entity to generate info for
|
|
||||||
* @param response The response object
|
|
||||||
* @param send_response_func Function pointer to send the response
|
|
||||||
* @return True if the message was sent successfully
|
|
||||||
*/
|
|
||||||
template<typename ResponseT>
|
|
||||||
bool try_send_entity_info_(esphome::EntityBase *entity, ResponseT &response,
|
|
||||||
bool (APIServerConnectionBase::*send_response_func)(const ResponseT &)) {
|
|
||||||
// Set common fields that are shared by all entity types
|
// Set common fields that are shared by all entity types
|
||||||
response.key = entity->get_object_id_hash();
|
response.key = entity->get_object_id_hash();
|
||||||
response.object_id = entity->get_object_id();
|
response.object_id = entity->get_object_id();
|
||||||
@ -514,12 +301,133 @@ class APIConnection : public APIServerConnection {
|
|||||||
response.icon = entity->get_icon();
|
response.icon = entity->get_icon();
|
||||||
response.disabled_by_default = entity->is_disabled_by_default();
|
response.disabled_by_default = entity->is_disabled_by_default();
|
||||||
response.entity_category = static_cast<enums::EntityCategory>(entity->get_entity_category());
|
response.entity_category = static_cast<enums::EntityCategory>(entity->get_entity_category());
|
||||||
|
|
||||||
// Send the response using the provided send method
|
|
||||||
return (this->*send_response_func)(response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool send_(const void *buf, size_t len, bool force);
|
// Non-template helper to encode any ProtoMessage
|
||||||
|
static uint16_t encode_message_to_buffer(ProtoMessage &msg, uint16_t message_type, APIConnection *conn,
|
||||||
|
uint32_t remaining_size, bool is_single);
|
||||||
|
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
static uint16_t try_send_binary_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
static uint16_t try_send_binary_sensor_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_COVER
|
||||||
|
static uint16_t try_send_cover_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
static uint16_t try_send_cover_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_FAN
|
||||||
|
static uint16_t try_send_fan_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
|
||||||
|
static uint16_t try_send_fan_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_LIGHT
|
||||||
|
static uint16_t try_send_light_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
static uint16_t try_send_light_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
static uint16_t try_send_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
static uint16_t try_send_sensor_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SWITCH
|
||||||
|
static uint16_t try_send_switch_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
static uint16_t try_send_switch_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TEXT_SENSOR
|
||||||
|
static uint16_t try_send_text_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
static uint16_t try_send_text_sensor_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_CLIMATE
|
||||||
|
static uint16_t try_send_climate_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
static uint16_t try_send_climate_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_NUMBER
|
||||||
|
static uint16_t try_send_number_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
static uint16_t try_send_number_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_DATETIME_DATE
|
||||||
|
static uint16_t try_send_date_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
|
||||||
|
static uint16_t try_send_date_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_DATETIME_TIME
|
||||||
|
static uint16_t try_send_time_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
|
||||||
|
static uint16_t try_send_time_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_DATETIME_DATETIME
|
||||||
|
static uint16_t try_send_datetime_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
static uint16_t try_send_datetime_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TEXT
|
||||||
|
static uint16_t try_send_text_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
|
||||||
|
static uint16_t try_send_text_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SELECT
|
||||||
|
static uint16_t try_send_select_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
static uint16_t try_send_select_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_BUTTON
|
||||||
|
static uint16_t try_send_button_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_LOCK
|
||||||
|
static uint16_t try_send_lock_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
|
||||||
|
static uint16_t try_send_lock_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_VALVE
|
||||||
|
static uint16_t try_send_valve_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
static uint16_t try_send_valve_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_MEDIA_PLAYER
|
||||||
|
static uint16_t try_send_media_player_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
static uint16_t try_send_media_player_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_ALARM_CONTROL_PANEL
|
||||||
|
static uint16_t try_send_alarm_control_panel_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
static uint16_t try_send_alarm_control_panel_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_EVENT
|
||||||
|
static uint16_t try_send_event_response(event::Event *event, const std::string &event_type, 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
|
||||||
|
#ifdef USE_UPDATE
|
||||||
|
static uint16_t try_send_update_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
static uint16_t try_send_update_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_ESP32_CAMERA
|
||||||
|
static uint16_t try_send_camera_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Method for ListEntitiesDone batching
|
||||||
|
static uint16_t try_send_list_info_done(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
|
||||||
|
// Helper function to get estimated message size for buffer pre-allocation
|
||||||
|
static uint16_t get_estimated_message_size(uint16_t message_type);
|
||||||
|
|
||||||
enum class ConnectionState {
|
enum class ConnectionState {
|
||||||
WAITING_FOR_HELLO,
|
WAITING_FOR_HELLO,
|
||||||
@ -529,9 +437,6 @@ class APIConnection : public APIServerConnection {
|
|||||||
|
|
||||||
bool remove_{false};
|
bool remove_{false};
|
||||||
|
|
||||||
// Buffer used to encode proto messages
|
|
||||||
// Re-use to prevent allocations
|
|
||||||
std::vector<uint8_t> proto_write_buffer_;
|
|
||||||
std::unique_ptr<APIFrameHelper> helper_;
|
std::unique_ptr<APIFrameHelper> helper_;
|
||||||
|
|
||||||
std::string client_info_;
|
std::string client_info_;
|
||||||
@ -552,10 +457,160 @@ class APIConnection : public APIServerConnection {
|
|||||||
bool service_call_subscription_{false};
|
bool service_call_subscription_{false};
|
||||||
bool next_close_ = false;
|
bool next_close_ = false;
|
||||||
APIServer *parent_;
|
APIServer *parent_;
|
||||||
DeferredMessageQueue deferred_message_queue_;
|
|
||||||
InitialStateIterator initial_state_iterator_;
|
InitialStateIterator initial_state_iterator_;
|
||||||
ListEntitiesIterator list_entities_iterator_;
|
ListEntitiesIterator list_entities_iterator_;
|
||||||
int state_subs_at_ = -1;
|
int state_subs_at_ = -1;
|
||||||
|
|
||||||
|
// Function pointer type for message encoding
|
||||||
|
using MessageCreatorPtr = uint16_t (*)(EntityBase *, APIConnection *, uint32_t remaining_size, bool is_single);
|
||||||
|
|
||||||
|
// Optimized MessageCreator class using union dispatch
|
||||||
|
class MessageCreator {
|
||||||
|
public:
|
||||||
|
// Constructor for function pointer (message_type = 0)
|
||||||
|
MessageCreator(MessageCreatorPtr ptr) : message_type_(0) { data_.ptr = ptr; }
|
||||||
|
|
||||||
|
// Constructor for string state capture
|
||||||
|
MessageCreator(const std::string &value, uint16_t msg_type) : message_type_(msg_type) {
|
||||||
|
data_.string_ptr = new std::string(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
~MessageCreator() {
|
||||||
|
// Clean up string data for string-based message types
|
||||||
|
if (uses_string_data_()) {
|
||||||
|
delete data_.string_ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy constructor
|
||||||
|
MessageCreator(const MessageCreator &other) : message_type_(other.message_type_) {
|
||||||
|
if (message_type_ == 0) {
|
||||||
|
data_.ptr = other.data_.ptr;
|
||||||
|
} else if (uses_string_data_()) {
|
||||||
|
data_.string_ptr = new std::string(*other.data_.string_ptr);
|
||||||
|
} else {
|
||||||
|
data_ = other.data_; // For POD types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move constructor
|
||||||
|
MessageCreator(MessageCreator &&other) noexcept : data_(other.data_), message_type_(other.message_type_) {
|
||||||
|
other.message_type_ = 0; // Reset other to function pointer type
|
||||||
|
other.data_.ptr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assignment operators (needed for batch deduplication)
|
||||||
|
MessageCreator &operator=(const MessageCreator &other) {
|
||||||
|
if (this != &other) {
|
||||||
|
// Clean up current string data if needed
|
||||||
|
if (uses_string_data_()) {
|
||||||
|
delete data_.string_ptr;
|
||||||
|
}
|
||||||
|
// Copy new data
|
||||||
|
message_type_ = other.message_type_;
|
||||||
|
if (other.message_type_ == 0) {
|
||||||
|
data_.ptr = other.data_.ptr;
|
||||||
|
} else if (other.uses_string_data_()) {
|
||||||
|
data_.string_ptr = new std::string(*other.data_.string_ptr);
|
||||||
|
} else {
|
||||||
|
data_ = other.data_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageCreator &operator=(MessageCreator &&other) noexcept {
|
||||||
|
if (this != &other) {
|
||||||
|
// Clean up current string data if needed
|
||||||
|
if (uses_string_data_()) {
|
||||||
|
delete data_.string_ptr;
|
||||||
|
}
|
||||||
|
// Move data
|
||||||
|
message_type_ = other.message_type_;
|
||||||
|
data_ = other.data_;
|
||||||
|
// Reset other to safe state
|
||||||
|
other.message_type_ = 0;
|
||||||
|
other.data_.ptr = nullptr;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call operator
|
||||||
|
uint16_t operator()(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Helper to check if this message type uses heap-allocated strings
|
||||||
|
bool uses_string_data_() const { return message_type_ == EventResponse::MESSAGE_TYPE; }
|
||||||
|
union CreatorData {
|
||||||
|
MessageCreatorPtr ptr; // 8 bytes
|
||||||
|
std::string *string_ptr; // 8 bytes
|
||||||
|
} data_; // 8 bytes
|
||||||
|
uint16_t message_type_; // 2 bytes (0 = function ptr, >0 = state capture)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Generic batching mechanism for both state updates and entity info
|
||||||
|
struct DeferredBatch {
|
||||||
|
struct BatchItem {
|
||||||
|
EntityBase *entity; // Entity pointer
|
||||||
|
MessageCreator creator; // Function that creates the message when needed
|
||||||
|
uint16_t message_type; // Message type for overhead calculation
|
||||||
|
|
||||||
|
// Constructor for creating BatchItem
|
||||||
|
BatchItem(EntityBase *entity, MessageCreator creator, uint16_t message_type)
|
||||||
|
: entity(entity), creator(std::move(creator)), message_type(message_type) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<BatchItem> items;
|
||||||
|
uint32_t batch_start_time{0};
|
||||||
|
bool batch_scheduled{false};
|
||||||
|
|
||||||
|
DeferredBatch() {
|
||||||
|
// Pre-allocate capacity for typical batch sizes to avoid reallocation
|
||||||
|
items.reserve(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add item to the batch
|
||||||
|
void add_item(EntityBase *entity, MessageCreator creator, uint16_t message_type);
|
||||||
|
void clear() {
|
||||||
|
items.clear();
|
||||||
|
batch_scheduled = false;
|
||||||
|
batch_start_time = 0;
|
||||||
|
}
|
||||||
|
bool empty() const { return items.empty(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
DeferredBatch deferred_batch_;
|
||||||
|
uint32_t get_batch_delay_ms_() const;
|
||||||
|
// Message will use 8 more bytes than the minimum size, and typical
|
||||||
|
// MTU is 1500. Sometimes users will see as low as 1460 MTU.
|
||||||
|
// If its IPv6 the header is 40 bytes, and if its IPv4
|
||||||
|
// the header is 20 bytes. So we have 1460 - 40 = 1420 bytes
|
||||||
|
// available for the payload. But we also need to add the size of
|
||||||
|
// the protobuf overhead, which is 8 bytes.
|
||||||
|
//
|
||||||
|
// To be safe we pick 1390 bytes as the maximum size
|
||||||
|
// to send in one go. This is the maximum size of a single packet
|
||||||
|
// that can be sent over the network.
|
||||||
|
// This is to avoid fragmentation of the packet.
|
||||||
|
static constexpr size_t MAX_PACKET_SIZE = 1390; // MTU
|
||||||
|
|
||||||
|
bool schedule_batch_();
|
||||||
|
void process_batch_();
|
||||||
|
|
||||||
|
// State for batch buffer allocation
|
||||||
|
bool batch_first_message_{false};
|
||||||
|
|
||||||
|
// Helper function to schedule a deferred message with known message type
|
||||||
|
bool schedule_message_(EntityBase *entity, MessageCreator creator, uint16_t message_type) {
|
||||||
|
this->deferred_batch_.add_item(entity, std::move(creator), message_type);
|
||||||
|
return this->schedule_batch_();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overload for function pointers (for info messages and current state reads)
|
||||||
|
bool schedule_message_(EntityBase *entity, MessageCreatorPtr function_ptr, uint16_t message_type) {
|
||||||
|
return schedule_message_(entity, MessageCreator(function_ptr), message_type);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
|
@ -605,9 +605,21 @@ APIError APINoiseFrameHelper::read_packet(ReadPacketBuffer *buffer) {
|
|||||||
return APIError::OK;
|
return APIError::OK;
|
||||||
}
|
}
|
||||||
APIError APINoiseFrameHelper::write_protobuf_packet(uint16_t type, ProtoWriteBuffer buffer) {
|
APIError APINoiseFrameHelper::write_protobuf_packet(uint16_t type, ProtoWriteBuffer buffer) {
|
||||||
int err;
|
std::vector<uint8_t> *raw_buffer = buffer.get_buffer();
|
||||||
APIError aerr;
|
uint16_t payload_len = static_cast<uint16_t>(raw_buffer->size() - frame_header_padding_);
|
||||||
aerr = state_action_();
|
|
||||||
|
// Resize to include MAC space (required for Noise encryption)
|
||||||
|
raw_buffer->resize(raw_buffer->size() + frame_footer_size_);
|
||||||
|
|
||||||
|
// Use write_protobuf_packets with a single packet
|
||||||
|
std::vector<PacketInfo> packets;
|
||||||
|
packets.emplace_back(type, 0, payload_len);
|
||||||
|
|
||||||
|
return write_protobuf_packets(buffer, packets);
|
||||||
|
}
|
||||||
|
|
||||||
|
APIError APINoiseFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, const std::vector<PacketInfo> &packets) {
|
||||||
|
APIError aerr = state_action_();
|
||||||
if (aerr != APIError::OK) {
|
if (aerr != APIError::OK) {
|
||||||
return aerr;
|
return aerr;
|
||||||
}
|
}
|
||||||
@ -616,56 +628,66 @@ APIError APINoiseFrameHelper::write_protobuf_packet(uint16_t type, ProtoWriteBuf
|
|||||||
return APIError::WOULD_BLOCK;
|
return APIError::WOULD_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (packets.empty()) {
|
||||||
|
return APIError::OK;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> *raw_buffer = buffer.get_buffer();
|
std::vector<uint8_t> *raw_buffer = buffer.get_buffer();
|
||||||
// Message data starts after padding
|
this->reusable_iovs_.clear();
|
||||||
uint16_t payload_len = raw_buffer->size() - frame_header_padding_;
|
this->reusable_iovs_.reserve(packets.size());
|
||||||
uint16_t padding = 0;
|
|
||||||
uint16_t msg_len = 4 + payload_len + padding;
|
|
||||||
|
|
||||||
// We need to resize to include MAC space, but we already reserved it in create_buffer
|
// We need to encrypt each packet in place
|
||||||
raw_buffer->resize(raw_buffer->size() + frame_footer_size_);
|
for (const auto &packet : packets) {
|
||||||
|
uint16_t type = packet.message_type;
|
||||||
|
uint16_t offset = packet.offset;
|
||||||
|
uint16_t payload_len = packet.payload_size;
|
||||||
|
uint16_t msg_len = 4 + payload_len; // type(2) + data_len(2) + payload
|
||||||
|
|
||||||
// Write the noise header in the padded area
|
// The buffer already has padding at offset
|
||||||
// Buffer layout:
|
uint8_t *buf_start = raw_buffer->data() + offset;
|
||||||
// [0] - 0x01 indicator byte
|
|
||||||
// [1-2] - Size of encrypted payload (filled after encryption)
|
// Write noise header
|
||||||
// [3-4] - Message type (encrypted)
|
|
||||||
// [5-6] - Payload length (encrypted)
|
|
||||||
// [7...] - Actual payload data (encrypted)
|
|
||||||
uint8_t *buf_start = raw_buffer->data();
|
|
||||||
buf_start[0] = 0x01; // indicator
|
buf_start[0] = 0x01; // indicator
|
||||||
// buf_start[1], buf_start[2] to be set later after encryption
|
// buf_start[1], buf_start[2] to be set after encryption
|
||||||
|
|
||||||
|
// Write message header (to be encrypted)
|
||||||
const uint8_t msg_offset = 3;
|
const uint8_t msg_offset = 3;
|
||||||
buf_start[msg_offset + 0] = (uint8_t) (type >> 8); // type high byte
|
buf_start[msg_offset + 0] = (uint8_t) (type >> 8); // type high byte
|
||||||
buf_start[msg_offset + 1] = (uint8_t) type; // type low byte
|
buf_start[msg_offset + 1] = (uint8_t) type; // type low byte
|
||||||
buf_start[msg_offset + 2] = (uint8_t) (payload_len >> 8); // data_len high byte
|
buf_start[msg_offset + 2] = (uint8_t) (payload_len >> 8); // data_len high byte
|
||||||
buf_start[msg_offset + 3] = (uint8_t) payload_len; // data_len low byte
|
buf_start[msg_offset + 3] = (uint8_t) payload_len; // data_len low byte
|
||||||
// payload data is already in the buffer starting at position 7
|
// payload data is already in the buffer starting at offset + 7
|
||||||
|
|
||||||
|
// Make sure we have space for MAC
|
||||||
|
// The buffer should already have been sized appropriately
|
||||||
|
|
||||||
|
// Encrypt the message in place
|
||||||
NoiseBuffer mbuf;
|
NoiseBuffer mbuf;
|
||||||
noise_buffer_init(mbuf);
|
noise_buffer_init(mbuf);
|
||||||
// The capacity parameter should be msg_len + frame_footer_size_ (MAC length) to allow space for encryption
|
|
||||||
noise_buffer_set_inout(mbuf, buf_start + msg_offset, msg_len, msg_len + frame_footer_size_);
|
noise_buffer_set_inout(mbuf, buf_start + msg_offset, msg_len, msg_len + frame_footer_size_);
|
||||||
err = noise_cipherstate_encrypt(send_cipher_, &mbuf);
|
|
||||||
|
int err = noise_cipherstate_encrypt(send_cipher_, &mbuf);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
state_ = State::FAILED;
|
state_ = State::FAILED;
|
||||||
HELPER_LOG("noise_cipherstate_encrypt failed: %s", noise_err_to_str(err).c_str());
|
HELPER_LOG("noise_cipherstate_encrypt failed: %s", noise_err_to_str(err).c_str());
|
||||||
return APIError::CIPHERSTATE_ENCRYPT_FAILED;
|
return APIError::CIPHERSTATE_ENCRYPT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t total_len = 3 + mbuf.size;
|
// Fill in the encrypted size
|
||||||
buf_start[1] = (uint8_t) (mbuf.size >> 8);
|
buf_start[1] = (uint8_t) (mbuf.size >> 8);
|
||||||
buf_start[2] = (uint8_t) mbuf.size;
|
buf_start[2] = (uint8_t) mbuf.size;
|
||||||
|
|
||||||
|
// Add iovec for this encrypted packet
|
||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
// Point iov_base to the beginning of the buffer (no unused padding in Noise)
|
|
||||||
// We send the entire frame: indicator + size + encrypted(type + data_len + payload + MAC)
|
|
||||||
iov.iov_base = buf_start;
|
iov.iov_base = buf_start;
|
||||||
iov.iov_len = total_len;
|
iov.iov_len = 3 + mbuf.size; // indicator + size + encrypted data
|
||||||
|
this->reusable_iovs_.push_back(iov);
|
||||||
|
}
|
||||||
|
|
||||||
// write raw to not have two packets sent if NAGLE disabled
|
// Send all encrypted packets in one writev call
|
||||||
return this->write_raw_(&iov, 1);
|
return this->write_raw_(this->reusable_iovs_.data(), this->reusable_iovs_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
APIError APINoiseFrameHelper::write_frame_(const uint8_t *data, uint16_t len) {
|
APIError APINoiseFrameHelper::write_frame_(const uint8_t *data, uint16_t len) {
|
||||||
uint8_t header[3];
|
uint8_t header[3];
|
||||||
header[0] = 0x01; // indicator
|
header[0] = 0x01; // indicator
|
||||||
@ -1004,24 +1026,40 @@ APIError APIPlaintextFrameHelper::read_packet(ReadPacketBuffer *buffer) {
|
|||||||
return APIError::OK;
|
return APIError::OK;
|
||||||
}
|
}
|
||||||
APIError APIPlaintextFrameHelper::write_protobuf_packet(uint16_t type, ProtoWriteBuffer buffer) {
|
APIError APIPlaintextFrameHelper::write_protobuf_packet(uint16_t type, ProtoWriteBuffer buffer) {
|
||||||
|
std::vector<uint8_t> *raw_buffer = buffer.get_buffer();
|
||||||
|
uint16_t payload_len = static_cast<uint16_t>(raw_buffer->size() - frame_header_padding_);
|
||||||
|
|
||||||
|
// Use write_protobuf_packets with a single packet
|
||||||
|
std::vector<PacketInfo> packets;
|
||||||
|
packets.emplace_back(type, 0, payload_len);
|
||||||
|
|
||||||
|
return write_protobuf_packets(buffer, packets);
|
||||||
|
}
|
||||||
|
|
||||||
|
APIError APIPlaintextFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer,
|
||||||
|
const std::vector<PacketInfo> &packets) {
|
||||||
if (state_ != State::DATA) {
|
if (state_ != State::DATA) {
|
||||||
return APIError::BAD_STATE;
|
return APIError::BAD_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> *raw_buffer = buffer.get_buffer();
|
if (packets.empty()) {
|
||||||
// Message data starts after padding (frame_header_padding_ = 6)
|
return APIError::OK;
|
||||||
uint16_t payload_len = static_cast<uint16_t>(raw_buffer->size() - frame_header_padding_);
|
}
|
||||||
|
|
||||||
// Calculate varint sizes for header components
|
std::vector<uint8_t> *raw_buffer = buffer.get_buffer();
|
||||||
|
this->reusable_iovs_.clear();
|
||||||
|
this->reusable_iovs_.reserve(packets.size());
|
||||||
|
|
||||||
|
for (const auto &packet : packets) {
|
||||||
|
uint16_t type = packet.message_type;
|
||||||
|
uint16_t offset = packet.offset;
|
||||||
|
uint16_t payload_len = packet.payload_size;
|
||||||
|
|
||||||
|
// Calculate varint sizes for header layout
|
||||||
uint8_t size_varint_len = api::ProtoSize::varint(static_cast<uint32_t>(payload_len));
|
uint8_t size_varint_len = api::ProtoSize::varint(static_cast<uint32_t>(payload_len));
|
||||||
uint8_t type_varint_len = api::ProtoSize::varint(static_cast<uint32_t>(type));
|
uint8_t type_varint_len = api::ProtoSize::varint(static_cast<uint32_t>(type));
|
||||||
uint8_t total_header_len = 1 + size_varint_len + type_varint_len;
|
uint8_t total_header_len = 1 + size_varint_len + type_varint_len;
|
||||||
|
|
||||||
if (total_header_len > frame_header_padding_) {
|
|
||||||
// Header is too large to fit in the padding
|
|
||||||
return APIError::BAD_ARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate where to start writing the header
|
// Calculate where to start writing the header
|
||||||
// The header starts at the latest possible position to minimize unused padding
|
// The header starts at the latest possible position to minimize unused padding
|
||||||
//
|
//
|
||||||
@ -1044,8 +1082,11 @@ APIError APIPlaintextFrameHelper::write_protobuf_packet(uint16_t type, ProtoWrit
|
|||||||
// [1-3] - Payload size varint (3 bytes, for sizes 16384-2097151)
|
// [1-3] - Payload size varint (3 bytes, for sizes 16384-2097151)
|
||||||
// [4-5] - Message type varint (2 bytes, for types 128-32767)
|
// [4-5] - Message type varint (2 bytes, for types 128-32767)
|
||||||
// [6...] - Actual payload data
|
// [6...] - Actual payload data
|
||||||
uint8_t *buf_start = raw_buffer->data();
|
//
|
||||||
uint8_t header_offset = frame_header_padding_ - total_header_len;
|
// The message starts at offset + frame_header_padding_
|
||||||
|
// So we write the header starting at offset + frame_header_padding_ - total_header_len
|
||||||
|
uint8_t *buf_start = raw_buffer->data() + offset;
|
||||||
|
uint32_t header_offset = frame_header_padding_ - total_header_len;
|
||||||
|
|
||||||
// Write the plaintext header
|
// Write the plaintext header
|
||||||
buf_start[header_offset] = 0x00; // indicator
|
buf_start[header_offset] = 0x00; // indicator
|
||||||
@ -1056,13 +1097,15 @@ APIError APIPlaintextFrameHelper::write_protobuf_packet(uint16_t type, ProtoWrit
|
|||||||
// Encode type varint directly into buffer
|
// Encode type varint directly into buffer
|
||||||
ProtoVarInt(type).encode_to_buffer_unchecked(buf_start + header_offset + 1 + size_varint_len, type_varint_len);
|
ProtoVarInt(type).encode_to_buffer_unchecked(buf_start + header_offset + 1 + size_varint_len, type_varint_len);
|
||||||
|
|
||||||
|
// Add iovec for this packet (header + payload)
|
||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
// Point iov_base to the beginning of our header (skip unused padding)
|
|
||||||
// This ensures we only send the actual header and payload, not the empty padding bytes
|
|
||||||
iov.iov_base = buf_start + header_offset;
|
iov.iov_base = buf_start + header_offset;
|
||||||
iov.iov_len = total_header_len + payload_len;
|
iov.iov_len = total_header_len + payload_len;
|
||||||
|
this->reusable_iovs_.push_back(iov);
|
||||||
|
}
|
||||||
|
|
||||||
return write_raw_(&iov, 1);
|
// Send all packets in one writev call
|
||||||
|
return write_raw_(this->reusable_iovs_.data(), this->reusable_iovs_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // USE_API_PLAINTEXT
|
#endif // USE_API_PLAINTEXT
|
||||||
|
@ -27,6 +27,17 @@ struct ReadPacketBuffer {
|
|||||||
uint16_t data_len;
|
uint16_t data_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Packed packet info structure to minimize memory usage
|
||||||
|
struct PacketInfo {
|
||||||
|
uint16_t message_type; // 2 bytes
|
||||||
|
uint16_t offset; // 2 bytes (sufficient for packet size ~1460 bytes)
|
||||||
|
uint16_t payload_size; // 2 bytes (up to 65535 bytes)
|
||||||
|
uint16_t padding; // 2 byte (for alignment)
|
||||||
|
|
||||||
|
PacketInfo(uint16_t type, uint16_t off, uint16_t size)
|
||||||
|
: message_type(type), offset(off), payload_size(size), padding(0) {}
|
||||||
|
};
|
||||||
|
|
||||||
enum class APIError : int {
|
enum class APIError : int {
|
||||||
OK = 0,
|
OK = 0,
|
||||||
WOULD_BLOCK = 1001,
|
WOULD_BLOCK = 1001,
|
||||||
@ -87,6 +98,10 @@ class APIFrameHelper {
|
|||||||
// Give this helper a name for logging
|
// Give this helper a name for logging
|
||||||
void set_log_info(std::string info) { info_ = std::move(info); }
|
void set_log_info(std::string info) { info_ = std::move(info); }
|
||||||
virtual APIError write_protobuf_packet(uint16_t type, ProtoWriteBuffer buffer) = 0;
|
virtual APIError write_protobuf_packet(uint16_t type, ProtoWriteBuffer buffer) = 0;
|
||||||
|
// Write multiple protobuf packets in a single operation
|
||||||
|
// packets contains (message_type, offset, length) for each message in the buffer
|
||||||
|
// The buffer contains all messages with appropriate padding before each
|
||||||
|
virtual APIError write_protobuf_packets(ProtoWriteBuffer buffer, const std::vector<PacketInfo> &packets) = 0;
|
||||||
// Get the frame header padding required by this protocol
|
// Get the frame header padding required by this protocol
|
||||||
virtual uint8_t frame_header_padding() = 0;
|
virtual uint8_t frame_header_padding() = 0;
|
||||||
// Get the frame footer size required by this protocol
|
// Get the frame footer size required by this protocol
|
||||||
@ -157,6 +172,9 @@ class APIFrameHelper {
|
|||||||
uint8_t frame_header_padding_{0};
|
uint8_t frame_header_padding_{0};
|
||||||
uint8_t frame_footer_size_{0};
|
uint8_t frame_footer_size_{0};
|
||||||
|
|
||||||
|
// Reusable IOV array for write_protobuf_packets to avoid repeated allocations
|
||||||
|
std::vector<struct iovec> reusable_iovs_;
|
||||||
|
|
||||||
// Receive buffer for reading frame data
|
// Receive buffer for reading frame data
|
||||||
std::vector<uint8_t> rx_buf_;
|
std::vector<uint8_t> rx_buf_;
|
||||||
uint16_t rx_buf_len_ = 0;
|
uint16_t rx_buf_len_ = 0;
|
||||||
@ -182,6 +200,7 @@ class APINoiseFrameHelper : public APIFrameHelper {
|
|||||||
APIError loop() override;
|
APIError loop() override;
|
||||||
APIError read_packet(ReadPacketBuffer *buffer) override;
|
APIError read_packet(ReadPacketBuffer *buffer) override;
|
||||||
APIError write_protobuf_packet(uint16_t type, ProtoWriteBuffer buffer) override;
|
APIError write_protobuf_packet(uint16_t type, ProtoWriteBuffer buffer) override;
|
||||||
|
APIError write_protobuf_packets(ProtoWriteBuffer buffer, const std::vector<PacketInfo> &packets) override;
|
||||||
// Get the frame header padding required by this protocol
|
// Get the frame header padding required by this protocol
|
||||||
uint8_t frame_header_padding() override { return frame_header_padding_; }
|
uint8_t frame_header_padding() override { return frame_header_padding_; }
|
||||||
// Get the frame footer size required by this protocol
|
// Get the frame footer size required by this protocol
|
||||||
@ -226,6 +245,7 @@ class APIPlaintextFrameHelper : public APIFrameHelper {
|
|||||||
APIError loop() override;
|
APIError loop() override;
|
||||||
APIError read_packet(ReadPacketBuffer *buffer) override;
|
APIError read_packet(ReadPacketBuffer *buffer) override;
|
||||||
APIError write_protobuf_packet(uint16_t type, ProtoWriteBuffer buffer) override;
|
APIError write_protobuf_packet(uint16_t type, ProtoWriteBuffer buffer) override;
|
||||||
|
APIError write_protobuf_packets(ProtoWriteBuffer buffer, const std::vector<PacketInfo> &packets) override;
|
||||||
uint8_t frame_header_padding() override { return frame_header_padding_; }
|
uint8_t frame_header_padding() override { return frame_header_padding_; }
|
||||||
// Get the frame footer size required by this protocol
|
// Get the frame footer size required by this protocol
|
||||||
uint8_t frame_footer_size() override { return frame_footer_size_; }
|
uint8_t frame_footer_size() override { return frame_footer_size_; }
|
||||||
|
@ -255,6 +255,11 @@ enum UpdateCommand : uint32_t {
|
|||||||
|
|
||||||
class HelloRequest : public ProtoMessage {
|
class HelloRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 1;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 17;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "hello_request"; }
|
||||||
|
#endif
|
||||||
std::string client_info{};
|
std::string client_info{};
|
||||||
uint32_t api_version_major{0};
|
uint32_t api_version_major{0};
|
||||||
uint32_t api_version_minor{0};
|
uint32_t api_version_minor{0};
|
||||||
@ -270,6 +275,11 @@ class HelloRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class HelloResponse : public ProtoMessage {
|
class HelloResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 2;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 26;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "hello_response"; }
|
||||||
|
#endif
|
||||||
uint32_t api_version_major{0};
|
uint32_t api_version_major{0};
|
||||||
uint32_t api_version_minor{0};
|
uint32_t api_version_minor{0};
|
||||||
std::string server_info{};
|
std::string server_info{};
|
||||||
@ -286,6 +296,11 @@ class HelloResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ConnectRequest : public ProtoMessage {
|
class ConnectRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 3;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 9;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "connect_request"; }
|
||||||
|
#endif
|
||||||
std::string password{};
|
std::string password{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
@ -298,6 +313,11 @@ class ConnectRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ConnectResponse : public ProtoMessage {
|
class ConnectResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 4;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 2;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "connect_response"; }
|
||||||
|
#endif
|
||||||
bool invalid_password{false};
|
bool invalid_password{false};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
@ -310,6 +330,11 @@ class ConnectResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class DisconnectRequest : public ProtoMessage {
|
class DisconnectRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 5;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 0;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "disconnect_request"; }
|
||||||
|
#endif
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
@ -320,6 +345,11 @@ class DisconnectRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class DisconnectResponse : public ProtoMessage {
|
class DisconnectResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 6;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 0;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "disconnect_response"; }
|
||||||
|
#endif
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
@ -330,6 +360,11 @@ class DisconnectResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class PingRequest : public ProtoMessage {
|
class PingRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 7;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 0;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "ping_request"; }
|
||||||
|
#endif
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
@ -340,6 +375,11 @@ class PingRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class PingResponse : public ProtoMessage {
|
class PingResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 8;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 0;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "ping_response"; }
|
||||||
|
#endif
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
@ -350,6 +390,11 @@ class PingResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class DeviceInfoRequest : public ProtoMessage {
|
class DeviceInfoRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 9;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 0;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "device_info_request"; }
|
||||||
|
#endif
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
@ -360,6 +405,11 @@ class DeviceInfoRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class DeviceInfoResponse : public ProtoMessage {
|
class DeviceInfoResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 10;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 129;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "device_info_response"; }
|
||||||
|
#endif
|
||||||
bool uses_password{false};
|
bool uses_password{false};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
std::string mac_address{};
|
std::string mac_address{};
|
||||||
@ -391,6 +441,11 @@ class DeviceInfoResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesRequest : public ProtoMessage {
|
class ListEntitiesRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 11;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 0;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_request"; }
|
||||||
|
#endif
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
@ -401,6 +456,11 @@ class ListEntitiesRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesDoneResponse : public ProtoMessage {
|
class ListEntitiesDoneResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 19;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 0;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_done_response"; }
|
||||||
|
#endif
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
@ -411,6 +471,11 @@ class ListEntitiesDoneResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class SubscribeStatesRequest : public ProtoMessage {
|
class SubscribeStatesRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 20;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 0;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "subscribe_states_request"; }
|
||||||
|
#endif
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
@ -421,6 +486,11 @@ class SubscribeStatesRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesBinarySensorResponse : public ProtoMessage {
|
class ListEntitiesBinarySensorResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 12;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 56;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_binary_sensor_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -443,6 +513,11 @@ class ListEntitiesBinarySensorResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BinarySensorStateResponse : public ProtoMessage {
|
class BinarySensorStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 21;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 9;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "binary_sensor_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
bool state{false};
|
bool state{false};
|
||||||
bool missing_state{false};
|
bool missing_state{false};
|
||||||
@ -458,6 +533,11 @@ class BinarySensorStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesCoverResponse : public ProtoMessage {
|
class ListEntitiesCoverResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 13;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 62;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_cover_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -483,6 +563,11 @@ class ListEntitiesCoverResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class CoverStateResponse : public ProtoMessage {
|
class CoverStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 22;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 19;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "cover_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
enums::LegacyCoverState legacy_state{};
|
enums::LegacyCoverState legacy_state{};
|
||||||
float position{0.0f};
|
float position{0.0f};
|
||||||
@ -500,6 +585,11 @@ class CoverStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class CoverCommandRequest : public ProtoMessage {
|
class CoverCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 30;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 25;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "cover_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
bool has_legacy_command{false};
|
bool has_legacy_command{false};
|
||||||
enums::LegacyCoverCommand legacy_command{};
|
enums::LegacyCoverCommand legacy_command{};
|
||||||
@ -520,6 +610,11 @@ class CoverCommandRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesFanResponse : public ProtoMessage {
|
class ListEntitiesFanResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 14;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 73;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_fan_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -545,6 +640,11 @@ class ListEntitiesFanResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class FanStateResponse : public ProtoMessage {
|
class FanStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 23;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 26;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "fan_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
bool state{false};
|
bool state{false};
|
||||||
bool oscillating{false};
|
bool oscillating{false};
|
||||||
@ -565,6 +665,11 @@ class FanStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class FanCommandRequest : public ProtoMessage {
|
class FanCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 31;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 38;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "fan_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
bool has_state{false};
|
bool has_state{false};
|
||||||
bool state{false};
|
bool state{false};
|
||||||
@ -591,6 +696,11 @@ class FanCommandRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesLightResponse : public ProtoMessage {
|
class ListEntitiesLightResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 15;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 85;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_light_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -619,6 +729,11 @@ class ListEntitiesLightResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class LightStateResponse : public ProtoMessage {
|
class LightStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 24;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 63;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "light_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
bool state{false};
|
bool state{false};
|
||||||
float brightness{0.0f};
|
float brightness{0.0f};
|
||||||
@ -645,6 +760,11 @@ class LightStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class LightCommandRequest : public ProtoMessage {
|
class LightCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 32;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 107;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "light_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
bool has_state{false};
|
bool has_state{false};
|
||||||
bool state{false};
|
bool state{false};
|
||||||
@ -685,6 +805,11 @@ class LightCommandRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesSensorResponse : public ProtoMessage {
|
class ListEntitiesSensorResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 16;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 73;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_sensor_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -711,6 +836,11 @@ class ListEntitiesSensorResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class SensorStateResponse : public ProtoMessage {
|
class SensorStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 25;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 12;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "sensor_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
float state{0.0f};
|
float state{0.0f};
|
||||||
bool missing_state{false};
|
bool missing_state{false};
|
||||||
@ -726,6 +856,11 @@ class SensorStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesSwitchResponse : public ProtoMessage {
|
class ListEntitiesSwitchResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 17;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 56;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_switch_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -748,6 +883,11 @@ class ListEntitiesSwitchResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class SwitchStateResponse : public ProtoMessage {
|
class SwitchStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 26;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 7;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "switch_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
bool state{false};
|
bool state{false};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -762,6 +902,11 @@ class SwitchStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class SwitchCommandRequest : public ProtoMessage {
|
class SwitchCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 33;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 7;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "switch_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
bool state{false};
|
bool state{false};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -776,6 +921,11 @@ class SwitchCommandRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesTextSensorResponse : public ProtoMessage {
|
class ListEntitiesTextSensorResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 18;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 54;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_text_sensor_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -797,6 +947,11 @@ class ListEntitiesTextSensorResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class TextSensorStateResponse : public ProtoMessage {
|
class TextSensorStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 27;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 16;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "text_sensor_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string state{};
|
std::string state{};
|
||||||
bool missing_state{false};
|
bool missing_state{false};
|
||||||
@ -813,6 +968,11 @@ class TextSensorStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class SubscribeLogsRequest : public ProtoMessage {
|
class SubscribeLogsRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 28;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 4;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "subscribe_logs_request"; }
|
||||||
|
#endif
|
||||||
enums::LogLevel level{};
|
enums::LogLevel level{};
|
||||||
bool dump_config{false};
|
bool dump_config{false};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -826,6 +986,11 @@ class SubscribeLogsRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class SubscribeLogsResponse : public ProtoMessage {
|
class SubscribeLogsResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 29;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 13;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "subscribe_logs_response"; }
|
||||||
|
#endif
|
||||||
enums::LogLevel level{};
|
enums::LogLevel level{};
|
||||||
std::string message{};
|
std::string message{};
|
||||||
bool send_failed{false};
|
bool send_failed{false};
|
||||||
@ -841,6 +1006,11 @@ class SubscribeLogsResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class NoiseEncryptionSetKeyRequest : public ProtoMessage {
|
class NoiseEncryptionSetKeyRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 124;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 9;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "noise_encryption_set_key_request"; }
|
||||||
|
#endif
|
||||||
std::string key{};
|
std::string key{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
@ -853,6 +1023,11 @@ class NoiseEncryptionSetKeyRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class NoiseEncryptionSetKeyResponse : public ProtoMessage {
|
class NoiseEncryptionSetKeyResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 125;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 2;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "noise_encryption_set_key_response"; }
|
||||||
|
#endif
|
||||||
bool success{false};
|
bool success{false};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
@ -865,6 +1040,11 @@ class NoiseEncryptionSetKeyResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class SubscribeHomeassistantServicesRequest : public ProtoMessage {
|
class SubscribeHomeassistantServicesRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 34;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 0;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "subscribe_homeassistant_services_request"; }
|
||||||
|
#endif
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
@ -888,6 +1068,11 @@ class HomeassistantServiceMap : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class HomeassistantServiceResponse : public ProtoMessage {
|
class HomeassistantServiceResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 35;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 113;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "homeassistant_service_response"; }
|
||||||
|
#endif
|
||||||
std::string service{};
|
std::string service{};
|
||||||
std::vector<HomeassistantServiceMap> data{};
|
std::vector<HomeassistantServiceMap> data{};
|
||||||
std::vector<HomeassistantServiceMap> data_template{};
|
std::vector<HomeassistantServiceMap> data_template{};
|
||||||
@ -905,6 +1090,11 @@ class HomeassistantServiceResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class SubscribeHomeAssistantStatesRequest : public ProtoMessage {
|
class SubscribeHomeAssistantStatesRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 38;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 0;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "subscribe_home_assistant_states_request"; }
|
||||||
|
#endif
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
@ -915,6 +1105,11 @@ class SubscribeHomeAssistantStatesRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class SubscribeHomeAssistantStateResponse : public ProtoMessage {
|
class SubscribeHomeAssistantStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 39;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 20;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "subscribe_home_assistant_state_response"; }
|
||||||
|
#endif
|
||||||
std::string entity_id{};
|
std::string entity_id{};
|
||||||
std::string attribute{};
|
std::string attribute{};
|
||||||
bool once{false};
|
bool once{false};
|
||||||
@ -930,6 +1125,11 @@ class SubscribeHomeAssistantStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class HomeAssistantStateResponse : public ProtoMessage {
|
class HomeAssistantStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 40;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 27;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "home_assistant_state_response"; }
|
||||||
|
#endif
|
||||||
std::string entity_id{};
|
std::string entity_id{};
|
||||||
std::string state{};
|
std::string state{};
|
||||||
std::string attribute{};
|
std::string attribute{};
|
||||||
@ -944,6 +1144,11 @@ class HomeAssistantStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class GetTimeRequest : public ProtoMessage {
|
class GetTimeRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 36;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 0;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "get_time_request"; }
|
||||||
|
#endif
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
@ -954,6 +1159,11 @@ class GetTimeRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class GetTimeResponse : public ProtoMessage {
|
class GetTimeResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 37;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 5;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "get_time_response"; }
|
||||||
|
#endif
|
||||||
uint32_t epoch_seconds{0};
|
uint32_t epoch_seconds{0};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
@ -980,6 +1190,11 @@ class ListEntitiesServicesArgument : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesServicesResponse : public ProtoMessage {
|
class ListEntitiesServicesResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 41;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 48;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_services_response"; }
|
||||||
|
#endif
|
||||||
std::string name{};
|
std::string name{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::vector<ListEntitiesServicesArgument> args{};
|
std::vector<ListEntitiesServicesArgument> args{};
|
||||||
@ -1017,6 +1232,11 @@ class ExecuteServiceArgument : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ExecuteServiceRequest : public ProtoMessage {
|
class ExecuteServiceRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 42;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 39;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "execute_service_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::vector<ExecuteServiceArgument> args{};
|
std::vector<ExecuteServiceArgument> args{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -1031,6 +1251,11 @@ class ExecuteServiceRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesCameraResponse : public ProtoMessage {
|
class ListEntitiesCameraResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 43;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 45;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_camera_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -1051,6 +1276,11 @@ class ListEntitiesCameraResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class CameraImageResponse : public ProtoMessage {
|
class CameraImageResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 44;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 16;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "camera_image_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string data{};
|
std::string data{};
|
||||||
bool done{false};
|
bool done{false};
|
||||||
@ -1067,6 +1297,11 @@ class CameraImageResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class CameraImageRequest : public ProtoMessage {
|
class CameraImageRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 45;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 4;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "camera_image_request"; }
|
||||||
|
#endif
|
||||||
bool single{false};
|
bool single{false};
|
||||||
bool stream{false};
|
bool stream{false};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -1080,6 +1315,11 @@ class CameraImageRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesClimateResponse : public ProtoMessage {
|
class ListEntitiesClimateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 46;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 151;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_climate_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -1118,6 +1358,11 @@ class ListEntitiesClimateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ClimateStateResponse : public ProtoMessage {
|
class ClimateStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 47;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 65;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "climate_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
enums::ClimateMode mode{};
|
enums::ClimateMode mode{};
|
||||||
float current_temperature{0.0f};
|
float current_temperature{0.0f};
|
||||||
@ -1146,6 +1391,11 @@ class ClimateStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ClimateCommandRequest : public ProtoMessage {
|
class ClimateCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 48;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 83;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "climate_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
bool has_mode{false};
|
bool has_mode{false};
|
||||||
enums::ClimateMode mode{};
|
enums::ClimateMode mode{};
|
||||||
@ -1182,6 +1432,11 @@ class ClimateCommandRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesNumberResponse : public ProtoMessage {
|
class ListEntitiesNumberResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 49;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 80;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_number_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -1208,6 +1463,11 @@ class ListEntitiesNumberResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class NumberStateResponse : public ProtoMessage {
|
class NumberStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 50;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 12;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "number_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
float state{0.0f};
|
float state{0.0f};
|
||||||
bool missing_state{false};
|
bool missing_state{false};
|
||||||
@ -1223,6 +1483,11 @@ class NumberStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class NumberCommandRequest : public ProtoMessage {
|
class NumberCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 51;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 10;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "number_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
float state{0.0f};
|
float state{0.0f};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -1236,6 +1501,11 @@ class NumberCommandRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesSelectResponse : public ProtoMessage {
|
class ListEntitiesSelectResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 52;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 63;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_select_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -1257,6 +1527,11 @@ class ListEntitiesSelectResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class SelectStateResponse : public ProtoMessage {
|
class SelectStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 53;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 16;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "select_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string state{};
|
std::string state{};
|
||||||
bool missing_state{false};
|
bool missing_state{false};
|
||||||
@ -1273,6 +1548,11 @@ class SelectStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class SelectCommandRequest : public ProtoMessage {
|
class SelectCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 54;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 14;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "select_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string state{};
|
std::string state{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -1287,6 +1567,11 @@ class SelectCommandRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesSirenResponse : public ProtoMessage {
|
class ListEntitiesSirenResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 55;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 67;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_siren_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -1310,6 +1595,11 @@ class ListEntitiesSirenResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class SirenStateResponse : public ProtoMessage {
|
class SirenStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 56;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 7;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "siren_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
bool state{false};
|
bool state{false};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -1324,6 +1614,11 @@ class SirenStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class SirenCommandRequest : public ProtoMessage {
|
class SirenCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 57;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 33;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "siren_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
bool has_state{false};
|
bool has_state{false};
|
||||||
bool state{false};
|
bool state{false};
|
||||||
@ -1346,6 +1641,11 @@ class SirenCommandRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesLockResponse : public ProtoMessage {
|
class ListEntitiesLockResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 58;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 60;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_lock_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -1370,6 +1670,11 @@ class ListEntitiesLockResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class LockStateResponse : public ProtoMessage {
|
class LockStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 59;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 7;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "lock_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
enums::LockState state{};
|
enums::LockState state{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -1384,6 +1689,11 @@ class LockStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class LockCommandRequest : public ProtoMessage {
|
class LockCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 60;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 18;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "lock_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
enums::LockCommand command{};
|
enums::LockCommand command{};
|
||||||
bool has_code{false};
|
bool has_code{false};
|
||||||
@ -1401,6 +1711,11 @@ class LockCommandRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesButtonResponse : public ProtoMessage {
|
class ListEntitiesButtonResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 61;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 54;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_button_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -1422,6 +1737,11 @@ class ListEntitiesButtonResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ButtonCommandRequest : public ProtoMessage {
|
class ButtonCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 62;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 5;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "button_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
@ -1451,6 +1771,11 @@ class MediaPlayerSupportedFormat : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesMediaPlayerResponse : public ProtoMessage {
|
class ListEntitiesMediaPlayerResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 63;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 81;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_media_player_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -1473,6 +1798,11 @@ class ListEntitiesMediaPlayerResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class MediaPlayerStateResponse : public ProtoMessage {
|
class MediaPlayerStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 64;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 14;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "media_player_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
enums::MediaPlayerState state{};
|
enums::MediaPlayerState state{};
|
||||||
float volume{0.0f};
|
float volume{0.0f};
|
||||||
@ -1489,6 +1819,11 @@ class MediaPlayerStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class MediaPlayerCommandRequest : public ProtoMessage {
|
class MediaPlayerCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 65;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 31;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "media_player_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
bool has_command{false};
|
bool has_command{false};
|
||||||
enums::MediaPlayerCommand command{};
|
enums::MediaPlayerCommand command{};
|
||||||
@ -1511,6 +1846,11 @@ class MediaPlayerCommandRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class SubscribeBluetoothLEAdvertisementsRequest : public ProtoMessage {
|
class SubscribeBluetoothLEAdvertisementsRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 66;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 4;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "subscribe_bluetooth_le_advertisements_request"; }
|
||||||
|
#endif
|
||||||
uint32_t flags{0};
|
uint32_t flags{0};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
@ -1538,6 +1878,11 @@ class BluetoothServiceData : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothLEAdvertisementResponse : public ProtoMessage {
|
class BluetoothLEAdvertisementResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 67;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 107;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_le_advertisement_response"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
int32_t rssi{0};
|
int32_t rssi{0};
|
||||||
@ -1573,6 +1918,11 @@ class BluetoothLERawAdvertisement : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothLERawAdvertisementsResponse : public ProtoMessage {
|
class BluetoothLERawAdvertisementsResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 93;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 34;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_le_raw_advertisements_response"; }
|
||||||
|
#endif
|
||||||
std::vector<BluetoothLERawAdvertisement> advertisements{};
|
std::vector<BluetoothLERawAdvertisement> advertisements{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
@ -1585,6 +1935,11 @@ class BluetoothLERawAdvertisementsResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothDeviceRequest : public ProtoMessage {
|
class BluetoothDeviceRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 68;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 12;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_device_request"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
enums::BluetoothDeviceRequestType request_type{};
|
enums::BluetoothDeviceRequestType request_type{};
|
||||||
bool has_address_type{false};
|
bool has_address_type{false};
|
||||||
@ -1600,6 +1955,11 @@ class BluetoothDeviceRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothDeviceConnectionResponse : public ProtoMessage {
|
class BluetoothDeviceConnectionResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 69;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 14;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_device_connection_response"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
bool connected{false};
|
bool connected{false};
|
||||||
uint32_t mtu{0};
|
uint32_t mtu{0};
|
||||||
@ -1615,6 +1975,11 @@ class BluetoothDeviceConnectionResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothGATTGetServicesRequest : public ProtoMessage {
|
class BluetoothGATTGetServicesRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 70;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 4;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_gatt_get_services_request"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
@ -1671,6 +2036,11 @@ class BluetoothGATTService : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothGATTGetServicesResponse : public ProtoMessage {
|
class BluetoothGATTGetServicesResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 71;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 38;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_gatt_get_services_response"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
std::vector<BluetoothGATTService> services{};
|
std::vector<BluetoothGATTService> services{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -1685,6 +2055,11 @@ class BluetoothGATTGetServicesResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothGATTGetServicesDoneResponse : public ProtoMessage {
|
class BluetoothGATTGetServicesDoneResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 72;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 4;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_gatt_get_services_done_response"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
@ -1697,6 +2072,11 @@ class BluetoothGATTGetServicesDoneResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothGATTReadRequest : public ProtoMessage {
|
class BluetoothGATTReadRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 73;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 8;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_gatt_read_request"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
uint32_t handle{0};
|
uint32_t handle{0};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -1710,6 +2090,11 @@ class BluetoothGATTReadRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothGATTReadResponse : public ProtoMessage {
|
class BluetoothGATTReadResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 74;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 17;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_gatt_read_response"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
uint32_t handle{0};
|
uint32_t handle{0};
|
||||||
std::string data{};
|
std::string data{};
|
||||||
@ -1725,6 +2110,11 @@ class BluetoothGATTReadResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothGATTWriteRequest : public ProtoMessage {
|
class BluetoothGATTWriteRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 75;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 19;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_gatt_write_request"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
uint32_t handle{0};
|
uint32_t handle{0};
|
||||||
bool response{false};
|
bool response{false};
|
||||||
@ -1741,6 +2131,11 @@ class BluetoothGATTWriteRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothGATTReadDescriptorRequest : public ProtoMessage {
|
class BluetoothGATTReadDescriptorRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 76;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 8;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_gatt_read_descriptor_request"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
uint32_t handle{0};
|
uint32_t handle{0};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -1754,6 +2149,11 @@ class BluetoothGATTReadDescriptorRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothGATTWriteDescriptorRequest : public ProtoMessage {
|
class BluetoothGATTWriteDescriptorRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 77;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 17;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_gatt_write_descriptor_request"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
uint32_t handle{0};
|
uint32_t handle{0};
|
||||||
std::string data{};
|
std::string data{};
|
||||||
@ -1769,6 +2169,11 @@ class BluetoothGATTWriteDescriptorRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothGATTNotifyRequest : public ProtoMessage {
|
class BluetoothGATTNotifyRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 78;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 10;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_gatt_notify_request"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
uint32_t handle{0};
|
uint32_t handle{0};
|
||||||
bool enable{false};
|
bool enable{false};
|
||||||
@ -1783,6 +2188,11 @@ class BluetoothGATTNotifyRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothGATTNotifyDataResponse : public ProtoMessage {
|
class BluetoothGATTNotifyDataResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 79;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 17;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_gatt_notify_data_response"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
uint32_t handle{0};
|
uint32_t handle{0};
|
||||||
std::string data{};
|
std::string data{};
|
||||||
@ -1798,6 +2208,11 @@ class BluetoothGATTNotifyDataResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class SubscribeBluetoothConnectionsFreeRequest : public ProtoMessage {
|
class SubscribeBluetoothConnectionsFreeRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 80;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 0;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "subscribe_bluetooth_connections_free_request"; }
|
||||||
|
#endif
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
@ -1808,6 +2223,11 @@ class SubscribeBluetoothConnectionsFreeRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothConnectionsFreeResponse : public ProtoMessage {
|
class BluetoothConnectionsFreeResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 81;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 16;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_connections_free_response"; }
|
||||||
|
#endif
|
||||||
uint32_t free{0};
|
uint32_t free{0};
|
||||||
uint32_t limit{0};
|
uint32_t limit{0};
|
||||||
std::vector<uint64_t> allocated{};
|
std::vector<uint64_t> allocated{};
|
||||||
@ -1822,6 +2242,11 @@ class BluetoothConnectionsFreeResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothGATTErrorResponse : public ProtoMessage {
|
class BluetoothGATTErrorResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 82;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 12;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_gatt_error_response"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
uint32_t handle{0};
|
uint32_t handle{0};
|
||||||
int32_t error{0};
|
int32_t error{0};
|
||||||
@ -1836,6 +2261,11 @@ class BluetoothGATTErrorResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothGATTWriteResponse : public ProtoMessage {
|
class BluetoothGATTWriteResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 83;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 8;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_gatt_write_response"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
uint32_t handle{0};
|
uint32_t handle{0};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -1849,6 +2279,11 @@ class BluetoothGATTWriteResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothGATTNotifyResponse : public ProtoMessage {
|
class BluetoothGATTNotifyResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 84;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 8;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_gatt_notify_response"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
uint32_t handle{0};
|
uint32_t handle{0};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -1862,6 +2297,11 @@ class BluetoothGATTNotifyResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothDevicePairingResponse : public ProtoMessage {
|
class BluetoothDevicePairingResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 85;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 10;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_device_pairing_response"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
bool paired{false};
|
bool paired{false};
|
||||||
int32_t error{0};
|
int32_t error{0};
|
||||||
@ -1876,6 +2316,11 @@ class BluetoothDevicePairingResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothDeviceUnpairingResponse : public ProtoMessage {
|
class BluetoothDeviceUnpairingResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 86;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 10;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_device_unpairing_response"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
bool success{false};
|
bool success{false};
|
||||||
int32_t error{0};
|
int32_t error{0};
|
||||||
@ -1890,6 +2335,11 @@ class BluetoothDeviceUnpairingResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class UnsubscribeBluetoothLEAdvertisementsRequest : public ProtoMessage {
|
class UnsubscribeBluetoothLEAdvertisementsRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 87;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 0;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "unsubscribe_bluetooth_le_advertisements_request"; }
|
||||||
|
#endif
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
@ -1900,6 +2350,11 @@ class UnsubscribeBluetoothLEAdvertisementsRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothDeviceClearCacheResponse : public ProtoMessage {
|
class BluetoothDeviceClearCacheResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 88;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 10;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_device_clear_cache_response"; }
|
||||||
|
#endif
|
||||||
uint64_t address{0};
|
uint64_t address{0};
|
||||||
bool success{false};
|
bool success{false};
|
||||||
int32_t error{0};
|
int32_t error{0};
|
||||||
@ -1914,6 +2369,11 @@ class BluetoothDeviceClearCacheResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothScannerStateResponse : public ProtoMessage {
|
class BluetoothScannerStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 126;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 4;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_scanner_state_response"; }
|
||||||
|
#endif
|
||||||
enums::BluetoothScannerState state{};
|
enums::BluetoothScannerState state{};
|
||||||
enums::BluetoothScannerMode mode{};
|
enums::BluetoothScannerMode mode{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -1927,6 +2387,11 @@ class BluetoothScannerStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class BluetoothScannerSetModeRequest : public ProtoMessage {
|
class BluetoothScannerSetModeRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 127;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 2;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "bluetooth_scanner_set_mode_request"; }
|
||||||
|
#endif
|
||||||
enums::BluetoothScannerMode mode{};
|
enums::BluetoothScannerMode mode{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
@ -1939,6 +2404,11 @@ class BluetoothScannerSetModeRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class SubscribeVoiceAssistantRequest : public ProtoMessage {
|
class SubscribeVoiceAssistantRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 89;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 6;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "subscribe_voice_assistant_request"; }
|
||||||
|
#endif
|
||||||
bool subscribe{false};
|
bool subscribe{false};
|
||||||
uint32_t flags{0};
|
uint32_t flags{0};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -1967,6 +2437,11 @@ class VoiceAssistantAudioSettings : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class VoiceAssistantRequest : public ProtoMessage {
|
class VoiceAssistantRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 90;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 41;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "voice_assistant_request"; }
|
||||||
|
#endif
|
||||||
bool start{false};
|
bool start{false};
|
||||||
std::string conversation_id{};
|
std::string conversation_id{};
|
||||||
uint32_t flags{0};
|
uint32_t flags{0};
|
||||||
@ -1984,6 +2459,11 @@ class VoiceAssistantRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class VoiceAssistantResponse : public ProtoMessage {
|
class VoiceAssistantResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 91;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 6;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "voice_assistant_response"; }
|
||||||
|
#endif
|
||||||
uint32_t port{0};
|
uint32_t port{0};
|
||||||
bool error{false};
|
bool error{false};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -2010,6 +2490,11 @@ class VoiceAssistantEventData : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class VoiceAssistantEventResponse : public ProtoMessage {
|
class VoiceAssistantEventResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 92;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 36;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "voice_assistant_event_response"; }
|
||||||
|
#endif
|
||||||
enums::VoiceAssistantEvent event_type{};
|
enums::VoiceAssistantEvent event_type{};
|
||||||
std::vector<VoiceAssistantEventData> data{};
|
std::vector<VoiceAssistantEventData> data{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -2024,6 +2509,11 @@ class VoiceAssistantEventResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class VoiceAssistantAudio : public ProtoMessage {
|
class VoiceAssistantAudio : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 106;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 11;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "voice_assistant_audio"; }
|
||||||
|
#endif
|
||||||
std::string data{};
|
std::string data{};
|
||||||
bool end{false};
|
bool end{false};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -2038,6 +2528,11 @@ class VoiceAssistantAudio : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class VoiceAssistantTimerEventResponse : public ProtoMessage {
|
class VoiceAssistantTimerEventResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 115;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 30;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "voice_assistant_timer_event_response"; }
|
||||||
|
#endif
|
||||||
enums::VoiceAssistantTimerEvent event_type{};
|
enums::VoiceAssistantTimerEvent event_type{};
|
||||||
std::string timer_id{};
|
std::string timer_id{};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -2056,6 +2551,11 @@ class VoiceAssistantTimerEventResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class VoiceAssistantAnnounceRequest : public ProtoMessage {
|
class VoiceAssistantAnnounceRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 119;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 29;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "voice_assistant_announce_request"; }
|
||||||
|
#endif
|
||||||
std::string media_id{};
|
std::string media_id{};
|
||||||
std::string text{};
|
std::string text{};
|
||||||
std::string preannounce_media_id{};
|
std::string preannounce_media_id{};
|
||||||
@ -2072,6 +2572,11 @@ class VoiceAssistantAnnounceRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class VoiceAssistantAnnounceFinished : public ProtoMessage {
|
class VoiceAssistantAnnounceFinished : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 120;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 2;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "voice_assistant_announce_finished"; }
|
||||||
|
#endif
|
||||||
bool success{false};
|
bool success{false};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
@ -2098,6 +2603,11 @@ class VoiceAssistantWakeWord : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class VoiceAssistantConfigurationRequest : public ProtoMessage {
|
class VoiceAssistantConfigurationRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 121;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 0;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "voice_assistant_configuration_request"; }
|
||||||
|
#endif
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
@ -2108,6 +2618,11 @@ class VoiceAssistantConfigurationRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class VoiceAssistantConfigurationResponse : public ProtoMessage {
|
class VoiceAssistantConfigurationResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 122;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 56;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "voice_assistant_configuration_response"; }
|
||||||
|
#endif
|
||||||
std::vector<VoiceAssistantWakeWord> available_wake_words{};
|
std::vector<VoiceAssistantWakeWord> available_wake_words{};
|
||||||
std::vector<std::string> active_wake_words{};
|
std::vector<std::string> active_wake_words{};
|
||||||
uint32_t max_active_wake_words{0};
|
uint32_t max_active_wake_words{0};
|
||||||
@ -2123,6 +2638,11 @@ class VoiceAssistantConfigurationResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class VoiceAssistantSetConfiguration : public ProtoMessage {
|
class VoiceAssistantSetConfiguration : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 123;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 18;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "voice_assistant_set_configuration"; }
|
||||||
|
#endif
|
||||||
std::vector<std::string> active_wake_words{};
|
std::vector<std::string> active_wake_words{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(uint32_t &total_size) const override;
|
void calculate_size(uint32_t &total_size) const override;
|
||||||
@ -2135,6 +2655,11 @@ class VoiceAssistantSetConfiguration : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesAlarmControlPanelResponse : public ProtoMessage {
|
class ListEntitiesAlarmControlPanelResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 94;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 53;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_alarm_control_panel_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -2158,6 +2683,11 @@ class ListEntitiesAlarmControlPanelResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class AlarmControlPanelStateResponse : public ProtoMessage {
|
class AlarmControlPanelStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 95;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 7;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "alarm_control_panel_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
enums::AlarmControlPanelState state{};
|
enums::AlarmControlPanelState state{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -2172,6 +2702,11 @@ class AlarmControlPanelStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class AlarmControlPanelCommandRequest : public ProtoMessage {
|
class AlarmControlPanelCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 96;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 16;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "alarm_control_panel_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
enums::AlarmControlPanelStateCommand command{};
|
enums::AlarmControlPanelStateCommand command{};
|
||||||
std::string code{};
|
std::string code{};
|
||||||
@ -2188,6 +2723,11 @@ class AlarmControlPanelCommandRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesTextResponse : public ProtoMessage {
|
class ListEntitiesTextResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 97;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 64;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_text_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -2212,6 +2752,11 @@ class ListEntitiesTextResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class TextStateResponse : public ProtoMessage {
|
class TextStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 98;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 16;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "text_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string state{};
|
std::string state{};
|
||||||
bool missing_state{false};
|
bool missing_state{false};
|
||||||
@ -2228,6 +2773,11 @@ class TextStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class TextCommandRequest : public ProtoMessage {
|
class TextCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 99;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 14;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "text_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string state{};
|
std::string state{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -2242,6 +2792,11 @@ class TextCommandRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesDateResponse : public ProtoMessage {
|
class ListEntitiesDateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 100;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 45;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_date_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -2262,6 +2817,11 @@ class ListEntitiesDateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class DateStateResponse : public ProtoMessage {
|
class DateStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 101;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 19;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "date_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
bool missing_state{false};
|
bool missing_state{false};
|
||||||
uint32_t year{0};
|
uint32_t year{0};
|
||||||
@ -2279,6 +2839,11 @@ class DateStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class DateCommandRequest : public ProtoMessage {
|
class DateCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 102;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 17;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "date_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
uint32_t year{0};
|
uint32_t year{0};
|
||||||
uint32_t month{0};
|
uint32_t month{0};
|
||||||
@ -2295,6 +2860,11 @@ class DateCommandRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesTimeResponse : public ProtoMessage {
|
class ListEntitiesTimeResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 103;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 45;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_time_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -2315,6 +2885,11 @@ class ListEntitiesTimeResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class TimeStateResponse : public ProtoMessage {
|
class TimeStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 104;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 19;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "time_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
bool missing_state{false};
|
bool missing_state{false};
|
||||||
uint32_t hour{0};
|
uint32_t hour{0};
|
||||||
@ -2332,6 +2907,11 @@ class TimeStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class TimeCommandRequest : public ProtoMessage {
|
class TimeCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 105;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 17;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "time_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
uint32_t hour{0};
|
uint32_t hour{0};
|
||||||
uint32_t minute{0};
|
uint32_t minute{0};
|
||||||
@ -2348,6 +2928,11 @@ class TimeCommandRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesEventResponse : public ProtoMessage {
|
class ListEntitiesEventResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 107;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 72;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_event_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -2370,6 +2955,11 @@ class ListEntitiesEventResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class EventResponse : public ProtoMessage {
|
class EventResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 108;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 14;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "event_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string event_type{};
|
std::string event_type{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -2384,6 +2974,11 @@ class EventResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesValveResponse : public ProtoMessage {
|
class ListEntitiesValveResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 109;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 60;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_valve_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -2408,6 +3003,11 @@ class ListEntitiesValveResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ValveStateResponse : public ProtoMessage {
|
class ValveStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 110;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 12;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "valve_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
float position{0.0f};
|
float position{0.0f};
|
||||||
enums::ValveOperation current_operation{};
|
enums::ValveOperation current_operation{};
|
||||||
@ -2423,6 +3023,11 @@ class ValveStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ValveCommandRequest : public ProtoMessage {
|
class ValveCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 111;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 14;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "valve_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
bool has_position{false};
|
bool has_position{false};
|
||||||
float position{0.0f};
|
float position{0.0f};
|
||||||
@ -2439,6 +3044,11 @@ class ValveCommandRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesDateTimeResponse : public ProtoMessage {
|
class ListEntitiesDateTimeResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 112;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 45;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_date_time_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -2459,6 +3069,11 @@ class ListEntitiesDateTimeResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class DateTimeStateResponse : public ProtoMessage {
|
class DateTimeStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 113;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 12;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "date_time_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
bool missing_state{false};
|
bool missing_state{false};
|
||||||
uint32_t epoch_seconds{0};
|
uint32_t epoch_seconds{0};
|
||||||
@ -2474,6 +3089,11 @@ class DateTimeStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class DateTimeCommandRequest : public ProtoMessage {
|
class DateTimeCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 114;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 10;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "date_time_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
uint32_t epoch_seconds{0};
|
uint32_t epoch_seconds{0};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
@ -2487,6 +3107,11 @@ class DateTimeCommandRequest : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class ListEntitiesUpdateResponse : public ProtoMessage {
|
class ListEntitiesUpdateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 116;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 54;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "list_entities_update_response"; }
|
||||||
|
#endif
|
||||||
std::string object_id{};
|
std::string object_id{};
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
std::string name{};
|
std::string name{};
|
||||||
@ -2508,6 +3133,11 @@ class ListEntitiesUpdateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class UpdateStateResponse : public ProtoMessage {
|
class UpdateStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 117;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 61;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "update_state_response"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
bool missing_state{false};
|
bool missing_state{false};
|
||||||
bool in_progress{false};
|
bool in_progress{false};
|
||||||
@ -2531,6 +3161,11 @@ class UpdateStateResponse : public ProtoMessage {
|
|||||||
};
|
};
|
||||||
class UpdateCommandRequest : public ProtoMessage {
|
class UpdateCommandRequest : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint16_t MESSAGE_TYPE = 118;
|
||||||
|
static constexpr uint16_t ESTIMATED_SIZE = 7;
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
static constexpr const char *message_name() { return "update_command_request"; }
|
||||||
|
#endif
|
||||||
uint32_t key{0};
|
uint32_t key{0};
|
||||||
enums::UpdateCommand command{};
|
enums::UpdateCommand command{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
|
@ -8,688 +8,12 @@ namespace api {
|
|||||||
|
|
||||||
static const char *const TAG = "api.service";
|
static const char *const TAG = "api.service";
|
||||||
|
|
||||||
bool APIServerConnectionBase::send_hello_response(const HelloResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
ESP_LOGVV(TAG, "send_hello_response: %s", msg.dump().c_str());
|
void APIServerConnectionBase::log_send_message_(const char *name, const std::string &dump) {
|
||||||
#endif
|
ESP_LOGVV(TAG, "send_message %s: %s", name, dump.c_str());
|
||||||
return this->send_message_<HelloResponse>(msg, 2);
|
|
||||||
}
|
|
||||||
bool APIServerConnectionBase::send_connect_response(const ConnectResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_connect_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ConnectResponse>(msg, 4);
|
|
||||||
}
|
|
||||||
bool APIServerConnectionBase::send_disconnect_request(const DisconnectRequest &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_disconnect_request: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<DisconnectRequest>(msg, 5);
|
|
||||||
}
|
|
||||||
bool APIServerConnectionBase::send_disconnect_response(const DisconnectResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_disconnect_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<DisconnectResponse>(msg, 6);
|
|
||||||
}
|
|
||||||
bool APIServerConnectionBase::send_ping_request(const PingRequest &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_ping_request: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<PingRequest>(msg, 7);
|
|
||||||
}
|
|
||||||
bool APIServerConnectionBase::send_ping_response(const PingResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_ping_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<PingResponse>(msg, 8);
|
|
||||||
}
|
|
||||||
bool APIServerConnectionBase::send_device_info_response(const DeviceInfoResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_device_info_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<DeviceInfoResponse>(msg, 10);
|
|
||||||
}
|
|
||||||
bool APIServerConnectionBase::send_list_entities_done_response(const ListEntitiesDoneResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_done_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesDoneResponse>(msg, 19);
|
|
||||||
}
|
|
||||||
#ifdef USE_BINARY_SENSOR
|
|
||||||
bool APIServerConnectionBase::send_list_entities_binary_sensor_response(const ListEntitiesBinarySensorResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_binary_sensor_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesBinarySensorResponse>(msg, 12);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BINARY_SENSOR
|
|
||||||
bool APIServerConnectionBase::send_binary_sensor_state_response(const BinarySensorStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_binary_sensor_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<BinarySensorStateResponse>(msg, 21);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_COVER
|
|
||||||
bool APIServerConnectionBase::send_list_entities_cover_response(const ListEntitiesCoverResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_cover_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesCoverResponse>(msg, 13);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_COVER
|
|
||||||
bool APIServerConnectionBase::send_cover_state_response(const CoverStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_cover_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<CoverStateResponse>(msg, 22);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_COVER
|
|
||||||
#endif
|
|
||||||
#ifdef USE_FAN
|
|
||||||
bool APIServerConnectionBase::send_list_entities_fan_response(const ListEntitiesFanResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_fan_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesFanResponse>(msg, 14);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_FAN
|
|
||||||
bool APIServerConnectionBase::send_fan_state_response(const FanStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_fan_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<FanStateResponse>(msg, 23);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_FAN
|
|
||||||
#endif
|
|
||||||
#ifdef USE_LIGHT
|
|
||||||
bool APIServerConnectionBase::send_list_entities_light_response(const ListEntitiesLightResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_light_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesLightResponse>(msg, 15);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_LIGHT
|
|
||||||
bool APIServerConnectionBase::send_light_state_response(const LightStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_light_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<LightStateResponse>(msg, 24);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_LIGHT
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SENSOR
|
|
||||||
bool APIServerConnectionBase::send_list_entities_sensor_response(const ListEntitiesSensorResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_sensor_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesSensorResponse>(msg, 16);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SENSOR
|
|
||||||
bool APIServerConnectionBase::send_sensor_state_response(const SensorStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_sensor_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<SensorStateResponse>(msg, 25);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SWITCH
|
|
||||||
bool APIServerConnectionBase::send_list_entities_switch_response(const ListEntitiesSwitchResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_switch_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesSwitchResponse>(msg, 17);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SWITCH
|
|
||||||
bool APIServerConnectionBase::send_switch_state_response(const SwitchStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_switch_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<SwitchStateResponse>(msg, 26);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SWITCH
|
|
||||||
#endif
|
|
||||||
#ifdef USE_TEXT_SENSOR
|
|
||||||
bool APIServerConnectionBase::send_list_entities_text_sensor_response(const ListEntitiesTextSensorResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_text_sensor_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesTextSensorResponse>(msg, 18);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_TEXT_SENSOR
|
|
||||||
bool APIServerConnectionBase::send_text_sensor_state_response(const TextSensorStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_text_sensor_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<TextSensorStateResponse>(msg, 27);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
bool APIServerConnectionBase::send_subscribe_logs_response(const SubscribeLogsResponse &msg) {
|
|
||||||
return this->send_message_<SubscribeLogsResponse>(msg, 29);
|
|
||||||
}
|
|
||||||
#ifdef USE_API_NOISE
|
|
||||||
#endif
|
|
||||||
#ifdef USE_API_NOISE
|
|
||||||
bool APIServerConnectionBase::send_noise_encryption_set_key_response(const NoiseEncryptionSetKeyResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_noise_encryption_set_key_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<NoiseEncryptionSetKeyResponse>(msg, 125);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
bool APIServerConnectionBase::send_homeassistant_service_response(const HomeassistantServiceResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_homeassistant_service_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<HomeassistantServiceResponse>(msg, 35);
|
|
||||||
}
|
|
||||||
bool APIServerConnectionBase::send_subscribe_home_assistant_state_response(
|
|
||||||
const SubscribeHomeAssistantStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_subscribe_home_assistant_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<SubscribeHomeAssistantStateResponse>(msg, 39);
|
|
||||||
}
|
|
||||||
bool APIServerConnectionBase::send_get_time_request(const GetTimeRequest &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_get_time_request: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<GetTimeRequest>(msg, 36);
|
|
||||||
}
|
|
||||||
bool APIServerConnectionBase::send_get_time_response(const GetTimeResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_get_time_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<GetTimeResponse>(msg, 37);
|
|
||||||
}
|
|
||||||
bool APIServerConnectionBase::send_list_entities_services_response(const ListEntitiesServicesResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_services_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesServicesResponse>(msg, 41);
|
|
||||||
}
|
|
||||||
#ifdef USE_ESP32_CAMERA
|
|
||||||
bool APIServerConnectionBase::send_list_entities_camera_response(const ListEntitiesCameraResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_camera_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesCameraResponse>(msg, 43);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_ESP32_CAMERA
|
|
||||||
bool APIServerConnectionBase::send_camera_image_response(const CameraImageResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_camera_image_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<CameraImageResponse>(msg, 44);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_ESP32_CAMERA
|
|
||||||
#endif
|
|
||||||
#ifdef USE_CLIMATE
|
|
||||||
bool APIServerConnectionBase::send_list_entities_climate_response(const ListEntitiesClimateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_climate_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesClimateResponse>(msg, 46);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_CLIMATE
|
|
||||||
bool APIServerConnectionBase::send_climate_state_response(const ClimateStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_climate_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ClimateStateResponse>(msg, 47);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_CLIMATE
|
|
||||||
#endif
|
|
||||||
#ifdef USE_NUMBER
|
|
||||||
bool APIServerConnectionBase::send_list_entities_number_response(const ListEntitiesNumberResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_number_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesNumberResponse>(msg, 49);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_NUMBER
|
|
||||||
bool APIServerConnectionBase::send_number_state_response(const NumberStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_number_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<NumberStateResponse>(msg, 50);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_NUMBER
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SELECT
|
|
||||||
bool APIServerConnectionBase::send_list_entities_select_response(const ListEntitiesSelectResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_select_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesSelectResponse>(msg, 52);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SELECT
|
|
||||||
bool APIServerConnectionBase::send_select_state_response(const SelectStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_select_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<SelectStateResponse>(msg, 53);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SELECT
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SIREN
|
|
||||||
bool APIServerConnectionBase::send_list_entities_siren_response(const ListEntitiesSirenResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_siren_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesSirenResponse>(msg, 55);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SIREN
|
|
||||||
bool APIServerConnectionBase::send_siren_state_response(const SirenStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_siren_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<SirenStateResponse>(msg, 56);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SIREN
|
|
||||||
#endif
|
|
||||||
#ifdef USE_LOCK
|
|
||||||
bool APIServerConnectionBase::send_list_entities_lock_response(const ListEntitiesLockResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_lock_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesLockResponse>(msg, 58);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_LOCK
|
|
||||||
bool APIServerConnectionBase::send_lock_state_response(const LockStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_lock_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<LockStateResponse>(msg, 59);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_LOCK
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BUTTON
|
|
||||||
bool APIServerConnectionBase::send_list_entities_button_response(const ListEntitiesButtonResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_button_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesButtonResponse>(msg, 61);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BUTTON
|
|
||||||
#endif
|
|
||||||
#ifdef USE_MEDIA_PLAYER
|
|
||||||
bool APIServerConnectionBase::send_list_entities_media_player_response(const ListEntitiesMediaPlayerResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_media_player_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesMediaPlayerResponse>(msg, 63);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_MEDIA_PLAYER
|
|
||||||
bool APIServerConnectionBase::send_media_player_state_response(const MediaPlayerStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_media_player_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<MediaPlayerStateResponse>(msg, 64);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_MEDIA_PLAYER
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool APIServerConnectionBase::send_bluetooth_le_advertisement_response(const BluetoothLEAdvertisementResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_bluetooth_le_advertisement_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<BluetoothLEAdvertisementResponse>(msg, 67);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool APIServerConnectionBase::send_bluetooth_le_raw_advertisements_response(
|
|
||||||
const BluetoothLERawAdvertisementsResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_bluetooth_le_raw_advertisements_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<BluetoothLERawAdvertisementsResponse>(msg, 93);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool APIServerConnectionBase::send_bluetooth_device_connection_response(const BluetoothDeviceConnectionResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_bluetooth_device_connection_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<BluetoothDeviceConnectionResponse>(msg, 69);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool APIServerConnectionBase::send_bluetooth_gatt_get_services_response(const BluetoothGATTGetServicesResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_bluetooth_gatt_get_services_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<BluetoothGATTGetServicesResponse>(msg, 71);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool APIServerConnectionBase::send_bluetooth_gatt_get_services_done_response(
|
|
||||||
const BluetoothGATTGetServicesDoneResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_bluetooth_gatt_get_services_done_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<BluetoothGATTGetServicesDoneResponse>(msg, 72);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool APIServerConnectionBase::send_bluetooth_gatt_read_response(const BluetoothGATTReadResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_bluetooth_gatt_read_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<BluetoothGATTReadResponse>(msg, 74);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool APIServerConnectionBase::send_bluetooth_gatt_notify_data_response(const BluetoothGATTNotifyDataResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_bluetooth_gatt_notify_data_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<BluetoothGATTNotifyDataResponse>(msg, 79);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool APIServerConnectionBase::send_bluetooth_connections_free_response(const BluetoothConnectionsFreeResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_bluetooth_connections_free_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<BluetoothConnectionsFreeResponse>(msg, 81);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool APIServerConnectionBase::send_bluetooth_gatt_error_response(const BluetoothGATTErrorResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_bluetooth_gatt_error_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<BluetoothGATTErrorResponse>(msg, 82);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool APIServerConnectionBase::send_bluetooth_gatt_write_response(const BluetoothGATTWriteResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_bluetooth_gatt_write_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<BluetoothGATTWriteResponse>(msg, 83);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool APIServerConnectionBase::send_bluetooth_gatt_notify_response(const BluetoothGATTNotifyResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_bluetooth_gatt_notify_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<BluetoothGATTNotifyResponse>(msg, 84);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool APIServerConnectionBase::send_bluetooth_device_pairing_response(const BluetoothDevicePairingResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_bluetooth_device_pairing_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<BluetoothDevicePairingResponse>(msg, 85);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool APIServerConnectionBase::send_bluetooth_device_unpairing_response(const BluetoothDeviceUnpairingResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_bluetooth_device_unpairing_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<BluetoothDeviceUnpairingResponse>(msg, 86);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool APIServerConnectionBase::send_bluetooth_device_clear_cache_response(const BluetoothDeviceClearCacheResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_bluetooth_device_clear_cache_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<BluetoothDeviceClearCacheResponse>(msg, 88);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool APIServerConnectionBase::send_bluetooth_scanner_state_response(const BluetoothScannerStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_bluetooth_scanner_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<BluetoothScannerStateResponse>(msg, 126);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
|
||||||
bool APIServerConnectionBase::send_voice_assistant_request(const VoiceAssistantRequest &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_voice_assistant_request: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<VoiceAssistantRequest>(msg, 90);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
|
||||||
bool APIServerConnectionBase::send_voice_assistant_audio(const VoiceAssistantAudio &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_voice_assistant_audio: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<VoiceAssistantAudio>(msg, 106);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
|
||||||
bool APIServerConnectionBase::send_voice_assistant_announce_finished(const VoiceAssistantAnnounceFinished &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_voice_assistant_announce_finished: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<VoiceAssistantAnnounceFinished>(msg, 120);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
|
||||||
bool APIServerConnectionBase::send_voice_assistant_configuration_response(
|
|
||||||
const VoiceAssistantConfigurationResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_voice_assistant_configuration_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<VoiceAssistantConfigurationResponse>(msg, 122);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
|
||||||
#endif
|
|
||||||
#ifdef USE_ALARM_CONTROL_PANEL
|
|
||||||
bool APIServerConnectionBase::send_list_entities_alarm_control_panel_response(
|
|
||||||
const ListEntitiesAlarmControlPanelResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_alarm_control_panel_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesAlarmControlPanelResponse>(msg, 94);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_ALARM_CONTROL_PANEL
|
|
||||||
bool APIServerConnectionBase::send_alarm_control_panel_state_response(const AlarmControlPanelStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_alarm_control_panel_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<AlarmControlPanelStateResponse>(msg, 95);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_ALARM_CONTROL_PANEL
|
|
||||||
#endif
|
|
||||||
#ifdef USE_TEXT
|
|
||||||
bool APIServerConnectionBase::send_list_entities_text_response(const ListEntitiesTextResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_text_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesTextResponse>(msg, 97);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_TEXT
|
|
||||||
bool APIServerConnectionBase::send_text_state_response(const TextStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_text_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<TextStateResponse>(msg, 98);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_TEXT
|
|
||||||
#endif
|
|
||||||
#ifdef USE_DATETIME_DATE
|
|
||||||
bool APIServerConnectionBase::send_list_entities_date_response(const ListEntitiesDateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_date_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesDateResponse>(msg, 100);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_DATETIME_DATE
|
|
||||||
bool APIServerConnectionBase::send_date_state_response(const DateStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_date_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<DateStateResponse>(msg, 101);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_DATETIME_DATE
|
|
||||||
#endif
|
|
||||||
#ifdef USE_DATETIME_TIME
|
|
||||||
bool APIServerConnectionBase::send_list_entities_time_response(const ListEntitiesTimeResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_time_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesTimeResponse>(msg, 103);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_DATETIME_TIME
|
|
||||||
bool APIServerConnectionBase::send_time_state_response(const TimeStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_time_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<TimeStateResponse>(msg, 104);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_DATETIME_TIME
|
|
||||||
#endif
|
|
||||||
#ifdef USE_EVENT
|
|
||||||
bool APIServerConnectionBase::send_list_entities_event_response(const ListEntitiesEventResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_event_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesEventResponse>(msg, 107);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_EVENT
|
|
||||||
bool APIServerConnectionBase::send_event_response(const EventResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_event_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<EventResponse>(msg, 108);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VALVE
|
|
||||||
bool APIServerConnectionBase::send_list_entities_valve_response(const ListEntitiesValveResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_valve_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesValveResponse>(msg, 109);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VALVE
|
|
||||||
bool APIServerConnectionBase::send_valve_state_response(const ValveStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_valve_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ValveStateResponse>(msg, 110);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VALVE
|
|
||||||
#endif
|
|
||||||
#ifdef USE_DATETIME_DATETIME
|
|
||||||
bool APIServerConnectionBase::send_list_entities_date_time_response(const ListEntitiesDateTimeResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_date_time_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesDateTimeResponse>(msg, 112);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_DATETIME_DATETIME
|
|
||||||
bool APIServerConnectionBase::send_date_time_state_response(const DateTimeStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_date_time_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<DateTimeStateResponse>(msg, 113);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_DATETIME_DATETIME
|
|
||||||
#endif
|
|
||||||
#ifdef USE_UPDATE
|
|
||||||
bool APIServerConnectionBase::send_list_entities_update_response(const ListEntitiesUpdateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_list_entities_update_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<ListEntitiesUpdateResponse>(msg, 116);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_UPDATE
|
|
||||||
bool APIServerConnectionBase::send_update_state_response(const UpdateStateResponse &msg) {
|
|
||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
||||||
ESP_LOGVV(TAG, "send_update_state_response: %s", msg.dump().c_str());
|
|
||||||
#endif
|
|
||||||
return this->send_message_<UpdateStateResponse>(msg, 117);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_UPDATE
|
|
||||||
#endif
|
|
||||||
bool APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) {
|
bool APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) {
|
||||||
switch (msg_type) {
|
switch (msg_type) {
|
||||||
case 1: {
|
case 1: {
|
||||||
@ -1273,25 +597,25 @@ bool APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
|||||||
|
|
||||||
void APIServerConnection::on_hello_request(const HelloRequest &msg) {
|
void APIServerConnection::on_hello_request(const HelloRequest &msg) {
|
||||||
HelloResponse ret = this->hello(msg);
|
HelloResponse ret = this->hello(msg);
|
||||||
if (!this->send_hello_response(ret)) {
|
if (!this->send_message(ret)) {
|
||||||
this->on_fatal_error();
|
this->on_fatal_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void APIServerConnection::on_connect_request(const ConnectRequest &msg) {
|
void APIServerConnection::on_connect_request(const ConnectRequest &msg) {
|
||||||
ConnectResponse ret = this->connect(msg);
|
ConnectResponse ret = this->connect(msg);
|
||||||
if (!this->send_connect_response(ret)) {
|
if (!this->send_message(ret)) {
|
||||||
this->on_fatal_error();
|
this->on_fatal_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void APIServerConnection::on_disconnect_request(const DisconnectRequest &msg) {
|
void APIServerConnection::on_disconnect_request(const DisconnectRequest &msg) {
|
||||||
DisconnectResponse ret = this->disconnect(msg);
|
DisconnectResponse ret = this->disconnect(msg);
|
||||||
if (!this->send_disconnect_response(ret)) {
|
if (!this->send_message(ret)) {
|
||||||
this->on_fatal_error();
|
this->on_fatal_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void APIServerConnection::on_ping_request(const PingRequest &msg) {
|
void APIServerConnection::on_ping_request(const PingRequest &msg) {
|
||||||
PingResponse ret = this->ping(msg);
|
PingResponse ret = this->ping(msg);
|
||||||
if (!this->send_ping_response(ret)) {
|
if (!this->send_message(ret)) {
|
||||||
this->on_fatal_error();
|
this->on_fatal_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1301,7 +625,7 @@ void APIServerConnection::on_device_info_request(const DeviceInfoRequest &msg) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DeviceInfoResponse ret = this->device_info(msg);
|
DeviceInfoResponse ret = this->device_info(msg);
|
||||||
if (!this->send_device_info_response(ret)) {
|
if (!this->send_message(ret)) {
|
||||||
this->on_fatal_error();
|
this->on_fatal_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1367,7 +691,7 @@ void APIServerConnection::on_get_time_request(const GetTimeRequest &msg) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GetTimeResponse ret = this->get_time(msg);
|
GetTimeResponse ret = this->get_time(msg);
|
||||||
if (!this->send_get_time_response(ret)) {
|
if (!this->send_message(ret)) {
|
||||||
this->on_fatal_error();
|
this->on_fatal_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1393,7 +717,7 @@ void APIServerConnection::on_noise_encryption_set_key_request(const NoiseEncrypt
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NoiseEncryptionSetKeyResponse ret = this->noise_encryption_set_key(msg);
|
NoiseEncryptionSetKeyResponse ret = this->noise_encryption_set_key(msg);
|
||||||
if (!this->send_noise_encryption_set_key_response(ret)) {
|
if (!this->send_message(ret)) {
|
||||||
this->on_fatal_error();
|
this->on_fatal_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1749,7 +1073,7 @@ void APIServerConnection::on_subscribe_bluetooth_connections_free_request(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BluetoothConnectionsFreeResponse ret = this->subscribe_bluetooth_connections_free(msg);
|
BluetoothConnectionsFreeResponse ret = this->subscribe_bluetooth_connections_free(msg);
|
||||||
if (!this->send_bluetooth_connections_free_response(ret)) {
|
if (!this->send_message(ret)) {
|
||||||
this->on_fatal_error();
|
this->on_fatal_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1805,7 +1129,7 @@ void APIServerConnection::on_voice_assistant_configuration_request(const VoiceAs
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
VoiceAssistantConfigurationResponse ret = this->voice_assistant_get_configuration(msg);
|
VoiceAssistantConfigurationResponse ret = this->voice_assistant_get_configuration(msg);
|
||||||
if (!this->send_voice_assistant_configuration_response(ret)) {
|
if (!this->send_message(ret)) {
|
||||||
this->on_fatal_error();
|
this->on_fatal_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,162 +10,94 @@ namespace api {
|
|||||||
|
|
||||||
class APIServerConnectionBase : public ProtoService {
|
class APIServerConnectionBase : public ProtoService {
|
||||||
public:
|
public:
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
protected:
|
||||||
|
void log_send_message_(const char *name, const std::string &dump);
|
||||||
|
|
||||||
|
public:
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename T> bool send_message(const T &msg) {
|
||||||
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
|
this->log_send_message_(T::message_name(), msg.dump());
|
||||||
|
#endif
|
||||||
|
return this->send_message_(msg, T::MESSAGE_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void on_hello_request(const HelloRequest &value){};
|
virtual void on_hello_request(const HelloRequest &value){};
|
||||||
bool send_hello_response(const HelloResponse &msg);
|
|
||||||
virtual void on_connect_request(const ConnectRequest &value){};
|
virtual void on_connect_request(const ConnectRequest &value){};
|
||||||
bool send_connect_response(const ConnectResponse &msg);
|
|
||||||
bool send_disconnect_request(const DisconnectRequest &msg);
|
|
||||||
virtual void on_disconnect_request(const DisconnectRequest &value){};
|
virtual void on_disconnect_request(const DisconnectRequest &value){};
|
||||||
bool send_disconnect_response(const DisconnectResponse &msg);
|
|
||||||
virtual void on_disconnect_response(const DisconnectResponse &value){};
|
virtual void on_disconnect_response(const DisconnectResponse &value){};
|
||||||
bool send_ping_request(const PingRequest &msg);
|
|
||||||
virtual void on_ping_request(const PingRequest &value){};
|
virtual void on_ping_request(const PingRequest &value){};
|
||||||
bool send_ping_response(const PingResponse &msg);
|
|
||||||
virtual void on_ping_response(const PingResponse &value){};
|
virtual void on_ping_response(const PingResponse &value){};
|
||||||
virtual void on_device_info_request(const DeviceInfoRequest &value){};
|
virtual void on_device_info_request(const DeviceInfoRequest &value){};
|
||||||
bool send_device_info_response(const DeviceInfoResponse &msg);
|
|
||||||
virtual void on_list_entities_request(const ListEntitiesRequest &value){};
|
virtual void on_list_entities_request(const ListEntitiesRequest &value){};
|
||||||
bool send_list_entities_done_response(const ListEntitiesDoneResponse &msg);
|
|
||||||
virtual void on_subscribe_states_request(const SubscribeStatesRequest &value){};
|
virtual void on_subscribe_states_request(const SubscribeStatesRequest &value){};
|
||||||
#ifdef USE_BINARY_SENSOR
|
|
||||||
bool send_list_entities_binary_sensor_response(const ListEntitiesBinarySensorResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BINARY_SENSOR
|
|
||||||
bool send_binary_sensor_state_response(const BinarySensorStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_COVER
|
|
||||||
bool send_list_entities_cover_response(const ListEntitiesCoverResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_COVER
|
|
||||||
bool send_cover_state_response(const CoverStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_COVER
|
#ifdef USE_COVER
|
||||||
virtual void on_cover_command_request(const CoverCommandRequest &value){};
|
virtual void on_cover_command_request(const CoverCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_FAN
|
|
||||||
bool send_list_entities_fan_response(const ListEntitiesFanResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_FAN
|
|
||||||
bool send_fan_state_response(const FanStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_FAN
|
#ifdef USE_FAN
|
||||||
virtual void on_fan_command_request(const FanCommandRequest &value){};
|
virtual void on_fan_command_request(const FanCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_LIGHT
|
|
||||||
bool send_list_entities_light_response(const ListEntitiesLightResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_LIGHT
|
|
||||||
bool send_light_state_response(const LightStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_LIGHT
|
#ifdef USE_LIGHT
|
||||||
virtual void on_light_command_request(const LightCommandRequest &value){};
|
virtual void on_light_command_request(const LightCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_SENSOR
|
|
||||||
bool send_list_entities_sensor_response(const ListEntitiesSensorResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SENSOR
|
|
||||||
bool send_sensor_state_response(const SensorStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SWITCH
|
|
||||||
bool send_list_entities_switch_response(const ListEntitiesSwitchResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SWITCH
|
|
||||||
bool send_switch_state_response(const SwitchStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SWITCH
|
#ifdef USE_SWITCH
|
||||||
virtual void on_switch_command_request(const SwitchCommandRequest &value){};
|
virtual void on_switch_command_request(const SwitchCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_TEXT_SENSOR
|
|
||||||
bool send_list_entities_text_sensor_response(const ListEntitiesTextSensorResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_TEXT_SENSOR
|
|
||||||
bool send_text_sensor_state_response(const TextSensorStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
virtual void on_subscribe_logs_request(const SubscribeLogsRequest &value){};
|
virtual void on_subscribe_logs_request(const SubscribeLogsRequest &value){};
|
||||||
bool send_subscribe_logs_response(const SubscribeLogsResponse &msg);
|
|
||||||
#ifdef USE_API_NOISE
|
#ifdef USE_API_NOISE
|
||||||
virtual void on_noise_encryption_set_key_request(const NoiseEncryptionSetKeyRequest &value){};
|
virtual void on_noise_encryption_set_key_request(const NoiseEncryptionSetKeyRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_API_NOISE
|
|
||||||
bool send_noise_encryption_set_key_response(const NoiseEncryptionSetKeyResponse &msg);
|
|
||||||
#endif
|
|
||||||
virtual void on_subscribe_homeassistant_services_request(const SubscribeHomeassistantServicesRequest &value){};
|
virtual void on_subscribe_homeassistant_services_request(const SubscribeHomeassistantServicesRequest &value){};
|
||||||
bool send_homeassistant_service_response(const HomeassistantServiceResponse &msg);
|
|
||||||
virtual void on_subscribe_home_assistant_states_request(const SubscribeHomeAssistantStatesRequest &value){};
|
virtual void on_subscribe_home_assistant_states_request(const SubscribeHomeAssistantStatesRequest &value){};
|
||||||
bool send_subscribe_home_assistant_state_response(const SubscribeHomeAssistantStateResponse &msg);
|
|
||||||
virtual void on_home_assistant_state_response(const HomeAssistantStateResponse &value){};
|
virtual void on_home_assistant_state_response(const HomeAssistantStateResponse &value){};
|
||||||
bool send_get_time_request(const GetTimeRequest &msg);
|
|
||||||
virtual void on_get_time_request(const GetTimeRequest &value){};
|
virtual void on_get_time_request(const GetTimeRequest &value){};
|
||||||
bool send_get_time_response(const GetTimeResponse &msg);
|
|
||||||
virtual void on_get_time_response(const GetTimeResponse &value){};
|
virtual void on_get_time_response(const GetTimeResponse &value){};
|
||||||
bool send_list_entities_services_response(const ListEntitiesServicesResponse &msg);
|
|
||||||
virtual void on_execute_service_request(const ExecuteServiceRequest &value){};
|
virtual void on_execute_service_request(const ExecuteServiceRequest &value){};
|
||||||
#ifdef USE_ESP32_CAMERA
|
|
||||||
bool send_list_entities_camera_response(const ListEntitiesCameraResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_ESP32_CAMERA
|
|
||||||
bool send_camera_image_response(const CameraImageResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_ESP32_CAMERA
|
#ifdef USE_ESP32_CAMERA
|
||||||
virtual void on_camera_image_request(const CameraImageRequest &value){};
|
virtual void on_camera_image_request(const CameraImageRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_CLIMATE
|
|
||||||
bool send_list_entities_climate_response(const ListEntitiesClimateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_CLIMATE
|
|
||||||
bool send_climate_state_response(const ClimateStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_CLIMATE
|
#ifdef USE_CLIMATE
|
||||||
virtual void on_climate_command_request(const ClimateCommandRequest &value){};
|
virtual void on_climate_command_request(const ClimateCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_NUMBER
|
|
||||||
bool send_list_entities_number_response(const ListEntitiesNumberResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_NUMBER
|
|
||||||
bool send_number_state_response(const NumberStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_NUMBER
|
#ifdef USE_NUMBER
|
||||||
virtual void on_number_command_request(const NumberCommandRequest &value){};
|
virtual void on_number_command_request(const NumberCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_SELECT
|
|
||||||
bool send_list_entities_select_response(const ListEntitiesSelectResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SELECT
|
|
||||||
bool send_select_state_response(const SelectStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SELECT
|
#ifdef USE_SELECT
|
||||||
virtual void on_select_command_request(const SelectCommandRequest &value){};
|
virtual void on_select_command_request(const SelectCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_SIREN
|
|
||||||
bool send_list_entities_siren_response(const ListEntitiesSirenResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SIREN
|
|
||||||
bool send_siren_state_response(const SirenStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_SIREN
|
#ifdef USE_SIREN
|
||||||
virtual void on_siren_command_request(const SirenCommandRequest &value){};
|
virtual void on_siren_command_request(const SirenCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_LOCK
|
|
||||||
bool send_list_entities_lock_response(const ListEntitiesLockResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_LOCK
|
|
||||||
bool send_lock_state_response(const LockStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_LOCK
|
#ifdef USE_LOCK
|
||||||
virtual void on_lock_command_request(const LockCommandRequest &value){};
|
virtual void on_lock_command_request(const LockCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_BUTTON
|
|
||||||
bool send_list_entities_button_response(const ListEntitiesButtonResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BUTTON
|
#ifdef USE_BUTTON
|
||||||
virtual void on_button_command_request(const ButtonCommandRequest &value){};
|
virtual void on_button_command_request(const ButtonCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_MEDIA_PLAYER
|
|
||||||
bool send_list_entities_media_player_response(const ListEntitiesMediaPlayerResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_MEDIA_PLAYER
|
|
||||||
bool send_media_player_state_response(const MediaPlayerStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_MEDIA_PLAYER
|
#ifdef USE_MEDIA_PLAYER
|
||||||
virtual void on_media_player_command_request(const MediaPlayerCommandRequest &value){};
|
virtual void on_media_player_command_request(const MediaPlayerCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
@ -173,33 +105,19 @@ class APIServerConnectionBase : public ProtoService {
|
|||||||
virtual void on_subscribe_bluetooth_le_advertisements_request(
|
virtual void on_subscribe_bluetooth_le_advertisements_request(
|
||||||
const SubscribeBluetoothLEAdvertisementsRequest &value){};
|
const SubscribeBluetoothLEAdvertisementsRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool send_bluetooth_le_advertisement_response(const BluetoothLEAdvertisementResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool send_bluetooth_le_raw_advertisements_response(const BluetoothLERawAdvertisementsResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
virtual void on_bluetooth_device_request(const BluetoothDeviceRequest &value){};
|
virtual void on_bluetooth_device_request(const BluetoothDeviceRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool send_bluetooth_device_connection_response(const BluetoothDeviceConnectionResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
virtual void on_bluetooth_gatt_get_services_request(const BluetoothGATTGetServicesRequest &value){};
|
virtual void on_bluetooth_gatt_get_services_request(const BluetoothGATTGetServicesRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool send_bluetooth_gatt_get_services_response(const BluetoothGATTGetServicesResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool send_bluetooth_gatt_get_services_done_response(const BluetoothGATTGetServicesDoneResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
virtual void on_bluetooth_gatt_read_request(const BluetoothGATTReadRequest &value){};
|
virtual void on_bluetooth_gatt_read_request(const BluetoothGATTReadRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool send_bluetooth_gatt_read_response(const BluetoothGATTReadResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
virtual void on_bluetooth_gatt_write_request(const BluetoothGATTWriteRequest &value){};
|
virtual void on_bluetooth_gatt_write_request(const BluetoothGATTWriteRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
@ -212,49 +130,23 @@ class APIServerConnectionBase : public ProtoService {
|
|||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
virtual void on_bluetooth_gatt_notify_request(const BluetoothGATTNotifyRequest &value){};
|
virtual void on_bluetooth_gatt_notify_request(const BluetoothGATTNotifyRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool send_bluetooth_gatt_notify_data_response(const BluetoothGATTNotifyDataResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
virtual void on_subscribe_bluetooth_connections_free_request(const SubscribeBluetoothConnectionsFreeRequest &value){};
|
virtual void on_subscribe_bluetooth_connections_free_request(const SubscribeBluetoothConnectionsFreeRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool send_bluetooth_connections_free_response(const BluetoothConnectionsFreeResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool send_bluetooth_gatt_error_response(const BluetoothGATTErrorResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool send_bluetooth_gatt_write_response(const BluetoothGATTWriteResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool send_bluetooth_gatt_notify_response(const BluetoothGATTNotifyResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool send_bluetooth_device_pairing_response(const BluetoothDevicePairingResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool send_bluetooth_device_unpairing_response(const BluetoothDeviceUnpairingResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
virtual void on_unsubscribe_bluetooth_le_advertisements_request(
|
virtual void on_unsubscribe_bluetooth_le_advertisements_request(
|
||||||
const UnsubscribeBluetoothLEAdvertisementsRequest &value){};
|
const UnsubscribeBluetoothLEAdvertisementsRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool send_bluetooth_device_clear_cache_response(const BluetoothDeviceClearCacheResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
|
||||||
bool send_bluetooth_scanner_state_response(const BluetoothScannerStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_BLUETOOTH_PROXY
|
#ifdef USE_BLUETOOTH_PROXY
|
||||||
virtual void on_bluetooth_scanner_set_mode_request(const BluetoothScannerSetModeRequest &value){};
|
virtual void on_bluetooth_scanner_set_mode_request(const BluetoothScannerSetModeRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
#ifdef USE_VOICE_ASSISTANT
|
||||||
virtual void on_subscribe_voice_assistant_request(const SubscribeVoiceAssistantRequest &value){};
|
virtual void on_subscribe_voice_assistant_request(const SubscribeVoiceAssistantRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
|
||||||
bool send_voice_assistant_request(const VoiceAssistantRequest &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
#ifdef USE_VOICE_ASSISTANT
|
||||||
virtual void on_voice_assistant_response(const VoiceAssistantResponse &value){};
|
virtual void on_voice_assistant_response(const VoiceAssistantResponse &value){};
|
||||||
#endif
|
#endif
|
||||||
@ -262,7 +154,6 @@ class APIServerConnectionBase : public ProtoService {
|
|||||||
virtual void on_voice_assistant_event_response(const VoiceAssistantEventResponse &value){};
|
virtual void on_voice_assistant_event_response(const VoiceAssistantEventResponse &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
#ifdef USE_VOICE_ASSISTANT
|
||||||
bool send_voice_assistant_audio(const VoiceAssistantAudio &msg);
|
|
||||||
virtual void on_voice_assistant_audio(const VoiceAssistantAudio &value){};
|
virtual void on_voice_assistant_audio(const VoiceAssistantAudio &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
#ifdef USE_VOICE_ASSISTANT
|
||||||
@ -271,84 +162,39 @@ class APIServerConnectionBase : public ProtoService {
|
|||||||
#ifdef USE_VOICE_ASSISTANT
|
#ifdef USE_VOICE_ASSISTANT
|
||||||
virtual void on_voice_assistant_announce_request(const VoiceAssistantAnnounceRequest &value){};
|
virtual void on_voice_assistant_announce_request(const VoiceAssistantAnnounceRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
|
||||||
bool send_voice_assistant_announce_finished(const VoiceAssistantAnnounceFinished &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
#ifdef USE_VOICE_ASSISTANT
|
||||||
virtual void on_voice_assistant_configuration_request(const VoiceAssistantConfigurationRequest &value){};
|
virtual void on_voice_assistant_configuration_request(const VoiceAssistantConfigurationRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
|
||||||
bool send_voice_assistant_configuration_response(const VoiceAssistantConfigurationResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VOICE_ASSISTANT
|
#ifdef USE_VOICE_ASSISTANT
|
||||||
virtual void on_voice_assistant_set_configuration(const VoiceAssistantSetConfiguration &value){};
|
virtual void on_voice_assistant_set_configuration(const VoiceAssistantSetConfiguration &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_ALARM_CONTROL_PANEL
|
|
||||||
bool send_list_entities_alarm_control_panel_response(const ListEntitiesAlarmControlPanelResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_ALARM_CONTROL_PANEL
|
|
||||||
bool send_alarm_control_panel_state_response(const AlarmControlPanelStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_ALARM_CONTROL_PANEL
|
#ifdef USE_ALARM_CONTROL_PANEL
|
||||||
virtual void on_alarm_control_panel_command_request(const AlarmControlPanelCommandRequest &value){};
|
virtual void on_alarm_control_panel_command_request(const AlarmControlPanelCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_TEXT
|
|
||||||
bool send_list_entities_text_response(const ListEntitiesTextResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_TEXT
|
|
||||||
bool send_text_state_response(const TextStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_TEXT
|
#ifdef USE_TEXT
|
||||||
virtual void on_text_command_request(const TextCommandRequest &value){};
|
virtual void on_text_command_request(const TextCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_DATETIME_DATE
|
|
||||||
bool send_list_entities_date_response(const ListEntitiesDateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_DATETIME_DATE
|
|
||||||
bool send_date_state_response(const DateStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_DATETIME_DATE
|
#ifdef USE_DATETIME_DATE
|
||||||
virtual void on_date_command_request(const DateCommandRequest &value){};
|
virtual void on_date_command_request(const DateCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_DATETIME_TIME
|
|
||||||
bool send_list_entities_time_response(const ListEntitiesTimeResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_DATETIME_TIME
|
|
||||||
bool send_time_state_response(const TimeStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_DATETIME_TIME
|
#ifdef USE_DATETIME_TIME
|
||||||
virtual void on_time_command_request(const TimeCommandRequest &value){};
|
virtual void on_time_command_request(const TimeCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_EVENT
|
|
||||||
bool send_list_entities_event_response(const ListEntitiesEventResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_EVENT
|
|
||||||
bool send_event_response(const EventResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VALVE
|
|
||||||
bool send_list_entities_valve_response(const ListEntitiesValveResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VALVE
|
|
||||||
bool send_valve_state_response(const ValveStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VALVE
|
#ifdef USE_VALVE
|
||||||
virtual void on_valve_command_request(const ValveCommandRequest &value){};
|
virtual void on_valve_command_request(const ValveCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_DATETIME_DATETIME
|
|
||||||
bool send_list_entities_date_time_response(const ListEntitiesDateTimeResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_DATETIME_DATETIME
|
|
||||||
bool send_date_time_state_response(const DateTimeStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_DATETIME_DATETIME
|
#ifdef USE_DATETIME_DATETIME
|
||||||
virtual void on_date_time_command_request(const DateTimeCommandRequest &value){};
|
virtual void on_date_time_command_request(const DateTimeCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_UPDATE
|
|
||||||
bool send_list_entities_update_response(const ListEntitiesUpdateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_UPDATE
|
|
||||||
bool send_update_state_response(const UpdateStateResponse &msg);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_UPDATE
|
#ifdef USE_UPDATE
|
||||||
virtual void on_update_command_request(const UpdateCommandRequest &value){};
|
virtual void on_update_command_request(const UpdateCommandRequest &value){};
|
||||||
#endif
|
#endif
|
||||||
|
@ -24,7 +24,11 @@ static const char *const TAG = "api";
|
|||||||
// APIServer
|
// APIServer
|
||||||
APIServer *global_api_server = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
APIServer *global_api_server = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||||
|
|
||||||
APIServer::APIServer() { global_api_server = this; }
|
APIServer::APIServer() {
|
||||||
|
global_api_server = this;
|
||||||
|
// Pre-allocate shared write buffer
|
||||||
|
shared_write_buffer_.reserve(64);
|
||||||
|
}
|
||||||
|
|
||||||
void APIServer::setup() {
|
void APIServer::setup() {
|
||||||
ESP_LOGCONFIG(TAG, "Running setup");
|
ESP_LOGCONFIG(TAG, "Running setup");
|
||||||
@ -227,7 +231,7 @@ void APIServer::on_binary_sensor_update(binary_sensor::BinarySensor *obj, bool s
|
|||||||
if (obj->is_internal())
|
if (obj->is_internal())
|
||||||
return;
|
return;
|
||||||
for (auto &c : this->clients_)
|
for (auto &c : this->clients_)
|
||||||
c->send_binary_sensor_state(obj, state);
|
c->send_binary_sensor_state(obj);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -263,7 +267,7 @@ void APIServer::on_sensor_update(sensor::Sensor *obj, float state) {
|
|||||||
if (obj->is_internal())
|
if (obj->is_internal())
|
||||||
return;
|
return;
|
||||||
for (auto &c : this->clients_)
|
for (auto &c : this->clients_)
|
||||||
c->send_sensor_state(obj, state);
|
c->send_sensor_state(obj);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -272,7 +276,7 @@ void APIServer::on_switch_update(switch_::Switch *obj, bool state) {
|
|||||||
if (obj->is_internal())
|
if (obj->is_internal())
|
||||||
return;
|
return;
|
||||||
for (auto &c : this->clients_)
|
for (auto &c : this->clients_)
|
||||||
c->send_switch_state(obj, state);
|
c->send_switch_state(obj);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -281,7 +285,7 @@ void APIServer::on_text_sensor_update(text_sensor::TextSensor *obj, const std::s
|
|||||||
if (obj->is_internal())
|
if (obj->is_internal())
|
||||||
return;
|
return;
|
||||||
for (auto &c : this->clients_)
|
for (auto &c : this->clients_)
|
||||||
c->send_text_sensor_state(obj, state);
|
c->send_text_sensor_state(obj);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -299,7 +303,7 @@ void APIServer::on_number_update(number::Number *obj, float state) {
|
|||||||
if (obj->is_internal())
|
if (obj->is_internal())
|
||||||
return;
|
return;
|
||||||
for (auto &c : this->clients_)
|
for (auto &c : this->clients_)
|
||||||
c->send_number_state(obj, state);
|
c->send_number_state(obj);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -335,7 +339,7 @@ void APIServer::on_text_update(text::Text *obj, const std::string &state) {
|
|||||||
if (obj->is_internal())
|
if (obj->is_internal())
|
||||||
return;
|
return;
|
||||||
for (auto &c : this->clients_)
|
for (auto &c : this->clients_)
|
||||||
c->send_text_state(obj, state);
|
c->send_text_state(obj);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -344,7 +348,7 @@ void APIServer::on_select_update(select::Select *obj, const std::string &state,
|
|||||||
if (obj->is_internal())
|
if (obj->is_internal())
|
||||||
return;
|
return;
|
||||||
for (auto &c : this->clients_)
|
for (auto &c : this->clients_)
|
||||||
c->send_select_state(obj, state);
|
c->send_select_state(obj);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -353,7 +357,7 @@ void APIServer::on_lock_update(lock::Lock *obj) {
|
|||||||
if (obj->is_internal())
|
if (obj->is_internal())
|
||||||
return;
|
return;
|
||||||
for (auto &c : this->clients_)
|
for (auto &c : this->clients_)
|
||||||
c->send_lock_state(obj, obj->state);
|
c->send_lock_state(obj);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -404,6 +408,8 @@ void APIServer::set_port(uint16_t port) { this->port_ = port; }
|
|||||||
|
|
||||||
void APIServer::set_password(const std::string &password) { this->password_ = password; }
|
void APIServer::set_password(const std::string &password) { this->password_ = password; }
|
||||||
|
|
||||||
|
void APIServer::set_batch_delay(uint32_t batch_delay) { this->batch_delay_ = batch_delay; }
|
||||||
|
|
||||||
void APIServer::send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
|
void APIServer::send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
|
||||||
for (auto &client : this->clients_) {
|
for (auto &client : this->clients_) {
|
||||||
client->send_homeassistant_service_call(call);
|
client->send_homeassistant_service_call(call);
|
||||||
@ -462,7 +468,7 @@ bool APIServer::save_noise_psk(psk_t psk, bool make_active) {
|
|||||||
ESP_LOGW(TAG, "Disconnecting all clients to reset connections");
|
ESP_LOGW(TAG, "Disconnecting all clients to reset connections");
|
||||||
this->set_noise_psk(psk);
|
this->set_noise_psk(psk);
|
||||||
for (auto &c : this->clients_) {
|
for (auto &c : this->clients_) {
|
||||||
c->send_disconnect_request(DisconnectRequest());
|
c->send_message(DisconnectRequest());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -492,7 +498,7 @@ void APIServer::on_shutdown() {
|
|||||||
|
|
||||||
// Send disconnect requests to all connected clients
|
// Send disconnect requests to all connected clients
|
||||||
for (auto &c : this->clients_) {
|
for (auto &c : this->clients_) {
|
||||||
if (!c->send_disconnect_request(DisconnectRequest())) {
|
if (!c->send_message(DisconnectRequest())) {
|
||||||
// If we can't send the disconnect request, mark for immediate closure
|
// If we can't send the disconnect request, mark for immediate closure
|
||||||
c->next_close_ = true;
|
c->next_close_ = true;
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,11 @@ class APIServer : public Component, public Controller {
|
|||||||
void set_port(uint16_t port);
|
void set_port(uint16_t port);
|
||||||
void set_password(const std::string &password);
|
void set_password(const std::string &password);
|
||||||
void set_reboot_timeout(uint32_t reboot_timeout);
|
void set_reboot_timeout(uint32_t reboot_timeout);
|
||||||
|
void set_batch_delay(uint32_t batch_delay);
|
||||||
|
uint32_t get_batch_delay() const { return batch_delay_; }
|
||||||
|
|
||||||
|
// Get reference to shared buffer for API connections
|
||||||
|
std::vector<uint8_t> &get_shared_buffer_ref() { return shared_write_buffer_; }
|
||||||
|
|
||||||
#ifdef USE_API_NOISE
|
#ifdef USE_API_NOISE
|
||||||
bool save_noise_psk(psk_t psk, bool make_active = true);
|
bool save_noise_psk(psk_t psk, bool make_active = true);
|
||||||
@ -141,9 +146,11 @@ class APIServer : public Component, public Controller {
|
|||||||
std::unique_ptr<socket::Socket> socket_ = nullptr;
|
std::unique_ptr<socket::Socket> socket_ = nullptr;
|
||||||
uint16_t port_{6053};
|
uint16_t port_{6053};
|
||||||
uint32_t reboot_timeout_{300000};
|
uint32_t reboot_timeout_{300000};
|
||||||
|
uint32_t batch_delay_{100};
|
||||||
uint32_t last_connected_{0};
|
uint32_t last_connected_{0};
|
||||||
std::vector<std::unique_ptr<APIConnection>> clients_;
|
std::vector<std::unique_ptr<APIConnection>> clients_;
|
||||||
std::string password_;
|
std::string password_;
|
||||||
|
std::vector<uint8_t> shared_write_buffer_; // Shared proto write buffer for all connections
|
||||||
std::vector<HomeAssistantStateSubscription> state_subs_;
|
std::vector<HomeAssistantStateSubscription> state_subs_;
|
||||||
std::vector<UserServiceDescriptor *> user_services_;
|
std::vector<UserServiceDescriptor *> user_services_;
|
||||||
Trigger<std::string, std::string> *client_connected_trigger_ = new Trigger<std::string, std::string>();
|
Trigger<std::string, std::string> *client_connected_trigger_ = new Trigger<std::string, std::string>();
|
||||||
|
@ -73,7 +73,7 @@ bool ListEntitiesIterator::on_end() { return this->client_->send_list_info_done(
|
|||||||
ListEntitiesIterator::ListEntitiesIterator(APIConnection *client) : client_(client) {}
|
ListEntitiesIterator::ListEntitiesIterator(APIConnection *client) : client_(client) {}
|
||||||
bool ListEntitiesIterator::on_service(UserServiceDescriptor *service) {
|
bool ListEntitiesIterator::on_service(UserServiceDescriptor *service) {
|
||||||
auto resp = service->encode_list_service_response();
|
auto resp = service->encode_list_service_response();
|
||||||
return this->client_->send_list_entities_services_response(resp);
|
return this->client_->send_message(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_ESP32_CAMERA
|
#ifdef USE_ESP32_CAMERA
|
||||||
|
@ -360,11 +360,11 @@ class ProtoService {
|
|||||||
* @return A ProtoWriteBuffer object with the reserved size.
|
* @return A ProtoWriteBuffer object with the reserved size.
|
||||||
*/
|
*/
|
||||||
virtual ProtoWriteBuffer create_buffer(uint32_t reserve_size) = 0;
|
virtual ProtoWriteBuffer create_buffer(uint32_t reserve_size) = 0;
|
||||||
virtual bool send_buffer(ProtoWriteBuffer buffer, uint32_t message_type) = 0;
|
virtual bool send_buffer(ProtoWriteBuffer buffer, uint16_t message_type) = 0;
|
||||||
virtual bool read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) = 0;
|
virtual bool read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) = 0;
|
||||||
|
|
||||||
// Optimized method that pre-allocates buffer based on message size
|
// Optimized method that pre-allocates buffer based on message size
|
||||||
template<class C> bool send_message_(const C &msg, uint32_t message_type) {
|
bool send_message_(const ProtoMessage &msg, uint16_t message_type) {
|
||||||
uint32_t msg_size = 0;
|
uint32_t msg_size = 0;
|
||||||
msg.calculate_size(msg_size);
|
msg.calculate_size(msg_size);
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ namespace api {
|
|||||||
|
|
||||||
#ifdef USE_BINARY_SENSOR
|
#ifdef USE_BINARY_SENSOR
|
||||||
bool InitialStateIterator::on_binary_sensor(binary_sensor::BinarySensor *binary_sensor) {
|
bool InitialStateIterator::on_binary_sensor(binary_sensor::BinarySensor *binary_sensor) {
|
||||||
return this->client_->send_binary_sensor_state(binary_sensor, binary_sensor->state);
|
return this->client_->send_binary_sensor_state(binary_sensor);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_COVER
|
#ifdef USE_COVER
|
||||||
@ -21,27 +21,21 @@ bool InitialStateIterator::on_fan(fan::Fan *fan) { return this->client_->send_fa
|
|||||||
bool InitialStateIterator::on_light(light::LightState *light) { return this->client_->send_light_state(light); }
|
bool InitialStateIterator::on_light(light::LightState *light) { return this->client_->send_light_state(light); }
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
bool InitialStateIterator::on_sensor(sensor::Sensor *sensor) {
|
bool InitialStateIterator::on_sensor(sensor::Sensor *sensor) { return this->client_->send_sensor_state(sensor); }
|
||||||
return this->client_->send_sensor_state(sensor, sensor->state);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_SWITCH
|
#ifdef USE_SWITCH
|
||||||
bool InitialStateIterator::on_switch(switch_::Switch *a_switch) {
|
bool InitialStateIterator::on_switch(switch_::Switch *a_switch) { return this->client_->send_switch_state(a_switch); }
|
||||||
return this->client_->send_switch_state(a_switch, a_switch->state);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_TEXT_SENSOR
|
#ifdef USE_TEXT_SENSOR
|
||||||
bool InitialStateIterator::on_text_sensor(text_sensor::TextSensor *text_sensor) {
|
bool InitialStateIterator::on_text_sensor(text_sensor::TextSensor *text_sensor) {
|
||||||
return this->client_->send_text_sensor_state(text_sensor, text_sensor->state);
|
return this->client_->send_text_sensor_state(text_sensor);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_CLIMATE
|
#ifdef USE_CLIMATE
|
||||||
bool InitialStateIterator::on_climate(climate::Climate *climate) { return this->client_->send_climate_state(climate); }
|
bool InitialStateIterator::on_climate(climate::Climate *climate) { return this->client_->send_climate_state(climate); }
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_NUMBER
|
#ifdef USE_NUMBER
|
||||||
bool InitialStateIterator::on_number(number::Number *number) {
|
bool InitialStateIterator::on_number(number::Number *number) { return this->client_->send_number_state(number); }
|
||||||
return this->client_->send_number_state(number, number->state);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_DATETIME_DATE
|
#ifdef USE_DATETIME_DATE
|
||||||
bool InitialStateIterator::on_date(datetime::DateEntity *date) { return this->client_->send_date_state(date); }
|
bool InitialStateIterator::on_date(datetime::DateEntity *date) { return this->client_->send_date_state(date); }
|
||||||
@ -55,15 +49,13 @@ bool InitialStateIterator::on_datetime(datetime::DateTimeEntity *datetime) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_TEXT
|
#ifdef USE_TEXT
|
||||||
bool InitialStateIterator::on_text(text::Text *text) { return this->client_->send_text_state(text, text->state); }
|
bool InitialStateIterator::on_text(text::Text *text) { return this->client_->send_text_state(text); }
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_SELECT
|
#ifdef USE_SELECT
|
||||||
bool InitialStateIterator::on_select(select::Select *select) {
|
bool InitialStateIterator::on_select(select::Select *select) { return this->client_->send_select_state(select); }
|
||||||
return this->client_->send_select_state(select, select->state);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_LOCK
|
#ifdef USE_LOCK
|
||||||
bool InitialStateIterator::on_lock(lock::Lock *a_lock) { return this->client_->send_lock_state(a_lock, a_lock->state); }
|
bool InitialStateIterator::on_lock(lock::Lock *a_lock) { return this->client_->send_lock_state(a_lock); }
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_VALVE
|
#ifdef USE_VALVE
|
||||||
bool InitialStateIterator::on_valve(valve::Valve *valve) { return this->client_->send_valve_state(valve); }
|
bool InitialStateIterator::on_valve(valve::Valve *valve) { return this->client_->send_valve_state(valve); }
|
||||||
|
@ -75,7 +75,7 @@ bool BluetoothConnection::gattc_event_handler(esp_gattc_cb_event_t event, esp_ga
|
|||||||
resp.data.reserve(param->read.value_len);
|
resp.data.reserve(param->read.value_len);
|
||||||
// Use bulk insert instead of individual push_backs
|
// Use bulk insert instead of individual push_backs
|
||||||
resp.data.insert(resp.data.end(), param->read.value, param->read.value + param->read.value_len);
|
resp.data.insert(resp.data.end(), param->read.value, param->read.value + param->read.value_len);
|
||||||
this->proxy_->get_api_connection()->send_bluetooth_gatt_read_response(resp);
|
this->proxy_->get_api_connection()->send_message(resp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ESP_GATTC_WRITE_CHAR_EVT:
|
case ESP_GATTC_WRITE_CHAR_EVT:
|
||||||
@ -89,7 +89,7 @@ bool BluetoothConnection::gattc_event_handler(esp_gattc_cb_event_t event, esp_ga
|
|||||||
api::BluetoothGATTWriteResponse resp;
|
api::BluetoothGATTWriteResponse resp;
|
||||||
resp.address = this->address_;
|
resp.address = this->address_;
|
||||||
resp.handle = param->write.handle;
|
resp.handle = param->write.handle;
|
||||||
this->proxy_->get_api_connection()->send_bluetooth_gatt_write_response(resp);
|
this->proxy_->get_api_connection()->send_message(resp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ESP_GATTC_UNREG_FOR_NOTIFY_EVT: {
|
case ESP_GATTC_UNREG_FOR_NOTIFY_EVT: {
|
||||||
@ -103,7 +103,7 @@ bool BluetoothConnection::gattc_event_handler(esp_gattc_cb_event_t event, esp_ga
|
|||||||
api::BluetoothGATTNotifyResponse resp;
|
api::BluetoothGATTNotifyResponse resp;
|
||||||
resp.address = this->address_;
|
resp.address = this->address_;
|
||||||
resp.handle = param->unreg_for_notify.handle;
|
resp.handle = param->unreg_for_notify.handle;
|
||||||
this->proxy_->get_api_connection()->send_bluetooth_gatt_notify_response(resp);
|
this->proxy_->get_api_connection()->send_message(resp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
|
case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
|
||||||
@ -116,7 +116,7 @@ bool BluetoothConnection::gattc_event_handler(esp_gattc_cb_event_t event, esp_ga
|
|||||||
api::BluetoothGATTNotifyResponse resp;
|
api::BluetoothGATTNotifyResponse resp;
|
||||||
resp.address = this->address_;
|
resp.address = this->address_;
|
||||||
resp.handle = param->reg_for_notify.handle;
|
resp.handle = param->reg_for_notify.handle;
|
||||||
this->proxy_->get_api_connection()->send_bluetooth_gatt_notify_response(resp);
|
this->proxy_->get_api_connection()->send_message(resp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ESP_GATTC_NOTIFY_EVT: {
|
case ESP_GATTC_NOTIFY_EVT: {
|
||||||
@ -128,7 +128,7 @@ bool BluetoothConnection::gattc_event_handler(esp_gattc_cb_event_t event, esp_ga
|
|||||||
resp.data.reserve(param->notify.value_len);
|
resp.data.reserve(param->notify.value_len);
|
||||||
// Use bulk insert instead of individual push_backs
|
// Use bulk insert instead of individual push_backs
|
||||||
resp.data.insert(resp.data.end(), param->notify.value, param->notify.value + param->notify.value_len);
|
resp.data.insert(resp.data.end(), param->notify.value, param->notify.value + param->notify.value_len);
|
||||||
this->proxy_->get_api_connection()->send_bluetooth_gatt_notify_data_response(resp);
|
this->proxy_->get_api_connection()->send_message(resp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -39,7 +39,7 @@ void BluetoothProxy::send_bluetooth_scanner_state_(esp32_ble_tracker::ScannerSta
|
|||||||
resp.state = static_cast<api::enums::BluetoothScannerState>(state);
|
resp.state = static_cast<api::enums::BluetoothScannerState>(state);
|
||||||
resp.mode = this->parent_->get_scan_active() ? api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_ACTIVE
|
resp.mode = this->parent_->get_scan_active() ? api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_ACTIVE
|
||||||
: api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_PASSIVE;
|
: api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_PASSIVE;
|
||||||
this->api_connection_->send_bluetooth_scanner_state_response(resp);
|
this->api_connection_->send_message(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BluetoothProxy::parse_device(const esp32_ble_tracker::ESPBTDevice &device) {
|
bool BluetoothProxy::parse_device(const esp32_ble_tracker::ESPBTDevice &device) {
|
||||||
@ -103,7 +103,7 @@ void BluetoothProxy::flush_pending_advertisements() {
|
|||||||
|
|
||||||
api::BluetoothLERawAdvertisementsResponse resp;
|
api::BluetoothLERawAdvertisementsResponse resp;
|
||||||
resp.advertisements.swap(batch_buffer);
|
resp.advertisements.swap(batch_buffer);
|
||||||
this->api_connection_->send_bluetooth_le_raw_advertisements_response(resp);
|
this->api_connection_->send_message(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BluetoothProxy::send_api_packet_(const esp32_ble_tracker::ESPBTDevice &device) {
|
void BluetoothProxy::send_api_packet_(const esp32_ble_tracker::ESPBTDevice &device) {
|
||||||
@ -141,7 +141,7 @@ void BluetoothProxy::send_api_packet_(const esp32_ble_tracker::ESPBTDevice &devi
|
|||||||
manufacturer_data.data.assign(data.data.begin(), data.data.end());
|
manufacturer_data.data.assign(data.data.begin(), data.data.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
this->api_connection_->send_bluetooth_le_advertisement(resp);
|
this->api_connection_->send_message(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BluetoothProxy::dump_config() {
|
void BluetoothProxy::dump_config() {
|
||||||
@ -302,7 +302,7 @@ void BluetoothProxy::loop() {
|
|||||||
service_resp.characteristics.push_back(std::move(characteristic_resp));
|
service_resp.characteristics.push_back(std::move(characteristic_resp));
|
||||||
}
|
}
|
||||||
resp.services.push_back(std::move(service_resp));
|
resp.services.push_back(std::move(service_resp));
|
||||||
this->api_connection_->send_bluetooth_gatt_get_services_response(resp);
|
this->api_connection_->send_message(resp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -455,7 +455,7 @@ void BluetoothProxy::bluetooth_device_request(const api::BluetoothDeviceRequest
|
|||||||
call.success = ret == ESP_OK;
|
call.success = ret == ESP_OK;
|
||||||
call.error = ret;
|
call.error = ret;
|
||||||
|
|
||||||
this->api_connection_->send_bluetooth_device_clear_cache_response(call);
|
this->api_connection_->send_message(call);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -579,7 +579,7 @@ void BluetoothProxy::send_device_connection(uint64_t address, bool connected, ui
|
|||||||
call.connected = connected;
|
call.connected = connected;
|
||||||
call.mtu = mtu;
|
call.mtu = mtu;
|
||||||
call.error = error;
|
call.error = error;
|
||||||
this->api_connection_->send_bluetooth_device_connection_response(call);
|
this->api_connection_->send_message(call);
|
||||||
}
|
}
|
||||||
void BluetoothProxy::send_connections_free() {
|
void BluetoothProxy::send_connections_free() {
|
||||||
if (this->api_connection_ == nullptr)
|
if (this->api_connection_ == nullptr)
|
||||||
@ -592,7 +592,7 @@ void BluetoothProxy::send_connections_free() {
|
|||||||
call.allocated.push_back(connection->address_);
|
call.allocated.push_back(connection->address_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->api_connection_->send_bluetooth_connections_free_response(call);
|
this->api_connection_->send_message(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BluetoothProxy::send_gatt_services_done(uint64_t address) {
|
void BluetoothProxy::send_gatt_services_done(uint64_t address) {
|
||||||
@ -600,7 +600,7 @@ void BluetoothProxy::send_gatt_services_done(uint64_t address) {
|
|||||||
return;
|
return;
|
||||||
api::BluetoothGATTGetServicesDoneResponse call;
|
api::BluetoothGATTGetServicesDoneResponse call;
|
||||||
call.address = address;
|
call.address = address;
|
||||||
this->api_connection_->send_bluetooth_gatt_get_services_done_response(call);
|
this->api_connection_->send_message(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BluetoothProxy::send_gatt_error(uint64_t address, uint16_t handle, esp_err_t error) {
|
void BluetoothProxy::send_gatt_error(uint64_t address, uint16_t handle, esp_err_t error) {
|
||||||
@ -610,7 +610,7 @@ void BluetoothProxy::send_gatt_error(uint64_t address, uint16_t handle, esp_err_
|
|||||||
call.address = address;
|
call.address = address;
|
||||||
call.handle = handle;
|
call.handle = handle;
|
||||||
call.error = error;
|
call.error = error;
|
||||||
this->api_connection_->send_bluetooth_gatt_error_response(call);
|
this->api_connection_->send_message(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BluetoothProxy::send_device_pairing(uint64_t address, bool paired, esp_err_t error) {
|
void BluetoothProxy::send_device_pairing(uint64_t address, bool paired, esp_err_t error) {
|
||||||
@ -619,7 +619,7 @@ void BluetoothProxy::send_device_pairing(uint64_t address, bool paired, esp_err_
|
|||||||
call.paired = paired;
|
call.paired = paired;
|
||||||
call.error = error;
|
call.error = error;
|
||||||
|
|
||||||
this->api_connection_->send_bluetooth_device_pairing_response(call);
|
this->api_connection_->send_message(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BluetoothProxy::send_device_unpairing(uint64_t address, bool success, esp_err_t error) {
|
void BluetoothProxy::send_device_unpairing(uint64_t address, bool success, esp_err_t error) {
|
||||||
@ -628,7 +628,7 @@ void BluetoothProxy::send_device_unpairing(uint64_t address, bool success, esp_e
|
|||||||
call.success = success;
|
call.success = success;
|
||||||
call.error = error;
|
call.error = error;
|
||||||
|
|
||||||
this->api_connection_->send_bluetooth_device_unpairing_response(call);
|
this->api_connection_->send_message(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BluetoothProxy::bluetooth_scanner_set_mode(bool active) {
|
void BluetoothProxy::bluetooth_scanner_set_mode(bool active) {
|
||||||
|
@ -223,7 +223,7 @@ void VoiceAssistant::loop() {
|
|||||||
msg.wake_word_phrase = this->wake_word_;
|
msg.wake_word_phrase = this->wake_word_;
|
||||||
this->wake_word_ = "";
|
this->wake_word_ = "";
|
||||||
|
|
||||||
if (this->api_client_ == nullptr || !this->api_client_->send_voice_assistant_request(msg)) {
|
if (this->api_client_ == nullptr || !this->api_client_->send_message(msg)) {
|
||||||
ESP_LOGW(TAG, "Could not request start");
|
ESP_LOGW(TAG, "Could not request start");
|
||||||
this->error_trigger_->trigger("not-connected", "Could not request start");
|
this->error_trigger_->trigger("not-connected", "Could not request start");
|
||||||
this->continuous_ = false;
|
this->continuous_ = false;
|
||||||
@ -245,7 +245,7 @@ void VoiceAssistant::loop() {
|
|||||||
if (this->audio_mode_ == AUDIO_MODE_API) {
|
if (this->audio_mode_ == AUDIO_MODE_API) {
|
||||||
api::VoiceAssistantAudio msg;
|
api::VoiceAssistantAudio msg;
|
||||||
msg.data.assign((char *) this->send_buffer_, read_bytes);
|
msg.data.assign((char *) this->send_buffer_, read_bytes);
|
||||||
this->api_client_->send_voice_assistant_audio(msg);
|
this->api_client_->send_message(msg);
|
||||||
} else {
|
} else {
|
||||||
if (!this->udp_socket_running_) {
|
if (!this->udp_socket_running_) {
|
||||||
if (!this->start_udp_socket_()) {
|
if (!this->start_udp_socket_()) {
|
||||||
@ -331,7 +331,7 @@ void VoiceAssistant::loop() {
|
|||||||
|
|
||||||
api::VoiceAssistantAnnounceFinished msg;
|
api::VoiceAssistantAnnounceFinished msg;
|
||||||
msg.success = true;
|
msg.success = true;
|
||||||
this->api_client_->send_voice_assistant_announce_finished(msg);
|
this->api_client_->send_message(msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -580,7 +580,7 @@ void VoiceAssistant::signal_stop_() {
|
|||||||
ESP_LOGD(TAG, "Signaling stop");
|
ESP_LOGD(TAG, "Signaling stop");
|
||||||
api::VoiceAssistantRequest msg;
|
api::VoiceAssistantRequest msg;
|
||||||
msg.start = false;
|
msg.start = false;
|
||||||
this->api_client_->send_voice_assistant_request(msg);
|
this->api_client_->send_message(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoiceAssistant::start_playback_timeout_() {
|
void VoiceAssistant::start_playback_timeout_() {
|
||||||
@ -590,7 +590,7 @@ void VoiceAssistant::start_playback_timeout_() {
|
|||||||
|
|
||||||
api::VoiceAssistantAnnounceFinished msg;
|
api::VoiceAssistantAnnounceFinished msg;
|
||||||
msg.success = true;
|
msg.success = true;
|
||||||
this->api_client_->send_voice_assistant_announce_finished(msg);
|
this->api_client_->send_message(msg);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,6 +258,14 @@ class TypeInfo(ABC):
|
|||||||
force: Whether to force encoding the field even if it has a default value
|
force: Whether to force encoding the field even if it has a default value
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
"""Get estimated size in bytes for this field with typical values.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Estimated size in bytes including field ID and typical data
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
TYPE_INFO: dict[int, TypeInfo] = {}
|
TYPE_INFO: dict[int, TypeInfo] = {}
|
||||||
|
|
||||||
@ -291,6 +299,9 @@ class DoubleType(TypeInfo):
|
|||||||
o = f"ProtoSize::add_fixed_field<8>(total_size, {field_id_size}, {name} != 0.0, {force_str(force)});"
|
o = f"ProtoSize::add_fixed_field<8>(total_size, {field_id_size}, {name} != 0.0, {force_str(force)});"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
return self.calculate_field_id_size() + 8 # field ID + 8 bytes for double
|
||||||
|
|
||||||
|
|
||||||
@register_type(2)
|
@register_type(2)
|
||||||
class FloatType(TypeInfo):
|
class FloatType(TypeInfo):
|
||||||
@ -310,6 +321,9 @@ class FloatType(TypeInfo):
|
|||||||
o = f"ProtoSize::add_fixed_field<4>(total_size, {field_id_size}, {name} != 0.0f, {force_str(force)});"
|
o = f"ProtoSize::add_fixed_field<4>(total_size, {field_id_size}, {name} != 0.0f, {force_str(force)});"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
return self.calculate_field_id_size() + 4 # field ID + 4 bytes for float
|
||||||
|
|
||||||
|
|
||||||
@register_type(3)
|
@register_type(3)
|
||||||
class Int64Type(TypeInfo):
|
class Int64Type(TypeInfo):
|
||||||
@ -329,6 +343,9 @@ class Int64Type(TypeInfo):
|
|||||||
o = f"ProtoSize::add_int64_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
o = f"ProtoSize::add_int64_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
return self.calculate_field_id_size() + 3 # field ID + 3 bytes typical varint
|
||||||
|
|
||||||
|
|
||||||
@register_type(4)
|
@register_type(4)
|
||||||
class UInt64Type(TypeInfo):
|
class UInt64Type(TypeInfo):
|
||||||
@ -348,6 +365,9 @@ class UInt64Type(TypeInfo):
|
|||||||
o = f"ProtoSize::add_uint64_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
o = f"ProtoSize::add_uint64_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
return self.calculate_field_id_size() + 3 # field ID + 3 bytes typical varint
|
||||||
|
|
||||||
|
|
||||||
@register_type(5)
|
@register_type(5)
|
||||||
class Int32Type(TypeInfo):
|
class Int32Type(TypeInfo):
|
||||||
@ -367,6 +387,9 @@ class Int32Type(TypeInfo):
|
|||||||
o = f"ProtoSize::add_int32_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
o = f"ProtoSize::add_int32_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
return self.calculate_field_id_size() + 3 # field ID + 3 bytes typical varint
|
||||||
|
|
||||||
|
|
||||||
@register_type(6)
|
@register_type(6)
|
||||||
class Fixed64Type(TypeInfo):
|
class Fixed64Type(TypeInfo):
|
||||||
@ -386,6 +409,9 @@ class Fixed64Type(TypeInfo):
|
|||||||
o = f"ProtoSize::add_fixed_field<8>(total_size, {field_id_size}, {name} != 0, {force_str(force)});"
|
o = f"ProtoSize::add_fixed_field<8>(total_size, {field_id_size}, {name} != 0, {force_str(force)});"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
return self.calculate_field_id_size() + 8 # field ID + 8 bytes fixed
|
||||||
|
|
||||||
|
|
||||||
@register_type(7)
|
@register_type(7)
|
||||||
class Fixed32Type(TypeInfo):
|
class Fixed32Type(TypeInfo):
|
||||||
@ -405,6 +431,9 @@ class Fixed32Type(TypeInfo):
|
|||||||
o = f"ProtoSize::add_fixed_field<4>(total_size, {field_id_size}, {name} != 0, {force_str(force)});"
|
o = f"ProtoSize::add_fixed_field<4>(total_size, {field_id_size}, {name} != 0, {force_str(force)});"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
return self.calculate_field_id_size() + 4 # field ID + 4 bytes fixed
|
||||||
|
|
||||||
|
|
||||||
@register_type(8)
|
@register_type(8)
|
||||||
class BoolType(TypeInfo):
|
class BoolType(TypeInfo):
|
||||||
@ -423,6 +452,9 @@ class BoolType(TypeInfo):
|
|||||||
o = f"ProtoSize::add_bool_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
o = f"ProtoSize::add_bool_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
return self.calculate_field_id_size() + 1 # field ID + 1 byte
|
||||||
|
|
||||||
|
|
||||||
@register_type(9)
|
@register_type(9)
|
||||||
class StringType(TypeInfo):
|
class StringType(TypeInfo):
|
||||||
@ -443,6 +475,9 @@ class StringType(TypeInfo):
|
|||||||
o = f"ProtoSize::add_string_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
o = f"ProtoSize::add_string_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
return self.calculate_field_id_size() + 8 # field ID + 8 bytes typical string
|
||||||
|
|
||||||
|
|
||||||
@register_type(11)
|
@register_type(11)
|
||||||
class MessageType(TypeInfo):
|
class MessageType(TypeInfo):
|
||||||
@ -478,6 +513,11 @@ class MessageType(TypeInfo):
|
|||||||
o = f"ProtoSize::add_message_object(total_size, {field_id_size}, {name}, {force_str(force)});"
|
o = f"ProtoSize::add_message_object(total_size, {field_id_size}, {name}, {force_str(force)});"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
return (
|
||||||
|
self.calculate_field_id_size() + 16
|
||||||
|
) # field ID + 16 bytes estimated submessage
|
||||||
|
|
||||||
|
|
||||||
@register_type(12)
|
@register_type(12)
|
||||||
class BytesType(TypeInfo):
|
class BytesType(TypeInfo):
|
||||||
@ -498,6 +538,9 @@ class BytesType(TypeInfo):
|
|||||||
o = f"ProtoSize::add_string_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
o = f"ProtoSize::add_string_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
return self.calculate_field_id_size() + 8 # field ID + 8 bytes typical bytes
|
||||||
|
|
||||||
|
|
||||||
@register_type(13)
|
@register_type(13)
|
||||||
class UInt32Type(TypeInfo):
|
class UInt32Type(TypeInfo):
|
||||||
@ -517,6 +560,9 @@ class UInt32Type(TypeInfo):
|
|||||||
o = f"ProtoSize::add_uint32_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
o = f"ProtoSize::add_uint32_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
return self.calculate_field_id_size() + 3 # field ID + 3 bytes typical varint
|
||||||
|
|
||||||
|
|
||||||
@register_type(14)
|
@register_type(14)
|
||||||
class EnumType(TypeInfo):
|
class EnumType(TypeInfo):
|
||||||
@ -544,6 +590,9 @@ class EnumType(TypeInfo):
|
|||||||
o = f"ProtoSize::add_enum_field(total_size, {field_id_size}, static_cast<uint32_t>({name}), {force_str(force)});"
|
o = f"ProtoSize::add_enum_field(total_size, {field_id_size}, static_cast<uint32_t>({name}), {force_str(force)});"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
return self.calculate_field_id_size() + 1 # field ID + 1 byte typical enum
|
||||||
|
|
||||||
|
|
||||||
@register_type(15)
|
@register_type(15)
|
||||||
class SFixed32Type(TypeInfo):
|
class SFixed32Type(TypeInfo):
|
||||||
@ -563,6 +612,9 @@ class SFixed32Type(TypeInfo):
|
|||||||
o = f"ProtoSize::add_fixed_field<4>(total_size, {field_id_size}, {name} != 0, {force_str(force)});"
|
o = f"ProtoSize::add_fixed_field<4>(total_size, {field_id_size}, {name} != 0, {force_str(force)});"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
return self.calculate_field_id_size() + 4 # field ID + 4 bytes fixed
|
||||||
|
|
||||||
|
|
||||||
@register_type(16)
|
@register_type(16)
|
||||||
class SFixed64Type(TypeInfo):
|
class SFixed64Type(TypeInfo):
|
||||||
@ -582,6 +634,9 @@ class SFixed64Type(TypeInfo):
|
|||||||
o = f"ProtoSize::add_fixed_field<8>(total_size, {field_id_size}, {name} != 0, {force_str(force)});"
|
o = f"ProtoSize::add_fixed_field<8>(total_size, {field_id_size}, {name} != 0, {force_str(force)});"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
return self.calculate_field_id_size() + 8 # field ID + 8 bytes fixed
|
||||||
|
|
||||||
|
|
||||||
@register_type(17)
|
@register_type(17)
|
||||||
class SInt32Type(TypeInfo):
|
class SInt32Type(TypeInfo):
|
||||||
@ -601,6 +656,9 @@ class SInt32Type(TypeInfo):
|
|||||||
o = f"ProtoSize::add_sint32_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
o = f"ProtoSize::add_sint32_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
return self.calculate_field_id_size() + 3 # field ID + 3 bytes typical varint
|
||||||
|
|
||||||
|
|
||||||
@register_type(18)
|
@register_type(18)
|
||||||
class SInt64Type(TypeInfo):
|
class SInt64Type(TypeInfo):
|
||||||
@ -620,6 +678,9 @@ class SInt64Type(TypeInfo):
|
|||||||
o = f"ProtoSize::add_sint64_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
o = f"ProtoSize::add_sint64_field(total_size, {field_id_size}, {name}, {force_str(force)});"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
return self.calculate_field_id_size() + 3 # field ID + 3 bytes typical varint
|
||||||
|
|
||||||
|
|
||||||
class RepeatedTypeInfo(TypeInfo):
|
class RepeatedTypeInfo(TypeInfo):
|
||||||
def __init__(self, field: descriptor.FieldDescriptorProto) -> None:
|
def __init__(self, field: descriptor.FieldDescriptorProto) -> None:
|
||||||
@ -738,6 +799,15 @@ class RepeatedTypeInfo(TypeInfo):
|
|||||||
o += "}"
|
o += "}"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def get_estimated_size(self) -> int:
|
||||||
|
# For repeated fields, estimate underlying type size * 2 (assume 2 items typically)
|
||||||
|
underlying_size = (
|
||||||
|
self._ti.get_estimated_size()
|
||||||
|
if hasattr(self._ti, "get_estimated_size")
|
||||||
|
else 8
|
||||||
|
)
|
||||||
|
return underlying_size * 2
|
||||||
|
|
||||||
|
|
||||||
def build_enum_type(desc) -> tuple[str, str]:
|
def build_enum_type(desc) -> tuple[str, str]:
|
||||||
"""Builds the enum type."""
|
"""Builds the enum type."""
|
||||||
@ -762,6 +832,22 @@ def build_enum_type(desc) -> tuple[str, str]:
|
|||||||
return out, cpp
|
return out, cpp
|
||||||
|
|
||||||
|
|
||||||
|
def calculate_message_estimated_size(desc: descriptor.DescriptorProto) -> int:
|
||||||
|
"""Calculate estimated size for a complete message based on typical values."""
|
||||||
|
total_size = 0
|
||||||
|
|
||||||
|
for field in desc.field:
|
||||||
|
if field.label == 3: # repeated
|
||||||
|
ti = RepeatedTypeInfo(field)
|
||||||
|
else:
|
||||||
|
ti = TYPE_INFO[field.type](field)
|
||||||
|
|
||||||
|
# Add estimated size for this field
|
||||||
|
total_size += ti.get_estimated_size()
|
||||||
|
|
||||||
|
return total_size
|
||||||
|
|
||||||
|
|
||||||
def build_message_type(desc: descriptor.DescriptorProto) -> tuple[str, str]:
|
def build_message_type(desc: descriptor.DescriptorProto) -> tuple[str, str]:
|
||||||
public_content: list[str] = []
|
public_content: list[str] = []
|
||||||
protected_content: list[str] = []
|
protected_content: list[str] = []
|
||||||
@ -773,6 +859,28 @@ def build_message_type(desc: descriptor.DescriptorProto) -> tuple[str, str]:
|
|||||||
dump: list[str] = []
|
dump: list[str] = []
|
||||||
size_calc: list[str] = []
|
size_calc: list[str] = []
|
||||||
|
|
||||||
|
# Get message ID if it's a service message
|
||||||
|
message_id: int | None = get_opt(desc, pb.id)
|
||||||
|
|
||||||
|
# Add MESSAGE_TYPE method if this is a service message
|
||||||
|
if message_id is not None:
|
||||||
|
# Add static constexpr for message type
|
||||||
|
public_content.append(f"static constexpr uint16_t MESSAGE_TYPE = {message_id};")
|
||||||
|
|
||||||
|
# Add estimated size constant
|
||||||
|
estimated_size = calculate_message_estimated_size(desc)
|
||||||
|
public_content.append(
|
||||||
|
f"static constexpr uint16_t ESTIMATED_SIZE = {estimated_size};"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add message_name method for debugging
|
||||||
|
public_content.append("#ifdef HAS_PROTO_MESSAGE_DUMP")
|
||||||
|
snake_name = camel_to_snake(desc.name)
|
||||||
|
public_content.append(
|
||||||
|
f'static constexpr const char *message_name() {{ return "{snake_name}"; }}'
|
||||||
|
)
|
||||||
|
public_content.append("#endif")
|
||||||
|
|
||||||
for field in desc.field:
|
for field in desc.field:
|
||||||
if field.label == 3:
|
if field.label == 3:
|
||||||
ti = RepeatedTypeInfo(field)
|
ti = RepeatedTypeInfo(field)
|
||||||
@ -941,24 +1049,18 @@ def build_service_message_type(
|
|||||||
hout = ""
|
hout = ""
|
||||||
cout = ""
|
cout = ""
|
||||||
|
|
||||||
|
# Store ifdef for later use
|
||||||
if ifdef is not None:
|
if ifdef is not None:
|
||||||
ifdefs[str(mt.name)] = ifdef
|
ifdefs[str(mt.name)] = ifdef
|
||||||
hout += f"#ifdef {ifdef}\n"
|
|
||||||
cout += f"#ifdef {ifdef}\n"
|
|
||||||
|
|
||||||
if source in (SOURCE_BOTH, SOURCE_SERVER):
|
if source in (SOURCE_BOTH, SOURCE_SERVER):
|
||||||
# Generate send
|
# Don't generate individual send methods anymore
|
||||||
func = f"send_{snake}"
|
# The generic send_message method will be used instead
|
||||||
hout += f"bool {func}(const {mt.name} &msg);\n"
|
pass
|
||||||
cout += f"bool APIServerConnectionBase::{func}(const {mt.name} &msg) {{\n"
|
|
||||||
if log:
|
|
||||||
cout += "#ifdef HAS_PROTO_MESSAGE_DUMP\n"
|
|
||||||
cout += f' ESP_LOGVV(TAG, "{func}: %s", msg.dump().c_str());\n'
|
|
||||||
cout += "#endif\n"
|
|
||||||
# cout += f' this->set_nodelay({str(nodelay).lower()});\n'
|
|
||||||
cout += f" return this->send_message_<{mt.name}>(msg, {id_});\n"
|
|
||||||
cout += "}\n"
|
|
||||||
if source in (SOURCE_BOTH, SOURCE_CLIENT):
|
if source in (SOURCE_BOTH, SOURCE_CLIENT):
|
||||||
|
# Only add ifdef when we're actually generating content
|
||||||
|
if ifdef is not None:
|
||||||
|
hout += f"#ifdef {ifdef}\n"
|
||||||
# Generate receive
|
# Generate receive
|
||||||
func = f"on_{snake}"
|
func = f"on_{snake}"
|
||||||
hout += f"virtual void {func}(const {mt.name} &value){{}};\n"
|
hout += f"virtual void {func}(const {mt.name} &value){{}};\n"
|
||||||
@ -977,9 +1079,9 @@ def build_service_message_type(
|
|||||||
case += "break;"
|
case += "break;"
|
||||||
RECEIVE_CASES[id_] = case
|
RECEIVE_CASES[id_] = case
|
||||||
|
|
||||||
|
# Only close ifdef if we opened it
|
||||||
if ifdef is not None:
|
if ifdef is not None:
|
||||||
hout += "#endif\n"
|
hout += "#endif\n"
|
||||||
cout += "#endif\n"
|
|
||||||
|
|
||||||
return hout, cout
|
return hout, cout
|
||||||
|
|
||||||
@ -1083,6 +1185,29 @@ def main() -> None:
|
|||||||
hpp += f"class {class_name} : public ProtoService {{\n"
|
hpp += f"class {class_name} : public ProtoService {{\n"
|
||||||
hpp += " public:\n"
|
hpp += " public:\n"
|
||||||
|
|
||||||
|
# Add logging helper method declaration
|
||||||
|
hpp += "#ifdef HAS_PROTO_MESSAGE_DUMP\n"
|
||||||
|
hpp += " protected:\n"
|
||||||
|
hpp += " void log_send_message_(const char *name, const std::string &dump);\n"
|
||||||
|
hpp += " public:\n"
|
||||||
|
hpp += "#endif\n\n"
|
||||||
|
|
||||||
|
# Add generic send_message method
|
||||||
|
hpp += " template<typename T>\n"
|
||||||
|
hpp += " bool send_message(const T &msg) {\n"
|
||||||
|
hpp += "#ifdef HAS_PROTO_MESSAGE_DUMP\n"
|
||||||
|
hpp += " this->log_send_message_(T::message_name(), msg.dump());\n"
|
||||||
|
hpp += "#endif\n"
|
||||||
|
hpp += " return this->send_message_(msg, T::MESSAGE_TYPE);\n"
|
||||||
|
hpp += " }\n\n"
|
||||||
|
|
||||||
|
# Add logging helper method implementation to cpp
|
||||||
|
cpp += "#ifdef HAS_PROTO_MESSAGE_DUMP\n"
|
||||||
|
cpp += f"void {class_name}::log_send_message_(const char *name, const std::string &dump) {{\n"
|
||||||
|
cpp += ' ESP_LOGVV(TAG, "send_message %s: %s", name, dump.c_str());\n'
|
||||||
|
cpp += "}\n"
|
||||||
|
cpp += "#endif\n\n"
|
||||||
|
|
||||||
for mt in file.message_type:
|
for mt in file.message_type:
|
||||||
obj = build_service_message_type(mt)
|
obj = build_service_message_type(mt)
|
||||||
if obj is None:
|
if obj is None:
|
||||||
@ -1155,8 +1280,7 @@ def main() -> None:
|
|||||||
body += f"this->{func}(msg);\n"
|
body += f"this->{func}(msg);\n"
|
||||||
else:
|
else:
|
||||||
body += f"{ret} ret = this->{func}(msg);\n"
|
body += f"{ret} ret = this->{func}(msg);\n"
|
||||||
ret_snake = camel_to_snake(ret)
|
body += "if (!this->send_message(ret)) {\n"
|
||||||
body += f"if (!this->send_{ret_snake}(ret)) {{\n"
|
|
||||||
body += " this->on_fatal_error();\n"
|
body += " this->on_fatal_error();\n"
|
||||||
body += "}\n"
|
body += "}\n"
|
||||||
cpp += indent(body) + "\n" + "}\n"
|
cpp += indent(body) + "\n" + "}\n"
|
||||||
|
55
tests/integration/fixtures/host_mode_batch_delay.yaml
Normal file
55
tests/integration/fixtures/host_mode_batch_delay.yaml
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
esphome:
|
||||||
|
name: host-batch-delay-test
|
||||||
|
host:
|
||||||
|
api:
|
||||||
|
batch_delay: 0ms
|
||||||
|
logger:
|
||||||
|
|
||||||
|
# Add multiple sensors to test batching
|
||||||
|
sensor:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 1"
|
||||||
|
id: test_sensor1
|
||||||
|
lambda: |-
|
||||||
|
return 1.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 2"
|
||||||
|
id: test_sensor2
|
||||||
|
lambda: |-
|
||||||
|
return 2.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 3"
|
||||||
|
id: test_sensor3
|
||||||
|
lambda: |-
|
||||||
|
return 3.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
|
||||||
|
binary_sensor:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Binary Sensor 1"
|
||||||
|
id: test_binary_sensor1
|
||||||
|
lambda: |-
|
||||||
|
return millis() % 1000 < 500;
|
||||||
|
- platform: template
|
||||||
|
name: "Test Binary Sensor 2"
|
||||||
|
id: test_binary_sensor2
|
||||||
|
lambda: |-
|
||||||
|
return millis() % 2000 < 1000;
|
||||||
|
|
||||||
|
switch:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Switch 1"
|
||||||
|
id: test_switch1
|
||||||
|
turn_on_action:
|
||||||
|
- logger.log: "Switch 1 turned on"
|
||||||
|
turn_off_action:
|
||||||
|
- logger.log: "Switch 1 turned off"
|
||||||
|
- platform: template
|
||||||
|
name: "Test Switch 2"
|
||||||
|
id: test_switch2
|
||||||
|
turn_on_action:
|
||||||
|
- logger.log: "Switch 2 turned on"
|
||||||
|
turn_off_action:
|
||||||
|
- logger.log: "Switch 2 turned off"
|
322
tests/integration/fixtures/host_mode_many_entities.yaml
Normal file
322
tests/integration/fixtures/host_mode_many_entities.yaml
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
esphome:
|
||||||
|
name: host-mode-many-entities
|
||||||
|
friendly_name: "Host Mode Many Entities Test"
|
||||||
|
|
||||||
|
logger:
|
||||||
|
|
||||||
|
host:
|
||||||
|
|
||||||
|
api:
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
# 50 test sensors with predictable values for batching test
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 1"
|
||||||
|
lambda: return 1.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 2"
|
||||||
|
lambda: return 2.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 3"
|
||||||
|
lambda: return 3.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 4"
|
||||||
|
lambda: return 4.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 5"
|
||||||
|
lambda: return 5.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 6"
|
||||||
|
lambda: return 6.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 7"
|
||||||
|
lambda: return 7.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 8"
|
||||||
|
lambda: return 8.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 9"
|
||||||
|
lambda: return 9.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 10"
|
||||||
|
lambda: return 10.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 11"
|
||||||
|
lambda: return 11.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 12"
|
||||||
|
lambda: return 12.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 13"
|
||||||
|
lambda: return 13.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 14"
|
||||||
|
lambda: return 14.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 15"
|
||||||
|
lambda: return 15.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 16"
|
||||||
|
lambda: return 16.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 17"
|
||||||
|
lambda: return 17.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 18"
|
||||||
|
lambda: return 18.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 19"
|
||||||
|
lambda: return 19.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 20"
|
||||||
|
lambda: return 20.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 21"
|
||||||
|
lambda: return 21.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 22"
|
||||||
|
lambda: return 22.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 23"
|
||||||
|
lambda: return 23.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 24"
|
||||||
|
lambda: return 24.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 25"
|
||||||
|
lambda: return 25.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 26"
|
||||||
|
lambda: return 26.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 27"
|
||||||
|
lambda: return 27.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 28"
|
||||||
|
lambda: return 28.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 29"
|
||||||
|
lambda: return 29.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 30"
|
||||||
|
lambda: return 30.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 31"
|
||||||
|
lambda: return 31.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 32"
|
||||||
|
lambda: return 32.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 33"
|
||||||
|
lambda: return 33.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 34"
|
||||||
|
lambda: return 34.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 35"
|
||||||
|
lambda: return 35.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 36"
|
||||||
|
lambda: return 36.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 37"
|
||||||
|
lambda: return 37.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 38"
|
||||||
|
lambda: return 38.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 39"
|
||||||
|
lambda: return 39.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 40"
|
||||||
|
lambda: return 40.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 41"
|
||||||
|
lambda: return 41.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 42"
|
||||||
|
lambda: return 42.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 43"
|
||||||
|
lambda: return 43.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 44"
|
||||||
|
lambda: return 44.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 45"
|
||||||
|
lambda: return 45.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 46"
|
||||||
|
lambda: return 46.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 47"
|
||||||
|
lambda: return 47.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 48"
|
||||||
|
lambda: return 48.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 49"
|
||||||
|
lambda: return 49.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 50"
|
||||||
|
lambda: return 50.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
|
||||||
|
# Mixed entity types for comprehensive batching test
|
||||||
|
binary_sensor:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Binary Sensor 1"
|
||||||
|
lambda: return millis() % 1000 < 500;
|
||||||
|
- platform: template
|
||||||
|
name: "Test Binary Sensor 2"
|
||||||
|
lambda: return millis() % 2000 < 1000;
|
||||||
|
|
||||||
|
switch:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Switch 1"
|
||||||
|
lambda: return true;
|
||||||
|
turn_on_action:
|
||||||
|
- logger.log: "Switch 1 ON"
|
||||||
|
turn_off_action:
|
||||||
|
- logger.log: "Switch 1 OFF"
|
||||||
|
- platform: template
|
||||||
|
name: "Test Switch 2"
|
||||||
|
lambda: return false;
|
||||||
|
turn_on_action:
|
||||||
|
- logger.log: "Switch 2 ON"
|
||||||
|
turn_off_action:
|
||||||
|
- logger.log: "Switch 2 OFF"
|
||||||
|
|
||||||
|
text_sensor:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Text Sensor 1"
|
||||||
|
lambda: return std::string("Test Value 1");
|
||||||
|
- platform: template
|
||||||
|
name: "Test Text Sensor 2"
|
||||||
|
lambda: return std::string("Test Value 2");
|
||||||
|
- platform: version
|
||||||
|
name: "ESPHome Version"
|
||||||
|
|
||||||
|
number:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Number"
|
||||||
|
min_value: 0
|
||||||
|
max_value: 100
|
||||||
|
step: 1
|
||||||
|
lambda: return 50.0;
|
||||||
|
set_action:
|
||||||
|
- logger.log: "Number set"
|
||||||
|
|
||||||
|
select:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Select"
|
||||||
|
options:
|
||||||
|
- "Option 1"
|
||||||
|
- "Option 2"
|
||||||
|
initial_option: "Option 1"
|
||||||
|
optimistic: true
|
||||||
|
set_action:
|
||||||
|
- logger.log: "Select changed"
|
||||||
|
|
||||||
|
text:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Text"
|
||||||
|
mode: text
|
||||||
|
initial_value: "Hello"
|
||||||
|
set_action:
|
||||||
|
- logger.log: "Text changed"
|
||||||
|
|
||||||
|
valve:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Valve"
|
||||||
|
open_action:
|
||||||
|
- logger.log: "Valve opening"
|
||||||
|
close_action:
|
||||||
|
- logger.log: "Valve closing"
|
||||||
|
stop_action:
|
||||||
|
- logger.log: "Valve stopping"
|
||||||
|
|
||||||
|
alarm_control_panel:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Alarm"
|
||||||
|
codes:
|
||||||
|
- "1234"
|
||||||
|
arming_away_time: 0s
|
||||||
|
arming_home_time: 0s
|
||||||
|
pending_time: 0s
|
||||||
|
trigger_time: 300s
|
||||||
|
restore_mode: ALWAYS_DISARMED
|
||||||
|
on_disarmed:
|
||||||
|
- logger.log: "Alarm disarmed"
|
||||||
|
on_arming:
|
||||||
|
- logger.log: "Alarm arming"
|
||||||
|
on_armed_away:
|
||||||
|
- logger.log: "Alarm armed away"
|
||||||
|
on_armed_home:
|
||||||
|
- logger.log: "Alarm armed home"
|
||||||
|
on_pending:
|
||||||
|
- logger.log: "Alarm pending"
|
||||||
|
on_triggered:
|
||||||
|
- logger.log: "Alarm triggered"
|
||||||
|
|
||||||
|
event:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Event"
|
||||||
|
event_types:
|
||||||
|
- first_event
|
||||||
|
- second_event
|
||||||
|
|
||||||
|
button:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Button"
|
||||||
|
on_press:
|
||||||
|
- logger.log: "Button pressed"
|
@ -0,0 +1,136 @@
|
|||||||
|
esphome:
|
||||||
|
name: host-mode-many-entities-multi
|
||||||
|
friendly_name: "Host Mode Many Entities Multiple Connections Test"
|
||||||
|
|
||||||
|
logger:
|
||||||
|
|
||||||
|
host:
|
||||||
|
|
||||||
|
api:
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
# 20 test sensors for faster testing with multiple connections
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 1"
|
||||||
|
lambda: return 1.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 2"
|
||||||
|
lambda: return 2.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 3"
|
||||||
|
lambda: return 3.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 4"
|
||||||
|
lambda: return 4.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 5"
|
||||||
|
lambda: return 5.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 6"
|
||||||
|
lambda: return 6.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 7"
|
||||||
|
lambda: return 7.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 8"
|
||||||
|
lambda: return 8.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 9"
|
||||||
|
lambda: return 9.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 10"
|
||||||
|
lambda: return 10.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 11"
|
||||||
|
lambda: return 11.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 12"
|
||||||
|
lambda: return 12.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 13"
|
||||||
|
lambda: return 13.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 14"
|
||||||
|
lambda: return 14.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 15"
|
||||||
|
lambda: return 15.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 16"
|
||||||
|
lambda: return 16.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 17"
|
||||||
|
lambda: return 17.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 18"
|
||||||
|
lambda: return 18.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 19"
|
||||||
|
lambda: return 19.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
- platform: template
|
||||||
|
name: "Test Sensor 20"
|
||||||
|
lambda: return 20.0;
|
||||||
|
update_interval: 0.1s
|
||||||
|
|
||||||
|
# Mixed entity types for comprehensive batching test
|
||||||
|
binary_sensor:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Binary Sensor 1"
|
||||||
|
lambda: return millis() % 1000 < 500;
|
||||||
|
- platform: template
|
||||||
|
name: "Test Binary Sensor 2"
|
||||||
|
lambda: return millis() % 2000 < 1000;
|
||||||
|
|
||||||
|
text_sensor:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Text Sensor 1"
|
||||||
|
lambda: return std::string("Test Value 1");
|
||||||
|
- platform: template
|
||||||
|
name: "Test Text Sensor 2"
|
||||||
|
lambda: return std::string("Test Value 2");
|
||||||
|
- platform: version
|
||||||
|
name: "ESPHome Version"
|
||||||
|
|
||||||
|
switch:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Switch 1"
|
||||||
|
lambda: return true;
|
||||||
|
turn_on_action:
|
||||||
|
- logger.log: "Switch 1 ON"
|
||||||
|
turn_off_action:
|
||||||
|
- logger.log: "Switch 1 OFF"
|
||||||
|
|
||||||
|
button:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Button"
|
||||||
|
on_press:
|
||||||
|
- logger.log: "Button pressed"
|
||||||
|
|
||||||
|
number:
|
||||||
|
- platform: template
|
||||||
|
name: "Test Number"
|
||||||
|
min_value: 0
|
||||||
|
max_value: 100
|
||||||
|
step: 1
|
||||||
|
lambda: return 50.0;
|
||||||
|
set_action:
|
||||||
|
- logger.log: "Number set"
|
@ -5,3 +5,46 @@ api:
|
|||||||
encryption:
|
encryption:
|
||||||
key: N4Yle5YirwZhPiHHsdZLdOA73ndj/84veVaLhTvxCuU=
|
key: N4Yle5YirwZhPiHHsdZLdOA73ndj/84veVaLhTvxCuU=
|
||||||
logger:
|
logger:
|
||||||
|
|
||||||
|
# Test sensors to verify batching works with noise encryption
|
||||||
|
sensor:
|
||||||
|
- platform: template
|
||||||
|
name: "Noise Test Sensor 1"
|
||||||
|
lambda: return 1.0;
|
||||||
|
update_interval: 2s
|
||||||
|
- platform: template
|
||||||
|
name: "Noise Test Sensor 2"
|
||||||
|
lambda: return 2.0;
|
||||||
|
update_interval: 2s
|
||||||
|
- platform: template
|
||||||
|
name: "Noise Test Sensor 3"
|
||||||
|
lambda: return 3.0;
|
||||||
|
update_interval: 2s
|
||||||
|
- platform: template
|
||||||
|
name: "Noise Test Sensor 4"
|
||||||
|
lambda: return 4.0;
|
||||||
|
update_interval: 2s
|
||||||
|
- platform: template
|
||||||
|
name: "Noise Test Sensor 5"
|
||||||
|
lambda: return 5.0;
|
||||||
|
update_interval: 2s
|
||||||
|
- platform: template
|
||||||
|
name: "Noise Test Sensor 6"
|
||||||
|
lambda: return 6.0;
|
||||||
|
update_interval: 2s
|
||||||
|
- platform: template
|
||||||
|
name: "Noise Test Sensor 7"
|
||||||
|
lambda: return 7.0;
|
||||||
|
update_interval: 2s
|
||||||
|
- platform: template
|
||||||
|
name: "Noise Test Sensor 8"
|
||||||
|
lambda: return 8.0;
|
||||||
|
update_interval: 2s
|
||||||
|
- platform: template
|
||||||
|
name: "Noise Test Sensor 9"
|
||||||
|
lambda: return 9.0;
|
||||||
|
update_interval: 2s
|
||||||
|
- platform: template
|
||||||
|
name: "Noise Test Sensor 10"
|
||||||
|
lambda: return 10.0;
|
||||||
|
update_interval: 2s
|
||||||
|
80
tests/integration/test_host_mode_batch_delay.py
Normal file
80
tests/integration/test_host_mode_batch_delay.py
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
"""Integration test for API batch_delay setting."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import time
|
||||||
|
|
||||||
|
from aioesphomeapi import EntityState
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from .types import APIClientConnectedFactory, RunCompiledFunction
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_host_mode_batch_delay(
|
||||||
|
yaml_config: str,
|
||||||
|
run_compiled: RunCompiledFunction,
|
||||||
|
api_client_connected: APIClientConnectedFactory,
|
||||||
|
) -> None:
|
||||||
|
"""Test API with batch_delay set to 0ms - messages should be sent immediately without batching."""
|
||||||
|
# Write, compile and run the ESPHome device, then connect to API
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
|
async with run_compiled(yaml_config), api_client_connected() as client:
|
||||||
|
# Verify we can get device info
|
||||||
|
device_info = await client.device_info()
|
||||||
|
assert device_info is not None
|
||||||
|
assert device_info.name == "host-batch-delay-test"
|
||||||
|
|
||||||
|
# Subscribe to state changes
|
||||||
|
states: dict[int, EntityState] = {}
|
||||||
|
state_timestamps: dict[int, float] = {}
|
||||||
|
entity_count_future: asyncio.Future[int] = loop.create_future()
|
||||||
|
|
||||||
|
def on_state(state: EntityState) -> None:
|
||||||
|
"""Track when states are received."""
|
||||||
|
states[state.key] = state
|
||||||
|
state_timestamps[state.key] = time.monotonic()
|
||||||
|
# When we have received all expected entities, resolve the future
|
||||||
|
if len(states) >= 7 and not entity_count_future.done():
|
||||||
|
entity_count_future.set_result(len(states))
|
||||||
|
|
||||||
|
client.subscribe_states(on_state)
|
||||||
|
|
||||||
|
# Wait for states from all entities with timeout
|
||||||
|
try:
|
||||||
|
entity_count = await asyncio.wait_for(entity_count_future, timeout=5.0)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
pytest.fail(
|
||||||
|
f"Did not receive states from at least 7 entities within 5 seconds. "
|
||||||
|
f"Received {len(states)} states"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Verify we received all states
|
||||||
|
assert entity_count >= 7, f"Expected at least 7 entities, got {entity_count}"
|
||||||
|
assert len(states) >= 7 # 3 sensors + 2 binary sensors + 2 switches
|
||||||
|
|
||||||
|
# When batch_delay is 0ms, states are sent immediately without batching
|
||||||
|
# This means each state arrives in its own packet, which may actually be slower
|
||||||
|
# than batching due to network overhead
|
||||||
|
if state_timestamps:
|
||||||
|
first_timestamp = min(state_timestamps.values())
|
||||||
|
last_timestamp = max(state_timestamps.values())
|
||||||
|
time_spread = last_timestamp - first_timestamp
|
||||||
|
|
||||||
|
# With batch_delay=0ms, states arrive individually which may take longer
|
||||||
|
# We just verify they all arrive within a reasonable time
|
||||||
|
assert time_spread < 1.0, f"States took {time_spread:.3f}s to arrive"
|
||||||
|
|
||||||
|
# Also test list_entities - with batch_delay=0ms each entity is sent separately
|
||||||
|
start_time = time.monotonic()
|
||||||
|
entity_info, services = await client.list_entities_services()
|
||||||
|
end_time = time.monotonic()
|
||||||
|
|
||||||
|
list_time = end_time - start_time
|
||||||
|
|
||||||
|
# Verify we got all expected entities
|
||||||
|
assert len(entity_info) >= 7 # 3 sensors + 2 binary sensors + 2 switches
|
||||||
|
|
||||||
|
# With batch_delay=0ms, listing sends each entity separately which may be slower
|
||||||
|
assert list_time < 1.0, f"list_entities took {list_time:.3f}s"
|
57
tests/integration/test_host_mode_many_entities.py
Normal file
57
tests/integration/test_host_mode_many_entities.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
"""Integration test for many entities to test API batching."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
from aioesphomeapi import EntityState
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from .types import APIClientConnectedFactory, RunCompiledFunction
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_host_mode_many_entities(
|
||||||
|
yaml_config: str,
|
||||||
|
run_compiled: RunCompiledFunction,
|
||||||
|
api_client_connected: APIClientConnectedFactory,
|
||||||
|
) -> None:
|
||||||
|
"""Test API batching with many entities of different types."""
|
||||||
|
# Write, compile and run the ESPHome device, then connect to API
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
|
async with run_compiled(yaml_config), api_client_connected() as client:
|
||||||
|
# Subscribe to state changes
|
||||||
|
states: dict[int, EntityState] = {}
|
||||||
|
entity_count_future: asyncio.Future[int] = loop.create_future()
|
||||||
|
|
||||||
|
def on_state(state: EntityState) -> None:
|
||||||
|
states[state.key] = state
|
||||||
|
# When we have received states from a good number of entities, resolve the future
|
||||||
|
if len(states) >= 50 and not entity_count_future.done():
|
||||||
|
entity_count_future.set_result(len(states))
|
||||||
|
|
||||||
|
client.subscribe_states(on_state)
|
||||||
|
|
||||||
|
# Wait for states from at least 50 entities with timeout
|
||||||
|
try:
|
||||||
|
entity_count = await asyncio.wait_for(entity_count_future, timeout=10.0)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
pytest.fail(
|
||||||
|
f"Did not receive states from at least 50 entities within 10 seconds. "
|
||||||
|
f"Received {len(states)} states: {list(states.keys())}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Verify we received a good number of entity states
|
||||||
|
assert entity_count >= 50, f"Expected at least 50 entities, got {entity_count}"
|
||||||
|
assert len(states) >= 50, f"Expected at least 50 states, got {len(states)}"
|
||||||
|
|
||||||
|
# Verify we have different entity types by checking some expected values
|
||||||
|
sensor_states = [
|
||||||
|
s
|
||||||
|
for s in states.values()
|
||||||
|
if hasattr(s, "state") and isinstance(s.state, float)
|
||||||
|
]
|
||||||
|
|
||||||
|
assert len(sensor_states) >= 50, (
|
||||||
|
f"Expected at least 50 sensor states, got {len(sensor_states)}"
|
||||||
|
)
|
@ -0,0 +1,71 @@
|
|||||||
|
"""Integration test for shared buffer optimization with multiple API connections."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
from aioesphomeapi import EntityState
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from .types import APIClientConnectedFactory, RunCompiledFunction
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_host_mode_many_entities_multiple_connections(
|
||||||
|
yaml_config: str,
|
||||||
|
run_compiled: RunCompiledFunction,
|
||||||
|
api_client_connected: APIClientConnectedFactory,
|
||||||
|
) -> None:
|
||||||
|
"""Test shared buffer optimization with multiple API connections."""
|
||||||
|
# Write, compile and run the ESPHome device
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
|
async with (
|
||||||
|
run_compiled(yaml_config),
|
||||||
|
api_client_connected() as client1,
|
||||||
|
api_client_connected() as client2,
|
||||||
|
):
|
||||||
|
# Subscribe both clients to state changes
|
||||||
|
states1: dict[int, EntityState] = {}
|
||||||
|
states2: dict[int, EntityState] = {}
|
||||||
|
|
||||||
|
client1_ready = loop.create_future()
|
||||||
|
client2_ready = loop.create_future()
|
||||||
|
|
||||||
|
def on_state1(state: EntityState) -> None:
|
||||||
|
states1[state.key] = state
|
||||||
|
if len(states1) >= 20 and not client1_ready.done():
|
||||||
|
client1_ready.set_result(len(states1))
|
||||||
|
|
||||||
|
def on_state2(state: EntityState) -> None:
|
||||||
|
states2[state.key] = state
|
||||||
|
if len(states2) >= 20 and not client2_ready.done():
|
||||||
|
client2_ready.set_result(len(states2))
|
||||||
|
|
||||||
|
client1.subscribe_states(on_state1)
|
||||||
|
client2.subscribe_states(on_state2)
|
||||||
|
|
||||||
|
# Wait for both clients to receive states
|
||||||
|
try:
|
||||||
|
count1, count2 = await asyncio.gather(
|
||||||
|
asyncio.wait_for(client1_ready, timeout=10.0),
|
||||||
|
asyncio.wait_for(client2_ready, timeout=10.0),
|
||||||
|
)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
pytest.fail(
|
||||||
|
f"One or both clients did not receive enough states within 10 seconds. "
|
||||||
|
f"Client1: {len(states1)}, Client2: {len(states2)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Verify both clients received states successfully
|
||||||
|
assert count1 >= 20, (
|
||||||
|
f"Client 1 should have received at least 20 states, got {count1}"
|
||||||
|
)
|
||||||
|
assert count2 >= 20, (
|
||||||
|
f"Client 2 should have received at least 20 states, got {count2}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Verify both clients received the same entity keys (same device state)
|
||||||
|
common_keys = set(states1.keys()) & set(states2.keys())
|
||||||
|
assert len(common_keys) >= 20, (
|
||||||
|
f"Expected at least 20 common entity keys, got {len(common_keys)}"
|
||||||
|
)
|
Loading…
x
Reference in New Issue
Block a user