From c1838fae6282aa8662fb10638948c863e532f1cc Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 20 Nov 2025 22:09:19 +0000 Subject: [PATCH] [api] Add support for ESPHome action responses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds the ability for ESPHome-defined actions (services) to send responses back to Home Assistant. This is the complement to the existing feature that allows ESPHome to receive responses from HA actions. New features: - ExecuteServiceResponse protobuf message (ID 131) for sending responses - call_id field in ExecuteServiceRequest for tracking service calls - api.respond action for sending responses from YAML automations - Support for JSON response data via data: lambda Example usage: ```yaml api: actions: - action: get_sensor_value variables: sensor_name: string then: - api.respond: data: |- root["value"] = id(my_sensor).state; root["unit"] = "°C"; ``` Note: This requires corresponding changes in aioesphomeapi and home-assistant/core to handle the new messages. --- esphome/components/api/__init__.py | 44 + esphome/components/api/api.proto | 14 + esphome/components/api/api_connection.cpp | 31 + esphome/components/api/api_connection.h | 7 + esphome/components/api/api_pb2.cpp | 1218 ++++++-------------- esphome/components/api/api_pb2.h | 315 +++-- esphome/components/api/api_pb2_dump.cpp | 39 +- esphome/components/api/api_pb2_service.cpp | 100 +- esphome/components/api/api_pb2_service.h | 46 +- esphome/components/api/api_server.cpp | 24 + esphome/components/api/api_server.h | 24 + esphome/components/api/user_services.h | 58 + esphome/core/defines.h | 2 + tests/components/api/common-base.yaml | 41 + 14 files changed, 977 insertions(+), 986 deletions(-) diff --git a/esphome/components/api/__init__.py b/esphome/components/api/__init__.py index a9286c531f..306d86a85e 100644 --- a/esphome/components/api/__init__.py +++ b/esphome/components/api/__init__.py @@ -63,6 +63,7 @@ HomeAssistantActionResponseTrigger = api_ns.class_( "HomeAssistantActionResponseTrigger", automation.Trigger ) APIConnectedCondition = api_ns.class_("APIConnectedCondition", Condition) +APIRespondAction = api_ns.class_("APIRespondAction", automation.Action) UserServiceTrigger = api_ns.class_("UserServiceTrigger", automation.Trigger) ListEntitiesServicesArgument = api_ns.class_("ListEntitiesServicesArgument") @@ -537,6 +538,49 @@ async def homeassistant_tag_scanned_to_code(config, action_id, template_arg, arg return var +CONF_SUCCESS = "success" +CONF_ERROR_MESSAGE = "error_message" + +API_RESPOND_ACTION_SCHEMA = cv.Schema( + { + cv.GenerateID(): cv.use_id(APIServer), + cv.Optional(CONF_SUCCESS, default=True): cv.templatable(cv.boolean), + cv.Optional(CONF_ERROR_MESSAGE, default=""): cv.templatable(cv.string), + cv.Optional(CONF_DATA): cv.lambda_, + } +) + + +@automation.register_action( + "api.respond", + APIRespondAction, + API_RESPOND_ACTION_SCHEMA, +) +async def api_respond_to_code(config, action_id, template_arg, args): + cg.add_define("USE_API_SERVICE_RESPONSES") + serv = await cg.get_variable(config[CONF_ID]) + var = cg.new_Pvariable(action_id, template_arg, serv) + + templ = await cg.templatable(config[CONF_SUCCESS], args, bool) + cg.add(var.set_success(templ)) + + templ = await cg.templatable(config[CONF_ERROR_MESSAGE], args, cg.std_string) + cg.add(var.set_error_message(templ)) + + if CONF_DATA in config: + cg.add_define("USE_API_SERVICE_RESPONSE_JSON") + # Track for AUTO_LOAD to include json component + CORE.data.setdefault(DOMAIN, {})[CONF_CAPTURE_RESPONSE] = True + lambda_ = await cg.process_lambda( + config[CONF_DATA], + args + [(cg.JsonObject, "root")], + return_type=cg.void, + ) + cg.add(var.set_data(lambda_)) + + return var + + @automation.register_condition("api.connected", APIConnectedCondition, {}) async def api_connected_to_code(config, condition_id, template_arg, args): return cg.new_Pvariable(condition_id, template_arg) diff --git a/esphome/components/api/api.proto b/esphome/components/api/api.proto index e115e4630d..14b62d5aac 100644 --- a/esphome/components/api/api.proto +++ b/esphome/components/api/api.proto @@ -889,6 +889,20 @@ message ExecuteServiceRequest { fixed32 key = 1; repeated ExecuteServiceArgument args = 2 [(fixed_vector) = true]; + uint32 call_id = 3 [(field_ifdef) = "USE_API_SERVICE_RESPONSES"]; +} + +// Message sent by ESPHome to Home Assistant with service execution response data +message ExecuteServiceResponse { + option (id) = 131; + option (source) = SOURCE_SERVER; + option (no_delay) = true; + option (ifdef) = "USE_API_SERVICE_RESPONSES"; + + uint32 call_id = 1; // Matches the call_id from ExecuteServiceRequest + bool success = 2; // Whether the service execution succeeded + string error_message = 3; // Error message if success = false + bytes response_data = 4 [(pointer_to_buffer) = true, (field_ifdef) = "USE_API_SERVICE_RESPONSE_JSON"]; } // ==================== CAMERA ==================== diff --git a/esphome/components/api/api_connection.cpp b/esphome/components/api/api_connection.cpp index 4acd2fc15c..2d3ee43568 100644 --- a/esphome/components/api/api_connection.cpp +++ b/esphome/components/api/api_connection.cpp @@ -1544,6 +1544,12 @@ void APIConnection::on_home_assistant_state_response(const HomeAssistantStateRes #ifdef USE_API_SERVICES void APIConnection::execute_service(const ExecuteServiceRequest &msg) { bool found = false; +#ifdef USE_API_SERVICE_RESPONSES + // Set the call context before executing so responses can be sent + if (msg.call_id != 0) { + this->parent_->set_current_service_call(msg.call_id, this); + } +#endif for (auto *service : this->parent_->get_user_services()) { if (service->execute_service(msg)) { found = true; @@ -1552,7 +1558,32 @@ void APIConnection::execute_service(const ExecuteServiceRequest &msg) { if (!found) { ESP_LOGV(TAG, "Could not find service"); } +#ifdef USE_API_SERVICE_RESPONSES + // Clear call context after execution (if not already cleared by sending a response) + this->parent_->clear_current_service_call(); +#endif } +#ifdef USE_API_SERVICE_RESPONSES +void APIConnection::send_execute_service_response(uint32_t call_id, bool success, const std::string &error_message) { + ExecuteServiceResponse resp; + resp.call_id = call_id; + resp.success = success; + resp.error_message = error_message; + this->send_message(resp, ExecuteServiceResponse::MESSAGE_TYPE); +} +#ifdef USE_API_SERVICE_RESPONSE_JSON +void APIConnection::send_execute_service_response(uint32_t call_id, bool success, const std::string &error_message, + const uint8_t *response_data, size_t response_data_len) { + ExecuteServiceResponse resp; + resp.call_id = call_id; + resp.success = success; + resp.error_message = error_message; + resp.response_data = response_data; + resp.response_data_len = response_data_len; + this->send_message(resp, ExecuteServiceResponse::MESSAGE_TYPE); +} +#endif // USE_API_SERVICE_RESPONSE_JSON +#endif // USE_API_SERVICE_RESPONSES #endif #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES diff --git a/esphome/components/api/api_connection.h b/esphome/components/api/api_connection.h index 6cfd108927..0cd8fbdece 100644 --- a/esphome/components/api/api_connection.h +++ b/esphome/components/api/api_connection.h @@ -223,6 +223,13 @@ class APIConnection final : public APIServerConnection { #endif #ifdef USE_API_SERVICES void execute_service(const ExecuteServiceRequest &msg) override; +#ifdef USE_API_SERVICE_RESPONSES + void send_execute_service_response(uint32_t call_id, bool success, const std::string &error_message); +#ifdef USE_API_SERVICE_RESPONSE_JSON + void send_execute_service_response(uint32_t call_id, bool success, const std::string &error_message, + const uint8_t *response_data, size_t response_data_len); +#endif // USE_API_SERVICE_RESPONSE_JSON +#endif // USE_API_SERVICE_RESPONSES #endif #ifdef USE_API_NOISE bool send_noise_encryption_set_key_response(const NoiseEncryptionSetKeyRequest &msg) override; diff --git a/esphome/components/api/api_pb2.cpp b/esphome/components/api/api_pb2.cpp index 0a073fb662..f31c36f97e 100644 --- a/esphome/components/api/api_pb2.cpp +++ b/esphome/components/api/api_pb2.cpp @@ -1,35 +1,31 @@ // This file was automatically generated with a tool. // See script/api_protobuf/api_protobuf.py -#include "api_pb2.h" -#include "esphome/core/log.h" -#include "esphome/core/helpers.h" -#include + #include "api_pb2.h" + #include "esphome/core/log.h" + #include "esphome/core/helpers.h" + #include namespace esphome::api { + + bool HelloRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 2: - this->api_version_major = value.as_uint32(); - break; - case 3: - this->api_version_minor = value.as_uint32(); - break; - default: - return false; + case 2: this->api_version_major = value.as_uint32(); break; + case 3: this->api_version_minor = value.as_uint32(); break; + default: return false; } return true; } bool HelloRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 1: { - // Use raw data directly to avoid allocation - this->client_info = value.data(); - this->client_info_len = value.size(); - break; - } - default: - return false; + // Use raw data directly to avoid allocation + this->client_info = value.data(); + this->client_info_len = value.size(); + break; + } + default: return false; } return true; } @@ -49,13 +45,12 @@ void HelloResponse::calculate_size(ProtoSize &size) const { bool AuthenticationRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 1: { - // Use raw data directly to avoid allocation - this->password = value.data(); - this->password_len = value.size(); - break; - } - default: - return false; + // Use raw data directly to avoid allocation + this->password = value.data(); + this->password_len = value.size(); + break; + } + default: return false; } return true; } @@ -305,38 +300,22 @@ void CoverStateResponse::calculate_size(ProtoSize &size) const { } bool CoverCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 4: - this->has_position = value.as_bool(); - break; - case 6: - this->has_tilt = value.as_bool(); - break; - case 8: - this->stop = value.as_bool(); - break; + case 4: this->has_position = value.as_bool(); break; + case 6: this->has_tilt = value.as_bool(); break; + case 8: this->stop = value.as_bool(); break; #ifdef USE_DEVICES - case 9: - this->device_id = value.as_uint32(); - break; + case 9: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool CoverCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - case 5: - this->position = value.as_float(); - break; - case 7: - this->tilt = value.as_float(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + case 5: this->position = value.as_float(); break; + case 7: this->tilt = value.as_float(); break; + default: return false; } return true; } @@ -408,60 +387,33 @@ void FanStateResponse::calculate_size(ProtoSize &size) const { } bool FanCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 2: - this->has_state = value.as_bool(); - break; - case 3: - this->state = value.as_bool(); - break; - case 6: - this->has_oscillating = value.as_bool(); - break; - case 7: - this->oscillating = value.as_bool(); - break; - case 8: - this->has_direction = value.as_bool(); - break; - case 9: - this->direction = static_cast(value.as_uint32()); - break; - case 10: - this->has_speed_level = value.as_bool(); - break; - case 11: - this->speed_level = value.as_int32(); - break; - case 12: - this->has_preset_mode = value.as_bool(); - break; + case 2: this->has_state = value.as_bool(); break; + case 3: this->state = value.as_bool(); break; + case 6: this->has_oscillating = value.as_bool(); break; + case 7: this->oscillating = value.as_bool(); break; + case 8: this->has_direction = value.as_bool(); break; + case 9: this->direction = static_cast(value.as_uint32()); break; + case 10: this->has_speed_level = value.as_bool(); break; + case 11: this->speed_level = value.as_int32(); break; + case 12: this->has_preset_mode = value.as_bool(); break; #ifdef USE_DEVICES - case 14: - this->device_id = value.as_uint32(); - break; + case 14: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool FanCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 13: - this->preset_mode = value.as_string(); - break; - default: - return false; + case 13: this->preset_mode = value.as_string(); break; + default: return false; } return true; } bool FanCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + default: return false; } return true; } @@ -551,108 +503,49 @@ void LightStateResponse::calculate_size(ProtoSize &size) const { } bool LightCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 2: - this->has_state = value.as_bool(); - break; - case 3: - this->state = value.as_bool(); - break; - case 4: - this->has_brightness = value.as_bool(); - break; - case 22: - this->has_color_mode = value.as_bool(); - break; - case 23: - this->color_mode = static_cast(value.as_uint32()); - break; - case 20: - this->has_color_brightness = value.as_bool(); - break; - case 6: - this->has_rgb = value.as_bool(); - break; - case 10: - this->has_white = value.as_bool(); - break; - case 12: - this->has_color_temperature = value.as_bool(); - break; - case 24: - this->has_cold_white = value.as_bool(); - break; - case 26: - this->has_warm_white = value.as_bool(); - break; - case 14: - this->has_transition_length = value.as_bool(); - break; - case 15: - this->transition_length = value.as_uint32(); - break; - case 16: - this->has_flash_length = value.as_bool(); - break; - case 17: - this->flash_length = value.as_uint32(); - break; - case 18: - this->has_effect = value.as_bool(); - break; + case 2: this->has_state = value.as_bool(); break; + case 3: this->state = value.as_bool(); break; + case 4: this->has_brightness = value.as_bool(); break; + case 22: this->has_color_mode = value.as_bool(); break; + case 23: this->color_mode = static_cast(value.as_uint32()); break; + case 20: this->has_color_brightness = value.as_bool(); break; + case 6: this->has_rgb = value.as_bool(); break; + case 10: this->has_white = value.as_bool(); break; + case 12: this->has_color_temperature = value.as_bool(); break; + case 24: this->has_cold_white = value.as_bool(); break; + case 26: this->has_warm_white = value.as_bool(); break; + case 14: this->has_transition_length = value.as_bool(); break; + case 15: this->transition_length = value.as_uint32(); break; + case 16: this->has_flash_length = value.as_bool(); break; + case 17: this->flash_length = value.as_uint32(); break; + case 18: this->has_effect = value.as_bool(); break; #ifdef USE_DEVICES - case 28: - this->device_id = value.as_uint32(); - break; + case 28: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool LightCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 19: - this->effect = value.as_string(); - break; - default: - return false; + case 19: this->effect = value.as_string(); break; + default: return false; } return true; } bool LightCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - case 5: - this->brightness = value.as_float(); - break; - case 21: - this->color_brightness = value.as_float(); - break; - case 7: - this->red = value.as_float(); - break; - case 8: - this->green = value.as_float(); - break; - case 9: - this->blue = value.as_float(); - break; - case 11: - this->white = value.as_float(); - break; - case 13: - this->color_temperature = value.as_float(); - break; - case 25: - this->cold_white = value.as_float(); - break; - case 27: - this->warm_white = value.as_float(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + case 5: this->brightness = value.as_float(); break; + case 21: this->color_brightness = value.as_float(); break; + case 7: this->red = value.as_float(); break; + case 8: this->green = value.as_float(); break; + case 9: this->blue = value.as_float(); break; + case 11: this->white = value.as_float(); break; + case 13: this->color_temperature = value.as_float(); break; + case 25: this->cold_white = value.as_float(); break; + case 27: this->warm_white = value.as_float(); break; + default: return false; } return true; } @@ -758,26 +651,18 @@ void SwitchStateResponse::calculate_size(ProtoSize &size) const { } bool SwitchCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 2: - this->state = value.as_bool(); - break; + case 2: this->state = value.as_bool(); break; #ifdef USE_DEVICES - case 3: - this->device_id = value.as_uint32(); - break; + case 3: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool SwitchCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + default: return false; } return true; } @@ -830,14 +715,9 @@ void TextSensorStateResponse::calculate_size(ProtoSize &size) const { #endif bool SubscribeLogsRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->level = static_cast(value.as_uint32()); - break; - case 2: - this->dump_config = value.as_bool(); - break; - default: - return false; + case 1: this->level = static_cast(value.as_uint32()); break; + case 2: this->dump_config = value.as_bool(); break; + default: return false; } return true; } @@ -852,11 +732,8 @@ void SubscribeLogsResponse::calculate_size(ProtoSize &size) const { #ifdef USE_API_NOISE bool NoiseEncryptionSetKeyRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 1: - this->key = value.as_string(); - break; - default: - return false; + case 1: this->key = value.as_string(); break; + default: return false; } return true; } @@ -914,32 +791,24 @@ void HomeassistantActionRequest::calculate_size(ProtoSize &size) const { #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES bool HomeassistantActionResponse::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->call_id = value.as_uint32(); - break; - case 2: - this->success = value.as_bool(); - break; - default: - return false; + case 1: this->call_id = value.as_uint32(); break; + case 2: this->success = value.as_bool(); break; + default: return false; } return true; } bool HomeassistantActionResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 3: - this->error_message = value.as_string(); - break; + case 3: this->error_message = value.as_string(); break; #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON case 4: { - // Use raw data directly to avoid allocation - this->response_data = value.data(); - this->response_data_len = value.size(); - break; - } + // Use raw data directly to avoid allocation + this->response_data = value.data(); + this->response_data_len = value.size(); + break; + } #endif - default: - return false; + default: return false; } return true; } @@ -957,17 +826,10 @@ void SubscribeHomeAssistantStateResponse::calculate_size(ProtoSize &size) const } bool HomeAssistantStateResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 1: - this->entity_id = value.as_string(); - break; - case 2: - this->state = value.as_string(); - break; - case 3: - this->attribute = value.as_string(); - break; - default: - return false; + case 1: this->entity_id = value.as_string(); break; + case 2: this->state = value.as_string(); break; + case 3: this->attribute = value.as_string(); break; + default: return false; } return true; } @@ -975,23 +837,19 @@ bool HomeAssistantStateResponse::decode_length(uint32_t field_id, ProtoLengthDel bool GetTimeResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 2: { - // Use raw data directly to avoid allocation - this->timezone = value.data(); - this->timezone_len = value.size(); - break; - } - default: - return false; + // Use raw data directly to avoid allocation + this->timezone = value.data(); + this->timezone_len = value.size(); + break; + } + default: return false; } return true; } bool GetTimeResponse::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->epoch_seconds = value.as_fixed32(); - break; - default: - return false; + case 1: this->epoch_seconds = value.as_fixed32(); break; + default: return false; } return true; } @@ -1018,49 +876,28 @@ void ListEntitiesServicesResponse::calculate_size(ProtoSize &size) const { } bool ExecuteServiceArgument::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->bool_ = value.as_bool(); - break; - case 2: - this->legacy_int = value.as_int32(); - break; - case 5: - this->int_ = value.as_sint32(); - break; - case 6: - this->bool_array.push_back(value.as_bool()); - break; - case 7: - this->int_array.push_back(value.as_sint32()); - break; - default: - return false; + case 1: this->bool_ = value.as_bool(); break; + case 2: this->legacy_int = value.as_int32(); break; + case 5: this->int_ = value.as_sint32(); break; + case 6: this->bool_array.push_back(value.as_bool()); break; + case 7: this->int_array.push_back(value.as_sint32()); break; + default: return false; } return true; } bool ExecuteServiceArgument::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 4: - this->string_ = value.as_string(); - break; - case 9: - this->string_array.push_back(value.as_string()); - break; - default: - return false; + case 4: this->string_ = value.as_string(); break; + case 9: this->string_array.push_back(value.as_string()); break; + default: return false; } return true; } bool ExecuteServiceArgument::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 3: - this->float_ = value.as_float(); - break; - case 8: - this->float_array.push_back(value.as_float()); - break; - default: - return false; + case 3: this->float_ = value.as_float(); break; + case 8: this->float_array.push_back(value.as_float()); break; + default: return false; } return true; } @@ -1075,24 +912,26 @@ void ExecuteServiceArgument::decode(const uint8_t *buffer, size_t length) { this->string_array.init(count_string_array); ProtoDecodableMessage::decode(buffer, length); } +bool ExecuteServiceRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { + switch (field_id) { +#ifdef USE_API_SERVICE_RESPONSES + case 3: this->call_id = value.as_uint32(); break; +#endif + default: return false; + } + return true; +} bool ExecuteServiceRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 2: - this->args.emplace_back(); - value.decode_to_message(this->args.back()); - break; - default: - return false; + case 2: this->args.emplace_back(); value.decode_to_message(this->args.back()); break; + default: return false; } return true; } bool ExecuteServiceRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + default: return false; } return true; } @@ -1102,6 +941,24 @@ void ExecuteServiceRequest::decode(const uint8_t *buffer, size_t length) { ProtoDecodableMessage::decode(buffer, length); } #endif +#ifdef USE_API_SERVICE_RESPONSES +void ExecuteServiceResponse::encode(ProtoWriteBuffer buffer) const { + buffer.encode_uint32(1, this->call_id); + buffer.encode_bool(2, this->success); + buffer.encode_string(3, this->error_message_ref_); +#ifdef USE_API_SERVICE_RESPONSE_JSON + buffer.encode_bytes(4, this->response_data, this->response_data_len); +#endif +} +void ExecuteServiceResponse::calculate_size(ProtoSize &size) const { + size.add_uint32(1, this->call_id); + size.add_bool(1, this->success); + size.add_length(1, this->error_message_ref_.size()); +#ifdef USE_API_SERVICE_RESPONSE_JSON + size.add_length(4, this->response_data_len); +#endif +} +#endif #ifdef USE_CAMERA void ListEntitiesCameraResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_string(1, this->object_id_ref_); @@ -1147,14 +1004,9 @@ void CameraImageResponse::calculate_size(ProtoSize &size) const { } bool CameraImageRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->single = value.as_bool(); - break; - case 2: - this->stream = value.as_bool(); - break; - default: - return false; + case 1: this->single = value.as_bool(); break; + case 2: this->stream = value.as_bool(); break; + default: return false; } return true; } @@ -1298,90 +1150,43 @@ void ClimateStateResponse::calculate_size(ProtoSize &size) const { } bool ClimateCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 2: - this->has_mode = value.as_bool(); - break; - case 3: - this->mode = static_cast(value.as_uint32()); - break; - case 4: - this->has_target_temperature = value.as_bool(); - break; - case 6: - this->has_target_temperature_low = value.as_bool(); - break; - case 8: - this->has_target_temperature_high = value.as_bool(); - break; - case 12: - this->has_fan_mode = value.as_bool(); - break; - case 13: - this->fan_mode = static_cast(value.as_uint32()); - break; - case 14: - this->has_swing_mode = value.as_bool(); - break; - case 15: - this->swing_mode = static_cast(value.as_uint32()); - break; - case 16: - this->has_custom_fan_mode = value.as_bool(); - break; - case 18: - this->has_preset = value.as_bool(); - break; - case 19: - this->preset = static_cast(value.as_uint32()); - break; - case 20: - this->has_custom_preset = value.as_bool(); - break; - case 22: - this->has_target_humidity = value.as_bool(); - break; + case 2: this->has_mode = value.as_bool(); break; + case 3: this->mode = static_cast(value.as_uint32()); break; + case 4: this->has_target_temperature = value.as_bool(); break; + case 6: this->has_target_temperature_low = value.as_bool(); break; + case 8: this->has_target_temperature_high = value.as_bool(); break; + case 12: this->has_fan_mode = value.as_bool(); break; + case 13: this->fan_mode = static_cast(value.as_uint32()); break; + case 14: this->has_swing_mode = value.as_bool(); break; + case 15: this->swing_mode = static_cast(value.as_uint32()); break; + case 16: this->has_custom_fan_mode = value.as_bool(); break; + case 18: this->has_preset = value.as_bool(); break; + case 19: this->preset = static_cast(value.as_uint32()); break; + case 20: this->has_custom_preset = value.as_bool(); break; + case 22: this->has_target_humidity = value.as_bool(); break; #ifdef USE_DEVICES - case 24: - this->device_id = value.as_uint32(); - break; + case 24: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool ClimateCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 17: - this->custom_fan_mode = value.as_string(); - break; - case 21: - this->custom_preset = value.as_string(); - break; - default: - return false; + case 17: this->custom_fan_mode = value.as_string(); break; + case 21: this->custom_preset = value.as_string(); break; + default: return false; } return true; } bool ClimateCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - case 5: - this->target_temperature = value.as_float(); - break; - case 7: - this->target_temperature_low = value.as_float(); - break; - case 9: - this->target_temperature_high = value.as_float(); - break; - case 23: - this->target_humidity = value.as_float(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + case 5: this->target_temperature = value.as_float(); break; + case 7: this->target_temperature_low = value.as_float(); break; + case 9: this->target_temperature_high = value.as_float(); break; + case 23: this->target_humidity = value.as_float(); break; + default: return false; } return true; } @@ -1444,25 +1249,17 @@ void NumberStateResponse::calculate_size(ProtoSize &size) const { bool NumberCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { #ifdef USE_DEVICES - case 3: - this->device_id = value.as_uint32(); - break; + case 3: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool NumberCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - case 2: - this->state = value.as_float(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + case 2: this->state = value.as_float(); break; + default: return false; } return true; } @@ -1521,32 +1318,23 @@ void SelectStateResponse::calculate_size(ProtoSize &size) const { bool SelectCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { #ifdef USE_DEVICES - case 3: - this->device_id = value.as_uint32(); - break; + case 3: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool SelectCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 2: - this->state = value.as_string(); - break; - default: - return false; + case 2: this->state = value.as_string(); break; + default: return false; } return true; } bool SelectCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + default: return false; } return true; } @@ -1606,54 +1394,31 @@ void SirenStateResponse::calculate_size(ProtoSize &size) const { } bool SirenCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 2: - this->has_state = value.as_bool(); - break; - case 3: - this->state = value.as_bool(); - break; - case 4: - this->has_tone = value.as_bool(); - break; - case 6: - this->has_duration = value.as_bool(); - break; - case 7: - this->duration = value.as_uint32(); - break; - case 8: - this->has_volume = value.as_bool(); - break; + case 2: this->has_state = value.as_bool(); break; + case 3: this->state = value.as_bool(); break; + case 4: this->has_tone = value.as_bool(); break; + case 6: this->has_duration = value.as_bool(); break; + case 7: this->duration = value.as_uint32(); break; + case 8: this->has_volume = value.as_bool(); break; #ifdef USE_DEVICES - case 10: - this->device_id = value.as_uint32(); - break; + case 10: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool SirenCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 5: - this->tone = value.as_string(); - break; - default: - return false; + case 5: this->tone = value.as_string(); break; + default: return false; } return true; } bool SirenCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - case 9: - this->volume = value.as_float(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + case 9: this->volume = value.as_float(); break; + default: return false; } return true; } @@ -1709,39 +1474,26 @@ void LockStateResponse::calculate_size(ProtoSize &size) const { } bool LockCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 2: - this->command = static_cast(value.as_uint32()); - break; - case 3: - this->has_code = value.as_bool(); - break; + case 2: this->command = static_cast(value.as_uint32()); break; + case 3: this->has_code = value.as_bool(); break; #ifdef USE_DEVICES - case 5: - this->device_id = value.as_uint32(); - break; + case 5: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool LockCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 4: - this->code = value.as_string(); - break; - default: - return false; + case 4: this->code = value.as_string(); break; + default: return false; } return true; } bool LockCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + default: return false; } return true; } @@ -1778,22 +1530,16 @@ void ListEntitiesButtonResponse::calculate_size(ProtoSize &size) const { bool ButtonCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { #ifdef USE_DEVICES - case 2: - this->device_id = value.as_uint32(); - break; + case 2: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool ButtonCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + default: return false; } return true; } @@ -1867,54 +1613,31 @@ void MediaPlayerStateResponse::calculate_size(ProtoSize &size) const { } bool MediaPlayerCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 2: - this->has_command = value.as_bool(); - break; - case 3: - this->command = static_cast(value.as_uint32()); - break; - case 4: - this->has_volume = value.as_bool(); - break; - case 6: - this->has_media_url = value.as_bool(); - break; - case 8: - this->has_announcement = value.as_bool(); - break; - case 9: - this->announcement = value.as_bool(); - break; + case 2: this->has_command = value.as_bool(); break; + case 3: this->command = static_cast(value.as_uint32()); break; + case 4: this->has_volume = value.as_bool(); break; + case 6: this->has_media_url = value.as_bool(); break; + case 8: this->has_announcement = value.as_bool(); break; + case 9: this->announcement = value.as_bool(); break; #ifdef USE_DEVICES - case 10: - this->device_id = value.as_uint32(); - break; + case 10: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool MediaPlayerCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 7: - this->media_url = value.as_string(); - break; - default: - return false; + case 7: this->media_url = value.as_string(); break; + default: return false; } return true; } bool MediaPlayerCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - case 5: - this->volume = value.as_float(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + case 5: this->volume = value.as_float(); break; + default: return false; } return true; } @@ -1922,11 +1645,8 @@ bool MediaPlayerCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value #ifdef USE_BLUETOOTH_PROXY bool SubscribeBluetoothLEAdvertisementsRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->flags = value.as_uint32(); - break; - default: - return false; + case 1: this->flags = value.as_uint32(); break; + default: return false; } return true; } @@ -1954,20 +1674,11 @@ void BluetoothLERawAdvertisementsResponse::calculate_size(ProtoSize &size) const } bool BluetoothDeviceRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->address = value.as_uint64(); - break; - case 2: - this->request_type = static_cast(value.as_uint32()); - break; - case 3: - this->has_address_type = value.as_bool(); - break; - case 4: - this->address_type = value.as_uint32(); - break; - default: - return false; + case 1: this->address = value.as_uint64(); break; + case 2: this->request_type = static_cast(value.as_uint32()); break; + case 3: this->has_address_type = value.as_bool(); break; + case 4: this->address_type = value.as_uint32(); break; + default: return false; } return true; } @@ -1985,11 +1696,8 @@ void BluetoothDeviceConnectionResponse::calculate_size(ProtoSize &size) const { } bool BluetoothGATTGetServicesRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->address = value.as_uint64(); - break; - default: - return false; + case 1: this->address = value.as_uint64(); break; + default: return false; } return true; } @@ -2067,14 +1775,9 @@ void BluetoothGATTGetServicesDoneResponse::encode(ProtoWriteBuffer buffer) const void BluetoothGATTGetServicesDoneResponse::calculate_size(ProtoSize &size) const { size.add_uint64(1, this->address); } bool BluetoothGATTReadRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->address = value.as_uint64(); - break; - case 2: - this->handle = value.as_uint32(); - break; - default: - return false; + case 1: this->address = value.as_uint64(); break; + case 2: this->handle = value.as_uint32(); break; + default: return false; } return true; } @@ -2090,85 +1793,59 @@ void BluetoothGATTReadResponse::calculate_size(ProtoSize &size) const { } bool BluetoothGATTWriteRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->address = value.as_uint64(); - break; - case 2: - this->handle = value.as_uint32(); - break; - case 3: - this->response = value.as_bool(); - break; - default: - return false; + case 1: this->address = value.as_uint64(); break; + case 2: this->handle = value.as_uint32(); break; + case 3: this->response = value.as_bool(); break; + default: return false; } return true; } bool BluetoothGATTWriteRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 4: { - // Use raw data directly to avoid allocation - this->data = value.data(); - this->data_len = value.size(); - break; - } - default: - return false; + // Use raw data directly to avoid allocation + this->data = value.data(); + this->data_len = value.size(); + break; + } + default: return false; } return true; } bool BluetoothGATTReadDescriptorRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->address = value.as_uint64(); - break; - case 2: - this->handle = value.as_uint32(); - break; - default: - return false; + case 1: this->address = value.as_uint64(); break; + case 2: this->handle = value.as_uint32(); break; + default: return false; } return true; } bool BluetoothGATTWriteDescriptorRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->address = value.as_uint64(); - break; - case 2: - this->handle = value.as_uint32(); - break; - default: - return false; + case 1: this->address = value.as_uint64(); break; + case 2: this->handle = value.as_uint32(); break; + default: return false; } return true; } bool BluetoothGATTWriteDescriptorRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 3: { - // Use raw data directly to avoid allocation - this->data = value.data(); - this->data_len = value.size(); - break; - } - default: - return false; + // Use raw data directly to avoid allocation + this->data = value.data(); + this->data_len = value.size(); + break; + } + default: return false; } return true; } bool BluetoothGATTNotifyRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->address = value.as_uint64(); - break; - case 2: - this->handle = value.as_uint32(); - break; - case 3: - this->enable = value.as_bool(); - break; - default: - return false; + case 1: this->address = value.as_uint64(); break; + case 2: this->handle = value.as_uint32(); break; + case 3: this->enable = value.as_bool(); break; + default: return false; } return true; } @@ -2268,11 +1945,8 @@ void BluetoothScannerStateResponse::calculate_size(ProtoSize &size) const { } bool BluetoothScannerSetModeRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->mode = static_cast(value.as_uint32()); - break; - default: - return false; + case 1: this->mode = static_cast(value.as_uint32()); break; + default: return false; } return true; } @@ -2280,14 +1954,9 @@ bool BluetoothScannerSetModeRequest::decode_varint(uint32_t field_id, ProtoVarIn #ifdef USE_VOICE_ASSISTANT bool SubscribeVoiceAssistantRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->subscribe = value.as_bool(); - break; - case 2: - this->flags = value.as_uint32(); - break; - default: - return false; + case 1: this->subscribe = value.as_bool(); break; + case 2: this->flags = value.as_uint32(); break; + default: return false; } return true; } @@ -2317,68 +1986,45 @@ void VoiceAssistantRequest::calculate_size(ProtoSize &size) const { } bool VoiceAssistantResponse::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->port = value.as_uint32(); - break; - case 2: - this->error = value.as_bool(); - break; - default: - return false; + case 1: this->port = value.as_uint32(); break; + case 2: this->error = value.as_bool(); break; + default: return false; } return true; } bool VoiceAssistantEventData::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 1: - this->name = value.as_string(); - break; - case 2: - this->value = value.as_string(); - break; - default: - return false; + case 1: this->name = value.as_string(); break; + case 2: this->value = value.as_string(); break; + default: return false; } return true; } bool VoiceAssistantEventResponse::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->event_type = static_cast(value.as_uint32()); - break; - default: - return false; + case 1: this->event_type = static_cast(value.as_uint32()); break; + default: return false; } return true; } bool VoiceAssistantEventResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 2: - this->data.emplace_back(); - value.decode_to_message(this->data.back()); - break; - default: - return false; + case 2: this->data.emplace_back(); value.decode_to_message(this->data.back()); break; + default: return false; } return true; } bool VoiceAssistantAudio::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 2: - this->end = value.as_bool(); - break; - default: - return false; + case 2: this->end = value.as_bool(); break; + default: return false; } return true; } bool VoiceAssistantAudio::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 1: - this->data = value.as_string(); - break; - default: - return false; + case 1: this->data = value.as_string(); break; + default: return false; } return true; } @@ -2392,59 +2038,35 @@ void VoiceAssistantAudio::calculate_size(ProtoSize &size) const { } bool VoiceAssistantTimerEventResponse::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->event_type = static_cast(value.as_uint32()); - break; - case 4: - this->total_seconds = value.as_uint32(); - break; - case 5: - this->seconds_left = value.as_uint32(); - break; - case 6: - this->is_active = value.as_bool(); - break; - default: - return false; + case 1: this->event_type = static_cast(value.as_uint32()); break; + case 4: this->total_seconds = value.as_uint32(); break; + case 5: this->seconds_left = value.as_uint32(); break; + case 6: this->is_active = value.as_bool(); break; + default: return false; } return true; } bool VoiceAssistantTimerEventResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 2: - this->timer_id = value.as_string(); - break; - case 3: - this->name = value.as_string(); - break; - default: - return false; + case 2: this->timer_id = value.as_string(); break; + case 3: this->name = value.as_string(); break; + default: return false; } return true; } bool VoiceAssistantAnnounceRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 4: - this->start_conversation = value.as_bool(); - break; - default: - return false; + case 4: this->start_conversation = value.as_bool(); break; + default: return false; } return true; } bool VoiceAssistantAnnounceRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 1: - this->media_id = value.as_string(); - break; - case 2: - this->text = value.as_string(); - break; - case 3: - this->preannounce_media_id = value.as_string(); - break; - default: - return false; + case 1: this->media_id = value.as_string(); break; + case 2: this->text = value.as_string(); break; + case 3: this->preannounce_media_id = value.as_string(); break; + default: return false; } return true; } @@ -2468,47 +2090,27 @@ void VoiceAssistantWakeWord::calculate_size(ProtoSize &size) const { } bool VoiceAssistantExternalWakeWord::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 5: - this->model_size = value.as_uint32(); - break; - default: - return false; + case 5: this->model_size = value.as_uint32(); break; + default: return false; } return true; } bool VoiceAssistantExternalWakeWord::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 1: - this->id = value.as_string(); - break; - case 2: - this->wake_word = value.as_string(); - break; - case 3: - this->trained_languages.push_back(value.as_string()); - break; - case 4: - this->model_type = value.as_string(); - break; - case 6: - this->model_hash = value.as_string(); - break; - case 7: - this->url = value.as_string(); - break; - default: - return false; + case 1: this->id = value.as_string(); break; + case 2: this->wake_word = value.as_string(); break; + case 3: this->trained_languages.push_back(value.as_string()); break; + case 4: this->model_type = value.as_string(); break; + case 6: this->model_hash = value.as_string(); break; + case 7: this->url = value.as_string(); break; + default: return false; } return true; } bool VoiceAssistantConfigurationRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 1: - this->external_wake_words.emplace_back(); - value.decode_to_message(this->external_wake_words.back()); - break; - default: - return false; + case 1: this->external_wake_words.emplace_back(); value.decode_to_message(this->external_wake_words.back()); break; + default: return false; } return true; } @@ -2532,11 +2134,8 @@ void VoiceAssistantConfigurationResponse::calculate_size(ProtoSize &size) const } bool VoiceAssistantSetConfiguration::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 1: - this->active_wake_words.push_back(value.as_string()); - break; - default: - return false; + case 1: this->active_wake_words.push_back(value.as_string()); break; + default: return false; } return true; } @@ -2590,36 +2189,25 @@ void AlarmControlPanelStateResponse::calculate_size(ProtoSize &size) const { } bool AlarmControlPanelCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 2: - this->command = static_cast(value.as_uint32()); - break; + case 2: this->command = static_cast(value.as_uint32()); break; #ifdef USE_DEVICES - case 4: - this->device_id = value.as_uint32(); - break; + case 4: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool AlarmControlPanelCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 3: - this->code = value.as_string(); - break; - default: - return false; + case 3: this->code = value.as_string(); break; + default: return false; } return true; } bool AlarmControlPanelCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + default: return false; } return true; } @@ -2678,32 +2266,23 @@ void TextStateResponse::calculate_size(ProtoSize &size) const { bool TextCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { #ifdef USE_DEVICES - case 3: - this->device_id = value.as_uint32(); - break; + case 3: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool TextCommandRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 2: - this->state = value.as_string(); - break; - default: - return false; + case 2: this->state = value.as_string(); break; + default: return false; } return true; } bool TextCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + default: return false; } return true; } @@ -2757,32 +2336,20 @@ void DateStateResponse::calculate_size(ProtoSize &size) const { } bool DateCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 2: - this->year = value.as_uint32(); - break; - case 3: - this->month = value.as_uint32(); - break; - case 4: - this->day = value.as_uint32(); - break; + case 2: this->year = value.as_uint32(); break; + case 3: this->month = value.as_uint32(); break; + case 4: this->day = value.as_uint32(); break; #ifdef USE_DEVICES - case 5: - this->device_id = value.as_uint32(); - break; + case 5: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool DateCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + default: return false; } return true; } @@ -2836,32 +2403,20 @@ void TimeStateResponse::calculate_size(ProtoSize &size) const { } bool TimeCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 2: - this->hour = value.as_uint32(); - break; - case 3: - this->minute = value.as_uint32(); - break; - case 4: - this->second = value.as_uint32(); - break; + case 2: this->hour = value.as_uint32(); break; + case 3: this->minute = value.as_uint32(); break; + case 4: this->second = value.as_uint32(); break; #ifdef USE_DEVICES - case 5: - this->device_id = value.as_uint32(); - break; + case 5: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool TimeCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + default: return false; } return true; } @@ -2971,32 +2526,20 @@ void ValveStateResponse::calculate_size(ProtoSize &size) const { } bool ValveCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 2: - this->has_position = value.as_bool(); - break; - case 4: - this->stop = value.as_bool(); - break; + case 2: this->has_position = value.as_bool(); break; + case 4: this->stop = value.as_bool(); break; #ifdef USE_DEVICES - case 5: - this->device_id = value.as_uint32(); - break; + case 5: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool ValveCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - case 3: - this->position = value.as_float(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + case 3: this->position = value.as_float(); break; + default: return false; } return true; } @@ -3047,25 +2590,17 @@ void DateTimeStateResponse::calculate_size(ProtoSize &size) const { bool DateTimeCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { #ifdef USE_DEVICES - case 3: - this->device_id = value.as_uint32(); - break; + case 3: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool DateTimeCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - case 2: - this->epoch_seconds = value.as_fixed32(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + case 2: this->epoch_seconds = value.as_fixed32(); break; + default: return false; } return true; } @@ -3131,26 +2666,18 @@ void UpdateStateResponse::calculate_size(ProtoSize &size) const { } bool UpdateCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 2: - this->command = static_cast(value.as_uint32()); - break; + case 2: this->command = static_cast(value.as_uint32()); break; #ifdef USE_DEVICES - case 3: - this->device_id = value.as_uint32(); - break; + case 3: this->device_id = value.as_uint32(); break; #endif - default: - return false; + default: return false; } return true; } bool UpdateCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { switch (field_id) { - case 1: - this->key = value.as_fixed32(); - break; - default: - return false; + case 1: this->key = value.as_fixed32(); break; + default: return false; } return true; } @@ -3159,13 +2686,12 @@ bool UpdateCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { bool ZWaveProxyFrame::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 1: { - // Use raw data directly to avoid allocation - this->data = value.data(); - this->data_len = value.size(); - break; - } - default: - return false; + // Use raw data directly to avoid allocation + this->data = value.data(); + this->data_len = value.size(); + break; + } + default: return false; } return true; } @@ -3173,24 +2699,20 @@ void ZWaveProxyFrame::encode(ProtoWriteBuffer buffer) const { buffer.encode_byte void ZWaveProxyFrame::calculate_size(ProtoSize &size) const { size.add_length(1, this->data_len); } bool ZWaveProxyRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { - case 1: - this->type = static_cast(value.as_uint32()); - break; - default: - return false; + case 1: this->type = static_cast(value.as_uint32()); break; + default: return false; } return true; } bool ZWaveProxyRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { case 2: { - // Use raw data directly to avoid allocation - this->data = value.data(); - this->data_len = value.size(); - break; - } - default: - return false; + // Use raw data directly to avoid allocation + this->data = value.data(); + this->data_len = value.size(); + break; + } + default: return false; } return true; } diff --git a/esphome/components/api/api_pb2.h b/esphome/components/api/api_pb2.h index 358049026e..da6b4599a7 100644 --- a/esphome/components/api/api_pb2.h +++ b/esphome/components/api/api_pb2.h @@ -290,14 +290,20 @@ class InfoResponseProtoMessage : public ProtoMessage { public: ~InfoResponseProtoMessage() override = default; StringRef object_id_ref_{}; - void set_object_id(const StringRef &ref) { this->object_id_ref_ = ref; } + void set_object_id(const StringRef &ref) { + this->object_id_ref_ = ref; + } uint32_t key{0}; StringRef name_ref_{}; - void set_name(const StringRef &ref) { this->name_ref_ = ref; } + void set_name(const StringRef &ref) { + this->name_ref_ = ref; + } bool disabled_by_default{false}; #ifdef USE_ENTITY_ICON StringRef icon_ref_{}; - void set_icon(const StringRef &ref) { this->icon_ref_ = ref; } + void set_icon(const StringRef &ref) { + this->icon_ref_ = ref; + } #endif enums::EntityCategory entity_category{}; #ifdef USE_DEVICES @@ -335,7 +341,7 @@ class HelloRequest final : public ProtoDecodableMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "hello_request"; } #endif - const uint8_t *client_info{nullptr}; + const uint8_t* client_info{nullptr}; uint16_t client_info_len{0}; uint32_t api_version_major{0}; uint32_t api_version_minor{0}; @@ -357,9 +363,13 @@ class HelloResponse final : public ProtoMessage { uint32_t api_version_major{0}; uint32_t api_version_minor{0}; StringRef server_info_ref_{}; - void set_server_info(const StringRef &ref) { this->server_info_ref_ = ref; } + void set_server_info(const StringRef &ref) { + this->server_info_ref_ = ref; + } StringRef name_ref_{}; - void set_name(const StringRef &ref) { this->name_ref_ = ref; } + void set_name(const StringRef &ref) { + this->name_ref_ = ref; + } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -376,7 +386,7 @@ class AuthenticationRequest final : public ProtoDecodableMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "authentication_request"; } #endif - const uint8_t *password{nullptr}; + const uint8_t* password{nullptr}; uint16_t password_len{0}; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; @@ -472,7 +482,9 @@ class AreaInfo final : public ProtoMessage { public: uint32_t area_id{0}; StringRef name_ref_{}; - void set_name(const StringRef &ref) { this->name_ref_ = ref; } + void set_name(const StringRef &ref) { + this->name_ref_ = ref; + } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -487,7 +499,9 @@ class DeviceInfo final : public ProtoMessage { public: uint32_t device_id{0}; StringRef name_ref_{}; - void set_name(const StringRef &ref) { this->name_ref_ = ref; } + void set_name(const StringRef &ref) { + this->name_ref_ = ref; + } uint32_t area_id{0}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; @@ -509,25 +523,39 @@ class DeviceInfoResponse final : public ProtoMessage { bool uses_password{false}; #endif StringRef name_ref_{}; - void set_name(const StringRef &ref) { this->name_ref_ = ref; } + void set_name(const StringRef &ref) { + this->name_ref_ = ref; + } StringRef mac_address_ref_{}; - void set_mac_address(const StringRef &ref) { this->mac_address_ref_ = ref; } + void set_mac_address(const StringRef &ref) { + this->mac_address_ref_ = ref; + } StringRef esphome_version_ref_{}; - void set_esphome_version(const StringRef &ref) { this->esphome_version_ref_ = ref; } + void set_esphome_version(const StringRef &ref) { + this->esphome_version_ref_ = ref; + } StringRef compilation_time_ref_{}; - void set_compilation_time(const StringRef &ref) { this->compilation_time_ref_ = ref; } + void set_compilation_time(const StringRef &ref) { + this->compilation_time_ref_ = ref; + } StringRef model_ref_{}; - void set_model(const StringRef &ref) { this->model_ref_ = ref; } + void set_model(const StringRef &ref) { + this->model_ref_ = ref; + } #ifdef USE_DEEP_SLEEP bool has_deep_sleep{false}; #endif #ifdef ESPHOME_PROJECT_NAME StringRef project_name_ref_{}; - void set_project_name(const StringRef &ref) { this->project_name_ref_ = ref; } + void set_project_name(const StringRef &ref) { + this->project_name_ref_ = ref; + } #endif #ifdef ESPHOME_PROJECT_NAME StringRef project_version_ref_{}; - void set_project_version(const StringRef &ref) { this->project_version_ref_ = ref; } + void set_project_version(const StringRef &ref) { + this->project_version_ref_ = ref; + } #endif #ifdef USE_WEBSERVER uint32_t webserver_port{0}; @@ -536,19 +564,27 @@ class DeviceInfoResponse final : public ProtoMessage { uint32_t bluetooth_proxy_feature_flags{0}; #endif StringRef manufacturer_ref_{}; - void set_manufacturer(const StringRef &ref) { this->manufacturer_ref_ = ref; } + void set_manufacturer(const StringRef &ref) { + this->manufacturer_ref_ = ref; + } StringRef friendly_name_ref_{}; - void set_friendly_name(const StringRef &ref) { this->friendly_name_ref_ = ref; } + void set_friendly_name(const StringRef &ref) { + this->friendly_name_ref_ = ref; + } #ifdef USE_VOICE_ASSISTANT uint32_t voice_assistant_feature_flags{0}; #endif #ifdef USE_AREAS StringRef suggested_area_ref_{}; - void set_suggested_area(const StringRef &ref) { this->suggested_area_ref_ = ref; } + void set_suggested_area(const StringRef &ref) { + this->suggested_area_ref_ = ref; + } #endif #ifdef USE_BLUETOOTH_PROXY StringRef bluetooth_mac_address_ref_{}; - void set_bluetooth_mac_address(const StringRef &ref) { this->bluetooth_mac_address_ref_ = ref; } + void set_bluetooth_mac_address(const StringRef &ref) { + this->bluetooth_mac_address_ref_ = ref; + } #endif #ifdef USE_API_NOISE bool api_encryption_supported{false}; @@ -624,7 +660,9 @@ class ListEntitiesBinarySensorResponse final : public InfoResponseProtoMessage { const char *message_name() const override { return "list_entities_binary_sensor_response"; } #endif StringRef device_class_ref_{}; - void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; } + void set_device_class(const StringRef &ref) { + this->device_class_ref_ = ref; + } bool is_status_binary_sensor{false}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; @@ -664,7 +702,9 @@ class ListEntitiesCoverResponse final : public InfoResponseProtoMessage { bool supports_position{false}; bool supports_tilt{false}; StringRef device_class_ref_{}; - void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; } + void set_device_class(const StringRef &ref) { + this->device_class_ref_ = ref; + } bool supports_stop{false}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; @@ -725,7 +765,7 @@ class ListEntitiesFanResponse final : public InfoResponseProtoMessage { bool supports_speed{false}; bool supports_direction{false}; int32_t supported_speed_count{0}; - const std::vector *supported_preset_modes{}; + const std::vector* supported_preset_modes{}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -746,7 +786,9 @@ class FanStateResponse final : public StateResponseProtoMessage { enums::FanDirection direction{}; int32_t speed_level{0}; StringRef preset_mode_ref_{}; - void set_preset_mode(const StringRef &ref) { this->preset_mode_ref_ = ref; } + void set_preset_mode(const StringRef &ref) { + this->preset_mode_ref_ = ref; + } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -790,7 +832,7 @@ class ListEntitiesLightResponse final : public InfoResponseProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "list_entities_light_response"; } #endif - const light::ColorModeMask *supported_color_modes{}; + const light::ColorModeMask* supported_color_modes{}; float min_mireds{0.0f}; float max_mireds{0.0f}; std::vector effects{}; @@ -821,7 +863,9 @@ class LightStateResponse final : public StateResponseProtoMessage { float cold_white{0.0f}; float warm_white{0.0f}; StringRef effect_ref_{}; - void set_effect(const StringRef &ref) { this->effect_ref_ = ref; } + void set_effect(const StringRef &ref) { + this->effect_ref_ = ref; + } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -882,11 +926,15 @@ class ListEntitiesSensorResponse final : public InfoResponseProtoMessage { const char *message_name() const override { return "list_entities_sensor_response"; } #endif StringRef unit_of_measurement_ref_{}; - void set_unit_of_measurement(const StringRef &ref) { this->unit_of_measurement_ref_ = ref; } + void set_unit_of_measurement(const StringRef &ref) { + this->unit_of_measurement_ref_ = ref; + } int32_t accuracy_decimals{0}; bool force_update{false}; StringRef device_class_ref_{}; - void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; } + void set_device_class(const StringRef &ref) { + this->device_class_ref_ = ref; + } enums::SensorStateClass state_class{}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; @@ -924,7 +972,9 @@ class ListEntitiesSwitchResponse final : public InfoResponseProtoMessage { #endif bool assumed_state{false}; StringRef device_class_ref_{}; - void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; } + void set_device_class(const StringRef &ref) { + this->device_class_ref_ = ref; + } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -975,7 +1025,9 @@ class ListEntitiesTextSensorResponse final : public InfoResponseProtoMessage { const char *message_name() const override { return "list_entities_text_sensor_response"; } #endif StringRef device_class_ref_{}; - void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; } + void set_device_class(const StringRef &ref) { + this->device_class_ref_ = ref; + } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -992,7 +1044,9 @@ class TextSensorStateResponse final : public StateResponseProtoMessage { const char *message_name() const override { return "text_sensor_state_response"; } #endif StringRef state_ref_{}; - void set_state(const StringRef &ref) { this->state_ref_ = ref; } + void set_state(const StringRef &ref) { + this->state_ref_ = ref; + } bool missing_state{false}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; @@ -1027,9 +1081,9 @@ class SubscribeLogsResponse final : public ProtoMessage { const char *message_name() const override { return "subscribe_logs_response"; } #endif enums::LogLevel level{}; - const uint8_t *message_ptr_{nullptr}; + const uint8_t* message_ptr_{nullptr}; size_t message_len_{0}; - void set_message(const uint8_t *data, size_t len) { + void set_message(const uint8_t* data, size_t len) { this->message_ptr_ = data; this->message_len_ = len; } @@ -1091,7 +1145,9 @@ class SubscribeHomeassistantServicesRequest final : public ProtoMessage { class HomeassistantServiceMap final : public ProtoMessage { public: StringRef key_ref_{}; - void set_key(const StringRef &ref) { this->key_ref_ = ref; } + void set_key(const StringRef &ref) { + this->key_ref_ = ref; + } std::string value{}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; @@ -1109,7 +1165,9 @@ class HomeassistantActionRequest final : public ProtoMessage { const char *message_name() const override { return "homeassistant_action_request"; } #endif StringRef service_ref_{}; - void set_service(const StringRef &ref) { this->service_ref_ = ref; } + void set_service(const StringRef &ref) { + this->service_ref_ = ref; + } FixedVector data{}; FixedVector data_template{}; FixedVector variables{}; @@ -1144,7 +1202,7 @@ class HomeassistantActionResponse final : public ProtoDecodableMessage { bool success{false}; std::string error_message{}; #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON - const uint8_t *response_data{nullptr}; + const uint8_t* response_data{nullptr}; uint16_t response_data_len{0}; #endif #ifdef HAS_PROTO_MESSAGE_DUMP @@ -1178,9 +1236,13 @@ class SubscribeHomeAssistantStateResponse final : public ProtoMessage { const char *message_name() const override { return "subscribe_home_assistant_state_response"; } #endif StringRef entity_id_ref_{}; - void set_entity_id(const StringRef &ref) { this->entity_id_ref_ = ref; } + void set_entity_id(const StringRef &ref) { + this->entity_id_ref_ = ref; + } StringRef attribute_ref_{}; - void set_attribute(const StringRef &ref) { this->attribute_ref_ = ref; } + void set_attribute(const StringRef &ref) { + this->attribute_ref_ = ref; + } bool once{false}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; @@ -1229,7 +1291,7 @@ class GetTimeResponse final : public ProtoDecodableMessage { const char *message_name() const override { return "get_time_response"; } #endif uint32_t epoch_seconds{0}; - const uint8_t *timezone{nullptr}; + const uint8_t* timezone{nullptr}; uint16_t timezone_len{0}; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; @@ -1243,7 +1305,9 @@ class GetTimeResponse final : public ProtoDecodableMessage { class ListEntitiesServicesArgument final : public ProtoMessage { public: StringRef name_ref_{}; - void set_name(const StringRef &ref) { this->name_ref_ = ref; } + void set_name(const StringRef &ref) { + this->name_ref_ = ref; + } enums::ServiceArgType type{}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; @@ -1261,7 +1325,9 @@ class ListEntitiesServicesResponse final : public ProtoMessage { const char *message_name() const override { return "list_entities_services_response"; } #endif StringRef name_ref_{}; - void set_name(const StringRef &ref) { this->name_ref_ = ref; } + void set_name(const StringRef &ref) { + this->name_ref_ = ref; + } uint32_t key{0}; FixedVector args{}; void encode(ProtoWriteBuffer buffer) const override; @@ -1296,12 +1362,15 @@ class ExecuteServiceArgument final : public ProtoDecodableMessage { class ExecuteServiceRequest final : public ProtoDecodableMessage { public: static constexpr uint8_t MESSAGE_TYPE = 42; - static constexpr uint8_t ESTIMATED_SIZE = 39; + static constexpr uint8_t ESTIMATED_SIZE = 43; #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "execute_service_request"; } #endif uint32_t key{0}; FixedVector args{}; +#ifdef USE_API_SERVICE_RESPONSES + uint32_t call_id{0}; +#endif void decode(const uint8_t *buffer, size_t length) override; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; @@ -1310,6 +1379,34 @@ class ExecuteServiceRequest final : public ProtoDecodableMessage { protected: bool decode_32bit(uint32_t field_id, Proto32Bit value) override; bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override; + bool decode_varint(uint32_t field_id, ProtoVarInt value) override; +}; +#endif +#ifdef USE_API_SERVICE_RESPONSES +class ExecuteServiceResponse final : public ProtoMessage { + public: + static constexpr uint8_t MESSAGE_TYPE = 131; + static constexpr uint8_t ESTIMATED_SIZE = 34; +#ifdef HAS_PROTO_MESSAGE_DUMP + const char *message_name() const override { return "execute_service_response"; } +#endif + uint32_t call_id{0}; + bool success{false}; + StringRef error_message_ref_{}; + void set_error_message(const StringRef &ref) { + this->error_message_ref_ = ref; + } +#ifdef USE_API_SERVICE_RESPONSE_JSON + const uint8_t* response_data{nullptr}; + uint16_t response_data_len{0}; +#endif + void encode(ProtoWriteBuffer buffer) const override; + void calculate_size(ProtoSize &size) const override; +#ifdef HAS_PROTO_MESSAGE_DUMP + void dump_to(std::string &out) const override; +#endif + + protected: }; #endif #ifdef USE_CAMERA @@ -1335,9 +1432,9 @@ class CameraImageResponse final : public StateResponseProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "camera_image_response"; } #endif - const uint8_t *data_ptr_{nullptr}; + const uint8_t* data_ptr_{nullptr}; size_t data_len_{0}; - void set_data(const uint8_t *data, size_t len) { + void set_data(const uint8_t* data, size_t len) { this->data_ptr_ = data; this->data_len_ = len; } @@ -1377,16 +1474,16 @@ class ListEntitiesClimateResponse final : public InfoResponseProtoMessage { #endif bool supports_current_temperature{false}; bool supports_two_point_target_temperature{false}; - const climate::ClimateModeMask *supported_modes{}; + const climate::ClimateModeMask* supported_modes{}; float visual_min_temperature{0.0f}; float visual_max_temperature{0.0f}; float visual_target_temperature_step{0.0f}; bool supports_action{false}; - const climate::ClimateFanModeMask *supported_fan_modes{}; - const climate::ClimateSwingModeMask *supported_swing_modes{}; - const std::vector *supported_custom_fan_modes{}; - const climate::ClimatePresetMask *supported_presets{}; - const std::vector *supported_custom_presets{}; + const climate::ClimateFanModeMask* supported_fan_modes{}; + const climate::ClimateSwingModeMask* supported_swing_modes{}; + const std::vector* supported_custom_fan_modes{}; + const climate::ClimatePresetMask* supported_presets{}; + const std::vector* supported_custom_presets{}; float visual_current_temperature_step{0.0f}; bool supports_current_humidity{false}; bool supports_target_humidity{false}; @@ -1417,10 +1514,14 @@ class ClimateStateResponse final : public StateResponseProtoMessage { enums::ClimateFanMode fan_mode{}; enums::ClimateSwingMode swing_mode{}; StringRef custom_fan_mode_ref_{}; - void set_custom_fan_mode(const StringRef &ref) { this->custom_fan_mode_ref_ = ref; } + void set_custom_fan_mode(const StringRef &ref) { + this->custom_fan_mode_ref_ = ref; + } enums::ClimatePreset preset{}; StringRef custom_preset_ref_{}; - void set_custom_preset(const StringRef &ref) { this->custom_preset_ref_ = ref; } + void set_custom_preset(const StringRef &ref) { + this->custom_preset_ref_ = ref; + } float current_humidity{0.0f}; float target_humidity{0.0f}; void encode(ProtoWriteBuffer buffer) const override; @@ -1480,10 +1581,14 @@ class ListEntitiesNumberResponse final : public InfoResponseProtoMessage { float max_value{0.0f}; float step{0.0f}; StringRef unit_of_measurement_ref_{}; - void set_unit_of_measurement(const StringRef &ref) { this->unit_of_measurement_ref_ = ref; } + void set_unit_of_measurement(const StringRef &ref) { + this->unit_of_measurement_ref_ = ref; + } enums::NumberMode mode{}; StringRef device_class_ref_{}; - void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; } + void set_device_class(const StringRef &ref) { + this->device_class_ref_ = ref; + } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -1534,7 +1639,7 @@ class ListEntitiesSelectResponse final : public InfoResponseProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "list_entities_select_response"; } #endif - const FixedVector *options{}; + const FixedVector* options{}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -1551,7 +1656,9 @@ class SelectStateResponse final : public StateResponseProtoMessage { const char *message_name() const override { return "select_state_response"; } #endif StringRef state_ref_{}; - void set_state(const StringRef &ref) { this->state_ref_ = ref; } + void set_state(const StringRef &ref) { + this->state_ref_ = ref; + } bool missing_state{false}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; @@ -1651,7 +1758,9 @@ class ListEntitiesLockResponse final : public InfoResponseProtoMessage { bool supports_open{false}; bool requires_code{false}; StringRef code_format_ref_{}; - void set_code_format(const StringRef &ref) { this->code_format_ref_ = ref; } + void set_code_format(const StringRef &ref) { + this->code_format_ref_ = ref; + } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -1705,7 +1814,9 @@ class ListEntitiesButtonResponse final : public InfoResponseProtoMessage { const char *message_name() const override { return "list_entities_button_response"; } #endif StringRef device_class_ref_{}; - void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; } + void set_device_class(const StringRef &ref) { + this->device_class_ref_ = ref; + } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -1734,7 +1845,9 @@ class ButtonCommandRequest final : public CommandProtoMessage { class MediaPlayerSupportedFormat final : public ProtoMessage { public: StringRef format_ref_{}; - void set_format(const StringRef &ref) { this->format_ref_ = ref; } + void set_format(const StringRef &ref) { + this->format_ref_ = ref; + } uint32_t sample_rate{0}; uint32_t num_channels{0}; enums::MediaPlayerFormatPurpose purpose{}; @@ -2008,9 +2121,9 @@ class BluetoothGATTReadResponse final : public ProtoMessage { #endif uint64_t address{0}; uint32_t handle{0}; - const uint8_t *data_ptr_{nullptr}; + const uint8_t* data_ptr_{nullptr}; size_t data_len_{0}; - void set_data(const uint8_t *data, size_t len) { + void set_data(const uint8_t* data, size_t len) { this->data_ptr_ = data; this->data_len_ = len; } @@ -2032,7 +2145,7 @@ class BluetoothGATTWriteRequest final : public ProtoDecodableMessage { uint64_t address{0}; uint32_t handle{0}; bool response{false}; - const uint8_t *data{nullptr}; + const uint8_t* data{nullptr}; uint16_t data_len{0}; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; @@ -2067,7 +2180,7 @@ class BluetoothGATTWriteDescriptorRequest final : public ProtoDecodableMessage { #endif uint64_t address{0}; uint32_t handle{0}; - const uint8_t *data{nullptr}; + const uint8_t* data{nullptr}; uint16_t data_len{0}; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; @@ -2103,9 +2216,9 @@ class BluetoothGATTNotifyDataResponse final : public ProtoMessage { #endif uint64_t address{0}; uint32_t handle{0}; - const uint8_t *data_ptr_{nullptr}; + const uint8_t* data_ptr_{nullptr}; size_t data_len_{0}; - void set_data(const uint8_t *data, size_t len) { + void set_data(const uint8_t* data, size_t len) { this->data_ptr_ = data; this->data_len_ = len; } @@ -2340,11 +2453,15 @@ class VoiceAssistantRequest final : public ProtoMessage { #endif bool start{false}; StringRef conversation_id_ref_{}; - void set_conversation_id(const StringRef &ref) { this->conversation_id_ref_ = ref; } + void set_conversation_id(const StringRef &ref) { + this->conversation_id_ref_ = ref; + } uint32_t flags{0}; VoiceAssistantAudioSettings audio_settings{}; StringRef wake_word_phrase_ref_{}; - void set_wake_word_phrase(const StringRef &ref) { this->wake_word_phrase_ref_ = ref; } + void set_wake_word_phrase(const StringRef &ref) { + this->wake_word_phrase_ref_ = ref; + } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -2405,9 +2522,9 @@ class VoiceAssistantAudio final : public ProtoDecodableMessage { const char *message_name() const override { return "voice_assistant_audio"; } #endif std::string data{}; - const uint8_t *data_ptr_{nullptr}; + const uint8_t* data_ptr_{nullptr}; size_t data_len_{0}; - void set_data(const uint8_t *data, size_t len) { + void set_data(const uint8_t* data, size_t len) { this->data_ptr_ = data; this->data_len_ = len; } @@ -2481,9 +2598,13 @@ class VoiceAssistantAnnounceFinished final : public ProtoMessage { class VoiceAssistantWakeWord final : public ProtoMessage { public: StringRef id_ref_{}; - void set_id(const StringRef &ref) { this->id_ref_ = ref; } + void set_id(const StringRef &ref) { + this->id_ref_ = ref; + } StringRef wake_word_ref_{}; - void set_wake_word(const StringRef &ref) { this->wake_word_ref_ = ref; } + void set_wake_word(const StringRef &ref) { + this->wake_word_ref_ = ref; + } std::vector trained_languages{}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; @@ -2533,7 +2654,7 @@ class VoiceAssistantConfigurationResponse final : public ProtoMessage { const char *message_name() const override { return "voice_assistant_configuration_response"; } #endif std::vector available_wake_words{}; - const std::vector *active_wake_words{}; + const std::vector* active_wake_words{}; uint32_t max_active_wake_words{0}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; @@ -2624,7 +2745,9 @@ class ListEntitiesTextResponse final : public InfoResponseProtoMessage { uint32_t min_length{0}; uint32_t max_length{0}; StringRef pattern_ref_{}; - void set_pattern(const StringRef &ref) { this->pattern_ref_ = ref; } + void set_pattern(const StringRef &ref) { + this->pattern_ref_ = ref; + } enums::TextMode mode{}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; @@ -2642,7 +2765,9 @@ class TextStateResponse final : public StateResponseProtoMessage { const char *message_name() const override { return "text_state_response"; } #endif StringRef state_ref_{}; - void set_state(const StringRef &ref) { this->state_ref_ = ref; } + void set_state(const StringRef &ref) { + this->state_ref_ = ref; + } bool missing_state{false}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; @@ -2787,8 +2912,10 @@ class ListEntitiesEventResponse final : public InfoResponseProtoMessage { const char *message_name() const override { return "list_entities_event_response"; } #endif StringRef device_class_ref_{}; - void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; } - const FixedVector *event_types{}; + void set_device_class(const StringRef &ref) { + this->device_class_ref_ = ref; + } + const FixedVector* event_types{}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -2805,7 +2932,9 @@ class EventResponse final : public StateResponseProtoMessage { const char *message_name() const override { return "event_response"; } #endif StringRef event_type_ref_{}; - void set_event_type(const StringRef &ref) { this->event_type_ref_ = ref; } + void set_event_type(const StringRef &ref) { + this->event_type_ref_ = ref; + } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -2824,7 +2953,9 @@ class ListEntitiesValveResponse final : public InfoResponseProtoMessage { const char *message_name() const override { return "list_entities_valve_response"; } #endif StringRef device_class_ref_{}; - void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; } + void set_device_class(const StringRef &ref) { + this->device_class_ref_ = ref; + } bool assumed_state{false}; bool supports_position{false}; bool supports_stop{false}; @@ -2931,7 +3062,9 @@ class ListEntitiesUpdateResponse final : public InfoResponseProtoMessage { const char *message_name() const override { return "list_entities_update_response"; } #endif StringRef device_class_ref_{}; - void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; } + void set_device_class(const StringRef &ref) { + this->device_class_ref_ = ref; + } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -2952,15 +3085,25 @@ class UpdateStateResponse final : public StateResponseProtoMessage { bool has_progress{false}; float progress{0.0f}; StringRef current_version_ref_{}; - void set_current_version(const StringRef &ref) { this->current_version_ref_ = ref; } + void set_current_version(const StringRef &ref) { + this->current_version_ref_ = ref; + } StringRef latest_version_ref_{}; - void set_latest_version(const StringRef &ref) { this->latest_version_ref_ = ref; } + void set_latest_version(const StringRef &ref) { + this->latest_version_ref_ = ref; + } StringRef title_ref_{}; - void set_title(const StringRef &ref) { this->title_ref_ = ref; } + void set_title(const StringRef &ref) { + this->title_ref_ = ref; + } StringRef release_summary_ref_{}; - void set_release_summary(const StringRef &ref) { this->release_summary_ref_ = ref; } + void set_release_summary(const StringRef &ref) { + this->release_summary_ref_ = ref; + } StringRef release_url_ref_{}; - void set_release_url(const StringRef &ref) { this->release_url_ref_ = ref; } + void set_release_url(const StringRef &ref) { + this->release_url_ref_ = ref; + } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -2994,7 +3137,7 @@ class ZWaveProxyFrame final : public ProtoDecodableMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "z_wave_proxy_frame"; } #endif - const uint8_t *data{nullptr}; + const uint8_t* data{nullptr}; uint16_t data_len{0}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; @@ -3013,7 +3156,7 @@ class ZWaveProxyRequest final : public ProtoDecodableMessage { const char *message_name() const override { return "z_wave_proxy_request"; } #endif enums::ZWaveProxyRequestType type{}; - const uint8_t *data{nullptr}; + const uint8_t* data{nullptr}; uint16_t data_len{0}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(ProtoSize &size) const override; diff --git a/esphome/components/api/api_pb2_dump.cpp b/esphome/components/api/api_pb2_dump.cpp index 127ef44cd8..c5b6d39e0d 100644 --- a/esphome/components/api/api_pb2_dump.cpp +++ b/esphome/components/api/api_pb2_dump.cpp @@ -94,7 +94,8 @@ static void dump_field(std::string &out, const char *field_name, const char *val out.append("\n"); } -template static void dump_field(std::string &out, const char *field_name, T value, int indent = 2) { +template +static void dump_field(std::string &out, const char *field_name, T value, int indent = 2) { append_field_prefix(out, field_name, indent); out.append(proto_enum_to_string(value)); out.append("\n"); @@ -445,8 +446,7 @@ template<> const char *proto_enum_to_string(enu } #endif #ifdef USE_BLUETOOTH_PROXY -template<> -const char *proto_enum_to_string(enums::BluetoothDeviceRequestType value) { +template<> const char *proto_enum_to_string(enums::BluetoothDeviceRequestType value) { switch (value) { case enums::BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT: return "BLUETOOTH_DEVICE_REQUEST_TYPE_CONNECT"; @@ -495,8 +495,7 @@ template<> const char *proto_enum_to_string(enums:: } } #endif -template<> -const char *proto_enum_to_string(enums::VoiceAssistantSubscribeFlag value) { +template<> const char *proto_enum_to_string(enums::VoiceAssistantSubscribeFlag value) { switch (value) { case enums::VOICE_ASSISTANT_SUBSCRIBE_NONE: return "VOICE_ASSISTANT_SUBSCRIBE_NONE"; @@ -599,8 +598,7 @@ template<> const char *proto_enum_to_string(enums return "UNKNOWN"; } } -template<> -const char *proto_enum_to_string(enums::AlarmControlPanelStateCommand value) { +template<> const char *proto_enum_to_string(enums::AlarmControlPanelStateCommand value) { switch (value) { case enums::ALARM_CONTROL_PANEL_DISARM: return "ALARM_CONTROL_PANEL_DISARM"; @@ -676,6 +674,7 @@ template<> const char *proto_enum_to_string(enums: } #endif + void HelloRequest::dump_to(std::string &out) const { MessageDumpHelper helper(out, "HelloRequest"); out.append(" client_info: "); @@ -1095,7 +1094,7 @@ void SubscribeLogsResponse::dump_to(std::string &out) const { void NoiseEncryptionSetKeyRequest::dump_to(std::string &out) const { MessageDumpHelper helper(out, "NoiseEncryptionSetKeyRequest"); out.append(" key: "); - out.append(format_hex_pretty(reinterpret_cast(this->key.data()), this->key.size())); + out.append(format_hex_pretty(reinterpret_cast(this->key.data()), this->key.size())); out.append("\n"); } void NoiseEncryptionSetKeyResponse::dump_to(std::string &out) const { dump_field(out, "success", this->success); } @@ -1221,6 +1220,22 @@ void ExecuteServiceRequest::dump_to(std::string &out) const { it.dump_to(out); out.append("\n"); } +#ifdef USE_API_SERVICE_RESPONSES + dump_field(out, "call_id", this->call_id); +#endif +} +#endif +#ifdef USE_API_SERVICE_RESPONSES +void ExecuteServiceResponse::dump_to(std::string &out) const { + MessageDumpHelper helper(out, "ExecuteServiceResponse"); + dump_field(out, "call_id", this->call_id); + dump_field(out, "success", this->success); + dump_field(out, "error_message", this->error_message_ref_); +#ifdef USE_API_SERVICE_RESPONSE_JSON + out.append(" response_data: "); + out.append(format_hex_pretty(this->response_data, this->response_data_len)); + out.append("\n"); +#endif } #endif #ifdef USE_CAMERA @@ -1823,10 +1838,10 @@ void VoiceAssistantAudio::dump_to(std::string &out) const { MessageDumpHelper helper(out, "VoiceAssistantAudio"); out.append(" data: "); if (this->data_ptr_ != nullptr) { - out.append(format_hex_pretty(this->data_ptr_, this->data_len_)); - } else { - out.append(format_hex_pretty(reinterpret_cast(this->data.data()), this->data.size())); - } + out.append(format_hex_pretty(this->data_ptr_, this->data_len_)); + } else { + out.append(format_hex_pretty(reinterpret_cast(this->data.data()), this->data.size())); + } out.append("\n"); dump_field(out, "end", this->end); } diff --git a/esphome/components/api/api_pb2_service.cpp b/esphome/components/api/api_pb2_service.cpp index 9d227af0a3..c5418ef56c 100644 --- a/esphome/components/api/api_pb2_service.cpp +++ b/esphome/components/api/api_pb2_service.cpp @@ -654,14 +654,17 @@ void APIServerConnection::on_device_info_request(const DeviceInfoRequest &msg) { this->on_fatal_error(); } } -void APIServerConnection::on_list_entities_request(const ListEntitiesRequest &msg) { this->list_entities(msg); } +void APIServerConnection::on_list_entities_request(const ListEntitiesRequest &msg) { + this->list_entities(msg); +} void APIServerConnection::on_subscribe_states_request(const SubscribeStatesRequest &msg) { this->subscribe_states(msg); } -void APIServerConnection::on_subscribe_logs_request(const SubscribeLogsRequest &msg) { this->subscribe_logs(msg); } +void APIServerConnection::on_subscribe_logs_request(const SubscribeLogsRequest &msg) { + this->subscribe_logs(msg); +} #ifdef USE_API_HOMEASSISTANT_SERVICES -void APIServerConnection::on_subscribe_homeassistant_services_request( - const SubscribeHomeassistantServicesRequest &msg) { +void APIServerConnection::on_subscribe_homeassistant_services_request(const SubscribeHomeassistantServicesRequest &msg) { this->subscribe_homeassistant_services(msg); } #endif @@ -671,7 +674,9 @@ void APIServerConnection::on_subscribe_home_assistant_states_request(const Subsc } #endif #ifdef USE_API_SERVICES -void APIServerConnection::on_execute_service_request(const ExecuteServiceRequest &msg) { this->execute_service(msg); } +void APIServerConnection::on_execute_service_request(const ExecuteServiceRequest &msg) { + this->execute_service(msg); +} #endif #ifdef USE_API_NOISE void APIServerConnection::on_noise_encryption_set_key_request(const NoiseEncryptionSetKeyRequest &msg) { @@ -681,19 +686,29 @@ void APIServerConnection::on_noise_encryption_set_key_request(const NoiseEncrypt } #endif #ifdef USE_BUTTON -void APIServerConnection::on_button_command_request(const ButtonCommandRequest &msg) { this->button_command(msg); } +void APIServerConnection::on_button_command_request(const ButtonCommandRequest &msg) { + this->button_command(msg); +} #endif #ifdef USE_CAMERA -void APIServerConnection::on_camera_image_request(const CameraImageRequest &msg) { this->camera_image(msg); } +void APIServerConnection::on_camera_image_request(const CameraImageRequest &msg) { + this->camera_image(msg); +} #endif #ifdef USE_CLIMATE -void APIServerConnection::on_climate_command_request(const ClimateCommandRequest &msg) { this->climate_command(msg); } +void APIServerConnection::on_climate_command_request(const ClimateCommandRequest &msg) { + this->climate_command(msg); +} #endif #ifdef USE_COVER -void APIServerConnection::on_cover_command_request(const CoverCommandRequest &msg) { this->cover_command(msg); } +void APIServerConnection::on_cover_command_request(const CoverCommandRequest &msg) { + this->cover_command(msg); +} #endif #ifdef USE_DATETIME_DATE -void APIServerConnection::on_date_command_request(const DateCommandRequest &msg) { this->date_command(msg); } +void APIServerConnection::on_date_command_request(const DateCommandRequest &msg) { + this->date_command(msg); +} #endif #ifdef USE_DATETIME_DATETIME void APIServerConnection::on_date_time_command_request(const DateTimeCommandRequest &msg) { @@ -701,13 +716,19 @@ void APIServerConnection::on_date_time_command_request(const DateTimeCommandRequ } #endif #ifdef USE_FAN -void APIServerConnection::on_fan_command_request(const FanCommandRequest &msg) { this->fan_command(msg); } +void APIServerConnection::on_fan_command_request(const FanCommandRequest &msg) { + this->fan_command(msg); +} #endif #ifdef USE_LIGHT -void APIServerConnection::on_light_command_request(const LightCommandRequest &msg) { this->light_command(msg); } +void APIServerConnection::on_light_command_request(const LightCommandRequest &msg) { + this->light_command(msg); +} #endif #ifdef USE_LOCK -void APIServerConnection::on_lock_command_request(const LockCommandRequest &msg) { this->lock_command(msg); } +void APIServerConnection::on_lock_command_request(const LockCommandRequest &msg) { + this->lock_command(msg); +} #endif #ifdef USE_MEDIA_PLAYER void APIServerConnection::on_media_player_command_request(const MediaPlayerCommandRequest &msg) { @@ -715,32 +736,47 @@ void APIServerConnection::on_media_player_command_request(const MediaPlayerComma } #endif #ifdef USE_NUMBER -void APIServerConnection::on_number_command_request(const NumberCommandRequest &msg) { this->number_command(msg); } +void APIServerConnection::on_number_command_request(const NumberCommandRequest &msg) { + this->number_command(msg); +} #endif #ifdef USE_SELECT -void APIServerConnection::on_select_command_request(const SelectCommandRequest &msg) { this->select_command(msg); } +void APIServerConnection::on_select_command_request(const SelectCommandRequest &msg) { + this->select_command(msg); +} #endif #ifdef USE_SIREN -void APIServerConnection::on_siren_command_request(const SirenCommandRequest &msg) { this->siren_command(msg); } +void APIServerConnection::on_siren_command_request(const SirenCommandRequest &msg) { + this->siren_command(msg); +} #endif #ifdef USE_SWITCH -void APIServerConnection::on_switch_command_request(const SwitchCommandRequest &msg) { this->switch_command(msg); } +void APIServerConnection::on_switch_command_request(const SwitchCommandRequest &msg) { + this->switch_command(msg); +} #endif #ifdef USE_TEXT -void APIServerConnection::on_text_command_request(const TextCommandRequest &msg) { this->text_command(msg); } +void APIServerConnection::on_text_command_request(const TextCommandRequest &msg) { + this->text_command(msg); +} #endif #ifdef USE_DATETIME_TIME -void APIServerConnection::on_time_command_request(const TimeCommandRequest &msg) { this->time_command(msg); } +void APIServerConnection::on_time_command_request(const TimeCommandRequest &msg) { + this->time_command(msg); +} #endif #ifdef USE_UPDATE -void APIServerConnection::on_update_command_request(const UpdateCommandRequest &msg) { this->update_command(msg); } +void APIServerConnection::on_update_command_request(const UpdateCommandRequest &msg) { + this->update_command(msg); +} #endif #ifdef USE_VALVE -void APIServerConnection::on_valve_command_request(const ValveCommandRequest &msg) { this->valve_command(msg); } +void APIServerConnection::on_valve_command_request(const ValveCommandRequest &msg) { + this->valve_command(msg); +} #endif #ifdef USE_BLUETOOTH_PROXY -void APIServerConnection::on_subscribe_bluetooth_le_advertisements_request( - const SubscribeBluetoothLEAdvertisementsRequest &msg) { +void APIServerConnection::on_subscribe_bluetooth_le_advertisements_request(const SubscribeBluetoothLEAdvertisementsRequest &msg) { this->subscribe_bluetooth_le_advertisements(msg); } #endif @@ -780,16 +816,14 @@ void APIServerConnection::on_bluetooth_gatt_notify_request(const BluetoothGATTNo } #endif #ifdef USE_BLUETOOTH_PROXY -void APIServerConnection::on_subscribe_bluetooth_connections_free_request( - const SubscribeBluetoothConnectionsFreeRequest &msg) { +void APIServerConnection::on_subscribe_bluetooth_connections_free_request(const SubscribeBluetoothConnectionsFreeRequest &msg) { if (!this->send_subscribe_bluetooth_connections_free_response(msg)) { this->on_fatal_error(); } } #endif #ifdef USE_BLUETOOTH_PROXY -void APIServerConnection::on_unsubscribe_bluetooth_le_advertisements_request( - const UnsubscribeBluetoothLEAdvertisementsRequest &msg) { +void APIServerConnection::on_unsubscribe_bluetooth_le_advertisements_request(const UnsubscribeBluetoothLEAdvertisementsRequest &msg) { this->unsubscribe_bluetooth_le_advertisements(msg); } #endif @@ -821,10 +855,14 @@ void APIServerConnection::on_alarm_control_panel_command_request(const AlarmCont } #endif #ifdef USE_ZWAVE_PROXY -void APIServerConnection::on_z_wave_proxy_frame(const ZWaveProxyFrame &msg) { this->zwave_proxy_frame(msg); } +void APIServerConnection::on_z_wave_proxy_frame(const ZWaveProxyFrame &msg) { + this->zwave_proxy_frame(msg); +} #endif #ifdef USE_ZWAVE_PROXY -void APIServerConnection::on_z_wave_proxy_request(const ZWaveProxyRequest &msg) { this->zwave_proxy_request(msg); } +void APIServerConnection::on_z_wave_proxy_request(const ZWaveProxyRequest &msg) { + this->zwave_proxy_request(msg); +} #endif void APIServerConnection::read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) { @@ -835,8 +873,8 @@ void APIServerConnection::read_message(uint32_t msg_size, uint32_t msg_type, uin case AuthenticationRequest::MESSAGE_TYPE: // No setup required #endif case DisconnectRequest::MESSAGE_TYPE: // No setup required - case PingRequest::MESSAGE_TYPE: // No setup required - break; // Skip all checks for these messages + case PingRequest::MESSAGE_TYPE: // No setup required + break; // Skip all checks for these messages case DeviceInfoRequest::MESSAGE_TYPE: // Connection setup only if (!this->check_connection_setup_()) { return; // Connection not setup diff --git a/esphome/components/api/api_pb2_service.h b/esphome/components/api/api_pb2_service.h index 549b00ee6a..8ddbff7261 100644 --- a/esphome/components/api/api_pb2_service.h +++ b/esphome/components/api/api_pb2_service.h @@ -13,7 +13,6 @@ class APIServerConnectionBase : public ProtoService { #ifdef HAS_PROTO_MESSAGE_DUMP protected: void log_send_message_(const char *name, const std::string &dump); - public: #endif @@ -40,22 +39,31 @@ class APIServerConnectionBase : public ProtoService { virtual void on_subscribe_states_request(const SubscribeStatesRequest &value){}; + + + #ifdef USE_COVER virtual void on_cover_command_request(const CoverCommandRequest &value){}; #endif + #ifdef USE_FAN virtual void on_fan_command_request(const FanCommandRequest &value){}; #endif + #ifdef USE_LIGHT virtual void on_light_command_request(const LightCommandRequest &value){}; #endif + + + #ifdef USE_SWITCH virtual void on_switch_command_request(const SwitchCommandRequest &value){}; #endif + virtual void on_subscribe_logs_request(const SubscribeLogsRequest &value){}; #ifdef USE_API_NOISE @@ -83,26 +91,33 @@ class APIServerConnectionBase : public ProtoService { virtual void on_execute_service_request(const ExecuteServiceRequest &value){}; #endif + + #ifdef USE_CAMERA virtual void on_camera_image_request(const CameraImageRequest &value){}; #endif + #ifdef USE_CLIMATE virtual void on_climate_command_request(const ClimateCommandRequest &value){}; #endif + #ifdef USE_NUMBER virtual void on_number_command_request(const NumberCommandRequest &value){}; #endif + #ifdef USE_SELECT virtual void on_select_command_request(const SelectCommandRequest &value){}; #endif + #ifdef USE_SIREN virtual void on_siren_command_request(const SirenCommandRequest &value){}; #endif + #ifdef USE_LOCK virtual void on_lock_command_request(const LockCommandRequest &value){}; #endif @@ -111,12 +126,12 @@ class APIServerConnectionBase : public ProtoService { virtual void on_button_command_request(const ButtonCommandRequest &value){}; #endif + #ifdef USE_MEDIA_PLAYER virtual void on_media_player_command_request(const MediaPlayerCommandRequest &value){}; #endif #ifdef USE_BLUETOOTH_PROXY - virtual void on_subscribe_bluetooth_le_advertisements_request( - const SubscribeBluetoothLEAdvertisementsRequest &value){}; + virtual void on_subscribe_bluetooth_le_advertisements_request(const SubscribeBluetoothLEAdvertisementsRequest &value){}; #endif #ifdef USE_BLUETOOTH_PROXY @@ -127,6 +142,7 @@ class APIServerConnectionBase : public ProtoService { virtual void on_bluetooth_gatt_get_services_request(const BluetoothGATTGetServicesRequest &value){}; #endif + #ifdef USE_BLUETOOTH_PROXY virtual void on_bluetooth_gatt_read_request(const BluetoothGATTReadRequest &value){}; #endif @@ -148,11 +164,16 @@ class APIServerConnectionBase : public ProtoService { virtual void on_subscribe_bluetooth_connections_free_request(const SubscribeBluetoothConnectionsFreeRequest &value){}; #endif + + + + + #ifdef USE_BLUETOOTH_PROXY - virtual void on_unsubscribe_bluetooth_le_advertisements_request( - const UnsubscribeBluetoothLEAdvertisementsRequest &value){}; + virtual void on_unsubscribe_bluetooth_le_advertisements_request(const UnsubscribeBluetoothLEAdvertisementsRequest &value){}; #endif + #ifdef USE_BLUETOOTH_PROXY virtual void on_bluetooth_scanner_set_mode_request(const BluetoothScannerSetModeRequest &value){}; #endif @@ -184,30 +205,39 @@ class APIServerConnectionBase : public ProtoService { virtual void on_voice_assistant_set_configuration(const VoiceAssistantSetConfiguration &value){}; #endif + #ifdef USE_ALARM_CONTROL_PANEL virtual void on_alarm_control_panel_command_request(const AlarmControlPanelCommandRequest &value){}; #endif + #ifdef USE_TEXT virtual void on_text_command_request(const TextCommandRequest &value){}; #endif + #ifdef USE_DATETIME_DATE virtual void on_date_command_request(const DateCommandRequest &value){}; #endif + #ifdef USE_DATETIME_TIME virtual void on_time_command_request(const TimeCommandRequest &value){}; #endif + + + #ifdef USE_VALVE virtual void on_valve_command_request(const ValveCommandRequest &value){}; #endif + #ifdef USE_DATETIME_DATETIME virtual void on_date_time_command_request(const DateTimeCommandRequest &value){}; #endif + #ifdef USE_UPDATE virtual void on_update_command_request(const UpdateCommandRequest &value){}; #endif @@ -324,8 +354,7 @@ class APIServerConnection : public APIServerConnectionBase { virtual void bluetooth_gatt_notify(const BluetoothGATTNotifyRequest &msg) = 0; #endif #ifdef USE_BLUETOOTH_PROXY - virtual bool send_subscribe_bluetooth_connections_free_response( - const SubscribeBluetoothConnectionsFreeRequest &msg) = 0; + virtual bool send_subscribe_bluetooth_connections_free_response(const SubscribeBluetoothConnectionsFreeRequest &msg) = 0; #endif #ifdef USE_BLUETOOTH_PROXY virtual void unsubscribe_bluetooth_le_advertisements(const UnsubscribeBluetoothLEAdvertisementsRequest &msg) = 0; @@ -456,8 +485,7 @@ class APIServerConnection : public APIServerConnectionBase { void on_subscribe_bluetooth_connections_free_request(const SubscribeBluetoothConnectionsFreeRequest &msg) override; #endif #ifdef USE_BLUETOOTH_PROXY - void on_unsubscribe_bluetooth_le_advertisements_request( - const UnsubscribeBluetoothLEAdvertisementsRequest &msg) override; + void on_unsubscribe_bluetooth_le_advertisements_request(const UnsubscribeBluetoothLEAdvertisementsRequest &msg) override; #endif #ifdef USE_BLUETOOTH_PROXY void on_bluetooth_scanner_set_mode_request(const BluetoothScannerSetModeRequest &msg) override; diff --git a/esphome/components/api/api_server.cpp b/esphome/components/api/api_server.cpp index 18601d74ff..93d60fff3d 100644 --- a/esphome/components/api/api_server.cpp +++ b/esphome/components/api/api_server.cpp @@ -430,6 +430,30 @@ void APIServer::handle_action_response(uint32_t call_id, bool success, const std #endif // USE_API_HOMEASSISTANT_ACTION_RESPONSES #endif // USE_API_HOMEASSISTANT_SERVICES +#ifdef USE_API_SERVICE_RESPONSES +void APIServer::send_service_response(bool success, const std::string &error_message) { + if (this->current_service_connection_ == nullptr || this->current_service_call_id_ == 0) { + ESP_LOGW(TAG, "Cannot send service response: no active service call"); + return; + } + this->current_service_connection_->send_execute_service_response(this->current_service_call_id_, success, + error_message); + this->clear_current_service_call(); +} +#ifdef USE_API_SERVICE_RESPONSE_JSON +void APIServer::send_service_response(bool success, const std::string &error_message, const uint8_t *response_data, + size_t response_data_len) { + if (this->current_service_connection_ == nullptr || this->current_service_call_id_ == 0) { + ESP_LOGW(TAG, "Cannot send service response: no active service call"); + return; + } + this->current_service_connection_->send_execute_service_response(this->current_service_call_id_, success, + error_message, response_data, response_data_len); + this->clear_current_service_call(); +} +#endif // USE_API_SERVICE_RESPONSE_JSON +#endif // USE_API_SERVICE_RESPONSES + #ifdef USE_API_HOMEASSISTANT_STATES void APIServer::subscribe_home_assistant_state(std::string entity_id, optional attribute, std::function f) { diff --git a/esphome/components/api/api_server.h b/esphome/components/api/api_server.h index 2d58063d6c..c5c3ad2a4d 100644 --- a/esphome/components/api/api_server.h +++ b/esphome/components/api/api_server.h @@ -132,6 +132,25 @@ class APIServer : public Component, public Controller { // Only compile push_back method when custom_services: true (external components) void register_user_service(UserServiceDescriptor *descriptor) { this->user_services_.push_back(descriptor); } #endif +#ifdef USE_API_SERVICE_RESPONSES + // Service response handling - set context before triggering service, clear after + void set_current_service_call(uint32_t call_id, APIConnection *conn) { + this->current_service_call_id_ = call_id; + this->current_service_connection_ = conn; + } + void clear_current_service_call() { + this->current_service_call_id_ = 0; + this->current_service_connection_ = nullptr; + } + uint32_t get_current_service_call_id() const { return this->current_service_call_id_; } + bool has_current_service_call() const { return this->current_service_call_id_ != 0; } + // Send response for current service call + void send_service_response(bool success, const std::string &error_message); +#ifdef USE_API_SERVICE_RESPONSE_JSON + void send_service_response(bool success, const std::string &error_message, const uint8_t *response_data, + size_t response_data_len); +#endif // USE_API_SERVICE_RESPONSE_JSON +#endif // USE_API_SERVICE_RESPONSES #endif #ifdef USE_HOMEASSISTANT_TIME void request_time(); @@ -208,6 +227,11 @@ class APIServer : public Component, public Controller { #endif #ifdef USE_API_SERVICES std::vector user_services_; +#ifdef USE_API_SERVICE_RESPONSES + // Current service call context for sending responses + uint32_t current_service_call_id_{0}; + APIConnection *current_service_connection_{nullptr}; +#endif // USE_API_SERVICE_RESPONSES #endif #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES struct PendingActionResponse { diff --git a/esphome/components/api/user_services.h b/esphome/components/api/user_services.h index 2a887fc52d..b347716a11 100644 --- a/esphome/components/api/user_services.h +++ b/esphome/components/api/user_services.h @@ -6,6 +6,10 @@ #include "esphome/core/component.h" #include "esphome/core/automation.h" #include "api_pb2.h" +#include "api_server.h" +#ifdef USE_API_SERVICE_RESPONSE_JSON +#include "esphome/components/json/json_util.h" +#endif #ifdef USE_API_SERVICES namespace esphome::api { @@ -121,5 +125,59 @@ template class UserServiceTrigger : public UserServiceBasetrigger(x...); } // NOLINT }; +#ifdef USE_API_SERVICE_RESPONSES +template class APIRespondAction : public Action { + public: + explicit APIRespondAction(APIServer *parent) : parent_(parent) {} + + template void set_success(V success) { this->success_ = success; } + template void set_error_message(V error) { this->error_message_ = error; } + +#ifdef USE_API_SERVICE_RESPONSE_JSON + void set_data(std::function func) { + this->json_builder_ = std::move(func); + this->has_data_ = true; + } +#endif + + void play(Ts... x) override { + if (!this->parent_->has_current_service_call()) { + ESP_LOGW("api", "api.respond called outside of service execution context"); + return; + } + + bool success = this->success_.value(x...); + std::string error_message = this->error_message_.value(x...); + +#ifdef USE_API_SERVICE_RESPONSE_JSON + if (this->has_data_) { + // Build JSON response + std::string json_str; + { + JsonDocument doc; + JsonObject root = doc.to(); + this->json_builder_(x..., root); + json::serialize_json(root, json_str); + } + this->parent_->send_service_response(success, error_message, reinterpret_cast(json_str.data()), + json_str.size()); + } else +#endif + { + this->parent_->send_service_response(success, error_message); + } + } + + protected: + APIServer *parent_; + TemplatableValue success_{true}; + TemplatableValue error_message_{""}; +#ifdef USE_API_SERVICE_RESPONSE_JSON + std::function json_builder_; + bool has_data_{false}; +#endif +}; +#endif // USE_API_SERVICE_RESPONSES + } // namespace esphome::api #endif // USE_API_SERVICES diff --git a/esphome/core/defines.h b/esphome/core/defines.h index 41f4b28cd5..f5114fd981 100644 --- a/esphome/core/defines.h +++ b/esphome/core/defines.h @@ -126,6 +126,8 @@ #define USE_API_PLAINTEXT #define USE_API_SERVICES #define USE_API_CUSTOM_SERVICES +#define USE_API_SERVICE_RESPONSES +#define USE_API_SERVICE_RESPONSE_JSON #define API_MAX_SEND_QUEUE 8 #define USE_MD5 #define USE_SHA256 diff --git a/tests/components/api/common-base.yaml b/tests/components/api/common-base.yaml index fc53b8ac7e..7ff8d94686 100644 --- a/tests/components/api/common-base.yaml +++ b/tests/components/api/common-base.yaml @@ -177,6 +177,47 @@ api: else: - logger.log: "Skipped loops" - logger.log: "After combined test" + # Test api.respond action - simple success response + - action: test_respond_simple + then: + - api.respond: + success: true + # Test api.respond action - with error message + - action: test_respond_error + variables: + error_msg: string + then: + - api.respond: + success: false + error_message: !lambda 'return error_msg;' + # Test api.respond action - with JSON data + - action: test_respond_with_data + variables: + sensor_name: string + value: float + then: + - api.respond: + data: |- + root["sensor"] = sensor_name; + root["value"] = value; + root["unit"] = "°C"; + # Test api.respond action - conditional response + - action: test_respond_conditional + variables: + do_succeed: bool + then: + - if: + condition: + lambda: 'return do_succeed;' + then: + - api.respond: + success: true + data: |- + root["status"] = "ok"; + else: + - api.respond: + success: false + error_message: "Operation failed" event: - platform: template