mirror of
https://github.com/esphome/esphome.git
synced 2026-09-16 01:28:39 +00:00
Merge remote-tracking branch 'upstream/dev' into devirtualize-decode
This commit is contained in:
@@ -56,6 +56,10 @@ _COMPONENT_PREFIX_LIB = "[lib]"
|
||||
_COMPONENT_CORE = f"{_COMPONENT_PREFIX_ESPHOME}core"
|
||||
_COMPONENT_API = f"{_COMPONENT_PREFIX_ESPHOME}api"
|
||||
|
||||
# Placement new storage suffix (generated by codegen Pvariable)
|
||||
_PSTORAGE_SUFFIX = "__pstorage"
|
||||
|
||||
|
||||
# C++ namespace prefixes
|
||||
_NAMESPACE_ESPHOME = "esphome::"
|
||||
_NAMESPACE_STD = "std::"
|
||||
@@ -332,6 +336,13 @@ class MemoryAnalyzer:
|
||||
# Demangle C++ names if needed
|
||||
demangled = self._demangle_symbol(symbol_name)
|
||||
|
||||
# Check for placement new storage symbols (generated by codegen)
|
||||
# Format: {component}__{id}__pstorage
|
||||
if demangled.endswith(_PSTORAGE_SUFFIX) and (
|
||||
component := self._match_pstorage_component(demangled)
|
||||
):
|
||||
return component
|
||||
|
||||
# Check for special component classes first (before namespace pattern)
|
||||
# This handles cases like esphome::ESPHomeOTAComponent which should map to ota
|
||||
if _NAMESPACE_ESPHOME in demangled:
|
||||
@@ -399,6 +410,24 @@ class MemoryAnalyzer:
|
||||
# Track uncategorized symbols for analysis
|
||||
return "other"
|
||||
|
||||
def _match_pstorage_component(self, symbol_name: str) -> str | None:
|
||||
"""Match a __pstorage symbol to its ESPHome component.
|
||||
|
||||
Symbol format: {component}__{id}__pstorage
|
||||
The component namespace is embedded by codegen before the double underscore.
|
||||
"""
|
||||
prefix = symbol_name[: -len(_PSTORAGE_SUFFIX)]
|
||||
# Extract component namespace before the first double underscore
|
||||
dunder_pos = prefix.find("__")
|
||||
if dunder_pos == -1:
|
||||
return None
|
||||
component_name = prefix[:dunder_pos]
|
||||
if component_name in get_esphome_components():
|
||||
return f"{_COMPONENT_PREFIX_ESPHOME}{component_name}"
|
||||
if component_name in self.external_components:
|
||||
return f"{_COMPONENT_PREFIX_EXTERNAL}{component_name}"
|
||||
return None
|
||||
|
||||
def _batch_demangle_symbols(self, symbols: list[str]) -> None:
|
||||
"""Batch demangle C++ symbol names for efficiency."""
|
||||
if not symbols:
|
||||
|
||||
@@ -15,6 +15,7 @@ from . import (
|
||||
_COMPONENT_PREFIX_ESPHOME,
|
||||
_COMPONENT_PREFIX_EXTERNAL,
|
||||
_COMPONENT_PREFIX_LIB,
|
||||
_PSTORAGE_SUFFIX,
|
||||
RAM_SECTIONS,
|
||||
MemoryAnalyzer,
|
||||
)
|
||||
@@ -23,6 +24,17 @@ if TYPE_CHECKING:
|
||||
from . import ComponentMemory
|
||||
|
||||
|
||||
def _format_pstorage_name(name: str) -> str:
|
||||
"""Format a __pstorage symbol as 'storage for {id}'."""
|
||||
if not name.endswith(_PSTORAGE_SUFFIX):
|
||||
return name
|
||||
prefix = name[: -len(_PSTORAGE_SUFFIX)]
|
||||
# Strip component namespace prefix: {component}__{id} -> {id}
|
||||
dunder_pos = prefix.find("__")
|
||||
var_id = prefix[dunder_pos + 2 :] if dunder_pos != -1 else prefix
|
||||
return f"storage for {var_id}"
|
||||
|
||||
|
||||
class MemoryAnalyzerCLI(MemoryAnalyzer):
|
||||
"""Memory analyzer with CLI-specific report generation."""
|
||||
|
||||
@@ -148,11 +160,14 @@ class MemoryAnalyzerCLI(MemoryAnalyzer):
|
||||
If section is one of the RAM sections (.data or .bss), a label like
|
||||
" [data]" or " [bss]" is appended. For non-RAM sections or when
|
||||
section is None, no section label is added.
|
||||
|
||||
Placement new storage symbols are formatted as "storage for {id}".
|
||||
"""
|
||||
display_name = _format_pstorage_name(demangled)
|
||||
section_label = ""
|
||||
if section in RAM_SECTIONS:
|
||||
section_label = f" [{section[1:]}]" # .data -> [data], .bss -> [bss]
|
||||
return f"{demangled} ({size:,} B){section_label}"
|
||||
return f"{display_name} ({size:,} B){section_label}"
|
||||
|
||||
def _add_top_symbols(self, lines: list[str]) -> None:
|
||||
"""Add a section showing the top largest symbols in the binary."""
|
||||
@@ -175,11 +190,13 @@ class MemoryAnalyzerCLI(MemoryAnalyzer):
|
||||
for i, (_, demangled, size, section, component) in enumerate(top_symbols):
|
||||
# Format section label
|
||||
section_label = f"[{section[1:]}]" if section else ""
|
||||
# Truncate demangled name if too long
|
||||
# Format storage symbols readably
|
||||
display_name = _format_pstorage_name(demangled)
|
||||
# Truncate if too long
|
||||
demangled_display = (
|
||||
f"{demangled[:truncate_limit]}..."
|
||||
if len(demangled) > self.COL_TOP_SYMBOL_NAME
|
||||
else demangled
|
||||
f"{display_name[:truncate_limit]}..."
|
||||
if len(display_name) > self.COL_TOP_SYMBOL_NAME
|
||||
else display_name
|
||||
)
|
||||
lines.append(
|
||||
f"{i + 1:>2}. {size:>7,} B {section_label:<8} {demangled_display:<{self.COL_TOP_SYMBOL_NAME}} {component}"
|
||||
@@ -573,15 +590,16 @@ class MemoryAnalyzerCLI(MemoryAnalyzer):
|
||||
lines.append(f"Total size: {comp_mem.flash_total:,} B")
|
||||
lines.append("")
|
||||
|
||||
# Show all symbols above threshold for better visibility
|
||||
# Show symbols above threshold, always include storage symbols
|
||||
large_symbols = [
|
||||
(sym, dem, size, sec)
|
||||
for sym, dem, size, sec in sorted_symbols
|
||||
if size > self.SYMBOL_SIZE_THRESHOLD
|
||||
or dem.endswith(_PSTORAGE_SUFFIX)
|
||||
]
|
||||
|
||||
lines.append(
|
||||
f"{comp_name} Symbols > {self.SYMBOL_SIZE_THRESHOLD} B ({len(large_symbols)} symbols):"
|
||||
f"{comp_name} Symbols > {self.SYMBOL_SIZE_THRESHOLD} B & storage ({len(large_symbols)} symbols):"
|
||||
)
|
||||
for i, (symbol, demangled, size, section) in enumerate(large_symbols):
|
||||
lines.append(
|
||||
@@ -604,7 +622,10 @@ class MemoryAnalyzerCLI(MemoryAnalyzer):
|
||||
# Sort by size descending
|
||||
sorted_ram_syms = sorted(ram_syms, key=lambda x: x[2], reverse=True)
|
||||
large_ram_syms = [
|
||||
s for s in sorted_ram_syms if s[2] > self.RAM_SYMBOL_SIZE_THRESHOLD
|
||||
s
|
||||
for s in sorted_ram_syms
|
||||
if s[2] > self.RAM_SYMBOL_SIZE_THRESHOLD
|
||||
or s[1].endswith(_PSTORAGE_SUFFIX)
|
||||
]
|
||||
|
||||
lines.append(f"{name} ({mem.ram_total:,} B total RAM):")
|
||||
@@ -622,13 +643,14 @@ class MemoryAnalyzerCLI(MemoryAnalyzer):
|
||||
for symbol, demangled, size, section in large_ram_syms[:10]:
|
||||
# Format section label consistently by stripping leading dot
|
||||
section_label = section.lstrip(".") if section else ""
|
||||
display_name = _format_pstorage_name(demangled)
|
||||
# Add ellipsis if name is truncated
|
||||
demangled_display = (
|
||||
f"{demangled[:70]}..." if len(demangled) > 70 else demangled
|
||||
)
|
||||
lines.append(
|
||||
f" {size:>6,} B [{section_label}] {demangled_display}"
|
||||
display_name = (
|
||||
f"{display_name[:70]}..."
|
||||
if len(display_name) > 70
|
||||
else display_name
|
||||
)
|
||||
lines.append(f" {size:>6,} B [{section_label}] {display_name}")
|
||||
if len(large_ram_syms) > 10:
|
||||
lines.append(f" ... and {len(large_ram_syms) - 10} more")
|
||||
lines.append("")
|
||||
|
||||
@@ -316,7 +316,7 @@ message ListEntitiesBinarySensorResponse {
|
||||
option (ifdef) = "USE_BINARY_SENSOR";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -334,7 +334,7 @@ message BinarySensorStateResponse {
|
||||
option (ifdef) = "USE_BINARY_SENSOR";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
bool state = 2;
|
||||
// If the binary sensor does not have a valid state yet.
|
||||
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
|
||||
@@ -350,7 +350,7 @@ message ListEntitiesCoverResponse {
|
||||
option (ifdef) = "USE_COVER";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -383,7 +383,7 @@ message CoverStateResponse {
|
||||
option (ifdef) = "USE_COVER";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
// legacy: state has been removed in 1.13
|
||||
// clients/servers must still send/accept it until the next protocol change
|
||||
// Deprecated in API version 1.1
|
||||
@@ -409,7 +409,7 @@ message CoverCommandRequest {
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
|
||||
// legacy: command has been removed in 1.13
|
||||
// clients/servers must still send/accept it until the next protocol change
|
||||
@@ -434,7 +434,7 @@ message ListEntitiesFanResponse {
|
||||
option (ifdef) = "USE_FAN";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -466,7 +466,7 @@ message FanStateResponse {
|
||||
option (ifdef) = "USE_FAN";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
bool state = 2;
|
||||
bool oscillating = 3;
|
||||
// Deprecated in API version 1.6
|
||||
@@ -483,7 +483,7 @@ message FanCommandRequest {
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
bool has_state = 2;
|
||||
bool state = 3;
|
||||
// Deprecated in API version 1.6
|
||||
@@ -522,7 +522,7 @@ message ListEntitiesLightResponse {
|
||||
option (ifdef) = "USE_LIGHT";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -551,7 +551,7 @@ message LightStateResponse {
|
||||
option (ifdef) = "USE_LIGHT";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
bool state = 2;
|
||||
float brightness = 3;
|
||||
ColorMode color_mode = 11;
|
||||
@@ -573,7 +573,7 @@ message LightCommandRequest {
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
bool has_state = 2;
|
||||
bool state = 3;
|
||||
bool has_brightness = 4;
|
||||
@@ -627,7 +627,7 @@ message ListEntitiesSensorResponse {
|
||||
option (ifdef) = "USE_SENSOR";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -651,7 +651,7 @@ message SensorStateResponse {
|
||||
option (ifdef) = "USE_SENSOR";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
float state = 2;
|
||||
// If the sensor does not have a valid state yet.
|
||||
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
|
||||
@@ -667,7 +667,7 @@ message ListEntitiesSwitchResponse {
|
||||
option (ifdef) = "USE_SWITCH";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -685,7 +685,7 @@ message SwitchStateResponse {
|
||||
option (ifdef) = "USE_SWITCH";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
bool state = 2;
|
||||
uint32 device_id = 3 [(field_ifdef) = "USE_DEVICES"];
|
||||
}
|
||||
@@ -696,7 +696,7 @@ message SwitchCommandRequest {
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
bool state = 2;
|
||||
uint32 device_id = 3 [(field_ifdef) = "USE_DEVICES"];
|
||||
}
|
||||
@@ -709,7 +709,7 @@ message ListEntitiesTextSensorResponse {
|
||||
option (ifdef) = "USE_TEXT_SENSOR";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -726,7 +726,7 @@ message TextSensorStateResponse {
|
||||
option (ifdef) = "USE_TEXT_SENSOR";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
string state = 2;
|
||||
// If the text sensor does not have a valid state yet.
|
||||
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
|
||||
@@ -922,7 +922,7 @@ message ListEntitiesServicesResponse {
|
||||
option (ifdef) = "USE_API_USER_DEFINED_ACTIONS";
|
||||
|
||||
string name = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
repeated ListEntitiesServicesArgument args = 3 [(fixed_vector) = true];
|
||||
SupportsResponseType supports_response = 4;
|
||||
}
|
||||
@@ -945,7 +945,7 @@ message ExecuteServiceRequest {
|
||||
option (no_delay) = true;
|
||||
option (ifdef) = "USE_API_USER_DEFINED_ACTIONS";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
repeated ExecuteServiceArgument args = 2 [(fixed_vector) = true];
|
||||
uint32 call_id = 3 [(field_ifdef) = "USE_API_USER_DEFINED_ACTION_RESPONSES"];
|
||||
bool return_response = 4 [(field_ifdef) = "USE_API_USER_DEFINED_ACTION_RESPONSES"];
|
||||
@@ -972,7 +972,7 @@ message ListEntitiesCameraResponse {
|
||||
option (ifdef) = "USE_CAMERA";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
bool disabled_by_default = 5;
|
||||
@@ -987,7 +987,7 @@ message CameraImageResponse {
|
||||
option (source) = SOURCE_SERVER;
|
||||
option (ifdef) = "USE_CAMERA";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
bytes data = 2;
|
||||
bool done = 3;
|
||||
uint32 device_id = 4 [(field_ifdef) = "USE_DEVICES"];
|
||||
@@ -1057,7 +1057,7 @@ message ListEntitiesClimateResponse {
|
||||
option (ifdef) = "USE_CLIMATE";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -1095,7 +1095,7 @@ message ClimateStateResponse {
|
||||
option (ifdef) = "USE_CLIMATE";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
ClimateMode mode = 2;
|
||||
float current_temperature = 3;
|
||||
float target_temperature = 4;
|
||||
@@ -1121,7 +1121,7 @@ message ClimateCommandRequest {
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
bool has_mode = 2;
|
||||
ClimateMode mode = 3;
|
||||
bool has_target_temperature = 4;
|
||||
@@ -1168,7 +1168,7 @@ message ListEntitiesWaterHeaterResponse {
|
||||
option (ifdef) = "USE_WATER_HEATER";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
string icon = 4 [(field_ifdef) = "USE_ENTITY_ICON"];
|
||||
bool disabled_by_default = 5;
|
||||
@@ -1189,7 +1189,7 @@ message WaterHeaterStateResponse {
|
||||
option (ifdef) = "USE_WATER_HEATER";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
float current_temperature = 2;
|
||||
float target_temperature = 3;
|
||||
WaterHeaterMode mode = 4;
|
||||
@@ -1219,7 +1219,7 @@ message WaterHeaterCommandRequest {
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
// Bitmask of which fields are set (see WaterHeaterCommandHasField)
|
||||
uint32 has_fields = 2;
|
||||
WaterHeaterMode mode = 3;
|
||||
@@ -1244,7 +1244,7 @@ message ListEntitiesNumberResponse {
|
||||
option (ifdef) = "USE_NUMBER";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -1266,7 +1266,7 @@ message NumberStateResponse {
|
||||
option (ifdef) = "USE_NUMBER";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
float state = 2;
|
||||
// If the number does not have a valid state yet.
|
||||
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
|
||||
@@ -1280,7 +1280,7 @@ message NumberCommandRequest {
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
float state = 2;
|
||||
uint32 device_id = 3 [(field_ifdef) = "USE_DEVICES"];
|
||||
}
|
||||
@@ -1293,7 +1293,7 @@ message ListEntitiesSelectResponse {
|
||||
option (ifdef) = "USE_SELECT";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -1310,7 +1310,7 @@ message SelectStateResponse {
|
||||
option (ifdef) = "USE_SELECT";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
string state = 2;
|
||||
// If the select does not have a valid state yet.
|
||||
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
|
||||
@@ -1324,7 +1324,7 @@ message SelectCommandRequest {
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
string state = 2;
|
||||
uint32 device_id = 3 [(field_ifdef) = "USE_DEVICES"];
|
||||
}
|
||||
@@ -1337,7 +1337,7 @@ message ListEntitiesSirenResponse {
|
||||
option (ifdef) = "USE_SIREN";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -1356,7 +1356,7 @@ message SirenStateResponse {
|
||||
option (ifdef) = "USE_SIREN";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
bool state = 2;
|
||||
uint32 device_id = 3 [(field_ifdef) = "USE_DEVICES"];
|
||||
}
|
||||
@@ -1367,7 +1367,7 @@ message SirenCommandRequest {
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
bool has_state = 2;
|
||||
bool state = 3;
|
||||
bool has_tone = 4;
|
||||
@@ -1400,7 +1400,7 @@ message ListEntitiesLockResponse {
|
||||
option (ifdef) = "USE_LOCK";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -1422,7 +1422,7 @@ message LockStateResponse {
|
||||
option (source) = SOURCE_SERVER;
|
||||
option (ifdef) = "USE_LOCK";
|
||||
option (no_delay) = true;
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
LockState state = 2;
|
||||
uint32 device_id = 3 [(field_ifdef) = "USE_DEVICES"];
|
||||
}
|
||||
@@ -1432,7 +1432,7 @@ message LockCommandRequest {
|
||||
option (ifdef) = "USE_LOCK";
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
LockCommand command = 2;
|
||||
|
||||
// Not yet implemented:
|
||||
@@ -1449,7 +1449,7 @@ message ListEntitiesButtonResponse {
|
||||
option (ifdef) = "USE_BUTTON";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -1466,7 +1466,7 @@ message ButtonCommandRequest {
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
uint32 device_id = 2 [(field_ifdef) = "USE_DEVICES"];
|
||||
}
|
||||
|
||||
@@ -1516,7 +1516,7 @@ message ListEntitiesMediaPlayerResponse {
|
||||
option (ifdef) = "USE_MEDIA_PLAYER";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -1538,7 +1538,7 @@ message MediaPlayerStateResponse {
|
||||
option (source) = SOURCE_SERVER;
|
||||
option (ifdef) = "USE_MEDIA_PLAYER";
|
||||
option (no_delay) = true;
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
MediaPlayerState state = 2;
|
||||
float volume = 3;
|
||||
bool muted = 4;
|
||||
@@ -1551,7 +1551,7 @@ message MediaPlayerCommandRequest {
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
|
||||
bool has_command = 2;
|
||||
MediaPlayerCommand command = 3;
|
||||
@@ -2104,7 +2104,7 @@ message ListEntitiesAlarmControlPanelResponse {
|
||||
option (ifdef) = "USE_ALARM_CONTROL_PANEL";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
|
||||
@@ -2122,7 +2122,7 @@ message AlarmControlPanelStateResponse {
|
||||
option (source) = SOURCE_SERVER;
|
||||
option (ifdef) = "USE_ALARM_CONTROL_PANEL";
|
||||
option (no_delay) = true;
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
AlarmControlPanelState state = 2;
|
||||
uint32 device_id = 3 [(field_ifdef) = "USE_DEVICES"];
|
||||
}
|
||||
@@ -2133,7 +2133,7 @@ message AlarmControlPanelCommandRequest {
|
||||
option (ifdef) = "USE_ALARM_CONTROL_PANEL";
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
AlarmControlPanelStateCommand command = 2;
|
||||
string code = 3;
|
||||
uint32 device_id = 4 [(field_ifdef) = "USE_DEVICES"];
|
||||
@@ -2151,7 +2151,7 @@ message ListEntitiesTextResponse {
|
||||
option (ifdef) = "USE_TEXT";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON"];
|
||||
@@ -2171,7 +2171,7 @@ message TextStateResponse {
|
||||
option (ifdef) = "USE_TEXT";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
string state = 2;
|
||||
// If the Text does not have a valid state yet.
|
||||
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
|
||||
@@ -2185,7 +2185,7 @@ message TextCommandRequest {
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
string state = 2;
|
||||
uint32 device_id = 3 [(field_ifdef) = "USE_DEVICES"];
|
||||
}
|
||||
@@ -2199,7 +2199,7 @@ message ListEntitiesDateResponse {
|
||||
option (ifdef) = "USE_DATETIME_DATE";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -2215,7 +2215,7 @@ message DateStateResponse {
|
||||
option (ifdef) = "USE_DATETIME_DATE";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
// If the date does not have a valid state yet.
|
||||
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
|
||||
bool missing_state = 2;
|
||||
@@ -2231,7 +2231,7 @@ message DateCommandRequest {
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
uint32 year = 2;
|
||||
uint32 month = 3;
|
||||
uint32 day = 4;
|
||||
@@ -2246,7 +2246,7 @@ message ListEntitiesTimeResponse {
|
||||
option (ifdef) = "USE_DATETIME_TIME";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -2262,7 +2262,7 @@ message TimeStateResponse {
|
||||
option (ifdef) = "USE_DATETIME_TIME";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
// If the time does not have a valid state yet.
|
||||
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
|
||||
bool missing_state = 2;
|
||||
@@ -2278,7 +2278,7 @@ message TimeCommandRequest {
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
uint32 hour = 2;
|
||||
uint32 minute = 3;
|
||||
uint32 second = 4;
|
||||
@@ -2293,7 +2293,7 @@ message ListEntitiesEventResponse {
|
||||
option (ifdef) = "USE_EVENT";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -2311,7 +2311,7 @@ message EventResponse {
|
||||
option (source) = SOURCE_SERVER;
|
||||
option (ifdef) = "USE_EVENT";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
string event_type = 2;
|
||||
uint32 device_id = 3 [(field_ifdef) = "USE_DEVICES"];
|
||||
}
|
||||
@@ -2324,7 +2324,7 @@ message ListEntitiesValveResponse {
|
||||
option (ifdef) = "USE_VALVE";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -2351,7 +2351,7 @@ message ValveStateResponse {
|
||||
option (ifdef) = "USE_VALVE";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
float position = 2;
|
||||
ValveOperation current_operation = 3;
|
||||
uint32 device_id = 4 [(field_ifdef) = "USE_DEVICES"];
|
||||
@@ -2364,7 +2364,7 @@ message ValveCommandRequest {
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
bool has_position = 2;
|
||||
float position = 3;
|
||||
bool stop = 4;
|
||||
@@ -2379,7 +2379,7 @@ message ListEntitiesDateTimeResponse {
|
||||
option (ifdef) = "USE_DATETIME_DATETIME";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -2395,7 +2395,7 @@ message DateTimeStateResponse {
|
||||
option (ifdef) = "USE_DATETIME_DATETIME";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
// If the datetime does not have a valid state yet.
|
||||
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
|
||||
bool missing_state = 2;
|
||||
@@ -2409,7 +2409,7 @@ message DateTimeCommandRequest {
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
fixed32 epoch_seconds = 2;
|
||||
uint32 device_id = 3 [(field_ifdef) = "USE_DEVICES"];
|
||||
}
|
||||
@@ -2422,7 +2422,7 @@ message ListEntitiesUpdateResponse {
|
||||
option (ifdef) = "USE_UPDATE";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
reserved 4; // Deprecated: was string unique_id
|
||||
|
||||
@@ -2439,7 +2439,7 @@ message UpdateStateResponse {
|
||||
option (ifdef) = "USE_UPDATE";
|
||||
option (no_delay) = true;
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
bool missing_state = 2;
|
||||
bool in_progress = 3;
|
||||
bool has_progress = 4;
|
||||
@@ -2463,7 +2463,7 @@ message UpdateCommandRequest {
|
||||
option (no_delay) = true;
|
||||
option (base_class) = "CommandProtoMessage";
|
||||
|
||||
fixed32 key = 1;
|
||||
fixed32 key = 1 [(force) = true];
|
||||
UpdateCommand command = 2;
|
||||
uint32 device_id = 3 [(field_ifdef) = "USE_DEVICES"];
|
||||
}
|
||||
@@ -2505,7 +2505,7 @@ message ListEntitiesInfraredResponse {
|
||||
option (ifdef) = "USE_INFRARED";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
fixed32 key = 2 [(force) = true];
|
||||
string name = 3;
|
||||
string icon = 4 [(field_ifdef) = "USE_ENTITY_ICON"];
|
||||
bool disabled_by_default = 5;
|
||||
@@ -2521,7 +2521,7 @@ message InfraredRFTransmitRawTimingsRequest {
|
||||
option (ifdef) = "USE_IR_RF";
|
||||
|
||||
uint32 device_id = 1 [(field_ifdef) = "USE_DEVICES"];
|
||||
fixed32 key = 2; // Key identifying the transmitter instance
|
||||
fixed32 key = 2 [(force) = true]; // Key identifying the transmitter instance
|
||||
uint32 carrier_frequency = 3; // Carrier frequency in Hz
|
||||
uint32 repeat_count = 4; // Number of times to transmit (1 = once, 2 = twice, etc.)
|
||||
repeated sint32 timings = 5 [packed = true, (packed_buffer) = true]; // Raw timings in microseconds (zigzag-encoded): positive = mark (LED/TX on), negative = space (LED/TX off)
|
||||
@@ -2535,7 +2535,7 @@ message InfraredRFReceiveEvent {
|
||||
option (no_delay) = true;
|
||||
|
||||
uint32 device_id = 1 [(field_ifdef) = "USE_DEVICES"];
|
||||
fixed32 key = 2; // Key identifying the receiver instance
|
||||
fixed32 key = 2 [(force) = true]; // Key identifying the receiver instance
|
||||
repeated sint32 timings = 3 [packed = true, (container_pointer_no_template) = "std::vector<int32_t>"]; // Raw timings in microseconds (zigzag-encoded): alternating mark/space periods
|
||||
}
|
||||
|
||||
|
||||
@@ -1519,16 +1519,16 @@ void APIConnection::on_serial_proxy_request(const SerialProxyRequest &msg) {
|
||||
resp.instance = msg.instance;
|
||||
resp.type = enums::SERIAL_PROXY_REQUEST_TYPE_FLUSH;
|
||||
switch (proxies[msg.instance]->flush_port()) {
|
||||
case uart::FlushResult::SUCCESS:
|
||||
case uart::UARTFlushResult::UART_FLUSH_RESULT_SUCCESS:
|
||||
resp.status = enums::SERIAL_PROXY_STATUS_OK;
|
||||
break;
|
||||
case uart::FlushResult::ASSUMED_SUCCESS:
|
||||
case uart::UARTFlushResult::UART_FLUSH_RESULT_ASSUMED_SUCCESS:
|
||||
resp.status = enums::SERIAL_PROXY_STATUS_ASSUMED_SUCCESS;
|
||||
break;
|
||||
case uart::FlushResult::TIMEOUT:
|
||||
case uart::UARTFlushResult::UART_FLUSH_RESULT_TIMEOUT:
|
||||
resp.status = enums::SERIAL_PROXY_STATUS_TIMEOUT;
|
||||
break;
|
||||
case uart::FlushResult::FAILED:
|
||||
case uart::UARTFlushResult::UART_FLUSH_RESULT_FAILED:
|
||||
resp.status = enums::SERIAL_PROXY_STATUS_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
+100
-100
@@ -208,7 +208,7 @@ uint32_t DeviceInfoResponse::calculate_size() const {
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
void ListEntitiesBinarySensorResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
buffer.encode_string(5, this->device_class);
|
||||
buffer.encode_bool(6, this->is_status_binary_sensor);
|
||||
@@ -224,7 +224,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
size += ProtoSize::calc_length(1, this->device_class.size());
|
||||
size += ProtoSize::calc_bool(1, this->is_status_binary_sensor);
|
||||
@@ -239,7 +239,7 @@ uint32_t ListEntitiesBinarySensorResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void BinarySensorStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_bool(2, this->state);
|
||||
buffer.encode_bool(3, this->missing_state);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -248,7 +248,7 @@ void BinarySensorStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t BinarySensorStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_bool(1, this->state);
|
||||
size += ProtoSize::calc_bool(1, this->missing_state);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -260,7 +260,7 @@ uint32_t BinarySensorStateResponse::calculate_size() const {
|
||||
#ifdef USE_COVER
|
||||
void ListEntitiesCoverResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
buffer.encode_bool(5, this->assumed_state);
|
||||
buffer.encode_bool(6, this->supports_position);
|
||||
@@ -279,7 +279,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
size += ProtoSize::calc_bool(1, this->assumed_state);
|
||||
size += ProtoSize::calc_bool(1, this->supports_position);
|
||||
@@ -297,7 +297,7 @@ uint32_t ListEntitiesCoverResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void CoverStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_float(3, this->position);
|
||||
buffer.encode_float(4, this->tilt);
|
||||
buffer.encode_uint32(5, static_cast<uint32_t>(this->current_operation));
|
||||
@@ -307,7 +307,7 @@ void CoverStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t CoverStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_float(1, this->position);
|
||||
size += ProtoSize::calc_float(1, this->tilt);
|
||||
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->current_operation));
|
||||
@@ -357,7 +357,7 @@ bool CoverCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
#ifdef USE_FAN
|
||||
void ListEntitiesFanResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
buffer.encode_bool(5, this->supports_oscillation);
|
||||
buffer.encode_bool(6, this->supports_speed);
|
||||
@@ -378,7 +378,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
size += ProtoSize::calc_bool(1, this->supports_oscillation);
|
||||
size += ProtoSize::calc_bool(1, this->supports_speed);
|
||||
@@ -400,7 +400,7 @@ uint32_t ListEntitiesFanResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void FanStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_bool(2, this->state);
|
||||
buffer.encode_bool(3, this->oscillating);
|
||||
buffer.encode_uint32(5, static_cast<uint32_t>(this->direction));
|
||||
@@ -412,7 +412,7 @@ void FanStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t FanStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_bool(1, this->state);
|
||||
size += ProtoSize::calc_bool(1, this->oscillating);
|
||||
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->direction));
|
||||
@@ -487,7 +487,7 @@ bool FanCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
#ifdef USE_LIGHT
|
||||
void ListEntitiesLightResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
for (const auto &it : *this->supported_color_modes) {
|
||||
buffer.encode_uint32(12, static_cast<uint32_t>(it), true);
|
||||
@@ -509,7 +509,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
if (!this->supported_color_modes->empty()) {
|
||||
for (const auto &it : *this->supported_color_modes) {
|
||||
@@ -534,7 +534,7 @@ uint32_t ListEntitiesLightResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void LightStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_bool(2, this->state);
|
||||
buffer.encode_float(3, this->brightness);
|
||||
buffer.encode_uint32(11, static_cast<uint32_t>(this->color_mode));
|
||||
@@ -553,7 +553,7 @@ void LightStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t LightStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_bool(1, this->state);
|
||||
size += ProtoSize::calc_float(1, this->brightness);
|
||||
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->color_mode));
|
||||
@@ -683,7 +683,7 @@ bool LightCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
#ifdef USE_SENSOR
|
||||
void ListEntitiesSensorResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(5, this->icon);
|
||||
@@ -702,7 +702,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -720,7 +720,7 @@ uint32_t ListEntitiesSensorResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void SensorStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_float(2, this->state);
|
||||
buffer.encode_bool(3, this->missing_state);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -729,7 +729,7 @@ void SensorStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t SensorStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_float(1, this->state);
|
||||
size += ProtoSize::calc_bool(1, this->missing_state);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -741,7 +741,7 @@ uint32_t SensorStateResponse::calculate_size() const {
|
||||
#ifdef USE_SWITCH
|
||||
void ListEntitiesSwitchResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(5, this->icon);
|
||||
@@ -757,7 +757,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -772,7 +772,7 @@ uint32_t ListEntitiesSwitchResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void SwitchStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_bool(2, this->state);
|
||||
#ifdef USE_DEVICES
|
||||
buffer.encode_uint32(3, this->device_id);
|
||||
@@ -780,7 +780,7 @@ void SwitchStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t SwitchStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_bool(1, this->state);
|
||||
#ifdef USE_DEVICES
|
||||
size += ProtoSize::calc_uint32(1, this->device_id);
|
||||
@@ -816,7 +816,7 @@ bool SwitchCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
void ListEntitiesTextSensorResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(5, this->icon);
|
||||
@@ -831,7 +831,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -845,7 +845,7 @@ uint32_t ListEntitiesTextSensorResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void TextSensorStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_string(2, this->state);
|
||||
buffer.encode_bool(3, this->missing_state);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -854,7 +854,7 @@ void TextSensorStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t TextSensorStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->state.size());
|
||||
size += ProtoSize::calc_bool(1, this->missing_state);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -1124,7 +1124,7 @@ uint32_t ListEntitiesServicesArgument::calculate_size() const {
|
||||
}
|
||||
void ListEntitiesServicesResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->name);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
for (auto &it : this->args) {
|
||||
buffer.encode_sub_message(3, it);
|
||||
}
|
||||
@@ -1133,7 +1133,7 @@ void ListEntitiesServicesResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
uint32_t ListEntitiesServicesResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
if (!this->args.empty()) {
|
||||
for (const auto &it : this->args) {
|
||||
size += ProtoSize::calc_message_force(1, it.calculate_size());
|
||||
@@ -1269,7 +1269,7 @@ uint32_t ExecuteServiceResponse::calculate_size() const {
|
||||
#ifdef USE_CAMERA
|
||||
void ListEntitiesCameraResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
buffer.encode_bool(5, this->disabled_by_default);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
@@ -1283,7 +1283,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
size += ProtoSize::calc_bool(1, this->disabled_by_default);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
@@ -1296,7 +1296,7 @@ uint32_t ListEntitiesCameraResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void CameraImageResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_bytes(2, this->data_ptr_, this->data_len_);
|
||||
buffer.encode_bool(3, this->done);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -1305,7 +1305,7 @@ void CameraImageResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t CameraImageResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->data_len_);
|
||||
size += ProtoSize::calc_bool(1, this->done);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -1330,7 +1330,7 @@ bool CameraImageRequest::decode_varint(uint32_t field_id, proto_varint_value_t v
|
||||
#ifdef USE_CLIMATE
|
||||
void ListEntitiesClimateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
buffer.encode_bool(5, this->supports_current_temperature);
|
||||
buffer.encode_bool(6, this->supports_two_point_target_temperature);
|
||||
@@ -1374,7 +1374,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
size += ProtoSize::calc_bool(1, this->supports_current_temperature);
|
||||
size += ProtoSize::calc_bool(1, this->supports_two_point_target_temperature);
|
||||
@@ -1429,7 +1429,7 @@ uint32_t ListEntitiesClimateResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void ClimateStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_uint32(2, static_cast<uint32_t>(this->mode));
|
||||
buffer.encode_float(3, this->current_temperature);
|
||||
buffer.encode_float(4, this->target_temperature);
|
||||
@@ -1449,7 +1449,7 @@ void ClimateStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t ClimateStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->mode));
|
||||
size += ProtoSize::calc_float(1, this->current_temperature);
|
||||
size += ProtoSize::calc_float(1, this->target_temperature);
|
||||
@@ -1563,7 +1563,7 @@ bool ClimateCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
#ifdef USE_WATER_HEATER
|
||||
void ListEntitiesWaterHeaterResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(4, this->icon);
|
||||
@@ -1584,7 +1584,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -1606,7 +1606,7 @@ uint32_t ListEntitiesWaterHeaterResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void WaterHeaterStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_float(2, this->current_temperature);
|
||||
buffer.encode_float(3, this->target_temperature);
|
||||
buffer.encode_uint32(4, static_cast<uint32_t>(this->mode));
|
||||
@@ -1619,7 +1619,7 @@ void WaterHeaterStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t WaterHeaterStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_float(1, this->current_temperature);
|
||||
size += ProtoSize::calc_float(1, this->target_temperature);
|
||||
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->mode));
|
||||
@@ -1675,7 +1675,7 @@ bool WaterHeaterCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value
|
||||
#ifdef USE_NUMBER
|
||||
void ListEntitiesNumberResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(5, this->icon);
|
||||
@@ -1695,7 +1695,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -1714,7 +1714,7 @@ uint32_t ListEntitiesNumberResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void NumberStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_float(2, this->state);
|
||||
buffer.encode_bool(3, this->missing_state);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -1723,7 +1723,7 @@ void NumberStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t NumberStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_float(1, this->state);
|
||||
size += ProtoSize::calc_bool(1, this->missing_state);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -1760,7 +1760,7 @@ bool NumberCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
#ifdef USE_SELECT
|
||||
void ListEntitiesSelectResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(5, this->icon);
|
||||
@@ -1777,7 +1777,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -1795,7 +1795,7 @@ uint32_t ListEntitiesSelectResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void SelectStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_string(2, this->state);
|
||||
buffer.encode_bool(3, this->missing_state);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -1804,7 +1804,7 @@ void SelectStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t SelectStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->state.size());
|
||||
size += ProtoSize::calc_bool(1, this->missing_state);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -1849,7 +1849,7 @@ bool SelectCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
#ifdef USE_SIREN
|
||||
void ListEntitiesSirenResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(5, this->icon);
|
||||
@@ -1868,7 +1868,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -1888,7 +1888,7 @@ uint32_t ListEntitiesSirenResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void SirenStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_bool(2, this->state);
|
||||
#ifdef USE_DEVICES
|
||||
buffer.encode_uint32(3, this->device_id);
|
||||
@@ -1896,7 +1896,7 @@ void SirenStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t SirenStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_bool(1, this->state);
|
||||
#ifdef USE_DEVICES
|
||||
size += ProtoSize::calc_uint32(1, this->device_id);
|
||||
@@ -1961,7 +1961,7 @@ bool SirenCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
#ifdef USE_LOCK
|
||||
void ListEntitiesLockResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(5, this->icon);
|
||||
@@ -1979,7 +1979,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -1996,7 +1996,7 @@ uint32_t ListEntitiesLockResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void LockStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_uint32(2, static_cast<uint32_t>(this->state));
|
||||
#ifdef USE_DEVICES
|
||||
buffer.encode_uint32(3, this->device_id);
|
||||
@@ -2004,7 +2004,7 @@ void LockStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t LockStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->state));
|
||||
#ifdef USE_DEVICES
|
||||
size += ProtoSize::calc_uint32(1, this->device_id);
|
||||
@@ -2054,7 +2054,7 @@ bool LockCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
#ifdef USE_BUTTON
|
||||
void ListEntitiesButtonResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(5, this->icon);
|
||||
@@ -2069,7 +2069,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -2124,7 +2124,7 @@ uint32_t MediaPlayerSupportedFormat::calculate_size() const {
|
||||
}
|
||||
void ListEntitiesMediaPlayerResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(5, this->icon);
|
||||
@@ -2143,7 +2143,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -2163,7 +2163,7 @@ uint32_t ListEntitiesMediaPlayerResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void MediaPlayerStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_uint32(2, static_cast<uint32_t>(this->state));
|
||||
buffer.encode_float(3, this->volume);
|
||||
buffer.encode_bool(4, this->muted);
|
||||
@@ -2173,7 +2173,7 @@ void MediaPlayerStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t MediaPlayerStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->state));
|
||||
size += ProtoSize::calc_float(1, this->volume);
|
||||
size += ProtoSize::calc_bool(1, this->muted);
|
||||
@@ -2942,7 +2942,7 @@ bool VoiceAssistantSetConfiguration::decode_length(uint32_t field_id, ProtoLengt
|
||||
#ifdef USE_ALARM_CONTROL_PANEL
|
||||
void ListEntitiesAlarmControlPanelResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(5, this->icon);
|
||||
@@ -2959,7 +2959,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -2975,7 +2975,7 @@ uint32_t ListEntitiesAlarmControlPanelResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void AlarmControlPanelStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_uint32(2, static_cast<uint32_t>(this->state));
|
||||
#ifdef USE_DEVICES
|
||||
buffer.encode_uint32(3, this->device_id);
|
||||
@@ -2983,7 +2983,7 @@ void AlarmControlPanelStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t AlarmControlPanelStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->state));
|
||||
#ifdef USE_DEVICES
|
||||
size += ProtoSize::calc_uint32(1, this->device_id);
|
||||
@@ -3030,7 +3030,7 @@ bool AlarmControlPanelCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit
|
||||
#ifdef USE_TEXT
|
||||
void ListEntitiesTextResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(5, this->icon);
|
||||
@@ -3048,7 +3048,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -3065,7 +3065,7 @@ uint32_t ListEntitiesTextResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void TextStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_string(2, this->state);
|
||||
buffer.encode_bool(3, this->missing_state);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -3074,7 +3074,7 @@ void TextStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t TextStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->state.size());
|
||||
size += ProtoSize::calc_bool(1, this->missing_state);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -3119,7 +3119,7 @@ bool TextCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
#ifdef USE_DATETIME_DATE
|
||||
void ListEntitiesDateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(5, this->icon);
|
||||
@@ -3133,7 +3133,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -3146,7 +3146,7 @@ uint32_t ListEntitiesDateResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void DateStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_bool(2, this->missing_state);
|
||||
buffer.encode_uint32(3, this->year);
|
||||
buffer.encode_uint32(4, this->month);
|
||||
@@ -3157,7 +3157,7 @@ void DateStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t DateStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_bool(1, this->missing_state);
|
||||
size += ProtoSize::calc_uint32(1, this->year);
|
||||
size += ProtoSize::calc_uint32(1, this->month);
|
||||
@@ -3202,7 +3202,7 @@ bool DateCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
#ifdef USE_DATETIME_TIME
|
||||
void ListEntitiesTimeResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(5, this->icon);
|
||||
@@ -3216,7 +3216,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -3229,7 +3229,7 @@ uint32_t ListEntitiesTimeResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void TimeStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_bool(2, this->missing_state);
|
||||
buffer.encode_uint32(3, this->hour);
|
||||
buffer.encode_uint32(4, this->minute);
|
||||
@@ -3240,7 +3240,7 @@ void TimeStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t TimeStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_bool(1, this->missing_state);
|
||||
size += ProtoSize::calc_uint32(1, this->hour);
|
||||
size += ProtoSize::calc_uint32(1, this->minute);
|
||||
@@ -3285,7 +3285,7 @@ bool TimeCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
#ifdef USE_EVENT
|
||||
void ListEntitiesEventResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(5, this->icon);
|
||||
@@ -3303,7 +3303,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -3322,7 +3322,7 @@ uint32_t ListEntitiesEventResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void EventResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_string(2, this->event_type);
|
||||
#ifdef USE_DEVICES
|
||||
buffer.encode_uint32(3, this->device_id);
|
||||
@@ -3330,7 +3330,7 @@ void EventResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t EventResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->event_type.size());
|
||||
#ifdef USE_DEVICES
|
||||
size += ProtoSize::calc_uint32(1, this->device_id);
|
||||
@@ -3341,7 +3341,7 @@ uint32_t EventResponse::calculate_size() const {
|
||||
#ifdef USE_VALVE
|
||||
void ListEntitiesValveResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(5, this->icon);
|
||||
@@ -3359,7 +3359,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -3376,7 +3376,7 @@ uint32_t ListEntitiesValveResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void ValveStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_float(2, this->position);
|
||||
buffer.encode_uint32(3, static_cast<uint32_t>(this->current_operation));
|
||||
#ifdef USE_DEVICES
|
||||
@@ -3385,7 +3385,7 @@ void ValveStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t ValveStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_float(1, this->position);
|
||||
size += ProtoSize::calc_uint32(1, static_cast<uint32_t>(this->current_operation));
|
||||
#ifdef USE_DEVICES
|
||||
@@ -3428,7 +3428,7 @@ bool ValveCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
#ifdef USE_DATETIME_DATETIME
|
||||
void ListEntitiesDateTimeResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(5, this->icon);
|
||||
@@ -3442,7 +3442,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -3455,7 +3455,7 @@ uint32_t ListEntitiesDateTimeResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void DateTimeStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_bool(2, this->missing_state);
|
||||
buffer.encode_fixed32(3, this->epoch_seconds);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -3464,7 +3464,7 @@ void DateTimeStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t DateTimeStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_bool(1, this->missing_state);
|
||||
size += ProtoSize::calc_fixed32(1, this->epoch_seconds);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -3501,7 +3501,7 @@ bool DateTimeCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
#ifdef USE_UPDATE
|
||||
void ListEntitiesUpdateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(5, this->icon);
|
||||
@@ -3516,7 +3516,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -3530,7 +3530,7 @@ uint32_t ListEntitiesUpdateResponse::calculate_size() const {
|
||||
return size;
|
||||
}
|
||||
void UpdateStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.write_tag_and_fixed32(13, this->key);
|
||||
buffer.encode_bool(2, this->missing_state);
|
||||
buffer.encode_bool(3, this->in_progress);
|
||||
buffer.encode_bool(4, this->has_progress);
|
||||
@@ -3546,7 +3546,7 @@ void UpdateStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
}
|
||||
uint32_t UpdateStateResponse::calculate_size() const {
|
||||
uint32_t size = 0;
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_bool(1, this->missing_state);
|
||||
size += ProtoSize::calc_bool(1, this->in_progress);
|
||||
size += ProtoSize::calc_bool(1, this->has_progress);
|
||||
@@ -3642,7 +3642,7 @@ uint32_t ZWaveProxyRequest::calculate_size() const {
|
||||
#ifdef USE_INFRARED
|
||||
void ListEntitiesInfraredResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
#ifdef USE_ENTITY_ICON
|
||||
buffer.encode_string(4, this->icon);
|
||||
@@ -3657,7 +3657,7 @@ 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 += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
size += ProtoSize::calc_length(1, this->name.size());
|
||||
#ifdef USE_ENTITY_ICON
|
||||
size += ProtoSize::calc_length(1, this->icon.size());
|
||||
@@ -3717,7 +3717,7 @@ void InfraredRFReceiveEvent::encode(ProtoWriteBuffer &buffer) const {
|
||||
#ifdef USE_DEVICES
|
||||
buffer.encode_uint32(1, this->device_id);
|
||||
#endif
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.write_tag_and_fixed32(21, this->key);
|
||||
for (const auto &it : *this->timings) {
|
||||
buffer.encode_sint32(3, it, true);
|
||||
}
|
||||
@@ -3727,7 +3727,7 @@ uint32_t InfraredRFReceiveEvent::calculate_size() const {
|
||||
#ifdef USE_DEVICES
|
||||
size += ProtoSize::calc_uint32(1, this->device_id);
|
||||
#endif
|
||||
size += ProtoSize::calc_fixed32(1, this->key);
|
||||
size += 5;
|
||||
if (!this->timings->empty()) {
|
||||
for (const auto &it : *this->timings) {
|
||||
size += ProtoSize::calc_sint32_force(1, it);
|
||||
|
||||
@@ -228,6 +228,21 @@ class ProtoWriteBuffer {
|
||||
* Following https://protobuf.dev/programming-guides/encoding/#structure
|
||||
*/
|
||||
void encode_field_raw(uint32_t field_id, uint32_t type) { this->encode_varint_raw((field_id << 3) | type); }
|
||||
/// 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 {
|
||||
this->debug_check_bounds_(5);
|
||||
this->pos_[0] = tag;
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
std::memcpy(this->pos_ + 1, &value, 4);
|
||||
#else
|
||||
this->pos_[1] = static_cast<uint8_t>(value & 0xFF);
|
||||
this->pos_[2] = static_cast<uint8_t>((value >> 8) & 0xFF);
|
||||
this->pos_[3] = static_cast<uint8_t>((value >> 16) & 0xFF);
|
||||
this->pos_[4] = static_cast<uint8_t>((value >> 24) & 0xFF);
|
||||
#endif
|
||||
this->pos_ += 5;
|
||||
}
|
||||
void encode_string(uint32_t field_id, const char *string, size_t len, bool force = false) {
|
||||
if (len == 0 && !force)
|
||||
return;
|
||||
@@ -268,8 +283,7 @@ class ProtoWriteBuffer {
|
||||
this->debug_check_bounds_(1);
|
||||
*this->pos_++ = value ? 0x01 : 0x00;
|
||||
}
|
||||
// noinline: 51 call sites; inlining causes net code growth vs a single out-of-line copy
|
||||
__attribute__((noinline)) void encode_fixed32(uint32_t field_id, uint32_t value, bool force = false) {
|
||||
void encode_fixed32(uint32_t field_id, uint32_t value, bool force = false) {
|
||||
if (value == 0 && !force)
|
||||
return;
|
||||
|
||||
|
||||
@@ -103,17 +103,17 @@ size_t BLENUS::available() {
|
||||
#endif
|
||||
}
|
||||
|
||||
uart::FlushResult BLENUS::flush() {
|
||||
uart::UARTFlushResult BLENUS::flush() {
|
||||
constexpr uint32_t timeout_500ms = 500;
|
||||
uint32_t start = millis();
|
||||
while (atomic_get(&this->tx_status_) != TX_DISABLED && !ring_buf_is_empty(&global_ble_tx_ring_buf)) {
|
||||
if (millis() - start > timeout_500ms) {
|
||||
ESP_LOGW(TAG, "Flush timeout");
|
||||
return uart::FlushResult::TIMEOUT;
|
||||
return uart::UARTFlushResult::UART_FLUSH_RESULT_TIMEOUT;
|
||||
}
|
||||
delay(1);
|
||||
}
|
||||
return uart::FlushResult::SUCCESS;
|
||||
return uart::UARTFlushResult::UART_FLUSH_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
void BLENUS::connected(bt_conn *conn, uint8_t err) {
|
||||
|
||||
@@ -26,7 +26,7 @@ class BLENUS : public uart::UARTComponent, public Component {
|
||||
bool peek_byte(uint8_t *data) override;
|
||||
bool read_array(uint8_t *data, size_t len) override;
|
||||
size_t available() override;
|
||||
uart::FlushResult flush() override;
|
||||
uart::UARTFlushResult flush() override;
|
||||
void check_logger_conflict() override {}
|
||||
void set_expose_log(bool expose_log) { this->expose_log_ = expose_log; }
|
||||
#ifdef USE_LOGGER
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#include "esphome/core/hal.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace combination {
|
||||
@@ -20,12 +18,12 @@ void CombinationComponent::log_config_(const LogString *combo_type) {
|
||||
|
||||
void CombinationNoParameterComponent::add_source(Sensor *sensor) { this->sensors_.emplace_back(sensor); }
|
||||
|
||||
void CombinationOneParameterComponent::add_source(Sensor *sensor, std::function<float(float)> const &stddev) {
|
||||
this->sensor_pairs_.emplace_back(sensor, stddev);
|
||||
void CombinationOneParameterComponent::add_source(Sensor *sensor, std::function<float(float)> const &compute) {
|
||||
this->sensor_sources_.push_back({sensor, compute, this});
|
||||
}
|
||||
|
||||
void CombinationOneParameterComponent::add_source(Sensor *sensor, float stddev) {
|
||||
this->add_source(sensor, std::function<float(float)>{[stddev](float x) -> float { return stddev; }});
|
||||
void CombinationOneParameterComponent::add_source(Sensor *sensor, float value) {
|
||||
this->add_source(sensor, std::function<float(float)>{[value](float x) -> float { return value; }});
|
||||
}
|
||||
|
||||
void CombinationNoParameterComponent::log_source_sensors() {
|
||||
@@ -37,9 +35,8 @@ void CombinationNoParameterComponent::log_source_sensors() {
|
||||
|
||||
void CombinationOneParameterComponent::log_source_sensors() {
|
||||
ESP_LOGCONFIG(TAG, " Source Sensors:");
|
||||
for (const auto &sensor : this->sensor_pairs_) {
|
||||
auto &entity = *sensor.first;
|
||||
ESP_LOGCONFIG(TAG, " - %s", entity.get_name().c_str());
|
||||
for (const auto &source : this->sensor_sources_) {
|
||||
ESP_LOGCONFIG(TAG, " - %s", source.sensor->get_name().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,9 +59,12 @@ void KalmanCombinationComponent::dump_config() {
|
||||
}
|
||||
|
||||
void KalmanCombinationComponent::setup() {
|
||||
for (const auto &sensor : this->sensor_pairs_) {
|
||||
const auto stddev = sensor.second;
|
||||
sensor.first->add_on_state_callback([this, stddev](float x) -> void { this->correct_(x, stddev(x)); });
|
||||
for (auto &source : this->sensor_sources_) {
|
||||
// [&source] is safe: source refers to a FixedVector element that never reallocates,
|
||||
// so the reference remains valid for the component's lifetime.
|
||||
source.sensor->add_on_state_callback([&source](float x) -> void {
|
||||
static_cast<KalmanCombinationComponent *>(source.parent)->correct_(x, source.compute(x));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,10 +117,10 @@ void KalmanCombinationComponent::correct_(float value, float stddev) {
|
||||
}
|
||||
|
||||
void LinearCombinationComponent::setup() {
|
||||
for (const auto &sensor : this->sensor_pairs_) {
|
||||
for (auto &source : this->sensor_sources_) {
|
||||
// All sensor updates are deferred until the next loop. This avoids publishing the combined sensor's result
|
||||
// repeatedly in the same loop if multiple source senors update.
|
||||
sensor.first->add_on_state_callback(
|
||||
source.sensor->add_on_state_callback(
|
||||
[this](float value) -> void { this->defer("update", [this, value]() { this->handle_new_value(value); }); });
|
||||
}
|
||||
}
|
||||
@@ -133,10 +133,10 @@ void LinearCombinationComponent::handle_new_value(float value) {
|
||||
|
||||
float sum = 0.0;
|
||||
|
||||
for (const auto &sensor : this->sensor_pairs_) {
|
||||
const float sensor_state = sensor.first->state;
|
||||
for (const auto &source : this->sensor_sources_) {
|
||||
const float sensor_state = source.sensor->state;
|
||||
if (std::isfinite(sensor_state)) {
|
||||
sum += sensor_state * sensor.second(sensor_state);
|
||||
sum += sensor_state * source.compute(sensor_state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
namespace esphome {
|
||||
namespace combination {
|
||||
@@ -41,14 +42,21 @@ class CombinationNoParameterComponent : public CombinationComponent {
|
||||
// Base class for opertions that require one parameter to compute the combination
|
||||
class CombinationOneParameterComponent : public CombinationComponent {
|
||||
public:
|
||||
void add_source(Sensor *sensor, std::function<float(float)> const &stddev);
|
||||
void add_source(Sensor *sensor, float stddev);
|
||||
void set_source_count(size_t count) { this->sensor_sources_.init(count); }
|
||||
void add_source(Sensor *sensor, std::function<float(float)> const &compute);
|
||||
void add_source(Sensor *sensor, float value);
|
||||
|
||||
/// @brief Logs all source sensor's names in sensor_pairs_
|
||||
/// @brief Logs all source sensors' names in sensor_sources_
|
||||
void log_source_sensors() override;
|
||||
|
||||
protected:
|
||||
std::vector<std::pair<Sensor *, std::function<float(float)>>> sensor_pairs_;
|
||||
struct SensorSource {
|
||||
sensor::Sensor *sensor;
|
||||
std::function<float(float)> compute;
|
||||
CombinationOneParameterComponent *parent;
|
||||
};
|
||||
|
||||
FixedVector<SensorSource> sensor_sources_;
|
||||
};
|
||||
|
||||
class KalmanCombinationComponent : public CombinationOneParameterComponent {
|
||||
|
||||
@@ -180,6 +180,9 @@ async def to_code(config):
|
||||
if proces_std_dev := config.get(CONF_PROCESS_STD_DEV):
|
||||
cg.add(var.set_process_std_dev(proces_std_dev))
|
||||
|
||||
if config[CONF_TYPE] in (CONF_KALMAN, CONF_LINEAR):
|
||||
cg.add(var.set_source_count(len(config[CONF_SOURCES])))
|
||||
|
||||
for source_conf in config[CONF_SOURCES]:
|
||||
source = await cg.get_variable(source_conf[CONF_SOURCE])
|
||||
if config[CONF_TYPE] == CONF_KALMAN:
|
||||
|
||||
@@ -4,12 +4,40 @@ import re
|
||||
# pylint: disable=E0602
|
||||
Import("env") # noqa
|
||||
|
||||
# IRAM size for testing mode (2MB - large enough to accommodate grouped tests)
|
||||
TESTING_IRAM_SIZE = 0x200000
|
||||
# Memory sizes for testing mode (large enough to accommodate grouped tests)
|
||||
TESTING_IRAM_SIZE = 0x200000 # 2MB
|
||||
TESTING_DRAM_SIZE = 0x200000 # 2MB
|
||||
|
||||
|
||||
def patch_segment(content, segment_name, new_size):
|
||||
"""Patch a memory segment's length in linker script content.
|
||||
|
||||
Handles both single-line and multi-line segment definitions, e.g.:
|
||||
iram0_0_seg (RX) : org = 0x40080000, len = 0x20000 + 0x0
|
||||
or split across lines:
|
||||
dram0_0_seg (RW) : org = 0x3FFB0000 + 0xdb5c,
|
||||
len = 0x2c200 - 0xdb5c
|
||||
|
||||
Args:
|
||||
content: Full linker script content as string
|
||||
segment_name: Name of the segment (e.g., 'iram0_0_seg')
|
||||
new_size: New size as integer
|
||||
|
||||
Returns:
|
||||
Tuple of (new_content, was_patched)
|
||||
"""
|
||||
# Match segment name through to "len = <value>" allowing newlines between org and len
|
||||
pattern = rf'({re.escape(segment_name)}\s*\([^)]*\)\s*:\s*org\s*=\s*.+?,\s*len\s*=\s*)(\S+[^\n]*)'
|
||||
if match := re.search(pattern, content, re.DOTALL):
|
||||
replacement = f"{match.group(1)}{new_size:#x}"
|
||||
new_content = content[:match.start()] + replacement + content[match.end():]
|
||||
if new_content != content:
|
||||
return new_content, True
|
||||
return content, False
|
||||
|
||||
|
||||
def patch_idf_linker_script(source, target, env):
|
||||
"""Patch ESP-IDF linker script to increase IRAM size for testing mode."""
|
||||
"""Patch ESP-IDF linker script to increase IRAM and DRAM size for testing mode."""
|
||||
# Check if we're in testing mode by looking for the define
|
||||
build_flags = env.get("BUILD_FLAGS", [])
|
||||
testing_mode = any("-DESPHOME_TESTING_MODE" in flag for flag in build_flags)
|
||||
@@ -34,36 +62,22 @@ def patch_idf_linker_script(source, target, env):
|
||||
print(f"ESPHome: Error reading linker script: {e}")
|
||||
return
|
||||
|
||||
# Check if this file contains iram0_0_seg
|
||||
if 'iram0_0_seg' not in content:
|
||||
print(f"ESPHome: Warning - iram0_0_seg not found in {memory_ld}")
|
||||
return
|
||||
patches = []
|
||||
|
||||
# Look for iram0_0_seg definition and increase its length
|
||||
# ESP-IDF format can be:
|
||||
# iram0_0_seg (RX) : org = 0x40080000, len = 0x20000 + 0x0
|
||||
# or more complex with nested parentheses:
|
||||
# iram0_0_seg (RX) : org = (0x40370000 + 0x4000), len = (((0x403CB700 - (0x40378000 - 0x3FC88000)) - 0x3FC88000) + 0x8000 - 0x4000)
|
||||
# We want to change len to TESTING_IRAM_SIZE for testing
|
||||
content, patched = patch_segment(content, 'iram0_0_seg', TESTING_IRAM_SIZE)
|
||||
if patched:
|
||||
patches.append(f"IRAM={TESTING_IRAM_SIZE:#x}")
|
||||
|
||||
# Use a more robust approach: find the line and manually parse it
|
||||
lines = content.split('\n')
|
||||
for i, line in enumerate(lines):
|
||||
if 'iram0_0_seg' in line and 'len' in line:
|
||||
# Find the position of "len = " and replace everything after it until the end of the statement
|
||||
match = re.search(r'(iram0_0_seg\s*\([^)]*\)\s*:\s*org\s*=\s*(?:\([^)]+\)|0x[0-9a-fA-F]+)\s*,\s*len\s*=\s*)(.+?)(\s*)$', line)
|
||||
if match:
|
||||
lines[i] = f"{match.group(1)}{TESTING_IRAM_SIZE:#x}{match.group(3)}"
|
||||
break
|
||||
content, patched = patch_segment(content, 'dram0_0_seg', TESTING_DRAM_SIZE)
|
||||
if patched:
|
||||
patches.append(f"DRAM={TESTING_DRAM_SIZE:#x}")
|
||||
|
||||
updated = '\n'.join(lines)
|
||||
|
||||
if updated != content:
|
||||
if patches:
|
||||
with open(memory_ld, "w") as f:
|
||||
f.write(updated)
|
||||
print(f"ESPHome: Patched IRAM size to {TESTING_IRAM_SIZE:#x} in {memory_ld} for testing mode")
|
||||
f.write(content)
|
||||
print(f"ESPHome: Patched {', '.join(patches)} in {memory_ld} for testing mode")
|
||||
else:
|
||||
print(f"ESPHome: Warning - could not patch iram0_0_seg in {memory_ld}")
|
||||
print(f"ESPHome: Warning - could not patch memory segments in {memory_ld}")
|
||||
|
||||
|
||||
# Hook into the build process before linking
|
||||
|
||||
@@ -18,12 +18,6 @@ void EthernetComponent::set_type(EthernetType type) { this->type_ = type; }
|
||||
void EthernetComponent::set_manual_ip(const ManualIP &manual_ip) { this->manual_ip_ = manual_ip; }
|
||||
#endif
|
||||
|
||||
// set_use_address() is guaranteed to be called during component setup by Python code generation,
|
||||
// so use_address_ will always be valid when get_use_address() is called - no fallback needed.
|
||||
const char *EthernetComponent::get_use_address() const { return this->use_address_; }
|
||||
|
||||
void EthernetComponent::set_use_address(const char *use_address) { this->use_address_ = use_address; }
|
||||
|
||||
#ifdef USE_ETHERNET_IP_STATE_LISTENERS
|
||||
void EthernetComponent::notify_ip_state_listeners_() {
|
||||
auto ips = this->get_ip_addresses();
|
||||
|
||||
@@ -103,8 +103,8 @@ class EthernetComponent final : public Component {
|
||||
|
||||
network::IPAddresses get_ip_addresses();
|
||||
network::IPAddress get_dns_address(uint8_t num);
|
||||
const char *get_use_address() const;
|
||||
void set_use_address(const char *use_address);
|
||||
const char *get_use_address() const { return this->use_address_; }
|
||||
void set_use_address(const char *use_address) { this->use_address_ = use_address; }
|
||||
void get_eth_mac_address_raw(uint8_t *mac);
|
||||
// Remove before 2026.9.0
|
||||
ESPDEPRECATED("Use get_eth_mac_address_pretty_into_buffer() instead. Removed in 2026.9.0", "2026.3.0")
|
||||
|
||||
@@ -366,14 +366,14 @@ class MQTTJsonMessageTrigger : public Trigger<JsonObjectConst> {
|
||||
|
||||
class MQTTConnectTrigger : public Trigger<bool> {
|
||||
public:
|
||||
explicit MQTTConnectTrigger(MQTTClientComponent *&client) {
|
||||
explicit MQTTConnectTrigger(MQTTClientComponent *client) {
|
||||
client->set_on_connect([this](bool session_present) { this->trigger(session_present); });
|
||||
}
|
||||
};
|
||||
|
||||
class MQTTDisconnectTrigger : public Trigger<MQTTClientDisconnectReason> {
|
||||
public:
|
||||
explicit MQTTDisconnectTrigger(MQTTClientComponent *&client) {
|
||||
explicit MQTTDisconnectTrigger(MQTTClientComponent *client) {
|
||||
client->set_on_disconnect([this](MQTTClientDisconnectReason reason) { this->trigger(reason); });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -42,29 +42,5 @@ network::IPAddresses get_ip_addresses() {
|
||||
return {};
|
||||
}
|
||||
|
||||
const char *get_use_address() {
|
||||
// Global component pointers are guaranteed to be set by component constructors when USE_* is defined
|
||||
#ifdef USE_ETHERNET
|
||||
return ethernet::global_eth_component->get_use_address();
|
||||
#endif
|
||||
|
||||
#ifdef USE_MODEM
|
||||
return modem::global_modem_component->get_use_address();
|
||||
#endif
|
||||
|
||||
#ifdef USE_WIFI
|
||||
return wifi::global_wifi_component->get_use_address();
|
||||
#endif
|
||||
|
||||
#ifdef USE_OPENTHREAD
|
||||
return openthread::global_openthread_component->get_use_address();
|
||||
#endif
|
||||
|
||||
#if !defined(USE_ETHERNET) && !defined(USE_MODEM) && !defined(USE_WIFI) && !defined(USE_OPENTHREAD)
|
||||
// Fallback when no network component is defined (e.g., host platform)
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace esphome::network
|
||||
#endif
|
||||
|
||||
@@ -54,7 +54,29 @@ ESPHOME_ALWAYS_INLINE inline bool is_connected() {
|
||||
/// Return whether the network is disabled (only wifi for now)
|
||||
bool is_disabled();
|
||||
/// Get the active network hostname
|
||||
const char *get_use_address();
|
||||
ESPHOME_ALWAYS_INLINE inline const char *get_use_address() {
|
||||
// Global component pointers are guaranteed to be set by component constructors when USE_* is defined
|
||||
#ifdef USE_ETHERNET
|
||||
return ethernet::global_eth_component->get_use_address();
|
||||
#endif
|
||||
|
||||
#ifdef USE_MODEM
|
||||
return modem::global_modem_component->get_use_address();
|
||||
#endif
|
||||
|
||||
#ifdef USE_WIFI
|
||||
return wifi::global_wifi_component->get_use_address();
|
||||
#endif
|
||||
|
||||
#ifdef USE_OPENTHREAD
|
||||
return openthread::global_openthread_component->get_use_address();
|
||||
#endif
|
||||
|
||||
#if !defined(USE_ETHERNET) && !defined(USE_MODEM) && !defined(USE_WIFI) && !defined(USE_OPENTHREAD)
|
||||
// Fallback when no network component is defined (e.g., host platform)
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
IPAddresses get_ip_addresses();
|
||||
|
||||
} // namespace esphome::network
|
||||
|
||||
@@ -257,11 +257,5 @@ void OpenThreadComponent::on_factory_reset(std::function<void()> callback) {
|
||||
ESP_LOGD(TAG, "Waiting on Confirmation Removal SRP Host and Services");
|
||||
}
|
||||
|
||||
// set_use_address() is guaranteed to be called during component setup by Python code generation,
|
||||
// so use_address_ will always be valid when get_use_address() is called - no fallback needed.
|
||||
const char *OpenThreadComponent::get_use_address() const { return this->use_address_; }
|
||||
|
||||
void OpenThreadComponent::set_use_address(const char *use_address) { this->use_address_ = use_address; }
|
||||
|
||||
} // namespace esphome::openthread
|
||||
#endif
|
||||
|
||||
@@ -37,8 +37,8 @@ class OpenThreadComponent : public Component {
|
||||
void on_factory_reset(std::function<void()> callback);
|
||||
void defer_factory_reset_external_callback();
|
||||
|
||||
const char *get_use_address() const;
|
||||
void set_use_address(const char *use_address);
|
||||
const char *get_use_address() const { return this->use_address_; }
|
||||
void set_use_address(const char *use_address) { this->use_address_ = use_address; }
|
||||
#if CONFIG_OPENTHREAD_MTD
|
||||
void set_poll_period(uint32_t poll_period) { this->poll_period_ = poll_period; }
|
||||
#endif
|
||||
|
||||
@@ -165,7 +165,7 @@ uint32_t SerialProxy::get_modem_pins() const {
|
||||
(this->dtr_state_ ? SERIAL_PROXY_LINE_STATE_FLAG_DTR : 0u);
|
||||
}
|
||||
|
||||
uart::FlushResult SerialProxy::flush_port() {
|
||||
uart::UARTFlushResult SerialProxy::flush_port() {
|
||||
ESP_LOGV(TAG, "Flushing serial proxy [%u]", this->instance_index_);
|
||||
return this->flush();
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ class SerialProxy : public uart::UARTDevice, public Component {
|
||||
uint32_t get_modem_pins() const;
|
||||
|
||||
/// Flush the serial port (block until all TX data is sent)
|
||||
uart::FlushResult flush_port();
|
||||
uart::UARTFlushResult flush_port();
|
||||
|
||||
/// Set the RTS GPIO pin (from YAML configuration)
|
||||
void set_rts_pin(GPIOPin *pin) { this->rts_pin_ = pin; }
|
||||
|
||||
@@ -45,7 +45,7 @@ class UARTDevice {
|
||||
|
||||
size_t available() { return this->parent_->available(); }
|
||||
|
||||
FlushResult flush() { return this->parent_->flush(); }
|
||||
UARTFlushResult flush() { return this->parent_->flush(); }
|
||||
|
||||
// Compat APIs
|
||||
int read() {
|
||||
|
||||
@@ -30,17 +30,12 @@ enum UARTDirection {
|
||||
const LogString *parity_to_str(UARTParityOptions parity);
|
||||
|
||||
/// Result of a flush() call.
|
||||
// Some vendor SDKs (e.g., Realtek) define SUCCESS as a macro.
|
||||
// Save and restore around the enum to avoid collisions with our scoped enum value.
|
||||
#pragma push_macro("SUCCESS")
|
||||
#undef SUCCESS
|
||||
enum class FlushResult {
|
||||
SUCCESS, ///< Confirmed: all bytes left the TX FIFO.
|
||||
TIMEOUT, ///< Confirmed: timed out before TX completed.
|
||||
FAILED, ///< Confirmed: driver or hardware error.
|
||||
ASSUMED_SUCCESS, ///< Platform cannot report result; success is assumed.
|
||||
enum class UARTFlushResult {
|
||||
UART_FLUSH_RESULT_SUCCESS, ///< Confirmed: all bytes left the TX FIFO.
|
||||
UART_FLUSH_RESULT_TIMEOUT, ///< Confirmed: timed out before TX completed.
|
||||
UART_FLUSH_RESULT_FAILED, ///< Confirmed: driver or hardware error.
|
||||
UART_FLUSH_RESULT_ASSUMED_SUCCESS, ///< Platform cannot report result; success is assumed.
|
||||
};
|
||||
#pragma pop_macro("SUCCESS")
|
||||
|
||||
class UARTComponent {
|
||||
public:
|
||||
@@ -87,8 +82,8 @@ class UARTComponent {
|
||||
virtual size_t available() = 0;
|
||||
|
||||
// Pure virtual method to block until all bytes have been written to the UART bus.
|
||||
// @return FlushResult indicating whether the flush was confirmed, timed out, failed, or assumed successful.
|
||||
virtual FlushResult flush() = 0;
|
||||
// @return UARTFlushResult indicating whether the flush was confirmed, timed out, failed, or assumed successful.
|
||||
virtual UARTFlushResult flush() = 0;
|
||||
|
||||
// Sets the maximum time to wait for TX to drain during flush().
|
||||
// Only meaningful on ESP32 (IDF). Other platforms ignore this value.
|
||||
|
||||
@@ -213,14 +213,14 @@ size_t ESP8266UartComponent::available() {
|
||||
return this->sw_serial_->available();
|
||||
}
|
||||
}
|
||||
FlushResult ESP8266UartComponent::flush() {
|
||||
UARTFlushResult ESP8266UartComponent::flush() {
|
||||
ESP_LOGVV(TAG, " Flushing");
|
||||
if (this->hw_serial_ != nullptr) {
|
||||
this->hw_serial_->flush();
|
||||
} else {
|
||||
this->sw_serial_->flush();
|
||||
}
|
||||
return FlushResult::ASSUMED_SUCCESS;
|
||||
return UARTFlushResult::UART_FLUSH_RESULT_ASSUMED_SUCCESS;
|
||||
}
|
||||
void ESP8266SoftwareSerial::setup(InternalGPIOPin *tx_pin, InternalGPIOPin *rx_pin, uint32_t baud_rate,
|
||||
uint8_t stop_bits, uint32_t data_bits, UARTParityOptions parity,
|
||||
|
||||
@@ -58,7 +58,7 @@ class ESP8266UartComponent : public UARTComponent, public Component {
|
||||
bool read_array(uint8_t *data, size_t len) override;
|
||||
|
||||
size_t available() override;
|
||||
FlushResult flush() override;
|
||||
UARTFlushResult flush() override;
|
||||
|
||||
uint32_t get_config();
|
||||
|
||||
|
||||
@@ -360,15 +360,15 @@ size_t IDFUARTComponent::available() {
|
||||
return available;
|
||||
}
|
||||
|
||||
FlushResult IDFUARTComponent::flush() {
|
||||
UARTFlushResult IDFUARTComponent::flush() {
|
||||
ESP_LOGVV(TAG, " Flushing");
|
||||
TickType_t ticks = this->flush_timeout_ms_ == 0 ? portMAX_DELAY : pdMS_TO_TICKS(this->flush_timeout_ms_);
|
||||
esp_err_t err = uart_wait_tx_done(this->uart_num_, ticks);
|
||||
if (err == ESP_OK)
|
||||
return FlushResult::SUCCESS;
|
||||
return UARTFlushResult::UART_FLUSH_RESULT_SUCCESS;
|
||||
if (err == ESP_ERR_TIMEOUT)
|
||||
return FlushResult::TIMEOUT;
|
||||
return FlushResult::FAILED;
|
||||
return UARTFlushResult::UART_FLUSH_RESULT_TIMEOUT;
|
||||
return UARTFlushResult::UART_FLUSH_RESULT_FAILED;
|
||||
}
|
||||
|
||||
void IDFUARTComponent::check_logger_conflict() {}
|
||||
|
||||
@@ -31,7 +31,7 @@ class IDFUARTComponent : public UARTComponent, public Component {
|
||||
bool read_array(uint8_t *data, size_t len) override;
|
||||
|
||||
size_t available() override;
|
||||
FlushResult flush() override;
|
||||
UARTFlushResult flush() override;
|
||||
|
||||
void set_flush_timeout(uint32_t flush_timeout_ms) override { this->flush_timeout_ms_ = flush_timeout_ms; }
|
||||
|
||||
|
||||
@@ -274,13 +274,13 @@ size_t HostUartComponent::available() {
|
||||
return result;
|
||||
};
|
||||
|
||||
FlushResult HostUartComponent::flush() {
|
||||
UARTFlushResult HostUartComponent::flush() {
|
||||
if (this->file_descriptor_ == -1) {
|
||||
return FlushResult::ASSUMED_SUCCESS;
|
||||
return UARTFlushResult::UART_FLUSH_RESULT_ASSUMED_SUCCESS;
|
||||
}
|
||||
tcflush(this->file_descriptor_, TCIOFLUSH);
|
||||
ESP_LOGV(TAG, " Flushing");
|
||||
return FlushResult::ASSUMED_SUCCESS;
|
||||
return UARTFlushResult::UART_FLUSH_RESULT_ASSUMED_SUCCESS;
|
||||
}
|
||||
|
||||
void HostUartComponent::update_error_(const std::string &error) {
|
||||
|
||||
@@ -18,7 +18,7 @@ class HostUartComponent : public UARTComponent, public Component {
|
||||
bool peek_byte(uint8_t *data) override;
|
||||
bool read_array(uint8_t *data, size_t len) override;
|
||||
size_t available() override;
|
||||
FlushResult flush() override;
|
||||
UARTFlushResult flush() override;
|
||||
void set_name(std::string port_name) { port_name_ = port_name; };
|
||||
|
||||
protected:
|
||||
|
||||
@@ -170,10 +170,10 @@ bool LibreTinyUARTComponent::read_array(uint8_t *data, size_t len) {
|
||||
}
|
||||
|
||||
size_t LibreTinyUARTComponent::available() { return this->serial_->available(); }
|
||||
FlushResult LibreTinyUARTComponent::flush() {
|
||||
UARTFlushResult LibreTinyUARTComponent::flush() {
|
||||
ESP_LOGVV(TAG, " Flushing");
|
||||
this->serial_->flush();
|
||||
return FlushResult::ASSUMED_SUCCESS;
|
||||
return UARTFlushResult::UART_FLUSH_RESULT_ASSUMED_SUCCESS;
|
||||
}
|
||||
|
||||
void LibreTinyUARTComponent::check_logger_conflict() {
|
||||
|
||||
@@ -22,7 +22,7 @@ class LibreTinyUARTComponent : public UARTComponent, public Component {
|
||||
bool read_array(uint8_t *data, size_t len) override;
|
||||
|
||||
size_t available() override;
|
||||
FlushResult flush() override;
|
||||
UARTFlushResult flush() override;
|
||||
|
||||
uint16_t get_config();
|
||||
|
||||
|
||||
@@ -208,10 +208,10 @@ bool RP2040UartComponent::read_array(uint8_t *data, size_t len) {
|
||||
return true;
|
||||
}
|
||||
size_t RP2040UartComponent::available() { return this->serial_->available(); }
|
||||
FlushResult RP2040UartComponent::flush() {
|
||||
UARTFlushResult RP2040UartComponent::flush() {
|
||||
ESP_LOGVV(TAG, " Flushing");
|
||||
this->serial_->flush();
|
||||
return FlushResult::ASSUMED_SUCCESS;
|
||||
return UARTFlushResult::UART_FLUSH_RESULT_ASSUMED_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace esphome::uart
|
||||
|
||||
@@ -25,7 +25,7 @@ class RP2040UartComponent : public UARTComponent, public Component {
|
||||
bool read_array(uint8_t *data, size_t len) override;
|
||||
|
||||
size_t available() override;
|
||||
FlushResult flush() override;
|
||||
UARTFlushResult flush() override;
|
||||
|
||||
uint16_t get_config();
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ class USBCDCACMInstance : public uart::UARTComponent, public Parented<USBCDCACMC
|
||||
bool peek_byte(uint8_t *data) override;
|
||||
bool read_array(uint8_t *data, size_t len) override;
|
||||
size_t available() override;
|
||||
uart::FlushResult flush() override;
|
||||
uart::UARTFlushResult flush() override;
|
||||
|
||||
protected:
|
||||
void check_logger_conflict() override;
|
||||
|
||||
@@ -325,10 +325,10 @@ size_t USBCDCACMInstance::available() {
|
||||
return waiting + (this->has_peek_ ? 1 : 0);
|
||||
}
|
||||
|
||||
uart::FlushResult USBCDCACMInstance::flush() {
|
||||
uart::UARTFlushResult USBCDCACMInstance::flush() {
|
||||
// Wait for TX ring buffer to be empty
|
||||
if (this->usb_tx_ringbuf_ == nullptr) {
|
||||
return uart::FlushResult::ASSUMED_SUCCESS;
|
||||
return uart::UARTFlushResult::UART_FLUSH_RESULT_ASSUMED_SUCCESS;
|
||||
}
|
||||
|
||||
UBaseType_t waiting = 1;
|
||||
@@ -342,10 +342,10 @@ uart::FlushResult USBCDCACMInstance::flush() {
|
||||
// Also wait for USB to finish transmitting
|
||||
esp_err_t err = tinyusb_cdcacm_write_flush(static_cast<tinyusb_cdcacm_itf_t>(this->itf_), pdMS_TO_TICKS(100));
|
||||
if (err == ESP_OK)
|
||||
return uart::FlushResult::SUCCESS;
|
||||
return uart::UARTFlushResult::UART_FLUSH_RESULT_SUCCESS;
|
||||
if (err == ESP_ERR_TIMEOUT)
|
||||
return uart::FlushResult::TIMEOUT;
|
||||
return uart::FlushResult::FAILED;
|
||||
return uart::UARTFlushResult::UART_FLUSH_RESULT_TIMEOUT;
|
||||
return uart::UARTFlushResult::UART_FLUSH_RESULT_FAILED;
|
||||
}
|
||||
|
||||
void USBCDCACMInstance::check_logger_conflict() {}
|
||||
|
||||
@@ -169,7 +169,7 @@ void USBUartChannel::write_array(const uint8_t *data, size_t len) {
|
||||
this->parent_->start_output(this);
|
||||
}
|
||||
|
||||
uart::FlushResult USBUartChannel::flush() {
|
||||
uart::UARTFlushResult USBUartChannel::flush() {
|
||||
// Spin until the output queue is drained and the last USB transfer completes.
|
||||
// Safe to call from the main loop only.
|
||||
// The flush_timeout_ms_ timeout guards against a device that stops responding mid-flush;
|
||||
@@ -181,8 +181,8 @@ uart::FlushResult USBUartChannel::flush() {
|
||||
yield();
|
||||
}
|
||||
if (!this->output_queue_.empty() || this->output_started_.load())
|
||||
return uart::FlushResult::TIMEOUT;
|
||||
return uart::FlushResult::SUCCESS;
|
||||
return uart::UARTFlushResult::UART_FLUSH_RESULT_TIMEOUT;
|
||||
return uart::UARTFlushResult::UART_FLUSH_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
bool USBUartChannel::peek_byte(uint8_t *data) {
|
||||
|
||||
@@ -140,7 +140,7 @@ class USBUartChannel : public uart::UARTComponent, public Parented<USBUartCompon
|
||||
bool peek_byte(uint8_t *data) override;
|
||||
bool read_array(uint8_t *data, size_t len) override;
|
||||
size_t available() override { return this->input_buffer_.get_available(); }
|
||||
uart::FlushResult flush() override;
|
||||
uart::UARTFlushResult flush() override;
|
||||
void check_logger_conflict() override {}
|
||||
void set_parity(UARTParityOptions parity) { this->parity_ = parity; }
|
||||
void set_debug(bool debug) { this->debug_ = debug; }
|
||||
|
||||
@@ -433,16 +433,16 @@ void WeikaiChannel::write_array(const uint8_t *buffer, size_t length) {
|
||||
this->reg(0).write_fifo(const_cast<uint8_t *>(buffer), length);
|
||||
}
|
||||
|
||||
uart::FlushResult WeikaiChannel::flush() {
|
||||
uart::UARTFlushResult WeikaiChannel::flush() {
|
||||
uint32_t const start_time = millis();
|
||||
while (this->tx_fifo_is_not_empty_()) { // wait until buffer empty
|
||||
if (millis() - start_time > 200) {
|
||||
ESP_LOGW(TAG, "WARNING flush timeout - still %d bytes not sent after 200 ms", this->tx_in_fifo_());
|
||||
return uart::FlushResult::TIMEOUT;
|
||||
return uart::UARTFlushResult::UART_FLUSH_RESULT_TIMEOUT;
|
||||
}
|
||||
yield(); // reschedule our thread to avoid blocking
|
||||
}
|
||||
return uart::FlushResult::SUCCESS;
|
||||
return uart::UARTFlushResult::UART_FLUSH_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
size_t WeikaiChannel::xfer_fifo_to_buffer_() {
|
||||
|
||||
@@ -380,7 +380,7 @@ class WeikaiChannel : public uart::UARTComponent {
|
||||
/// @details If we refer to Serial.flush() in Arduino it says: ** Waits for the transmission of outgoing serial data
|
||||
/// to complete. (Prior to Arduino 1.0, this the method was removing any buffered incoming serial data.). ** Therefore
|
||||
/// we wait until all bytes are gone with a timeout of 100 ms
|
||||
uart::FlushResult flush() override;
|
||||
uart::UARTFlushResult flush() override;
|
||||
|
||||
protected:
|
||||
friend class WeikaiComponent;
|
||||
|
||||
@@ -891,10 +891,6 @@ network::IPAddress WiFiComponent::get_dns_address(int num) {
|
||||
return this->wifi_dns_ip_(num);
|
||||
return {};
|
||||
}
|
||||
// set_use_address() is guaranteed to be called during component setup by Python code generation,
|
||||
// so use_address_ will always be valid when get_use_address() is called - no fallback needed.
|
||||
const char *WiFiComponent::get_use_address() const { return this->use_address_; }
|
||||
void WiFiComponent::set_use_address(const char *use_address) { this->use_address_ = use_address; }
|
||||
|
||||
#ifdef USE_WIFI_AP
|
||||
void WiFiComponent::setup_ap_config_() {
|
||||
|
||||
@@ -481,8 +481,8 @@ class WiFiComponent final : public Component {
|
||||
|
||||
network::IPAddress get_dns_address(int num);
|
||||
network::IPAddresses get_ip_addresses();
|
||||
const char *get_use_address() const;
|
||||
void set_use_address(const char *use_address);
|
||||
const char *get_use_address() const { return this->use_address_; }
|
||||
void set_use_address(const char *use_address) { this->use_address_ = use_address; }
|
||||
|
||||
const wifi_scan_vector_t<WiFiScanResult> &get_scan_result() const { return scan_result_; }
|
||||
|
||||
|
||||
@@ -166,7 +166,13 @@ void HOT Scheduler::set_timer_common_(Component *component, SchedulerItem::Type
|
||||
item->component = component;
|
||||
item->set_name(name_type, static_name, hash_or_id);
|
||||
item->type = type;
|
||||
item->callback = std::move(func);
|
||||
// Use destroy + placement-new instead of move-assignment.
|
||||
// GCC's std::function::operator=(function&&) does a full swap dance even when the
|
||||
// target is empty. Since recycled/new items always have an empty callback, we can
|
||||
// destroy the empty one (no-op) and move-construct directly, saving ~40 bytes of
|
||||
// swap/destructor code on Xtensa.
|
||||
item->callback.~function();
|
||||
new (&item->callback) std::function<void()>(std::move(func));
|
||||
// Reset remove flag - recycled items may have been cancelled (remove=true) in previous use
|
||||
this->set_item_removed_(item, false);
|
||||
item->is_retry = is_retry;
|
||||
|
||||
@@ -565,6 +565,29 @@ def new_variable(
|
||||
return obj
|
||||
|
||||
|
||||
def _extract_component_ns(type_str: str) -> str:
|
||||
"""Extract the component namespace from a fully-qualified C++ type string.
|
||||
|
||||
Strips leading ``esphome::`` and template arguments, then returns
|
||||
the first namespace segment. Falls back to ``"esphome"`` when the
|
||||
type has no namespace qualifier (after stripping templates).
|
||||
|
||||
Examples::
|
||||
|
||||
esphome::dsmr::Dsmr -> dsmr
|
||||
esphome::logger::Logger -> logger
|
||||
esphome::Automation<std::optional<bool>, std::optional<bool>> -> esphome
|
||||
Logger -> esphome
|
||||
"""
|
||||
bare = type_str.removeprefix("esphome::")
|
||||
# Strip template arguments before namespace extraction to avoid
|
||||
# matching :: inside template params (e.g. Automation<std::optional<bool>>)
|
||||
bare_no_template = bare.split("<", maxsplit=1)[0]
|
||||
if "::" in bare_no_template:
|
||||
return bare_no_template.split("::", maxsplit=1)[0].rstrip("_")
|
||||
return "esphome"
|
||||
|
||||
|
||||
def Pvariable(id_: ID, rhs: SafeExpType, type_: "MockObj" = None) -> "MockObj":
|
||||
"""Declare a new pointer variable in the code generation.
|
||||
|
||||
@@ -584,7 +607,9 @@ def Pvariable(id_: ID, rhs: SafeExpType, type_: "MockObj" = None) -> "MockObj":
|
||||
# For 'new' allocations, use placement new into static storage
|
||||
# to avoid heap fragmentation on embedded devices.
|
||||
the_type = id_.type
|
||||
storage_name = f"{id_.id}__pstorage"
|
||||
# Extract component namespace from type for memory analysis attribution
|
||||
component_ns = _extract_component_ns(str(the_type))
|
||||
storage_name = f"{component_ns}__{id_.id}__pstorage"
|
||||
|
||||
# Declare aligned byte array for the object storage
|
||||
CORE.add_global(
|
||||
|
||||
@@ -254,14 +254,17 @@ class TypeInfo(ABC):
|
||||
def dump(self, name: str) -> str:
|
||||
"""Dump the value to the output."""
|
||||
|
||||
def calculate_tag(self) -> int:
|
||||
"""Calculate the protobuf tag (field_id << 3 | wire_type)."""
|
||||
return (self.number << 3) | (self.wire_type & 0b111)
|
||||
|
||||
def calculate_field_id_size(self) -> int:
|
||||
"""Calculates the size of a field ID in bytes.
|
||||
|
||||
Returns:
|
||||
The number of bytes needed to encode the field ID
|
||||
"""
|
||||
# Calculate the tag by combining field_id and wire_type
|
||||
tag = (self.number << 3) | (self.wire_type & 0b111)
|
||||
tag = self.calculate_tag()
|
||||
|
||||
# Calculate the varint size
|
||||
if tag < 128:
|
||||
@@ -556,6 +559,16 @@ class Fixed32Type(TypeInfo):
|
||||
o += "out.append(buffer);"
|
||||
return o
|
||||
|
||||
@property
|
||||
def encode_content(self) -> str:
|
||||
tag = self.calculate_tag()
|
||||
if self.force and tag < 128:
|
||||
# Emit combined tag+value write: precomputed tag + direct memcpy
|
||||
return f"buffer.write_tag_and_fixed32({tag}, this->{self.field_name});"
|
||||
if self.force:
|
||||
return f"buffer.{self.encode_func}({self.number}, this->{self.field_name}, true);"
|
||||
return f"buffer.{self.encode_func}({self.number}, this->{self.field_name});"
|
||||
|
||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||
field_id_size = self.calculate_field_id_size()
|
||||
if force:
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
from tests.testing_helpers import ComponentManifestOverride
|
||||
|
||||
|
||||
def override_manifest(manifest: ComponentManifestOverride) -> None:
|
||||
manifest.enable_codegen()
|
||||
@@ -0,0 +1,61 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
|
||||
namespace esphome::binary_sensor::benchmarks {
|
||||
|
||||
static constexpr int kInnerIterations = 2000;
|
||||
|
||||
// Benchmark: publish_state with alternating values (forces state change every time)
|
||||
static void BinarySensorPublish_Alternating(benchmark::State &state) {
|
||||
BinarySensor sensor;
|
||||
|
||||
// First publish to establish initial state
|
||||
sensor.publish_initial_state(false);
|
||||
|
||||
for (auto _ : state) {
|
||||
for (int i = 0; i < kInnerIterations; i++) {
|
||||
sensor.publish_state(i % 2 == 0);
|
||||
}
|
||||
benchmark::DoNotOptimize(sensor.state);
|
||||
}
|
||||
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
||||
}
|
||||
BENCHMARK(BinarySensorPublish_Alternating);
|
||||
|
||||
// Benchmark: publish_state with same value (tests dedup fast path)
|
||||
static void BinarySensorPublish_NoChange(benchmark::State &state) {
|
||||
BinarySensor sensor;
|
||||
|
||||
sensor.publish_initial_state(true);
|
||||
|
||||
for (auto _ : state) {
|
||||
for (int i = 0; i < kInnerIterations; i++) {
|
||||
sensor.publish_state(true);
|
||||
}
|
||||
benchmark::DoNotOptimize(sensor.state);
|
||||
}
|
||||
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
||||
}
|
||||
BENCHMARK(BinarySensorPublish_NoChange);
|
||||
|
||||
// Benchmark: publish_state with a callback registered
|
||||
static void BinarySensorPublish_WithCallback(benchmark::State &state) {
|
||||
BinarySensor sensor;
|
||||
|
||||
int callback_count = 0;
|
||||
sensor.add_on_state_callback([&callback_count](bool) { callback_count++; });
|
||||
|
||||
sensor.publish_initial_state(false);
|
||||
|
||||
for (auto _ : state) {
|
||||
for (int i = 0; i < kInnerIterations; i++) {
|
||||
sensor.publish_state(i % 2 == 0);
|
||||
}
|
||||
benchmark::DoNotOptimize(callback_count);
|
||||
}
|
||||
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
||||
}
|
||||
BENCHMARK(BinarySensorPublish_WithCallback);
|
||||
|
||||
} // namespace esphome::binary_sensor::benchmarks
|
||||
@@ -0,0 +1 @@
|
||||
binary_sensor:
|
||||
@@ -0,0 +1,12 @@
|
||||
import esphome.codegen as cg
|
||||
from tests.testing_helpers import ComponentManifestOverride
|
||||
|
||||
|
||||
def override_manifest(manifest: ComponentManifestOverride) -> None:
|
||||
# Sensor filter benchmarks need USE_SENSOR_FILTER defined.
|
||||
# We use a custom to_code instead of enable_codegen() to avoid
|
||||
# pulling in the full sensor component setup.
|
||||
async def to_code(config):
|
||||
cg.add_define("USE_SENSOR_FILTER")
|
||||
|
||||
manifest.to_code = to_code
|
||||
@@ -0,0 +1,78 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/sensor/filter.h"
|
||||
|
||||
namespace esphome::sensor::benchmarks {
|
||||
|
||||
static constexpr int kInnerIterations = 2000;
|
||||
|
||||
// Benchmark: sensor publish through a SlidingWindowMovingAverageFilter (window=5, send_every=1)
|
||||
static void SensorFilter_SlidingWindowAvg(benchmark::State &state) {
|
||||
Sensor sensor;
|
||||
|
||||
// Create filter: window_size=5, send_every=1, send_first_at=1
|
||||
auto *filter = new SlidingWindowMovingAverageFilter(5, 1, 1);
|
||||
sensor.add_filter(filter);
|
||||
|
||||
float value = 0.0f;
|
||||
for (auto _ : state) {
|
||||
for (int i = 0; i < kInnerIterations; i++) {
|
||||
sensor.publish_state(value);
|
||||
value += 0.1f;
|
||||
if (value > 1000.0f)
|
||||
value = 0.0f;
|
||||
}
|
||||
benchmark::DoNotOptimize(sensor.state);
|
||||
}
|
||||
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
||||
}
|
||||
BENCHMARK(SensorFilter_SlidingWindowAvg);
|
||||
|
||||
// Benchmark: sensor publish through ExponentialMovingAverageFilter
|
||||
static void SensorFilter_ExponentialMovingAvg(benchmark::State &state) {
|
||||
Sensor sensor;
|
||||
|
||||
// alpha=0.1, send_every=1, send_first_at=1
|
||||
auto *filter = new ExponentialMovingAverageFilter(0.1f, 1, 1);
|
||||
sensor.add_filter(filter);
|
||||
|
||||
float value = 0.0f;
|
||||
for (auto _ : state) {
|
||||
for (int i = 0; i < kInnerIterations; i++) {
|
||||
sensor.publish_state(value);
|
||||
value += 0.1f;
|
||||
if (value > 1000.0f)
|
||||
value = 0.0f;
|
||||
}
|
||||
benchmark::DoNotOptimize(sensor.state);
|
||||
}
|
||||
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
||||
}
|
||||
BENCHMARK(SensorFilter_ExponentialMovingAvg);
|
||||
|
||||
// Benchmark: sensor publish through a chain of 3 filters (offset + multiply + sliding window)
|
||||
static void SensorFilter_Chain3(benchmark::State &state) {
|
||||
Sensor sensor;
|
||||
|
||||
sensor.add_filters({
|
||||
new OffsetFilter(1.0f),
|
||||
new MultiplyFilter(2.0f),
|
||||
new SlidingWindowMovingAverageFilter(5, 1, 1),
|
||||
});
|
||||
|
||||
float value = 0.0f;
|
||||
for (auto _ : state) {
|
||||
for (int i = 0; i < kInnerIterations; i++) {
|
||||
sensor.publish_state(value);
|
||||
value += 0.1f;
|
||||
if (value > 1000.0f)
|
||||
value = 0.0f;
|
||||
}
|
||||
benchmark::DoNotOptimize(sensor.state);
|
||||
}
|
||||
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
||||
}
|
||||
BENCHMARK(SensorFilter_Chain3);
|
||||
|
||||
} // namespace esphome::sensor::benchmarks
|
||||
@@ -0,0 +1 @@
|
||||
sensor:
|
||||
@@ -8,7 +8,7 @@ def test_deep_sleep_setup(generate_main):
|
||||
main_cpp = generate_main("tests/component_tests/deep_sleep/test_deep_sleep1.yaml")
|
||||
|
||||
assert (
|
||||
"static deep_sleep::DeepSleepComponent *const deepsleep = reinterpret_cast<deep_sleep::DeepSleepComponent *>(deepsleep__pstorage);"
|
||||
"static deep_sleep::DeepSleepComponent *const deepsleep = reinterpret_cast<deep_sleep::DeepSleepComponent *>(deep_sleep__deepsleep__pstorage);"
|
||||
in main_cpp
|
||||
)
|
||||
assert "new(deepsleep) deep_sleep::DeepSleepComponent();" in main_cpp
|
||||
|
||||
@@ -242,11 +242,11 @@ def test_image_generation(
|
||||
main_cpp = generate_main(component_config_path("image_test.yaml"))
|
||||
assert "uint8_t_id[] PROGMEM = {0x24, 0x21, 0x24, 0x21" in main_cpp
|
||||
assert (
|
||||
"alignas(image::Image) static unsigned char cat_img__pstorage[sizeof(image::Image)];"
|
||||
"alignas(image::Image) static unsigned char image__cat_img__pstorage[sizeof(image::Image)];"
|
||||
in main_cpp
|
||||
)
|
||||
assert (
|
||||
"static image::Image *const cat_img = reinterpret_cast<image::Image *>(cat_img__pstorage);"
|
||||
"static image::Image *const cat_img = reinterpret_cast<image::Image *>(image__cat_img__pstorage);"
|
||||
in main_cpp
|
||||
)
|
||||
assert (
|
||||
|
||||
@@ -119,11 +119,11 @@ def test_code_generation(
|
||||
|
||||
main_cpp = generate_main(component_fixture_path("mipi_dsi.yaml"))
|
||||
assert (
|
||||
"alignas(mipi_dsi::MIPI_DSI) static unsigned char p4_nano__pstorage[sizeof(mipi_dsi::MIPI_DSI)];"
|
||||
"alignas(mipi_dsi::MIPI_DSI) static unsigned char mipi_dsi__p4_nano__pstorage[sizeof(mipi_dsi::MIPI_DSI)];"
|
||||
in main_cpp
|
||||
)
|
||||
assert (
|
||||
"static mipi_dsi::MIPI_DSI *const p4_nano = reinterpret_cast<mipi_dsi::MIPI_DSI *>(p4_nano__pstorage);"
|
||||
"static mipi_dsi::MIPI_DSI *const p4_nano = reinterpret_cast<mipi_dsi::MIPI_DSI *>(mipi_dsi__p4_nano__pstorage);"
|
||||
in main_cpp
|
||||
)
|
||||
assert (
|
||||
|
||||
@@ -13,11 +13,11 @@ def test_status_led_generation(
|
||||
"""Test status_led generation."""
|
||||
main_cpp = generate_main(component_config_path("status_led_test.yaml"))
|
||||
assert (
|
||||
"alignas(status_led::StatusLED) static unsigned char status_led_statusled_id__pstorage[sizeof(status_led::StatusLED)];"
|
||||
"alignas(status_led::StatusLED) static unsigned char status_led__status_led_statusled_id__pstorage[sizeof(status_led::StatusLED)];"
|
||||
in main_cpp
|
||||
)
|
||||
assert (
|
||||
"static status_led::StatusLED *const status_led_statusled_id = reinterpret_cast<status_led::StatusLED *>(status_led_statusled_id__pstorage);"
|
||||
"static status_led::StatusLED *const status_led_statusled_id = reinterpret_cast<status_led::StatusLED *>(status_led__status_led_statusled_id__pstorage);"
|
||||
in main_cpp
|
||||
)
|
||||
assert "new(status_led_statusled_id) status_led::StatusLED(" in main_cpp
|
||||
|
||||
@@ -16,7 +16,7 @@ class MockUARTComponent : public uart::UARTComponent {
|
||||
MOCK_METHOD(bool, read_array, (uint8_t * data, size_t len), (override));
|
||||
MOCK_METHOD(bool, peek_byte, (uint8_t * data), (override));
|
||||
MOCK_METHOD(size_t, available, (), (override));
|
||||
MOCK_METHOD(uart::FlushResult, flush, (), (override));
|
||||
MOCK_METHOD(uart::UARTFlushResult, flush, (), (override));
|
||||
MOCK_METHOD(void, check_logger_conflict, (), (override));
|
||||
};
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class MockUARTComponent : public UARTComponent {
|
||||
MOCK_METHOD(bool, read_array, (uint8_t * data, size_t len), (override));
|
||||
MOCK_METHOD(bool, peek_byte, (uint8_t * data), (override));
|
||||
MOCK_METHOD(size_t, available, (), (override));
|
||||
MOCK_METHOD(FlushResult, flush, (), (override));
|
||||
MOCK_METHOD(UARTFlushResult, flush, (), (override));
|
||||
MOCK_METHOD(void, check_logger_conflict, (), (override));
|
||||
};
|
||||
|
||||
|
||||
@@ -153,9 +153,9 @@ bool MockUartComponent::read_array(uint8_t *data, size_t len) {
|
||||
|
||||
size_t MockUartComponent::available() { return this->rx_buffer_.size(); }
|
||||
|
||||
uart::FlushResult MockUartComponent::flush() {
|
||||
uart::UARTFlushResult MockUartComponent::flush() {
|
||||
// Nothing to flush in mock
|
||||
return uart::FlushResult::ASSUMED_SUCCESS;
|
||||
return uart::UARTFlushResult::UART_FLUSH_RESULT_ASSUMED_SUCCESS;
|
||||
}
|
||||
|
||||
void MockUartComponent::set_rx_full_threshold(size_t rx_full_threshold) {
|
||||
|
||||
@@ -28,7 +28,7 @@ class MockUartComponent : public uart::UARTComponent, public Component {
|
||||
bool peek_byte(uint8_t *data) override;
|
||||
bool read_array(uint8_t *data, size_t len) override;
|
||||
size_t available() override;
|
||||
uart::FlushResult flush() override;
|
||||
uart::UARTFlushResult flush() override;
|
||||
void set_rx_full_threshold(size_t rx_full_threshold) override;
|
||||
void set_rx_timeout(size_t rx_timeout) override;
|
||||
|
||||
|
||||
@@ -79,9 +79,15 @@ async def test_uart_mock_ld2412(
|
||||
],
|
||||
)
|
||||
|
||||
# Signal when we see recovery frame values
|
||||
# Signal when we see all recovery frame values
|
||||
recovery_received = collector.add_waiter(
|
||||
lambda: pytest.approx(50.0) in collector.sensor_states["moving_distance"]
|
||||
lambda: (
|
||||
pytest.approx(50.0) in collector.sensor_states["moving_distance"]
|
||||
and pytest.approx(75.0) in collector.sensor_states["still_distance"]
|
||||
and pytest.approx(100.0) in collector.sensor_states["moving_energy"]
|
||||
and pytest.approx(80.0) in collector.sensor_states["still_energy"]
|
||||
and pytest.approx(50.0) in collector.sensor_states["detection_distance"]
|
||||
)
|
||||
)
|
||||
|
||||
async with (
|
||||
@@ -150,23 +156,12 @@ async def test_uart_mock_ld2412(
|
||||
)
|
||||
|
||||
# Recovery frame: moving=50, still=75, energy=100/80, detect=50
|
||||
recovery_idx = next(
|
||||
i
|
||||
for i, v in enumerate(collector.sensor_states["moving_distance"])
|
||||
if v == pytest.approx(50.0)
|
||||
)
|
||||
assert collector.sensor_states["still_distance"][recovery_idx] == pytest.approx(
|
||||
75.0
|
||||
)
|
||||
assert collector.sensor_states["moving_energy"][recovery_idx] == pytest.approx(
|
||||
100.0
|
||||
)
|
||||
assert collector.sensor_states["still_energy"][recovery_idx] == pytest.approx(
|
||||
80.0
|
||||
)
|
||||
assert collector.sensor_states["detection_distance"][
|
||||
recovery_idx
|
||||
] == pytest.approx(50.0)
|
||||
# Check values exist (waiter already ensured all are present)
|
||||
assert pytest.approx(50.0) in collector.sensor_states["moving_distance"]
|
||||
assert pytest.approx(75.0) in collector.sensor_states["still_distance"]
|
||||
assert pytest.approx(100.0) in collector.sensor_states["moving_energy"]
|
||||
assert pytest.approx(80.0) in collector.sensor_states["still_energy"]
|
||||
assert pytest.approx(50.0) in collector.sensor_states["detection_distance"]
|
||||
|
||||
# Verify binary sensors detected targets (from Phase 1 frame)
|
||||
assert collector.binary_states["has_target"][0] is True
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
"""Tests for __pstorage symbol attribution in memory analyzer."""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from esphome.analyze_memory import _PSTORAGE_SUFFIX, MemoryAnalyzer
|
||||
|
||||
|
||||
def _make_analyzer(external_components: set[str] | None = None) -> MemoryAnalyzer:
|
||||
"""Create a MemoryAnalyzer with mocked dependencies."""
|
||||
with patch.object(MemoryAnalyzer, "__init__", lambda self, *a, **kw: None):
|
||||
analyzer = MemoryAnalyzer.__new__(MemoryAnalyzer)
|
||||
analyzer.external_components = external_components or set()
|
||||
return analyzer
|
||||
|
||||
|
||||
def test_pstorage_suffix_constant() -> None:
|
||||
"""Verify the suffix constant matches what codegen produces."""
|
||||
assert _PSTORAGE_SUFFIX == "__pstorage"
|
||||
|
||||
|
||||
def test_match_pstorage_simple_component() -> None:
|
||||
"""Simple component name like 'logger'."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component("logger__logger_id__pstorage")
|
||||
assert result == "[esphome]logger"
|
||||
|
||||
|
||||
def test_match_pstorage_underscore_component() -> None:
|
||||
"""Component with underscore like 'web_server'."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component("web_server__webserver_id__pstorage")
|
||||
assert result == "[esphome]web_server"
|
||||
|
||||
|
||||
def test_match_pstorage_api() -> None:
|
||||
"""API component."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component("api__apiserver_id__pstorage")
|
||||
assert result == "[esphome]api"
|
||||
|
||||
|
||||
def test_match_pstorage_deep_sleep() -> None:
|
||||
"""Component with underscore: deep_sleep."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component("deep_sleep__deepsleep__pstorage")
|
||||
assert result == "[esphome]deep_sleep"
|
||||
|
||||
|
||||
def test_match_pstorage_status_led() -> None:
|
||||
"""Component with underscore: status_led."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component("status_led__statusled_id__pstorage")
|
||||
assert result == "[esphome]status_led"
|
||||
|
||||
|
||||
def test_match_pstorage_external_component() -> None:
|
||||
"""External component should be attributed correctly."""
|
||||
analyzer = _make_analyzer(external_components={"my_custom"})
|
||||
result = analyzer._match_pstorage_component("my_custom__thing_id__pstorage")
|
||||
assert result == "[external]my_custom"
|
||||
|
||||
|
||||
def test_match_pstorage_no_dunder_returns_none() -> None:
|
||||
"""Symbol without double underscore separator returns None."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component("something__pstorage")
|
||||
assert result is None
|
||||
|
||||
|
||||
def test_match_pstorage_unknown_component_returns_none() -> None:
|
||||
"""Unknown component namespace returns None."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component("nonexistent__thing_id__pstorage")
|
||||
assert result is None
|
||||
|
||||
|
||||
def test_match_pstorage_esphome_component() -> None:
|
||||
"""esphome:: namespace types map to the esphome component."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component(
|
||||
"esphome__esphomeotacomponent_id__pstorage"
|
||||
)
|
||||
assert result == "[esphome]esphome"
|
||||
|
||||
|
||||
def test_match_pstorage_user_id_with_component_prefix() -> None:
|
||||
"""User-chosen ID that happens to contain a component name."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component("logger__relay1__pstorage")
|
||||
assert result == "[esphome]logger"
|
||||
@@ -1,6 +1,7 @@
|
||||
import pytest
|
||||
|
||||
from esphome import codegen as cg
|
||||
from esphome.cpp_generator import _extract_component_ns
|
||||
|
||||
|
||||
# Test interface remains the same.
|
||||
@@ -75,3 +76,29 @@ from esphome import codegen as cg
|
||||
)
|
||||
def test_exists(attr):
|
||||
assert hasattr(cg, attr)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("type_str", "expected"),
|
||||
(
|
||||
("esphome::dsmr::Dsmr", "dsmr"),
|
||||
("esphome::logger::Logger", "logger"),
|
||||
("esphome::web_server::WebServer", "web_server"),
|
||||
("esphome::deep_sleep::DeepSleep", "deep_sleep"),
|
||||
("esphome::Component", "esphome"),
|
||||
("Logger", "esphome"),
|
||||
# Template types with :: in template args must not confuse extraction
|
||||
(
|
||||
"esphome::Automation<std::optional<bool>, std::optional<bool>>",
|
||||
"esphome",
|
||||
),
|
||||
(
|
||||
"esphome::StatelessLambdaAction<std::optional<bool>, std::optional<bool>>",
|
||||
"esphome",
|
||||
),
|
||||
# Namespaced template type
|
||||
("esphome::sensor::Sensor<std::string>", "sensor"),
|
||||
),
|
||||
)
|
||||
def test_extract_component_ns(type_str, expected):
|
||||
assert _extract_component_ns(type_str) == expected
|
||||
|
||||
Reference in New Issue
Block a user