diff --git a/esphome/components/api/api_connection.cpp b/esphome/components/api/api_connection.cpp index 6fe6037f31..60dc0a113d 100644 --- a/esphome/components/api/api_connection.cpp +++ b/esphome/components/api/api_connection.cpp @@ -248,8 +248,10 @@ void APIConnection::loop() { if (state_subs_at_ < static_cast(subs.size())) { auto &it = subs[state_subs_at_]; SubscribeHomeAssistantStateResponse resp; - resp.entity_id = it.entity_id; - resp.attribute = it.attribute.value(); + resp.set_entity_id(StringRef(it.entity_id)); + // attribute.value() returns temporary - must store it + std::string attribute_value = it.attribute.value(); + resp.set_attribute(StringRef(attribute_value)); resp.once = it.once; if (this->send_message(resp, SubscribeHomeAssistantStateResponse::MESSAGE_TYPE)) { state_subs_at_++; @@ -260,14 +262,14 @@ void APIConnection::loop() { } } -DisconnectResponse APIConnection::disconnect(const DisconnectRequest &msg) { +bool APIConnection::send_disconnect_response(const DisconnectRequest &msg) { // remote initiated disconnect_client // don't close yet, we still need to send the disconnect response // close will happen on next loop ESP_LOGD(TAG, "%s disconnected", this->get_client_combined_info().c_str()); this->flags_.next_close = true; DisconnectResponse resp; - return resp; + return this->send_message(resp, DisconnectResponse::MESSAGE_TYPE); } void APIConnection::on_disconnect_response(const DisconnectResponse &value) { this->helper_->close(); @@ -344,7 +346,7 @@ uint16_t APIConnection::try_send_binary_sensor_info(EntityBase *entity, APIConne bool is_single) { auto *binary_sensor = static_cast(entity); ListEntitiesBinarySensorResponse msg; - msg.device_class = binary_sensor->get_device_class(); + msg.set_device_class(binary_sensor->get_device_class_ref()); msg.is_status_binary_sensor = binary_sensor->is_status_binary_sensor(); return fill_and_encode_entity_info(binary_sensor, msg, ListEntitiesBinarySensorResponse::MESSAGE_TYPE, conn, remaining_size, is_single); @@ -376,7 +378,7 @@ uint16_t APIConnection::try_send_cover_info(EntityBase *entity, APIConnection *c msg.supports_position = traits.get_supports_position(); msg.supports_tilt = traits.get_supports_tilt(); msg.supports_stop = traits.get_supports_stop(); - msg.device_class = cover->get_device_class(); + msg.set_device_class(cover->get_device_class_ref()); return fill_and_encode_entity_info(cover, msg, ListEntitiesCoverResponse::MESSAGE_TYPE, conn, remaining_size, is_single); } @@ -411,7 +413,7 @@ uint16_t APIConnection::try_send_fan_state(EntityBase *entity, APIConnection *co if (traits.supports_direction()) msg.direction = static_cast(fan->direction); if (traits.supports_preset_modes()) - msg.preset_mode = fan->preset_mode; + msg.set_preset_mode(StringRef(fan->preset_mode)); return fill_and_encode_entity_state(fan, msg, FanStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single); } uint16_t APIConnection::try_send_fan_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, @@ -468,8 +470,11 @@ uint16_t APIConnection::try_send_light_state(EntityBase *entity, APIConnection * resp.color_temperature = values.get_color_temperature(); resp.cold_white = values.get_cold_white(); resp.warm_white = values.get_warm_white(); - if (light->supports_effects()) - resp.effect = light->get_effect_name(); + if (light->supports_effects()) { + // get_effect_name() returns temporary std::string - must store it + std::string effect_name = light->get_effect_name(); + resp.set_effect(StringRef(effect_name)); + } return fill_and_encode_entity_state(light, resp, LightStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single); } uint16_t APIConnection::try_send_light_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, @@ -545,10 +550,10 @@ uint16_t APIConnection::try_send_sensor_info(EntityBase *entity, APIConnection * bool is_single) { auto *sensor = static_cast(entity); ListEntitiesSensorResponse msg; - msg.unit_of_measurement = sensor->get_unit_of_measurement(); + msg.set_unit_of_measurement(sensor->get_unit_of_measurement_ref()); msg.accuracy_decimals = sensor->get_accuracy_decimals(); msg.force_update = sensor->get_force_update(); - msg.device_class = sensor->get_device_class(); + msg.set_device_class(sensor->get_device_class_ref()); msg.state_class = static_cast(sensor->get_state_class()); return fill_and_encode_entity_info(sensor, msg, ListEntitiesSensorResponse::MESSAGE_TYPE, conn, remaining_size, is_single); @@ -575,7 +580,7 @@ uint16_t APIConnection::try_send_switch_info(EntityBase *entity, APIConnection * auto *a_switch = static_cast(entity); ListEntitiesSwitchResponse msg; msg.assumed_state = a_switch->assumed_state(); - msg.device_class = a_switch->get_device_class(); + msg.set_device_class(a_switch->get_device_class_ref()); return fill_and_encode_entity_info(a_switch, msg, ListEntitiesSwitchResponse::MESSAGE_TYPE, conn, remaining_size, is_single); } @@ -600,7 +605,7 @@ uint16_t APIConnection::try_send_text_sensor_state(EntityBase *entity, APIConnec bool is_single) { auto *text_sensor = static_cast(entity); TextSensorStateResponse resp; - resp.state = text_sensor->state; + resp.set_state(StringRef(text_sensor->state)); resp.missing_state = !text_sensor->has_state(); return fill_and_encode_entity_state(text_sensor, resp, TextSensorStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single); @@ -609,7 +614,7 @@ uint16_t APIConnection::try_send_text_sensor_info(EntityBase *entity, APIConnect bool is_single) { auto *text_sensor = static_cast(entity); ListEntitiesTextSensorResponse msg; - msg.device_class = text_sensor->get_device_class(); + msg.set_device_class(text_sensor->get_device_class_ref()); return fill_and_encode_entity_info(text_sensor, msg, ListEntitiesTextSensorResponse::MESSAGE_TYPE, conn, remaining_size, is_single); } @@ -637,13 +642,19 @@ uint16_t APIConnection::try_send_climate_state(EntityBase *entity, APIConnection } if (traits.get_supports_fan_modes() && climate->fan_mode.has_value()) resp.fan_mode = static_cast(climate->fan_mode.value()); - if (!traits.get_supported_custom_fan_modes().empty() && climate->custom_fan_mode.has_value()) - resp.custom_fan_mode = climate->custom_fan_mode.value(); + if (!traits.get_supported_custom_fan_modes().empty() && climate->custom_fan_mode.has_value()) { + // custom_fan_mode.value() returns temporary - must store it + std::string custom_fan_mode = climate->custom_fan_mode.value(); + resp.set_custom_fan_mode(StringRef(custom_fan_mode)); + } if (traits.get_supports_presets() && climate->preset.has_value()) { resp.preset = static_cast(climate->preset.value()); } - if (!traits.get_supported_custom_presets().empty() && climate->custom_preset.has_value()) - resp.custom_preset = climate->custom_preset.value(); + if (!traits.get_supported_custom_presets().empty() && climate->custom_preset.has_value()) { + // custom_preset.value() returns temporary - must store it + std::string custom_preset = climate->custom_preset.value(); + resp.set_custom_preset(StringRef(custom_preset)); + } if (traits.get_supports_swing_modes()) resp.swing_mode = static_cast(climate->swing_mode); if (traits.get_supports_current_humidity()) @@ -729,9 +740,9 @@ uint16_t APIConnection::try_send_number_info(EntityBase *entity, APIConnection * bool is_single) { auto *number = static_cast(entity); ListEntitiesNumberResponse msg; - msg.unit_of_measurement = number->traits.get_unit_of_measurement(); + msg.set_unit_of_measurement(number->traits.get_unit_of_measurement_ref()); msg.mode = static_cast(number->traits.get_mode()); - msg.device_class = number->traits.get_device_class(); + msg.set_device_class(number->traits.get_device_class_ref()); msg.min_value = number->traits.get_min_value(); msg.max_value = number->traits.get_max_value(); msg.step = number->traits.get_step(); @@ -844,7 +855,7 @@ uint16_t APIConnection::try_send_text_state(EntityBase *entity, APIConnection *c bool is_single) { auto *text = static_cast(entity); TextStateResponse resp; - resp.state = text->state; + resp.set_state(StringRef(text->state)); resp.missing_state = !text->has_state(); return fill_and_encode_entity_state(text, resp, TextStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single); } @@ -856,7 +867,7 @@ uint16_t APIConnection::try_send_text_info(EntityBase *entity, APIConnection *co msg.mode = static_cast(text->traits.get_mode()); msg.min_length = text->traits.get_min_length(); msg.max_length = text->traits.get_max_length(); - msg.pattern = text->traits.get_pattern(); + msg.set_pattern(text->traits.get_pattern_ref()); return fill_and_encode_entity_info(text, msg, ListEntitiesTextResponse::MESSAGE_TYPE, conn, remaining_size, is_single); } @@ -877,7 +888,7 @@ uint16_t APIConnection::try_send_select_state(EntityBase *entity, APIConnection bool is_single) { auto *select = static_cast(entity); SelectStateResponse resp; - resp.state = select->state; + resp.set_state(StringRef(select->state)); resp.missing_state = !select->has_state(); return fill_and_encode_entity_state(select, resp, SelectStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single); } @@ -903,7 +914,7 @@ uint16_t APIConnection::try_send_button_info(EntityBase *entity, APIConnection * bool is_single) { auto *button = static_cast(entity); ListEntitiesButtonResponse msg; - msg.device_class = button->get_device_class(); + msg.set_device_class(button->get_device_class_ref()); return fill_and_encode_entity_info(button, msg, ListEntitiesButtonResponse::MESSAGE_TYPE, conn, remaining_size, is_single); } @@ -972,7 +983,7 @@ uint16_t APIConnection::try_send_valve_info(EntityBase *entity, APIConnection *c auto *valve = static_cast(entity); ListEntitiesValveResponse msg; auto traits = valve->get_traits(); - msg.device_class = valve->get_device_class(); + msg.set_device_class(valve->get_device_class_ref()); msg.assumed_state = traits.get_is_assumed_state(); msg.supports_position = traits.get_supports_position(); msg.supports_stop = traits.get_supports_stop(); @@ -1014,13 +1025,13 @@ uint16_t APIConnection::try_send_media_player_info(EntityBase *entity, APIConnec auto traits = media_player->get_traits(); msg.supports_pause = traits.get_supports_pause(); for (auto &supported_format : traits.get_supported_formats()) { - MediaPlayerSupportedFormat media_format; - media_format.format = supported_format.format; + msg.supported_formats.emplace_back(); + auto &media_format = msg.supported_formats.back(); + media_format.set_format(StringRef(supported_format.format)); media_format.sample_rate = supported_format.sample_rate; media_format.num_channels = supported_format.num_channels; media_format.purpose = static_cast(supported_format.purpose); media_format.sample_bytes = supported_format.sample_bytes; - msg.supported_formats.push_back(media_format); } return fill_and_encode_entity_info(media_player, msg, ListEntitiesMediaPlayerResponse::MESSAGE_TYPE, conn, remaining_size, is_single); @@ -1083,6 +1094,12 @@ void APIConnection::on_get_time_response(const GetTimeResponse &value) { } #endif +bool APIConnection::send_get_time_response(const GetTimeRequest &msg) { + GetTimeResponse resp; + resp.epoch_seconds = ::time(nullptr); + return this->send_message(resp, GetTimeResponse::MESSAGE_TYPE); +} + #ifdef USE_BLUETOOTH_PROXY void APIConnection::subscribe_bluetooth_le_advertisements(const SubscribeBluetoothLEAdvertisementsRequest &msg) { bluetooth_proxy::global_bluetooth_proxy->subscribe_api_connection(this, msg.flags); @@ -1113,12 +1130,12 @@ void APIConnection::bluetooth_gatt_notify(const BluetoothGATTNotifyRequest &msg) bluetooth_proxy::global_bluetooth_proxy->bluetooth_gatt_notify(msg); } -BluetoothConnectionsFreeResponse APIConnection::subscribe_bluetooth_connections_free( +bool APIConnection::send_subscribe_bluetooth_connections_free_response( const SubscribeBluetoothConnectionsFreeRequest &msg) { BluetoothConnectionsFreeResponse resp; resp.free = bluetooth_proxy::global_bluetooth_proxy->get_bluetooth_connections_free(); resp.limit = bluetooth_proxy::global_bluetooth_proxy->get_bluetooth_connections_limit(); - return resp; + return this->send_message(resp, BluetoothConnectionsFreeResponse::MESSAGE_TYPE); } void APIConnection::bluetooth_scanner_set_mode(const BluetoothScannerSetModeRequest &msg) { @@ -1179,28 +1196,27 @@ void APIConnection::on_voice_assistant_announce_request(const VoiceAssistantAnno } } -VoiceAssistantConfigurationResponse APIConnection::voice_assistant_get_configuration( - const VoiceAssistantConfigurationRequest &msg) { +bool APIConnection::send_voice_assistant_get_configuration_response(const VoiceAssistantConfigurationRequest &msg) { VoiceAssistantConfigurationResponse resp; if (!this->check_voice_assistant_api_connection_()) { - return resp; + return this->send_message(resp, VoiceAssistantConfigurationResponse::MESSAGE_TYPE); } auto &config = voice_assistant::global_voice_assistant->get_configuration(); for (auto &wake_word : config.available_wake_words) { - VoiceAssistantWakeWord resp_wake_word; - resp_wake_word.id = wake_word.id; - resp_wake_word.wake_word = wake_word.wake_word; + resp.available_wake_words.emplace_back(); + auto &resp_wake_word = resp.available_wake_words.back(); + resp_wake_word.set_id(StringRef(wake_word.id)); + resp_wake_word.set_wake_word(StringRef(wake_word.wake_word)); for (const auto &lang : wake_word.trained_languages) { resp_wake_word.trained_languages.push_back(lang); } - resp.available_wake_words.push_back(std::move(resp_wake_word)); } for (auto &wake_word_id : config.active_wake_words) { resp.active_wake_words.push_back(wake_word_id); } resp.max_active_wake_words = config.max_active_wake_words; - return resp; + return this->send_message(resp, VoiceAssistantConfigurationResponse::MESSAGE_TYPE); } void APIConnection::voice_assistant_set_configuration(const VoiceAssistantSetConfiguration &msg) { @@ -1273,7 +1289,7 @@ void APIConnection::send_event(event::Event *event, const std::string &event_typ uint16_t APIConnection::try_send_event_response(event::Event *event, const std::string &event_type, APIConnection *conn, uint32_t remaining_size, bool is_single) { EventResponse resp; - resp.event_type = event_type; + resp.set_event_type(StringRef(event_type)); return fill_and_encode_entity_state(event, resp, EventResponse::MESSAGE_TYPE, conn, remaining_size, is_single); } @@ -1281,7 +1297,7 @@ uint16_t APIConnection::try_send_event_info(EntityBase *entity, APIConnection *c bool is_single) { auto *event = static_cast(entity); ListEntitiesEventResponse msg; - msg.device_class = event->get_device_class(); + msg.set_device_class(event->get_device_class_ref()); for (const auto &event_type : event->get_event_types()) msg.event_types.push_back(event_type); return fill_and_encode_entity_info(event, msg, ListEntitiesEventResponse::MESSAGE_TYPE, conn, remaining_size, @@ -1305,11 +1321,11 @@ uint16_t APIConnection::try_send_update_state(EntityBase *entity, APIConnection resp.has_progress = true; resp.progress = update->update_info.progress; } - resp.current_version = update->update_info.current_version; - resp.latest_version = update->update_info.latest_version; - resp.title = update->update_info.title; - resp.release_summary = update->update_info.summary; - resp.release_url = update->update_info.release_url; + resp.set_current_version(StringRef(update->update_info.current_version)); + resp.set_latest_version(StringRef(update->update_info.latest_version)); + resp.set_title(StringRef(update->update_info.title)); + resp.set_release_summary(StringRef(update->update_info.summary)); + resp.set_release_url(StringRef(update->update_info.release_url)); } return fill_and_encode_entity_state(update, resp, UpdateStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single); } @@ -1317,7 +1333,7 @@ uint16_t APIConnection::try_send_update_info(EntityBase *entity, APIConnection * bool is_single) { auto *update = static_cast(entity); ListEntitiesUpdateResponse msg; - msg.device_class = update->get_device_class(); + msg.set_device_class(update->get_device_class_ref()); return fill_and_encode_entity_info(update, msg, ListEntitiesUpdateResponse::MESSAGE_TYPE, conn, remaining_size, is_single); } @@ -1366,7 +1382,7 @@ void APIConnection::complete_authentication_() { #endif } -HelloResponse APIConnection::hello(const HelloRequest &msg) { +bool APIConnection::send_hello_response(const HelloRequest &msg) { this->client_info_.name = msg.client_info; this->client_info_.peername = this->helper_->getpeername(); this->client_api_version_major_ = msg.api_version_major; @@ -1377,8 +1393,10 @@ HelloResponse APIConnection::hello(const HelloRequest &msg) { HelloResponse resp; resp.api_version_major = 1; resp.api_version_minor = 10; - resp.server_info = App.get_name() + " (esphome v" ESPHOME_VERSION ")"; - resp.name = App.get_name(); + // Temporary string for concatenation - will be valid during send_message call + std::string server_info = App.get_name() + " (esphome v" ESPHOME_VERSION ")"; + resp.set_server_info(StringRef(server_info)); + resp.set_name(StringRef(App.get_name())); #ifdef USE_API_PASSWORD // Password required - wait for authentication @@ -1388,9 +1406,9 @@ HelloResponse APIConnection::hello(const HelloRequest &msg) { this->complete_authentication_(); #endif - return resp; + return this->send_message(resp, HelloResponse::MESSAGE_TYPE); } -ConnectResponse APIConnection::connect(const ConnectRequest &msg) { +bool APIConnection::send_connect_response(const ConnectRequest &msg) { bool correct = true; #ifdef USE_API_PASSWORD correct = this->parent_->check_password(msg.password); @@ -1402,48 +1420,71 @@ ConnectResponse APIConnection::connect(const ConnectRequest &msg) { if (correct) { this->complete_authentication_(); } - return resp; + return this->send_message(resp, ConnectResponse::MESSAGE_TYPE); } -DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) { + +bool APIConnection::send_ping_response(const PingRequest &msg) { + PingResponse resp; + return this->send_message(resp, PingResponse::MESSAGE_TYPE); +} + +bool APIConnection::send_device_info_response(const DeviceInfoRequest &msg) { DeviceInfoResponse resp{}; #ifdef USE_API_PASSWORD resp.uses_password = true; #endif - resp.name = App.get_name(); - resp.friendly_name = App.get_friendly_name(); + resp.set_name(StringRef(App.get_name())); + resp.set_friendly_name(StringRef(App.get_friendly_name())); #ifdef USE_AREAS - resp.suggested_area = App.get_area(); + resp.set_suggested_area(StringRef(App.get_area())); #endif - resp.mac_address = get_mac_address_pretty(); - resp.esphome_version = ESPHOME_VERSION; - resp.compilation_time = App.get_compilation_time(); + // mac_address must store temporary string - will be valid during send_message call + std::string mac_address = get_mac_address_pretty(); + resp.set_mac_address(StringRef(mac_address)); + + // Compile-time StringRef constants + static constexpr auto ESPHOME_VERSION_REF = StringRef::from_lit(ESPHOME_VERSION); + resp.set_esphome_version(ESPHOME_VERSION_REF); + + // get_compilation_time() returns temporary std::string - must store it + std::string compilation_time = App.get_compilation_time(); + resp.set_compilation_time(StringRef(compilation_time)); + + // Compile-time StringRef constants for manufacturers #if defined(USE_ESP8266) || defined(USE_ESP32) - resp.manufacturer = "Espressif"; + static constexpr auto MANUFACTURER = StringRef::from_lit("Espressif"); #elif defined(USE_RP2040) - resp.manufacturer = "Raspberry Pi"; + static constexpr auto MANUFACTURER = StringRef::from_lit("Raspberry Pi"); #elif defined(USE_BK72XX) - resp.manufacturer = "Beken"; + static constexpr auto MANUFACTURER = StringRef::from_lit("Beken"); #elif defined(USE_LN882X) - resp.manufacturer = "Lightning"; + static constexpr auto MANUFACTURER = StringRef::from_lit("Lightning"); #elif defined(USE_RTL87XX) - resp.manufacturer = "Realtek"; + static constexpr auto MANUFACTURER = StringRef::from_lit("Realtek"); #elif defined(USE_HOST) - resp.manufacturer = "Host"; + static constexpr auto MANUFACTURER = StringRef::from_lit("Host"); #endif - resp.model = ESPHOME_BOARD; + resp.set_manufacturer(MANUFACTURER); + + static constexpr auto MODEL = StringRef::from_lit(ESPHOME_BOARD); + resp.set_model(MODEL); #ifdef USE_DEEP_SLEEP resp.has_deep_sleep = deep_sleep::global_has_deep_sleep; #endif #ifdef ESPHOME_PROJECT_NAME - resp.project_name = ESPHOME_PROJECT_NAME; - resp.project_version = ESPHOME_PROJECT_VERSION; + static constexpr auto PROJECT_NAME = StringRef::from_lit(ESPHOME_PROJECT_NAME); + static constexpr auto PROJECT_VERSION = StringRef::from_lit(ESPHOME_PROJECT_VERSION); + resp.set_project_name(PROJECT_NAME); + resp.set_project_version(PROJECT_VERSION); #endif #ifdef USE_WEBSERVER resp.webserver_port = USE_WEBSERVER_PORT; #endif #ifdef USE_BLUETOOTH_PROXY resp.bluetooth_proxy_feature_flags = bluetooth_proxy::global_bluetooth_proxy->get_feature_flags(); - resp.bluetooth_mac_address = bluetooth_proxy::global_bluetooth_proxy->get_bluetooth_mac_address_pretty(); + // bt_mac must store temporary string - will be valid during send_message call + std::string bluetooth_mac = bluetooth_proxy::global_bluetooth_proxy->get_bluetooth_mac_address_pretty(); + resp.set_bluetooth_mac_address(StringRef(bluetooth_mac)); #endif #ifdef USE_VOICE_ASSISTANT resp.voice_assistant_feature_flags = voice_assistant::global_voice_assistant->get_feature_flags(); @@ -1453,23 +1494,25 @@ DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) { #endif #ifdef USE_DEVICES for (auto const &device : App.get_devices()) { - DeviceInfo device_info; + resp.devices.emplace_back(); + auto &device_info = resp.devices.back(); device_info.device_id = device->get_device_id(); - device_info.name = device->get_name(); + device_info.set_name(StringRef(device->get_name())); device_info.area_id = device->get_area_id(); - resp.devices.push_back(device_info); } #endif #ifdef USE_AREAS for (auto const &area : App.get_areas()) { - AreaInfo area_info; + resp.areas.emplace_back(); + auto &area_info = resp.areas.back(); area_info.area_id = area->get_area_id(); - area_info.name = area->get_name(); - resp.areas.push_back(area_info); + area_info.set_name(StringRef(area->get_name())); } #endif - return resp; + + return this->send_message(resp, DeviceInfoResponse::MESSAGE_TYPE); } + void APIConnection::on_home_assistant_state_response(const HomeAssistantStateResponse &msg) { for (auto &it : this->parent_->get_state_subs()) { if (it.entity_id == msg.entity_id && it.attribute.value() == msg.attribute) { @@ -1491,23 +1534,21 @@ void APIConnection::execute_service(const ExecuteServiceRequest &msg) { } #endif #ifdef USE_API_NOISE -NoiseEncryptionSetKeyResponse APIConnection::noise_encryption_set_key(const NoiseEncryptionSetKeyRequest &msg) { +bool APIConnection::send_noise_encryption_set_key_response(const NoiseEncryptionSetKeyRequest &msg) { psk_t psk{}; NoiseEncryptionSetKeyResponse resp; if (base64_decode(msg.key, psk.data(), msg.key.size()) != psk.size()) { ESP_LOGW(TAG, "Invalid encryption key length"); resp.success = false; - return resp; + return this->send_message(resp, NoiseEncryptionSetKeyResponse::MESSAGE_TYPE); } - if (!this->parent_->save_noise_psk(psk, true)) { ESP_LOGW(TAG, "Failed to save encryption key"); resp.success = false; - return resp; + return this->send_message(resp, NoiseEncryptionSetKeyResponse::MESSAGE_TYPE); } - resp.success = true; - return resp; + return this->send_message(resp, NoiseEncryptionSetKeyResponse::MESSAGE_TYPE); } #endif void APIConnection::subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) { diff --git a/esphome/components/api/api_connection.h b/esphome/components/api/api_connection.h index de7e91de01..5365a48292 100644 --- a/esphome/components/api/api_connection.h +++ b/esphome/components/api/api_connection.h @@ -148,8 +148,7 @@ class APIConnection : public APIServerConnection { void bluetooth_gatt_write_descriptor(const BluetoothGATTWriteDescriptorRequest &msg) override; void bluetooth_gatt_get_services(const BluetoothGATTGetServicesRequest &msg) override; void bluetooth_gatt_notify(const BluetoothGATTNotifyRequest &msg) override; - BluetoothConnectionsFreeResponse subscribe_bluetooth_connections_free( - const SubscribeBluetoothConnectionsFreeRequest &msg) override; + bool send_subscribe_bluetooth_connections_free_response(const SubscribeBluetoothConnectionsFreeRequest &msg) override; void bluetooth_scanner_set_mode(const BluetoothScannerSetModeRequest &msg) override; #endif @@ -167,8 +166,7 @@ class APIConnection : public APIServerConnection { void on_voice_assistant_audio(const VoiceAssistantAudio &msg) override; void on_voice_assistant_timer_event_response(const VoiceAssistantTimerEventResponse &msg) override; void on_voice_assistant_announce_request(const VoiceAssistantAnnounceRequest &msg) override; - VoiceAssistantConfigurationResponse voice_assistant_get_configuration( - const VoiceAssistantConfigurationRequest &msg) override; + bool send_voice_assistant_get_configuration_response(const VoiceAssistantConfigurationRequest &msg) override; void voice_assistant_set_configuration(const VoiceAssistantSetConfiguration &msg) override; #endif @@ -195,11 +193,11 @@ class APIConnection : public APIServerConnection { #ifdef USE_HOMEASSISTANT_TIME void on_get_time_response(const GetTimeResponse &value) override; #endif - HelloResponse hello(const HelloRequest &msg) override; - ConnectResponse connect(const ConnectRequest &msg) override; - DisconnectResponse disconnect(const DisconnectRequest &msg) override; - PingResponse ping(const PingRequest &msg) override { return {}; } - DeviceInfoResponse device_info(const DeviceInfoRequest &msg) override; + bool send_hello_response(const HelloRequest &msg) override; + bool send_connect_response(const ConnectRequest &msg) override; + bool send_disconnect_response(const DisconnectRequest &msg) override; + bool send_ping_response(const PingRequest &msg) override; + bool send_device_info_response(const DeviceInfoRequest &msg) override; void list_entities(const ListEntitiesRequest &msg) override { this->list_entities_iterator_.begin(); } void subscribe_states(const SubscribeStatesRequest &msg) override { this->flags_.state_subscription = true; @@ -214,15 +212,12 @@ class APIConnection : public APIServerConnection { this->flags_.service_call_subscription = true; } void subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) override; - GetTimeResponse get_time(const GetTimeRequest &msg) override { - // TODO - return {}; - } + bool send_get_time_response(const GetTimeRequest &msg) override; #ifdef USE_API_SERVICES void execute_service(const ExecuteServiceRequest &msg) override; #endif #ifdef USE_API_NOISE - NoiseEncryptionSetKeyResponse noise_encryption_set_key(const NoiseEncryptionSetKeyRequest &msg) override; + bool send_noise_encryption_set_key_response(const NoiseEncryptionSetKeyRequest &msg) override; #endif bool is_authenticated() override { @@ -313,14 +308,17 @@ class APIConnection : public APIServerConnection { APIConnection *conn, uint32_t remaining_size, bool is_single) { // Set common fields that are shared by all entity types msg.key = entity->get_object_id_hash(); - msg.object_id = entity->get_object_id(); + // IMPORTANT: get_object_id() may return a temporary std::string + std::string object_id = entity->get_object_id(); + msg.set_object_id(StringRef(object_id)); - if (entity->has_own_name()) - msg.name = entity->get_name(); + if (entity->has_own_name()) { + msg.set_name(entity->get_name()); + } - // Set common EntityBase properties + // Set common EntityBase properties #ifdef USE_ENTITY_ICON - msg.icon = entity->get_icon(); + msg.set_icon(entity->get_icon_ref()); #endif msg.disabled_by_default = entity->is_disabled_by_default(); msg.entity_category = static_cast(entity->get_entity_category()); diff --git a/esphome/components/api/api_pb2.cpp b/esphome/components/api/api_pb2.cpp index 09a1522fb4..d51f641746 100644 --- a/esphome/components/api/api_pb2.cpp +++ b/esphome/components/api/api_pb2.cpp @@ -34,14 +34,14 @@ bool HelloRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) void HelloResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_uint32(1, this->api_version_major); buffer.encode_uint32(2, this->api_version_minor); - buffer.encode_string(3, this->server_info); - buffer.encode_string(4, this->name); + buffer.encode_string(3, this->server_info_ref_); + buffer.encode_string(4, this->name_ref_); } void HelloResponse::calculate_size(uint32_t &total_size) const { ProtoSize::add_uint32_field(total_size, 1, this->api_version_major); ProtoSize::add_uint32_field(total_size, 1, this->api_version_minor); - ProtoSize::add_string_field(total_size, 1, this->server_info); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->server_info_ref_.size()); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); } bool ConnectRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { @@ -60,22 +60,22 @@ void ConnectResponse::calculate_size(uint32_t &total_size) const { #ifdef USE_AREAS void AreaInfo::encode(ProtoWriteBuffer buffer) const { buffer.encode_uint32(1, this->area_id); - buffer.encode_string(2, this->name); + buffer.encode_string(2, this->name_ref_); } void AreaInfo::calculate_size(uint32_t &total_size) const { ProtoSize::add_uint32_field(total_size, 1, this->area_id); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); } #endif #ifdef USE_DEVICES void DeviceInfo::encode(ProtoWriteBuffer buffer) const { buffer.encode_uint32(1, this->device_id); - buffer.encode_string(2, this->name); + buffer.encode_string(2, this->name_ref_); buffer.encode_uint32(3, this->area_id); } void DeviceInfo::calculate_size(uint32_t &total_size) const { ProtoSize::add_uint32_field(total_size, 1, this->device_id); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); ProtoSize::add_uint32_field(total_size, 1, this->area_id); } #endif @@ -83,19 +83,19 @@ void DeviceInfoResponse::encode(ProtoWriteBuffer buffer) const { #ifdef USE_API_PASSWORD buffer.encode_bool(1, this->uses_password); #endif - buffer.encode_string(2, this->name); - buffer.encode_string(3, this->mac_address); - buffer.encode_string(4, this->esphome_version); - buffer.encode_string(5, this->compilation_time); - buffer.encode_string(6, this->model); + buffer.encode_string(2, this->name_ref_); + buffer.encode_string(3, this->mac_address_ref_); + buffer.encode_string(4, this->esphome_version_ref_); + buffer.encode_string(5, this->compilation_time_ref_); + buffer.encode_string(6, this->model_ref_); #ifdef USE_DEEP_SLEEP buffer.encode_bool(7, this->has_deep_sleep); #endif #ifdef ESPHOME_PROJECT_NAME - buffer.encode_string(8, this->project_name); + buffer.encode_string(8, this->project_name_ref_); #endif #ifdef ESPHOME_PROJECT_NAME - buffer.encode_string(9, this->project_version); + buffer.encode_string(9, this->project_version_ref_); #endif #ifdef USE_WEBSERVER buffer.encode_uint32(10, this->webserver_port); @@ -103,16 +103,16 @@ void DeviceInfoResponse::encode(ProtoWriteBuffer buffer) const { #ifdef USE_BLUETOOTH_PROXY buffer.encode_uint32(15, this->bluetooth_proxy_feature_flags); #endif - buffer.encode_string(12, this->manufacturer); - buffer.encode_string(13, this->friendly_name); + buffer.encode_string(12, this->manufacturer_ref_); + buffer.encode_string(13, this->friendly_name_ref_); #ifdef USE_VOICE_ASSISTANT buffer.encode_uint32(17, this->voice_assistant_feature_flags); #endif #ifdef USE_AREAS - buffer.encode_string(16, this->suggested_area); + buffer.encode_string(16, this->suggested_area_ref_); #endif #ifdef USE_BLUETOOTH_PROXY - buffer.encode_string(18, this->bluetooth_mac_address); + buffer.encode_string(18, this->bluetooth_mac_address_ref_); #endif #ifdef USE_API_NOISE buffer.encode_bool(19, this->api_encryption_supported); @@ -135,19 +135,19 @@ void DeviceInfoResponse::calculate_size(uint32_t &total_size) const { #ifdef USE_API_PASSWORD ProtoSize::add_bool_field(total_size, 1, this->uses_password); #endif - ProtoSize::add_string_field(total_size, 1, this->name); - ProtoSize::add_string_field(total_size, 1, this->mac_address); - ProtoSize::add_string_field(total_size, 1, this->esphome_version); - ProtoSize::add_string_field(total_size, 1, this->compilation_time); - ProtoSize::add_string_field(total_size, 1, this->model); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); + ProtoSize::add_string_field(total_size, 1, this->mac_address_ref_.size()); + ProtoSize::add_string_field(total_size, 1, this->esphome_version_ref_.size()); + ProtoSize::add_string_field(total_size, 1, this->compilation_time_ref_.size()); + ProtoSize::add_string_field(total_size, 1, this->model_ref_.size()); #ifdef USE_DEEP_SLEEP ProtoSize::add_bool_field(total_size, 1, this->has_deep_sleep); #endif #ifdef ESPHOME_PROJECT_NAME - ProtoSize::add_string_field(total_size, 1, this->project_name); + ProtoSize::add_string_field(total_size, 1, this->project_name_ref_.size()); #endif #ifdef ESPHOME_PROJECT_NAME - ProtoSize::add_string_field(total_size, 1, this->project_version); + ProtoSize::add_string_field(total_size, 1, this->project_version_ref_.size()); #endif #ifdef USE_WEBSERVER ProtoSize::add_uint32_field(total_size, 1, this->webserver_port); @@ -155,16 +155,16 @@ void DeviceInfoResponse::calculate_size(uint32_t &total_size) const { #ifdef USE_BLUETOOTH_PROXY ProtoSize::add_uint32_field(total_size, 1, this->bluetooth_proxy_feature_flags); #endif - ProtoSize::add_string_field(total_size, 1, this->manufacturer); - ProtoSize::add_string_field(total_size, 1, this->friendly_name); + ProtoSize::add_string_field(total_size, 1, this->manufacturer_ref_.size()); + ProtoSize::add_string_field(total_size, 1, this->friendly_name_ref_.size()); #ifdef USE_VOICE_ASSISTANT ProtoSize::add_uint32_field(total_size, 2, this->voice_assistant_feature_flags); #endif #ifdef USE_AREAS - ProtoSize::add_string_field(total_size, 2, this->suggested_area); + ProtoSize::add_string_field(total_size, 2, this->suggested_area_ref_.size()); #endif #ifdef USE_BLUETOOTH_PROXY - ProtoSize::add_string_field(total_size, 2, this->bluetooth_mac_address); + ProtoSize::add_string_field(total_size, 2, this->bluetooth_mac_address_ref_.size()); #endif #ifdef USE_API_NOISE ProtoSize::add_bool_field(total_size, 2, this->api_encryption_supported); @@ -181,14 +181,14 @@ void DeviceInfoResponse::calculate_size(uint32_t &total_size) const { } #ifdef USE_BINARY_SENSOR void ListEntitiesBinarySensorResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); - buffer.encode_string(5, this->device_class); + buffer.encode_string(3, this->name_ref_); + buffer.encode_string(5, this->device_class_ref_); buffer.encode_bool(6, this->is_status_binary_sensor); buffer.encode_bool(7, this->disabled_by_default); #ifdef USE_ENTITY_ICON - buffer.encode_string(8, this->icon); + buffer.encode_string(8, this->icon_ref_); #endif buffer.encode_uint32(9, static_cast(this->entity_category)); #ifdef USE_DEVICES @@ -196,14 +196,14 @@ void ListEntitiesBinarySensorResponse::encode(ProtoWriteBuffer buffer) const { #endif } void ListEntitiesBinarySensorResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); - ProtoSize::add_string_field(total_size, 1, this->device_class); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); + ProtoSize::add_string_field(total_size, 1, this->device_class_ref_.size()); ProtoSize::add_bool_field(total_size, 1, this->is_status_binary_sensor); ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); #ifdef USE_DEVICES @@ -229,16 +229,16 @@ void BinarySensorStateResponse::calculate_size(uint32_t &total_size) const { #endif #ifdef USE_COVER void ListEntitiesCoverResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); buffer.encode_bool(5, this->assumed_state); buffer.encode_bool(6, this->supports_position); buffer.encode_bool(7, this->supports_tilt); - buffer.encode_string(8, this->device_class); + buffer.encode_string(8, this->device_class_ref_); buffer.encode_bool(9, this->disabled_by_default); #ifdef USE_ENTITY_ICON - buffer.encode_string(10, this->icon); + buffer.encode_string(10, this->icon_ref_); #endif buffer.encode_uint32(11, static_cast(this->entity_category)); buffer.encode_bool(12, this->supports_stop); @@ -247,16 +247,16 @@ void ListEntitiesCoverResponse::encode(ProtoWriteBuffer buffer) const { #endif } void ListEntitiesCoverResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); ProtoSize::add_bool_field(total_size, 1, this->assumed_state); ProtoSize::add_bool_field(total_size, 1, this->supports_position); ProtoSize::add_bool_field(total_size, 1, this->supports_tilt); - ProtoSize::add_string_field(total_size, 1, this->device_class); + ProtoSize::add_string_field(total_size, 1, this->device_class_ref_.size()); ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); ProtoSize::add_bool_field(total_size, 1, this->supports_stop); @@ -322,16 +322,16 @@ bool CoverCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { #endif #ifdef USE_FAN void ListEntitiesFanResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); buffer.encode_bool(5, this->supports_oscillation); buffer.encode_bool(6, this->supports_speed); buffer.encode_bool(7, this->supports_direction); buffer.encode_int32(8, this->supported_speed_count); buffer.encode_bool(9, this->disabled_by_default); #ifdef USE_ENTITY_ICON - buffer.encode_string(10, this->icon); + buffer.encode_string(10, this->icon_ref_); #endif buffer.encode_uint32(11, static_cast(this->entity_category)); for (auto &it : this->supported_preset_modes) { @@ -342,16 +342,16 @@ void ListEntitiesFanResponse::encode(ProtoWriteBuffer buffer) const { #endif } void ListEntitiesFanResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); ProtoSize::add_bool_field(total_size, 1, this->supports_oscillation); ProtoSize::add_bool_field(total_size, 1, this->supports_speed); ProtoSize::add_bool_field(total_size, 1, this->supports_direction); ProtoSize::add_int32_field(total_size, 1, this->supported_speed_count); ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); if (!this->supported_preset_modes.empty()) { @@ -369,7 +369,7 @@ void FanStateResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_bool(3, this->oscillating); buffer.encode_uint32(5, static_cast(this->direction)); buffer.encode_int32(6, this->speed_level); - buffer.encode_string(7, this->preset_mode); + buffer.encode_string(7, this->preset_mode_ref_); #ifdef USE_DEVICES buffer.encode_uint32(8, this->device_id); #endif @@ -380,7 +380,7 @@ void FanStateResponse::calculate_size(uint32_t &total_size) const { ProtoSize::add_bool_field(total_size, 1, this->oscillating); ProtoSize::add_enum_field(total_size, 1, static_cast(this->direction)); ProtoSize::add_int32_field(total_size, 1, this->speed_level); - ProtoSize::add_string_field(total_size, 1, this->preset_mode); + ProtoSize::add_string_field(total_size, 1, this->preset_mode_ref_.size()); #ifdef USE_DEVICES ProtoSize::add_uint32_field(total_size, 1, this->device_id); #endif @@ -447,9 +447,9 @@ bool FanCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { #endif #ifdef USE_LIGHT void ListEntitiesLightResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); for (auto &it : this->supported_color_modes) { buffer.encode_uint32(12, static_cast(it), true); } @@ -460,7 +460,7 @@ void ListEntitiesLightResponse::encode(ProtoWriteBuffer buffer) const { } buffer.encode_bool(13, this->disabled_by_default); #ifdef USE_ENTITY_ICON - buffer.encode_string(14, this->icon); + buffer.encode_string(14, this->icon_ref_); #endif buffer.encode_uint32(15, static_cast(this->entity_category)); #ifdef USE_DEVICES @@ -468,9 +468,9 @@ void ListEntitiesLightResponse::encode(ProtoWriteBuffer buffer) const { #endif } void ListEntitiesLightResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); if (!this->supported_color_modes.empty()) { for (const auto &it : this->supported_color_modes) { ProtoSize::add_enum_field_repeated(total_size, 1, static_cast(it)); @@ -485,7 +485,7 @@ void ListEntitiesLightResponse::calculate_size(uint32_t &total_size) const { } ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); #ifdef USE_DEVICES @@ -505,7 +505,7 @@ void LightStateResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_float(8, this->color_temperature); buffer.encode_float(12, this->cold_white); buffer.encode_float(13, this->warm_white); - buffer.encode_string(9, this->effect); + buffer.encode_string(9, this->effect_ref_); #ifdef USE_DEVICES buffer.encode_uint32(14, this->device_id); #endif @@ -523,7 +523,7 @@ void LightStateResponse::calculate_size(uint32_t &total_size) const { ProtoSize::add_float_field(total_size, 1, this->color_temperature); ProtoSize::add_float_field(total_size, 1, this->cold_white); ProtoSize::add_float_field(total_size, 1, this->warm_white); - ProtoSize::add_string_field(total_size, 1, this->effect); + ProtoSize::add_string_field(total_size, 1, this->effect_ref_.size()); #ifdef USE_DEVICES ProtoSize::add_uint32_field(total_size, 1, this->device_id); #endif @@ -638,16 +638,16 @@ bool LightCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { #endif #ifdef USE_SENSOR void ListEntitiesSensorResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); #ifdef USE_ENTITY_ICON - buffer.encode_string(5, this->icon); + buffer.encode_string(5, this->icon_ref_); #endif - buffer.encode_string(6, this->unit_of_measurement); + buffer.encode_string(6, this->unit_of_measurement_ref_); buffer.encode_int32(7, this->accuracy_decimals); buffer.encode_bool(8, this->force_update); - buffer.encode_string(9, this->device_class); + buffer.encode_string(9, this->device_class_ref_); buffer.encode_uint32(10, static_cast(this->state_class)); buffer.encode_bool(12, this->disabled_by_default); buffer.encode_uint32(13, static_cast(this->entity_category)); @@ -656,16 +656,16 @@ void ListEntitiesSensorResponse::encode(ProtoWriteBuffer buffer) const { #endif } void ListEntitiesSensorResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif - ProtoSize::add_string_field(total_size, 1, this->unit_of_measurement); + ProtoSize::add_string_field(total_size, 1, this->unit_of_measurement_ref_.size()); ProtoSize::add_int32_field(total_size, 1, this->accuracy_decimals); ProtoSize::add_bool_field(total_size, 1, this->force_update); - ProtoSize::add_string_field(total_size, 1, this->device_class); + ProtoSize::add_string_field(total_size, 1, this->device_class_ref_.size()); ProtoSize::add_enum_field(total_size, 1, static_cast(this->state_class)); ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); @@ -692,31 +692,31 @@ void SensorStateResponse::calculate_size(uint32_t &total_size) const { #endif #ifdef USE_SWITCH void ListEntitiesSwitchResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); #ifdef USE_ENTITY_ICON - buffer.encode_string(5, this->icon); + buffer.encode_string(5, this->icon_ref_); #endif buffer.encode_bool(6, this->assumed_state); buffer.encode_bool(7, this->disabled_by_default); buffer.encode_uint32(8, static_cast(this->entity_category)); - buffer.encode_string(9, this->device_class); + buffer.encode_string(9, this->device_class_ref_); #ifdef USE_DEVICES buffer.encode_uint32(10, this->device_id); #endif } void ListEntitiesSwitchResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_bool_field(total_size, 1, this->assumed_state); ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); - ProtoSize::add_string_field(total_size, 1, this->device_class); + ProtoSize::add_string_field(total_size, 1, this->device_class_ref_.size()); #ifdef USE_DEVICES ProtoSize::add_uint32_field(total_size, 1, this->device_id); #endif @@ -763,36 +763,36 @@ bool SwitchCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { #endif #ifdef USE_TEXT_SENSOR void ListEntitiesTextSensorResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); #ifdef USE_ENTITY_ICON - buffer.encode_string(5, this->icon); + buffer.encode_string(5, this->icon_ref_); #endif buffer.encode_bool(6, this->disabled_by_default); buffer.encode_uint32(7, static_cast(this->entity_category)); - buffer.encode_string(8, this->device_class); + buffer.encode_string(8, this->device_class_ref_); #ifdef USE_DEVICES buffer.encode_uint32(9, this->device_id); #endif } void ListEntitiesTextSensorResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); - ProtoSize::add_string_field(total_size, 1, this->device_class); + ProtoSize::add_string_field(total_size, 1, this->device_class_ref_.size()); #ifdef USE_DEVICES ProtoSize::add_uint32_field(total_size, 1, this->device_id); #endif } void TextSensorStateResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_fixed32(1, this->key); - buffer.encode_string(2, this->state); + buffer.encode_string(2, this->state_ref_); buffer.encode_bool(3, this->missing_state); #ifdef USE_DEVICES buffer.encode_uint32(4, this->device_id); @@ -800,7 +800,7 @@ void TextSensorStateResponse::encode(ProtoWriteBuffer buffer) const { } void TextSensorStateResponse::calculate_size(uint32_t &total_size) const { ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->state); + ProtoSize::add_string_field(total_size, 1, this->state_ref_.size()); ProtoSize::add_bool_field(total_size, 1, this->missing_state); #ifdef USE_DEVICES ProtoSize::add_uint32_field(total_size, 1, this->device_id); @@ -845,15 +845,15 @@ void NoiseEncryptionSetKeyResponse::calculate_size(uint32_t &total_size) const { } #endif void HomeassistantServiceMap::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->key); - buffer.encode_string(2, this->value); + buffer.encode_string(1, this->key_ref_); + buffer.encode_string(2, this->value_ref_); } void HomeassistantServiceMap::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->value); + ProtoSize::add_string_field(total_size, 1, this->key_ref_.size()); + ProtoSize::add_string_field(total_size, 1, this->value_ref_.size()); } void HomeassistantServiceResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->service); + buffer.encode_string(1, this->service_ref_); for (auto &it : this->data) { buffer.encode_message(2, it, true); } @@ -866,20 +866,20 @@ void HomeassistantServiceResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_bool(5, this->is_event); } void HomeassistantServiceResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->service); + ProtoSize::add_string_field(total_size, 1, this->service_ref_.size()); ProtoSize::add_repeated_message(total_size, 1, this->data); ProtoSize::add_repeated_message(total_size, 1, this->data_template); ProtoSize::add_repeated_message(total_size, 1, this->variables); ProtoSize::add_bool_field(total_size, 1, this->is_event); } void SubscribeHomeAssistantStateResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->entity_id); - buffer.encode_string(2, this->attribute); + buffer.encode_string(1, this->entity_id_ref_); + buffer.encode_string(2, this->attribute_ref_); buffer.encode_bool(3, this->once); } void SubscribeHomeAssistantStateResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->entity_id); - ProtoSize::add_string_field(total_size, 1, this->attribute); + ProtoSize::add_string_field(total_size, 1, this->entity_id_ref_.size()); + ProtoSize::add_string_field(total_size, 1, this->attribute_ref_.size()); ProtoSize::add_bool_field(total_size, 1, this->once); } bool HomeAssistantStateResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) { @@ -914,22 +914,22 @@ void GetTimeResponse::calculate_size(uint32_t &total_size) const { } #ifdef USE_API_SERVICES void ListEntitiesServicesArgument::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->name); + buffer.encode_string(1, this->name_ref_); buffer.encode_uint32(2, static_cast(this->type)); } void ListEntitiesServicesArgument::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); ProtoSize::add_enum_field(total_size, 1, static_cast(this->type)); } void ListEntitiesServicesResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->name); + buffer.encode_string(1, this->name_ref_); buffer.encode_fixed32(2, this->key); for (auto &it : this->args) { buffer.encode_message(3, it, true); } } void ListEntitiesServicesResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); ProtoSize::add_repeated_message(total_size, 1, this->args); } @@ -1005,12 +1005,12 @@ bool ExecuteServiceRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { #endif #ifdef USE_CAMERA void ListEntitiesCameraResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); buffer.encode_bool(5, this->disabled_by_default); #ifdef USE_ENTITY_ICON - buffer.encode_string(6, this->icon); + buffer.encode_string(6, this->icon_ref_); #endif buffer.encode_uint32(7, static_cast(this->entity_category)); #ifdef USE_DEVICES @@ -1018,12 +1018,12 @@ void ListEntitiesCameraResponse::encode(ProtoWriteBuffer buffer) const { #endif } void ListEntitiesCameraResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); #ifdef USE_DEVICES @@ -1062,9 +1062,9 @@ bool CameraImageRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { #endif #ifdef USE_CLIMATE void ListEntitiesClimateResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); buffer.encode_bool(5, this->supports_current_temperature); buffer.encode_bool(6, this->supports_two_point_target_temperature); for (auto &it : this->supported_modes) { @@ -1091,7 +1091,7 @@ void ListEntitiesClimateResponse::encode(ProtoWriteBuffer buffer) const { } buffer.encode_bool(18, this->disabled_by_default); #ifdef USE_ENTITY_ICON - buffer.encode_string(19, this->icon); + buffer.encode_string(19, this->icon_ref_); #endif buffer.encode_uint32(20, static_cast(this->entity_category)); buffer.encode_float(21, this->visual_current_temperature_step); @@ -1104,9 +1104,9 @@ void ListEntitiesClimateResponse::encode(ProtoWriteBuffer buffer) const { #endif } void ListEntitiesClimateResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); ProtoSize::add_bool_field(total_size, 1, this->supports_current_temperature); ProtoSize::add_bool_field(total_size, 1, this->supports_two_point_target_temperature); if (!this->supported_modes.empty()) { @@ -1145,7 +1145,7 @@ void ListEntitiesClimateResponse::calculate_size(uint32_t &total_size) const { } ProtoSize::add_bool_field(total_size, 2, this->disabled_by_default); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 2, this->icon); + ProtoSize::add_string_field(total_size, 2, this->icon_ref_.size()); #endif ProtoSize::add_enum_field(total_size, 2, static_cast(this->entity_category)); ProtoSize::add_float_field(total_size, 2, this->visual_current_temperature_step); @@ -1167,9 +1167,9 @@ void ClimateStateResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_uint32(8, static_cast(this->action)); buffer.encode_uint32(9, static_cast(this->fan_mode)); buffer.encode_uint32(10, static_cast(this->swing_mode)); - buffer.encode_string(11, this->custom_fan_mode); + buffer.encode_string(11, this->custom_fan_mode_ref_); buffer.encode_uint32(12, static_cast(this->preset)); - buffer.encode_string(13, this->custom_preset); + buffer.encode_string(13, this->custom_preset_ref_); buffer.encode_float(14, this->current_humidity); buffer.encode_float(15, this->target_humidity); #ifdef USE_DEVICES @@ -1186,9 +1186,9 @@ void ClimateStateResponse::calculate_size(uint32_t &total_size) const { ProtoSize::add_enum_field(total_size, 1, static_cast(this->action)); ProtoSize::add_enum_field(total_size, 1, static_cast(this->fan_mode)); ProtoSize::add_enum_field(total_size, 1, static_cast(this->swing_mode)); - ProtoSize::add_string_field(total_size, 1, this->custom_fan_mode); + ProtoSize::add_string_field(total_size, 1, this->custom_fan_mode_ref_.size()); ProtoSize::add_enum_field(total_size, 1, static_cast(this->preset)); - ProtoSize::add_string_field(total_size, 1, this->custom_preset); + ProtoSize::add_string_field(total_size, 1, this->custom_preset_ref_.size()); ProtoSize::add_float_field(total_size, 1, this->current_humidity); ProtoSize::add_float_field(total_size, 1, this->target_humidity); #ifdef USE_DEVICES @@ -1287,39 +1287,39 @@ bool ClimateCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { #endif #ifdef USE_NUMBER void ListEntitiesNumberResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); #ifdef USE_ENTITY_ICON - buffer.encode_string(5, this->icon); + buffer.encode_string(5, this->icon_ref_); #endif buffer.encode_float(6, this->min_value); buffer.encode_float(7, this->max_value); buffer.encode_float(8, this->step); buffer.encode_bool(9, this->disabled_by_default); buffer.encode_uint32(10, static_cast(this->entity_category)); - buffer.encode_string(11, this->unit_of_measurement); + buffer.encode_string(11, this->unit_of_measurement_ref_); buffer.encode_uint32(12, static_cast(this->mode)); - buffer.encode_string(13, this->device_class); + buffer.encode_string(13, this->device_class_ref_); #ifdef USE_DEVICES buffer.encode_uint32(14, this->device_id); #endif } void ListEntitiesNumberResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_float_field(total_size, 1, this->min_value); ProtoSize::add_float_field(total_size, 1, this->max_value); ProtoSize::add_float_field(total_size, 1, this->step); ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); - ProtoSize::add_string_field(total_size, 1, this->unit_of_measurement); + ProtoSize::add_string_field(total_size, 1, this->unit_of_measurement_ref_.size()); ProtoSize::add_enum_field(total_size, 1, static_cast(this->mode)); - ProtoSize::add_string_field(total_size, 1, this->device_class); + ProtoSize::add_string_field(total_size, 1, this->device_class_ref_.size()); #ifdef USE_DEVICES ProtoSize::add_uint32_field(total_size, 1, this->device_id); #endif @@ -1368,11 +1368,11 @@ bool NumberCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { #endif #ifdef USE_SELECT void ListEntitiesSelectResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); #ifdef USE_ENTITY_ICON - buffer.encode_string(5, this->icon); + buffer.encode_string(5, this->icon_ref_); #endif for (auto &it : this->options) { buffer.encode_string(6, it, true); @@ -1384,11 +1384,11 @@ void ListEntitiesSelectResponse::encode(ProtoWriteBuffer buffer) const { #endif } void ListEntitiesSelectResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif if (!this->options.empty()) { for (const auto &it : this->options) { @@ -1403,7 +1403,7 @@ void ListEntitiesSelectResponse::calculate_size(uint32_t &total_size) const { } void SelectStateResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_fixed32(1, this->key); - buffer.encode_string(2, this->state); + buffer.encode_string(2, this->state_ref_); buffer.encode_bool(3, this->missing_state); #ifdef USE_DEVICES buffer.encode_uint32(4, this->device_id); @@ -1411,7 +1411,7 @@ void SelectStateResponse::encode(ProtoWriteBuffer buffer) const { } void SelectStateResponse::calculate_size(uint32_t &total_size) const { ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->state); + ProtoSize::add_string_field(total_size, 1, this->state_ref_.size()); ProtoSize::add_bool_field(total_size, 1, this->missing_state); #ifdef USE_DEVICES ProtoSize::add_uint32_field(total_size, 1, this->device_id); @@ -1452,11 +1452,11 @@ bool SelectCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { #endif #ifdef USE_SIREN void ListEntitiesSirenResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); #ifdef USE_ENTITY_ICON - buffer.encode_string(5, this->icon); + buffer.encode_string(5, this->icon_ref_); #endif buffer.encode_bool(6, this->disabled_by_default); for (auto &it : this->tones) { @@ -1470,11 +1470,11 @@ void ListEntitiesSirenResponse::encode(ProtoWriteBuffer buffer) const { #endif } void ListEntitiesSirenResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); if (!this->tones.empty()) { @@ -1559,35 +1559,35 @@ bool SirenCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { #endif #ifdef USE_LOCK void ListEntitiesLockResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); #ifdef USE_ENTITY_ICON - buffer.encode_string(5, this->icon); + buffer.encode_string(5, this->icon_ref_); #endif buffer.encode_bool(6, this->disabled_by_default); buffer.encode_uint32(7, static_cast(this->entity_category)); buffer.encode_bool(8, this->assumed_state); buffer.encode_bool(9, this->supports_open); buffer.encode_bool(10, this->requires_code); - buffer.encode_string(11, this->code_format); + buffer.encode_string(11, this->code_format_ref_); #ifdef USE_DEVICES buffer.encode_uint32(12, this->device_id); #endif } void ListEntitiesLockResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); ProtoSize::add_bool_field(total_size, 1, this->assumed_state); ProtoSize::add_bool_field(total_size, 1, this->supports_open); ProtoSize::add_bool_field(total_size, 1, this->requires_code); - ProtoSize::add_string_field(total_size, 1, this->code_format); + ProtoSize::add_string_field(total_size, 1, this->code_format_ref_.size()); #ifdef USE_DEVICES ProtoSize::add_uint32_field(total_size, 1, this->device_id); #endif @@ -1647,29 +1647,29 @@ bool LockCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { #endif #ifdef USE_BUTTON void ListEntitiesButtonResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); #ifdef USE_ENTITY_ICON - buffer.encode_string(5, this->icon); + buffer.encode_string(5, this->icon_ref_); #endif buffer.encode_bool(6, this->disabled_by_default); buffer.encode_uint32(7, static_cast(this->entity_category)); - buffer.encode_string(8, this->device_class); + buffer.encode_string(8, this->device_class_ref_); #ifdef USE_DEVICES buffer.encode_uint32(9, this->device_id); #endif } void ListEntitiesButtonResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); - ProtoSize::add_string_field(total_size, 1, this->device_class); + ProtoSize::add_string_field(total_size, 1, this->device_class_ref_.size()); #ifdef USE_DEVICES ProtoSize::add_uint32_field(total_size, 1, this->device_id); #endif @@ -1699,25 +1699,25 @@ bool ButtonCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { #endif #ifdef USE_MEDIA_PLAYER void MediaPlayerSupportedFormat::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->format); + buffer.encode_string(1, this->format_ref_); buffer.encode_uint32(2, this->sample_rate); buffer.encode_uint32(3, this->num_channels); buffer.encode_uint32(4, static_cast(this->purpose)); buffer.encode_uint32(5, this->sample_bytes); } void MediaPlayerSupportedFormat::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->format); + ProtoSize::add_string_field(total_size, 1, this->format_ref_.size()); ProtoSize::add_uint32_field(total_size, 1, this->sample_rate); ProtoSize::add_uint32_field(total_size, 1, this->num_channels); ProtoSize::add_enum_field(total_size, 1, static_cast(this->purpose)); ProtoSize::add_uint32_field(total_size, 1, this->sample_bytes); } void ListEntitiesMediaPlayerResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); #ifdef USE_ENTITY_ICON - buffer.encode_string(5, this->icon); + buffer.encode_string(5, this->icon_ref_); #endif buffer.encode_bool(6, this->disabled_by_default); buffer.encode_uint32(7, static_cast(this->entity_category)); @@ -1730,11 +1730,11 @@ void ListEntitiesMediaPlayerResponse::encode(ProtoWriteBuffer buffer) const { #endif } void ListEntitiesMediaPlayerResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); @@ -2172,17 +2172,17 @@ void VoiceAssistantAudioSettings::calculate_size(uint32_t &total_size) const { } void VoiceAssistantRequest::encode(ProtoWriteBuffer buffer) const { buffer.encode_bool(1, this->start); - buffer.encode_string(2, this->conversation_id); + buffer.encode_string(2, this->conversation_id_ref_); buffer.encode_uint32(3, this->flags); buffer.encode_message(4, this->audio_settings); - buffer.encode_string(5, this->wake_word_phrase); + buffer.encode_string(5, this->wake_word_phrase_ref_); } void VoiceAssistantRequest::calculate_size(uint32_t &total_size) const { ProtoSize::add_bool_field(total_size, 1, this->start); - ProtoSize::add_string_field(total_size, 1, this->conversation_id); + ProtoSize::add_string_field(total_size, 1, this->conversation_id_ref_.size()); ProtoSize::add_uint32_field(total_size, 1, this->flags); ProtoSize::add_message_object(total_size, 1, this->audio_settings); - ProtoSize::add_string_field(total_size, 1, this->wake_word_phrase); + ProtoSize::add_string_field(total_size, 1, this->wake_word_phrase_ref_.size()); } bool VoiceAssistantResponse::decode_varint(uint32_t field_id, ProtoVarInt value) { switch (field_id) { @@ -2322,15 +2322,15 @@ void VoiceAssistantAnnounceFinished::calculate_size(uint32_t &total_size) const ProtoSize::add_bool_field(total_size, 1, this->success); } void VoiceAssistantWakeWord::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->id); - buffer.encode_string(2, this->wake_word); + buffer.encode_string(1, this->id_ref_); + buffer.encode_string(2, this->wake_word_ref_); for (auto &it : this->trained_languages) { buffer.encode_string(3, it, true); } } void VoiceAssistantWakeWord::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->id); - ProtoSize::add_string_field(total_size, 1, this->wake_word); + ProtoSize::add_string_field(total_size, 1, this->id_ref_.size()); + ProtoSize::add_string_field(total_size, 1, this->wake_word_ref_.size()); if (!this->trained_languages.empty()) { for (const auto &it : this->trained_languages) { ProtoSize::add_string_field_repeated(total_size, 1, it); @@ -2368,11 +2368,11 @@ bool VoiceAssistantSetConfiguration::decode_length(uint32_t field_id, ProtoLengt #endif #ifdef USE_ALARM_CONTROL_PANEL void ListEntitiesAlarmControlPanelResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); #ifdef USE_ENTITY_ICON - buffer.encode_string(5, this->icon); + buffer.encode_string(5, this->icon_ref_); #endif buffer.encode_bool(6, this->disabled_by_default); buffer.encode_uint32(7, static_cast(this->entity_category)); @@ -2384,11 +2384,11 @@ void ListEntitiesAlarmControlPanelResponse::encode(ProtoWriteBuffer buffer) cons #endif } void ListEntitiesAlarmControlPanelResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); @@ -2451,34 +2451,34 @@ bool AlarmControlPanelCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit #endif #ifdef USE_TEXT void ListEntitiesTextResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); #ifdef USE_ENTITY_ICON - buffer.encode_string(5, this->icon); + buffer.encode_string(5, this->icon_ref_); #endif buffer.encode_bool(6, this->disabled_by_default); buffer.encode_uint32(7, static_cast(this->entity_category)); buffer.encode_uint32(8, this->min_length); buffer.encode_uint32(9, this->max_length); - buffer.encode_string(10, this->pattern); + buffer.encode_string(10, this->pattern_ref_); buffer.encode_uint32(11, static_cast(this->mode)); #ifdef USE_DEVICES buffer.encode_uint32(12, this->device_id); #endif } void ListEntitiesTextResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); ProtoSize::add_uint32_field(total_size, 1, this->min_length); ProtoSize::add_uint32_field(total_size, 1, this->max_length); - ProtoSize::add_string_field(total_size, 1, this->pattern); + ProtoSize::add_string_field(total_size, 1, this->pattern_ref_.size()); ProtoSize::add_enum_field(total_size, 1, static_cast(this->mode)); #ifdef USE_DEVICES ProtoSize::add_uint32_field(total_size, 1, this->device_id); @@ -2486,7 +2486,7 @@ void ListEntitiesTextResponse::calculate_size(uint32_t &total_size) const { } void TextStateResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_fixed32(1, this->key); - buffer.encode_string(2, this->state); + buffer.encode_string(2, this->state_ref_); buffer.encode_bool(3, this->missing_state); #ifdef USE_DEVICES buffer.encode_uint32(4, this->device_id); @@ -2494,7 +2494,7 @@ void TextStateResponse::encode(ProtoWriteBuffer buffer) const { } void TextStateResponse::calculate_size(uint32_t &total_size) const { ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->state); + ProtoSize::add_string_field(total_size, 1, this->state_ref_.size()); ProtoSize::add_bool_field(total_size, 1, this->missing_state); #ifdef USE_DEVICES ProtoSize::add_uint32_field(total_size, 1, this->device_id); @@ -2535,11 +2535,11 @@ bool TextCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { #endif #ifdef USE_DATETIME_DATE void ListEntitiesDateResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); #ifdef USE_ENTITY_ICON - buffer.encode_string(5, this->icon); + buffer.encode_string(5, this->icon_ref_); #endif buffer.encode_bool(6, this->disabled_by_default); buffer.encode_uint32(7, static_cast(this->entity_category)); @@ -2548,11 +2548,11 @@ void ListEntitiesDateResponse::encode(ProtoWriteBuffer buffer) const { #endif } void ListEntitiesDateResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); @@ -2614,11 +2614,11 @@ bool DateCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { #endif #ifdef USE_DATETIME_TIME void ListEntitiesTimeResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); #ifdef USE_ENTITY_ICON - buffer.encode_string(5, this->icon); + buffer.encode_string(5, this->icon_ref_); #endif buffer.encode_bool(6, this->disabled_by_default); buffer.encode_uint32(7, static_cast(this->entity_category)); @@ -2627,11 +2627,11 @@ void ListEntitiesTimeResponse::encode(ProtoWriteBuffer buffer) const { #endif } void ListEntitiesTimeResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); @@ -2693,15 +2693,15 @@ bool TimeCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { #endif #ifdef USE_EVENT void ListEntitiesEventResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); #ifdef USE_ENTITY_ICON - buffer.encode_string(5, this->icon); + buffer.encode_string(5, this->icon_ref_); #endif buffer.encode_bool(6, this->disabled_by_default); buffer.encode_uint32(7, static_cast(this->entity_category)); - buffer.encode_string(8, this->device_class); + buffer.encode_string(8, this->device_class_ref_); for (auto &it : this->event_types) { buffer.encode_string(9, it, true); } @@ -2710,15 +2710,15 @@ void ListEntitiesEventResponse::encode(ProtoWriteBuffer buffer) const { #endif } void ListEntitiesEventResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); - ProtoSize::add_string_field(total_size, 1, this->device_class); + ProtoSize::add_string_field(total_size, 1, this->device_class_ref_.size()); if (!this->event_types.empty()) { for (const auto &it : this->event_types) { ProtoSize::add_string_field_repeated(total_size, 1, it); @@ -2730,14 +2730,14 @@ void ListEntitiesEventResponse::calculate_size(uint32_t &total_size) const { } void EventResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_fixed32(1, this->key); - buffer.encode_string(2, this->event_type); + buffer.encode_string(2, this->event_type_ref_); #ifdef USE_DEVICES buffer.encode_uint32(3, this->device_id); #endif } void EventResponse::calculate_size(uint32_t &total_size) const { ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->event_type); + ProtoSize::add_string_field(total_size, 1, this->event_type_ref_.size()); #ifdef USE_DEVICES ProtoSize::add_uint32_field(total_size, 1, this->device_id); #endif @@ -2745,15 +2745,15 @@ void EventResponse::calculate_size(uint32_t &total_size) const { #endif #ifdef USE_VALVE void ListEntitiesValveResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); #ifdef USE_ENTITY_ICON - buffer.encode_string(5, this->icon); + buffer.encode_string(5, this->icon_ref_); #endif buffer.encode_bool(6, this->disabled_by_default); buffer.encode_uint32(7, static_cast(this->entity_category)); - buffer.encode_string(8, this->device_class); + buffer.encode_string(8, this->device_class_ref_); buffer.encode_bool(9, this->assumed_state); buffer.encode_bool(10, this->supports_position); buffer.encode_bool(11, this->supports_stop); @@ -2762,15 +2762,15 @@ void ListEntitiesValveResponse::encode(ProtoWriteBuffer buffer) const { #endif } void ListEntitiesValveResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); - ProtoSize::add_string_field(total_size, 1, this->device_class); + ProtoSize::add_string_field(total_size, 1, this->device_class_ref_.size()); ProtoSize::add_bool_field(total_size, 1, this->assumed_state); ProtoSize::add_bool_field(total_size, 1, this->supports_position); ProtoSize::add_bool_field(total_size, 1, this->supports_stop); @@ -2828,11 +2828,11 @@ bool ValveCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { #endif #ifdef USE_DATETIME_DATETIME void ListEntitiesDateTimeResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); #ifdef USE_ENTITY_ICON - buffer.encode_string(5, this->icon); + buffer.encode_string(5, this->icon_ref_); #endif buffer.encode_bool(6, this->disabled_by_default); buffer.encode_uint32(7, static_cast(this->entity_category)); @@ -2841,11 +2841,11 @@ void ListEntitiesDateTimeResponse::encode(ProtoWriteBuffer buffer) const { #endif } void ListEntitiesDateTimeResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); @@ -2897,29 +2897,29 @@ bool DateTimeCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) { #endif #ifdef USE_UPDATE void ListEntitiesUpdateResponse::encode(ProtoWriteBuffer buffer) const { - buffer.encode_string(1, this->object_id); + buffer.encode_string(1, this->object_id_ref_); buffer.encode_fixed32(2, this->key); - buffer.encode_string(3, this->name); + buffer.encode_string(3, this->name_ref_); #ifdef USE_ENTITY_ICON - buffer.encode_string(5, this->icon); + buffer.encode_string(5, this->icon_ref_); #endif buffer.encode_bool(6, this->disabled_by_default); buffer.encode_uint32(7, static_cast(this->entity_category)); - buffer.encode_string(8, this->device_class); + buffer.encode_string(8, this->device_class_ref_); #ifdef USE_DEVICES buffer.encode_uint32(9, this->device_id); #endif } void ListEntitiesUpdateResponse::calculate_size(uint32_t &total_size) const { - ProtoSize::add_string_field(total_size, 1, this->object_id); + ProtoSize::add_string_field(total_size, 1, this->object_id_ref_.size()); ProtoSize::add_fixed32_field(total_size, 1, this->key); - ProtoSize::add_string_field(total_size, 1, this->name); + ProtoSize::add_string_field(total_size, 1, this->name_ref_.size()); #ifdef USE_ENTITY_ICON - ProtoSize::add_string_field(total_size, 1, this->icon); + ProtoSize::add_string_field(total_size, 1, this->icon_ref_.size()); #endif ProtoSize::add_bool_field(total_size, 1, this->disabled_by_default); ProtoSize::add_enum_field(total_size, 1, static_cast(this->entity_category)); - ProtoSize::add_string_field(total_size, 1, this->device_class); + ProtoSize::add_string_field(total_size, 1, this->device_class_ref_.size()); #ifdef USE_DEVICES ProtoSize::add_uint32_field(total_size, 1, this->device_id); #endif @@ -2930,11 +2930,11 @@ void UpdateStateResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_bool(3, this->in_progress); buffer.encode_bool(4, this->has_progress); buffer.encode_float(5, this->progress); - buffer.encode_string(6, this->current_version); - buffer.encode_string(7, this->latest_version); - buffer.encode_string(8, this->title); - buffer.encode_string(9, this->release_summary); - buffer.encode_string(10, this->release_url); + buffer.encode_string(6, this->current_version_ref_); + buffer.encode_string(7, this->latest_version_ref_); + buffer.encode_string(8, this->title_ref_); + buffer.encode_string(9, this->release_summary_ref_); + buffer.encode_string(10, this->release_url_ref_); #ifdef USE_DEVICES buffer.encode_uint32(11, this->device_id); #endif @@ -2945,11 +2945,11 @@ void UpdateStateResponse::calculate_size(uint32_t &total_size) const { ProtoSize::add_bool_field(total_size, 1, this->in_progress); ProtoSize::add_bool_field(total_size, 1, this->has_progress); ProtoSize::add_float_field(total_size, 1, this->progress); - ProtoSize::add_string_field(total_size, 1, this->current_version); - ProtoSize::add_string_field(total_size, 1, this->latest_version); - ProtoSize::add_string_field(total_size, 1, this->title); - ProtoSize::add_string_field(total_size, 1, this->release_summary); - ProtoSize::add_string_field(total_size, 1, this->release_url); + ProtoSize::add_string_field(total_size, 1, this->current_version_ref_.size()); + ProtoSize::add_string_field(total_size, 1, this->latest_version_ref_.size()); + ProtoSize::add_string_field(total_size, 1, this->title_ref_.size()); + ProtoSize::add_string_field(total_size, 1, this->release_summary_ref_.size()); + ProtoSize::add_string_field(total_size, 1, this->release_url_ref_.size()); #ifdef USE_DEVICES ProtoSize::add_uint32_field(total_size, 1, this->device_id); #endif diff --git a/esphome/components/api/api_pb2.h b/esphome/components/api/api_pb2.h index 1d052f6114..9bf50fd18b 100644 --- a/esphome/components/api/api_pb2.h +++ b/esphome/components/api/api_pb2.h @@ -3,6 +3,7 @@ #pragma once #include "esphome/core/defines.h" +#include "esphome/core/string_ref.h" #include "proto.h" @@ -269,12 +270,15 @@ enum UpdateCommand : uint32_t { class InfoResponseProtoMessage : public ProtoMessage { public: ~InfoResponseProtoMessage() override = default; - std::string object_id{}; + StringRef object_id_ref_{}; + void set_object_id(const StringRef &ref) { this->object_id_ref_ = ref; } uint32_t key{0}; - std::string name{}; + StringRef name_ref_{}; + void set_name(const StringRef &ref) { this->name_ref_ = ref; } bool disabled_by_default{false}; #ifdef USE_ENTITY_ICON - std::string icon{}; + StringRef icon_ref_{}; + void set_icon(const StringRef &ref) { this->icon_ref_ = ref; } #endif enums::EntityCategory entity_category{}; #ifdef USE_DEVICES @@ -332,8 +336,10 @@ class HelloResponse : public ProtoMessage { #endif uint32_t api_version_major{0}; uint32_t api_version_minor{0}; - std::string server_info{}; - std::string name{}; + StringRef server_info_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 encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -442,7 +448,8 @@ class DeviceInfoRequest : public ProtoDecodableMessage { class AreaInfo : public ProtoMessage { public: uint32_t area_id{0}; - std::string name{}; + StringRef name_ref_{}; + void set_name(const StringRef &ref) { this->name_ref_ = ref; } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -456,7 +463,8 @@ class AreaInfo : public ProtoMessage { class DeviceInfo : public ProtoMessage { public: uint32_t device_id{0}; - std::string name{}; + StringRef name_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(uint32_t &total_size) const override; @@ -477,19 +485,26 @@ class DeviceInfoResponse : public ProtoMessage { #ifdef USE_API_PASSWORD bool uses_password{false}; #endif - std::string name{}; - std::string mac_address{}; - std::string esphome_version{}; - std::string compilation_time{}; - std::string model{}; + StringRef name_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; } + StringRef esphome_version_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; } + StringRef model_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 - std::string project_name{}; + StringRef project_name_ref_{}; + void set_project_name(const StringRef &ref) { this->project_name_ref_ = ref; } #endif #ifdef ESPHOME_PROJECT_NAME - std::string project_version{}; + StringRef project_version_ref_{}; + void set_project_version(const StringRef &ref) { this->project_version_ref_ = ref; } #endif #ifdef USE_WEBSERVER uint32_t webserver_port{0}; @@ -497,16 +512,20 @@ class DeviceInfoResponse : public ProtoMessage { #ifdef USE_BLUETOOTH_PROXY uint32_t bluetooth_proxy_feature_flags{0}; #endif - std::string manufacturer{}; - std::string friendly_name{}; + StringRef manufacturer_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; } #ifdef USE_VOICE_ASSISTANT uint32_t voice_assistant_feature_flags{0}; #endif #ifdef USE_AREAS - std::string suggested_area{}; + StringRef suggested_area_ref_{}; + void set_suggested_area(const StringRef &ref) { this->suggested_area_ref_ = ref; } #endif #ifdef USE_BLUETOOTH_PROXY - std::string bluetooth_mac_address{}; + StringRef bluetooth_mac_address_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}; @@ -575,7 +594,8 @@ class ListEntitiesBinarySensorResponse : public InfoResponseProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "list_entities_binary_sensor_response"; } #endif - std::string device_class{}; + StringRef device_class_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(uint32_t &total_size) const override; @@ -614,7 +634,8 @@ class ListEntitiesCoverResponse : public InfoResponseProtoMessage { bool assumed_state{false}; bool supports_position{false}; bool supports_tilt{false}; - std::string device_class{}; + StringRef device_class_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(uint32_t &total_size) const override; @@ -695,7 +716,8 @@ class FanStateResponse : public StateResponseProtoMessage { bool oscillating{false}; enums::FanDirection direction{}; int32_t speed_level{0}; - std::string preset_mode{}; + StringRef preset_mode_ref_{}; + void set_preset_mode(const StringRef &ref) { this->preset_mode_ref_ = ref; } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -769,7 +791,8 @@ class LightStateResponse : public StateResponseProtoMessage { float color_temperature{0.0f}; float cold_white{0.0f}; float warm_white{0.0f}; - std::string effect{}; + StringRef effect_ref_{}; + void set_effect(const StringRef &ref) { this->effect_ref_ = ref; } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -829,10 +852,12 @@ class ListEntitiesSensorResponse : public InfoResponseProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "list_entities_sensor_response"; } #endif - std::string unit_of_measurement{}; + StringRef unit_of_measurement_ref_{}; + void set_unit_of_measurement(const StringRef &ref) { this->unit_of_measurement_ref_ = ref; } int32_t accuracy_decimals{0}; bool force_update{false}; - std::string device_class{}; + StringRef device_class_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(uint32_t &total_size) const override; @@ -869,7 +894,8 @@ class ListEntitiesSwitchResponse : public InfoResponseProtoMessage { const char *message_name() const override { return "list_entities_switch_response"; } #endif bool assumed_state{false}; - std::string device_class{}; + StringRef device_class_ref_{}; + void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -919,7 +945,8 @@ class ListEntitiesTextSensorResponse : public InfoResponseProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "list_entities_text_sensor_response"; } #endif - std::string device_class{}; + StringRef device_class_ref_{}; + void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -935,7 +962,8 @@ class TextSensorStateResponse : public StateResponseProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "text_sensor_state_response"; } #endif - std::string state{}; + StringRef state_ref_{}; + void set_state(const StringRef &ref) { this->state_ref_ = ref; } bool missing_state{false}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; @@ -1032,8 +1060,10 @@ class SubscribeHomeassistantServicesRequest : public ProtoDecodableMessage { }; class HomeassistantServiceMap : public ProtoMessage { public: - std::string key{}; - std::string value{}; + StringRef key_ref_{}; + void set_key(const StringRef &ref) { this->key_ref_ = ref; } + StringRef value_ref_{}; + void set_value(const StringRef &ref) { this->value_ref_ = ref; } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -1049,7 +1079,8 @@ class HomeassistantServiceResponse : public ProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "homeassistant_service_response"; } #endif - std::string service{}; + StringRef service_ref_{}; + void set_service(const StringRef &ref) { this->service_ref_ = ref; } std::vector data{}; std::vector data_template{}; std::vector variables{}; @@ -1082,8 +1113,10 @@ class SubscribeHomeAssistantStateResponse : public ProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "subscribe_home_assistant_state_response"; } #endif - std::string entity_id{}; - std::string attribute{}; + StringRef entity_id_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; } bool once{false}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; @@ -1143,7 +1176,8 @@ class GetTimeResponse : public ProtoDecodableMessage { #ifdef USE_API_SERVICES class ListEntitiesServicesArgument : public ProtoMessage { public: - std::string name{}; + StringRef name_ref_{}; + void set_name(const StringRef &ref) { this->name_ref_ = ref; } enums::ServiceArgType type{}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; @@ -1160,7 +1194,8 @@ class ListEntitiesServicesResponse : public ProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "list_entities_services_response"; } #endif - std::string name{}; + StringRef name_ref_{}; + void set_name(const StringRef &ref) { this->name_ref_ = ref; } uint32_t key{0}; std::vector args{}; void encode(ProtoWriteBuffer buffer) const override; @@ -1312,9 +1347,11 @@ class ClimateStateResponse : public StateResponseProtoMessage { enums::ClimateAction action{}; enums::ClimateFanMode fan_mode{}; enums::ClimateSwingMode swing_mode{}; - std::string custom_fan_mode{}; + StringRef custom_fan_mode_ref_{}; + void set_custom_fan_mode(const StringRef &ref) { this->custom_fan_mode_ref_ = ref; } enums::ClimatePreset preset{}; - std::string custom_preset{}; + StringRef custom_preset_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; @@ -1373,9 +1410,11 @@ class ListEntitiesNumberResponse : public InfoResponseProtoMessage { float min_value{0.0f}; float max_value{0.0f}; float step{0.0f}; - std::string unit_of_measurement{}; + StringRef unit_of_measurement_ref_{}; + void set_unit_of_measurement(const StringRef &ref) { this->unit_of_measurement_ref_ = ref; } enums::NumberMode mode{}; - std::string device_class{}; + StringRef device_class_ref_{}; + void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -1442,7 +1481,8 @@ class SelectStateResponse : public StateResponseProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "select_state_response"; } #endif - std::string state{}; + StringRef state_ref_{}; + void set_state(const StringRef &ref) { this->state_ref_ = ref; } bool missing_state{false}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; @@ -1541,7 +1581,8 @@ class ListEntitiesLockResponse : public InfoResponseProtoMessage { bool assumed_state{false}; bool supports_open{false}; bool requires_code{false}; - std::string code_format{}; + StringRef code_format_ref_{}; + void set_code_format(const StringRef &ref) { this->code_format_ref_ = ref; } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -1594,7 +1635,8 @@ class ListEntitiesButtonResponse : public InfoResponseProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "list_entities_button_response"; } #endif - std::string device_class{}; + StringRef device_class_ref_{}; + void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -1622,7 +1664,8 @@ class ButtonCommandRequest : public CommandProtoMessage { #ifdef USE_MEDIA_PLAYER class MediaPlayerSupportedFormat : public ProtoMessage { public: - std::string format{}; + StringRef format_ref_{}; + void set_format(const StringRef &ref) { this->format_ref_ = ref; } uint32_t sample_rate{0}; uint32_t num_channels{0}; enums::MediaPlayerFormatPurpose purpose{}; @@ -2219,10 +2262,12 @@ class VoiceAssistantRequest : public ProtoMessage { const char *message_name() const override { return "voice_assistant_request"; } #endif bool start{false}; - std::string conversation_id{}; + StringRef conversation_id_ref_{}; + void set_conversation_id(const StringRef &ref) { this->conversation_id_ref_ = ref; } uint32_t flags{0}; VoiceAssistantAudioSettings audio_settings{}; - std::string wake_word_phrase{}; + StringRef wake_word_phrase_ref_{}; + void set_wake_word_phrase(const StringRef &ref) { this->wake_word_phrase_ref_ = ref; } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -2358,8 +2403,10 @@ class VoiceAssistantAnnounceFinished : public ProtoMessage { }; class VoiceAssistantWakeWord : public ProtoMessage { public: - std::string id{}; - std::string wake_word{}; + StringRef id_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; } std::vector trained_languages{}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; @@ -2480,7 +2527,8 @@ class ListEntitiesTextResponse : public InfoResponseProtoMessage { #endif uint32_t min_length{0}; uint32_t max_length{0}; - std::string pattern{}; + StringRef pattern_ref_{}; + void set_pattern(const StringRef &ref) { this->pattern_ref_ = ref; } enums::TextMode mode{}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; @@ -2497,7 +2545,8 @@ class TextStateResponse : public StateResponseProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "text_state_response"; } #endif - std::string state{}; + StringRef state_ref_{}; + void set_state(const StringRef &ref) { this->state_ref_ = ref; } bool missing_state{false}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; @@ -2641,7 +2690,8 @@ class ListEntitiesEventResponse : public InfoResponseProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "list_entities_event_response"; } #endif - std::string device_class{}; + StringRef device_class_ref_{}; + void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; } std::vector event_types{}; void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; @@ -2658,7 +2708,8 @@ class EventResponse : public StateResponseProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "event_response"; } #endif - std::string event_type{}; + StringRef event_type_ref_{}; + void set_event_type(const StringRef &ref) { this->event_type_ref_ = ref; } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -2676,7 +2727,8 @@ class ListEntitiesValveResponse : public InfoResponseProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "list_entities_valve_response"; } #endif - std::string device_class{}; + StringRef device_class_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}; @@ -2782,7 +2834,8 @@ class ListEntitiesUpdateResponse : public InfoResponseProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const char *message_name() const override { return "list_entities_update_response"; } #endif - std::string device_class{}; + StringRef device_class_ref_{}; + void set_device_class(const StringRef &ref) { this->device_class_ref_ = ref; } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP @@ -2802,11 +2855,16 @@ class UpdateStateResponse : public StateResponseProtoMessage { bool in_progress{false}; bool has_progress{false}; float progress{0.0f}; - std::string current_version{}; - std::string latest_version{}; - std::string title{}; - std::string release_summary{}; - std::string release_url{}; + StringRef current_version_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; } + StringRef title_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; } + StringRef release_url_ref_{}; + void set_release_url(const StringRef &ref) { this->release_url_ref_ = ref; } void encode(ProtoWriteBuffer buffer) const override; void calculate_size(uint32_t &total_size) const override; #ifdef HAS_PROTO_MESSAGE_DUMP diff --git a/esphome/components/api/api_pb2_dump.cpp b/esphome/components/api/api_pb2_dump.cpp index 03852bd365..4e44bff11e 100644 --- a/esphome/components/api/api_pb2_dump.cpp +++ b/esphome/components/api/api_pb2_dump.cpp @@ -10,6 +10,15 @@ namespace esphome { namespace api { +// Helper function to append a quoted string, handling empty StringRef +static inline void append_quoted_string(std::string &out, const StringRef &ref) { + out.append("'"); + if (!ref.empty()) { + out.append(ref.c_str()); + } + out.append("'"); +} + template<> const char *proto_enum_to_string(enums::EntityCategory value) { switch (value) { case enums::ENTITY_CATEGORY_NONE: @@ -580,11 +589,11 @@ void HelloResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" server_info: "); - out.append("'").append(this->server_info).append("'"); + append_quoted_string(out, this->server_info_ref_); out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); out.append("}"); } @@ -619,7 +628,7 @@ void AreaInfo::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); out.append("}"); } @@ -634,7 +643,7 @@ void DeviceInfo::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); out.append(" area_id: "); @@ -654,23 +663,23 @@ void DeviceInfoResponse::dump_to(std::string &out) const { #endif out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); out.append(" mac_address: "); - out.append("'").append(this->mac_address).append("'"); + append_quoted_string(out, this->mac_address_ref_); out.append("\n"); out.append(" esphome_version: "); - out.append("'").append(this->esphome_version).append("'"); + append_quoted_string(out, this->esphome_version_ref_); out.append("\n"); out.append(" compilation_time: "); - out.append("'").append(this->compilation_time).append("'"); + append_quoted_string(out, this->compilation_time_ref_); out.append("\n"); out.append(" model: "); - out.append("'").append(this->model).append("'"); + append_quoted_string(out, this->model_ref_); out.append("\n"); #ifdef USE_DEEP_SLEEP @@ -681,13 +690,13 @@ void DeviceInfoResponse::dump_to(std::string &out) const { #endif #ifdef ESPHOME_PROJECT_NAME out.append(" project_name: "); - out.append("'").append(this->project_name).append("'"); + append_quoted_string(out, this->project_name_ref_); out.append("\n"); #endif #ifdef ESPHOME_PROJECT_NAME out.append(" project_version: "); - out.append("'").append(this->project_version).append("'"); + append_quoted_string(out, this->project_version_ref_); out.append("\n"); #endif @@ -706,11 +715,11 @@ void DeviceInfoResponse::dump_to(std::string &out) const { #endif out.append(" manufacturer: "); - out.append("'").append(this->manufacturer).append("'"); + append_quoted_string(out, this->manufacturer_ref_); out.append("\n"); out.append(" friendly_name: "); - out.append("'").append(this->friendly_name).append("'"); + append_quoted_string(out, this->friendly_name_ref_); out.append("\n"); #ifdef USE_VOICE_ASSISTANT @@ -722,13 +731,13 @@ void DeviceInfoResponse::dump_to(std::string &out) const { #endif #ifdef USE_AREAS out.append(" suggested_area: "); - out.append("'").append(this->suggested_area).append("'"); + append_quoted_string(out, this->suggested_area_ref_); out.append("\n"); #endif #ifdef USE_BLUETOOTH_PROXY out.append(" bluetooth_mac_address: "); - out.append("'").append(this->bluetooth_mac_address).append("'"); + append_quoted_string(out, this->bluetooth_mac_address_ref_); out.append("\n"); #endif @@ -770,7 +779,7 @@ void ListEntitiesBinarySensorResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesBinarySensorResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -779,11 +788,11 @@ void ListEntitiesBinarySensorResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); out.append(" device_class: "); - out.append("'").append(this->device_class).append("'"); + append_quoted_string(out, this->device_class_ref_); out.append("\n"); out.append(" is_status_binary_sensor: "); @@ -796,7 +805,7 @@ void ListEntitiesBinarySensorResponse::dump_to(std::string &out) const { #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -844,7 +853,7 @@ void ListEntitiesCoverResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesCoverResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -853,7 +862,7 @@ void ListEntitiesCoverResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); out.append(" assumed_state: "); @@ -869,7 +878,7 @@ void ListEntitiesCoverResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" device_class: "); - out.append("'").append(this->device_class).append("'"); + append_quoted_string(out, this->device_class_ref_); out.append("\n"); out.append(" disabled_by_default: "); @@ -878,7 +887,7 @@ void ListEntitiesCoverResponse::dump_to(std::string &out) const { #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -975,7 +984,7 @@ void ListEntitiesFanResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesFanResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -984,7 +993,7 @@ void ListEntitiesFanResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); out.append(" supports_oscillation: "); @@ -1010,7 +1019,7 @@ void ListEntitiesFanResponse::dump_to(std::string &out) const { #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -1020,7 +1029,7 @@ void ListEntitiesFanResponse::dump_to(std::string &out) const { for (const auto &it : this->supported_preset_modes) { out.append(" supported_preset_modes: "); - out.append("'").append(it).append("'"); + append_quoted_string(out, StringRef(it)); out.append("\n"); } @@ -1059,7 +1068,7 @@ void FanStateResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" preset_mode: "); - out.append("'").append(this->preset_mode).append("'"); + append_quoted_string(out, this->preset_mode_ref_); out.append("\n"); #ifdef USE_DEVICES @@ -1135,7 +1144,7 @@ void ListEntitiesLightResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesLightResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -1144,7 +1153,7 @@ void ListEntitiesLightResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); for (const auto &it : this->supported_color_modes) { @@ -1165,7 +1174,7 @@ void ListEntitiesLightResponse::dump_to(std::string &out) const { for (const auto &it : this->effects) { out.append(" effects: "); - out.append("'").append(it).append("'"); + append_quoted_string(out, StringRef(it)); out.append("\n"); } @@ -1175,7 +1184,7 @@ void ListEntitiesLightResponse::dump_to(std::string &out) const { #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -1254,7 +1263,7 @@ void LightStateResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" effect: "); - out.append("'").append(this->effect).append("'"); + append_quoted_string(out, this->effect_ref_); out.append("\n"); #ifdef USE_DEVICES @@ -1404,7 +1413,7 @@ void ListEntitiesSensorResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesSensorResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -1413,17 +1422,17 @@ void ListEntitiesSensorResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif out.append(" unit_of_measurement: "); - out.append("'").append(this->unit_of_measurement).append("'"); + append_quoted_string(out, this->unit_of_measurement_ref_); out.append("\n"); out.append(" accuracy_decimals: "); @@ -1436,7 +1445,7 @@ void ListEntitiesSensorResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" device_class: "); - out.append("'").append(this->device_class).append("'"); + append_quoted_string(out, this->device_class_ref_); out.append("\n"); out.append(" state_class: "); @@ -1492,7 +1501,7 @@ void ListEntitiesSwitchResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesSwitchResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -1501,12 +1510,12 @@ void ListEntitiesSwitchResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -1523,7 +1532,7 @@ void ListEntitiesSwitchResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" device_class: "); - out.append("'").append(this->device_class).append("'"); + append_quoted_string(out, this->device_class_ref_); out.append("\n"); #ifdef USE_DEVICES @@ -1583,7 +1592,7 @@ void ListEntitiesTextSensorResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesTextSensorResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -1592,12 +1601,12 @@ void ListEntitiesTextSensorResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -1610,7 +1619,7 @@ void ListEntitiesTextSensorResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" device_class: "); - out.append("'").append(this->device_class).append("'"); + append_quoted_string(out, this->device_class_ref_); out.append("\n"); #ifdef USE_DEVICES @@ -1631,7 +1640,7 @@ void TextSensorStateResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" state: "); - out.append("'").append(this->state).append("'"); + append_quoted_string(out, this->state_ref_); out.append("\n"); out.append(" missing_state: "); @@ -1697,11 +1706,11 @@ void HomeassistantServiceMap::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("HomeassistantServiceMap {\n"); out.append(" key: "); - out.append("'").append(this->key).append("'"); + append_quoted_string(out, this->key_ref_); out.append("\n"); out.append(" value: "); - out.append("'").append(this->value).append("'"); + append_quoted_string(out, this->value_ref_); out.append("\n"); out.append("}"); } @@ -1709,7 +1718,7 @@ void HomeassistantServiceResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("HomeassistantServiceResponse {\n"); out.append(" service: "); - out.append("'").append(this->service).append("'"); + append_quoted_string(out, this->service_ref_); out.append("\n"); for (const auto &it : this->data) { @@ -1742,11 +1751,11 @@ void SubscribeHomeAssistantStateResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("SubscribeHomeAssistantStateResponse {\n"); out.append(" entity_id: "); - out.append("'").append(this->entity_id).append("'"); + append_quoted_string(out, this->entity_id_ref_); out.append("\n"); out.append(" attribute: "); - out.append("'").append(this->attribute).append("'"); + append_quoted_string(out, this->attribute_ref_); out.append("\n"); out.append(" once: "); @@ -1785,7 +1794,7 @@ void ListEntitiesServicesArgument::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesServicesArgument {\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); out.append(" type: "); @@ -1797,7 +1806,7 @@ void ListEntitiesServicesResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesServicesResponse {\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); out.append(" key: "); @@ -1860,7 +1869,7 @@ void ExecuteServiceArgument::dump_to(std::string &out) const { for (const auto &it : this->string_array) { out.append(" string_array: "); - out.append("'").append(it).append("'"); + append_quoted_string(out, StringRef(it)); out.append("\n"); } out.append("}"); @@ -1886,7 +1895,7 @@ void ListEntitiesCameraResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesCameraResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -1895,7 +1904,7 @@ void ListEntitiesCameraResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); out.append(" disabled_by_default: "); @@ -1904,7 +1913,7 @@ void ListEntitiesCameraResponse::dump_to(std::string &out) const { #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -1964,7 +1973,7 @@ void ListEntitiesClimateResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesClimateResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -1973,7 +1982,7 @@ void ListEntitiesClimateResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); out.append(" supports_current_temperature: "); @@ -2023,7 +2032,7 @@ void ListEntitiesClimateResponse::dump_to(std::string &out) const { for (const auto &it : this->supported_custom_fan_modes) { out.append(" supported_custom_fan_modes: "); - out.append("'").append(it).append("'"); + append_quoted_string(out, StringRef(it)); out.append("\n"); } @@ -2035,7 +2044,7 @@ void ListEntitiesClimateResponse::dump_to(std::string &out) const { for (const auto &it : this->supported_custom_presets) { out.append(" supported_custom_presets: "); - out.append("'").append(it).append("'"); + append_quoted_string(out, StringRef(it)); out.append("\n"); } @@ -2045,7 +2054,7 @@ void ListEntitiesClimateResponse::dump_to(std::string &out) const { #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -2130,7 +2139,7 @@ void ClimateStateResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" custom_fan_mode: "); - out.append("'").append(this->custom_fan_mode).append("'"); + append_quoted_string(out, this->custom_fan_mode_ref_); out.append("\n"); out.append(" preset: "); @@ -2138,7 +2147,7 @@ void ClimateStateResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" custom_preset: "); - out.append("'").append(this->custom_preset).append("'"); + append_quoted_string(out, this->custom_preset_ref_); out.append("\n"); out.append(" current_humidity: "); @@ -2267,7 +2276,7 @@ void ListEntitiesNumberResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesNumberResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -2276,12 +2285,12 @@ void ListEntitiesNumberResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -2309,7 +2318,7 @@ void ListEntitiesNumberResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" unit_of_measurement: "); - out.append("'").append(this->unit_of_measurement).append("'"); + append_quoted_string(out, this->unit_of_measurement_ref_); out.append("\n"); out.append(" mode: "); @@ -2317,7 +2326,7 @@ void ListEntitiesNumberResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" device_class: "); - out.append("'").append(this->device_class).append("'"); + append_quoted_string(out, this->device_class_ref_); out.append("\n"); #ifdef USE_DEVICES @@ -2383,7 +2392,7 @@ void ListEntitiesSelectResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesSelectResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -2392,18 +2401,18 @@ void ListEntitiesSelectResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif for (const auto &it : this->options) { out.append(" options: "); - out.append("'").append(it).append("'"); + append_quoted_string(out, StringRef(it)); out.append("\n"); } @@ -2433,7 +2442,7 @@ void SelectStateResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" state: "); - out.append("'").append(this->state).append("'"); + append_quoted_string(out, this->state_ref_); out.append("\n"); out.append(" missing_state: "); @@ -2476,7 +2485,7 @@ void ListEntitiesSirenResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesSirenResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -2485,12 +2494,12 @@ void ListEntitiesSirenResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -2500,7 +2509,7 @@ void ListEntitiesSirenResponse::dump_to(std::string &out) const { for (const auto &it : this->tones) { out.append(" tones: "); - out.append("'").append(it).append("'"); + append_quoted_string(out, StringRef(it)); out.append("\n"); } @@ -2603,7 +2612,7 @@ void ListEntitiesLockResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesLockResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -2612,12 +2621,12 @@ void ListEntitiesLockResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -2642,7 +2651,7 @@ void ListEntitiesLockResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" code_format: "); - out.append("'").append(this->code_format).append("'"); + append_quoted_string(out, this->code_format_ref_); out.append("\n"); #ifdef USE_DEVICES @@ -2710,7 +2719,7 @@ void ListEntitiesButtonResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesButtonResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -2719,12 +2728,12 @@ void ListEntitiesButtonResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -2737,7 +2746,7 @@ void ListEntitiesButtonResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" device_class: "); - out.append("'").append(this->device_class).append("'"); + append_quoted_string(out, this->device_class_ref_); out.append("\n"); #ifdef USE_DEVICES @@ -2772,7 +2781,7 @@ void MediaPlayerSupportedFormat::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("MediaPlayerSupportedFormat {\n"); out.append(" format: "); - out.append("'").append(this->format).append("'"); + append_quoted_string(out, this->format_ref_); out.append("\n"); out.append(" sample_rate: "); @@ -2799,7 +2808,7 @@ void ListEntitiesMediaPlayerResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesMediaPlayerResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -2808,12 +2817,12 @@ void ListEntitiesMediaPlayerResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -3423,7 +3432,7 @@ void VoiceAssistantRequest::dump_to(std::string &out) const { out.append("\n"); out.append(" conversation_id: "); - out.append("'").append(this->conversation_id).append("'"); + append_quoted_string(out, this->conversation_id_ref_); out.append("\n"); out.append(" flags: "); @@ -3436,7 +3445,7 @@ void VoiceAssistantRequest::dump_to(std::string &out) const { out.append("\n"); out.append(" wake_word_phrase: "); - out.append("'").append(this->wake_word_phrase).append("'"); + append_quoted_string(out, this->wake_word_phrase_ref_); out.append("\n"); out.append("}"); } @@ -3557,16 +3566,16 @@ void VoiceAssistantWakeWord::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("VoiceAssistantWakeWord {\n"); out.append(" id: "); - out.append("'").append(this->id).append("'"); + append_quoted_string(out, this->id_ref_); out.append("\n"); out.append(" wake_word: "); - out.append("'").append(this->wake_word).append("'"); + append_quoted_string(out, this->wake_word_ref_); out.append("\n"); for (const auto &it : this->trained_languages) { out.append(" trained_languages: "); - out.append("'").append(it).append("'"); + append_quoted_string(out, StringRef(it)); out.append("\n"); } out.append("}"); @@ -3585,7 +3594,7 @@ void VoiceAssistantConfigurationResponse::dump_to(std::string &out) const { for (const auto &it : this->active_wake_words) { out.append(" active_wake_words: "); - out.append("'").append(it).append("'"); + append_quoted_string(out, StringRef(it)); out.append("\n"); } @@ -3600,7 +3609,7 @@ void VoiceAssistantSetConfiguration::dump_to(std::string &out) const { out.append("VoiceAssistantSetConfiguration {\n"); for (const auto &it : this->active_wake_words) { out.append(" active_wake_words: "); - out.append("'").append(it).append("'"); + append_quoted_string(out, StringRef(it)); out.append("\n"); } out.append("}"); @@ -3611,7 +3620,7 @@ void ListEntitiesAlarmControlPanelResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesAlarmControlPanelResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -3620,12 +3629,12 @@ void ListEntitiesAlarmControlPanelResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -3711,7 +3720,7 @@ void ListEntitiesTextResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesTextResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -3720,12 +3729,12 @@ void ListEntitiesTextResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -3748,7 +3757,7 @@ void ListEntitiesTextResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" pattern: "); - out.append("'").append(this->pattern).append("'"); + append_quoted_string(out, this->pattern_ref_); out.append("\n"); out.append(" mode: "); @@ -3773,7 +3782,7 @@ void TextStateResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" state: "); - out.append("'").append(this->state).append("'"); + append_quoted_string(out, this->state_ref_); out.append("\n"); out.append(" missing_state: "); @@ -3816,7 +3825,7 @@ void ListEntitiesDateResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesDateResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -3825,12 +3834,12 @@ void ListEntitiesDateResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -3925,7 +3934,7 @@ void ListEntitiesTimeResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesTimeResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -3934,12 +3943,12 @@ void ListEntitiesTimeResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -4034,7 +4043,7 @@ void ListEntitiesEventResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesEventResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -4043,12 +4052,12 @@ void ListEntitiesEventResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -4061,12 +4070,12 @@ void ListEntitiesEventResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" device_class: "); - out.append("'").append(this->device_class).append("'"); + append_quoted_string(out, this->device_class_ref_); out.append("\n"); for (const auto &it : this->event_types) { out.append(" event_types: "); - out.append("'").append(it).append("'"); + append_quoted_string(out, StringRef(it)); out.append("\n"); } @@ -4088,7 +4097,7 @@ void EventResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" event_type: "); - out.append("'").append(this->event_type).append("'"); + append_quoted_string(out, this->event_type_ref_); out.append("\n"); #ifdef USE_DEVICES @@ -4106,7 +4115,7 @@ void ListEntitiesValveResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesValveResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -4115,12 +4124,12 @@ void ListEntitiesValveResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -4133,7 +4142,7 @@ void ListEntitiesValveResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" device_class: "); - out.append("'").append(this->device_class).append("'"); + append_quoted_string(out, this->device_class_ref_); out.append("\n"); out.append(" assumed_state: "); @@ -4219,7 +4228,7 @@ void ListEntitiesDateTimeResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesDateTimeResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -4228,12 +4237,12 @@ void ListEntitiesDateTimeResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -4308,7 +4317,7 @@ void ListEntitiesUpdateResponse::dump_to(std::string &out) const { __attribute__((unused)) char buffer[64]; out.append("ListEntitiesUpdateResponse {\n"); out.append(" object_id: "); - out.append("'").append(this->object_id).append("'"); + append_quoted_string(out, this->object_id_ref_); out.append("\n"); out.append(" key: "); @@ -4317,12 +4326,12 @@ void ListEntitiesUpdateResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" name: "); - out.append("'").append(this->name).append("'"); + append_quoted_string(out, this->name_ref_); out.append("\n"); #ifdef USE_ENTITY_ICON out.append(" icon: "); - out.append("'").append(this->icon).append("'"); + append_quoted_string(out, this->icon_ref_); out.append("\n"); #endif @@ -4335,7 +4344,7 @@ void ListEntitiesUpdateResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" device_class: "); - out.append("'").append(this->device_class).append("'"); + append_quoted_string(out, this->device_class_ref_); out.append("\n"); #ifdef USE_DEVICES @@ -4373,23 +4382,23 @@ void UpdateStateResponse::dump_to(std::string &out) const { out.append("\n"); out.append(" current_version: "); - out.append("'").append(this->current_version).append("'"); + append_quoted_string(out, this->current_version_ref_); out.append("\n"); out.append(" latest_version: "); - out.append("'").append(this->latest_version).append("'"); + append_quoted_string(out, this->latest_version_ref_); out.append("\n"); out.append(" title: "); - out.append("'").append(this->title).append("'"); + append_quoted_string(out, this->title_ref_); out.append("\n"); out.append(" release_summary: "); - out.append("'").append(this->release_summary).append("'"); + append_quoted_string(out, this->release_summary_ref_); out.append("\n"); out.append(" release_url: "); - out.append("'").append(this->release_url).append("'"); + append_quoted_string(out, this->release_url_ref_); out.append("\n"); #ifdef USE_DEVICES diff --git a/esphome/components/api/api_pb2_service.cpp b/esphome/components/api/api_pb2_service.cpp index 888dc16836..498c396ae3 100644 --- a/esphome/components/api/api_pb2_service.cpp +++ b/esphome/components/api/api_pb2_service.cpp @@ -597,33 +597,28 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type, } void APIServerConnection::on_hello_request(const HelloRequest &msg) { - HelloResponse ret = this->hello(msg); - if (!this->send_message(ret, HelloResponse::MESSAGE_TYPE)) { + if (!this->send_hello_response(msg)) { this->on_fatal_error(); } } void APIServerConnection::on_connect_request(const ConnectRequest &msg) { - ConnectResponse ret = this->connect(msg); - if (!this->send_message(ret, ConnectResponse::MESSAGE_TYPE)) { + if (!this->send_connect_response(msg)) { this->on_fatal_error(); } } void APIServerConnection::on_disconnect_request(const DisconnectRequest &msg) { - DisconnectResponse ret = this->disconnect(msg); - if (!this->send_message(ret, DisconnectResponse::MESSAGE_TYPE)) { + if (!this->send_disconnect_response(msg)) { this->on_fatal_error(); } } void APIServerConnection::on_ping_request(const PingRequest &msg) { - PingResponse ret = this->ping(msg); - if (!this->send_message(ret, PingResponse::MESSAGE_TYPE)) { + if (!this->send_ping_response(msg)) { this->on_fatal_error(); } } void APIServerConnection::on_device_info_request(const DeviceInfoRequest &msg) { if (this->check_connection_setup_()) { - DeviceInfoResponse ret = this->device_info(msg); - if (!this->send_message(ret, DeviceInfoResponse::MESSAGE_TYPE)) { + if (!this->send_device_info_response(msg)) { this->on_fatal_error(); } } @@ -656,8 +651,7 @@ void APIServerConnection::on_subscribe_home_assistant_states_request(const Subsc } void APIServerConnection::on_get_time_request(const GetTimeRequest &msg) { if (this->check_connection_setup_()) { - GetTimeResponse ret = this->get_time(msg); - if (!this->send_message(ret, GetTimeResponse::MESSAGE_TYPE)) { + if (!this->send_get_time_response(msg)) { this->on_fatal_error(); } } @@ -672,8 +666,7 @@ void APIServerConnection::on_execute_service_request(const ExecuteServiceRequest #ifdef USE_API_NOISE void APIServerConnection::on_noise_encryption_set_key_request(const NoiseEncryptionSetKeyRequest &msg) { if (this->check_authenticated_()) { - NoiseEncryptionSetKeyResponse ret = this->noise_encryption_set_key(msg); - if (!this->send_message(ret, NoiseEncryptionSetKeyResponse::MESSAGE_TYPE)) { + if (!this->send_noise_encryption_set_key_response(msg)) { this->on_fatal_error(); } } @@ -866,8 +859,7 @@ void APIServerConnection::on_bluetooth_gatt_notify_request(const BluetoothGATTNo void APIServerConnection::on_subscribe_bluetooth_connections_free_request( const SubscribeBluetoothConnectionsFreeRequest &msg) { if (this->check_authenticated_()) { - BluetoothConnectionsFreeResponse ret = this->subscribe_bluetooth_connections_free(msg); - if (!this->send_message(ret, BluetoothConnectionsFreeResponse::MESSAGE_TYPE)) { + if (!this->send_subscribe_bluetooth_connections_free_response(msg)) { this->on_fatal_error(); } } @@ -898,8 +890,7 @@ void APIServerConnection::on_subscribe_voice_assistant_request(const SubscribeVo #ifdef USE_VOICE_ASSISTANT void APIServerConnection::on_voice_assistant_configuration_request(const VoiceAssistantConfigurationRequest &msg) { if (this->check_authenticated_()) { - VoiceAssistantConfigurationResponse ret = this->voice_assistant_get_configuration(msg); - if (!this->send_message(ret, VoiceAssistantConfigurationResponse::MESSAGE_TYPE)) { + if (!this->send_voice_assistant_get_configuration_response(msg)) { this->on_fatal_error(); } } diff --git a/esphome/components/api/api_pb2_service.h b/esphome/components/api/api_pb2_service.h index f7076a28ca..f06ebdf9d5 100644 --- a/esphome/components/api/api_pb2_service.h +++ b/esphome/components/api/api_pb2_service.h @@ -207,22 +207,22 @@ class APIServerConnectionBase : public ProtoService { class APIServerConnection : public APIServerConnectionBase { public: - virtual HelloResponse hello(const HelloRequest &msg) = 0; - virtual ConnectResponse connect(const ConnectRequest &msg) = 0; - virtual DisconnectResponse disconnect(const DisconnectRequest &msg) = 0; - virtual PingResponse ping(const PingRequest &msg) = 0; - virtual DeviceInfoResponse device_info(const DeviceInfoRequest &msg) = 0; + virtual bool send_hello_response(const HelloRequest &msg) = 0; + virtual bool send_connect_response(const ConnectRequest &msg) = 0; + virtual bool send_disconnect_response(const DisconnectRequest &msg) = 0; + virtual bool send_ping_response(const PingRequest &msg) = 0; + virtual bool send_device_info_response(const DeviceInfoRequest &msg) = 0; virtual void list_entities(const ListEntitiesRequest &msg) = 0; virtual void subscribe_states(const SubscribeStatesRequest &msg) = 0; virtual void subscribe_logs(const SubscribeLogsRequest &msg) = 0; virtual void subscribe_homeassistant_services(const SubscribeHomeassistantServicesRequest &msg) = 0; virtual void subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) = 0; - virtual GetTimeResponse get_time(const GetTimeRequest &msg) = 0; + virtual bool send_get_time_response(const GetTimeRequest &msg) = 0; #ifdef USE_API_SERVICES virtual void execute_service(const ExecuteServiceRequest &msg) = 0; #endif #ifdef USE_API_NOISE - virtual NoiseEncryptionSetKeyResponse noise_encryption_set_key(const NoiseEncryptionSetKeyRequest &msg) = 0; + virtual bool send_noise_encryption_set_key_response(const NoiseEncryptionSetKeyRequest &msg) = 0; #endif #ifdef USE_BUTTON virtual void button_command(const ButtonCommandRequest &msg) = 0; @@ -303,7 +303,7 @@ class APIServerConnection : public APIServerConnectionBase { virtual void bluetooth_gatt_notify(const BluetoothGATTNotifyRequest &msg) = 0; #endif #ifdef USE_BLUETOOTH_PROXY - virtual BluetoothConnectionsFreeResponse subscribe_bluetooth_connections_free( + virtual bool send_subscribe_bluetooth_connections_free_response( const SubscribeBluetoothConnectionsFreeRequest &msg) = 0; #endif #ifdef USE_BLUETOOTH_PROXY @@ -316,8 +316,7 @@ class APIServerConnection : public APIServerConnectionBase { virtual void subscribe_voice_assistant(const SubscribeVoiceAssistantRequest &msg) = 0; #endif #ifdef USE_VOICE_ASSISTANT - virtual VoiceAssistantConfigurationResponse voice_assistant_get_configuration( - const VoiceAssistantConfigurationRequest &msg) = 0; + virtual bool send_voice_assistant_get_configuration_response(const VoiceAssistantConfigurationRequest &msg) = 0; #endif #ifdef USE_VOICE_ASSISTANT virtual void voice_assistant_set_configuration(const VoiceAssistantSetConfiguration &msg) = 0; diff --git a/esphome/components/api/custom_api_device.h b/esphome/components/api/custom_api_device.h index 35329c4a5e..6375dbfb9f 100644 --- a/esphome/components/api/custom_api_device.h +++ b/esphome/components/api/custom_api_device.h @@ -148,7 +148,7 @@ class CustomAPIDevice { */ void call_homeassistant_service(const std::string &service_name) { HomeassistantServiceResponse resp; - resp.service = service_name; + resp.set_service(StringRef(service_name)); global_api_server->send_homeassistant_service_call(resp); } @@ -168,12 +168,12 @@ class CustomAPIDevice { */ void call_homeassistant_service(const std::string &service_name, const std::map &data) { HomeassistantServiceResponse resp; - resp.service = service_name; + resp.set_service(StringRef(service_name)); for (auto &it : data) { - HomeassistantServiceMap kv; - kv.key = it.first; - kv.value = it.second; - resp.data.push_back(kv); + resp.data.emplace_back(); + auto &kv = resp.data.back(); + kv.set_key(StringRef(it.first)); + kv.set_value(StringRef(it.second)); } global_api_server->send_homeassistant_service_call(resp); } @@ -190,7 +190,7 @@ class CustomAPIDevice { */ void fire_homeassistant_event(const std::string &event_name) { HomeassistantServiceResponse resp; - resp.service = event_name; + resp.set_service(StringRef(event_name)); resp.is_event = true; global_api_server->send_homeassistant_service_call(resp); } @@ -210,13 +210,13 @@ class CustomAPIDevice { */ void fire_homeassistant_event(const std::string &service_name, const std::map &data) { HomeassistantServiceResponse resp; - resp.service = service_name; + resp.set_service(StringRef(service_name)); resp.is_event = true; for (auto &it : data) { - HomeassistantServiceMap kv; - kv.key = it.first; - kv.value = it.second; - resp.data.push_back(kv); + resp.data.emplace_back(); + auto &kv = resp.data.back(); + kv.set_key(StringRef(it.first)); + kv.set_value(StringRef(it.second)); } global_api_server->send_homeassistant_service_call(resp); } diff --git a/esphome/components/api/homeassistant_service.h b/esphome/components/api/homeassistant_service.h index f765f1f806..4980c0224c 100644 --- a/esphome/components/api/homeassistant_service.h +++ b/esphome/components/api/homeassistant_service.h @@ -59,25 +59,29 @@ template class HomeAssistantServiceCallAction : public Actionservice_.value(x...); + std::string service_value = this->service_.value(x...); + resp.set_service(StringRef(service_value)); resp.is_event = this->is_event_; for (auto &it : this->data_) { - HomeassistantServiceMap kv; - kv.key = it.key; - kv.value = it.value.value(x...); - resp.data.push_back(kv); + resp.data.emplace_back(); + auto &kv = resp.data.back(); + kv.set_key(StringRef(it.key)); + std::string value = it.value.value(x...); + kv.set_value(StringRef(value)); } for (auto &it : this->data_template_) { - HomeassistantServiceMap kv; - kv.key = it.key; - kv.value = it.value.value(x...); - resp.data_template.push_back(kv); + resp.data_template.emplace_back(); + auto &kv = resp.data_template.back(); + kv.set_key(StringRef(it.key)); + std::string value = it.value.value(x...); + kv.set_value(StringRef(value)); } for (auto &it : this->variables_) { - HomeassistantServiceMap kv; - kv.key = it.key; - kv.value = it.value.value(x...); - resp.variables.push_back(kv); + resp.variables.emplace_back(); + auto &kv = resp.variables.back(); + kv.set_key(StringRef(it.key)); + std::string value = it.value.value(x...); + kv.set_value(StringRef(value)); } this->parent_->send_homeassistant_service_call(resp); } diff --git a/esphome/components/api/proto.h b/esphome/components/api/proto.h index 6ae4556cc1..3e59ee1541 100644 --- a/esphome/components/api/proto.h +++ b/esphome/components/api/proto.h @@ -3,6 +3,7 @@ #include "esphome/core/component.h" #include "esphome/core/helpers.h" #include "esphome/core/log.h" +#include "esphome/core/string_ref.h" #include #include @@ -15,6 +16,37 @@ namespace esphome { namespace api { +/* + * StringRef Ownership Model for API Protocol Messages + * =================================================== + * + * StringRef is used for zero-copy string handling in outgoing (SOURCE_SERVER) messages. + * It holds a pointer and length to existing string data without copying. + * + * CRITICAL: The referenced string data MUST remain valid until message encoding completes. + * + * Safe StringRef Patterns: + * 1. String literals: StringRef("literal") - Always safe (static storage duration) + * 2. Member variables: StringRef(this->member_string_) - Safe if object outlives encoding + * 3. Global/static strings: StringRef(GLOBAL_CONSTANT) - Always safe + * 4. Local variables: Safe ONLY if encoding happens before function returns: + * std::string temp = compute_value(); + * msg.set_field(StringRef(temp)); + * return this->send_message(msg); // temp is valid during encoding + * + * Unsafe Patterns (WILL cause crashes/corruption): + * 1. Temporaries: msg.set_field(StringRef(obj.get_string())) // get_string() returns by value + * 2. Optional values: msg.set_field(StringRef(optional.value())) // value() returns a copy + * 3. Concatenation: msg.set_field(StringRef(str1 + str2)) // Result is temporary + * + * For unsafe patterns, store in a local variable first: + * std::string temp = optional.value(); // or get_string() or str1 + str2 + * msg.set_field(StringRef(temp)); + * + * The send_*_response pattern ensures proper lifetime management by encoding + * within the same function scope where temporaries are created. + */ + /// Representation of a VarInt - in ProtoBuf should be 64bit but we only use 32bit class ProtoVarInt { public: @@ -218,6 +250,9 @@ class ProtoWriteBuffer { void encode_string(uint32_t field_id, const std::string &value, bool force = false) { this->encode_string(field_id, value.data(), value.size(), force); } + void encode_string(uint32_t field_id, const StringRef &ref, bool force = false) { + this->encode_string(field_id, ref.c_str(), ref.size(), force); + } void encode_bytes(uint32_t field_id, const uint8_t *data, size_t len, bool force = false) { this->encode_string(field_id, reinterpret_cast(data), len, force); } @@ -669,17 +704,16 @@ class ProtoSize { // sint64 type is not supported by ESPHome API to reduce overhead on embedded systems /** - * @brief Calculates and adds the size of a string/bytes field to the total message size + * @brief Calculates and adds the size of a string field using length */ - static inline void add_string_field(uint32_t &total_size, uint32_t field_id_size, const std::string &str) { + static inline void add_string_field(uint32_t &total_size, uint32_t field_id_size, size_t len) { // Skip calculation if string is empty - if (str.empty()) { + if (len == 0) { return; // No need to update total_size } - // Calculate and directly add to total_size - const uint32_t str_size = static_cast(str.size()); - total_size += field_id_size + varint(str_size) + str_size; + // Field ID + length varint + string bytes + total_size += field_id_size + varint(static_cast(len)) + static_cast(len); } /** diff --git a/esphome/components/api/user_services.h b/esphome/components/api/user_services.h index 1420a15ff9..deec636cae 100644 --- a/esphome/components/api/user_services.h +++ b/esphome/components/api/user_services.h @@ -33,14 +33,14 @@ template class UserServiceBase : public UserServiceDescriptor { ListEntitiesServicesResponse encode_list_service_response() override { ListEntitiesServicesResponse msg; - msg.name = this->name_; + msg.set_name(StringRef(this->name_)); msg.key = this->key_; std::array arg_types = {to_service_arg_type()...}; for (int i = 0; i < sizeof...(Ts); i++) { - ListEntitiesServicesArgument arg; + msg.args.emplace_back(); + auto &arg = msg.args.back(); arg.type = arg_types[i]; - arg.name = this->arg_names_[i]; - msg.args.push_back(arg); + arg.set_name(StringRef(this->arg_names_[i])); } return msg; } diff --git a/esphome/components/homeassistant/number/homeassistant_number.cpp b/esphome/components/homeassistant/number/homeassistant_number.cpp index a7f71c3244..ffb352c969 100644 --- a/esphome/components/homeassistant/number/homeassistant_number.cpp +++ b/esphome/components/homeassistant/number/homeassistant_number.cpp @@ -83,18 +83,24 @@ void HomeassistantNumber::control(float value) { this->publish_state(value); + static constexpr auto SERVICE_NAME = StringRef::from_lit("number.set_value"); + static constexpr auto ENTITY_ID_KEY = StringRef::from_lit("entity_id"); + static constexpr auto VALUE_KEY = StringRef::from_lit("value"); + api::HomeassistantServiceResponse resp; - resp.service = "number.set_value"; + resp.set_service(SERVICE_NAME); - api::HomeassistantServiceMap entity_id; - entity_id.key = "entity_id"; - entity_id.value = this->entity_id_; - resp.data.push_back(entity_id); + resp.data.emplace_back(); + auto &entity_id = resp.data.back(); + entity_id.set_key(ENTITY_ID_KEY); + entity_id.set_value(StringRef(this->entity_id_)); - api::HomeassistantServiceMap entity_value; - entity_value.key = "value"; - entity_value.value = to_string(value); - resp.data.push_back(entity_value); + resp.data.emplace_back(); + auto &entity_value = resp.data.back(); + entity_value.set_key(VALUE_KEY); + // to_string() returns a temporary - must store it to avoid dangling reference + std::string value_str = to_string(value); + entity_value.set_value(StringRef(value_str)); api::global_api_server->send_homeassistant_service_call(resp); } diff --git a/esphome/components/homeassistant/switch/homeassistant_switch.cpp b/esphome/components/homeassistant/switch/homeassistant_switch.cpp index 0451c95069..0fe609bf43 100644 --- a/esphome/components/homeassistant/switch/homeassistant_switch.cpp +++ b/esphome/components/homeassistant/switch/homeassistant_switch.cpp @@ -40,17 +40,21 @@ void HomeassistantSwitch::write_state(bool state) { return; } + static constexpr auto SERVICE_ON = StringRef::from_lit("homeassistant.turn_on"); + static constexpr auto SERVICE_OFF = StringRef::from_lit("homeassistant.turn_off"); + static constexpr auto ENTITY_ID_KEY = StringRef::from_lit("entity_id"); + api::HomeassistantServiceResponse resp; if (state) { - resp.service = "homeassistant.turn_on"; + resp.set_service(SERVICE_ON); } else { - resp.service = "homeassistant.turn_off"; + resp.set_service(SERVICE_OFF); } - api::HomeassistantServiceMap entity_id_kv; - entity_id_kv.key = "entity_id"; - entity_id_kv.value = this->entity_id_; - resp.data.push_back(entity_id_kv); + resp.data.emplace_back(); + auto &entity_id_kv = resp.data.back(); + entity_id_kv.set_key(ENTITY_ID_KEY); + entity_id_kv.set_value(StringRef(this->entity_id_)); api::global_api_server->send_homeassistant_service_call(resp); } diff --git a/esphome/components/text/text_traits.h b/esphome/components/text/text_traits.h index 952afa70c7..ceaba2dead 100644 --- a/esphome/components/text/text_traits.h +++ b/esphome/components/text/text_traits.h @@ -3,6 +3,7 @@ #include #include "esphome/core/helpers.h" +#include "esphome/core/string_ref.h" namespace esphome { namespace text { @@ -23,6 +24,7 @@ class TextTraits { // Set/get the pattern. void set_pattern(std::string pattern) { this->pattern_ = std::move(pattern); } std::string get_pattern() const { return this->pattern_; } + StringRef get_pattern_ref() const { return StringRef(this->pattern_); } // Set/get the frontend mode. void set_mode(TextMode mode) { this->mode_ = mode; } diff --git a/esphome/components/voice_assistant/voice_assistant.cpp b/esphome/components/voice_assistant/voice_assistant.cpp index 481a4efa62..743c90e700 100644 --- a/esphome/components/voice_assistant/voice_assistant.cpp +++ b/esphome/components/voice_assistant/voice_assistant.cpp @@ -238,10 +238,10 @@ void VoiceAssistant::loop() { api::VoiceAssistantRequest msg; msg.start = true; - msg.conversation_id = this->conversation_id_; + msg.set_conversation_id(StringRef(this->conversation_id_)); msg.flags = flags; msg.audio_settings = audio_settings; - msg.wake_word_phrase = this->wake_word_; + msg.set_wake_word_phrase(StringRef(this->wake_word_)); this->wake_word_ = ""; // Reset media player state tracking diff --git a/esphome/core/entity_base.h b/esphome/core/entity_base.h index 00b1264ed0..e60e0728bc 100644 --- a/esphome/core/entity_base.h +++ b/esphome/core/entity_base.h @@ -54,6 +54,14 @@ class EntityBase { // Get/set this entity's icon std::string get_icon() const; void set_icon(const char *icon); + StringRef get_icon_ref() const { + static constexpr auto EMPTY_STRING = StringRef::from_lit(""); +#ifdef USE_ENTITY_ICON + return this->icon_c_str_ == nullptr ? EMPTY_STRING : StringRef(this->icon_c_str_); +#else + return EMPTY_STRING; +#endif + } #ifdef USE_DEVICES // Get/set this entity's device id @@ -105,6 +113,11 @@ class EntityBase_DeviceClass { // NOLINT(readability-identifier-naming) std::string get_device_class(); /// Manually set the device class. void set_device_class(const char *device_class); + /// Get the device class as StringRef + StringRef get_device_class_ref() const { + static constexpr auto EMPTY_STRING = StringRef::from_lit(""); + return this->device_class_ == nullptr ? EMPTY_STRING : StringRef(this->device_class_); + } protected: const char *device_class_{nullptr}; ///< Device class override @@ -116,6 +129,11 @@ class EntityBase_UnitOfMeasurement { // NOLINT(readability-identifier-naming) std::string get_unit_of_measurement(); /// Manually set the unit of measurement. void set_unit_of_measurement(const char *unit_of_measurement); + /// Get the unit of measurement as StringRef + StringRef get_unit_of_measurement_ref() const { + static constexpr auto EMPTY_STRING = StringRef::from_lit(""); + return this->unit_of_measurement_ == nullptr ? EMPTY_STRING : StringRef(this->unit_of_measurement_); + } protected: const char *unit_of_measurement_{nullptr}; ///< Unit of measurement override diff --git a/script/api_protobuf/api_protobuf.py b/script/api_protobuf/api_protobuf.py index 2d49ac5ece..766a84c9fd 100755 --- a/script/api_protobuf/api_protobuf.py +++ b/script/api_protobuf/api_protobuf.py @@ -343,6 +343,10 @@ def create_field_type_info( if field.type == 12: return BytesType(field, needs_decode, needs_encode) + # Special handling for string fields + if field.type == 9: + return StringType(field, needs_decode, needs_encode) + validate_field_type(field.type, field.name) return TYPE_INFO[field.type](field) @@ -543,12 +547,67 @@ class StringType(TypeInfo): encode_func = "encode_string" wire_type = WireType.LENGTH_DELIMITED # Uses wire type 2 + @property + def public_content(self) -> list[str]: + content: list[str] = [] + # Add std::string storage if message needs decoding + if self._needs_decode: + content.append(f"std::string {self.field_name}{{}};") + + if self._needs_encode: + content.extend( + [ + # Add StringRef field if message needs encoding + f"StringRef {self.field_name}_ref_{{}};", + # Add setter method if message needs encoding + f"void set_{self.field_name}(const StringRef &ref) {{", + f" this->{self.field_name}_ref_ = ref;", + "}", + ] + ) + return content + + @property + def encode_content(self) -> str: + return f"buffer.encode_string({self.number}, this->{self.field_name}_ref_);" + def dump(self, name): - o = f'out.append("\'").append({name}).append("\'");' - return o + # If name is 'it', this is a repeated field element - always use string + if name == "it": + return "append_quoted_string(out, StringRef(it));" + + # For SOURCE_CLIENT only, always use std::string + if not self._needs_encode: + return f'out.append("\'").append(this->{self.field_name}).append("\'");' + + # For SOURCE_SERVER, always use StringRef + if not self._needs_decode: + return f"append_quoted_string(out, this->{self.field_name}_ref_);" + + # For SOURCE_BOTH, check if StringRef is set (sending) or use string (received) + return ( + f"if (!this->{self.field_name}_ref_.empty()) {{" + f' out.append("\'").append(this->{self.field_name}_ref_.c_str()).append("\'");' + f"}} else {{" + f' out.append("\'").append(this->{self.field_name}).append("\'");' + f"}}" + ) def get_size_calculation(self, name: str, force: bool = False) -> str: - return self._get_simple_size_calculation(name, force, "add_string_field") + # For SOURCE_CLIENT only messages, use the string field directly + if not self._needs_encode: + return self._get_simple_size_calculation(name, force, "add_string_field") + + # Check if this is being called from a repeated field context + # In that case, 'name' will be 'it' and we need to use the repeated version + if name == "it": + # For repeated fields, we need to use add_string_field_repeated which includes field ID + field_id_size = self.calculate_field_id_size() + return f"ProtoSize::add_string_field_repeated(total_size, {field_id_size}, it);" + + # For messages that need encoding, use the StringRef size + field_id_size = self.calculate_field_id_size() + return f"ProtoSize::add_string_field(total_size, {field_id_size}, this->{self.field_name}_ref_.size());" def get_estimated_size(self) -> int: return self.calculate_field_id_size() + 8 # field ID + 8 bytes typical string @@ -1902,6 +1961,7 @@ def main() -> None: #pragma once #include "esphome/core/defines.h" +#include "esphome/core/string_ref.h" #include "proto.h" @@ -1935,6 +1995,15 @@ namespace api { namespace esphome { namespace api { +// Helper function to append a quoted string, handling empty StringRef +static inline void append_quoted_string(std::string &out, const StringRef &ref) { + out.append("'"); + if (!ref.empty()) { + out.append(ref.c_str()); + } + out.append("'"); +} + """ content += "namespace enums {\n\n" @@ -2174,7 +2243,13 @@ static const char *const TAG = "api.service"; cpp += f"#ifdef {ifdef}\n" hpp_protected += f" void {on_func}(const {inp} &msg) override;\n" - hpp += f" virtual {ret} {func}(const {inp} &msg) = 0;\n" + + # For non-void methods, generate a send_ method instead of return-by-value + if is_void: + hpp += f" virtual void {func}(const {inp} &msg) = 0;\n" + else: + hpp += f" virtual bool send_{func}_response(const {inp} &msg) = 0;\n" + cpp += f"void {class_name}::{on_func}(const {inp} &msg) {{\n" # Start with authentication/connection check if needed @@ -2192,10 +2267,7 @@ static const char *const TAG = "api.service"; if is_void: handler_body = f"this->{func}(msg);\n" else: - handler_body = f"{ret} ret = this->{func}(msg);\n" - handler_body += ( - f"if (!this->send_message(ret, {ret}::MESSAGE_TYPE)) {{\n" - ) + handler_body = f"if (!this->send_{func}_response(msg)) {{\n" handler_body += " this->on_fatal_error();\n" handler_body += "}\n" @@ -2207,8 +2279,7 @@ static const char *const TAG = "api.service"; if is_void: body += f"this->{func}(msg);\n" else: - body += f"{ret} ret = this->{func}(msg);\n" - body += f"if (!this->send_message(ret, {ret}::MESSAGE_TYPE)) {{\n" + body += f"if (!this->send_{func}_response(msg)) {{\n" body += " this->on_fatal_error();\n" body += "}\n"