Merge branch 'integration' of https://github.com/esphome/esphome into integration

This commit is contained in:
J. Nick Koston
2026-04-03 18:22:32 -10:00
19 changed files with 479 additions and 293 deletions
+93 -87
View File
@@ -308,6 +308,12 @@ enum EntityCategory {
ENTITY_CATEGORY_DIAGNOSTIC = 2;
}
// Entity field max_data_length values match constants in esphome/core/config.py:
// name/object_id = 120 (NAME_MAX_LENGTH)
// icon = 63 (ICON_MAX_LENGTH)
// device_class = 47 (DEVICE_CLASS_MAX_LENGTH)
// unit_of_measurement = 63 (UNIT_OF_MEASUREMENT_MAX_LENGTH)
// ==================== BINARY SENSOR ====================
message ListEntitiesBinarySensorResponse {
option (id) = 12;
@@ -315,15 +321,15 @@ message ListEntitiesBinarySensorResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_BINARY_SENSOR";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string device_class = 5;
string device_class = 5 [(max_data_length) = 47];
bool is_status_binary_sensor = 6;
bool disabled_by_default = 7;
string icon = 8 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 8 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
EntityCategory entity_category = 9;
uint32 device_id = 10 [(field_ifdef) = "USE_DEVICES"];
}
@@ -349,17 +355,17 @@ message ListEntitiesCoverResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_COVER";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
bool assumed_state = 5;
bool supports_position = 6;
bool supports_tilt = 7;
string device_class = 8;
string device_class = 8 [(max_data_length) = 47];
bool disabled_by_default = 9;
string icon = 10 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 10 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
EntityCategory entity_category = 11;
bool supports_stop = 12;
uint32 device_id = 13 [(field_ifdef) = "USE_DEVICES"];
@@ -433,9 +439,9 @@ message ListEntitiesFanResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_FAN";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
bool supports_oscillation = 5;
@@ -443,7 +449,7 @@ message ListEntitiesFanResponse {
bool supports_direction = 7;
int32 supported_speed_count = 8;
bool disabled_by_default = 9;
string icon = 10 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 10 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
EntityCategory entity_category = 11;
repeated string supported_preset_modes = 12 [(container_pointer_no_template) = "std::vector<const char *>"];
uint32 device_id = 13 [(field_ifdef) = "USE_DEVICES"];
@@ -521,9 +527,9 @@ message ListEntitiesLightResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_LIGHT";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
repeated ColorMode supported_color_modes = 12 [(container_pointer_no_template) = "light::ColorModeMask"];
@@ -540,7 +546,7 @@ message ListEntitiesLightResponse {
float max_mireds = 10;
repeated string effects = 11 [(container_pointer_no_template) = "FixedVector<const char *>"];
bool disabled_by_default = 13;
string icon = 14 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 14 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
EntityCategory entity_category = 15;
uint32 device_id = 16 [(field_ifdef) = "USE_DEVICES"];
}
@@ -626,16 +632,16 @@ message ListEntitiesSensorResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_SENSOR";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
string unit_of_measurement = 6;
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
string unit_of_measurement = 6 [(max_data_length) = 63];
int32 accuracy_decimals = 7;
bool force_update = 8;
string device_class = 9;
string device_class = 9 [(max_data_length) = 47];
SensorStateClass state_class = 10;
// Last reset type removed in 2021.9.0
// Deprecated in API version 1.5
@@ -666,16 +672,16 @@ message ListEntitiesSwitchResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_SWITCH";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool assumed_state = 6;
bool disabled_by_default = 7;
EntityCategory entity_category = 8;
string device_class = 9;
string device_class = 9 [(max_data_length) = 47];
uint32 device_id = 10 [(field_ifdef) = "USE_DEVICES"];
}
message SwitchStateResponse {
@@ -708,15 +714,15 @@ message ListEntitiesTextSensorResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_TEXT_SENSOR";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 6;
EntityCategory entity_category = 7;
string device_class = 8;
string device_class = 8 [(max_data_length) = 47];
uint32 device_id = 9 [(field_ifdef) = "USE_DEVICES"];
}
message TextSensorStateResponse {
@@ -971,12 +977,12 @@ message ListEntitiesCameraResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_CAMERA";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
bool disabled_by_default = 5;
string icon = 6 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 6 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
EntityCategory entity_category = 7;
uint32 device_id = 8 [(field_ifdef) = "USE_DEVICES"];
}
@@ -1056,9 +1062,9 @@ message ListEntitiesClimateResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_CLIMATE";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
bool supports_current_temperature = 5; // Deprecated: use feature_flags
@@ -1078,7 +1084,7 @@ message ListEntitiesClimateResponse {
repeated ClimatePreset supported_presets = 16 [(container_pointer_no_template) = "climate::ClimatePresetMask"];
repeated string supported_custom_presets = 17 [(container_pointer_no_template) = "std::vector<const char *>"];
bool disabled_by_default = 18;
string icon = 19 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 19 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
EntityCategory entity_category = 20;
float visual_current_temperature_step = 21;
bool supports_current_humidity = 22; // Deprecated: use feature_flags
@@ -1167,10 +1173,10 @@ message ListEntitiesWaterHeaterResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_WATER_HEATER";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string icon = 4 [(field_ifdef) = "USE_ENTITY_ICON"];
string name = 3 [(max_data_length) = 120, (force) = true];
string icon = 4 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 5;
EntityCategory entity_category = 6;
uint32 device_id = 7 [(field_ifdef) = "USE_DEVICES"];
@@ -1243,12 +1249,12 @@ message ListEntitiesNumberResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_NUMBER";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
float min_value = 6;
float max_value = 7;
float step = 8;
@@ -1256,7 +1262,7 @@ message ListEntitiesNumberResponse {
EntityCategory entity_category = 10;
string unit_of_measurement = 11;
NumberMode mode = 12;
string device_class = 13;
string device_class = 13 [(max_data_length) = 47];
uint32 device_id = 14 [(field_ifdef) = "USE_DEVICES"];
}
message NumberStateResponse {
@@ -1292,12 +1298,12 @@ message ListEntitiesSelectResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_SELECT";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
repeated string options = 6 [(container_pointer_no_template) = "FixedVector<const char *>"];
bool disabled_by_default = 7;
EntityCategory entity_category = 8;
@@ -1336,12 +1342,12 @@ message ListEntitiesSirenResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_SIREN";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 6;
repeated string tones = 7 [(container_pointer_no_template) = "FixedVector<const char *>"];
bool supports_duration = 8;
@@ -1399,12 +1405,12 @@ message ListEntitiesLockResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_LOCK";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 6;
EntityCategory entity_category = 7;
bool assumed_state = 8;
@@ -1448,15 +1454,15 @@ message ListEntitiesButtonResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_BUTTON";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 6;
EntityCategory entity_category = 7;
string device_class = 8;
string device_class = 8 [(max_data_length) = 47];
uint32 device_id = 9 [(field_ifdef) = "USE_DEVICES"];
}
message ButtonCommandRequest {
@@ -1515,12 +1521,12 @@ message ListEntitiesMediaPlayerResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_MEDIA_PLAYER";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 6;
EntityCategory entity_category = 7;
@@ -1606,7 +1612,7 @@ message BluetoothLEAdvertisementResponse {
message BluetoothLERawAdvertisement {
uint64 address = 1 [(force) = true];
sint32 rssi = 2 [(force) = true];
uint32 address_type = 3;
uint32 address_type = 3 [(max_value) = 4];
bytes data = 4 [(fixed_array_size) = 62, (force) = true];
}
@@ -2103,11 +2109,11 @@ message ListEntitiesAlarmControlPanelResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_ALARM_CONTROL_PANEL";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 6;
EntityCategory entity_category = 7;
uint32 supported_features = 8;
@@ -2150,11 +2156,11 @@ message ListEntitiesTextResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_TEXT";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 6;
EntityCategory entity_category = 7;
@@ -2198,12 +2204,12 @@ message ListEntitiesDateResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_DATETIME_DATE";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 6;
EntityCategory entity_category = 7;
uint32 device_id = 8 [(field_ifdef) = "USE_DEVICES"];
@@ -2245,12 +2251,12 @@ message ListEntitiesTimeResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_DATETIME_TIME";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 6;
EntityCategory entity_category = 7;
uint32 device_id = 8 [(field_ifdef) = "USE_DEVICES"];
@@ -2292,15 +2298,15 @@ message ListEntitiesEventResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_EVENT";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 6;
EntityCategory entity_category = 7;
string device_class = 8;
string device_class = 8 [(max_data_length) = 47];
repeated string event_types = 9 [(container_pointer_no_template) = "FixedVector<const char *>"];
uint32 device_id = 10 [(field_ifdef) = "USE_DEVICES"];
@@ -2323,15 +2329,15 @@ message ListEntitiesValveResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_VALVE";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 6;
EntityCategory entity_category = 7;
string device_class = 8;
string device_class = 8 [(max_data_length) = 47];
bool assumed_state = 9;
bool supports_position = 10;
@@ -2378,12 +2384,12 @@ message ListEntitiesDateTimeResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_DATETIME_DATETIME";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 6;
EntityCategory entity_category = 7;
uint32 device_id = 8 [(field_ifdef) = "USE_DEVICES"];
@@ -2421,15 +2427,15 @@ message ListEntitiesUpdateResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_UPDATE";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string name = 3 [(max_data_length) = 120, (force) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 6;
EntityCategory entity_category = 7;
string device_class = 8;
string device_class = 8 [(max_data_length) = 47];
uint32 device_id = 9 [(field_ifdef) = "USE_DEVICES"];
}
message UpdateStateResponse {
@@ -2504,10 +2510,10 @@ message ListEntitiesInfraredResponse {
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_INFRARED";
string object_id = 1;
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3;
string icon = 4 [(field_ifdef) = "USE_ENTITY_ICON"];
string name = 3 [(max_data_length) = 120, (force) = true];
string icon = 4 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 5;
EntityCategory entity_category = 6;
uint32 device_id = 7 [(field_ifdef) = "USE_DEVICES"];
+12
View File
@@ -96,4 +96,16 @@ extend google.protobuf.FieldOptions {
// variant of the calc_ method. Use on fields that are almost always non-default
// to eliminate dead branches on hot paths.
optional bool force = 50016 [default=false];
// max_value: Maximum value a field can have.
// When max_value < 128, the code generator emits constant-size calculations
// and direct byte writes instead of varint branching, since the encoded varint
// is guaranteed to be 1 byte.
optional uint32 max_value = 50017;
// max_data_length: Maximum length of a string or bytes field.
// When max_data_length < 128, the code generator emits constant-size
// length varint calculations and direct byte writes, since the length
// varint is guaranteed to be 1 byte.
optional uint32 max_data_length = 50018;
}
+139 -139
View File
@@ -207,9 +207,9 @@ uint32_t DeviceInfoResponse::calculate_size() const {
}
#ifdef USE_BINARY_SENSOR
void ListEntitiesBinarySensorResponse::encode(ProtoWriteBuffer &buffer) const {
buffer.encode_string(1, this->object_id);
buffer.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
buffer.encode_string(5, this->device_class);
buffer.encode_bool(6, this->is_status_binary_sensor);
buffer.encode_bool(7, this->disabled_by_default);
@@ -223,14 +223,14 @@ void ListEntitiesBinarySensorResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesBinarySensorResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += ProtoSize::calc_length(1, this->device_class.size());
size += 2 + this->name.size();
size += !this->device_class.empty() ? 2 + this->device_class.size() : 0;
size += ProtoSize::calc_bool(1, this->is_status_binary_sensor);
size += ProtoSize::calc_bool(1, this->disabled_by_default);
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
#ifdef USE_DEVICES
@@ -259,9 +259,9 @@ uint32_t BinarySensorStateResponse::calculate_size() const {
#endif
#ifdef USE_COVER
void ListEntitiesCoverResponse::encode(ProtoWriteBuffer &buffer) const {
buffer.encode_string(1, this->object_id);
buffer.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
buffer.encode_bool(5, this->assumed_state);
buffer.encode_bool(6, this->supports_position);
buffer.encode_bool(7, this->supports_tilt);
@@ -278,16 +278,16 @@ void ListEntitiesCoverResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesCoverResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
size += ProtoSize::calc_bool(1, this->assumed_state);
size += ProtoSize::calc_bool(1, this->supports_position);
size += ProtoSize::calc_bool(1, this->supports_tilt);
size += ProtoSize::calc_length(1, this->device_class.size());
size += !this->device_class.empty() ? 2 + this->device_class.size() : 0;
size += ProtoSize::calc_bool(1, this->disabled_by_default);
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
size += ProtoSize::calc_bool(1, this->supports_stop);
@@ -356,9 +356,9 @@ 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.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
buffer.encode_bool(5, this->supports_oscillation);
buffer.encode_bool(6, this->supports_speed);
buffer.encode_bool(7, this->supports_direction);
@@ -377,16 +377,16 @@ void ListEntitiesFanResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesFanResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
size += ProtoSize::calc_bool(1, this->supports_oscillation);
size += ProtoSize::calc_bool(1, this->supports_speed);
size += ProtoSize::calc_bool(1, this->supports_direction);
size += ProtoSize::calc_int32(1, this->supported_speed_count);
size += ProtoSize::calc_bool(1, this->disabled_by_default);
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
if (!this->supported_preset_modes->empty()) {
@@ -486,9 +486,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.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
for (const auto &it : *this->supported_color_modes) {
buffer.encode_uint32(12, static_cast<uint32_t>(it), true);
}
@@ -508,9 +508,9 @@ void ListEntitiesLightResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesLightResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
if (!this->supported_color_modes->empty()) {
for (const auto &it : *this->supported_color_modes) {
size += ProtoSize::calc_uint32_force(1, static_cast<uint32_t>(it));
@@ -525,7 +525,7 @@ uint32_t ListEntitiesLightResponse::calculate_size() const {
}
size += ProtoSize::calc_bool(1, this->disabled_by_default);
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
#ifdef USE_DEVICES
@@ -682,9 +682,9 @@ 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.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(5, this->icon);
#endif
@@ -701,16 +701,16 @@ void ListEntitiesSensorResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesSensorResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_length(1, this->unit_of_measurement.size());
size += !this->unit_of_measurement.empty() ? 2 + this->unit_of_measurement.size() : 0;
size += ProtoSize::calc_int32(1, this->accuracy_decimals);
size += ProtoSize::calc_bool(1, this->force_update);
size += ProtoSize::calc_length(1, this->device_class.size());
size += !this->device_class.empty() ? 2 + this->device_class.size() : 0;
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->state_class));
size += ProtoSize::calc_bool(1, this->disabled_by_default);
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
@@ -740,9 +740,9 @@ uint32_t SensorStateResponse::calculate_size() const {
#endif
#ifdef USE_SWITCH
void ListEntitiesSwitchResponse::encode(ProtoWriteBuffer &buffer) const {
buffer.encode_string(1, this->object_id);
buffer.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(5, this->icon);
#endif
@@ -756,16 +756,16 @@ void ListEntitiesSwitchResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesSwitchResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_bool(1, this->assumed_state);
size += ProtoSize::calc_bool(1, this->disabled_by_default);
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
size += ProtoSize::calc_length(1, this->device_class.size());
size += !this->device_class.empty() ? 2 + this->device_class.size() : 0;
#ifdef USE_DEVICES
size += ProtoSize::calc_uint32(1, this->device_id);
#endif
@@ -815,9 +815,9 @@ 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.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(5, this->icon);
#endif
@@ -830,15 +830,15 @@ void ListEntitiesTextSensorResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesTextSensorResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_bool(1, this->disabled_by_default);
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
size += ProtoSize::calc_length(1, this->device_class.size());
size += !this->device_class.empty() ? 2 + this->device_class.size() : 0;
#ifdef USE_DEVICES
size += ProtoSize::calc_uint32(1, this->device_id);
#endif
@@ -1264,9 +1264,9 @@ uint32_t ExecuteServiceResponse::calculate_size() const {
#endif
#ifdef USE_CAMERA
void ListEntitiesCameraResponse::encode(ProtoWriteBuffer &buffer) const {
buffer.encode_string(1, this->object_id);
buffer.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
buffer.encode_bool(5, this->disabled_by_default);
#ifdef USE_ENTITY_ICON
buffer.encode_string(6, this->icon);
@@ -1278,12 +1278,12 @@ void ListEntitiesCameraResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesCameraResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
size += ProtoSize::calc_bool(1, this->disabled_by_default);
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
#ifdef USE_DEVICES
@@ -1325,9 +1325,9 @@ bool CameraImageRequest::decode_varint(uint32_t field_id, proto_varint_value_t v
#endif
#ifdef USE_CLIMATE
void ListEntitiesClimateResponse::encode(ProtoWriteBuffer &buffer) const {
buffer.encode_string(1, this->object_id);
buffer.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
buffer.encode_bool(5, this->supports_current_temperature);
buffer.encode_bool(6, this->supports_two_point_target_temperature);
for (const auto &it : *this->supported_modes) {
@@ -1369,9 +1369,9 @@ void ListEntitiesClimateResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesClimateResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
size += ProtoSize::calc_bool(1, this->supports_current_temperature);
size += ProtoSize::calc_bool(1, this->supports_two_point_target_temperature);
if (!this->supported_modes->empty()) {
@@ -1410,7 +1410,7 @@ uint32_t ListEntitiesClimateResponse::calculate_size() const {
}
size += ProtoSize::calc_bool(2, this->disabled_by_default);
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(2, this->icon.size());
size += !this->icon.empty() ? 3 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_uint32(2, static_cast<uint32_t>(this->entity_category));
size += ProtoSize::calc_float(2, this->visual_current_temperature_step);
@@ -1558,9 +1558,9 @@ bool ClimateCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
#endif
#ifdef USE_WATER_HEATER
void ListEntitiesWaterHeaterResponse::encode(ProtoWriteBuffer &buffer) const {
buffer.encode_string(1, this->object_id);
buffer.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(4, this->icon);
#endif
@@ -1579,11 +1579,11 @@ void ListEntitiesWaterHeaterResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesWaterHeaterResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_bool(1, this->disabled_by_default);
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
@@ -1670,9 +1670,9 @@ bool WaterHeaterCommandRequest::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.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(5, this->icon);
#endif
@@ -1690,11 +1690,11 @@ void ListEntitiesNumberResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesNumberResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_float(1, this->min_value);
size += ProtoSize::calc_float(1, this->max_value);
@@ -1703,7 +1703,7 @@ uint32_t ListEntitiesNumberResponse::calculate_size() const {
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
size += ProtoSize::calc_length(1, this->unit_of_measurement.size());
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->mode));
size += ProtoSize::calc_length(1, this->device_class.size());
size += !this->device_class.empty() ? 2 + this->device_class.size() : 0;
#ifdef USE_DEVICES
size += ProtoSize::calc_uint32(1, this->device_id);
#endif
@@ -1755,9 +1755,9 @@ 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.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(5, this->icon);
#endif
@@ -1772,11 +1772,11 @@ void ListEntitiesSelectResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesSelectResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
if (!this->options->empty()) {
for (const char *it : *this->options) {
@@ -1844,9 +1844,9 @@ 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.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(5, this->icon);
#endif
@@ -1863,11 +1863,11 @@ void ListEntitiesSirenResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesSirenResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_bool(1, this->disabled_by_default);
if (!this->tones->empty()) {
@@ -1956,9 +1956,9 @@ 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.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(5, this->icon);
#endif
@@ -1974,11 +1974,11 @@ void ListEntitiesLockResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesLockResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_bool(1, this->disabled_by_default);
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
@@ -2049,9 +2049,9 @@ 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.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(5, this->icon);
#endif
@@ -2064,15 +2064,15 @@ void ListEntitiesButtonResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesButtonResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_bool(1, this->disabled_by_default);
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
size += ProtoSize::calc_length(1, this->device_class.size());
size += !this->device_class.empty() ? 2 + this->device_class.size() : 0;
#ifdef USE_DEVICES
size += ProtoSize::calc_uint32(1, this->device_id);
#endif
@@ -2119,9 +2119,9 @@ uint32_t MediaPlayerSupportedFormat::calculate_size() const {
return size;
}
void ListEntitiesMediaPlayerResponse::encode(ProtoWriteBuffer &buffer) const {
buffer.encode_string(1, this->object_id);
buffer.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(5, this->icon);
#endif
@@ -2138,11 +2138,11 @@ void ListEntitiesMediaPlayerResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesMediaPlayerResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_bool(1, this->disabled_by_default);
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
@@ -2251,15 +2251,15 @@ void BluetoothLERawAdvertisement::encode(ProtoWriteBuffer &buffer) const {
buffer.encode_varint_raw_short(encode_zigzag32(this->rssi));
buffer.encode_uint32(3, this->address_type);
buffer.write_raw_byte(34);
buffer.encode_varint_raw(this->data_len);
buffer.write_raw_byte(static_cast<uint8_t>(this->data_len));
buffer.encode_raw(this->data, this->data_len);
}
uint32_t BluetoothLERawAdvertisement::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_uint64_force(1, this->address);
size += ProtoSize::calc_sint32_force(1, this->rssi);
size += ProtoSize::calc_uint32(1, this->address_type);
size += ProtoSize::calc_length_force(1, this->data_len);
size += this->address_type ? 2 : 0;
size += 2 + this->data_len;
return size;
}
void BluetoothLERawAdvertisementsResponse::encode(ProtoWriteBuffer &buffer) const {
@@ -2941,9 +2941,9 @@ 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.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(5, this->icon);
#endif
@@ -2958,11 +2958,11 @@ void ListEntitiesAlarmControlPanelResponse::encode(ProtoWriteBuffer &buffer) con
}
uint32_t ListEntitiesAlarmControlPanelResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_bool(1, this->disabled_by_default);
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
@@ -3029,9 +3029,9 @@ 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.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(5, this->icon);
#endif
@@ -3047,11 +3047,11 @@ void ListEntitiesTextResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesTextResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_bool(1, this->disabled_by_default);
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
@@ -3118,9 +3118,9 @@ 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.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(5, this->icon);
#endif
@@ -3132,11 +3132,11 @@ void ListEntitiesDateResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesDateResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_bool(1, this->disabled_by_default);
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
@@ -3201,9 +3201,9 @@ 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.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(5, this->icon);
#endif
@@ -3215,11 +3215,11 @@ void ListEntitiesTimeResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesTimeResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_bool(1, this->disabled_by_default);
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
@@ -3284,9 +3284,9 @@ 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.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(5, this->icon);
#endif
@@ -3302,15 +3302,15 @@ void ListEntitiesEventResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesEventResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_bool(1, this->disabled_by_default);
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
size += ProtoSize::calc_length(1, this->device_class.size());
size += !this->device_class.empty() ? 2 + this->device_class.size() : 0;
if (!this->event_types->empty()) {
for (const char *it : *this->event_types) {
size += ProtoSize::calc_length_force(1, strlen(it));
@@ -3340,9 +3340,9 @@ uint32_t EventResponse::calculate_size() const {
#endif
#ifdef USE_VALVE
void ListEntitiesValveResponse::encode(ProtoWriteBuffer &buffer) const {
buffer.encode_string(1, this->object_id);
buffer.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(5, this->icon);
#endif
@@ -3358,15 +3358,15 @@ void ListEntitiesValveResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesValveResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_bool(1, this->disabled_by_default);
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
size += ProtoSize::calc_length(1, this->device_class.size());
size += !this->device_class.empty() ? 2 + this->device_class.size() : 0;
size += ProtoSize::calc_bool(1, this->assumed_state);
size += ProtoSize::calc_bool(1, this->supports_position);
size += ProtoSize::calc_bool(1, this->supports_stop);
@@ -3427,9 +3427,9 @@ 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.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(5, this->icon);
#endif
@@ -3441,11 +3441,11 @@ void ListEntitiesDateTimeResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesDateTimeResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_bool(1, this->disabled_by_default);
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
@@ -3500,9 +3500,9 @@ 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.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(5, this->icon);
#endif
@@ -3515,15 +3515,15 @@ void ListEntitiesUpdateResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesUpdateResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_bool(1, this->disabled_by_default);
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
size += ProtoSize::calc_length(1, this->device_class.size());
size += !this->device_class.empty() ? 2 + this->device_class.size() : 0;
#ifdef USE_DEVICES
size += ProtoSize::calc_uint32(1, this->device_id);
#endif
@@ -3641,9 +3641,9 @@ uint32_t ZWaveProxyRequest::calculate_size() const {
#endif
#ifdef USE_INFRARED
void ListEntitiesInfraredResponse::encode(ProtoWriteBuffer &buffer) const {
buffer.encode_string(1, this->object_id);
buffer.write_short_string(10, this->object_id);
buffer.write_tag_and_fixed32(21, this->key);
buffer.encode_string(3, this->name);
buffer.write_short_string(26, this->name);
#ifdef USE_ENTITY_ICON
buffer.encode_string(4, this->icon);
#endif
@@ -3657,11 +3657,11 @@ void ListEntitiesInfraredResponse::encode(ProtoWriteBuffer &buffer) const {
}
uint32_t ListEntitiesInfraredResponse::calculate_size() const {
uint32_t size = 0;
size += ProtoSize::calc_length(1, this->object_id.size());
size += 2 + this->object_id.size();
size += 5;
size += ProtoSize::calc_length(1, this->name.size());
size += 2 + this->name.size();
#ifdef USE_ENTITY_ICON
size += ProtoSize::calc_length(1, this->icon.size());
size += !this->icon.empty() ? 2 + this->icon.size() : 0;
#endif
size += ProtoSize::calc_bool(1, this->disabled_by_default);
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->entity_category));
+10
View File
@@ -280,6 +280,16 @@ class ProtoWriteBuffer {
std::memcpy(pos, data, len);
this->pos_ = pos + len;
}
/// Write tag + 1-byte length + raw string data. For strings with max_data_length < 128.
/// Tag must be a single-byte varint (< 128). Always encodes (no zero check).
inline void write_short_string(uint8_t tag, const StringRef &ref) ESPHOME_ALWAYS_INLINE {
this->debug_check_bounds_(2 + ref.size());
uint8_t *__restrict__ pos = this->pos_;
*pos++ = tag;
*pos++ = static_cast<uint8_t>(ref.size());
std::memcpy(pos, ref.c_str(), ref.size());
this->pos_ = pos + ref.size();
}
/// Write a precomputed tag byte + 32-bit value in one operation.
/// Tag must be a single-byte varint (< 128). No zero check.
inline void write_tag_and_fixed32(uint8_t tag, uint32_t value) ESPHOME_ALWAYS_INLINE {
+1 -1
View File
@@ -16,7 +16,7 @@ void log_button(const char *tag, const char *prefix, const char *type, Button *o
}
void Button::press() {
ESP_LOGD(TAG, "'%s' Pressed.", this->get_name().c_str());
ESP_LOGV(TAG, "'%s' Pressed.", this->get_name().c_str());
this->press_action();
this->press_callback_.call();
}
+14 -9
View File
@@ -399,8 +399,17 @@ void ESP32BLE::loop() {
return;
}
#ifdef USE_ESP32_BLE_ADVERTISING
if (this->advertising_ != nullptr) {
this->advertising_->loop();
}
#endif
BLEEvent *ble_event = this->ble_events_.pop();
while (ble_event != nullptr) {
if (ble_event == nullptr)
return;
do {
switch (ble_event->type_) {
#if defined(USE_ESP32_BLE_SERVER) && defined(ESPHOME_ESP32_BLE_GATTS_EVENT_HANDLER_COUNT)
case BLEEvent::GATTS: {
@@ -488,15 +497,11 @@ void ESP32BLE::loop() {
}
// Return the event to the pool
this->ble_event_pool_.release(ble_event);
ble_event = this->ble_events_.pop();
}
#ifdef USE_ESP32_BLE_ADVERTISING
if (this->advertising_ != nullptr) {
this->advertising_->loop();
}
#endif
} while ((ble_event = this->ble_events_.pop()) != nullptr);
// Log dropped events periodically
// Log dropped events - only reachable when events were processed.
// Drops only occur when the queue is full, and only this loop drains it,
// so if pop() returned nullptr above we can skip this check (saves a memw).
uint16_t dropped = this->ble_events_.get_and_reset_dropped_count();
if (dropped > 0) {
ESP_LOGW(TAG, "Dropped %u BLE events due to buffer overflow", dropped);
+2 -2
View File
@@ -73,13 +73,13 @@ void HLW8012Component::update() {
// Only read cf1 after one cycle. Apparently it's quite unstable after being changed.
if (this->current_mode_) {
float current = cf1_hz * this->current_multiplier_;
ESP_LOGD(TAG, "Got power=%.1fW, current=%.1fA", power, current);
ESP_LOGV(TAG, "Got power=%.1fW, current=%.1fA", power, current);
if (this->current_sensor_ != nullptr) {
this->current_sensor_->publish_state(current);
}
} else {
float voltage = cf1_hz * this->voltage_multiplier_;
ESP_LOGD(TAG, "Got power=%.1fW, voltage=%.1fV", power, voltage);
ESP_LOGV(TAG, "Got power=%.1fW, voltage=%.1fV", power, voltage);
if (this->voltage_sensor_ != nullptr) {
this->voltage_sensor_->publish_state(voltage);
}
+6 -1
View File
@@ -79,6 +79,7 @@ from esphome.const import (
DEVICE_CLASS_WIND_SPEED,
)
from esphome.core import CORE, CoroPriority, coroutine_with_priority
from esphome.core.config import UNIT_OF_MEASUREMENT_MAX_LENGTH
from esphome.core.entity_helpers import (
entity_duplicate_validator,
setup_device_class,
@@ -186,7 +187,11 @@ NUMBER_OPERATION_OPTIONS = {
}
validate_device_class = cv.one_of(*DEVICE_CLASSES, lower=True, space="_")
validate_unit_of_measurement = cv.string_strict
validate_unit_of_measurement = cv.All(
cv.string_strict,
# Keep in sync with max_data_length in api.proto
cv.Length(max=UNIT_OF_MEASUREMENT_MAX_LENGTH),
)
_NUMBER_SCHEMA = (
cv.ENTITY_BASE_SCHEMA.extend(web_server.WEBSERVER_SORTING_SCHEMA)
+1 -1
View File
@@ -116,7 +116,7 @@ void SelectCall::perform() {
auto idx = target_index.value();
// All operations use indices, call control() by index to avoid string conversion
ESP_LOGD(TAG, "'%s' - Set selected option to: %s", name, parent->option_at(idx));
ESP_LOGV(TAG, "'%s' - Set selected option to: %s", name, parent->option_at(idx));
parent->control(idx);
}
+6 -1
View File
@@ -106,6 +106,7 @@ from esphome.const import (
ENTITY_CATEGORY_CONFIG,
)
from esphome.core import CORE, CoroPriority, coroutine_with_priority
from esphome.core.config import UNIT_OF_MEASUREMENT_MAX_LENGTH
from esphome.core.entity_helpers import (
entity_duplicate_validator,
setup_device_class,
@@ -290,7 +291,11 @@ ClampFilter = sensor_ns.class_("ClampFilter", Filter)
RoundFilter = sensor_ns.class_("RoundFilter", Filter)
RoundMultipleFilter = sensor_ns.class_("RoundMultipleFilter", Filter)
validate_unit_of_measurement = cv.string_strict
validate_unit_of_measurement = cv.All(
cv.string_strict,
# Keep in sync with max_data_length in api.proto
cv.Length(max=UNIT_OF_MEASUREMENT_MAX_LENGTH),
)
validate_accuracy_decimals = cv.int_
validate_icon = cv.icon
validate_device_class = cv.one_of(*DEVICE_CLASSES, lower=True, space="_")
+3 -3
View File
@@ -18,15 +18,15 @@ void Switch::control(bool target_state) {
}
}
void Switch::turn_on() {
ESP_LOGD(TAG, "'%s' Turning ON.", this->get_name().c_str());
ESP_LOGV(TAG, "'%s' Turning ON.", this->get_name().c_str());
this->write_state(!this->inverted_);
}
void Switch::turn_off() {
ESP_LOGD(TAG, "'%s' Turning OFF.", this->get_name().c_str());
ESP_LOGV(TAG, "'%s' Turning OFF.", this->get_name().c_str());
this->write_state(this->inverted_);
}
void Switch::toggle() {
ESP_LOGD(TAG, "'%s' Toggling %s.", this->get_name().c_str(), this->state ? "OFF" : "ON");
ESP_LOGV(TAG, "'%s' Toggling %s.", this->get_name().c_str(), this->state ? "OFF" : "ON");
this->write_state(this->inverted_ == this->state);
}
optional<bool> Switch::get_initial_state() {
@@ -1,10 +1,21 @@
#include "total_daily_energy.h"
#include "esphome/core/application.h"
#include "esphome/core/log.h"
namespace esphome {
namespace total_daily_energy {
namespace esphome::total_daily_energy {
static const char *const TAG = "total_daily_energy";
static constexpr uint32_t TIMEOUT_ID_MIDNIGHT = 1;
static constexpr uint8_t SECONDS_PER_MINUTE = 60;
static constexpr uint8_t MINUTES_PER_HOUR = 60;
static constexpr uint8_t HOURS_PER_DAY = 24;
static constexpr uint32_t SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;
static constexpr uint16_t MILLIS_PER_SECOND = 1000;
// Wake up 90 minutes before midnight to recalculate, ensuring DST transitions
// (which shift wall clock by 1 hour but don't change millis()) don't cause
// the midnight reset to fire late. DST transitions don't trigger the time sync
// callback since they change local time interpretation, not the epoch.
static constexpr uint32_t PRE_MIDNIGHT_SECONDS = 90 * SECONDS_PER_MINUTE;
void TotalDailyEnergy::setup() {
float initial_value = 0;
@@ -15,28 +26,53 @@ void TotalDailyEnergy::setup() {
}
this->publish_state_and_save(initial_value);
this->last_update_ = millis();
this->last_update_ = App.get_loop_component_start_time();
this->parent_->add_on_state_callback([this](float state) { this->process_new_state_(state); });
// Schedule initial midnight reset if time is already valid, otherwise
// the time sync callback will handle it once time becomes available.
this->schedule_midnight_reset_();
// Re-schedule on every NTP sync in case the clock jumped across midnight.
this->time_->add_on_time_sync_callback([this]() { this->schedule_midnight_reset_(); });
}
void TotalDailyEnergy::dump_config() { LOG_SENSOR("", "Total Daily Energy", this); }
void TotalDailyEnergy::loop() {
void TotalDailyEnergy::schedule_midnight_reset_() {
auto t = this->time_->now();
if (!t.is_valid())
return;
if (this->last_day_of_year_ == 0) {
// Check if the day changed (time sync moved us past midnight, or first call)
if (this->last_day_of_year_ != t.day_of_year) {
if (this->last_day_of_year_ != 0) {
// Day actually changed — reset energy
this->total_energy_ = 0;
this->publish_state_and_save(0);
}
this->last_day_of_year_ = t.day_of_year;
return;
}
if (t.day_of_year != this->last_day_of_year_) {
this->last_day_of_year_ = t.day_of_year;
this->total_energy_ = 0;
this->publish_state_and_save(0);
// Calculate seconds until next midnight.
// Uses the same TIMEOUT_ID_MIDNIGHT ID so re-scheduling (e.g. from time sync) cancels
// any previously pending timeout.
uint32_t seconds_until_midnight =
((HOURS_PER_DAY - 1 - t.hour) * MINUTES_PER_HOUR + (MINUTES_PER_HOUR - 1 - t.minute)) * SECONDS_PER_MINUTE +
(SECONDS_PER_MINUTE - t.second);
uint32_t timeout_seconds;
if (seconds_until_midnight > PRE_MIDNIGHT_SECONDS) {
// Far from midnight — wake up 90 minutes before to recalculate with fresh wall clock
timeout_seconds = seconds_until_midnight - PRE_MIDNIGHT_SECONDS;
} else {
// Close to midnight — schedule the actual reset with 1s buffer
timeout_seconds = seconds_until_midnight + 1;
}
ESP_LOGD(TAG, "Scheduling midnight check in %us", timeout_seconds);
this->set_timeout(TIMEOUT_ID_MIDNIGHT, timeout_seconds * MILLIS_PER_SECOND,
[this]() { this->schedule_midnight_reset_(); });
}
void TotalDailyEnergy::publish_state_and_save(float state) {
@@ -50,14 +86,14 @@ void TotalDailyEnergy::publish_state_and_save(float state) {
void TotalDailyEnergy::process_new_state_(float state) {
if (std::isnan(state))
return;
const uint32_t now = millis();
const uint32_t now = App.get_loop_component_start_time();
const float old_state = this->last_power_state_;
const float new_state = state;
float delta_hours = (now - this->last_update_) / 1000.0f / 60.0f / 60.0f;
float delta_hours = (now - this->last_update_) / static_cast<float>(MILLIS_PER_SECOND) / SECONDS_PER_HOUR;
float delta_energy = 0.0f;
switch (this->method_) {
case TOTAL_DAILY_ENERGY_METHOD_TRAPEZOID:
delta_energy = delta_hours * (old_state + new_state) / 2.0;
delta_energy = delta_hours * (old_state + new_state) / 2.0f;
break;
case TOTAL_DAILY_ENERGY_METHOD_LEFT:
delta_energy = delta_hours * old_state;
@@ -71,5 +107,4 @@ void TotalDailyEnergy::process_new_state_(float state) {
this->publish_state_and_save(this->total_energy_ + delta_energy);
}
} // namespace total_daily_energy
} // namespace esphome
} // namespace esphome::total_daily_energy
@@ -6,8 +6,7 @@
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/time/real_time_clock.h"
namespace esphome {
namespace total_daily_energy {
namespace esphome::total_daily_energy {
enum TotalDailyEnergyMethod {
TOTAL_DAILY_ENERGY_METHOD_TRAPEZOID = 0,
@@ -23,12 +22,12 @@ class TotalDailyEnergy : public sensor::Sensor, public Component {
void set_method(TotalDailyEnergyMethod method) { method_ = method; }
void setup() override;
void dump_config() override;
void loop() override;
void publish_state_and_save(float state);
protected:
void process_new_state_(float state);
void schedule_midnight_reset_();
ESPPreferenceObject pref_;
time::RealTimeClock *time_;
@@ -41,5 +40,4 @@ class TotalDailyEnergy : public sensor::Sensor, public Component {
float last_power_state_{0.0f};
};
} // namespace total_daily_energy
} // namespace esphome
} // namespace esphome::total_daily_energy
@@ -717,20 +717,23 @@ const char *get_disconnect_reason_str(uint8_t reason) {
}
bool WiFiComponent::wifi_loop_() {
// Fast path: skip dropped count check and pop loop when queue is empty
if (this->event_queue_.empty())
// Use pop() directly instead of empty() — pop() costs 1 memw (acquire on tail_),
// while empty() costs 2 memw (acquire on both head_ and tail_) on Xtensa.
IDFWiFiEvent *data = this->event_queue_.pop();
if (data == nullptr)
return false;
do {
wifi_process_event_(data);
delete data; // NOLINT(cppcoreguidelines-owning-memory)
} while ((data = this->event_queue_.pop()) != nullptr);
// Drops only occur when the queue is full, and only this loop drains it,
// so if pop() returned nullptr above we can skip this check.
uint16_t dropped = this->event_queue_.get_and_reset_dropped_count();
if (dropped > 0) {
ESP_LOGW(TAG, "Dropped %u WiFi events due to buffer overflow", dropped);
}
IDFWiFiEvent *data;
while ((data = this->event_queue_.pop()) != nullptr) {
wifi_process_event_(data);
delete data; // NOLINT(cppcoreguidelines-owning-memory)
}
return true;
}
// Events are processed from queue in main loop context, but listener notifications
@@ -778,20 +778,24 @@ network::IPAddress WiFiComponent::wifi_subnet_mask_() { return {WiFi.subnetMask(
network::IPAddress WiFiComponent::wifi_gateway_ip_() { return {WiFi.gatewayIP()}; }
network::IPAddress WiFiComponent::wifi_dns_ip_(int num) { return {WiFi.dnsIP(num)}; }
bool WiFiComponent::wifi_loop_() {
// Fast path: skip dropped count check and pop loop when queue is empty
if (this->event_queue_.empty())
// Use pop() directly instead of empty() — avoids redundant synchronization.
// LockFreeQueue: pop() costs 1 memw vs empty()'s 2 memw on Xtensa.
// FreeRTOSQueue: pop() is 1 critical section vs empty() + pop() = 2.
LTWiFiEvent *event = this->event_queue_.pop();
if (event == nullptr)
return false;
do {
wifi_process_event_(event);
delete event; // NOLINT(cppcoreguidelines-owning-memory)
} while ((event = this->event_queue_.pop()) != nullptr);
// Drops only occur when the queue is full, and only this loop drains it,
// so if pop() returned nullptr above we can skip this check.
uint16_t dropped = this->event_queue_.get_and_reset_dropped_count();
if (dropped > 0) {
ESP_LOGW(TAG, "Dropped %" PRIu16 " WiFi events due to buffer overflow", dropped);
}
LTWiFiEvent *event;
while ((event = this->event_queue_.pop()) != nullptr) {
wifi_process_event_(event);
delete event; // NOLINT(cppcoreguidelines-owning-memory)
}
return true;
}
+3
View File
@@ -233,6 +233,9 @@ DEVICE_CLASS_MAX_LENGTH = 47
# Keep in sync with MAX_ICON_LENGTH in esphome/core/entity_base.h
ICON_MAX_LENGTH = 63
# Max unit of measurement string length
UNIT_OF_MEASUREMENT_MAX_LENGTH = 63
AREA_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_ID): cv.declare_id(Area),
+10 -1
View File
@@ -17,7 +17,11 @@ from esphome.const import (
CONF_UNIT_OF_MEASUREMENT,
)
from esphome.core import CORE, ID, CoroPriority, coroutine_with_priority
from esphome.core.config import DEVICE_CLASS_MAX_LENGTH, ICON_MAX_LENGTH
from esphome.core.config import (
DEVICE_CLASS_MAX_LENGTH,
ICON_MAX_LENGTH,
UNIT_OF_MEASUREMENT_MAX_LENGTH,
)
from esphome.cpp_generator import MockObj, RawStatement, add, get_variable
import esphome.final_validate as fv
from esphome.helpers import cpp_string_escape, fnv1_hash_object_id, sanitize, snake_case
@@ -200,6 +204,11 @@ def register_device_class(value: str) -> int:
def register_unit_of_measurement(value: str) -> int:
"""Register a unit_of_measurement string and return its 1-based index."""
if value and len(value) > UNIT_OF_MEASUREMENT_MAX_LENGTH:
raise ValueError(
f"Unit of measurement string too long ({len(value)} chars, "
f"max {UNIT_OF_MEASUREMENT_MAX_LENGTH}): '{value}'"
)
return _register_string(value, _get_pool().units, _MAX_UNITS, "unit_of_measurement")
+86 -12
View File
@@ -156,6 +156,16 @@ class TypeInfo(ABC):
"""Check if this field should always be encoded (skip zero/empty check)."""
return get_field_opt(self._field, pb.force, False)
@property
def max_value(self) -> int | None:
"""Get the max_value option for this field, or None if not set."""
return get_field_opt(self._field, pb.max_value, None)
@property
def max_data_length(self) -> int | None:
"""Get the max_data_length option for this field, or None if not set."""
return get_field_opt(self._field, pb.max_data_length, None)
@property
def wire_type(self) -> WireType:
"""Get the wire type for the field."""
@@ -235,37 +245,56 @@ class TypeInfo(ABC):
"encode_bool": "buffer.write_raw_byte({value} ? 0x01 : 0x00);",
}
# When max_value < 128, the varint is always 1 byte — use a direct byte write
RAW_ENCODE_SMALL_MAP: dict[str, str] = {
"encode_uint32": "buffer.write_raw_byte(static_cast<uint8_t>({value}));",
"encode_uint64": "buffer.write_raw_byte(static_cast<uint8_t>({value}));",
}
def _encode_with_precomputed_tag(self, value_expr: str) -> str | None:
"""Try to emit a precomputed-tag encode for a forced field.
Returns the raw encode string if the tag is a single byte and the
encode_func has a known raw equivalent, or None otherwise.
When max_value < 128, uses direct byte write instead of varint encoding.
"""
if not self.force:
return None
tag = self.calculate_tag()
if tag >= 128:
return None
raw_expr = self.RAW_ENCODE_MAP.get(self.encode_func)
max_val = self.max_value
raw_expr = None
if max_val is not None and max_val < 128:
raw_expr = self.RAW_ENCODE_SMALL_MAP.get(self.encode_func)
if raw_expr is None:
raw_expr = self.RAW_ENCODE_MAP.get(self.encode_func)
if raw_expr is None:
return None
return f"buffer.write_raw_byte({tag});\n{raw_expr.format(value=value_expr)}"
def _encode_bytes_with_precomputed_tag(
self, data_expr: str, len_expr: str
self, data_expr: str, len_expr: str, max_len: int | None = None
) -> str | None:
"""Try to emit a precomputed-tag encode for a forced bytes/string field.
Returns the raw encode string if the tag is a single byte, or None.
When max_len < 128, uses direct byte write for the length varint.
"""
if not self.force:
return None
tag = self.calculate_tag()
if tag >= 128:
return None
# When max_len < 128, length varint is always 1 byte
len_encode = (
f"buffer.write_raw_byte(static_cast<uint8_t>({len_expr}));"
if max_len is not None and max_len < 128
else f"buffer.encode_varint_raw({len_expr});"
)
return (
f"buffer.write_raw_byte({tag});\n"
f"buffer.encode_varint_raw({len_expr});\n"
f"{len_encode}\n"
f"buffer.encode_raw({data_expr}, {len_expr});"
)
@@ -346,6 +375,31 @@ class TypeInfo(ABC):
value = value_expr or name
return f"size += ProtoSize::{method}({field_id_size}, {value});"
def _get_single_byte_varint_size(
self,
name: str,
force: bool,
extra_expr: str | None = None,
zero_check: str | None = None,
) -> str:
"""Size calculation when the varint is guaranteed to be 1 byte.
Used when max_value < 128 or fixed_array_size < 128.
The fixed part is field_id_size + 1 (tag + 1-byte varint).
Args:
name: Expression to check for zero (non-force only)
force: Whether to skip the zero check
extra_expr: Additional variable expression to add (e.g., data length)
zero_check: Override expression for the zero check (e.g., "!x.empty()")
"""
fixed = self.calculate_field_id_size() + 1
size_expr = f"{fixed} + {extra_expr}" if extra_expr else str(fixed)
if force:
return f"size += {size_expr};"
check = zero_check or name
return f"size += {check} ? {size_expr} : 0;"
@abstractmethod
def get_size_calculation(self, name: str, force: bool = False) -> str:
"""Calculate the size needed for encoding this field.
@@ -1020,8 +1074,14 @@ class PointerToStringBufferType(PointerToBufferTypeBase):
@property
def encode_content(self) -> str:
max_len = self.max_data_length
if max_len is not None and max_len < 128 and self.force:
tag = self.calculate_tag()
if tag < 128:
return f"buffer.write_short_string({tag}, this->{self.field_name});"
if result := self._encode_bytes_with_precomputed_tag(
f"this->{self.field_name}.c_str()", f"this->{self.field_name}.size()"
f"this->{self.field_name}.c_str()",
f"this->{self.field_name}.size()",
):
return result
if self.force:
@@ -1046,7 +1106,16 @@ class PointerToStringBufferType(PointerToBufferTypeBase):
return f'dump_field(out, ESPHOME_PSTR("{self.name}"), this->{self.field_name});'
def get_size_calculation(self, name: str, force: bool = False) -> str:
return f"size += ProtoSize::calc_length({self.calculate_field_id_size()}, this->{self.field_name}.size());"
size_field = f"this->{self.field_name}.size()"
max_len = self.max_data_length
if max_len is not None and max_len < 128:
return self._get_single_byte_varint_size(
size_field,
force,
extra_expr=size_field,
zero_check=f"!this->{self.field_name}.empty()",
)
return self._get_simple_size_calculation(size_field, force, "length")
def get_estimated_size(self) -> int:
return self.calculate_field_id_size() + 8 # field ID + 8 bytes typical string
@@ -1191,8 +1260,9 @@ class FixedArrayBytesType(TypeInfo):
@property
def encode_content(self) -> str:
max_len = self.array_size if isinstance(self.array_size, int) else None
if result := self._encode_bytes_with_precomputed_tag(
f"this->{self.field_name}", f"this->{self.field_name}_len"
f"this->{self.field_name}", f"this->{self.field_name}_len", max_len=max_len
):
return result
if self.force:
@@ -1212,13 +1282,14 @@ class FixedArrayBytesType(TypeInfo):
def get_size_calculation(self, name: str, force: bool = False) -> str:
# Use the actual length stored in the _len field
length_field = f"this->{self.field_name}_len"
field_id_size = self.calculate_field_id_size()
if force:
# For repeated fields, always calculate size (no zero check)
return f"size += ProtoSize::calc_length_force({field_id_size}, {length_field});"
# For non-repeated fields, length already checks for zero
return f"size += ProtoSize::calc_length({field_id_size}, {length_field});"
# When array_size < 128, length varint is always 1 byte
if isinstance(self.array_size, int) and self.array_size < 128:
return self._get_single_byte_varint_size(
length_field, force, extra_expr=length_field
)
return self._get_simple_size_calculation(length_field, force, "length")
def get_estimated_size(self) -> int:
# Estimate based on typical BLE advertisement size
@@ -1245,6 +1316,9 @@ class UInt32Type(TypeInfo):
return o
def get_size_calculation(self, name: str, force: bool = False) -> str:
max_val = self.max_value
if max_val is not None and max_val < 128:
return self._get_single_byte_varint_size(name, force)
return self._get_simple_size_calculation(name, force, "uint32")
def get_estimated_size(self) -> int:
@@ -28,6 +28,7 @@ from esphome.core.entity_helpers import (
get_base_entity_object_id,
register_device_class,
register_icon,
register_unit_of_measurement,
setup_device_class,
setup_entity,
setup_unit_of_measurement,
@@ -925,6 +926,22 @@ def test_register_device_class_max_length() -> None:
assert register_device_class("") == 0
def test_register_unit_of_measurement_max_length() -> None:
"""Test register_unit_of_measurement rejects units exceeding 63 characters."""
# 63 chars should succeed
max_uom = "a" * 63
idx = register_unit_of_measurement(max_uom)
assert idx > 0
# 64 chars should fail
too_long = "a" * 64
with pytest.raises(ValueError, match="Unit of measurement string too long"):
register_unit_of_measurement(too_long)
# Empty string returns 0
assert register_unit_of_measurement("") == 0
@pytest.mark.asyncio
async def test_setup_entity_with_entity_category(
setup_test_environment: list[str],