mirror of
https://github.com/esphome/esphome.git
synced 2026-02-28 09:54:19 -07:00
Merge branch 'dev' into setup_heap_stats
This commit is contained in:
@@ -431,6 +431,14 @@ def run_miniterm(config: ConfigType, port: str, args) -> int:
|
||||
return 1
|
||||
_LOGGER.info("Starting log output from %s with baud rate %s", port, baud_rate)
|
||||
|
||||
process_stacktrace = None
|
||||
|
||||
try:
|
||||
module = importlib.import_module("esphome.components." + CORE.target_platform)
|
||||
process_stacktrace = getattr(module, "process_stacktrace")
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
backtrace_state = False
|
||||
ser = serial.Serial()
|
||||
ser.baudrate = baud_rate
|
||||
@@ -472,9 +480,14 @@ def run_miniterm(config: ConfigType, port: str, args) -> int:
|
||||
)
|
||||
safe_print(parser.parse_line(line, time_str))
|
||||
|
||||
backtrace_state = platformio_api.process_stacktrace(
|
||||
config, line, backtrace_state=backtrace_state
|
||||
)
|
||||
if process_stacktrace:
|
||||
backtrace_state = process_stacktrace(
|
||||
config, line, backtrace_state
|
||||
)
|
||||
else:
|
||||
backtrace_state = platformio_api.process_stacktrace(
|
||||
config, line, backtrace_state=backtrace_state
|
||||
)
|
||||
except serial.SerialException:
|
||||
_LOGGER.error("Serial port closed!")
|
||||
return 0
|
||||
@@ -944,12 +957,6 @@ def command_clean_all(args: ArgsProtocol) -> int | None:
|
||||
return 0
|
||||
|
||||
|
||||
def command_mqtt_fingerprint(args: ArgsProtocol, config: ConfigType) -> int | None:
|
||||
from esphome import mqtt
|
||||
|
||||
return mqtt.get_fingerprint(config)
|
||||
|
||||
|
||||
def command_version(args: ArgsProtocol) -> int | None:
|
||||
safe_print(f"Version: {const.__version__}")
|
||||
return 0
|
||||
@@ -1237,7 +1244,6 @@ POST_CONFIG_ACTIONS = {
|
||||
"run": command_run,
|
||||
"clean": command_clean,
|
||||
"clean-mqtt": command_clean_mqtt,
|
||||
"mqtt-fingerprint": command_mqtt_fingerprint,
|
||||
"idedata": command_idedata,
|
||||
"rename": command_rename,
|
||||
"discover": command_discover,
|
||||
@@ -1451,13 +1457,6 @@ def parse_args(argv):
|
||||
)
|
||||
parser_wizard.add_argument("configuration", help="Your YAML configuration file.")
|
||||
|
||||
parser_fingerprint = subparsers.add_parser(
|
||||
"mqtt-fingerprint", help="Get the SSL fingerprint from a MQTT broker."
|
||||
)
|
||||
parser_fingerprint.add_argument(
|
||||
"configuration", help="Your YAML configuration file(s).", nargs="+"
|
||||
)
|
||||
|
||||
subparsers.add_parser("version", help="Print the ESPHome version and exit.")
|
||||
|
||||
parser_clean = subparsers.add_parser(
|
||||
|
||||
@@ -347,9 +347,7 @@ uint16_t APIConnection::encode_message_to_buffer(ProtoMessage &msg, uint8_t mess
|
||||
#endif
|
||||
|
||||
// Calculate size
|
||||
ProtoSize size_calc;
|
||||
msg.calculate_size(size_calc);
|
||||
uint32_t calculated_size = size_calc.get_size();
|
||||
uint32_t calculated_size = msg.calculated_size();
|
||||
|
||||
// Cache frame sizes to avoid repeated virtual calls
|
||||
const uint8_t header_padding = conn->helper_->frame_header_padding();
|
||||
@@ -377,19 +375,14 @@ uint16_t APIConnection::encode_message_to_buffer(ProtoMessage &msg, uint8_t mess
|
||||
shared_buf.resize(current_size + footer_size + header_padding);
|
||||
}
|
||||
|
||||
// Encode directly into buffer
|
||||
size_t size_before_encode = shared_buf.size();
|
||||
msg.encode({&shared_buf});
|
||||
// Pre-resize buffer to include payload, then encode through raw pointer
|
||||
size_t write_start = shared_buf.size();
|
||||
shared_buf.resize(write_start + calculated_size);
|
||||
ProtoWriteBuffer buffer{&shared_buf, write_start};
|
||||
msg.encode(buffer);
|
||||
|
||||
// Calculate actual encoded size (not including header that was already added)
|
||||
size_t actual_payload_size = shared_buf.size() - size_before_encode;
|
||||
|
||||
// Return actual total size (header + actual payload + footer)
|
||||
size_t actual_total_size = header_padding + actual_payload_size + footer_size;
|
||||
|
||||
// Verify that calculate_size() returned the correct value
|
||||
assert(calculated_size == actual_payload_size);
|
||||
return static_cast<uint16_t>(actual_total_size);
|
||||
// Return total size (header + payload + footer)
|
||||
return static_cast<uint16_t>(header_padding + calculated_size + footer_size);
|
||||
}
|
||||
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
@@ -1854,12 +1847,14 @@ bool APIConnection::try_to_clear_buffer(bool log_out_of_space) {
|
||||
return false;
|
||||
}
|
||||
bool APIConnection::send_message_impl(const ProtoMessage &msg, uint8_t message_type) {
|
||||
ProtoSize size;
|
||||
msg.calculate_size(size);
|
||||
uint32_t payload_size = msg.calculated_size();
|
||||
std::vector<uint8_t> &shared_buf = this->parent_->get_shared_buffer_ref();
|
||||
this->prepare_first_message_buffer(shared_buf, size.get_size());
|
||||
msg.encode({&shared_buf});
|
||||
return this->send_buffer({&shared_buf}, message_type);
|
||||
this->prepare_first_message_buffer(shared_buf, payload_size);
|
||||
size_t write_start = shared_buf.size();
|
||||
shared_buf.resize(write_start + payload_size);
|
||||
ProtoWriteBuffer buffer{&shared_buf, write_start};
|
||||
msg.encode(buffer);
|
||||
return this->send_buffer(ProtoWriteBuffer{&shared_buf}, message_type);
|
||||
}
|
||||
bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) {
|
||||
const bool is_log_message = (message_type == SubscribeLogsResponse::MESSAGE_TYPE);
|
||||
|
||||
@@ -31,7 +31,7 @@ bool HelloRequest::decode_length(uint32_t field_id, ProtoLengthDelimited value)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void HelloResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void HelloResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint32(1, this->api_version_major);
|
||||
buffer.encode_uint32(2, this->api_version_minor);
|
||||
buffer.encode_string(3, this->server_info);
|
||||
@@ -44,7 +44,7 @@ void HelloResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_length(1, this->name.size());
|
||||
}
|
||||
#ifdef USE_AREAS
|
||||
void AreaInfo::encode(ProtoWriteBuffer buffer) const {
|
||||
void AreaInfo::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint32(1, this->area_id);
|
||||
buffer.encode_string(2, this->name);
|
||||
}
|
||||
@@ -54,7 +54,7 @@ void AreaInfo::calculate_size(ProtoSize &size) const {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_DEVICES
|
||||
void DeviceInfo::encode(ProtoWriteBuffer buffer) const {
|
||||
void DeviceInfo::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint32(1, this->device_id);
|
||||
buffer.encode_string(2, this->name);
|
||||
buffer.encode_uint32(3, this->area_id);
|
||||
@@ -65,7 +65,7 @@ void DeviceInfo::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->area_id);
|
||||
}
|
||||
#endif
|
||||
void DeviceInfoResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void DeviceInfoResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(2, this->name);
|
||||
buffer.encode_string(3, this->mac_address);
|
||||
buffer.encode_string(4, this->esphome_version);
|
||||
@@ -111,7 +111,7 @@ void DeviceInfoResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_AREAS
|
||||
buffer.encode_message(22, this->area);
|
||||
buffer.encode_message(22, this->area, false);
|
||||
#endif
|
||||
#ifdef USE_ZWAVE_PROXY
|
||||
buffer.encode_uint32(23, this->zwave_proxy_feature_flags);
|
||||
@@ -176,7 +176,7 @@ void DeviceInfoResponse::calculate_size(ProtoSize &size) const {
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
void ListEntitiesBinarySensorResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesBinarySensorResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -206,7 +206,7 @@ void ListEntitiesBinarySensorResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void BinarySensorStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void BinarySensorStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_bool(2, this->state);
|
||||
buffer.encode_bool(3, this->missing_state);
|
||||
@@ -224,7 +224,7 @@ void BinarySensorStateResponse::calculate_size(ProtoSize &size) const {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_COVER
|
||||
void ListEntitiesCoverResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesCoverResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -260,7 +260,7 @@ void ListEntitiesCoverResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void CoverStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void CoverStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_float(3, this->position);
|
||||
buffer.encode_float(4, this->tilt);
|
||||
@@ -317,7 +317,7 @@ bool CoverCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_FAN
|
||||
void ListEntitiesFanResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesFanResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -359,7 +359,7 @@ void ListEntitiesFanResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void FanStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void FanStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_bool(2, this->state);
|
||||
buffer.encode_bool(3, this->oscillating);
|
||||
@@ -443,7 +443,7 @@ bool FanCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_LIGHT
|
||||
void ListEntitiesLightResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesLightResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -489,7 +489,7 @@ void ListEntitiesLightResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(2, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void LightStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void LightStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_bool(2, this->state);
|
||||
buffer.encode_float(3, this->brightness);
|
||||
@@ -635,7 +635,7 @@ bool LightCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SENSOR
|
||||
void ListEntitiesSensorResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesSensorResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -671,7 +671,7 @@ void ListEntitiesSensorResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void SensorStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void SensorStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_float(2, this->state);
|
||||
buffer.encode_bool(3, this->missing_state);
|
||||
@@ -689,7 +689,7 @@ void SensorStateResponse::calculate_size(ProtoSize &size) const {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SWITCH
|
||||
void ListEntitiesSwitchResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesSwitchResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -719,7 +719,7 @@ void ListEntitiesSwitchResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void SwitchStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void SwitchStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_bool(2, this->state);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -760,7 +760,7 @@ bool SwitchCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
void ListEntitiesTextSensorResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesTextSensorResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -788,7 +788,7 @@ void ListEntitiesTextSensorResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void TextSensorStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void TextSensorStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_string(2, this->state);
|
||||
buffer.encode_bool(3, this->missing_state);
|
||||
@@ -818,7 +818,7 @@ bool SubscribeLogsRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void SubscribeLogsResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void SubscribeLogsResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint32(1, static_cast<uint32_t>(this->level));
|
||||
buffer.encode_bytes(3, this->message_ptr_, this->message_len_);
|
||||
}
|
||||
@@ -839,11 +839,11 @@ bool NoiseEncryptionSetKeyRequest::decode_length(uint32_t field_id, ProtoLengthD
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void NoiseEncryptionSetKeyResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_bool(1, this->success); }
|
||||
void NoiseEncryptionSetKeyResponse::encode(ProtoWriteBuffer &buffer) const { buffer.encode_bool(1, this->success); }
|
||||
void NoiseEncryptionSetKeyResponse::calculate_size(ProtoSize &size) const { size.add_bool(1, this->success); }
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_SERVICES
|
||||
void HomeassistantServiceMap::encode(ProtoWriteBuffer buffer) const {
|
||||
void HomeassistantServiceMap::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->key);
|
||||
buffer.encode_string(2, this->value);
|
||||
}
|
||||
@@ -851,7 +851,7 @@ void HomeassistantServiceMap::calculate_size(ProtoSize &size) const {
|
||||
size.add_length(1, this->key.size());
|
||||
size.add_length(1, this->value.size());
|
||||
}
|
||||
void HomeassistantActionRequest::encode(ProtoWriteBuffer buffer) const {
|
||||
void HomeassistantActionRequest::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->service);
|
||||
for (auto &it : this->data) {
|
||||
buffer.encode_message(2, it);
|
||||
@@ -924,7 +924,7 @@ bool HomeassistantActionResponse::decode_length(uint32_t field_id, ProtoLengthDe
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
void SubscribeHomeAssistantStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void SubscribeHomeAssistantStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->entity_id);
|
||||
buffer.encode_string(2, this->attribute);
|
||||
buffer.encode_bool(3, this->once);
|
||||
@@ -976,7 +976,7 @@ bool GetTimeResponse::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
return true;
|
||||
}
|
||||
#ifdef USE_API_USER_DEFINED_ACTIONS
|
||||
void ListEntitiesServicesArgument::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesServicesArgument::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->name);
|
||||
buffer.encode_uint32(2, static_cast<uint32_t>(this->type));
|
||||
}
|
||||
@@ -984,7 +984,7 @@ void ListEntitiesServicesArgument::calculate_size(ProtoSize &size) const {
|
||||
size.add_length(1, this->name.size());
|
||||
size.add_uint32(1, static_cast<uint32_t>(this->type));
|
||||
}
|
||||
void ListEntitiesServicesResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesServicesResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->name);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
for (auto &it : this->args) {
|
||||
@@ -1103,7 +1103,7 @@ void ExecuteServiceRequest::decode(const uint8_t *buffer, size_t length) {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES
|
||||
void ExecuteServiceResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ExecuteServiceResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint32(1, this->call_id);
|
||||
buffer.encode_bool(2, this->success);
|
||||
buffer.encode_string(3, this->error_message);
|
||||
@@ -1121,7 +1121,7 @@ void ExecuteServiceResponse::calculate_size(ProtoSize &size) const {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_CAMERA
|
||||
void ListEntitiesCameraResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesCameraResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -1147,7 +1147,7 @@ void ListEntitiesCameraResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void CameraImageResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void CameraImageResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_bytes(2, this->data_ptr_, this->data_len_);
|
||||
buffer.encode_bool(3, this->done);
|
||||
@@ -1178,7 +1178,7 @@ bool CameraImageRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_CLIMATE
|
||||
void ListEntitiesClimateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesClimateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -1276,7 +1276,7 @@ void ListEntitiesClimateResponse::calculate_size(ProtoSize &size) const {
|
||||
#endif
|
||||
size.add_uint32(2, this->feature_flags);
|
||||
}
|
||||
void ClimateStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ClimateStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_uint32(2, static_cast<uint32_t>(this->mode));
|
||||
buffer.encode_float(3, this->current_temperature);
|
||||
@@ -1407,7 +1407,7 @@ bool ClimateCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_WATER_HEATER
|
||||
void ListEntitiesWaterHeaterResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesWaterHeaterResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -1449,7 +1449,7 @@ void ListEntitiesWaterHeaterResponse::calculate_size(ProtoSize &size) const {
|
||||
}
|
||||
size.add_uint32(1, this->supported_features);
|
||||
}
|
||||
void WaterHeaterStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void WaterHeaterStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_float(2, this->current_temperature);
|
||||
buffer.encode_float(3, this->target_temperature);
|
||||
@@ -1515,7 +1515,7 @@ bool WaterHeaterCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_NUMBER
|
||||
void ListEntitiesNumberResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesNumberResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -1553,7 +1553,7 @@ void ListEntitiesNumberResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void NumberStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void NumberStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_float(2, this->state);
|
||||
buffer.encode_bool(3, this->missing_state);
|
||||
@@ -1596,7 +1596,7 @@ bool NumberCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SELECT
|
||||
void ListEntitiesSelectResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesSelectResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -1630,7 +1630,7 @@ void ListEntitiesSelectResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void SelectStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void SelectStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_string(2, this->state);
|
||||
buffer.encode_bool(3, this->missing_state);
|
||||
@@ -1681,7 +1681,7 @@ bool SelectCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SIREN
|
||||
void ListEntitiesSirenResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesSirenResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -1719,7 +1719,7 @@ void ListEntitiesSirenResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void SirenStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void SirenStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_bool(2, this->state);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -1789,7 +1789,7 @@ bool SirenCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_LOCK
|
||||
void ListEntitiesLockResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesLockResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -1823,7 +1823,7 @@ void ListEntitiesLockResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void LockStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void LockStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_uint32(2, static_cast<uint32_t>(this->state));
|
||||
#ifdef USE_DEVICES
|
||||
@@ -1878,7 +1878,7 @@ bool LockCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_BUTTON
|
||||
void ListEntitiesButtonResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesButtonResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -1930,7 +1930,7 @@ bool ButtonCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_MEDIA_PLAYER
|
||||
void MediaPlayerSupportedFormat::encode(ProtoWriteBuffer buffer) const {
|
||||
void MediaPlayerSupportedFormat::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->format);
|
||||
buffer.encode_uint32(2, this->sample_rate);
|
||||
buffer.encode_uint32(3, this->num_channels);
|
||||
@@ -1944,7 +1944,7 @@ void MediaPlayerSupportedFormat::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, static_cast<uint32_t>(this->purpose));
|
||||
size.add_uint32(1, this->sample_bytes);
|
||||
}
|
||||
void ListEntitiesMediaPlayerResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesMediaPlayerResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -1978,7 +1978,7 @@ void ListEntitiesMediaPlayerResponse::calculate_size(ProtoSize &size) const {
|
||||
#endif
|
||||
size.add_uint32(1, this->feature_flags);
|
||||
}
|
||||
void MediaPlayerStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void MediaPlayerStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_uint32(2, static_cast<uint32_t>(this->state));
|
||||
buffer.encode_float(3, this->volume);
|
||||
@@ -2062,7 +2062,7 @@ bool SubscribeBluetoothLEAdvertisementsRequest::decode_varint(uint32_t field_id,
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void BluetoothLERawAdvertisement::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothLERawAdvertisement::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint64(1, this->address);
|
||||
buffer.encode_sint32(2, this->rssi);
|
||||
buffer.encode_uint32(3, this->address_type);
|
||||
@@ -2074,7 +2074,7 @@ void BluetoothLERawAdvertisement::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->address_type);
|
||||
size.add_length(1, this->data_len);
|
||||
}
|
||||
void BluetoothLERawAdvertisementsResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothLERawAdvertisementsResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
for (uint16_t i = 0; i < this->advertisements_len; i++) {
|
||||
buffer.encode_message(1, this->advertisements[i]);
|
||||
}
|
||||
@@ -2103,7 +2103,7 @@ bool BluetoothDeviceRequest::decode_varint(uint32_t field_id, ProtoVarInt value)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void BluetoothDeviceConnectionResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothDeviceConnectionResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint64(1, this->address);
|
||||
buffer.encode_bool(2, this->connected);
|
||||
buffer.encode_uint32(3, this->mtu);
|
||||
@@ -2125,7 +2125,7 @@ bool BluetoothGATTGetServicesRequest::decode_varint(uint32_t field_id, ProtoVarI
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void BluetoothGATTDescriptor::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothGATTDescriptor::encode(ProtoWriteBuffer &buffer) const {
|
||||
if (this->uuid[0] != 0 || this->uuid[1] != 0) {
|
||||
buffer.encode_uint64(1, this->uuid[0], true);
|
||||
buffer.encode_uint64(1, this->uuid[1], true);
|
||||
@@ -2141,7 +2141,7 @@ void BluetoothGATTDescriptor::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->handle);
|
||||
size.add_uint32(1, this->short_uuid);
|
||||
}
|
||||
void BluetoothGATTCharacteristic::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothGATTCharacteristic::encode(ProtoWriteBuffer &buffer) const {
|
||||
if (this->uuid[0] != 0 || this->uuid[1] != 0) {
|
||||
buffer.encode_uint64(1, this->uuid[0], true);
|
||||
buffer.encode_uint64(1, this->uuid[1], true);
|
||||
@@ -2163,7 +2163,7 @@ void BluetoothGATTCharacteristic::calculate_size(ProtoSize &size) const {
|
||||
size.add_repeated_message(1, this->descriptors);
|
||||
size.add_uint32(1, this->short_uuid);
|
||||
}
|
||||
void BluetoothGATTService::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothGATTService::encode(ProtoWriteBuffer &buffer) const {
|
||||
if (this->uuid[0] != 0 || this->uuid[1] != 0) {
|
||||
buffer.encode_uint64(1, this->uuid[0], true);
|
||||
buffer.encode_uint64(1, this->uuid[1], true);
|
||||
@@ -2183,7 +2183,7 @@ void BluetoothGATTService::calculate_size(ProtoSize &size) const {
|
||||
size.add_repeated_message(1, this->characteristics);
|
||||
size.add_uint32(1, this->short_uuid);
|
||||
}
|
||||
void BluetoothGATTGetServicesResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothGATTGetServicesResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint64(1, this->address);
|
||||
for (auto &it : this->services) {
|
||||
buffer.encode_message(2, it);
|
||||
@@ -2193,7 +2193,7 @@ void BluetoothGATTGetServicesResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint64(1, this->address);
|
||||
size.add_repeated_message(1, this->services);
|
||||
}
|
||||
void BluetoothGATTGetServicesDoneResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothGATTGetServicesDoneResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint64(1, this->address);
|
||||
}
|
||||
void BluetoothGATTGetServicesDoneResponse::calculate_size(ProtoSize &size) const { size.add_uint64(1, this->address); }
|
||||
@@ -2210,7 +2210,7 @@ bool BluetoothGATTReadRequest::decode_varint(uint32_t field_id, ProtoVarInt valu
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void BluetoothGATTReadResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothGATTReadResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint64(1, this->address);
|
||||
buffer.encode_uint32(2, this->handle);
|
||||
buffer.encode_bytes(3, this->data_ptr_, this->data_len_);
|
||||
@@ -2302,7 +2302,7 @@ bool BluetoothGATTNotifyRequest::decode_varint(uint32_t field_id, ProtoVarInt va
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void BluetoothGATTNotifyDataResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothGATTNotifyDataResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint64(1, this->address);
|
||||
buffer.encode_uint32(2, this->handle);
|
||||
buffer.encode_bytes(3, this->data_ptr_, this->data_len_);
|
||||
@@ -2312,7 +2312,7 @@ void BluetoothGATTNotifyDataResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->handle);
|
||||
size.add_length(1, this->data_len_);
|
||||
}
|
||||
void BluetoothConnectionsFreeResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothConnectionsFreeResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint32(1, this->free);
|
||||
buffer.encode_uint32(2, this->limit);
|
||||
for (const auto &it : this->allocated) {
|
||||
@@ -2330,7 +2330,7 @@ void BluetoothConnectionsFreeResponse::calculate_size(ProtoSize &size) const {
|
||||
}
|
||||
}
|
||||
}
|
||||
void BluetoothGATTErrorResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothGATTErrorResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint64(1, this->address);
|
||||
buffer.encode_uint32(2, this->handle);
|
||||
buffer.encode_int32(3, this->error);
|
||||
@@ -2340,7 +2340,7 @@ void BluetoothGATTErrorResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->handle);
|
||||
size.add_int32(1, this->error);
|
||||
}
|
||||
void BluetoothGATTWriteResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothGATTWriteResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint64(1, this->address);
|
||||
buffer.encode_uint32(2, this->handle);
|
||||
}
|
||||
@@ -2348,7 +2348,7 @@ void BluetoothGATTWriteResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint64(1, this->address);
|
||||
size.add_uint32(1, this->handle);
|
||||
}
|
||||
void BluetoothGATTNotifyResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothGATTNotifyResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint64(1, this->address);
|
||||
buffer.encode_uint32(2, this->handle);
|
||||
}
|
||||
@@ -2356,7 +2356,7 @@ void BluetoothGATTNotifyResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint64(1, this->address);
|
||||
size.add_uint32(1, this->handle);
|
||||
}
|
||||
void BluetoothDevicePairingResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothDevicePairingResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint64(1, this->address);
|
||||
buffer.encode_bool(2, this->paired);
|
||||
buffer.encode_int32(3, this->error);
|
||||
@@ -2366,7 +2366,7 @@ void BluetoothDevicePairingResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_bool(1, this->paired);
|
||||
size.add_int32(1, this->error);
|
||||
}
|
||||
void BluetoothDeviceUnpairingResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothDeviceUnpairingResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint64(1, this->address);
|
||||
buffer.encode_bool(2, this->success);
|
||||
buffer.encode_int32(3, this->error);
|
||||
@@ -2376,7 +2376,7 @@ void BluetoothDeviceUnpairingResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_bool(1, this->success);
|
||||
size.add_int32(1, this->error);
|
||||
}
|
||||
void BluetoothDeviceClearCacheResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothDeviceClearCacheResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint64(1, this->address);
|
||||
buffer.encode_bool(2, this->success);
|
||||
buffer.encode_int32(3, this->error);
|
||||
@@ -2386,7 +2386,7 @@ void BluetoothDeviceClearCacheResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_bool(1, this->success);
|
||||
size.add_int32(1, this->error);
|
||||
}
|
||||
void BluetoothScannerStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void BluetoothScannerStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint32(1, static_cast<uint32_t>(this->state));
|
||||
buffer.encode_uint32(2, static_cast<uint32_t>(this->mode));
|
||||
buffer.encode_uint32(3, static_cast<uint32_t>(this->configured_mode));
|
||||
@@ -2421,7 +2421,7 @@ bool SubscribeVoiceAssistantRequest::decode_varint(uint32_t field_id, ProtoVarIn
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void VoiceAssistantAudioSettings::encode(ProtoWriteBuffer buffer) const {
|
||||
void VoiceAssistantAudioSettings::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint32(1, this->noise_suppression_level);
|
||||
buffer.encode_uint32(2, this->auto_gain);
|
||||
buffer.encode_float(3, this->volume_multiplier);
|
||||
@@ -2431,11 +2431,11 @@ void VoiceAssistantAudioSettings::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->auto_gain);
|
||||
size.add_float(1, this->volume_multiplier);
|
||||
}
|
||||
void VoiceAssistantRequest::encode(ProtoWriteBuffer buffer) const {
|
||||
void VoiceAssistantRequest::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_bool(1, this->start);
|
||||
buffer.encode_string(2, this->conversation_id);
|
||||
buffer.encode_uint32(3, this->flags);
|
||||
buffer.encode_message(4, this->audio_settings);
|
||||
buffer.encode_message(4, this->audio_settings, false);
|
||||
buffer.encode_string(5, this->wake_word_phrase);
|
||||
}
|
||||
void VoiceAssistantRequest::calculate_size(ProtoSize &size) const {
|
||||
@@ -2516,7 +2516,7 @@ bool VoiceAssistantAudio::decode_length(uint32_t field_id, ProtoLengthDelimited
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void VoiceAssistantAudio::encode(ProtoWriteBuffer buffer) const {
|
||||
void VoiceAssistantAudio::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_bytes(1, this->data, this->data_len);
|
||||
buffer.encode_bool(2, this->end);
|
||||
}
|
||||
@@ -2587,9 +2587,9 @@ bool VoiceAssistantAnnounceRequest::decode_length(uint32_t field_id, ProtoLength
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void VoiceAssistantAnnounceFinished::encode(ProtoWriteBuffer buffer) const { buffer.encode_bool(1, this->success); }
|
||||
void VoiceAssistantAnnounceFinished::encode(ProtoWriteBuffer &buffer) const { buffer.encode_bool(1, this->success); }
|
||||
void VoiceAssistantAnnounceFinished::calculate_size(ProtoSize &size) const { size.add_bool(1, this->success); }
|
||||
void VoiceAssistantWakeWord::encode(ProtoWriteBuffer buffer) const {
|
||||
void VoiceAssistantWakeWord::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->id);
|
||||
buffer.encode_string(2, this->wake_word);
|
||||
for (auto &it : this->trained_languages) {
|
||||
@@ -2656,7 +2656,7 @@ bool VoiceAssistantConfigurationRequest::decode_length(uint32_t field_id, ProtoL
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void VoiceAssistantConfigurationResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void VoiceAssistantConfigurationResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
for (auto &it : this->available_wake_words) {
|
||||
buffer.encode_message(1, it);
|
||||
}
|
||||
@@ -2686,7 +2686,7 @@ bool VoiceAssistantSetConfiguration::decode_length(uint32_t field_id, ProtoLengt
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_ALARM_CONTROL_PANEL
|
||||
void ListEntitiesAlarmControlPanelResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesAlarmControlPanelResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -2718,7 +2718,7 @@ void ListEntitiesAlarmControlPanelResponse::calculate_size(ProtoSize &size) cons
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void AlarmControlPanelStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void AlarmControlPanelStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_uint32(2, static_cast<uint32_t>(this->state));
|
||||
#ifdef USE_DEVICES
|
||||
@@ -2770,7 +2770,7 @@ bool AlarmControlPanelCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_TEXT
|
||||
void ListEntitiesTextResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesTextResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -2804,7 +2804,7 @@ void ListEntitiesTextResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void TextStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void TextStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_string(2, this->state);
|
||||
buffer.encode_bool(3, this->missing_state);
|
||||
@@ -2855,7 +2855,7 @@ bool TextCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_DATETIME_DATE
|
||||
void ListEntitiesDateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesDateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -2881,7 +2881,7 @@ void ListEntitiesDateResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void DateStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void DateStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_bool(2, this->missing_state);
|
||||
buffer.encode_uint32(3, this->year);
|
||||
@@ -2934,7 +2934,7 @@ bool DateCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_DATETIME_TIME
|
||||
void ListEntitiesTimeResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesTimeResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -2960,7 +2960,7 @@ void ListEntitiesTimeResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void TimeStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void TimeStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_bool(2, this->missing_state);
|
||||
buffer.encode_uint32(3, this->hour);
|
||||
@@ -3013,7 +3013,7 @@ bool TimeCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_EVENT
|
||||
void ListEntitiesEventResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesEventResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -3049,7 +3049,7 @@ void ListEntitiesEventResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void EventResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void EventResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_string(2, this->event_type);
|
||||
#ifdef USE_DEVICES
|
||||
@@ -3065,7 +3065,7 @@ void EventResponse::calculate_size(ProtoSize &size) const {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_VALVE
|
||||
void ListEntitiesValveResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesValveResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -3099,7 +3099,7 @@ void ListEntitiesValveResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void ValveStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ValveStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_float(2, this->position);
|
||||
buffer.encode_uint32(3, static_cast<uint32_t>(this->current_operation));
|
||||
@@ -3148,7 +3148,7 @@ bool ValveCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_DATETIME_DATETIME
|
||||
void ListEntitiesDateTimeResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesDateTimeResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -3174,7 +3174,7 @@ void ListEntitiesDateTimeResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void DateTimeStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void DateTimeStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_bool(2, this->missing_state);
|
||||
buffer.encode_fixed32(3, this->epoch_seconds);
|
||||
@@ -3217,7 +3217,7 @@ bool DateTimeCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_UPDATE
|
||||
void ListEntitiesUpdateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesUpdateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -3245,7 +3245,7 @@ void ListEntitiesUpdateResponse::calculate_size(ProtoSize &size) const {
|
||||
size.add_uint32(1, this->device_id);
|
||||
#endif
|
||||
}
|
||||
void UpdateStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void UpdateStateResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_fixed32(1, this->key);
|
||||
buffer.encode_bool(2, this->missing_state);
|
||||
buffer.encode_bool(3, this->in_progress);
|
||||
@@ -3314,7 +3314,7 @@ bool ZWaveProxyFrame::decode_length(uint32_t field_id, ProtoLengthDelimited valu
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void ZWaveProxyFrame::encode(ProtoWriteBuffer buffer) const { buffer.encode_bytes(1, this->data, this->data_len); }
|
||||
void ZWaveProxyFrame::encode(ProtoWriteBuffer &buffer) const { buffer.encode_bytes(1, this->data, this->data_len); }
|
||||
void ZWaveProxyFrame::calculate_size(ProtoSize &size) const { size.add_length(1, this->data_len); }
|
||||
bool ZWaveProxyRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
|
||||
switch (field_id) {
|
||||
@@ -3338,7 +3338,7 @@ bool ZWaveProxyRequest::decode_length(uint32_t field_id, ProtoLengthDelimited va
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void ZWaveProxyRequest::encode(ProtoWriteBuffer buffer) const {
|
||||
void ZWaveProxyRequest::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_uint32(1, static_cast<uint32_t>(this->type));
|
||||
buffer.encode_bytes(2, this->data, this->data_len);
|
||||
}
|
||||
@@ -3348,7 +3348,7 @@ void ZWaveProxyRequest::calculate_size(ProtoSize &size) const {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_INFRARED
|
||||
void ListEntitiesInfraredResponse::encode(ProtoWriteBuffer buffer) const {
|
||||
void ListEntitiesInfraredResponse::encode(ProtoWriteBuffer &buffer) const {
|
||||
buffer.encode_string(1, this->object_id);
|
||||
buffer.encode_fixed32(2, this->key);
|
||||
buffer.encode_string(3, this->name);
|
||||
@@ -3419,7 +3419,7 @@ bool InfraredRFTransmitRawTimingsRequest::decode_32bit(uint32_t field_id, Proto3
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void InfraredRFReceiveEvent::encode(ProtoWriteBuffer buffer) const {
|
||||
void InfraredRFReceiveEvent::encode(ProtoWriteBuffer &buffer) const {
|
||||
#ifdef USE_DEVICES
|
||||
buffer.encode_uint32(1, this->device_id);
|
||||
#endif
|
||||
|
||||
@@ -382,7 +382,7 @@ class HelloResponse final : public ProtoMessage {
|
||||
uint32_t api_version_minor{0};
|
||||
StringRef server_info{};
|
||||
StringRef name{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -447,7 +447,7 @@ class AreaInfo final : public ProtoMessage {
|
||||
public:
|
||||
uint32_t area_id{0};
|
||||
StringRef name{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -462,7 +462,7 @@ class DeviceInfo final : public ProtoMessage {
|
||||
uint32_t device_id{0};
|
||||
StringRef name{};
|
||||
uint32_t area_id{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -527,7 +527,7 @@ class DeviceInfoResponse final : public ProtoMessage {
|
||||
#ifdef USE_ZWAVE_PROXY
|
||||
uint32_t zwave_home_id{0};
|
||||
#endif
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -558,7 +558,7 @@ class ListEntitiesBinarySensorResponse final : public InfoResponseProtoMessage {
|
||||
#endif
|
||||
StringRef device_class{};
|
||||
bool is_status_binary_sensor{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -575,7 +575,7 @@ class BinarySensorStateResponse final : public StateResponseProtoMessage {
|
||||
#endif
|
||||
bool state{false};
|
||||
bool missing_state{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -597,7 +597,7 @@ class ListEntitiesCoverResponse final : public InfoResponseProtoMessage {
|
||||
bool supports_tilt{false};
|
||||
StringRef device_class{};
|
||||
bool supports_stop{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -615,7 +615,7 @@ class CoverStateResponse final : public StateResponseProtoMessage {
|
||||
float position{0.0f};
|
||||
float tilt{0.0f};
|
||||
enums::CoverOperation current_operation{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -657,7 +657,7 @@ class ListEntitiesFanResponse final : public InfoResponseProtoMessage {
|
||||
bool supports_direction{false};
|
||||
int32_t supported_speed_count{0};
|
||||
const std::vector<const char *> *supported_preset_modes{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -677,7 +677,7 @@ class FanStateResponse final : public StateResponseProtoMessage {
|
||||
enums::FanDirection direction{};
|
||||
int32_t speed_level{0};
|
||||
StringRef preset_mode{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -724,7 +724,7 @@ class ListEntitiesLightResponse final : public InfoResponseProtoMessage {
|
||||
float min_mireds{0.0f};
|
||||
float max_mireds{0.0f};
|
||||
const FixedVector<const char *> *effects{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -751,7 +751,7 @@ class LightStateResponse final : public StateResponseProtoMessage {
|
||||
float cold_white{0.0f};
|
||||
float warm_white{0.0f};
|
||||
StringRef effect{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -815,7 +815,7 @@ class ListEntitiesSensorResponse final : public InfoResponseProtoMessage {
|
||||
bool force_update{false};
|
||||
StringRef device_class{};
|
||||
enums::SensorStateClass state_class{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -832,7 +832,7 @@ class SensorStateResponse final : public StateResponseProtoMessage {
|
||||
#endif
|
||||
float state{0.0f};
|
||||
bool missing_state{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -851,7 +851,7 @@ class ListEntitiesSwitchResponse final : public InfoResponseProtoMessage {
|
||||
#endif
|
||||
bool assumed_state{false};
|
||||
StringRef device_class{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -867,7 +867,7 @@ class SwitchStateResponse final : public StateResponseProtoMessage {
|
||||
const char *message_name() const override { return "switch_state_response"; }
|
||||
#endif
|
||||
bool state{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -901,7 +901,7 @@ class ListEntitiesTextSensorResponse final : public InfoResponseProtoMessage {
|
||||
const char *message_name() const override { return "list_entities_text_sensor_response"; }
|
||||
#endif
|
||||
StringRef device_class{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -918,7 +918,7 @@ class TextSensorStateResponse final : public StateResponseProtoMessage {
|
||||
#endif
|
||||
StringRef state{};
|
||||
bool missing_state{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -957,7 +957,7 @@ class SubscribeLogsResponse final : public ProtoMessage {
|
||||
this->message_ptr_ = data;
|
||||
this->message_len_ = len;
|
||||
}
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -990,7 +990,7 @@ class NoiseEncryptionSetKeyResponse final : public ProtoMessage {
|
||||
const char *message_name() const override { return "noise_encryption_set_key_response"; }
|
||||
#endif
|
||||
bool success{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1004,7 +1004,7 @@ class HomeassistantServiceMap final : public ProtoMessage {
|
||||
public:
|
||||
StringRef key{};
|
||||
StringRef value{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1033,7 +1033,7 @@ class HomeassistantActionRequest final : public ProtoMessage {
|
||||
#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
|
||||
StringRef response_template{};
|
||||
#endif
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1077,7 +1077,7 @@ class SubscribeHomeAssistantStateResponse final : public ProtoMessage {
|
||||
StringRef entity_id{};
|
||||
StringRef attribute{};
|
||||
bool once{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1138,7 +1138,7 @@ class ListEntitiesServicesArgument final : public ProtoMessage {
|
||||
public:
|
||||
StringRef name{};
|
||||
enums::ServiceArgType type{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1157,7 +1157,7 @@ class ListEntitiesServicesResponse final : public ProtoMessage {
|
||||
uint32_t key{0};
|
||||
FixedVector<ListEntitiesServicesArgument> args{};
|
||||
enums::SupportsResponseType supports_response{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1227,7 +1227,7 @@ class ExecuteServiceResponse final : public ProtoMessage {
|
||||
const uint8_t *response_data{nullptr};
|
||||
uint16_t response_data_len{0};
|
||||
#endif
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1244,7 +1244,7 @@ class ListEntitiesCameraResponse final : public InfoResponseProtoMessage {
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *message_name() const override { return "list_entities_camera_response"; }
|
||||
#endif
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1266,7 +1266,7 @@ class CameraImageResponse final : public StateResponseProtoMessage {
|
||||
this->data_len_ = len;
|
||||
}
|
||||
bool done{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1317,7 +1317,7 @@ class ListEntitiesClimateResponse final : public InfoResponseProtoMessage {
|
||||
float visual_min_humidity{0.0f};
|
||||
float visual_max_humidity{0.0f};
|
||||
uint32_t feature_flags{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1345,7 +1345,7 @@ class ClimateStateResponse final : public StateResponseProtoMessage {
|
||||
StringRef custom_preset{};
|
||||
float current_humidity{0.0f};
|
||||
float target_humidity{0.0f};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1403,7 +1403,7 @@ class ListEntitiesWaterHeaterResponse final : public InfoResponseProtoMessage {
|
||||
float target_temperature_step{0.0f};
|
||||
const water_heater::WaterHeaterModeMask *supported_modes{};
|
||||
uint32_t supported_features{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1424,7 +1424,7 @@ class WaterHeaterStateResponse final : public StateResponseProtoMessage {
|
||||
uint32_t state{0};
|
||||
float target_temperature_low{0.0f};
|
||||
float target_temperature_high{0.0f};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1468,7 +1468,7 @@ class ListEntitiesNumberResponse final : public InfoResponseProtoMessage {
|
||||
StringRef unit_of_measurement{};
|
||||
enums::NumberMode mode{};
|
||||
StringRef device_class{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1485,7 +1485,7 @@ class NumberStateResponse final : public StateResponseProtoMessage {
|
||||
#endif
|
||||
float state{0.0f};
|
||||
bool missing_state{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1519,7 +1519,7 @@ class ListEntitiesSelectResponse final : public InfoResponseProtoMessage {
|
||||
const char *message_name() const override { return "list_entities_select_response"; }
|
||||
#endif
|
||||
const FixedVector<const char *> *options{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1536,7 +1536,7 @@ class SelectStateResponse final : public StateResponseProtoMessage {
|
||||
#endif
|
||||
StringRef state{};
|
||||
bool missing_state{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1573,7 +1573,7 @@ class ListEntitiesSirenResponse final : public InfoResponseProtoMessage {
|
||||
const FixedVector<const char *> *tones{};
|
||||
bool supports_duration{false};
|
||||
bool supports_volume{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1589,7 +1589,7 @@ class SirenStateResponse final : public StateResponseProtoMessage {
|
||||
const char *message_name() const override { return "siren_state_response"; }
|
||||
#endif
|
||||
bool state{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1634,7 +1634,7 @@ class ListEntitiesLockResponse final : public InfoResponseProtoMessage {
|
||||
bool supports_open{false};
|
||||
bool requires_code{false};
|
||||
StringRef code_format{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1650,7 +1650,7 @@ class LockStateResponse final : public StateResponseProtoMessage {
|
||||
const char *message_name() const override { return "lock_state_response"; }
|
||||
#endif
|
||||
enums::LockState state{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1687,7 +1687,7 @@ class ListEntitiesButtonResponse final : public InfoResponseProtoMessage {
|
||||
const char *message_name() const override { return "list_entities_button_response"; }
|
||||
#endif
|
||||
StringRef device_class{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1719,7 +1719,7 @@ class MediaPlayerSupportedFormat final : public ProtoMessage {
|
||||
uint32_t num_channels{0};
|
||||
enums::MediaPlayerFormatPurpose purpose{};
|
||||
uint32_t sample_bytes{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1737,7 +1737,7 @@ class ListEntitiesMediaPlayerResponse final : public InfoResponseProtoMessage {
|
||||
bool supports_pause{false};
|
||||
std::vector<MediaPlayerSupportedFormat> supported_formats{};
|
||||
uint32_t feature_flags{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1755,7 +1755,7 @@ class MediaPlayerStateResponse final : public StateResponseProtoMessage {
|
||||
enums::MediaPlayerState state{};
|
||||
float volume{0.0f};
|
||||
bool muted{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1811,7 +1811,7 @@ class BluetoothLERawAdvertisement final : public ProtoMessage {
|
||||
uint32_t address_type{0};
|
||||
uint8_t data[62]{};
|
||||
uint8_t data_len{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1828,7 +1828,7 @@ class BluetoothLERawAdvertisementsResponse final : public ProtoMessage {
|
||||
#endif
|
||||
std::array<BluetoothLERawAdvertisement, BLUETOOTH_PROXY_ADVERTISEMENT_BATCH_SIZE> advertisements{};
|
||||
uint16_t advertisements_len{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1865,7 +1865,7 @@ class BluetoothDeviceConnectionResponse final : public ProtoMessage {
|
||||
bool connected{false};
|
||||
uint32_t mtu{0};
|
||||
int32_t error{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1893,7 +1893,7 @@ class BluetoothGATTDescriptor final : public ProtoMessage {
|
||||
std::array<uint64_t, 2> uuid{};
|
||||
uint32_t handle{0};
|
||||
uint32_t short_uuid{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1908,7 +1908,7 @@ class BluetoothGATTCharacteristic final : public ProtoMessage {
|
||||
uint32_t properties{0};
|
||||
FixedVector<BluetoothGATTDescriptor> descriptors{};
|
||||
uint32_t short_uuid{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1922,7 +1922,7 @@ class BluetoothGATTService final : public ProtoMessage {
|
||||
uint32_t handle{0};
|
||||
FixedVector<BluetoothGATTCharacteristic> characteristics{};
|
||||
uint32_t short_uuid{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1939,7 +1939,7 @@ class BluetoothGATTGetServicesResponse final : public ProtoMessage {
|
||||
#endif
|
||||
uint64_t address{0};
|
||||
std::vector<BluetoothGATTService> services{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1955,7 +1955,7 @@ class BluetoothGATTGetServicesDoneResponse final : public ProtoMessage {
|
||||
const char *message_name() const override { return "bluetooth_gatt_get_services_done_response"; }
|
||||
#endif
|
||||
uint64_t address{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -1994,7 +1994,7 @@ class BluetoothGATTReadResponse final : public ProtoMessage {
|
||||
this->data_ptr_ = data;
|
||||
this->data_len_ = len;
|
||||
}
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2089,7 +2089,7 @@ class BluetoothGATTNotifyDataResponse final : public ProtoMessage {
|
||||
this->data_ptr_ = data;
|
||||
this->data_len_ = len;
|
||||
}
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2107,7 +2107,7 @@ class BluetoothConnectionsFreeResponse final : public ProtoMessage {
|
||||
uint32_t free{0};
|
||||
uint32_t limit{0};
|
||||
std::array<uint64_t, BLUETOOTH_PROXY_MAX_CONNECTIONS> allocated{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2125,7 +2125,7 @@ class BluetoothGATTErrorResponse final : public ProtoMessage {
|
||||
uint64_t address{0};
|
||||
uint32_t handle{0};
|
||||
int32_t error{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2142,7 +2142,7 @@ class BluetoothGATTWriteResponse final : public ProtoMessage {
|
||||
#endif
|
||||
uint64_t address{0};
|
||||
uint32_t handle{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2159,7 +2159,7 @@ class BluetoothGATTNotifyResponse final : public ProtoMessage {
|
||||
#endif
|
||||
uint64_t address{0};
|
||||
uint32_t handle{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2177,7 +2177,7 @@ class BluetoothDevicePairingResponse final : public ProtoMessage {
|
||||
uint64_t address{0};
|
||||
bool paired{false};
|
||||
int32_t error{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2195,7 +2195,7 @@ class BluetoothDeviceUnpairingResponse final : public ProtoMessage {
|
||||
uint64_t address{0};
|
||||
bool success{false};
|
||||
int32_t error{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2213,7 +2213,7 @@ class BluetoothDeviceClearCacheResponse final : public ProtoMessage {
|
||||
uint64_t address{0};
|
||||
bool success{false};
|
||||
int32_t error{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2231,7 +2231,7 @@ class BluetoothScannerStateResponse final : public ProtoMessage {
|
||||
enums::BluetoothScannerState state{};
|
||||
enums::BluetoothScannerMode mode{};
|
||||
enums::BluetoothScannerMode configured_mode{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2277,7 +2277,7 @@ class VoiceAssistantAudioSettings final : public ProtoMessage {
|
||||
uint32_t noise_suppression_level{0};
|
||||
uint32_t auto_gain{0};
|
||||
float volume_multiplier{0.0f};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2297,7 +2297,7 @@ class VoiceAssistantRequest final : public ProtoMessage {
|
||||
uint32_t flags{0};
|
||||
VoiceAssistantAudioSettings audio_settings{};
|
||||
StringRef wake_word_phrase{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2359,7 +2359,7 @@ class VoiceAssistantAudio final : public ProtoDecodableMessage {
|
||||
const uint8_t *data{nullptr};
|
||||
uint16_t data_len{0};
|
||||
bool end{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2417,7 +2417,7 @@ class VoiceAssistantAnnounceFinished final : public ProtoMessage {
|
||||
const char *message_name() const override { return "voice_assistant_announce_finished"; }
|
||||
#endif
|
||||
bool success{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2430,7 +2430,7 @@ class VoiceAssistantWakeWord final : public ProtoMessage {
|
||||
StringRef id{};
|
||||
StringRef wake_word{};
|
||||
std::vector<std::string> trained_languages{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2480,7 +2480,7 @@ class VoiceAssistantConfigurationResponse final : public ProtoMessage {
|
||||
std::vector<VoiceAssistantWakeWord> available_wake_words{};
|
||||
const std::vector<std::string> *active_wake_words{};
|
||||
uint32_t max_active_wake_words{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2515,7 +2515,7 @@ class ListEntitiesAlarmControlPanelResponse final : public InfoResponseProtoMess
|
||||
uint32_t supported_features{0};
|
||||
bool requires_code{false};
|
||||
bool requires_code_to_arm{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2531,7 +2531,7 @@ class AlarmControlPanelStateResponse final : public StateResponseProtoMessage {
|
||||
const char *message_name() const override { return "alarm_control_panel_state_response"; }
|
||||
#endif
|
||||
enums::AlarmControlPanelState state{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2570,7 +2570,7 @@ class ListEntitiesTextResponse final : public InfoResponseProtoMessage {
|
||||
uint32_t max_length{0};
|
||||
StringRef pattern{};
|
||||
enums::TextMode mode{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2587,7 +2587,7 @@ class TextStateResponse final : public StateResponseProtoMessage {
|
||||
#endif
|
||||
StringRef state{};
|
||||
bool missing_state{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2621,7 +2621,7 @@ class ListEntitiesDateResponse final : public InfoResponseProtoMessage {
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *message_name() const override { return "list_entities_date_response"; }
|
||||
#endif
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2640,7 +2640,7 @@ class DateStateResponse final : public StateResponseProtoMessage {
|
||||
uint32_t year{0};
|
||||
uint32_t month{0};
|
||||
uint32_t day{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2675,7 +2675,7 @@ class ListEntitiesTimeResponse final : public InfoResponseProtoMessage {
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *message_name() const override { return "list_entities_time_response"; }
|
||||
#endif
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2694,7 +2694,7 @@ class TimeStateResponse final : public StateResponseProtoMessage {
|
||||
uint32_t hour{0};
|
||||
uint32_t minute{0};
|
||||
uint32_t second{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2731,7 +2731,7 @@ class ListEntitiesEventResponse final : public InfoResponseProtoMessage {
|
||||
#endif
|
||||
StringRef device_class{};
|
||||
const FixedVector<const char *> *event_types{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2747,7 +2747,7 @@ class EventResponse final : public StateResponseProtoMessage {
|
||||
const char *message_name() const override { return "event_response"; }
|
||||
#endif
|
||||
StringRef event_type{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2768,7 +2768,7 @@ class ListEntitiesValveResponse final : public InfoResponseProtoMessage {
|
||||
bool assumed_state{false};
|
||||
bool supports_position{false};
|
||||
bool supports_stop{false};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2785,7 +2785,7 @@ class ValveStateResponse final : public StateResponseProtoMessage {
|
||||
#endif
|
||||
float position{0.0f};
|
||||
enums::ValveOperation current_operation{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2820,7 +2820,7 @@ class ListEntitiesDateTimeResponse final : public InfoResponseProtoMessage {
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *message_name() const override { return "list_entities_date_time_response"; }
|
||||
#endif
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2837,7 +2837,7 @@ class DateTimeStateResponse final : public StateResponseProtoMessage {
|
||||
#endif
|
||||
bool missing_state{false};
|
||||
uint32_t epoch_seconds{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2871,7 +2871,7 @@ class ListEntitiesUpdateResponse final : public InfoResponseProtoMessage {
|
||||
const char *message_name() const override { return "list_entities_update_response"; }
|
||||
#endif
|
||||
StringRef device_class{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2895,7 +2895,7 @@ class UpdateStateResponse final : public StateResponseProtoMessage {
|
||||
StringRef title{};
|
||||
StringRef release_summary{};
|
||||
StringRef release_url{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2930,7 +2930,7 @@ class ZWaveProxyFrame final : public ProtoDecodableMessage {
|
||||
#endif
|
||||
const uint8_t *data{nullptr};
|
||||
uint16_t data_len{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2949,7 +2949,7 @@ class ZWaveProxyRequest final : public ProtoDecodableMessage {
|
||||
enums::ZWaveProxyRequestType type{};
|
||||
const uint8_t *data{nullptr};
|
||||
uint16_t data_len{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -2969,7 +2969,7 @@ class ListEntitiesInfraredResponse final : public InfoResponseProtoMessage {
|
||||
const char *message_name() const override { return "list_entities_infrared_response"; }
|
||||
#endif
|
||||
uint32_t capabilities{0};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
@@ -3016,7 +3016,7 @@ class InfraredRFReceiveEvent final : public ProtoMessage {
|
||||
#endif
|
||||
uint32_t key{0};
|
||||
const std::vector<int32_t> *timings{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void encode(ProtoWriteBuffer &buffer) const override;
|
||||
void calculate_size(ProtoSize &size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
|
||||
@@ -30,6 +30,12 @@ APIServer *global_api_server = nullptr; // NOLINT(cppcoreguidelines-avoid-non-c
|
||||
|
||||
APIServer::APIServer() { global_api_server = this; }
|
||||
|
||||
void APIServer::socket_failed_(const LogString *msg) {
|
||||
ESP_LOGW(TAG, "Socket %s: errno %d", LOG_STR_ARG(msg), errno);
|
||||
this->destroy_socket_();
|
||||
this->mark_failed();
|
||||
}
|
||||
|
||||
void APIServer::setup() {
|
||||
ControllerRegistry::register_controller(this);
|
||||
|
||||
@@ -48,22 +54,20 @@ void APIServer::setup() {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
this->socket_ = socket::socket_ip_loop_monitored(SOCK_STREAM, 0); // monitored for incoming connections
|
||||
this->socket_ = socket::socket_ip_loop_monitored(SOCK_STREAM, 0).release(); // monitored for incoming connections
|
||||
if (this->socket_ == nullptr) {
|
||||
ESP_LOGW(TAG, "Could not create socket");
|
||||
this->mark_failed();
|
||||
this->socket_failed_(LOG_STR("creation"));
|
||||
return;
|
||||
}
|
||||
int enable = 1;
|
||||
int err = this->socket_->setsockopt(SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
|
||||
if (err != 0) {
|
||||
ESP_LOGW(TAG, "Socket unable to set reuseaddr: errno %d", err);
|
||||
ESP_LOGW(TAG, "Socket reuseaddr: errno %d", errno);
|
||||
// we can still continue
|
||||
}
|
||||
err = this->socket_->setblocking(false);
|
||||
if (err != 0) {
|
||||
ESP_LOGW(TAG, "Socket unable to set nonblocking mode: errno %d", err);
|
||||
this->mark_failed();
|
||||
this->socket_failed_(LOG_STR("nonblocking"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -71,22 +75,19 @@ void APIServer::setup() {
|
||||
|
||||
socklen_t sl = socket::set_sockaddr_any((struct sockaddr *) &server, sizeof(server), this->port_);
|
||||
if (sl == 0) {
|
||||
ESP_LOGW(TAG, "Socket unable to set sockaddr: errno %d", errno);
|
||||
this->mark_failed();
|
||||
this->socket_failed_(LOG_STR("set sockaddr"));
|
||||
return;
|
||||
}
|
||||
|
||||
err = this->socket_->bind((struct sockaddr *) &server, sl);
|
||||
if (err != 0) {
|
||||
ESP_LOGW(TAG, "Socket unable to bind: errno %d", errno);
|
||||
this->mark_failed();
|
||||
this->socket_failed_(LOG_STR("bind"));
|
||||
return;
|
||||
}
|
||||
|
||||
err = this->socket_->listen(this->listen_backlog_);
|
||||
if (err != 0) {
|
||||
ESP_LOGW(TAG, "Socket unable to listen: errno %d", errno);
|
||||
this->mark_failed();
|
||||
this->socket_failed_(LOG_STR("listen"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -622,10 +623,7 @@ void APIServer::on_shutdown() {
|
||||
this->shutting_down_ = true;
|
||||
|
||||
// Close the listening socket to prevent new connections
|
||||
if (this->socket_) {
|
||||
this->socket_->close();
|
||||
this->socket_ = nullptr;
|
||||
}
|
||||
this->destroy_socket_();
|
||||
|
||||
// Change batch delay to 5ms for quick flushing during shutdown
|
||||
this->batch_delay_ = 5;
|
||||
|
||||
@@ -249,8 +249,15 @@ class APIServer : public Component,
|
||||
void add_state_subscription_(std::string entity_id, optional<std::string> attribute,
|
||||
std::function<void(const std::string &)> f, bool once);
|
||||
#endif // USE_API_HOMEASSISTANT_STATES
|
||||
// No explicit close() needed — listen sockets have no active connections on
|
||||
// failure/shutdown. Destructor handles fd cleanup (close or abort per platform).
|
||||
inline void destroy_socket_() {
|
||||
delete this->socket_;
|
||||
this->socket_ = nullptr;
|
||||
}
|
||||
void socket_failed_(const LogString *msg);
|
||||
// Pointers and pointer-like types first (4 bytes each)
|
||||
std::unique_ptr<socket::Socket> socket_ = nullptr;
|
||||
socket::Socket *socket_{nullptr};
|
||||
#ifdef USE_API_CLIENT_CONNECTED_TRIGGER
|
||||
Trigger<std::string, std::string> client_connected_trigger_;
|
||||
#endif
|
||||
|
||||
@@ -36,6 +36,8 @@ template<typename... X> class TemplatableStringValue : public TemplatableValue<s
|
||||
static std::string value_to_string(const char *val) { return std::string(val); } // For lambdas returning .c_str()
|
||||
static std::string value_to_string(const std::string &val) { return val; }
|
||||
static std::string value_to_string(std::string &&val) { return std::move(val); }
|
||||
static std::string value_to_string(const StringRef &val) { return val.str(); }
|
||||
static std::string value_to_string(StringRef &&val) { return val.str(); }
|
||||
|
||||
public:
|
||||
TemplatableStringValue() : TemplatableValue<std::string, X...>() {}
|
||||
|
||||
@@ -70,6 +70,21 @@ uint32_t ProtoDecodableMessage::count_repeated_field(const uint8_t *buffer, size
|
||||
return count;
|
||||
}
|
||||
|
||||
#ifdef ESPHOME_DEBUG_API
|
||||
void ProtoWriteBuffer::debug_check_bounds_(size_t bytes, const char *caller) {
|
||||
if (this->pos_ + bytes > this->buffer_->data() + this->buffer_->size()) {
|
||||
ESP_LOGE(TAG, "ProtoWriteBuffer bounds check failed in %s: bytes=%zu offset=%td buf_size=%zu", caller, bytes,
|
||||
this->pos_ - this->buffer_->data(), this->buffer_->size());
|
||||
abort();
|
||||
}
|
||||
}
|
||||
void ProtoWriteBuffer::debug_check_encode_size_(uint32_t field_id, uint32_t expected, ptrdiff_t actual) {
|
||||
ESP_LOGE(TAG, "encode_message: size mismatch for field %" PRIu32 ": calculated=%" PRIu32 " actual=%td", field_id,
|
||||
expected, actual);
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
void ProtoDecodableMessage::decode(const uint8_t *buffer, size_t length) {
|
||||
const uint8_t *ptr = buffer;
|
||||
const uint8_t *end = buffer + length;
|
||||
|
||||
@@ -217,21 +217,26 @@ class Proto32Bit {
|
||||
|
||||
class ProtoWriteBuffer {
|
||||
public:
|
||||
ProtoWriteBuffer(std::vector<uint8_t> *buffer) : buffer_(buffer) {}
|
||||
void write(uint8_t value) { this->buffer_->push_back(value); }
|
||||
ProtoWriteBuffer(std::vector<uint8_t> *buffer) : buffer_(buffer), pos_(buffer->data() + buffer->size()) {}
|
||||
ProtoWriteBuffer(std::vector<uint8_t> *buffer, size_t write_pos)
|
||||
: buffer_(buffer), pos_(buffer->data() + write_pos) {}
|
||||
void encode_varint_raw(uint32_t value) {
|
||||
while (value > 0x7F) {
|
||||
this->buffer_->push_back(static_cast<uint8_t>(value | 0x80));
|
||||
this->debug_check_bounds_(1);
|
||||
*this->pos_++ = static_cast<uint8_t>(value | 0x80);
|
||||
value >>= 7;
|
||||
}
|
||||
this->buffer_->push_back(static_cast<uint8_t>(value));
|
||||
this->debug_check_bounds_(1);
|
||||
*this->pos_++ = static_cast<uint8_t>(value);
|
||||
}
|
||||
void encode_varint_raw_64(uint64_t value) {
|
||||
while (value > 0x7F) {
|
||||
this->buffer_->push_back(static_cast<uint8_t>(value | 0x80));
|
||||
this->debug_check_bounds_(1);
|
||||
*this->pos_++ = static_cast<uint8_t>(value | 0x80);
|
||||
value >>= 7;
|
||||
}
|
||||
this->buffer_->push_back(static_cast<uint8_t>(value));
|
||||
this->debug_check_bounds_(1);
|
||||
*this->pos_++ = static_cast<uint8_t>(value);
|
||||
}
|
||||
/**
|
||||
* Encode a field key (tag/wire type combination).
|
||||
@@ -245,23 +250,18 @@ class ProtoWriteBuffer {
|
||||
*
|
||||
* Following https://protobuf.dev/programming-guides/encoding/#structure
|
||||
*/
|
||||
void encode_field_raw(uint32_t field_id, uint32_t type) {
|
||||
uint32_t val = (field_id << 3) | (type & WIRE_TYPE_MASK);
|
||||
this->encode_varint_raw(val);
|
||||
}
|
||||
void encode_field_raw(uint32_t field_id, uint32_t type) { this->encode_varint_raw((field_id << 3) | type); }
|
||||
void encode_string(uint32_t field_id, const char *string, size_t len, bool force = false) {
|
||||
if (len == 0 && !force)
|
||||
return;
|
||||
|
||||
this->encode_field_raw(field_id, 2); // type 2: Length-delimited string
|
||||
this->encode_varint_raw(len);
|
||||
|
||||
// Using resize + memcpy instead of insert provides significant performance improvement:
|
||||
// ~10-11x faster for 16-32 byte strings, ~3x faster for 64-byte strings
|
||||
// as it avoids iterator checks and potential element moves that insert performs
|
||||
size_t old_size = this->buffer_->size();
|
||||
this->buffer_->resize(old_size + len);
|
||||
std::memcpy(this->buffer_->data() + old_size, string, len);
|
||||
// Direct memcpy into pre-sized buffer — avoids push_back() per-byte capacity checks
|
||||
// and vector::insert() iterator overhead. ~10-11x faster for 16-32 byte strings.
|
||||
this->debug_check_bounds_(len);
|
||||
std::memcpy(this->pos_, string, len);
|
||||
this->pos_ += len;
|
||||
}
|
||||
void encode_string(uint32_t field_id, const std::string &value, bool force = false) {
|
||||
this->encode_string(field_id, value.data(), value.size(), force);
|
||||
@@ -288,17 +288,26 @@ class ProtoWriteBuffer {
|
||||
if (!value && !force)
|
||||
return;
|
||||
this->encode_field_raw(field_id, 0); // type 0: Varint - bool
|
||||
this->buffer_->push_back(value ? 0x01 : 0x00);
|
||||
this->debug_check_bounds_(1);
|
||||
*this->pos_++ = value ? 0x01 : 0x00;
|
||||
}
|
||||
void encode_fixed32(uint32_t field_id, uint32_t value, bool force = false) {
|
||||
// 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) {
|
||||
if (value == 0 && !force)
|
||||
return;
|
||||
|
||||
this->encode_field_raw(field_id, 5); // type 5: 32-bit fixed32
|
||||
this->write((value >> 0) & 0xFF);
|
||||
this->write((value >> 8) & 0xFF);
|
||||
this->write((value >> 16) & 0xFF);
|
||||
this->write((value >> 24) & 0xFF);
|
||||
this->debug_check_bounds_(4);
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
// Protobuf fixed32 is little-endian, so direct copy works
|
||||
std::memcpy(this->pos_, &value, 4);
|
||||
this->pos_ += 4;
|
||||
#else
|
||||
*this->pos_++ = (value >> 0) & 0xFF;
|
||||
*this->pos_++ = (value >> 8) & 0xFF;
|
||||
*this->pos_++ = (value >> 16) & 0xFF;
|
||||
*this->pos_++ = (value >> 24) & 0xFF;
|
||||
#endif
|
||||
}
|
||||
// NOTE: Wire type 1 (64-bit fixed: double, fixed64, sfixed64) is intentionally
|
||||
// not supported to reduce overhead on embedded systems. All ESPHome devices are
|
||||
@@ -334,11 +343,20 @@ class ProtoWriteBuffer {
|
||||
}
|
||||
/// Encode a packed repeated sint32 field (zero-copy from vector)
|
||||
void encode_packed_sint32(uint32_t field_id, const std::vector<int32_t> &values);
|
||||
void encode_message(uint32_t field_id, const ProtoMessage &value);
|
||||
/// Encode a nested message field (force=true for repeated, false for singular)
|
||||
void encode_message(uint32_t field_id, const ProtoMessage &value, bool force = true);
|
||||
std::vector<uint8_t> *get_buffer() const { return buffer_; }
|
||||
|
||||
protected:
|
||||
#ifdef ESPHOME_DEBUG_API
|
||||
void debug_check_bounds_(size_t bytes, const char *caller = __builtin_FUNCTION());
|
||||
void debug_check_encode_size_(uint32_t field_id, uint32_t expected, ptrdiff_t actual);
|
||||
#else
|
||||
void debug_check_bounds_([[maybe_unused]] size_t bytes) {}
|
||||
#endif
|
||||
|
||||
std::vector<uint8_t> *buffer_;
|
||||
uint8_t *pos_;
|
||||
};
|
||||
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
@@ -416,9 +434,11 @@ class ProtoMessage {
|
||||
public:
|
||||
virtual ~ProtoMessage() = default;
|
||||
// Default implementation for messages with no fields
|
||||
virtual void encode(ProtoWriteBuffer buffer) const {}
|
||||
virtual void encode(ProtoWriteBuffer &buffer) const {}
|
||||
// Default implementation for messages with no fields
|
||||
virtual void calculate_size(ProtoSize &size) const {}
|
||||
// Convenience: calculate and return size directly (defined after ProtoSize)
|
||||
uint32_t calculated_size() const;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
virtual const char *dump_to(DumpBuffer &out) const = 0;
|
||||
virtual const char *message_name() const { return "unknown"; }
|
||||
@@ -877,6 +897,14 @@ class ProtoSize {
|
||||
}
|
||||
};
|
||||
|
||||
// Implementation of methods that depend on ProtoSize being fully defined
|
||||
|
||||
inline uint32_t ProtoMessage::calculated_size() const {
|
||||
ProtoSize size;
|
||||
this->calculate_size(size);
|
||||
return size.get_size();
|
||||
}
|
||||
|
||||
// Implementation of encode_packed_sint32 - must be after ProtoSize is defined
|
||||
inline void ProtoWriteBuffer::encode_packed_sint32(uint32_t field_id, const std::vector<int32_t> &values) {
|
||||
if (values.empty())
|
||||
@@ -897,30 +925,30 @@ inline void ProtoWriteBuffer::encode_packed_sint32(uint32_t field_id, const std:
|
||||
}
|
||||
|
||||
// Implementation of encode_message - must be after ProtoMessage is defined
|
||||
inline void ProtoWriteBuffer::encode_message(uint32_t field_id, const ProtoMessage &value) {
|
||||
this->encode_field_raw(field_id, 2); // type 2: Length-delimited message
|
||||
|
||||
inline void ProtoWriteBuffer::encode_message(uint32_t field_id, const ProtoMessage &value, bool force) {
|
||||
// Calculate the message size first
|
||||
ProtoSize msg_size;
|
||||
value.calculate_size(msg_size);
|
||||
uint32_t msg_length_bytes = msg_size.get_size();
|
||||
|
||||
// Calculate how many bytes the length varint needs
|
||||
uint32_t varint_length_bytes = ProtoSize::varint(msg_length_bytes);
|
||||
// Skip empty singular messages (matches add_message_field which skips when nested_size == 0)
|
||||
// Repeated messages (force=true) are always encoded since an empty item is meaningful
|
||||
if (msg_length_bytes == 0 && !force)
|
||||
return;
|
||||
|
||||
// Reserve exact space for the length varint
|
||||
size_t begin = this->buffer_->size();
|
||||
this->buffer_->resize(this->buffer_->size() + varint_length_bytes);
|
||||
this->encode_field_raw(field_id, 2); // type 2: Length-delimited message
|
||||
|
||||
// Write the length varint directly
|
||||
encode_varint_to_buffer(msg_length_bytes, this->buffer_->data() + begin);
|
||||
|
||||
// Now encode the message content - it will append to the buffer
|
||||
value.encode(*this);
|
||||
// Write the length varint directly through pos_
|
||||
this->encode_varint_raw(msg_length_bytes);
|
||||
|
||||
// Encode nested message - pos_ advances directly through the reference
|
||||
#ifdef ESPHOME_DEBUG_API
|
||||
// Verify that the encoded size matches what we calculated
|
||||
assert(this->buffer_->size() == begin + varint_length_bytes + msg_length_bytes);
|
||||
uint8_t *start = this->pos_;
|
||||
value.encode(*this);
|
||||
if (static_cast<uint32_t>(this->pos_ - start) != msg_length_bytes)
|
||||
this->debug_check_encode_size_(field_id, msg_length_bytes, this->pos_ - start);
|
||||
#else
|
||||
value.encode(*this);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -178,8 +178,11 @@ async def to_code_base(config):
|
||||
bsec2_arr = cg.progmem_array(config[CONF_RAW_DATA_ID], rhs)
|
||||
cg.add(var.set_bsec2_configuration(bsec2_arr, len(rhs)))
|
||||
|
||||
# Although this component does not use SPI, the BSEC2 Arduino library requires the SPI library
|
||||
# The BSEC2 and BME68x Arduino libraries unconditionally include Wire.h and
|
||||
# SPI.h in their source files, so these libraries must be available even though
|
||||
# ESPHome uses its own I2C/SPI abstractions instead of the Arduino ones.
|
||||
if core.CORE.using_arduino:
|
||||
cg.add_library("Wire", None)
|
||||
cg.add_library("SPI", None)
|
||||
cg.add_library(
|
||||
"BME68x Sensor library",
|
||||
|
||||
@@ -53,7 +53,7 @@ void DNSServer::start(const network::IPAddress &ip) {
|
||||
#endif
|
||||
|
||||
// Create loop-monitored UDP socket
|
||||
this->socket_ = socket::socket_ip_loop_monitored(SOCK_DGRAM, IPPROTO_UDP);
|
||||
this->socket_ = socket::socket_ip_loop_monitored(SOCK_DGRAM, IPPROTO_UDP).release();
|
||||
if (this->socket_ == nullptr) {
|
||||
ESP_LOGE(TAG, "Socket create failed");
|
||||
return;
|
||||
@@ -70,17 +70,14 @@ void DNSServer::start(const network::IPAddress &ip) {
|
||||
int err = this->socket_->bind((struct sockaddr *) &server_addr, addr_len);
|
||||
if (err != 0) {
|
||||
ESP_LOGE(TAG, "Bind failed: %d", errno);
|
||||
this->socket_ = nullptr;
|
||||
this->destroy_socket_();
|
||||
return;
|
||||
}
|
||||
ESP_LOGV(TAG, "Bound to port %d", DNS_PORT);
|
||||
}
|
||||
|
||||
void DNSServer::stop() {
|
||||
if (this->socket_ != nullptr) {
|
||||
this->socket_->close();
|
||||
this->socket_ = nullptr;
|
||||
}
|
||||
this->destroy_socket_();
|
||||
ESP_LOGV(TAG, "Stopped");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
#ifdef USE_ESP32
|
||||
|
||||
#include <memory>
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/components/network/ip_address.h"
|
||||
#include "esphome/components/socket/socket.h"
|
||||
@@ -15,9 +14,15 @@ class DNSServer {
|
||||
void process_next_request();
|
||||
|
||||
protected:
|
||||
// No explicit close() needed — listen sockets have no active connections on
|
||||
// failure/shutdown. Destructor handles fd cleanup (close or abort per platform).
|
||||
inline void destroy_socket_() {
|
||||
delete this->socket_;
|
||||
this->socket_ = nullptr;
|
||||
}
|
||||
static constexpr size_t DNS_BUFFER_SIZE = 192;
|
||||
|
||||
std::unique_ptr<socket::Socket> socket_{nullptr};
|
||||
socket::Socket *socket_{nullptr};
|
||||
network::IPAddress server_ip_;
|
||||
uint8_t buffer_[DNS_BUFFER_SIZE];
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@ from esphome.const import (
|
||||
CONF_DATA,
|
||||
CONF_FREQUENCY,
|
||||
CONF_ID,
|
||||
CONF_VALUE,
|
||||
CONF_WAIT_TIME,
|
||||
)
|
||||
from esphome.core import ID
|
||||
@@ -333,3 +334,94 @@ async def send_packet_action_to_code(config, action_id, template_arg, args):
|
||||
arr = cg.static_const_array(arr_id, cg.ArrayInitializer(*data))
|
||||
cg.add(var.set_data_static(arr, len(data)))
|
||||
return var
|
||||
|
||||
|
||||
# Setter action definitions: (setter_name, validator, template_type, enum_map)
|
||||
_SETTER_ACTIONS = [
|
||||
(
|
||||
"set_frequency",
|
||||
cv.All(cv.frequency, cv.float_range(min=300.0e6, max=928.0e6)),
|
||||
float,
|
||||
None,
|
||||
),
|
||||
("set_output_power", cv.float_range(min=-30.0, max=11.0), float, None),
|
||||
("set_modulation_type", cv.enum(MODULATION, upper=False), Modulation, MODULATION),
|
||||
("set_symbol_rate", cv.float_range(min=600, max=500000), float, None),
|
||||
(
|
||||
"set_rx_attenuation",
|
||||
cv.enum(RX_ATTENUATION, upper=False),
|
||||
RxAttenuation,
|
||||
RX_ATTENUATION,
|
||||
),
|
||||
("set_dc_blocking_filter", cv.boolean, bool, None),
|
||||
("set_manchester", cv.boolean, bool, None),
|
||||
(
|
||||
"set_filter_bandwidth",
|
||||
cv.All(cv.frequency, cv.float_range(min=58000, max=812000)),
|
||||
float,
|
||||
None,
|
||||
),
|
||||
(
|
||||
"set_fsk_deviation",
|
||||
cv.All(cv.frequency, cv.float_range(min=1500, max=381000)),
|
||||
float,
|
||||
None,
|
||||
),
|
||||
("set_msk_deviation", cv.int_range(min=1, max=8), cg.uint8, None),
|
||||
("set_channel", cv.uint8_t, cg.uint8, None),
|
||||
(
|
||||
"set_channel_spacing",
|
||||
cv.All(cv.frequency, cv.float_range(min=25000, max=405000)),
|
||||
float,
|
||||
None,
|
||||
),
|
||||
(
|
||||
"set_if_frequency",
|
||||
cv.All(cv.frequency, cv.float_range(min=25000, max=788000)),
|
||||
float,
|
||||
None,
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def _register_setter_actions():
|
||||
for setter_name, validator, templ_type, enum_map in _SETTER_ACTIONS:
|
||||
class_name = (
|
||||
"".join(word.capitalize() for word in setter_name.split("_")) + "Action"
|
||||
)
|
||||
action_cls = ns.class_(
|
||||
class_name, automation.Action, cg.Parented.template(CC1101Component)
|
||||
)
|
||||
schema = cv.maybe_simple_value(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(CC1101Component),
|
||||
cv.Required(CONF_VALUE): cv.templatable(validator),
|
||||
},
|
||||
key=CONF_VALUE,
|
||||
)
|
||||
|
||||
async def _setter_action_to_code(
|
||||
config,
|
||||
action_id,
|
||||
template_arg,
|
||||
args,
|
||||
_setter=setter_name,
|
||||
_type=templ_type,
|
||||
_map=enum_map,
|
||||
):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
await cg.register_parented(var, config[CONF_ID])
|
||||
data = config[CONF_VALUE]
|
||||
if cg.is_template(data):
|
||||
templ_ = await cg.templatable(data, args, _type)
|
||||
cg.add(getattr(var, _setter)(templ_))
|
||||
else:
|
||||
cg.add(getattr(var, _setter)(_map[data] if _map else data))
|
||||
return var
|
||||
|
||||
automation.register_action(f"cc1101.{setter_name}", action_cls, schema)(
|
||||
_setter_action_to_code
|
||||
)
|
||||
|
||||
|
||||
_register_setter_actions()
|
||||
|
||||
@@ -161,4 +161,82 @@ template<typename... Ts> class SendPacketAction : public Action<Ts...>, public P
|
||||
size_t data_static_len_{0};
|
||||
};
|
||||
|
||||
template<typename... Ts> class SetSymbolRateAction : public Action<Ts...>, public Parented<CC1101Component> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(float, symbol_rate)
|
||||
void play(const Ts &...x) override { this->parent_->set_symbol_rate(this->symbol_rate_.value(x...)); }
|
||||
};
|
||||
|
||||
template<typename... Ts> class SetFrequencyAction : public Action<Ts...>, public Parented<CC1101Component> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(float, frequency)
|
||||
void play(const Ts &...x) override { this->parent_->set_frequency(this->frequency_.value(x...)); }
|
||||
};
|
||||
|
||||
template<typename... Ts> class SetOutputPowerAction : public Action<Ts...>, public Parented<CC1101Component> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(float, output_power)
|
||||
void play(const Ts &...x) override { this->parent_->set_output_power(this->output_power_.value(x...)); }
|
||||
};
|
||||
|
||||
template<typename... Ts> class SetModulationTypeAction : public Action<Ts...>, public Parented<CC1101Component> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(Modulation, modulation_type)
|
||||
void play(const Ts &...x) override { this->parent_->set_modulation_type(this->modulation_type_.value(x...)); }
|
||||
};
|
||||
|
||||
template<typename... Ts> class SetRxAttenuationAction : public Action<Ts...>, public Parented<CC1101Component> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(RxAttenuation, rx_attenuation)
|
||||
void play(const Ts &...x) override { this->parent_->set_rx_attenuation(this->rx_attenuation_.value(x...)); }
|
||||
};
|
||||
|
||||
template<typename... Ts> class SetDcBlockingFilterAction : public Action<Ts...>, public Parented<CC1101Component> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(bool, dc_blocking_filter)
|
||||
void play(const Ts &...x) override { this->parent_->set_dc_blocking_filter(this->dc_blocking_filter_.value(x...)); }
|
||||
};
|
||||
|
||||
template<typename... Ts> class SetManchesterAction : public Action<Ts...>, public Parented<CC1101Component> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(bool, manchester)
|
||||
void play(const Ts &...x) override { this->parent_->set_manchester(this->manchester_.value(x...)); }
|
||||
};
|
||||
|
||||
template<typename... Ts> class SetFilterBandwidthAction : public Action<Ts...>, public Parented<CC1101Component> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(float, filter_bandwidth)
|
||||
void play(const Ts &...x) override { this->parent_->set_filter_bandwidth(this->filter_bandwidth_.value(x...)); }
|
||||
};
|
||||
|
||||
template<typename... Ts> class SetFskDeviationAction : public Action<Ts...>, public Parented<CC1101Component> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(float, fsk_deviation)
|
||||
void play(const Ts &...x) override { this->parent_->set_fsk_deviation(this->fsk_deviation_.value(x...)); }
|
||||
};
|
||||
|
||||
template<typename... Ts> class SetMskDeviationAction : public Action<Ts...>, public Parented<CC1101Component> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint8_t, msk_deviation)
|
||||
void play(const Ts &...x) override { this->parent_->set_msk_deviation(this->msk_deviation_.value(x...)); }
|
||||
};
|
||||
|
||||
template<typename... Ts> class SetChannelAction : public Action<Ts...>, public Parented<CC1101Component> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint8_t, channel)
|
||||
void play(const Ts &...x) override { this->parent_->set_channel(this->channel_.value(x...)); }
|
||||
};
|
||||
|
||||
template<typename... Ts> class SetChannelSpacingAction : public Action<Ts...>, public Parented<CC1101Component> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(float, channel_spacing)
|
||||
void play(const Ts &...x) override { this->parent_->set_channel_spacing(this->channel_spacing_.value(x...)); }
|
||||
};
|
||||
|
||||
template<typename... Ts> class SetIfFrequencyAction : public Action<Ts...>, public Parented<CC1101Component> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(float, if_frequency)
|
||||
void play(const Ts &...x) override { this->parent_->set_if_frequency(this->if_frequency_.value(x...)); }
|
||||
};
|
||||
|
||||
} // namespace esphome::cc1101
|
||||
|
||||
@@ -64,6 +64,9 @@ class Dsmr : public Component, public uart::UARTDevice {
|
||||
void dump_config() override;
|
||||
|
||||
void set_decryption_key(const char *decryption_key);
|
||||
// Remove before 2026.8.0
|
||||
ESPDEPRECATED("Pass .c_str() - e.g. set_decryption_key(key.c_str()). Removed in 2026.8.0", "2026.2.0")
|
||||
void set_decryption_key(const std::string &decryption_key) { this->set_decryption_key(decryption_key.c_str()); }
|
||||
void set_max_telegram_length(size_t length) { this->max_telegram_len_ = length; }
|
||||
void set_request_pin(GPIOPin *request_pin) { this->request_pin_ = request_pin; }
|
||||
void set_request_interval(uint32_t interval) { this->request_interval_ = interval; }
|
||||
|
||||
@@ -76,7 +76,7 @@ class EPaperBase : public Display,
|
||||
static uint8_t color_to_bit(Color color) {
|
||||
// It's always a shade of gray. Map to BLACK or WHITE.
|
||||
// We split the luminance at a suitable point
|
||||
if ((static_cast<int>(color.r) + color.g + color.b) > 512) {
|
||||
if ((color.r + color.g + color.b) >= 382) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -5,9 +5,24 @@ namespace esphome::epaper_spi {
|
||||
|
||||
static constexpr const char *const TAG = "epaper_weact_3c";
|
||||
|
||||
enum class BwrState : uint8_t {
|
||||
BWR_BLACK,
|
||||
BWR_WHITE,
|
||||
BWR_RED,
|
||||
};
|
||||
|
||||
static BwrState color_to_bwr(Color color) {
|
||||
if (color.r > color.g + color.b && color.r > 127) {
|
||||
return BwrState::BWR_RED;
|
||||
}
|
||||
if (color.r + color.g + color.b >= 382) {
|
||||
return BwrState::BWR_WHITE;
|
||||
}
|
||||
return BwrState::BWR_BLACK;
|
||||
}
|
||||
// SSD1680 3-color display notes:
|
||||
// - Buffer uses 1 bit per pixel, 8 pixels per byte
|
||||
// - Buffer first half (black_offset): Black/White plane (1=black, 0=white)
|
||||
// - Buffer first half (black_offset): Black/White plane (0=black, 1=white)
|
||||
// - Buffer second half (red_offset): Red plane (1=red, 0=no red)
|
||||
// - Total buffer: width * height / 4 bytes = 2 * (width * height / 8)
|
||||
// - For 128x296: 128*296/4 = 9472 bytes total (4736 per color)
|
||||
@@ -23,20 +38,20 @@ void EPaperWeAct3C::draw_pixel_at(int x, int y, Color color) {
|
||||
|
||||
// Use luminance threshold for B/W mapping
|
||||
// Split at halfway point (382 = (255*3)/2)
|
||||
bool is_white = (static_cast<int>(color.r) + color.g + color.b) > 382;
|
||||
auto bwr = color_to_bwr(color);
|
||||
|
||||
// Update black/white plane (first half of buffer)
|
||||
if (is_white) {
|
||||
// White pixel - clear bit in black plane
|
||||
this->buffer_[pos] &= ~bit;
|
||||
} else {
|
||||
// Black pixel - set bit in black plane
|
||||
if (bwr == BwrState::BWR_WHITE) {
|
||||
// White pixel - set bit in black plane
|
||||
this->buffer_[pos] |= bit;
|
||||
} else {
|
||||
// Black pixel - clear bit in black plane
|
||||
this->buffer_[pos] &= ~bit;
|
||||
}
|
||||
|
||||
// Update red plane (second half of buffer)
|
||||
// Red if red component is dominant (r > g+b)
|
||||
if (color.r > color.g + color.b) {
|
||||
if (bwr == BwrState::BWR_RED) {
|
||||
// Red pixel - set bit in red plane
|
||||
this->buffer_[red_offset + pos] |= bit;
|
||||
} else {
|
||||
@@ -53,21 +68,20 @@ void EPaperWeAct3C::fill(Color color) {
|
||||
const size_t half_buffer = this->buffer_length_ / 2u;
|
||||
|
||||
// Use luminance threshold for B/W mapping
|
||||
bool is_white = (static_cast<int>(color.r) + color.g + color.b) > 382;
|
||||
bool is_red = color.r > color.g + color.b;
|
||||
auto bits = color_to_bwr(color);
|
||||
|
||||
// Fill both planes
|
||||
if (is_white) {
|
||||
// White - both planes = 0x00
|
||||
if (bits == BwrState::BWR_BLACK) {
|
||||
// Black - both planes = 0x00
|
||||
this->buffer_.fill(0x00);
|
||||
} else if (is_red) {
|
||||
} else if (bits == BwrState::BWR_RED) {
|
||||
// Red - black plane = 0x00, red plane = 0xFF
|
||||
for (size_t i = 0; i < half_buffer; i++)
|
||||
this->buffer_[i] = 0x00;
|
||||
for (size_t i = 0; i < half_buffer; i++)
|
||||
this->buffer_[half_buffer + i] = 0xFF;
|
||||
} else {
|
||||
// Black - black plane = 0xFF, red plane = 0x00
|
||||
// White - black plane = 0xFF, red plane = 0x00
|
||||
for (size_t i = 0; i < half_buffer; i++)
|
||||
this->buffer_[i] = 0xFF;
|
||||
for (size_t i = 0; i < half_buffer; i++)
|
||||
@@ -112,7 +126,6 @@ bool HOT EPaperWeAct3C::transfer_data() {
|
||||
ESP_LOGV(TAG, "transfer_data: buffer_length=%u, half_buffer=%u", buffer_length, half_buffer);
|
||||
|
||||
// Use a local buffer for SPI transfers
|
||||
static constexpr size_t MAX_TRANSFER_SIZE = 128;
|
||||
uint8_t bytes_to_send[MAX_TRANSFER_SIZE];
|
||||
|
||||
// First, send the RED buffer (0x26 = WRITE_COLOR)
|
||||
|
||||
@@ -28,10 +28,9 @@ static constexpr uint32_t OTA_SOCKET_TIMEOUT_HANDSHAKE = 20000; // milliseconds
|
||||
static constexpr uint32_t OTA_SOCKET_TIMEOUT_DATA = 90000; // milliseconds for data transfer
|
||||
|
||||
void ESPHomeOTAComponent::setup() {
|
||||
this->server_ = socket::socket_ip_loop_monitored(SOCK_STREAM, 0); // monitored for incoming connections
|
||||
this->server_ = socket::socket_ip_loop_monitored(SOCK_STREAM, 0).release(); // monitored for incoming connections
|
||||
if (this->server_ == nullptr) {
|
||||
this->log_socket_error_(LOG_STR("creation"));
|
||||
this->mark_failed();
|
||||
this->server_failed_(LOG_STR("creation"));
|
||||
return;
|
||||
}
|
||||
int enable = 1;
|
||||
@@ -42,8 +41,7 @@ void ESPHomeOTAComponent::setup() {
|
||||
}
|
||||
err = this->server_->setblocking(false);
|
||||
if (err != 0) {
|
||||
this->log_socket_error_(LOG_STR("non-blocking"));
|
||||
this->mark_failed();
|
||||
this->server_failed_(LOG_STR("nonblocking"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -51,22 +49,19 @@ void ESPHomeOTAComponent::setup() {
|
||||
|
||||
socklen_t sl = socket::set_sockaddr_any((struct sockaddr *) &server, sizeof(server), this->port_);
|
||||
if (sl == 0) {
|
||||
this->log_socket_error_(LOG_STR("set sockaddr"));
|
||||
this->mark_failed();
|
||||
this->server_failed_(LOG_STR("set sockaddr"));
|
||||
return;
|
||||
}
|
||||
|
||||
err = this->server_->bind((struct sockaddr *) &server, sizeof(server));
|
||||
if (err != 0) {
|
||||
this->log_socket_error_(LOG_STR("bind"));
|
||||
this->mark_failed();
|
||||
this->server_failed_(LOG_STR("bind"));
|
||||
return;
|
||||
}
|
||||
|
||||
err = this->server_->listen(1); // Only one client at a time
|
||||
if (err != 0) {
|
||||
this->log_socket_error_(LOG_STR("listen"));
|
||||
this->mark_failed();
|
||||
this->server_failed_(LOG_STR("listen"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -455,6 +450,15 @@ void ESPHomeOTAComponent::log_remote_closed_(const LogString *during) {
|
||||
ESP_LOGW(TAG, "Remote closed at %s", LOG_STR_ARG(during));
|
||||
}
|
||||
|
||||
void ESPHomeOTAComponent::server_failed_(const LogString *msg) {
|
||||
this->log_socket_error_(msg);
|
||||
// No explicit close() needed — listen sockets have no active connections on
|
||||
// failure/shutdown. Destructor handles fd cleanup (close or abort per platform).
|
||||
delete this->server_;
|
||||
this->server_ = nullptr;
|
||||
this->mark_failed();
|
||||
}
|
||||
|
||||
bool ESPHomeOTAComponent::handle_read_error_(ssize_t read, const LogString *desc) {
|
||||
if (read == -1 && this->would_block_(errno)) {
|
||||
return false; // No data yet, try again next loop
|
||||
|
||||
@@ -66,6 +66,7 @@ class ESPHomeOTAComponent : public ota::OTAComponent {
|
||||
this->handshake_buf_pos_ = 0; // Reset buffer position for next state
|
||||
}
|
||||
|
||||
void server_failed_(const LogString *msg);
|
||||
void log_socket_error_(const LogString *msg);
|
||||
void log_read_error_(const LogString *what);
|
||||
void log_start_(const LogString *phase);
|
||||
@@ -83,7 +84,7 @@ class ESPHomeOTAComponent : public ota::OTAComponent {
|
||||
std::unique_ptr<uint8_t[]> auth_buf_;
|
||||
#endif // USE_OTA_PASSWORD
|
||||
|
||||
std::unique_ptr<socket::Socket> server_;
|
||||
socket::Socket *server_{nullptr};
|
||||
std::unique_ptr<socket::Socket> client_;
|
||||
std::unique_ptr<ota::OTABackend> backend_;
|
||||
|
||||
|
||||
@@ -29,10 +29,10 @@ enum class CleaningState : uint8_t {
|
||||
enum class HonControlMethod { MONITOR_ONLY = 0, SET_GROUP_PARAMETERS, SET_SINGLE_PARAMETER };
|
||||
|
||||
struct HonSettings {
|
||||
hon_protocol::VerticalSwingMode last_vertiacal_swing;
|
||||
hon_protocol::HorizontalSwingMode last_horizontal_swing;
|
||||
bool beeper_state;
|
||||
bool quiet_mode_state;
|
||||
hon_protocol::VerticalSwingMode last_vertiacal_swing{hon_protocol::VerticalSwingMode::CENTER};
|
||||
hon_protocol::HorizontalSwingMode last_horizontal_swing{hon_protocol::HorizontalSwingMode::CENTER};
|
||||
bool beeper_state{true};
|
||||
bool quiet_mode_state{false};
|
||||
};
|
||||
|
||||
class HonClimate : public HaierClimateBase {
|
||||
@@ -189,7 +189,7 @@ class HonClimate : public HaierClimateBase {
|
||||
int big_data_sensors_{0};
|
||||
esphome::optional<hon_protocol::VerticalSwingMode> current_vertical_swing_{};
|
||||
esphome::optional<hon_protocol::HorizontalSwingMode> current_horizontal_swing_{};
|
||||
HonSettings settings_;
|
||||
HonSettings settings_{};
|
||||
ESPPreferenceObject hon_rtc_;
|
||||
SwitchState quiet_mode_state_{SwitchState::OFF};
|
||||
};
|
||||
|
||||
@@ -77,9 +77,10 @@ void init_uart(uart_port_t uart_num, uint32_t baud_rate, int tx_buffer_size) {
|
||||
uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
|
||||
uart_config.source_clk = UART_SCLK_DEFAULT;
|
||||
uart_param_config(uart_num, &uart_config);
|
||||
const int uart_buffer_size = tx_buffer_size;
|
||||
// Install UART driver using an event queue here
|
||||
uart_driver_install(uart_num, uart_buffer_size, uart_buffer_size, 10, nullptr, 0);
|
||||
// The logger only writes to UART, never reads, so use the minimum RX buffer.
|
||||
// ESP-IDF requires rx_buffer_size > UART_HW_FIFO_LEN (128 bytes).
|
||||
const int min_rx_buffer_size = UART_HW_FIFO_LEN(uart_num) + 1;
|
||||
uart_driver_install(uart_num, min_rx_buffer_size, tx_buffer_size, 0, nullptr, 0);
|
||||
}
|
||||
|
||||
void Logger::pre_setup() {
|
||||
|
||||
@@ -87,38 +87,24 @@ COLOR_DEPTHS = {
|
||||
|
||||
def model_schema(config):
|
||||
model = MODELS[config[CONF_MODEL].upper()]
|
||||
model.defaults[CONF_SWAP_XY] = cv.UNDEFINED
|
||||
transform = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_MIRROR_X): cv.boolean,
|
||||
cv.Required(CONF_MIRROR_Y): cv.boolean,
|
||||
cv.Optional(CONF_SWAP_XY): cv.invalid(
|
||||
"Axis swapping not supported by DSI displays"
|
||||
),
|
||||
}
|
||||
)
|
||||
if model.get_default(CONF_SWAP_XY) != cv.UNDEFINED:
|
||||
transform = transform.extend(
|
||||
{
|
||||
cv.Optional(CONF_SWAP_XY): cv.invalid(
|
||||
"Axis swapping not supported by this model"
|
||||
)
|
||||
}
|
||||
)
|
||||
else:
|
||||
transform = transform.extend(
|
||||
{
|
||||
cv.Required(CONF_SWAP_XY): cv.boolean,
|
||||
}
|
||||
)
|
||||
# CUSTOM model will need to provide a custom init sequence
|
||||
iseqconf = (
|
||||
cv.Required(CONF_INIT_SEQUENCE)
|
||||
if model.initsequence is None
|
||||
else cv.Optional(CONF_INIT_SEQUENCE)
|
||||
)
|
||||
swap_xy = config.get(CONF_TRANSFORM, {}).get(CONF_SWAP_XY, False)
|
||||
|
||||
# Dimensions are optional if the model has a default width and the swap_xy transform is not overridden
|
||||
cv_dimensions = (
|
||||
cv.Optional if model.get_default(CONF_WIDTH) and not swap_xy else cv.Required
|
||||
)
|
||||
# Dimensions are optional if the model has a default width
|
||||
cv_dimensions = cv.Optional if model.get_default(CONF_WIDTH) else cv.Required
|
||||
pixel_modes = (PIXEL_MODE_16BIT, PIXEL_MODE_24BIT, "16", "24")
|
||||
schema = display.FULL_DISPLAY_SCHEMA.extend(
|
||||
{
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import re
|
||||
|
||||
from esphome import automation
|
||||
from esphome.automation import Condition
|
||||
import esphome.codegen as cg
|
||||
@@ -46,7 +44,6 @@ from esphome.const import (
|
||||
CONF_RETAIN,
|
||||
CONF_SHUTDOWN_MESSAGE,
|
||||
CONF_SKIP_CERT_CN_CHECK,
|
||||
CONF_SSL_FINGERPRINTS,
|
||||
CONF_STATE_TOPIC,
|
||||
CONF_SUBSCRIBE_QOS,
|
||||
CONF_TOPIC,
|
||||
@@ -221,13 +218,6 @@ def validate_config(value):
|
||||
return out
|
||||
|
||||
|
||||
def validate_fingerprint(value):
|
||||
value = cv.string(value)
|
||||
if re.match(r"^[0-9a-f]{40}$", value) is None:
|
||||
raise cv.Invalid("fingerprint must be valid SHA1 hash")
|
||||
return value
|
||||
|
||||
|
||||
def _consume_mqtt_sockets(config: ConfigType) -> ConfigType:
|
||||
"""Register socket needs for MQTT component."""
|
||||
# MQTT needs 1 socket for the broker connection
|
||||
@@ -291,9 +281,6 @@ CONFIG_SCHEMA = cv.All(
|
||||
),
|
||||
validate_message_just_topic,
|
||||
),
|
||||
cv.Optional(CONF_SSL_FINGERPRINTS): cv.All(
|
||||
cv.only_on_esp8266, cv.ensure_list(validate_fingerprint)
|
||||
),
|
||||
cv.Optional(CONF_KEEPALIVE, default="15s"): cv.positive_time_period_seconds,
|
||||
cv.Optional(
|
||||
CONF_REBOOT_TIMEOUT, default="15min"
|
||||
@@ -444,14 +431,6 @@ async def to_code(config):
|
||||
if CONF_LEVEL in log_topic:
|
||||
cg.add(var.set_log_level(logger.LOG_LEVELS[log_topic[CONF_LEVEL]]))
|
||||
|
||||
if CONF_SSL_FINGERPRINTS in config:
|
||||
for fingerprint in config[CONF_SSL_FINGERPRINTS]:
|
||||
arr = [
|
||||
cg.RawExpression(f"0x{fingerprint[i : i + 2]}") for i in range(0, 40, 2)
|
||||
]
|
||||
cg.add(var.add_ssl_fingerprint(arr))
|
||||
cg.add_build_flag("-DASYNC_TCP_SSL_ENABLED=1")
|
||||
|
||||
cg.add(var.set_keep_alive(config[CONF_KEEPALIVE]))
|
||||
|
||||
cg.add(var.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT]))
|
||||
|
||||
@@ -21,11 +21,6 @@ class MQTTBackendESP8266 final : public MQTTBackend {
|
||||
}
|
||||
void set_server(network::IPAddress ip, uint16_t port) final { mqtt_client_.setServer(ip, port); }
|
||||
void set_server(const char *host, uint16_t port) final { mqtt_client_.setServer(host, port); }
|
||||
#if ASYNC_TCP_SSL_ENABLED
|
||||
void set_secure(bool secure) { mqtt_client.setSecure(secure); }
|
||||
void add_server_fingerprint(const uint8_t *fingerprint) { mqtt_client.addServerFingerprint(fingerprint); }
|
||||
#endif
|
||||
|
||||
void set_on_connect(std::function<on_connect_callback_t> &&callback) final {
|
||||
this->mqtt_client_.onConnect(std::move(callback));
|
||||
}
|
||||
|
||||
@@ -21,11 +21,6 @@ class MQTTBackendLibreTiny final : public MQTTBackend {
|
||||
}
|
||||
void set_server(network::IPAddress ip, uint16_t port) final { mqtt_client_.setServer(IPAddress(ip), port); }
|
||||
void set_server(const char *host, uint16_t port) final { mqtt_client_.setServer(host, port); }
|
||||
#if ASYNC_TCP_SSL_ENABLED
|
||||
void set_secure(bool secure) { mqtt_client.setSecure(secure); }
|
||||
void add_server_fingerprint(const uint8_t *fingerprint) { mqtt_client.addServerFingerprint(fingerprint); }
|
||||
#endif
|
||||
|
||||
void set_on_connect(std::function<on_connect_callback_t> &&callback) final {
|
||||
this->mqtt_client_.onConnect(std::move(callback));
|
||||
}
|
||||
|
||||
@@ -749,13 +749,6 @@ void MQTTClientComponent::set_on_disconnect(mqtt_on_disconnect_callback_t &&call
|
||||
this->on_disconnect_.add(std::move(callback_copy));
|
||||
}
|
||||
|
||||
#if ASYNC_TCP_SSL_ENABLED
|
||||
void MQTTClientComponent::add_ssl_fingerprint(const std::array<uint8_t, SHA1_SIZE> &fingerprint) {
|
||||
this->mqtt_backend_.setSecure(true);
|
||||
this->mqtt_backend_.addServerFingerprint(fingerprint.data());
|
||||
}
|
||||
#endif
|
||||
|
||||
MQTTClientComponent *global_mqtt_client = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
// MQTTMessageTrigger
|
||||
|
||||
@@ -137,21 +137,6 @@ class MQTTClientComponent : public Component {
|
||||
bool is_discovery_enabled() const;
|
||||
bool is_discovery_ip_enabled() const;
|
||||
|
||||
#if ASYNC_TCP_SSL_ENABLED
|
||||
/** Add a SSL fingerprint to use for TCP SSL connections to the MQTT broker.
|
||||
*
|
||||
* To use this feature you first have to globally enable the `ASYNC_TCP_SSL_ENABLED` define flag.
|
||||
* This function can be called multiple times and any certificate that matches any of the provided fingerprints
|
||||
* will match. Calling this method will also automatically disable all non-ssl connections.
|
||||
*
|
||||
* @warning This is *not* secure and *not* how SSL is usually done. You'll have to add
|
||||
* a separate fingerprint for every certificate you use. Additionally, the hashing
|
||||
* algorithm used here due to the constraints of the MCU, SHA1, is known to be insecure.
|
||||
*
|
||||
* @param fingerprint The SSL fingerprint as a 20 value long std::array.
|
||||
*/
|
||||
void add_ssl_fingerprint(const std::array<uint8_t, SHA1_SIZE> &fingerprint);
|
||||
#endif
|
||||
#ifdef USE_ESP32
|
||||
void set_ca_certificate(const char *cert) { this->mqtt_backend_.set_ca_certificate(cert); }
|
||||
void set_cl_certificate(const char *cert) { this->mqtt_backend_.set_cl_certificate(cert); }
|
||||
|
||||
@@ -243,6 +243,7 @@
|
||||
X(MQTT_STATE_VALUE_TEMPLATE, "stat_val_tpl", "state_value_template") \
|
||||
X(MQTT_STEP, "step", "step") \
|
||||
X(MQTT_SUBTYPE, "stype", "subtype") \
|
||||
X(MQTT_SUGGESTED_DISPLAY_PRECISION, "sug_dsp_prc", "suggested_display_precision") \
|
||||
X(MQTT_SUPPORTED_COLOR_MODES, "sup_clrm", "supported_color_modes") \
|
||||
X(MQTT_SUPPORTED_FEATURES, "sup_feat", "supported_features") \
|
||||
X(MQTT_SWING_MODE_COMMAND_TEMPLATE, "swing_mode_cmd_tpl", "swing_mode_command_template") \
|
||||
|
||||
@@ -49,6 +49,10 @@ void MQTTSensorComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryCon
|
||||
root[MQTT_DEVICE_CLASS] = device_class;
|
||||
}
|
||||
|
||||
if (this->sensor_->has_accuracy_decimals()) {
|
||||
root[MQTT_SUGGESTED_DISPLAY_PRECISION] = this->sensor_->get_accuracy_decimals();
|
||||
}
|
||||
|
||||
const auto unit_of_measurement = this->sensor_->get_unit_of_measurement_ref();
|
||||
if (!unit_of_measurement.empty()) {
|
||||
root[MQTT_UNIT_OF_MEASUREMENT] = unit_of_measurement;
|
||||
|
||||
@@ -220,6 +220,7 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) {
|
||||
}
|
||||
|
||||
if (code != 200 and code != 206) {
|
||||
ESP_LOGE(TAG, "HTTP request failed with status %d", code);
|
||||
return this->upload_end_(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -238,6 +238,7 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) {
|
||||
esp_get_free_heap_size());
|
||||
int status_code = esp_http_client_get_status_code(http_client);
|
||||
if (status_code != 200 && status_code != 206) {
|
||||
ESP_LOGE(TAG, "HTTP request failed with status %d", status_code);
|
||||
return this->upload_end_(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ from __future__ import annotations
|
||||
import asyncio
|
||||
import logging
|
||||
from pathlib import Path
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
@@ -380,3 +382,41 @@ def show_logs(config: ConfigType, args, devices: list[str]) -> bool:
|
||||
asyncio.run(logger_connect(address))
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _addr2line(addr2line: str, elf: Path, addr: str) -> str:
|
||||
try:
|
||||
result = subprocess.run(
|
||||
[addr2line, "-e", elf, addr],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
return result.stdout.strip().splitlines()[0]
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
_LOGGER.error("Running command failed: %s", err)
|
||||
return ""
|
||||
|
||||
|
||||
def process_stacktrace(config: ConfigType, line: str, backtrace_state: bool) -> bool:
|
||||
if "Last crash:" in line:
|
||||
return True
|
||||
if backtrace_state:
|
||||
match = re.search(r"PC=(0x[0-9a-fA-F]+)\s+LR=(0x[0-9a-fA-F]+)", line)
|
||||
if match:
|
||||
pc = match.group(1)
|
||||
lr = match.group(2)
|
||||
from esphome.analyze_memory.toolchain import find_tool
|
||||
|
||||
addr2line = find_tool("addr2line")
|
||||
if addr2line is None:
|
||||
return False
|
||||
elf = CORE.relative_pioenvs_path(CORE.name, "firmware.elf")
|
||||
if not elf.exists():
|
||||
_LOGGER.warning("%s does not exists", elf)
|
||||
return False
|
||||
_LOGGER.error("=== CRASH ===")
|
||||
_LOGGER.error("PC: %s", _addr2line(addr2line, elf, pc))
|
||||
_LOGGER.error("LR: %s", _addr2line(addr2line, elf, lr))
|
||||
|
||||
return False
|
||||
|
||||
@@ -48,6 +48,8 @@ class Sensor : public EntityBase, public EntityBase_DeviceClass, public EntityBa
|
||||
int8_t get_accuracy_decimals();
|
||||
/// Manually set the accuracy in decimals.
|
||||
void set_accuracy_decimals(int8_t accuracy_decimals);
|
||||
/// Check if the accuracy in decimals has been manually set.
|
||||
bool has_accuracy_decimals() const { return this->sensor_flags_.has_accuracy_override; }
|
||||
|
||||
/// Get the state class, using the manual override if set.
|
||||
StateClass get_state_class();
|
||||
|
||||
@@ -1,30 +1,16 @@
|
||||
#include "uptime_seconds_sensor.h"
|
||||
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/application.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace uptime {
|
||||
namespace esphome::uptime {
|
||||
|
||||
static const char *const TAG = "uptime.sensor";
|
||||
|
||||
void UptimeSecondsSensor::update() {
|
||||
const uint32_t ms = millis();
|
||||
const uint64_t ms_mask = (1ULL << 32) - 1ULL;
|
||||
const uint32_t last_ms = this->uptime_ & ms_mask;
|
||||
if (ms < last_ms) {
|
||||
this->uptime_ += ms_mask + 1ULL;
|
||||
ESP_LOGD(TAG, "Detected roll-over \xf0\x9f\xa6\x84");
|
||||
}
|
||||
this->uptime_ &= ~ms_mask;
|
||||
this->uptime_ |= ms;
|
||||
|
||||
// Do separate second and milliseconds conversion to avoid floating point division errors
|
||||
// Probably some IEEE standard already guarantees this division can be done without loss
|
||||
// of precision in a single division, but let's do it like this to be sure.
|
||||
const uint64_t seconds_int = this->uptime_ / 1000ULL;
|
||||
const float seconds = float(seconds_int) + (this->uptime_ % 1000ULL) / 1000.0f;
|
||||
const uint64_t uptime = App.scheduler.millis_64();
|
||||
const uint64_t seconds_int = uptime / 1000ULL;
|
||||
const float seconds = float(seconds_int) + (uptime % 1000ULL) / 1000.0f;
|
||||
this->publish_state(seconds);
|
||||
}
|
||||
float UptimeSecondsSensor::get_setup_priority() const { return setup_priority::HARDWARE; }
|
||||
@@ -33,5 +19,4 @@ void UptimeSecondsSensor::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, " Type: Seconds");
|
||||
}
|
||||
|
||||
} // namespace uptime
|
||||
} // namespace esphome
|
||||
} // namespace esphome::uptime
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace uptime {
|
||||
namespace esphome::uptime {
|
||||
|
||||
class UptimeSecondsSensor : public sensor::Sensor, public PollingComponent {
|
||||
public:
|
||||
@@ -12,10 +11,6 @@ class UptimeSecondsSensor : public sensor::Sensor, public PollingComponent {
|
||||
void dump_config() override;
|
||||
|
||||
float get_setup_priority() const override;
|
||||
|
||||
protected:
|
||||
uint64_t uptime_{0};
|
||||
};
|
||||
|
||||
} // namespace uptime
|
||||
} // namespace esphome
|
||||
} // namespace esphome::uptime
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace uptime {
|
||||
namespace esphome::uptime {
|
||||
|
||||
static const char *const TAG = "uptime.sensor";
|
||||
|
||||
@@ -33,7 +32,6 @@ void UptimeTimestampSensor::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, " Type: Timestamp");
|
||||
}
|
||||
|
||||
} // namespace uptime
|
||||
} // namespace esphome
|
||||
} // namespace esphome::uptime
|
||||
|
||||
#endif // USE_TIME
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
#include "esphome/components/time/real_time_clock.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace uptime {
|
||||
namespace esphome::uptime {
|
||||
|
||||
class UptimeTimestampSensor : public sensor::Sensor, public Component {
|
||||
public:
|
||||
@@ -24,7 +23,6 @@ class UptimeTimestampSensor : public sensor::Sensor, public Component {
|
||||
time::RealTimeClock *time_;
|
||||
};
|
||||
|
||||
} // namespace uptime
|
||||
} // namespace esphome
|
||||
} // namespace esphome::uptime
|
||||
|
||||
#endif // USE_TIME
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#include "uptime_text_sensor.h"
|
||||
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/application.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace uptime {
|
||||
namespace esphome::uptime {
|
||||
|
||||
static const char *const TAG = "uptime.sensor";
|
||||
|
||||
@@ -17,22 +16,10 @@ static void append_unit(char *buf, size_t buf_size, size_t &pos, const char *sep
|
||||
pos = buf_append_printf(buf, buf_size, pos, "%u%s", value, label);
|
||||
}
|
||||
|
||||
void UptimeTextSensor::setup() {
|
||||
this->last_ms_ = millis();
|
||||
if (this->last_ms_ < 60 * 1000)
|
||||
this->last_ms_ = 0;
|
||||
this->update();
|
||||
}
|
||||
void UptimeTextSensor::setup() { this->update(); }
|
||||
|
||||
void UptimeTextSensor::update() {
|
||||
auto now = millis();
|
||||
// get whole seconds since last update. Note that even if the millis count has overflowed between updates,
|
||||
// the difference will still be correct due to the way twos-complement arithmetic works.
|
||||
uint32_t delta = now - this->last_ms_;
|
||||
this->last_ms_ = now - delta % 1000; // save remainder for next update
|
||||
delta /= 1000;
|
||||
this->uptime_ += delta;
|
||||
uint32_t uptime = this->uptime_;
|
||||
uint32_t uptime = static_cast<uint32_t>(App.scheduler.millis_64() / 1000);
|
||||
unsigned interval = this->get_update_interval() / 1000;
|
||||
|
||||
// Calculate all time units
|
||||
@@ -89,5 +76,4 @@ void UptimeTextSensor::update() {
|
||||
float UptimeTextSensor::get_setup_priority() const { return setup_priority::HARDWARE; }
|
||||
void UptimeTextSensor::dump_config() { LOG_TEXT_SENSOR("", "Uptime Text Sensor", this); }
|
||||
|
||||
} // namespace uptime
|
||||
} // namespace esphome
|
||||
} // namespace esphome::uptime
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
#include "esphome/components/text_sensor/text_sensor.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace uptime {
|
||||
namespace esphome::uptime {
|
||||
|
||||
class UptimeTextSensor : public text_sensor::TextSensor, public PollingComponent {
|
||||
public:
|
||||
@@ -35,9 +34,6 @@ class UptimeTextSensor : public text_sensor::TextSensor, public PollingComponent
|
||||
const char *seconds_text_;
|
||||
const char *separator_;
|
||||
bool expand_{};
|
||||
uint32_t uptime_{0}; // uptime in seconds, will overflow after 136 years
|
||||
uint32_t last_ms_{0};
|
||||
};
|
||||
|
||||
} // namespace uptime
|
||||
} // namespace esphome
|
||||
} // namespace esphome::uptime
|
||||
|
||||
@@ -943,7 +943,6 @@ CONF_SPI = "spi"
|
||||
CONF_SPI_ID = "spi_id"
|
||||
CONF_SPIKE_REJECTION = "spike_rejection"
|
||||
CONF_SSID = "ssid"
|
||||
CONF_SSL_FINGERPRINTS = "ssl_fingerprints"
|
||||
CONF_STARTUP_DELAY = "startup_delay"
|
||||
CONF_STATE = "state"
|
||||
CONF_STATE_CLASS = "state_class"
|
||||
|
||||
@@ -119,10 +119,16 @@ uint32_t Scheduler::calculate_interval_offset_(uint32_t delay) {
|
||||
// Remove before 2026.8.0 along with all retry code
|
||||
bool Scheduler::is_retry_cancelled_locked_(Component *component, NameType name_type, const char *static_name,
|
||||
uint32_t hash_or_id) {
|
||||
return has_cancelled_timeout_in_container_locked_(this->items_, component, name_type, static_name, hash_or_id,
|
||||
/* match_retry= */ true) ||
|
||||
has_cancelled_timeout_in_container_locked_(this->to_add_, component, name_type, static_name, hash_or_id,
|
||||
/* match_retry= */ true);
|
||||
for (auto *container : {&this->items_, &this->to_add_}) {
|
||||
for (auto &item : *container) {
|
||||
if (item && this->is_item_removed_locked_(item.get()) &&
|
||||
this->matches_item_locked_(item, component, name_type, static_name, hash_or_id, SchedulerItem::TIMEOUT,
|
||||
/* match_retry= */ true, /* skip_removed= */ false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Common implementation for both timeout and interval
|
||||
@@ -406,7 +412,7 @@ void Scheduler::full_cleanup_removed_items_() {
|
||||
// Compact in-place: move valid items forward, recycle removed ones
|
||||
size_t write = 0;
|
||||
for (size_t read = 0; read < this->items_.size(); ++read) {
|
||||
if (!is_item_removed_(this->items_[read].get())) {
|
||||
if (!is_item_removed_locked_(this->items_[read].get())) {
|
||||
if (write != read) {
|
||||
this->items_[write] = std::move(this->items_[read]);
|
||||
}
|
||||
@@ -421,6 +427,29 @@ void Scheduler::full_cleanup_removed_items_() {
|
||||
this->to_remove_ = 0;
|
||||
}
|
||||
|
||||
#ifndef ESPHOME_THREAD_SINGLE
|
||||
void Scheduler::compact_defer_queue_locked_() {
|
||||
// Rare case: new items were added during processing - compact the vector
|
||||
// This only happens when:
|
||||
// 1. A deferred callback calls defer() again, or
|
||||
// 2. Another thread calls defer() while we're processing
|
||||
//
|
||||
// Move unprocessed items (added during this loop) to the front for next iteration
|
||||
//
|
||||
// SAFETY: Compacted items may include cancelled items (marked for removal via
|
||||
// cancel_item_locked_() during execution). This is safe because should_skip_item_()
|
||||
// checks is_item_removed_() before executing, so cancelled items will be skipped
|
||||
// and recycled on the next loop iteration.
|
||||
size_t remaining = this->defer_queue_.size() - this->defer_queue_front_;
|
||||
for (size_t i = 0; i < remaining; i++) {
|
||||
this->defer_queue_[i] = std::move(this->defer_queue_[this->defer_queue_front_ + i]);
|
||||
}
|
||||
// Use erase() instead of resize() to avoid instantiating _M_default_append
|
||||
// (saves ~156 bytes flash). Erasing from the end is O(1) - no shifting needed.
|
||||
this->defer_queue_.erase(this->defer_queue_.begin() + remaining, this->defer_queue_.end());
|
||||
}
|
||||
#endif /* not ESPHOME_THREAD_SINGLE */
|
||||
|
||||
void HOT Scheduler::call(uint32_t now) {
|
||||
#ifndef ESPHOME_THREAD_SINGLE
|
||||
this->process_defer_queue_(now);
|
||||
@@ -508,7 +537,7 @@ void HOT Scheduler::call(uint32_t now) {
|
||||
// Multi-threaded platforms without atomics: must take lock to safely read remove flag
|
||||
{
|
||||
LockGuard guard{this->lock_};
|
||||
if (is_item_removed_(item.get())) {
|
||||
if (is_item_removed_locked_(item.get())) {
|
||||
this->recycle_item_main_loop_(this->pop_raw_locked_());
|
||||
this->to_remove_--;
|
||||
continue;
|
||||
@@ -545,7 +574,7 @@ void HOT Scheduler::call(uint32_t now) {
|
||||
// during the function call and know if we were cancelled.
|
||||
auto executed_item = this->pop_raw_locked_();
|
||||
|
||||
if (executed_item->remove) {
|
||||
if (this->is_item_removed_locked_(executed_item.get())) {
|
||||
// We were removed/cancelled in the function call, recycle and continue
|
||||
this->to_remove_--;
|
||||
this->recycle_item_main_loop_(std::move(executed_item));
|
||||
@@ -572,7 +601,7 @@ void HOT Scheduler::call(uint32_t now) {
|
||||
void HOT Scheduler::process_to_add() {
|
||||
LockGuard guard{this->lock_};
|
||||
for (auto &it : this->to_add_) {
|
||||
if (is_item_removed_(it.get())) {
|
||||
if (is_item_removed_locked_(it.get())) {
|
||||
// Recycle cancelled items
|
||||
this->recycle_item_main_loop_(std::move(it));
|
||||
continue;
|
||||
@@ -605,7 +634,7 @@ size_t HOT Scheduler::cleanup_() {
|
||||
LockGuard guard{this->lock_};
|
||||
while (!this->items_.empty()) {
|
||||
auto &item = this->items_[0];
|
||||
if (!item->remove)
|
||||
if (!this->is_item_removed_locked_(item.get()))
|
||||
break;
|
||||
this->to_remove_--;
|
||||
this->recycle_item_main_loop_(this->pop_raw_locked_());
|
||||
@@ -675,6 +704,8 @@ bool HOT Scheduler::cancel_item_locked_(Component *component, NameType name_type
|
||||
return total_cancelled > 0;
|
||||
}
|
||||
|
||||
uint64_t Scheduler::millis_64() { return this->millis_64_(millis()); }
|
||||
|
||||
uint64_t Scheduler::millis_64_(uint32_t now) {
|
||||
// THREAD SAFETY NOTE:
|
||||
// This function has three implementations, based on the precompiler flags
|
||||
|
||||
@@ -116,6 +116,9 @@ class Scheduler {
|
||||
ESPDEPRECATED("cancel_retry is deprecated and will be removed in 2026.8.0.", "2026.2.0")
|
||||
bool cancel_retry(Component *component, uint32_t id);
|
||||
|
||||
/// Get 64-bit millisecond timestamp (handles 32-bit millis() rollover)
|
||||
uint64_t millis_64();
|
||||
|
||||
// Calculate when the next scheduled item should run
|
||||
// @param now Fresh timestamp from millis() - must not be stale/cached
|
||||
// Returns the time in milliseconds until the next scheduled item, or nullopt if no items
|
||||
@@ -305,14 +308,14 @@ class Scheduler {
|
||||
SchedulerItem::Type type, bool match_retry, bool skip_removed = true) const {
|
||||
// THREAD SAFETY: Check for nullptr first to prevent LoadProhibited crashes. On multi-threaded
|
||||
// platforms, items can be moved out of defer_queue_ during processing, leaving nullptr entries.
|
||||
// PR #11305 added nullptr checks in callers (mark_matching_items_removed_locked_() and
|
||||
// has_cancelled_timeout_in_container_locked_()), but this check provides defense-in-depth: helper
|
||||
// PR #11305 added nullptr checks in callers (mark_matching_items_removed_locked_()), but this check
|
||||
// provides defense-in-depth: helper
|
||||
// functions should be safe regardless of caller behavior.
|
||||
// Fixes: https://github.com/esphome/esphome/issues/11940
|
||||
if (!item)
|
||||
return false;
|
||||
if (item->component != component || item->type != type || (skip_removed && item->remove) ||
|
||||
(match_retry && !item->is_retry)) {
|
||||
if (item->component != component || item->type != type ||
|
||||
(skip_removed && this->is_item_removed_locked_(item.get())) || (match_retry && !item->is_retry)) {
|
||||
return false;
|
||||
}
|
||||
// Name type must match
|
||||
@@ -384,41 +387,45 @@ class Scheduler {
|
||||
// No lock needed: single consumer (main loop), stale read just means we process less this iteration
|
||||
size_t defer_queue_end = this->defer_queue_.size();
|
||||
|
||||
// Fast path: nothing to process, avoid lock entirely.
|
||||
// Safe without lock: single consumer (main loop) reads front_, and a stale size() read
|
||||
// from a concurrent push can only make us see fewer items — they'll be processed next loop.
|
||||
if (this->defer_queue_front_ >= defer_queue_end)
|
||||
return;
|
||||
|
||||
// Merge lock acquisitions: instead of separate locks for move-out and recycle (2N+1 total),
|
||||
// recycle each item after re-acquiring the lock for the next iteration (N+1 total).
|
||||
// The lock is held across: recycle → loop condition → move-out, then released for execution.
|
||||
std::unique_ptr<SchedulerItem> item;
|
||||
|
||||
this->lock_.lock();
|
||||
while (this->defer_queue_front_ < defer_queue_end) {
|
||||
std::unique_ptr<SchedulerItem> item;
|
||||
{
|
||||
LockGuard lock(this->lock_);
|
||||
// SAFETY: Moving out the unique_ptr leaves a nullptr in the vector at defer_queue_front_.
|
||||
// This is intentional and safe because:
|
||||
// 1. The vector is only cleaned up by cleanup_defer_queue_locked_() at the end of this function
|
||||
// 2. Any code iterating defer_queue_ MUST check for nullptr items (see mark_matching_items_removed_locked_
|
||||
// and has_cancelled_timeout_in_container_locked_ in scheduler.h)
|
||||
// 3. The lock protects concurrent access, but the nullptr remains until cleanup
|
||||
item = std::move(this->defer_queue_[this->defer_queue_front_]);
|
||||
this->defer_queue_front_++;
|
||||
}
|
||||
// SAFETY: Moving out the unique_ptr leaves a nullptr in the vector at defer_queue_front_.
|
||||
// This is intentional and safe because:
|
||||
// 1. The vector is only cleaned up by cleanup_defer_queue_locked_() at the end of this function
|
||||
// 2. Any code iterating defer_queue_ MUST check for nullptr items (see mark_matching_items_removed_locked_)
|
||||
// 3. The lock protects concurrent access, but the nullptr remains until cleanup
|
||||
item = std::move(this->defer_queue_[this->defer_queue_front_]);
|
||||
this->defer_queue_front_++;
|
||||
this->lock_.unlock();
|
||||
|
||||
// Execute callback without holding lock to prevent deadlocks
|
||||
// if the callback tries to call defer() again
|
||||
if (!this->should_skip_item_(item.get())) {
|
||||
now = this->execute_item_(item.get(), now);
|
||||
}
|
||||
// Recycle the defer item after execution
|
||||
{
|
||||
LockGuard lock(this->lock_);
|
||||
this->recycle_item_main_loop_(std::move(item));
|
||||
}
|
||||
}
|
||||
|
||||
// If we've consumed all items up to the snapshot point, clean up the dead space
|
||||
// Single consumer (main loop), so no lock needed for this check
|
||||
if (this->defer_queue_front_ >= defer_queue_end) {
|
||||
LockGuard lock(this->lock_);
|
||||
this->cleanup_defer_queue_locked_();
|
||||
this->lock_.lock();
|
||||
this->recycle_item_main_loop_(std::move(item));
|
||||
}
|
||||
// Clean up the queue (lock already held from last recycle or initial acquisition)
|
||||
this->cleanup_defer_queue_locked_();
|
||||
this->lock_.unlock();
|
||||
}
|
||||
|
||||
// Helper to cleanup defer_queue_ after processing
|
||||
// Helper to cleanup defer_queue_ after processing.
|
||||
// Keeps the common clear() path inline, outlines the rare compaction to keep
|
||||
// cold code out of the hot instruction cache lines.
|
||||
// IMPORTANT: Caller must hold the scheduler lock before calling this function.
|
||||
inline void cleanup_defer_queue_locked_() {
|
||||
// Check if new items were added by producers during processing
|
||||
@@ -426,27 +433,17 @@ class Scheduler {
|
||||
// Common case: no new items - clear everything
|
||||
this->defer_queue_.clear();
|
||||
} else {
|
||||
// Rare case: new items were added during processing - compact the vector
|
||||
// This only happens when:
|
||||
// 1. A deferred callback calls defer() again, or
|
||||
// 2. Another thread calls defer() while we're processing
|
||||
//
|
||||
// Move unprocessed items (added during this loop) to the front for next iteration
|
||||
//
|
||||
// SAFETY: Compacted items may include cancelled items (marked for removal via
|
||||
// cancel_item_locked_() during execution). This is safe because should_skip_item_()
|
||||
// checks is_item_removed_() before executing, so cancelled items will be skipped
|
||||
// and recycled on the next loop iteration.
|
||||
size_t remaining = this->defer_queue_.size() - this->defer_queue_front_;
|
||||
for (size_t i = 0; i < remaining; i++) {
|
||||
this->defer_queue_[i] = std::move(this->defer_queue_[this->defer_queue_front_ + i]);
|
||||
}
|
||||
// Use erase() instead of resize() to avoid instantiating _M_default_append
|
||||
// (saves ~156 bytes flash). Erasing from the end is O(1) - no shifting needed.
|
||||
this->defer_queue_.erase(this->defer_queue_.begin() + remaining, this->defer_queue_.end());
|
||||
// Rare case: new items were added during processing - outlined to keep cold code
|
||||
// out of the hot instruction cache lines
|
||||
this->compact_defer_queue_locked_();
|
||||
}
|
||||
this->defer_queue_front_ = 0;
|
||||
}
|
||||
|
||||
// Cold path for compacting defer_queue_ when new items were added during processing.
|
||||
// IMPORTANT: Caller must hold the scheduler lock before calling this function.
|
||||
// IMPORTANT: Must not be inlined - rare path, outlined to keep it out of the hot instruction cache lines.
|
||||
void __attribute__((noinline)) compact_defer_queue_locked_();
|
||||
#endif /* not ESPHOME_THREAD_SINGLE */
|
||||
|
||||
// Helper to check if item is marked for removal (platform-specific)
|
||||
@@ -465,6 +462,18 @@ class Scheduler {
|
||||
#endif
|
||||
}
|
||||
|
||||
// Helper to check if item is marked for removal when lock is already held.
|
||||
// Uses relaxed ordering since the mutex provides all necessary synchronization.
|
||||
// IMPORTANT: Caller must hold the scheduler lock before calling this function.
|
||||
bool is_item_removed_locked_(SchedulerItem *item) const {
|
||||
#ifdef ESPHOME_THREAD_MULTI_ATOMICS
|
||||
// Lock already held - relaxed is sufficient, mutex provides ordering
|
||||
return item->remove.load(std::memory_order_relaxed);
|
||||
#else
|
||||
return item->remove;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Helper to set item removal flag (platform-specific)
|
||||
// For ESPHOME_THREAD_MULTI_NO_ATOMICS platforms, the caller must hold the scheduler lock before calling this
|
||||
// function. Uses memory_order_release when setting to true (for cancellation synchronization),
|
||||
@@ -487,19 +496,16 @@ class Scheduler {
|
||||
// name_type determines matching: STATIC_STRING uses static_name, others use hash_or_id
|
||||
// Returns the number of items marked for removal
|
||||
// IMPORTANT: Must be called with scheduler lock held
|
||||
template<typename Container>
|
||||
size_t mark_matching_items_removed_locked_(Container &container, Component *component, NameType name_type,
|
||||
const char *static_name, uint32_t hash_or_id, SchedulerItem::Type type,
|
||||
bool match_retry) {
|
||||
size_t mark_matching_items_removed_locked_(std::vector<std::unique_ptr<SchedulerItem>> &container,
|
||||
Component *component, NameType name_type, const char *static_name,
|
||||
uint32_t hash_or_id, SchedulerItem::Type type, bool match_retry) {
|
||||
size_t count = 0;
|
||||
for (auto &item : container) {
|
||||
// Skip nullptr items (can happen in defer_queue_ when items are being processed)
|
||||
// The defer_queue_ uses index-based processing: items are std::moved out but left in the
|
||||
// vector as nullptr until cleanup. Even though this function is called with lock held,
|
||||
// the vector can still contain nullptr items from the processing loop. This check prevents crashes.
|
||||
if (!item)
|
||||
continue;
|
||||
if (this->matches_item_locked_(item, component, name_type, static_name, hash_or_id, type, match_retry)) {
|
||||
if (item && this->matches_item_locked_(item, component, name_type, static_name, hash_or_id, type, match_retry)) {
|
||||
this->set_item_removed_(item.get(), true);
|
||||
count++;
|
||||
}
|
||||
@@ -507,29 +513,6 @@ class Scheduler {
|
||||
return count;
|
||||
}
|
||||
|
||||
// Template helper to check if any item in a container matches our criteria
|
||||
// name_type determines matching: STATIC_STRING uses static_name, others use hash_or_id
|
||||
// IMPORTANT: Must be called with scheduler lock held
|
||||
template<typename Container>
|
||||
bool has_cancelled_timeout_in_container_locked_(const Container &container, Component *component, NameType name_type,
|
||||
const char *static_name, uint32_t hash_or_id,
|
||||
bool match_retry) const {
|
||||
for (const auto &item : container) {
|
||||
// Skip nullptr items (can happen in defer_queue_ when items are being processed)
|
||||
// The defer_queue_ uses index-based processing: items are std::moved out but left in the
|
||||
// vector as nullptr until cleanup. If this function is called during defer queue processing,
|
||||
// it will iterate over these nullptr items. This check prevents crashes.
|
||||
if (!item)
|
||||
continue;
|
||||
if (is_item_removed_(item.get()) &&
|
||||
this->matches_item_locked_(item, component, name_type, static_name, hash_or_id, SchedulerItem::TIMEOUT,
|
||||
match_retry, /* skip_removed= */ false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Mutex lock_;
|
||||
std::vector<std::unique_ptr<SchedulerItem>> items_;
|
||||
std::vector<std::unique_ptr<SchedulerItem>> to_add_;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import contextlib
|
||||
from datetime import datetime
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
import ssl
|
||||
@@ -22,14 +21,12 @@ from esphome.const import (
|
||||
CONF_PASSWORD,
|
||||
CONF_PORT,
|
||||
CONF_SKIP_CERT_CN_CHECK,
|
||||
CONF_SSL_FINGERPRINTS,
|
||||
CONF_TOPIC,
|
||||
CONF_TOPIC_PREFIX,
|
||||
CONF_USERNAME,
|
||||
)
|
||||
from esphome.core import CORE, EsphomeError
|
||||
from esphome.core import EsphomeError
|
||||
from esphome.helpers import get_int_env, get_str_env
|
||||
from esphome.log import AnsiFore, color
|
||||
from esphome.types import ConfigType
|
||||
from esphome.util import safe_print
|
||||
|
||||
@@ -102,9 +99,7 @@ def prepare(
|
||||
elif username:
|
||||
client.username_pw_set(username, password)
|
||||
|
||||
if config[CONF_MQTT].get(CONF_SSL_FINGERPRINTS) or config[CONF_MQTT].get(
|
||||
CONF_CERTIFICATE_AUTHORITY
|
||||
):
|
||||
if config[CONF_MQTT].get(CONF_CERTIFICATE_AUTHORITY):
|
||||
context = ssl.create_default_context(
|
||||
cadata=config[CONF_MQTT].get(CONF_CERTIFICATE_AUTHORITY)
|
||||
)
|
||||
@@ -283,23 +278,3 @@ def clear_topic(config, topic, username=None, password=None, client_id=None):
|
||||
client.publish(msg.topic, None, retain=True)
|
||||
|
||||
return initialize(config, [topic], on_message, None, username, password, client_id)
|
||||
|
||||
|
||||
# From marvinroger/async-mqtt-client -> scripts/get-fingerprint/get-fingerprint.py
|
||||
def get_fingerprint(config):
|
||||
addr = str(config[CONF_MQTT][CONF_BROKER]), int(config[CONF_MQTT][CONF_PORT])
|
||||
_LOGGER.info("Getting fingerprint from %s:%s", addr[0], addr[1])
|
||||
try:
|
||||
cert_pem = ssl.get_server_certificate(addr)
|
||||
except OSError as err:
|
||||
_LOGGER.error("Unable to connect to server: %s", err)
|
||||
return 1
|
||||
cert_der = ssl.PEM_cert_to_DER_cert(cert_pem)
|
||||
|
||||
sha1 = hashlib.sha1(cert_der).hexdigest()
|
||||
|
||||
safe_print(f"SHA1 Fingerprint: {color(AnsiFore.CYAN, sha1)}")
|
||||
safe_print(
|
||||
f"Copy the string above into mqtt.ssl_fingerprints section of {CORE.config_path}"
|
||||
)
|
||||
return 0
|
||||
|
||||
@@ -5,6 +5,7 @@ import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import subprocess
|
||||
import time
|
||||
from typing import Any
|
||||
|
||||
from esphome.const import CONF_COMPILE_PROCESS_LIMIT, CONF_ESPHOME, KEY_CORE
|
||||
@@ -44,31 +45,61 @@ def patch_structhash():
|
||||
|
||||
|
||||
def patch_file_downloader():
|
||||
"""Patch PlatformIO's FileDownloader to retry on PackageException errors."""
|
||||
"""Patch PlatformIO's FileDownloader to retry on PackageException errors.
|
||||
|
||||
PlatformIO's FileDownloader uses HTTPSession which lacks built-in retry
|
||||
for 502/503 errors. We add retries with exponential backoff and close the
|
||||
session between attempts to force a fresh TCP connection, which may route
|
||||
to a different CDN edge node.
|
||||
"""
|
||||
from platformio.package.download import FileDownloader
|
||||
from platformio.package.exception import PackageException
|
||||
|
||||
if getattr(FileDownloader.__init__, "_esphome_patched", False):
|
||||
return
|
||||
|
||||
original_init = FileDownloader.__init__
|
||||
|
||||
def patched_init(self, *args: Any, **kwargs: Any) -> None:
|
||||
max_retries = 3
|
||||
max_retries = 5
|
||||
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
return original_init(self, *args, **kwargs)
|
||||
original_init(self, *args, **kwargs)
|
||||
return
|
||||
except PackageException as e:
|
||||
if attempt < max_retries - 1:
|
||||
# Exponential backoff: 2, 4, 8, 16 seconds
|
||||
delay = 2 ** (attempt + 1)
|
||||
_LOGGER.warning(
|
||||
"Package download failed: %s. Retrying... (attempt %d/%d)",
|
||||
"Package download failed: %s. "
|
||||
"Retrying in %d seconds... (attempt %d/%d)",
|
||||
str(e),
|
||||
delay,
|
||||
attempt + 1,
|
||||
max_retries,
|
||||
)
|
||||
# Close the response and session to free resources
|
||||
# and force a new TCP connection on retry, which may
|
||||
# route to a different CDN edge node
|
||||
# pylint: disable=protected-access,broad-except
|
||||
try:
|
||||
if (
|
||||
hasattr(self, "_http_response")
|
||||
and self._http_response is not None
|
||||
):
|
||||
self._http_response.close()
|
||||
if hasattr(self, "_http_session"):
|
||||
self._http_session.close()
|
||||
except Exception:
|
||||
pass
|
||||
# pylint: enable=protected-access,broad-except
|
||||
time.sleep(delay)
|
||||
else:
|
||||
# Final attempt - re-raise
|
||||
raise
|
||||
return None
|
||||
|
||||
patched_init._esphome_patched = True # type: ignore[attr-defined] # pylint: disable=protected-access
|
||||
FileDownloader.__init__ = patched_init
|
||||
|
||||
|
||||
|
||||
@@ -689,6 +689,14 @@ class MessageType(TypeInfo):
|
||||
def encode_func(self) -> str:
|
||||
return "encode_message"
|
||||
|
||||
@property
|
||||
def encode_content(self) -> str:
|
||||
# Singular message fields pass force=false (skip empty messages)
|
||||
# The default for encode_nested_message is force=true (for repeated fields)
|
||||
return (
|
||||
f"buffer.{self.encode_func}({self.number}, this->{self.field_name}, false);"
|
||||
)
|
||||
|
||||
@property
|
||||
def decode_length(self) -> str:
|
||||
# Override to return None for message types because we can't use template-based
|
||||
@@ -2186,7 +2194,7 @@ def build_message_type(
|
||||
|
||||
# Only generate encode method if this message needs encoding and has fields
|
||||
if needs_encode and encode:
|
||||
o = f"void {desc.name}::encode(ProtoWriteBuffer buffer) const {{"
|
||||
o = f"void {desc.name}::encode(ProtoWriteBuffer &buffer) const {{"
|
||||
if len(encode) == 1 and len(encode[0]) + len(o) + 3 < 120:
|
||||
o += f" {encode[0]} }}\n"
|
||||
else:
|
||||
@@ -2194,7 +2202,7 @@ def build_message_type(
|
||||
o += indent("\n".join(encode)) + "\n"
|
||||
o += "}\n"
|
||||
cpp += o
|
||||
prot = "void encode(ProtoWriteBuffer buffer) const override;"
|
||||
prot = "void encode(ProtoWriteBuffer &buffer) const override;"
|
||||
public_content.append(prot)
|
||||
# If no fields to encode or message doesn't need encoding, the default implementation in ProtoMessage will be used
|
||||
|
||||
|
||||
@@ -494,6 +494,22 @@ def lint_no_byte_datatype(fname, match):
|
||||
)
|
||||
|
||||
|
||||
@lint_re_check(
|
||||
r"(?:std\s*::\s*string_view|#include\s*<string_view>)" + CPP_RE_EOL,
|
||||
include=cpp_include,
|
||||
)
|
||||
def lint_no_std_string_view(fname, match):
|
||||
return (
|
||||
f"{highlight('std::string_view')} is not allowed in ESPHome. "
|
||||
f"It pulls in significant STL template machinery that bloats flash on "
|
||||
f"resource-constrained embedded targets, does not work well with ArduinoJson, "
|
||||
f"and duplicates functionality already provided by {highlight('StringRef')}.\n"
|
||||
f"Please use {highlight('StringRef')} from {highlight('esphome/core/string_ref.h')} "
|
||||
f"for non-owning string references, or {highlight('const char *')} for simple cases.\n"
|
||||
f"(If strictly necessary, add `{highlight('// NOLINT')}` to the end of the line)"
|
||||
)
|
||||
|
||||
|
||||
@lint_post_check
|
||||
def lint_constants_usage():
|
||||
errs = []
|
||||
|
||||
@@ -15,8 +15,13 @@ esp_ldo:
|
||||
|
||||
display:
|
||||
- platform: mipi_dsi
|
||||
id: p4_nano
|
||||
model: WAVESHARE-P4-NANO-10.1
|
||||
|
||||
rotation: 90
|
||||
- platform: mipi_dsi
|
||||
id: p4_86
|
||||
model: "WAVESHARE-P4-86-PANEL"
|
||||
rotation: 180
|
||||
i2c:
|
||||
sda: GPIO7
|
||||
scl: GPIO8
|
||||
|
||||
@@ -119,9 +119,11 @@ def test_code_generation(
|
||||
|
||||
main_cpp = generate_main(component_fixture_path("mipi_dsi.yaml"))
|
||||
assert (
|
||||
"mipi_dsi_mipi_dsi_id = new mipi_dsi::MIPI_DSI(800, 1280, display::COLOR_BITNESS_565, 16);"
|
||||
"p4_nano = new mipi_dsi::MIPI_DSI(800, 1280, display::COLOR_BITNESS_565, 16);"
|
||||
in main_cpp
|
||||
)
|
||||
assert "set_init_sequence({224, 1, 0, 225, 1, 147, 226, 1," in main_cpp
|
||||
assert "mipi_dsi_mipi_dsi_id->set_lane_bit_rate(1500);" in main_cpp
|
||||
assert "p4_nano->set_lane_bit_rate(1500);" in main_cpp
|
||||
assert "p4_nano->set_rotation(display::DISPLAY_ROTATION_90_DEGREES);" in main_cpp
|
||||
assert "p4_86->set_rotation(display::DISPLAY_ROTATION_0_DEGREES);" in main_cpp
|
||||
# assert "backlight_id = new light::LightState(mipi_dsi_dsibacklight_id);" in main_cpp
|
||||
|
||||
4
tests/components/bme68x_bsec2_i2c/test.esp32-ard.yaml
Normal file
4
tests/components/bme68x_bsec2_i2c/test.esp32-ard.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
packages:
|
||||
i2c: !include ../../test_build_components/common/i2c/esp32-ard.yaml
|
||||
|
||||
<<: !include common.yaml
|
||||
@@ -35,3 +35,99 @@ button:
|
||||
data: [0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef]
|
||||
- cc1101.send_packet: !lambda |-
|
||||
return {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
|
||||
|
||||
- cc1101.set_frequency: !lambda |-
|
||||
return 433.91e6;
|
||||
- cc1101.set_frequency:
|
||||
value: "433.91MHz"
|
||||
- cc1101.set_frequency:
|
||||
value: 433911000
|
||||
- cc1101.set_frequency: 433912000
|
||||
|
||||
- cc1101.set_output_power: !lambda |-
|
||||
return -29.9;
|
||||
- cc1101.set_output_power:
|
||||
value: "-28"
|
||||
- cc1101.set_output_power:
|
||||
value: 10
|
||||
- cc1101.set_output_power: 11
|
||||
|
||||
- cc1101.set_modulation_type: !lambda |-
|
||||
return cc1101::Modulation::MODULATION_2_FSK;
|
||||
- cc1101.set_modulation_type:
|
||||
value: "4-FSK"
|
||||
- cc1101.set_modulation_type: "GFSK"
|
||||
|
||||
- cc1101.set_symbol_rate: !lambda |-
|
||||
return 6000.0;
|
||||
- cc1101.set_symbol_rate:
|
||||
value: "7000.0"
|
||||
- cc1101.set_symbol_rate:
|
||||
value: 8000.0
|
||||
- cc1101.set_symbol_rate: 9000
|
||||
|
||||
- cc1101.set_rx_attenuation: !lambda |-
|
||||
return cc1101::RxAttenuation::RX_ATTENUATION_0DB;
|
||||
- cc1101.set_rx_attenuation:
|
||||
value: "6dB"
|
||||
- cc1101.set_rx_attenuation: "12dB"
|
||||
|
||||
- cc1101.set_dc_blocking_filter: !lambda |-
|
||||
return false;
|
||||
- cc1101.set_dc_blocking_filter:
|
||||
value: true
|
||||
- cc1101.set_dc_blocking_filter: false
|
||||
|
||||
- cc1101.set_manchester: !lambda |-
|
||||
return false;
|
||||
- cc1101.set_manchester:
|
||||
value: true
|
||||
- cc1101.set_manchester: false
|
||||
|
||||
- cc1101.set_filter_bandwidth: !lambda |-
|
||||
return 58e3;
|
||||
- cc1101.set_filter_bandwidth:
|
||||
value: "59kHz"
|
||||
- cc1101.set_filter_bandwidth:
|
||||
value: 60000
|
||||
- cc1101.set_filter_bandwidth: "61kHz"
|
||||
|
||||
- cc1101.set_fsk_deviation: !lambda |-
|
||||
return 1.5e3;
|
||||
- cc1101.set_fsk_deviation:
|
||||
value: "1.6kHz"
|
||||
- cc1101.set_fsk_deviation:
|
||||
value: 1700
|
||||
- cc1101.set_fsk_deviation: "1.8kHz"
|
||||
|
||||
- cc1101.set_msk_deviation: !lambda |-
|
||||
return 1;
|
||||
- cc1101.set_msk_deviation:
|
||||
value: "2"
|
||||
- cc1101.set_msk_deviation:
|
||||
value: 3
|
||||
- cc1101.set_msk_deviation: "4"
|
||||
|
||||
- cc1101.set_channel: !lambda |-
|
||||
return 0;
|
||||
- cc1101.set_channel:
|
||||
value: "1"
|
||||
- cc1101.set_channel:
|
||||
value: 3
|
||||
- cc1101.set_channel: 3
|
||||
|
||||
- cc1101.set_channel_spacing: !lambda |-
|
||||
return 25e3;
|
||||
- cc1101.set_channel_spacing:
|
||||
value: "26kHz"
|
||||
- cc1101.set_channel_spacing:
|
||||
value: 27000
|
||||
- cc1101.set_channel_spacing: "28kHz"
|
||||
|
||||
- cc1101.set_if_frequency: !lambda |-
|
||||
return 25e3;
|
||||
- cc1101.set_if_frequency:
|
||||
value: "26kHz"
|
||||
- cc1101.set_if_frequency:
|
||||
value: 27000
|
||||
- cc1101.set_if_frequency: "28kHz"
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
esphome:
|
||||
on_boot:
|
||||
then:
|
||||
- lambda: |-
|
||||
// Test deprecated std::string overload still compiles
|
||||
std::string key = "00112233445566778899aabbccddeeff";
|
||||
id(dsmr_instance).set_decryption_key(key);
|
||||
|
||||
dsmr:
|
||||
id: dsmr_instance
|
||||
decryption_key: 00112233445566778899aabbccddeeff
|
||||
max_telegram_length: 1000
|
||||
request_pin: ${request_pin}
|
||||
|
||||
@@ -90,6 +90,19 @@ text_sensor:
|
||||
id: ha_hello_world_text2
|
||||
attribute: some_attribute
|
||||
|
||||
event:
|
||||
- platform: template
|
||||
name: Test Event
|
||||
id: test_event
|
||||
event_types:
|
||||
- test_event_type
|
||||
on_event:
|
||||
- homeassistant.event:
|
||||
event: esphome.test_event
|
||||
data:
|
||||
event_name: !lambda |-
|
||||
return event_type;
|
||||
|
||||
time:
|
||||
- platform: homeassistant
|
||||
on_time:
|
||||
|
||||
@@ -2951,6 +2951,7 @@ def test_run_miniterm_batches_lines_with_same_timestamp(
|
||||
|
||||
mock_serial = MockSerial([chunk, MOCK_SERIAL_END])
|
||||
|
||||
CORE.data[KEY_CORE] = {KEY_TARGET_PLATFORM: PLATFORM_ESP32}
|
||||
config = {
|
||||
CONF_LOGGER: {
|
||||
CONF_BAUD_RATE: 115200,
|
||||
@@ -2989,6 +2990,7 @@ def test_run_miniterm_different_chunks_different_timestamps(
|
||||
|
||||
mock_serial = MockSerial([chunk1, chunk2, MOCK_SERIAL_END])
|
||||
|
||||
CORE.data[KEY_CORE] = {KEY_TARGET_PLATFORM: PLATFORM_ESP32}
|
||||
config = {
|
||||
CONF_LOGGER: {
|
||||
CONF_BAUD_RATE: 115200,
|
||||
@@ -3019,6 +3021,7 @@ def test_run_miniterm_handles_split_lines() -> None:
|
||||
|
||||
mock_serial = MockSerial([chunk1, chunk2, MOCK_SERIAL_END])
|
||||
|
||||
CORE.data[KEY_CORE] = {KEY_TARGET_PLATFORM: PLATFORM_ESP32}
|
||||
config = {
|
||||
CONF_LOGGER: {
|
||||
CONF_BAUD_RATE: 115200,
|
||||
@@ -3057,6 +3060,7 @@ def test_run_miniterm_backtrace_state_maintained() -> None:
|
||||
|
||||
mock_serial = MockSerial([backtrace_chunk, MOCK_SERIAL_END])
|
||||
|
||||
CORE.data[KEY_CORE] = {KEY_TARGET_PLATFORM: PLATFORM_ESP32}
|
||||
config = {
|
||||
CONF_LOGGER: {
|
||||
CONF_BAUD_RATE: 115200,
|
||||
@@ -3122,6 +3126,7 @@ def test_run_miniterm_handles_empty_reads(
|
||||
|
||||
mock_serial = MockSerial([b"", chunk, b"", MOCK_SERIAL_END])
|
||||
|
||||
CORE.data[KEY_CORE] = {KEY_TARGET_PLATFORM: PLATFORM_ESP32}
|
||||
config = {
|
||||
CONF_LOGGER: {
|
||||
CONF_BAUD_RATE: 115200,
|
||||
@@ -3194,6 +3199,7 @@ def test_run_miniterm_buffer_limit_prevents_unbounded_growth() -> None:
|
||||
|
||||
mock_serial = MockSerial([large_data_no_newline, final_line, MOCK_SERIAL_END])
|
||||
|
||||
CORE.data[KEY_CORE] = {KEY_TARGET_PLATFORM: PLATFORM_ESP32}
|
||||
config = {
|
||||
CONF_LOGGER: {
|
||||
CONF_BAUD_RATE: 115200,
|
||||
|
||||
@@ -6,7 +6,7 @@ import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import MagicMock, Mock, patch
|
||||
from unittest.mock import MagicMock, Mock, call, patch
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -673,6 +673,200 @@ def test_process_stacktrace_bad_alloc(
|
||||
assert state is False
|
||||
|
||||
|
||||
def test_patch_file_downloader_succeeds_first_try() -> None:
|
||||
"""Test patch_file_downloader succeeds on first attempt."""
|
||||
mock_exception_cls = type("PackageException", (Exception,), {})
|
||||
original_init = MagicMock()
|
||||
|
||||
with patch.dict(
|
||||
"sys.modules",
|
||||
{
|
||||
"platformio": MagicMock(),
|
||||
"platformio.package": MagicMock(),
|
||||
"platformio.package.download": SimpleNamespace(
|
||||
FileDownloader=type("FileDownloader", (), {"__init__": original_init})
|
||||
),
|
||||
"platformio.package.exception": SimpleNamespace(
|
||||
PackageException=mock_exception_cls
|
||||
),
|
||||
},
|
||||
):
|
||||
platformio_api.patch_file_downloader()
|
||||
|
||||
from platformio.package.download import FileDownloader
|
||||
|
||||
instance = object.__new__(FileDownloader)
|
||||
FileDownloader.__init__(instance, "http://example.com/file.zip")
|
||||
|
||||
original_init.assert_called_once()
|
||||
|
||||
|
||||
def test_patch_file_downloader_retries_on_failure() -> None:
|
||||
"""Test patch_file_downloader retries with backoff on PackageException."""
|
||||
mock_exception_cls = type("PackageException", (Exception,), {})
|
||||
call_count = 0
|
||||
|
||||
def failing_init(self, *args, **kwargs):
|
||||
nonlocal call_count
|
||||
call_count += 1
|
||||
if call_count < 3:
|
||||
raise mock_exception_cls(f"502 error attempt {call_count}")
|
||||
|
||||
with (
|
||||
patch.dict(
|
||||
"sys.modules",
|
||||
{
|
||||
"platformio": MagicMock(),
|
||||
"platformio.package": MagicMock(),
|
||||
"platformio.package.download": SimpleNamespace(
|
||||
FileDownloader=type(
|
||||
"FileDownloader", (), {"__init__": failing_init}
|
||||
)
|
||||
),
|
||||
"platformio.package.exception": SimpleNamespace(
|
||||
PackageException=mock_exception_cls
|
||||
),
|
||||
},
|
||||
),
|
||||
patch("time.sleep") as mock_sleep,
|
||||
):
|
||||
platformio_api.patch_file_downloader()
|
||||
|
||||
from platformio.package.download import FileDownloader
|
||||
|
||||
instance = object.__new__(FileDownloader)
|
||||
FileDownloader.__init__(instance, "http://example.com/file.zip")
|
||||
|
||||
# Should have been called 3 times (2 failures + 1 success)
|
||||
assert call_count == 3
|
||||
|
||||
# Should have slept with exponential backoff: 2s, 4s
|
||||
assert mock_sleep.call_count == 2
|
||||
mock_sleep.assert_any_call(2)
|
||||
mock_sleep.assert_any_call(4)
|
||||
|
||||
|
||||
def test_patch_file_downloader_raises_after_max_retries() -> None:
|
||||
"""Test patch_file_downloader raises after exhausting all retries."""
|
||||
mock_exception_cls = type("PackageException", (Exception,), {})
|
||||
|
||||
def always_failing_init(self, *args, **kwargs):
|
||||
raise mock_exception_cls("502 error")
|
||||
|
||||
with (
|
||||
patch.dict(
|
||||
"sys.modules",
|
||||
{
|
||||
"platformio": MagicMock(),
|
||||
"platformio.package": MagicMock(),
|
||||
"platformio.package.download": SimpleNamespace(
|
||||
FileDownloader=type(
|
||||
"FileDownloader", (), {"__init__": always_failing_init}
|
||||
)
|
||||
),
|
||||
"platformio.package.exception": SimpleNamespace(
|
||||
PackageException=mock_exception_cls
|
||||
),
|
||||
},
|
||||
),
|
||||
patch("time.sleep") as mock_sleep,
|
||||
):
|
||||
platformio_api.patch_file_downloader()
|
||||
|
||||
from platformio.package.download import FileDownloader
|
||||
|
||||
instance = object.__new__(FileDownloader)
|
||||
with pytest.raises(mock_exception_cls, match="502 error"):
|
||||
FileDownloader.__init__(instance, "http://example.com/file.zip")
|
||||
|
||||
# Should have slept 4 times (before attempts 2-5), not on final attempt
|
||||
assert mock_sleep.call_count == 4
|
||||
mock_sleep.assert_has_calls([call(2), call(4), call(8), call(16)])
|
||||
|
||||
|
||||
def test_patch_file_downloader_closes_session_and_response_between_retries() -> None:
|
||||
"""Test patch_file_downloader closes HTTP session and response between retries."""
|
||||
mock_exception_cls = type("PackageException", (Exception,), {})
|
||||
mock_session = MagicMock()
|
||||
mock_response = MagicMock()
|
||||
call_count = 0
|
||||
|
||||
def failing_init_with_session(self, *args, **kwargs):
|
||||
nonlocal call_count
|
||||
call_count += 1
|
||||
self._http_session = mock_session
|
||||
self._http_response = mock_response
|
||||
if call_count < 2:
|
||||
raise mock_exception_cls("502 error")
|
||||
|
||||
with (
|
||||
patch.dict(
|
||||
"sys.modules",
|
||||
{
|
||||
"platformio": MagicMock(),
|
||||
"platformio.package": MagicMock(),
|
||||
"platformio.package.download": SimpleNamespace(
|
||||
FileDownloader=type(
|
||||
"FileDownloader",
|
||||
(),
|
||||
{"__init__": failing_init_with_session},
|
||||
)
|
||||
),
|
||||
"platformio.package.exception": SimpleNamespace(
|
||||
PackageException=mock_exception_cls
|
||||
),
|
||||
},
|
||||
),
|
||||
patch("time.sleep"),
|
||||
):
|
||||
platformio_api.patch_file_downloader()
|
||||
|
||||
from platformio.package.download import FileDownloader
|
||||
|
||||
instance = object.__new__(FileDownloader)
|
||||
FileDownloader.__init__(instance, "http://example.com/file.zip")
|
||||
|
||||
# Both response and session should have been closed between retries
|
||||
mock_response.close.assert_called_once()
|
||||
mock_session.close.assert_called_once()
|
||||
|
||||
|
||||
def test_patch_file_downloader_idempotent() -> None:
|
||||
"""Test patch_file_downloader does not stack wrappers when called multiple times."""
|
||||
mock_exception_cls = type("PackageException", (Exception,), {})
|
||||
call_count = 0
|
||||
|
||||
def counting_init(self, *args, **kwargs):
|
||||
nonlocal call_count
|
||||
call_count += 1
|
||||
|
||||
with patch.dict(
|
||||
"sys.modules",
|
||||
{
|
||||
"platformio": MagicMock(),
|
||||
"platformio.package": MagicMock(),
|
||||
"platformio.package.download": SimpleNamespace(
|
||||
FileDownloader=type("FileDownloader", (), {"__init__": counting_init})
|
||||
),
|
||||
"platformio.package.exception": SimpleNamespace(
|
||||
PackageException=mock_exception_cls
|
||||
),
|
||||
},
|
||||
):
|
||||
# Patch multiple times
|
||||
platformio_api.patch_file_downloader()
|
||||
platformio_api.patch_file_downloader()
|
||||
platformio_api.patch_file_downloader()
|
||||
|
||||
from platformio.package.download import FileDownloader
|
||||
|
||||
instance = object.__new__(FileDownloader)
|
||||
FileDownloader.__init__(instance, "http://example.com/file.zip")
|
||||
|
||||
# Should only be called once, not 3 times from stacked wrappers
|
||||
assert call_count == 1
|
||||
|
||||
|
||||
def test_platformio_log_filter_allows_non_platformio_messages() -> None:
|
||||
"""Test that non-platformio logger messages are allowed through."""
|
||||
log_filter = platformio_api.PlatformioLogFilter()
|
||||
|
||||
Reference in New Issue
Block a user