Merge branch 'dev' into light-gamma-lut

This commit is contained in:
J. Nick Koston
2026-02-23 17:05:12 -06:00
committed by GitHub
243 changed files with 3552 additions and 1423 deletions

View File

@@ -1 +1 @@
ce05c28e9dc0b12c4f6e7454986ffea5123ac974a949da841be698c535f2083e
5eb1e5852765114ad06533220d3160b6c23f5ccefc4de41828699de5dfff5ad6

View File

@@ -58,7 +58,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@9e907b5e64f6b83e7804b09294d44122997950d6 # v4.32.3
uses: github/codeql-action/init@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
@@ -86,6 +86,6 @@ jobs:
exit 1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@9e907b5e64f6b83e7804b09294d44122997950d6 # v4.32.3
uses: github/codeql-action/analyze@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
with:
category: "/language:${{matrix.language}}"

View File

@@ -11,7 +11,7 @@ ci:
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.15.1
rev: v0.15.2
hooks:
# Run the linter.
- id: ruff

View File

@@ -213,6 +213,7 @@ esphome/components/hbridge/light/* @DotNetDann
esphome/components/hbridge/switch/* @dwmw2
esphome/components/hc8/* @omartijn
esphome/components/hdc2010/* @optimusprimespace @ssieb
esphome/components/hdc302x/* @joshuasing
esphome/components/he60r/* @clydebarrow
esphome/components/heatpumpir/* @rob-deutsch
esphome/components/hitachi_ac424/* @sourabhjaiswal

View File

@@ -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(

View File

@@ -92,10 +92,7 @@ void AbsoluteHumidityComponent::loop() {
// Calculate absolute humidity
const float absolute_humidity = vapor_density(es, hr, temperature_k);
ESP_LOGD(TAG,
"Saturation vapor pressure %f kPa\n"
"Publishing absolute humidity %f g/m³",
es, absolute_humidity);
ESP_LOGD(TAG, "Saturation vapor pressure %f kPa, absolute humidity %f g/m³", es, absolute_humidity);
// Publish absolute humidity
this->status_clear_warning();

View File

@@ -67,10 +67,8 @@ void Anova::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_
case ESP_GATTC_SEARCH_CMPL_EVT: {
auto *chr = this->parent_->get_characteristic(ANOVA_SERVICE_UUID, ANOVA_CHARACTERISTIC_UUID);
if (chr == nullptr) {
ESP_LOGW(TAG,
"[%s] No control service found at device, not an Anova..?\n"
"[%s] Note, this component does not currently support Anova Nano.",
this->get_name().c_str(), this->get_name().c_str());
ESP_LOGW(TAG, "[%s] No control service found at device, not an Anova..?", this->get_name().c_str());
ESP_LOGW(TAG, "[%s] Note, this component does not currently support Anova Nano.", this->get_name().c_str());
break;
}
this->char_handle_ = chr->handle;

View File

@@ -233,8 +233,8 @@ def _consume_api_sockets(config: ConfigType) -> ConfigType:
# API needs 1 listening socket + typically 3 concurrent client connections
# (not max_connections, which is the upper limit rarely reached)
sockets_needed = 1 + 3
socket.consume_sockets(sockets_needed, "api")(config)
socket.consume_sockets(3, "api")(config)
socket.consume_sockets(1, "api", socket.SocketType.TCP_LISTEN)(config)
return config

View File

@@ -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
@@ -1353,9 +1346,8 @@ uint16_t APIConnection::try_send_water_heater_state(EntityBase *entity, APIConne
resp.target_temperature_low = wh->get_target_temperature_low();
resp.target_temperature_high = wh->get_target_temperature_high();
resp.state = wh->get_state();
resp.key = wh->get_object_id_hash();
return encode_message_to_buffer(resp, WaterHeaterStateResponse::MESSAGE_TYPE, conn, remaining_size);
return fill_and_encode_entity_state(wh, resp, WaterHeaterStateResponse::MESSAGE_TYPE, conn, remaining_size);
}
uint16_t APIConnection::try_send_water_heater_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size) {
auto *wh = static_cast<water_heater::WaterHeater *>(entity);
@@ -1534,6 +1526,12 @@ bool APIConnection::send_hello_response_(const HelloRequest &msg) {
ESP_LOGV(TAG, "Hello from client: '%s' | %s | API Version %" PRIu16 ".%" PRIu16, this->helper_->get_client_name(),
this->helper_->get_peername_to(peername), this->client_api_version_major_, this->client_api_version_minor_);
// TODO: Remove before 2026.8.0 (one version after get_object_id backward compat removal)
if (!this->client_supports_api_version(1, 14)) {
ESP_LOGW(TAG, "'%s' using outdated API %" PRIu16 ".%" PRIu16 ", update to 1.14+", this->helper_->get_client_name(),
this->client_api_version_major_, this->client_api_version_minor_);
}
HelloResponse resp;
resp.api_version_major = 1;
resp.api_version_minor = 14;
@@ -1848,12 +1846,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);

View File

@@ -19,7 +19,7 @@ namespace esphome::api {
static const char *const TAG = "api.noise";
#ifdef USE_ESP8266
static const char PROLOGUE_INIT[] PROGMEM = "NoiseAPIInit";
static constexpr char PROLOGUE_INIT[] PROGMEM = "NoiseAPIInit";
#else
static const char *const PROLOGUE_INIT = "NoiseAPIInit";
#endif

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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...>() {}

View File

@@ -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;

View File

@@ -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
}

View File

@@ -307,9 +307,9 @@ void AS3935Component::tune_antenna() {
uint8_t tune_val = this->read_capacitance();
ESP_LOGI(TAG,
"Starting antenna tuning\n"
"Division Ratio is set to: %d\n"
"Internal Capacitor is set to: %d\n"
"Displaying oscillator on INT pin. Measure its frequency - multiply value by Division Ratio",
" Division Ratio is set to: %d\n"
" Internal Capacitor is set to: %d\n"
" Displaying oscillator on INT pin. Measure its frequency - multiply value by Division Ratio",
div_ratio, tune_val);
this->display_oscillator(true, ANTFREQ);
}

View File

@@ -77,14 +77,14 @@ void AT581XComponent::dump_config() { LOG_I2C_DEVICE(this); }
bool AT581XComponent::i2c_write_config() {
ESP_LOGCONFIG(TAG,
"Writing new config for AT581X\n"
"Frequency: %dMHz\n"
"Sensing distance: %d\n"
"Power: %dµA\n"
"Gain: %d\n"
"Trigger base time: %dms\n"
"Trigger keep time: %dms\n"
"Protect time: %dms\n"
"Self check time: %dms",
" Frequency: %dMHz\n"
" Sensing distance: %d\n"
" Power: %dµA\n"
" Gain: %d\n"
" Trigger base time: %dms\n"
" Trigger keep time: %dms\n"
" Protect time: %dms\n"
" Self check time: %dms",
this->freq_, this->delta_, this->power_, this->gain_, this->trigger_base_time_ms_,
this->trigger_keep_time_ms_, this->protect_time_ms_, this->self_check_time_ms_);

View File

@@ -562,6 +562,7 @@ async def setup_binary_sensor_core_(var, config):
if inverted := config.get(CONF_INVERTED):
cg.add(var.set_inverted(inverted))
if filters_config := config.get(CONF_FILTERS):
cg.add_define("USE_BINARY_SENSOR_FILTER")
filters = await cg.build_registry_list(FILTER_REGISTRY, filters_config)
cg.add(var.add_filters(filters))

View File

@@ -29,10 +29,8 @@ void MultiClickTrigger::on_state_(bool state) {
// Start matching
MultiClickTriggerEvent evt = this->timing_[0];
if (evt.state == state) {
ESP_LOGV(TAG,
"START min=%" PRIu32 " max=%" PRIu32 "\n"
"Multi Click: Starting multi click action!",
evt.min_length, evt.max_length);
ESP_LOGV(TAG, "START min=%" PRIu32 " max=%" PRIu32, evt.min_length, evt.max_length);
ESP_LOGV(TAG, "Multi Click: Starting multi click action!");
this->at_index_ = 1;
if (this->timing_.size() == 1 && evt.max_length == 4294967294UL) {
this->set_timeout(MULTICLICK_TRIGGER_ID, evt.min_length, [this]() { this->trigger_(); });

View File

@@ -18,11 +18,15 @@ void log_binary_sensor(const char *tag, const char *prefix, const char *type, Bi
}
void BinarySensor::publish_state(bool new_state) {
#ifdef USE_BINARY_SENSOR_FILTER
if (this->filter_list_ == nullptr) {
#endif
this->send_state_internal(new_state);
#ifdef USE_BINARY_SENSOR_FILTER
} else {
this->filter_list_->input(new_state);
}
#endif
}
void BinarySensor::publish_initial_state(bool new_state) {
this->invalidate_state();
@@ -47,6 +51,7 @@ bool BinarySensor::set_new_state(const optional<bool> &new_state) {
return false;
}
#ifdef USE_BINARY_SENSOR_FILTER
void BinarySensor::add_filter(Filter *filter) {
filter->parent_ = this;
if (this->filter_list_ == nullptr) {
@@ -63,6 +68,7 @@ void BinarySensor::add_filters(std::initializer_list<Filter *> filters) {
this->add_filter(filter);
}
}
#endif // USE_BINARY_SENSOR_FILTER
bool BinarySensor::is_status_binary_sensor() const { return false; }
} // namespace esphome::binary_sensor

View File

@@ -2,7 +2,9 @@
#include "esphome/core/entity_base.h"
#include "esphome/core/helpers.h"
#ifdef USE_BINARY_SENSOR_FILTER
#include "esphome/components/binary_sensor/filter.h"
#endif
#include <initializer_list>
@@ -45,8 +47,10 @@ class BinarySensor : public StatefulEntityBase<bool>, public EntityBase_DeviceCl
*/
void publish_initial_state(bool new_state);
#ifdef USE_BINARY_SENSOR_FILTER
void add_filter(Filter *filter);
void add_filters(std::initializer_list<Filter *> filters);
#endif
// ========== INTERNAL METHODS ==========
// (In most use cases you won't need these)
@@ -60,7 +64,9 @@ class BinarySensor : public StatefulEntityBase<bool>, public EntityBase_DeviceCl
bool state{};
protected:
#ifdef USE_BINARY_SENSOR_FILTER
Filter *filter_list_{nullptr};
#endif
bool set_new_state(const optional<bool> &new_state) override;
};

View File

@@ -1,3 +1,6 @@
#include "esphome/core/defines.h"
#ifdef USE_BINARY_SENSOR_FILTER
#include "filter.h"
#include "binary_sensor.h"
@@ -142,3 +145,5 @@ optional<bool> SettleFilter::new_value(bool value) {
float SettleFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
} // namespace esphome::binary_sensor
#endif // USE_BINARY_SENSOR_FILTER

View File

@@ -1,5 +1,8 @@
#pragma once
#include "esphome/core/defines.h"
#ifdef USE_BINARY_SENSOR_FILTER
#include "esphome/core/automation.h"
#include "esphome/core/component.h"
#include "esphome/core/helpers.h"
@@ -138,3 +141,5 @@ class SettleFilter : public Filter, public Component {
};
} // namespace esphome::binary_sensor
#endif // USE_BINARY_SENSOR_FILTER

View File

@@ -182,7 +182,10 @@ void BL0940::recalibrate_() {
ESP_LOGD(TAG,
"Recalibrated reference values:\n"
"Voltage: %f\n, Current: %f\n, Power: %f\n, Energy: %f\n",
" Voltage: %f\n"
" Current: %f\n"
" Power: %f\n"
" Energy: %f",
this->voltage_reference_cal_, this->current_reference_cal_, this->power_reference_cal_,
this->energy_reference_cal_);
}

View File

@@ -22,11 +22,11 @@ static const uint8_t BME680_REGISTER_CHIPID = 0xD0;
static const uint8_t BME680_REGISTER_FIELD0 = 0x1D;
const float BME680_GAS_LOOKUP_TABLE_1[16] PROGMEM = {0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -0.8,
0.0, 0.0, -0.2, -0.5, 0.0, -1.0, 0.0, 0.0};
constexpr float BME680_GAS_LOOKUP_TABLE_1[16] PROGMEM = {0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -0.8,
0.0, 0.0, -0.2, -0.5, 0.0, -1.0, 0.0, 0.0};
const float BME680_GAS_LOOKUP_TABLE_2[16] PROGMEM = {0.0, 0.0, 0.0, 0.0, 0.1, 0.7, 0.0, -0.8,
-0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
constexpr float BME680_GAS_LOOKUP_TABLE_2[16] PROGMEM = {0.0, 0.0, 0.0, 0.0, 0.1, 0.7, 0.0, -0.8,
-0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
[[maybe_unused]] static const char *oversampling_to_str(BME680Oversampling oversampling) {
switch (oversampling) {

View File

@@ -7,6 +7,7 @@
#include "esphome/core/preferences.h"
#include "esphome/core/defines.h"
#include <map>
#include <queue>
#ifdef USE_BSEC
#include <bsec.h>

View File

@@ -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",

View File

@@ -76,13 +76,15 @@ def _final_validate(config: ConfigType) -> ConfigType:
# Register socket needs for DNS server and additional HTTP connections
# - 1 UDP socket for DNS server
# - 3 additional TCP sockets for captive portal detection probes + configuration requests
# - 3 TCP sockets for captive portal detection probes + configuration requests
# OS captive portal detection makes multiple probe requests that stay in TIME_WAIT.
# Need headroom for actual user configuration requests.
# LRU purging will reclaim idle sockets to prevent exhaustion from repeated attempts.
# The listening socket is registered by web_server_base (shared HTTP server).
from esphome.components import socket
socket.consume_sockets(4, "captive_portal")(config)
socket.consume_sockets(3, "captive_portal")(config)
socket.consume_sockets(1, "captive_portal", socket.SocketType.UDP)(config)
return config

View File

@@ -6,7 +6,7 @@
namespace esphome::captive_portal {
#ifdef USE_CAPTIVE_PORTAL_GZIP
const uint8_t INDEX_GZ[] PROGMEM = {
constexpr uint8_t INDEX_GZ[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x95, 0x16, 0x6b, 0x8f, 0xdb, 0x36, 0xf2, 0x7b, 0x7e,
0x05, 0x8f, 0x49, 0xbb, 0x52, 0xb3, 0x7a, 0x7a, 0xed, 0x6c, 0x24, 0x51, 0x45, 0x9a, 0xbb, 0xa2, 0x05, 0x9a, 0x36,
0xc0, 0x6e, 0x73, 0x1f, 0x82, 0x00, 0x4b, 0x53, 0x23, 0x8b, 0x31, 0x45, 0xea, 0x48, 0xca, 0x8f, 0x18, 0xbe, 0xdf,
@@ -86,7 +86,7 @@ const uint8_t INDEX_GZ[] PROGMEM = {
0xfc, 0xda, 0xd1, 0xf8, 0xe9, 0xa3, 0xe1, 0xa6, 0xfb, 0x1f, 0x53, 0x58, 0x46, 0xb2, 0xf9, 0x0a, 0x00, 0x00};
#else // Brotli (default, smaller)
const uint8_t INDEX_BR[] PROGMEM = {
constexpr uint8_t INDEX_BR[] PROGMEM = {
0x1b, 0xf8, 0x0a, 0x00, 0x64, 0x5a, 0xd3, 0xfa, 0xe7, 0xf3, 0x62, 0xd8, 0x06, 0x1b, 0xe9, 0x6a, 0x8a, 0x81, 0x2b,
0xb5, 0x49, 0x14, 0x37, 0xdc, 0x9e, 0x1a, 0xcb, 0x56, 0x87, 0xfb, 0xff, 0xf7, 0x73, 0x75, 0x12, 0x0a, 0xd6, 0x48,
0x84, 0xc6, 0x21, 0xa4, 0x6d, 0xb5, 0x71, 0xef, 0x13, 0xbe, 0x4e, 0x54, 0xf1, 0x64, 0x8f, 0x3f, 0xcc, 0x9a, 0x78,

View File

@@ -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");
}

View File

@@ -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];
};

View File

@@ -9,6 +9,8 @@ from esphome.const import (
CONF_DATA,
CONF_FREQUENCY,
CONF_ID,
CONF_OUTPUT_POWER,
CONF_VALUE,
CONF_WAIT_TIME,
)
from esphome.core import ID
@@ -21,7 +23,6 @@ ns = cg.esphome_ns.namespace("cc1101")
CC1101Component = ns.class_("CC1101Component", cg.Component, spi.SPIDevice)
# Config keys
CONF_OUTPUT_POWER = "output_power"
CONF_RX_ATTENUATION = "rx_attenuation"
CONF_DC_BLOCKING_FILTER = "dc_blocking_filter"
CONF_IF_FREQUENCY = "if_frequency"
@@ -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()

View File

@@ -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

View File

@@ -124,9 +124,11 @@ bool CH422GComponent::write_outputs_() {
float CH422GComponent::get_setup_priority() const { return setup_priority::IO; }
#ifdef USE_LOOP_PRIORITY
// Run our loop() method very early in the loop, so that we cache read values
// before other components call our digital_read() method.
float CH422GComponent::get_loop_priority() const { return 9.0f; } // Just after WIFI
#endif
void CH422GGPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
bool CH422GGPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) ^ this->inverted_; }

View File

@@ -23,7 +23,9 @@ class CH422GComponent : public Component, public i2c::I2CDevice {
void pin_mode(uint8_t pin, gpio::Flags flags);
float get_setup_priority() const override;
#ifdef USE_LOOP_PRIORITY
float get_loop_priority() const override;
#endif
void dump_config() override;
protected:

View File

@@ -129,9 +129,11 @@ bool CH423Component::write_outputs_() {
float CH423Component::get_setup_priority() const { return setup_priority::IO; }
#ifdef USE_LOOP_PRIORITY
// Run our loop() method very early in the loop, so that we cache read values
// before other components call our digital_read() method.
float CH423Component::get_loop_priority() const { return 9.0f; } // Just after WIFI
#endif
void CH423GPIOPin::pin_mode(gpio::Flags flags) { this->parent_->pin_mode(this->pin_, flags); }
bool CH423GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) ^ this->inverted_; }

View File

@@ -22,7 +22,9 @@ class CH423Component : public Component, public i2c::I2CDevice {
void pin_mode(uint8_t pin, gpio::Flags flags);
float get_setup_priority() const override;
#ifdef USE_LOOP_PRIORITY
float get_loop_priority() const override;
#endif
void dump_config() override;
protected:

View File

@@ -148,14 +148,14 @@ void CurrentBasedCover::dump_config() {
}
ESP_LOGCONFIG(TAG,
" Close Duration: %.1fs\n"
"Obstacle Rollback: %.1f%%",
" Obstacle Rollback: %.1f%%",
this->close_duration_ / 1e3f, this->obstacle_rollback_ * 100);
if (this->max_duration_ != UINT32_MAX) {
ESP_LOGCONFIG(TAG, "Maximum duration: %.1fs", this->max_duration_ / 1e3f);
ESP_LOGCONFIG(TAG, " Maximum duration: %.1fs", this->max_duration_ / 1e3f);
}
ESP_LOGCONFIG(TAG,
"Start sensing delay: %.1fs\n"
"Malfunction detection: %s",
" Start sensing delay: %.1fs\n"
" Malfunction detection: %s",
this->start_sensing_delay_ / 1e3f, YESNO(this->malfunction_detection_));
}

View File

@@ -79,7 +79,6 @@ const char *DebugComponent::get_reset_reason_(std::span<char, RESET_REASON_BUFFE
} else {
snprintf(buf, size, "unknown source");
}
ESP_LOGD(TAG, "Reset Reason: %s", buf);
return buf;
}
@@ -107,7 +106,6 @@ const char *DebugComponent::get_wakeup_cause_(std::span<char, RESET_REASON_BUFFE
} else {
wake_reason = "unknown source";
}
ESP_LOGD(TAG, "Wakeup Reason: %s", wake_reason);
// Return the static string directly - no need to copy to buffer
return wake_reason;
}
@@ -172,7 +170,6 @@ size_t DebugComponent::get_device_info_(std::span<char, DEVICE_INFO_BUFFER_SIZE>
}
uint32_t flash_size = ESP.getFlashChipSize() / 1024; // NOLINT
uint32_t flash_speed = ESP.getFlashChipSpeed() / 1000000; // NOLINT
ESP_LOGD(TAG, "Flash Chip: Size=%" PRIu32 "kB Speed=%" PRIu32 "MHz Mode=%s", flash_size, flash_speed, flash_mode);
pos = buf_append_printf(buf, size, pos, "|Flash: %" PRIu32 "kB Speed:%" PRIu32 "MHz Mode:%s", flash_size, flash_speed,
flash_mode);
#endif
@@ -194,39 +191,46 @@ size_t DebugComponent::get_device_info_(std::span<char, DEVICE_INFO_BUFFER_SIZE>
if (info.features != 0) {
pos = buf_append_printf(buf, size, pos, "%sOther:0x%" PRIx32, first_feature ? "" : ", ", info.features);
}
ESP_LOGD(TAG, "Chip: Model=%s, Cores=%u, Revision=%u", model, info.cores, info.revision);
pos = buf_append_printf(buf, size, pos, " Cores:%u Revision:%u", info.cores, info.revision);
uint32_t cpu_freq_mhz = arch_get_cpu_freq_hz() / 1000000;
ESP_LOGD(TAG, "CPU Frequency: %" PRIu32 " MHz", cpu_freq_mhz);
pos = buf_append_printf(buf, size, pos, "|CPU Frequency: %" PRIu32 " MHz", cpu_freq_mhz);
// Framework detection
#ifdef USE_ARDUINO
ESP_LOGD(TAG, "Framework: Arduino");
pos = buf_append_printf(buf, size, pos, "|Framework: Arduino");
#elif defined(USE_ESP32)
ESP_LOGD(TAG, "Framework: ESP-IDF");
pos = buf_append_printf(buf, size, pos, "|Framework: ESP-IDF");
#else
ESP_LOGW(TAG, "Framework: UNKNOWN");
pos = buf_append_printf(buf, size, pos, "|Framework: UNKNOWN");
#endif
ESP_LOGD(TAG, "ESP-IDF Version: %s", esp_get_idf_version());
pos = buf_append_printf(buf, size, pos, "|ESP-IDF: %s", esp_get_idf_version());
uint8_t mac[6];
get_mac_address_raw(mac);
ESP_LOGD(TAG, "EFuse MAC: %02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
pos = buf_append_printf(buf, size, pos, "|EFuse MAC: %02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3],
mac[4], mac[5]);
char reason_buffer[RESET_REASON_BUFFER_SIZE];
const char *reset_reason = get_reset_reason_(std::span<char, RESET_REASON_BUFFER_SIZE>(reason_buffer));
pos = buf_append_printf(buf, size, pos, "|Reset: %s", reset_reason);
const char *wakeup_cause = get_wakeup_cause_(std::span<char, RESET_REASON_BUFFER_SIZE>(reason_buffer));
uint8_t mac[6];
get_mac_address_raw(mac);
ESP_LOGD(TAG,
"ESP32 debug info:\n"
" Chip: %s\n"
" Cores: %u\n"
" Revision: %u\n"
" CPU Frequency: %" PRIu32 " MHz\n"
" ESP-IDF Version: %s\n"
" EFuse MAC: %02X:%02X:%02X:%02X:%02X:%02X\n"
" Reset Reason: %s\n"
" Wakeup Cause: %s",
model, info.cores, info.revision, cpu_freq_mhz, esp_get_idf_version(), mac[0], mac[1], mac[2], mac[3],
mac[4], mac[5], reset_reason, wakeup_cause);
#if defined(USE_ARDUINO)
ESP_LOGD(TAG, " Flash: Size=%" PRIu32 "kB Speed=%" PRIu32 "MHz Mode=%s", flash_size, flash_speed, flash_mode);
#endif
// Framework detection
#ifdef USE_ARDUINO
ESP_LOGD(TAG, " Framework: Arduino");
pos = buf_append_printf(buf, size, pos, "|Framework: Arduino");
#else
ESP_LOGD(TAG, " Framework: ESP-IDF");
pos = buf_append_printf(buf, size, pos, "|Framework: ESP-IDF");
#endif
pos = buf_append_printf(buf, size, pos, "|ESP-IDF: %s", esp_get_idf_version());
pos = buf_append_printf(buf, size, pos, "|EFuse MAC: %02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3],
mac[4], mac[5]);
pos = buf_append_printf(buf, size, pos, "|Reset: %s", reset_reason);
pos = buf_append_printf(buf, size, pos, "|Wakeup: %s", wakeup_cause);
return pos;

View File

@@ -128,14 +128,16 @@ size_t DebugComponent::get_device_info_(std::span<char, DEVICE_INFO_BUFFER_SIZE>
// NOLINTEND(readability-static-accessed-through-instance)
ESP_LOGD(TAG,
"Chip ID: 0x%08" PRIX32 "\n"
"SDK Version: %s\n"
"Core Version: %s\n"
"Boot Version=%u Mode=%u\n"
"CPU Frequency: %u\n"
"Flash Chip ID=0x%08" PRIX32 "\n"
"Reset Reason: %s\n"
"Reset Info: %s",
"ESP8266 debug info:\n"
" Chip ID: 0x%08" PRIX32 "\n"
" SDK Version: %s\n"
" Core Version: %s\n"
" Boot Version: %u\n"
" Boot Mode: %u\n"
" CPU Frequency: %u\n"
" Flash Chip ID: 0x%08" PRIX32 "\n"
" Reset Reason: %s\n"
" Reset Info: %s",
chip_id, sdk_version, get_core_version_str(core_version_buffer), boot_version, boot_mode, cpu_freq,
flash_chip_id, reset_reason, get_reset_info_str(reset_info_buffer, resetInfo.reason));

View File

@@ -27,12 +27,14 @@ size_t DebugComponent::get_device_info_(std::span<char, DEVICE_INFO_BUFFER_SIZE>
uint32_t mac_id = lt_cpu_get_mac_id();
ESP_LOGD(TAG,
"LibreTiny Version: %s\n"
"Chip: %s (%04x) @ %u MHz\n"
"Chip ID: 0x%06" PRIX32 "\n"
"Board: %s\n"
"Flash: %" PRIu32 " KiB / RAM: %" PRIu32 " KiB\n"
"Reset Reason: %s",
"LibreTiny debug info:\n"
" Version: %s\n"
" Chip: %s (%04x) @ %u MHz\n"
" Chip ID: 0x%06" PRIX32 "\n"
" Board: %s\n"
" Flash: %" PRIu32 " KiB\n"
" RAM: %" PRIu32 " KiB\n"
" Reset Reason: %s",
lt_get_version(), lt_cpu_get_model_name(), lt_cpu_get_model(), lt_cpu_get_freq_mhz(), mac_id,
lt_get_board_code(), flash_kib, ram_kib, reset_reason);

View File

@@ -2,6 +2,7 @@
#ifdef USE_ZEPHYR
#include <climits>
#include "esphome/core/log.h"
#include <esphome/components/zephyr/reset_reason.h>
#include <zephyr/drivers/hwinfo.h>
#include <hal/nrf_power.h>
#include <cstdint>
@@ -15,16 +16,6 @@ static const char *const TAG = "debug";
constexpr std::uintptr_t MBR_PARAM_PAGE_ADDR = 0xFFC;
constexpr std::uintptr_t MBR_BOOTLOADER_ADDR = 0xFF8;
static size_t append_reset_reason(char *buf, size_t size, size_t pos, bool set, const char *reason) {
if (!set) {
return pos;
}
if (pos > 0) {
pos = buf_append_printf(buf, size, pos, ", ");
}
return buf_append_printf(buf, size, pos, "%s", reason);
}
static inline uint32_t read_mem_u32(uintptr_t addr) {
return *reinterpret_cast<volatile uint32_t *>(addr); // NOLINT(performance-no-int-to-ptr)
}
@@ -57,39 +48,7 @@ static inline uint32_t sd_version_get() {
}
const char *DebugComponent::get_reset_reason_(std::span<char, RESET_REASON_BUFFER_SIZE> buffer) {
char *buf = buffer.data();
const size_t size = RESET_REASON_BUFFER_SIZE;
uint32_t cause;
auto ret = hwinfo_get_reset_cause(&cause);
if (ret) {
ESP_LOGE(TAG, "Unable to get reset cause: %d", ret);
buf[0] = '\0';
return buf;
}
size_t pos = 0;
pos = append_reset_reason(buf, size, pos, cause & RESET_PIN, "External pin");
pos = append_reset_reason(buf, size, pos, cause & RESET_SOFTWARE, "Software reset");
pos = append_reset_reason(buf, size, pos, cause & RESET_BROWNOUT, "Brownout (drop in voltage)");
pos = append_reset_reason(buf, size, pos, cause & RESET_POR, "Power-on reset (POR)");
pos = append_reset_reason(buf, size, pos, cause & RESET_WATCHDOG, "Watchdog timer expiration");
pos = append_reset_reason(buf, size, pos, cause & RESET_DEBUG, "Debug event");
pos = append_reset_reason(buf, size, pos, cause & RESET_SECURITY, "Security violation");
pos = append_reset_reason(buf, size, pos, cause & RESET_LOW_POWER_WAKE, "Waking up from low power mode");
pos = append_reset_reason(buf, size, pos, cause & RESET_CPU_LOCKUP, "CPU lock-up detected");
pos = append_reset_reason(buf, size, pos, cause & RESET_PARITY, "Parity error");
pos = append_reset_reason(buf, size, pos, cause & RESET_PLL, "PLL error");
pos = append_reset_reason(buf, size, pos, cause & RESET_CLOCK, "Clock error");
pos = append_reset_reason(buf, size, pos, cause & RESET_HARDWARE, "Hardware reset");
pos = append_reset_reason(buf, size, pos, cause & RESET_USER, "User reset");
pos = append_reset_reason(buf, size, pos, cause & RESET_TEMPERATURE, "Temperature reset");
// Ensure null termination if nothing was written
if (pos == 0) {
buf[0] = '\0';
}
const char *buf = zephyr::get_reset_reason(buffer);
ESP_LOGD(TAG, "Reset Reason: %s", buf);
return buf;
}
@@ -120,13 +79,13 @@ static void fa_cb(const struct flash_area *fa, void *user_data) {
void DebugComponent::log_partition_info_() {
#if CONFIG_FLASH_MAP_LABELS
ESP_LOGCONFIG(TAG, "ID | Device | Device Name "
"| Label | Offset | Size\n"
"--------------------------------------------"
"| Label | Offset | Size");
ESP_LOGCONFIG(TAG, "--------------------------------------------"
"-----------------------------------------------");
#else
ESP_LOGCONFIG(TAG, "ID | Device | Device Name "
"| Offset | Size\n"
"-----------------------------------------"
"| Offset | Size");
ESP_LOGCONFIG(TAG, "-----------------------------------------"
"------------------------------");
#endif
flash_area_foreach(fa_cb, nullptr);
@@ -325,11 +284,12 @@ size_t DebugComponent::get_device_info_(std::span<char, DEVICE_INFO_BUFFER_SIZE>
char mac_pretty[MAC_ADDRESS_PRETTY_BUFFER_SIZE];
get_mac_address_pretty_into_buffer(mac_pretty);
ESP_LOGD(TAG,
"Code page size: %u, code size: %u, device id: 0x%08x%08x\n"
"Encryption root: 0x%08x%08x%08x%08x, Identity Root: 0x%08x%08x%08x%08x\n"
"Device address type: %s, address: %s\n"
"Part code: nRF%x, version: %c%c%c%c, package: %s\n"
"RAM: %ukB, Flash: %ukB, production test: %sdone",
"nRF debug info:\n"
" Code page size: %u, code size: %u, device id: 0x%08x%08x\n"
" Encryption root: 0x%08x%08x%08x%08x, Identity Root: 0x%08x%08x%08x%08x\n"
" Device address type: %s, address: %s\n"
" Part code: nRF%x, version: %c%c%c%c, package: %s\n"
" RAM: %ukB, Flash: %ukB, production test: %sdone",
NRF_FICR->CODEPAGESIZE, NRF_FICR->CODESIZE, NRF_FICR->DEVICEID[1], NRF_FICR->DEVICEID[0], NRF_FICR->ER[0],
NRF_FICR->ER[1], NRF_FICR->ER[2], NRF_FICR->ER[3], NRF_FICR->IR[0], NRF_FICR->IR[1], NRF_FICR->IR[2],
NRF_FICR->IR[3], (NRF_FICR->DEVICEADDRTYPE & 0x1 ? "Random" : "Public"), mac_pretty, NRF_FICR->INFO.PART,
@@ -340,23 +300,22 @@ size_t DebugComponent::get_device_info_(std::span<char, DEVICE_INFO_BUFFER_SIZE>
(NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) == UICR_PSELRESET_CONNECT_Connected
<< UICR_PSELRESET_CONNECT_Pos;
ESP_LOGD(
TAG, "GPIO as NFC pins: %s, GPIO as nRESET pin: %s",
TAG, " GPIO as NFC pins: %s, GPIO as nRESET pin: %s",
YESNO((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)),
YESNO(n_reset_enabled));
if (n_reset_enabled) {
uint8_t port = (NRF_UICR->PSELRESET[0] & UICR_PSELRESET_PORT_Msk) >> UICR_PSELRESET_PORT_Pos;
uint8_t pin = (NRF_UICR->PSELRESET[0] & UICR_PSELRESET_PIN_Msk) >> UICR_PSELRESET_PIN_Pos;
ESP_LOGD(TAG, "nRESET port P%u.%02u", port, pin);
ESP_LOGD(TAG, " nRESET port P%u.%02u", port, pin);
}
#ifdef USE_BOOTLOADER_MCUBOOT
ESP_LOGD(TAG, "bootloader: mcuboot");
ESP_LOGD(TAG, " Bootloader: mcuboot");
#else
ESP_LOGD(TAG, "bootloader: Adafruit, version %u.%u.%u", (BOOTLOADER_VERSION_REGISTER >> 16) & 0xFF,
ESP_LOGD(TAG, " Bootloader: Adafruit, version %u.%u.%u", (BOOTLOADER_VERSION_REGISTER >> 16) & 0xFF,
(BOOTLOADER_VERSION_REGISTER >> 8) & 0xFF, BOOTLOADER_VERSION_REGISTER & 0xFF);
ESP_LOGD(TAG,
"MBR bootloader addr 0x%08x, UICR bootloader addr 0x%08x\n"
"MBR param page addr 0x%08x, UICR param page addr 0x%08x",
read_mem_u32(MBR_BOOTLOADER_ADDR), NRF_UICR->NRFFW[0], read_mem_u32(MBR_PARAM_PAGE_ADDR),
ESP_LOGD(TAG, " MBR bootloader addr 0x%08x, UICR bootloader addr 0x%08x", read_mem_u32(MBR_BOOTLOADER_ADDR),
NRF_UICR->NRFFW[0]);
ESP_LOGD(TAG, " MBR param page addr 0x%08x, UICR param page addr 0x%08x", read_mem_u32(MBR_PARAM_PAGE_ADDR),
NRF_UICR->NRFFW[1]);
if (is_sd_present()) {
uint32_t const sd_id = sd_id_get();
@@ -367,7 +326,7 @@ size_t DebugComponent::get_device_info_(std::span<char, DEVICE_INFO_BUFFER_SIZE>
ver[1] = (sd_version - ver[0] * 1000000) / 1000;
ver[2] = (sd_version - ver[0] * 1000000 - ver[1] * 1000);
ESP_LOGD(TAG, "SoftDevice: S%u %u.%u.%u", sd_id, ver[0], ver[1], ver[2]);
ESP_LOGD(TAG, " SoftDevice: S%u %u.%u.%u", sd_id, ver[0], ver[1], ver[2]);
#ifdef USE_SOFTDEVICE_ID
#ifdef USE_SOFTDEVICE_VERSION
if (USE_SOFTDEVICE_ID != sd_id || USE_SOFTDEVICE_VERSION != ver[0]) {
@@ -393,10 +352,8 @@ size_t DebugComponent::get_device_info_(std::span<char, DEVICE_INFO_BUFFER_SIZE>
}
return res;
};
ESP_LOGD(TAG,
"NRFFW %s\n"
"NRFHW %s",
uicr(NRF_UICR->NRFFW, 13).c_str(), uicr(NRF_UICR->NRFHW, 12).c_str());
ESP_LOGD(TAG, " NRFFW %s", uicr(NRF_UICR->NRFFW, 13).c_str());
ESP_LOGD(TAG, " NRFHW %s", uicr(NRF_UICR->NRFHW, 12).c_str());
return pos;
}

View File

@@ -40,9 +40,11 @@ void DeepSleepComponent::loop() {
this->begin_sleep();
}
#ifdef USE_LOOP_PRIORITY
float DeepSleepComponent::get_loop_priority() const {
return -100.0f; // run after everything else is ready
}
#endif
void DeepSleepComponent::set_sleep_duration(uint32_t time_ms) { this->sleep_duration_ = uint64_t(time_ms) * 1000; }

View File

@@ -113,7 +113,9 @@ class DeepSleepComponent : public Component {
void setup() override;
void dump_config() override;
void loop() override;
#ifdef USE_LOOP_PRIORITY
float get_loop_priority() const override;
#endif
float get_setup_priority() const override;
/// Helper to enter deep sleep mode

View File

@@ -187,18 +187,18 @@ uint8_t DetRangeCfgCommand::on_message(std::string &message) {
} else if (message == "Done") {
ESP_LOGI(TAG,
"Updated detection area config:\n"
"Detection area 1 from %.02fm to %.02fm.",
" Detection area 1 from %.02fm to %.02fm.",
this->min1_, this->max1_);
if (this->min2_ >= 0 && this->max2_ >= 0) {
ESP_LOGI(TAG, "Detection area 2 from %.02fm to %.02fm.", this->min2_, this->max2_);
ESP_LOGI(TAG, " Detection area 2 from %.02fm to %.02fm.", this->min2_, this->max2_);
}
if (this->min3_ >= 0 && this->max3_ >= 0) {
ESP_LOGI(TAG, "Detection area 3 from %.02fm to %.02fm.", this->min3_, this->max3_);
ESP_LOGI(TAG, " Detection area 3 from %.02fm to %.02fm.", this->min3_, this->max3_);
}
if (this->min4_ >= 0 && this->max4_ >= 0) {
ESP_LOGI(TAG, "Detection area 4 from %.02fm to %.02fm.", this->min4_, this->max4_);
ESP_LOGI(TAG, " Detection area 4 from %.02fm to %.02fm.", this->min4_, this->max4_);
}
ESP_LOGD(TAG, "Used command: %s", this->cmd_.c_str());
ESP_LOGD(TAG, " Used command: %s", this->cmd_.c_str());
return 1; // Command done
}
return 0; // Command not done yet.
@@ -222,10 +222,10 @@ uint8_t SetLatencyCommand::on_message(std::string &message) {
} else if (message == "Done") {
ESP_LOGI(TAG,
"Updated output latency config:\n"
"Signal that someone was detected is delayed by %.03f s.\n"
"Signal that nobody is detected anymore is delayed by %.03f s.",
" Signal that someone was detected is delayed by %.03f s.\n"
" Signal that nobody is detected anymore is delayed by %.03f s.",
this->delay_after_detection_, this->delay_after_disappear_);
ESP_LOGD(TAG, "Used command: %s", this->cmd_.c_str());
ESP_LOGD(TAG, " Used command: %s", this->cmd_.c_str());
return 1; // Command done
}
return 0; // Command not done yet

View File

@@ -810,9 +810,9 @@ bool Display::clamp_y_(int y, int h, int &min_y, int &max_y) {
return min_y < max_y;
}
const uint8_t TESTCARD_FONT[3][8] PROGMEM = {{0x41, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00}, // 'R'
{0x1C, 0x3E, 0x63, 0x41, 0x51, 0x73, 0x72, 0x00}, // 'G'
{0x41, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00}}; // 'B'
constexpr uint8_t TESTCARD_FONT[3][8] PROGMEM = {{0x41, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00}, // 'R'
{0x1C, 0x3E, 0x63, 0x41, 0x51, 0x73, 0x72, 0x00}, // 'G'
{0x41, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00}}; // 'B'
void Display::test_card() {
int w = get_width(), h = get_height(), image_w, image_h;

View File

@@ -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; }

View File

@@ -70,27 +70,12 @@ void E131Component::loop() {
E131Packet packet;
int universe = 0;
uint8_t buf[1460];
ssize_t len;
#if defined(USE_SOCKET_IMPL_BSD_SOCKETS) || defined(USE_SOCKET_IMPL_LWIP_SOCKETS)
ssize_t len = this->socket_->read(buf, sizeof(buf));
if (len == -1) {
return;
}
if (!this->packet_(buf, (size_t) len, universe, packet)) {
ESP_LOGV(TAG, "Invalid packet received of size %d.", (int) len);
return;
}
if (!this->process_(universe, packet)) {
ESP_LOGV(TAG, "Ignored packet for %d universe of size %d.", universe, packet.count);
}
#elif defined(USE_SOCKET_IMPL_LWIP_TCP)
while (auto packet_size = this->udp_.parsePacket()) {
auto len = this->udp_.read(buf, sizeof(buf));
if (len <= 0)
continue;
// Drain all queued packets so multi-universe frames are applied
// atomically before the light writes. Without this, each universe
// packet would trigger a separate full-strip write causing tearing.
while ((len = this->read_(buf, sizeof(buf))) > 0) {
if (!this->packet_(buf, (size_t) len, universe, packet)) {
ESP_LOGV(TAG, "Invalid packet received of size %d.", (int) len);
continue;
@@ -100,7 +85,6 @@ void E131Component::loop() {
ESP_LOGV(TAG, "Ignored packet for %d universe of size %d.", universe, packet.count);
}
}
#endif
}
void E131Component::add_effect(E131AddressableLightEffect *light_effect) {

View File

@@ -46,6 +46,15 @@ class E131Component : public esphome::Component {
void set_method(E131ListenMethod listen_method) { this->listen_method_ = listen_method; }
protected:
inline ssize_t read_(uint8_t *buf, size_t len) {
#if defined(USE_SOCKET_IMPL_BSD_SOCKETS) || defined(USE_SOCKET_IMPL_LWIP_SOCKETS)
return this->socket_->read(buf, len);
#elif defined(USE_SOCKET_IMPL_LWIP_TCP)
if (!this->udp_.parsePacket())
return -1;
return this->udp_.read(buf, len);
#endif
}
bool packet_(const uint8_t *data, size_t len, int &universe, E131Packet &packet);
bool process_(int universe, const E131Packet &packet);
bool join_igmp_groups_();

View File

@@ -153,10 +153,7 @@ void EmmetiClimate::reverse_add_(T val, size_t len, esphome::remote_base::Remote
bool EmmetiClimate::check_checksum_(uint8_t checksum) {
uint8_t expected = this->gen_checksum_();
ESP_LOGV(TAG,
"Expected checksum: %X\n"
"Checksum received: %X",
expected, checksum);
ESP_LOGV(TAG, "Expected checksum: %X, Checksum received: %X", expected, checksum);
return checksum == expected;
}
@@ -266,10 +263,7 @@ bool EmmetiClimate::on_receive(remote_base::RemoteReceiveData data) {
}
}
ESP_LOGD(TAG,
"Swing: %d\n"
"Sleep: %d",
(curr_state.bitmap >> 1) & 0x01, (curr_state.bitmap >> 2) & 0x01);
ESP_LOGD(TAG, "Swing: %d, Sleep: %d", (curr_state.bitmap >> 1) & 0x01, (curr_state.bitmap >> 2) & 0x01);
for (size_t pos = 0; pos < 4; pos++) {
if (data.expect_item(EMMETI_BIT_MARK, EMMETI_ONE_SPACE)) {
@@ -295,13 +289,8 @@ bool EmmetiClimate::on_receive(remote_base::RemoteReceiveData data) {
}
}
ESP_LOGD(TAG,
"Turbo: %d\n"
"Light: %d\n"
"Tree: %d\n"
"Blow: %d",
(curr_state.bitmap >> 3) & 0x01, (curr_state.bitmap >> 4) & 0x01, (curr_state.bitmap >> 5) & 0x01,
(curr_state.bitmap >> 6) & 0x01);
ESP_LOGD(TAG, "Turbo: %d, Light: %d, Tree: %d, Blow: %d", (curr_state.bitmap >> 3) & 0x01,
(curr_state.bitmap >> 4) & 0x01, (curr_state.bitmap >> 5) & 0x01, (curr_state.bitmap >> 6) & 0x01);
uint16_t control_data = 0;
for (size_t pos = 0; pos < 11; pos++) {

View File

@@ -152,12 +152,13 @@ void ENS160Component::update() {
// verbose status logging
ESP_LOGV(TAG,
"Status: ENS160 STATAS bit 0x%x\n"
"Status: ENS160 STATER bit 0x%x\n"
"Status: ENS160 VALIDITY FLAG 0x%02x\n"
"Status: ENS160 NEWDAT bit 0x%x\n"
"Status: ENS160 NEWGPR bit 0x%x",
(ENS160_DATA_STATUS_STATAS & (status_value)) == ENS160_DATA_STATUS_STATAS,
"ENS160 Status Register: 0x%02x\n"
" STATAS bit 0x%x\n"
" STATER bit 0x%x\n"
" VALIDITY FLAG 0x%02x\n"
" NEWDAT bit 0x%x\n"
" NEWGPR bit 0x%x",
status_value, (ENS160_DATA_STATUS_STATAS & (status_value)) == ENS160_DATA_STATUS_STATAS,
(ENS160_DATA_STATUS_STATER & (status_value)) == ENS160_DATA_STATUS_STATER,
(ENS160_DATA_STATUS_VALIDITY & status_value) >> 2,
(ENS160_DATA_STATUS_NEWDAT & (status_value)) == ENS160_DATA_STATUS_NEWDAT,

View File

@@ -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;

View File

@@ -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)

View File

@@ -209,9 +209,10 @@ bool ES8388::set_dac_output(DacOutputLine line) {
};
ESP_LOGV(TAG,
"Setting ES8388_DACPOWER to 0x%02X\n"
"Setting ES8388_DACCONTROL24 / ES8388_DACCONTROL25 to 0x%02X\n"
"Setting ES8388_DACCONTROL26 / ES8388_DACCONTROL27 to 0x%02X",
"DAC output config:\n"
" DACPOWER: 0x%02X\n"
" DACCONTROL24/25: 0x%02X\n"
" DACCONTROL26/27: 0x%02X",
dac_power, reg_out1, reg_out2);
ES8388_ERROR_CHECK(this->write_byte(ES8388_DACCONTROL24, reg_out1)); // LOUT1VOL

View File

@@ -14,6 +14,7 @@ from esphome.const import (
CONF_BOARD,
CONF_COMPONENTS,
CONF_DISABLED,
CONF_ENABLE_OTA_ROLLBACK,
CONF_ESPHOME,
CONF_FRAMEWORK,
CONF_IGNORE_EFUSE_CUSTOM_MAC,
@@ -87,9 +88,9 @@ IS_TARGET_PLATFORM = True
CONF_ASSERTION_LEVEL = "assertion_level"
CONF_COMPILER_OPTIMIZATION = "compiler_optimization"
CONF_ENABLE_IDF_EXPERIMENTAL_FEATURES = "enable_idf_experimental_features"
CONF_ENGINEERING_SAMPLE = "engineering_sample"
CONF_INCLUDE_BUILTIN_IDF_COMPONENTS = "include_builtin_idf_components"
CONF_ENABLE_LWIP_ASSERT = "enable_lwip_assert"
CONF_ENABLE_OTA_ROLLBACK = "enable_ota_rollback"
CONF_EXECUTE_FROM_PSRAM = "execute_from_psram"
CONF_MINIMUM_CHIP_REVISION = "minimum_chip_revision"
CONF_RELEASE = "release"
@@ -587,16 +588,22 @@ def _format_framework_arduino_version(ver: cv.Version) -> str:
return f"{ARDUINO_FRAMEWORK_PKG}@https://github.com/espressif/arduino-esp32/releases/download/{ver}/{filename}"
def _format_framework_espidf_version(ver: cv.Version, release: str) -> str:
def _format_framework_espidf_version(
ver: cv.Version, release: str | None = None
) -> str:
# format the given espidf (https://github.com/pioarduino/esp-idf/releases) version to
# a PIO platformio/framework-espidf value
if ver == cv.Version(5, 4, 3) or ver >= cv.Version(5, 5, 1):
ext = "tar.xz"
else:
ext = "zip"
# Build version string with dot-separated extra (e.g., "5.5.3.1" not "5.5.3-1")
ver_str = f"{ver.major}.{ver.minor}.{ver.patch}"
if ver.extra:
ver_str += f".{ver.extra}"
if release:
return f"pioarduino/framework-espidf@https://github.com/pioarduino/esp-idf/releases/download/v{str(ver)}.{release}/esp-idf-v{str(ver)}.{ext}"
return f"pioarduino/framework-espidf@https://github.com/pioarduino/esp-idf/releases/download/v{str(ver)}/esp-idf-v{str(ver)}.{ext}"
return f"pioarduino/framework-espidf@https://github.com/pioarduino/esp-idf/releases/download/v{ver_str}.{release}/esp-idf-v{ver_str}.{ext}"
return f"pioarduino/framework-espidf@https://github.com/pioarduino/esp-idf/releases/download/v{ver_str}/esp-idf-v{ver_str}.{ext}"
def _is_framework_url(source: str) -> bool:
@@ -643,7 +650,7 @@ ARDUINO_PLATFORM_VERSION_LOOKUP = {
# These versions correspond to pioarduino/esp-idf releases
# See: https://github.com/pioarduino/esp-idf/releases
ARDUINO_IDF_VERSION_LOOKUP = {
cv.Version(3, 3, 7): cv.Version(5, 5, 2),
cv.Version(3, 3, 7): cv.Version(5, 5, 3, "1"),
cv.Version(3, 3, 6): cv.Version(5, 5, 2),
cv.Version(3, 3, 5): cv.Version(5, 5, 2),
cv.Version(3, 3, 4): cv.Version(5, 5, 1),
@@ -662,11 +669,13 @@ ARDUINO_IDF_VERSION_LOOKUP = {
# The default/recommended esp-idf framework version
# - https://github.com/espressif/esp-idf/releases
ESP_IDF_FRAMEWORK_VERSION_LOOKUP = {
"recommended": cv.Version(5, 5, 2),
"latest": cv.Version(5, 5, 2),
"dev": cv.Version(5, 5, 2),
"recommended": cv.Version(5, 5, 3, "1"),
"latest": cv.Version(5, 5, 3, "1"),
"dev": cv.Version(5, 5, 3, "1"),
}
ESP_IDF_PLATFORM_VERSION_LOOKUP = {
cv.Version(5, 5, 3, "1"): cv.Version(55, 3, 37),
cv.Version(5, 5, 3): cv.Version(55, 3, 37),
cv.Version(5, 5, 2): cv.Version(55, 3, 37),
cv.Version(5, 5, 1): cv.Version(55, 3, 31, "2"),
cv.Version(5, 5, 0): cv.Version(55, 3, 31, "2"),
@@ -729,7 +738,7 @@ def _check_versions(config):
platform_lookup = ESP_IDF_PLATFORM_VERSION_LOOKUP.get(version)
value[CONF_SOURCE] = value.get(
CONF_SOURCE,
_format_framework_espidf_version(version, value.get(CONF_RELEASE, None)),
_format_framework_espidf_version(version, value.get(CONF_RELEASE)),
)
if _is_framework_url(value[CONF_SOURCE]):
value[CONF_SOURCE] = f"pioarduino/framework-espidf@{value[CONF_SOURCE]}"
@@ -777,6 +786,15 @@ def _detect_variant(value):
# variant has already been validated against the known set
value = value.copy()
value[CONF_BOARD] = STANDARD_BOARDS[variant]
if variant == VARIANT_ESP32P4:
engineering_sample = value.get(CONF_ENGINEERING_SAMPLE)
if engineering_sample is None:
_LOGGER.warning(
"No board specified for ESP32-P4. Defaulting to production silicon (rev3). "
"If you have an early engineering sample (pre-rev3), set 'engineering_sample: true'."
)
elif engineering_sample:
value[CONF_BOARD] = "esp32-p4-evboard"
elif board in BOARDS:
variant = variant or BOARDS[board][KEY_VARIANT]
if variant != BOARDS[board][KEY_VARIANT]:
@@ -840,6 +858,30 @@ def final_validate(config):
path=[CONF_FRAMEWORK, CONF_ADVANCED, CONF_MINIMUM_CHIP_REVISION],
)
)
if (
config[CONF_VARIANT] != VARIANT_ESP32P4
and config.get(CONF_ENGINEERING_SAMPLE) is not None
):
errs.append(
cv.Invalid(
f"'{CONF_ENGINEERING_SAMPLE}' is only supported on {VARIANT_ESP32P4}",
path=[CONF_ENGINEERING_SAMPLE],
)
)
if (
config[CONF_VARIANT] == VARIANT_ESP32P4
and config.get(CONF_ENGINEERING_SAMPLE) is not None
):
board_is_es = BOARDS.get(config[CONF_BOARD], {}).get(
"engineering_sample", False
)
if config[CONF_ENGINEERING_SAMPLE] != board_is_es:
errs.append(
cv.Invalid(
f"'{CONF_ENGINEERING_SAMPLE}' does not match board '{config[CONF_BOARD]}'",
path=[CONF_ENGINEERING_SAMPLE],
)
)
if advanced[CONF_EXECUTE_FROM_PSRAM]:
if config[CONF_VARIANT] != VARIANT_ESP32S3:
errs.append(
@@ -1189,6 +1231,7 @@ CONFIG_SCHEMA = cv.All(
cv.Optional(CONF_CPU_FREQUENCY): cv.one_of(
*FULL_CPU_FREQUENCIES, upper=True
),
cv.Optional(CONF_ENGINEERING_SAMPLE): cv.boolean,
cv.Optional(CONF_FLASH_SIZE, default="4MB"): cv.one_of(
*FLASH_SIZES, upper=True
),
@@ -1215,21 +1258,15 @@ def _configure_lwip_max_sockets(conf: dict) -> None:
This function runs in to_code() after all components have registered their socket needs.
User-provided sdkconfig_options take precedence.
"""
from esphome.components.socket import KEY_SOCKET_CONSUMERS
from esphome.components.socket import get_socket_counts
# Check if user manually specified CONFIG_LWIP_MAX_SOCKETS
user_max_sockets = conf[CONF_SDKCONFIG_OPTIONS].get("CONFIG_LWIP_MAX_SOCKETS")
socket_consumers: dict[str, int] = CORE.data.get(KEY_SOCKET_CONSUMERS, {})
total_sockets = sum(socket_consumers.values())
# Early return if no sockets registered and no user override
if total_sockets == 0 and user_max_sockets is None:
return
components_list = ", ".join(
f"{name}={count}" for name, count in sorted(socket_consumers.items())
)
# CONFIG_LWIP_MAX_SOCKETS is a single VFS socket pool shared by all socket
# types (TCP clients, TCP listeners, and UDP). Include all three counts.
sc = get_socket_counts()
total_sockets = sc.tcp + sc.udp + sc.tcp_listen
# User specified their own value - respect it but warn if insufficient
if user_max_sockets is not None:
@@ -1238,22 +1275,23 @@ def _configure_lwip_max_sockets(conf: dict) -> None:
user_max_sockets,
)
# Warn if user's value is less than what components need
if total_sockets > 0:
user_sockets_int = 0
with contextlib.suppress(ValueError, TypeError):
user_sockets_int = int(user_max_sockets)
user_sockets_int = 0
with contextlib.suppress(ValueError, TypeError):
user_sockets_int = int(user_max_sockets)
if user_sockets_int < total_sockets:
_LOGGER.warning(
"CONFIG_LWIP_MAX_SOCKETS is set to %d but your configuration "
"needs %d sockets (registered: %s). You may experience socket "
"exhaustion errors. Consider increasing to at least %d.",
user_sockets_int,
total_sockets,
components_list,
total_sockets,
)
if user_sockets_int < total_sockets:
_LOGGER.warning(
"CONFIG_LWIP_MAX_SOCKETS is set to %d but your configuration "
"needs %d sockets (%d TCP + %d UDP + %d TCP_LISTEN). You may "
"experience socket exhaustion errors. Consider increasing to "
"at least %d.",
user_sockets_int,
total_sockets,
sc.tcp,
sc.udp,
sc.tcp_listen,
total_sockets,
)
# User's value already added via sdkconfig_options processing
return
@@ -1262,11 +1300,19 @@ def _configure_lwip_max_sockets(conf: dict) -> None:
max_sockets = max(DEFAULT_MAX_SOCKETS, total_sockets)
log_level = logging.INFO if max_sockets > DEFAULT_MAX_SOCKETS else logging.DEBUG
sock_min = " (min)" if max_sockets > total_sockets else ""
_LOGGER.log(
log_level,
"Setting CONFIG_LWIP_MAX_SOCKETS to %d (registered: %s)",
"Setting CONFIG_LWIP_MAX_SOCKETS to %d%s "
"(TCP=%d [%s], UDP=%d [%s], TCP_LISTEN=%d [%s])",
max_sockets,
components_list,
sock_min,
sc.tcp,
sc.tcp_details,
sc.udp,
sc.udp_details,
sc.tcp_listen,
sc.tcp_listen_details,
)
add_idf_sdkconfig_option("CONFIG_LWIP_MAX_SOCKETS", max_sockets)
@@ -1427,7 +1473,7 @@ async def to_code(config):
if (idf_ver := ARDUINO_IDF_VERSION_LOOKUP.get(framework_ver)) is not None:
cg.add_platformio_option(
"platform_packages",
[_format_framework_espidf_version(idf_ver, None)],
[_format_framework_espidf_version(idf_ver)],
)
# Use stub package to skip downloading precompiled libs
stubs_dir = CORE.relative_build_path("arduino_libs_stub")
@@ -1471,6 +1517,16 @@ async def to_code(config):
f"CONFIG_ESPTOOLPY_FLASHSIZE_{config[CONF_FLASH_SIZE]}", True
)
# ESP32-P4: ESP-IDF 5.5.3 changed the default of ESP32P4_SELECTS_REV_LESS_V3
# from y to n. PlatformIO uses sections.ld.in (for rev <3) or
# sections.rev3.ld.in (for rev >=3) based on board definition.
# Set the sdkconfig option to match the board's chip revision.
if variant == VARIANT_ESP32P4:
is_eng_sample = BOARDS.get(config[CONF_BOARD], {}).get(
"engineering_sample", False
)
add_idf_sdkconfig_option("CONFIG_ESP32P4_SELECTS_REV_LESS_V3", is_eng_sample)
# Set minimum chip revision for ESP32 variant
# Setting this to 3.0 or higher reduces flash size by excluding workaround code,
# and for PSRAM users saves significant IRAM by keeping C library functions in ROM.

View File

@@ -20,7 +20,7 @@ STANDARD_BOARDS = {
VARIANT_ESP32C6: "esp32-c6-devkitm-1",
VARIANT_ESP32C61: "esp32-c61-devkitc1-n8r2",
VARIANT_ESP32H2: "esp32-h2-devkitm-1",
VARIANT_ESP32P4: "esp32-p4-evboard",
VARIANT_ESP32P4: "esp32-p4_r3-evboard",
VARIANT_ESP32S2: "esp32-s2-kaluga-1",
VARIANT_ESP32S3: "esp32-s3-devkitc-1",
}
@@ -1713,10 +1713,12 @@ BOARDS = {
"esp32-p4": {
"name": "Espressif ESP32-P4 ES (pre rev.300) generic",
"variant": VARIANT_ESP32P4,
"engineering_sample": True,
},
"esp32-p4-evboard": {
"name": "Espressif ESP32-P4 Function EV Board (ES pre rev.300)",
"variant": VARIANT_ESP32P4,
"engineering_sample": True,
},
"esp32-p4_r3": {
"name": "Espressif ESP32-P4 rev.300 generic",
@@ -2141,6 +2143,7 @@ BOARDS = {
"m5stack-tab5-p4": {
"name": "M5STACK Tab5 esp32-p4 Board (ES pre rev.300)",
"variant": VARIANT_ESP32P4,
"engineering_sample": True,
},
"m5stack-timer-cam": {
"name": "M5Stack Timer CAM",

View File

@@ -413,16 +413,16 @@ def final_validation(config):
add_idf_sdkconfig_option("CONFIG_ESP_HOSTED_ENABLE_BT_BLUEDROID", True)
add_idf_sdkconfig_option("CONFIG_ESP_HOSTED_BLUEDROID_HCI_VHCI", True)
# Check if BLE Server is needed
has_ble_server = "esp32_ble_server" in full_config
# Check if BLE Client is needed (via esp32_ble_tracker or esp32_ble_client)
has_ble_client = (
"esp32_ble_tracker" in full_config or "esp32_ble_client" in full_config
)
# Check if BLE Server is needed
has_ble_server = "esp32_ble_server" in full_config
# ESP-IDF BLE stack requires GATT Server to be enabled when GATT Client is enabled
# This is an internal dependency in the Bluedroid stack (tested ESP-IDF 5.4.2-5.5.1)
# This is an internal dependency in the Bluedroid stack
# See: https://github.com/espressif/esp-idf/issues/17724
add_idf_sdkconfig_option("CONFIG_BT_GATTS_ENABLE", has_ble_server or has_ble_client)
add_idf_sdkconfig_option("CONFIG_BT_GATTC_ENABLE", has_ble_client)

View File

@@ -423,10 +423,8 @@ bool BLEClientBase::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
for (auto &svc : this->services_) {
char uuid_buf[espbt::UUID_STR_LEN];
svc->uuid.to_str(uuid_buf);
ESP_LOGV(TAG,
"[%d] [%s] Service UUID: %s\n"
"[%d] [%s] start_handle: 0x%x end_handle: 0x%x",
this->connection_index_, this->address_str_, uuid_buf, this->connection_index_, this->address_str_,
ESP_LOGV(TAG, "[%d] [%s] Service UUID: %s", this->connection_index_, this->address_str_, uuid_buf);
ESP_LOGV(TAG, "[%d] [%s] start_handle: 0x%x end_handle: 0x%x", this->connection_index_, this->address_str_,
svc->start_handle, svc->end_handle);
}
#endif

View File

@@ -20,8 +20,10 @@ def _consume_camera_web_server_sockets(config: ConfigType) -> ConfigType:
from esphome.components import socket
# Each camera web server instance needs 1 listening socket + 2 client connections
sockets_needed = 3
socket.consume_sockets(sockets_needed, "esp32_camera_web_server")(config)
socket.consume_sockets(2, "esp32_camera_web_server")(config)
socket.consume_sockets(1, "esp32_camera_web_server", socket.SocketType.TCP_LISTEN)(
config
)
return config

View File

@@ -106,11 +106,12 @@ void Esp32HostedUpdate::setup() {
esp_app_desc_t *app_desc = (esp_app_desc_t *) (this->firmware_data_ + app_desc_offset);
if (app_desc->magic_word == ESP_APP_DESC_MAGIC_WORD) {
ESP_LOGD(TAG,
"Firmware version: %s\n"
"Project name: %s\n"
"Build date: %s\n"
"Build time: %s\n"
"IDF version: %s",
"ESP32 Hosted firmware:\n"
" Firmware version: %s\n"
" Project name: %s\n"
" Build date: %s\n"
" Build time: %s\n"
" IDF version: %s",
app_desc->version, app_desc->project_name, app_desc->date, app_desc->time, app_desc->idf_ver);
this->update_info_.latest_version = app_desc->version;
if (this->update_info_.latest_version != this->update_info_.current_version) {

View File

@@ -202,11 +202,11 @@ async def add_pin_initial_states_array():
cg.add_global(
cg.RawExpression(
f"const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_MODE[16] PROGMEM = {{{initial_modes_s}}}"
f"constexpr uint8_t ESPHOME_ESP8266_GPIO_INITIAL_MODE[16] PROGMEM = {{{initial_modes_s}}}"
)
)
cg.add_global(
cg.RawExpression(
f"const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_LEVEL[16] PROGMEM = {{{initial_levels_s}}}"
f"constexpr uint8_t ESPHOME_ESP8266_GPIO_INITIAL_LEVEL[16] PROGMEM = {{{initial_levels_s}}}"
)
)

View File

@@ -97,8 +97,9 @@ def _consume_ota_sockets(config: ConfigType) -> ConfigType:
"""Register socket needs for OTA component."""
from esphome.components import socket
# OTA needs 1 listening socket (client connections are temporary during updates)
socket.consume_sockets(1, "ota")(config)
# OTA needs 1 listening socket. The active transfer connection during an update
# uses a TCP PCB from the general pool, covered by MIN_TCP_SOCKETS headroom.
socket.consume_sockets(1, "ota", socket.SocketType.TCP_LISTEN)(config)
return config

View File

@@ -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

View File

@@ -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_;

View File

@@ -21,11 +21,9 @@ void ESPNowTransport::setup() {
return;
}
ESP_LOGI(TAG,
"Registering ESP-NOW handlers\n"
"Peer address: %02X:%02X:%02X:%02X:%02X:%02X",
this->peer_address_[0], this->peer_address_[1], this->peer_address_[2], this->peer_address_[3],
this->peer_address_[4], this->peer_address_[5]);
ESP_LOGI(TAG, "Registering ESP-NOW handlers, peer: %02X:%02X:%02X:%02X:%02X:%02X", this->peer_address_[0],
this->peer_address_[1], this->peer_address_[2], this->peer_address_[3], this->peer_address_[4],
this->peer_address_[5]);
// Register received handler
this->parent_->register_received_handler(this);

View File

@@ -866,10 +866,7 @@ void EthernetComponent::write_phy_register_(esp_eth_mac_t *mac, PHYRegister regi
}
#endif
ESP_LOGD(TAG,
"Writing to PHY Register Address: 0x%02" PRIX32 "\n"
"Writing to PHY Register Value: 0x%04" PRIX32,
register_data.address, register_data.value);
ESP_LOGD(TAG, "Writing PHY reg 0x%02" PRIX32 " = 0x%04" PRIX32, register_data.address, register_data.value);
err = mac->write_phy_reg(mac, this->phy_addr_, register_data.address, register_data.value);
ESPHL_ERROR_CHECK(err, "Writing PHY Register failed");

View File

@@ -150,9 +150,9 @@ void EzoPMP::read_command_result_() {
if (current_char == '\0') {
ESP_LOGV(TAG,
"Read Response from device: %s\n"
"First Component: %s\n"
"Second Component: %s\n"
"Third Component: %s",
" First Component: %s\n"
" Second Component: %s\n"
" Third Component: %s",
(char *) response_buffer, (char *) first_parameter_buffer, (char *) second_parameter_buffer,
(char *) third_parameter_buffer);

View File

@@ -97,10 +97,10 @@ void GCJA5Component::parse_data_() {
ESP_LOGI(TAG,
"GCJA5 Status\n"
"Overall Status : %i\n"
"PD Status : %i\n"
"LD Status : %i\n"
"Fan Status : %i",
" Overall Status : %i\n"
" PD Status : %i\n"
" LD Status : %i\n"
" Fan Status : %i",
(status >> 6) & 0x03, (status >> 4) & 0x03, (status >> 2) & 0x03, (status >> 0) & 0x03);
}
}

View File

@@ -38,13 +38,13 @@ void GraphicalDisplayMenu::setup() {
void GraphicalDisplayMenu::dump_config() {
ESP_LOGCONFIG(TAG,
"Graphical Display Menu\n"
"Has Display: %s\n"
"Popup Mode: %s\n"
"Advanced Drawing Mode: %s\n"
"Has Font: %s\n"
"Mode: %s\n"
"Active: %s\n"
"Menu items:",
" Has Display: %s\n"
" Popup Mode: %s\n"
" Advanced Drawing Mode: %s\n"
" Has Font: %s\n"
" Mode: %s\n"
" Active: %s\n"
" Menu items:",
YESNO(this->display_ != nullptr), YESNO(this->display_ != nullptr), YESNO(this->display_ == nullptr),
YESNO(this->font_ != nullptr),
this->mode_ == display_menu_base::MENU_MODE_ROTARY ? "Rotary" : "Joystick", YESNO(this->active_));

View File

@@ -1,6 +1,7 @@
#pragma once
#include <chrono>
#include <queue>
#ifdef USE_SENSOR
#include "esphome/components/sensor/sensor.h"
#endif
@@ -29,10 +30,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 +190,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};
};

View File

@@ -0,0 +1 @@
CODEOWNERS = ["@joshuasing"]

View File

@@ -0,0 +1,171 @@
#include "hdc302x.h"
#include "esphome/core/hal.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome::hdc302x {
static const char *const TAG = "hdc302x.sensor";
// Commands (per datasheet Table 7-4)
static const uint8_t HDC302X_CMD_SOFT_RESET[2] = {0x30, 0xa2};
static const uint8_t HDC302X_CMD_CLEAR_STATUS_REGISTER[2] = {0x30, 0x41};
static const uint8_t HDC302X_CMD_TRIGGER_MSB = 0x24;
static const uint8_t HDC302X_CMD_HEATER_ENABLE[2] = {0x30, 0x6d};
static const uint8_t HDC302X_CMD_HEATER_DISABLE[2] = {0x30, 0x66};
static const uint8_t HDC302X_CMD_HEATER_CONFIGURE[2] = {0x30, 0x6e};
void HDC302XComponent::setup() {
// Soft reset the device
if (this->write(HDC302X_CMD_SOFT_RESET, 2) != i2c::ERROR_OK) {
this->mark_failed(LOG_STR("Soft reset failed"));
return;
}
// Delay SensorRR (reset ready), per datasheet, 6.5.
delay(3);
// Clear status register
if (this->write(HDC302X_CMD_CLEAR_STATUS_REGISTER, 2) != i2c::ERROR_OK) {
this->mark_failed(LOG_STR("Clear status failed"));
return;
}
}
void HDC302XComponent::dump_config() {
ESP_LOGCONFIG(TAG,
"HDC302x:\n"
" Heater: %s",
this->heater_active_ ? "active" : "inactive");
LOG_I2C_DEVICE(this);
LOG_UPDATE_INTERVAL(this);
LOG_SENSOR(" ", "Temperature", this->temp_sensor_);
LOG_SENSOR(" ", "Humidity", this->humidity_sensor_);
}
void HDC302XComponent::update() {
uint8_t cmd[] = {
HDC302X_CMD_TRIGGER_MSB,
this->power_mode_,
};
if (this->write(cmd, 2) != i2c::ERROR_OK) {
this->status_set_warning(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
return;
}
// Read data after ADC conversion has completed
this->set_timeout(this->conversion_delay_ms_(), [this]() { this->read_data_(); });
}
void HDC302XComponent::start_heater(uint16_t power, uint32_t duration_ms) {
if (!this->disable_heater_()) {
ESP_LOGD(TAG, "Heater disable before start failed");
}
if (!this->configure_heater_(power) || !this->enable_heater_()) {
ESP_LOGW(TAG, "Heater start failed");
return;
}
this->heater_active_ = true;
this->cancel_timeout("heater_off");
if (duration_ms > 0) {
this->set_timeout("heater_off", duration_ms, [this]() { this->stop_heater(); });
}
}
void HDC302XComponent::stop_heater() {
this->cancel_timeout("heater_off");
if (!this->disable_heater_()) {
ESP_LOGW(TAG, "Heater stop failed");
}
this->heater_active_ = false;
}
bool HDC302XComponent::enable_heater_() {
if (this->write(HDC302X_CMD_HEATER_ENABLE, 2) != i2c::ERROR_OK) {
ESP_LOGE(TAG, "Enable heater failed");
return false;
}
return true;
}
bool HDC302XComponent::configure_heater_(uint16_t power_level) {
if (power_level > 0x3fff) {
ESP_LOGW(TAG, "Heater power 0x%04x exceeds max 0x3fff", power_level);
return false;
}
// Heater current level config.
uint8_t config[] = {
static_cast<uint8_t>((power_level >> 8) & 0xff), // MSB
static_cast<uint8_t>(power_level & 0xff) // LSB
};
// Configure level of heater current (per datasheet 7.5.7.8).
uint8_t cmd[] = {
HDC302X_CMD_HEATER_CONFIGURE[0], HDC302X_CMD_HEATER_CONFIGURE[1], config[0], config[1],
crc8(config, 2, 0xff, 0x31, true),
};
if (this->write(cmd, sizeof(cmd)) != i2c::ERROR_OK) {
ESP_LOGE(TAG, "Configure heater failed");
return false;
}
return true;
}
bool HDC302XComponent::disable_heater_() {
if (this->write(HDC302X_CMD_HEATER_DISABLE, 2) != i2c::ERROR_OK) {
ESP_LOGE(TAG, "Disable heater failed");
return false;
}
return true;
}
void HDC302XComponent::read_data_() {
uint8_t buf[6];
if (this->read(buf, 6) != i2c::ERROR_OK) {
this->status_set_warning(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
return;
}
// Check checksums
if (crc8(buf, 2, 0xff, 0x31, true) != buf[2] || crc8(buf + 3, 2, 0xff, 0x31, true) != buf[5]) {
this->status_set_warning(LOG_STR("Read data: invalid CRC"));
return;
}
this->status_clear_warning();
if (this->temp_sensor_ != nullptr) {
uint16_t raw_t = encode_uint16(buf[0], buf[1]);
// Calculate temperature in Celsius per datasheet section 7.3.3.
float temp = -45 + 175 * (float(raw_t) / 65535.0f);
this->temp_sensor_->publish_state(temp);
}
if (this->humidity_sensor_ != nullptr) {
uint16_t raw_rh = encode_uint16(buf[3], buf[4]);
// Calculate RH% per datasheet section 7.3.3.
float humidity = 100 * (float(raw_rh) / 65535.0f);
this->humidity_sensor_->publish_state(humidity);
}
}
uint32_t HDC302XComponent::conversion_delay_ms_() {
// ADC conversion delay per datasheet, Table 7-5. - Trigger on Demand
switch (this->power_mode_) {
case HDC302XPowerMode::BALANCED:
return 8;
case HDC302XPowerMode::LOW_POWER:
return 5;
case HDC302XPowerMode::ULTRA_LOW_POWER:
return 4;
case HDC302XPowerMode::HIGH_ACCURACY:
default:
return 13;
}
}
} // namespace esphome::hdc302x

View File

@@ -0,0 +1,68 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/core/automation.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/i2c/i2c.h"
namespace esphome::hdc302x {
enum HDC302XPowerMode : uint8_t {
HIGH_ACCURACY = 0x00,
BALANCED = 0x0b,
LOW_POWER = 0x16,
ULTRA_LOW_POWER = 0xff,
};
/**
HDC302x Temperature and humidity sensor.
Datasheet:
https://www.ti.com/lit/ds/symlink/hdc3020.pdf
*/
class HDC302XComponent : public PollingComponent, public i2c::I2CDevice {
public:
void setup() override;
void dump_config() override;
void update() override;
void start_heater(uint16_t power, uint32_t duration_ms);
void stop_heater();
void set_temp_sensor(sensor::Sensor *temp_sensor) { this->temp_sensor_ = temp_sensor; }
void set_humidity_sensor(sensor::Sensor *humidity_sensor) { this->humidity_sensor_ = humidity_sensor; }
void set_power_mode(HDC302XPowerMode power_mode) { this->power_mode_ = power_mode; }
protected:
sensor::Sensor *temp_sensor_{nullptr};
sensor::Sensor *humidity_sensor_{nullptr};
HDC302XPowerMode power_mode_{HDC302XPowerMode::HIGH_ACCURACY};
bool heater_active_{false};
bool enable_heater_();
bool configure_heater_(uint16_t power_level);
bool disable_heater_();
void read_data_();
uint32_t conversion_delay_ms_();
};
template<typename... Ts> class HeaterOnAction : public Action<Ts...>, public Parented<HDC302XComponent> {
public:
TEMPLATABLE_VALUE(uint16_t, power)
TEMPLATABLE_VALUE(uint32_t, duration)
void play(const Ts &...x) override {
auto power_val = this->power_.value(x...);
auto duration_val = this->duration_.value(x...);
this->parent_->start_heater(power_val, duration_val);
}
};
template<typename... Ts> class HeaterOffAction : public Action<Ts...>, public Parented<HDC302XComponent> {
public:
void play(const Ts &...x) override { this->parent_->stop_heater(); }
};
} // namespace esphome::hdc302x

View File

@@ -0,0 +1,135 @@
from esphome import automation
from esphome.automation import maybe_simple_id
import esphome.codegen as cg
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_DURATION,
CONF_HUMIDITY,
CONF_ID,
CONF_POWER,
CONF_POWER_MODE,
CONF_TEMPERATURE,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_TEMPERATURE,
STATE_CLASS_MEASUREMENT,
UNIT_CELSIUS,
UNIT_PERCENT,
)
DEPENDENCIES = ["i2c"]
hdc302x_ns = cg.esphome_ns.namespace("hdc302x")
HDC302XComponent = hdc302x_ns.class_(
"HDC302XComponent", cg.PollingComponent, i2c.I2CDevice
)
HDC302XPowerMode = hdc302x_ns.enum("HDC302XPowerMode")
POWER_MODE_OPTIONS = {
"HIGH_ACCURACY": HDC302XPowerMode.HIGH_ACCURACY,
"BALANCED": HDC302XPowerMode.BALANCED,
"LOW_POWER": HDC302XPowerMode.LOW_POWER,
"ULTRA_LOW_POWER": HDC302XPowerMode.ULTRA_LOW_POWER,
}
# Actions
HeaterOnAction = hdc302x_ns.class_("HeaterOnAction", automation.Action)
HeaterOffAction = hdc302x_ns.class_("HeaterOffAction", automation.Action)
CONFIG_SCHEMA = (
cv.Schema(
{
cv.GenerateID(): cv.declare_id(HDC302XComponent),
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
unit_of_measurement=UNIT_CELSIUS,
accuracy_decimals=2,
device_class=DEVICE_CLASS_TEMPERATURE,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
unit_of_measurement=UNIT_PERCENT,
accuracy_decimals=2,
device_class=DEVICE_CLASS_HUMIDITY,
state_class=STATE_CLASS_MEASUREMENT,
),
cv.Optional(CONF_POWER_MODE, default="HIGH_ACCURACY"): cv.enum(
POWER_MODE_OPTIONS, upper=True
),
}
)
.extend(cv.polling_component_schema("60s"))
.extend(i2c.i2c_device_schema(0x44)) # Default address per datasheet, Table 7-2.
)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await i2c.register_i2c_device(var, config)
if temp_config := config.get(CONF_TEMPERATURE):
sens = await sensor.new_sensor(temp_config)
cg.add(var.set_temp_sensor(sens))
if humidity_config := config.get(CONF_HUMIDITY):
sens = await sensor.new_sensor(humidity_config)
cg.add(var.set_humidity_sensor(sens))
cg.add(var.set_power_mode(config[CONF_POWER_MODE]))
# HDC302x heater power configs, per datasheet Table 7-15.
HDC302X_HEATER_POWER_MAP = {
"QUARTER": 0x009F,
"HALF": 0x03FF,
"FULL": 0x3FFF,
}
def heater_power_value(value):
"""Accept enum names or raw uint16 values"""
if isinstance(value, cv.Lambda):
return value
if isinstance(value, str):
upper = value.upper()
if upper in HDC302X_HEATER_POWER_MAP:
return HDC302X_HEATER_POWER_MAP[upper]
raise cv.Invalid(
f"Unknown heater power preset: {value}. Use QUARTER, HALF, FULL, or a raw value 0-16383"
)
return cv.int_range(min=0, max=0x3FFF)(value)
HDC302X_ACTION_SCHEMA = maybe_simple_id({cv.GenerateID(): cv.use_id(HDC302XComponent)})
HDC302X_HEATER_ON_ACTION_SCHEMA = maybe_simple_id(
{
cv.GenerateID(): cv.use_id(HDC302XComponent),
cv.Optional(CONF_POWER, default="QUARTER"): cv.templatable(heater_power_value),
cv.Optional(CONF_DURATION, default="5s"): cv.templatable(
cv.positive_time_period_milliseconds
),
}
)
@automation.register_action(
"hdc302x.heater_on", HeaterOnAction, HDC302X_HEATER_ON_ACTION_SCHEMA
)
async def hdc302x_heater_on_to_code(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
template_ = await cg.templatable(config[CONF_POWER], args, cg.uint16)
cg.add(var.set_power(template_))
template_ = await cg.templatable(config[CONF_DURATION], args, cg.uint32)
cg.add(var.set_duration(template_))
return var
@automation.register_action(
"hdc302x.heater_off", HeaterOffAction, HDC302X_ACTION_SCHEMA
)
async def hdc302x_heater_off_to_code(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var

View File

@@ -35,10 +35,7 @@ uint8_t HONEYWELLABPSensor::readsensor_() {
pressure_count_ = ((uint16_t) (buf_[0]) << 8 & 0x3F00) | ((uint16_t) (buf_[1]) & 0xFF);
// 11 - bit temperature is all of byte 2 (lowest 8 bits) and the first three bits of byte 3
temperature_count_ = (((uint16_t) (buf_[2]) << 3) & 0x7F8) | (((uint16_t) (buf_[3]) >> 5) & 0x7);
ESP_LOGV(TAG,
"Sensor pressure_count_ %d\n"
"Sensor temperature_count_ %d",
pressure_count_, temperature_count_);
ESP_LOGV(TAG, "Sensor pressure_count_ %d, temperature_count_ %d", pressure_count_, temperature_count_);
}
return status_;
}

View File

@@ -330,38 +330,72 @@ class HttpRequestComponent : public Component {
void set_follow_redirects(bool follow_redirects) { this->follow_redirects_ = follow_redirects; }
void set_redirect_limit(uint16_t limit) { this->redirect_limit_ = limit; }
std::shared_ptr<HttpContainer> get(const std::string &url) { return this->start(url, "GET", "", {}); }
std::shared_ptr<HttpContainer> get(const std::string &url, const std::list<Header> &request_headers) {
std::shared_ptr<HttpContainer> get(const std::string &url) {
return this->start(url, "GET", "", std::vector<Header>{});
}
std::shared_ptr<HttpContainer> get(const std::string &url, const std::vector<Header> &request_headers) {
return this->start(url, "GET", "", request_headers);
}
std::shared_ptr<HttpContainer> get(const std::string &url, const std::list<Header> &request_headers,
std::shared_ptr<HttpContainer> get(const std::string &url, const std::vector<Header> &request_headers,
const std::vector<std::string> &lower_case_collect_headers) {
return this->start(url, "GET", "", request_headers, lower_case_collect_headers);
}
std::shared_ptr<HttpContainer> post(const std::string &url, const std::string &body) {
return this->start(url, "POST", body, {});
return this->start(url, "POST", body, std::vector<Header>{});
}
std::shared_ptr<HttpContainer> post(const std::string &url, const std::string &body,
const std::list<Header> &request_headers) {
const std::vector<Header> &request_headers) {
return this->start(url, "POST", body, request_headers);
}
std::shared_ptr<HttpContainer> post(const std::string &url, const std::string &body,
const std::list<Header> &request_headers,
const std::vector<Header> &request_headers,
const std::vector<std::string> &lower_case_collect_headers) {
return this->start(url, "POST", body, request_headers, lower_case_collect_headers);
}
// Remove before 2027.1.0
ESPDEPRECATED("Pass request_headers as std::vector<Header> instead of std::list. Removed in 2027.1.0.", "2026.7.0")
std::shared_ptr<HttpContainer> get(const std::string &url, const std::list<Header> &request_headers) {
return this->get(url, std::vector<Header>(request_headers.begin(), request_headers.end()));
}
// Remove before 2027.1.0
ESPDEPRECATED("Pass request_headers as std::vector<Header> instead of std::list. Removed in 2027.1.0.", "2026.7.0")
std::shared_ptr<HttpContainer> get(const std::string &url, const std::list<Header> &request_headers,
const std::vector<std::string> &collect_headers) {
return this->get(url, std::vector<Header>(request_headers.begin(), request_headers.end()), collect_headers);
}
// Remove before 2027.1.0
ESPDEPRECATED("Pass request_headers as std::vector<Header> instead of std::list. Removed in 2027.1.0.", "2026.7.0")
std::shared_ptr<HttpContainer> post(const std::string &url, const std::string &body,
const std::list<Header> &request_headers) {
return this->post(url, body, std::vector<Header>(request_headers.begin(), request_headers.end()));
}
// Remove before 2027.1.0
ESPDEPRECATED("Pass request_headers as std::vector<Header> instead of std::list. Removed in 2027.1.0.", "2026.7.0")
std::shared_ptr<HttpContainer> post(const std::string &url, const std::string &body,
const std::list<Header> &request_headers,
const std::vector<std::string> &collect_headers) {
return this->post(url, body, std::vector<Header>(request_headers.begin(), request_headers.end()), collect_headers);
}
std::shared_ptr<HttpContainer> start(const std::string &url, const std::string &method, const std::string &body,
const std::vector<Header> &request_headers) {
// Call perform() directly to avoid ambiguity with the deprecated overloads
return this->perform(url, method, body, request_headers, {});
}
// Remove before 2027.1.0
ESPDEPRECATED("Pass request_headers as std::vector<Header> instead of std::list. Removed in 2027.1.0.", "2026.7.0")
std::shared_ptr<HttpContainer> start(const std::string &url, const std::string &method, const std::string &body,
const std::list<Header> &request_headers) {
// Call perform() directly to avoid ambiguity with the std::set overload
return this->perform(url, method, body, request_headers, {});
return this->start(url, method, body, std::vector<Header>(request_headers.begin(), request_headers.end()));
}
// Remove before 2027.1.0
ESPDEPRECATED("Pass collect_headers as std::vector<std::string> instead of std::set. Removed in 2027.1.0.",
"2026.7.0")
std::shared_ptr<HttpContainer> start(const std::string &url, const std::string &method, const std::string &body,
const std::list<Header> &request_headers,
const std::vector<Header> &request_headers,
const std::set<std::string> &collect_headers) {
std::vector<std::string> lower;
lower.reserve(collect_headers.size());
@@ -371,15 +405,39 @@ class HttpRequestComponent : public Component {
return this->perform(url, method, body, request_headers, lower);
}
// Remove before 2027.1.0
ESPDEPRECATED("Pass request_headers as std::vector<Header> instead of std::list, and collect_headers as "
"std::vector<std::string> instead of std::set. Removed in 2027.1.0.",
"2026.7.0")
std::shared_ptr<HttpContainer> start(const std::string &url, const std::string &method, const std::string &body,
const std::list<Header> &request_headers,
const std::set<std::string> &collect_headers) {
std::vector<std::string> lower;
lower.reserve(collect_headers.size());
for (const auto &h : collect_headers) {
lower.push_back(str_lower_case(h));
}
return this->perform(url, method, body, std::vector<Header>(request_headers.begin(), request_headers.end()), lower);
}
// Remove before 2027.1.0
ESPDEPRECATED("Pass request_headers as std::vector<Header> instead of std::list. Removed in 2027.1.0.", "2026.7.0")
std::shared_ptr<HttpContainer> start(const std::string &url, const std::string &method, const std::string &body,
const std::list<Header> &request_headers,
const std::vector<std::string> &lower_case_collect_headers) {
return this->perform(url, method, body, std::vector<Header>(request_headers.begin(), request_headers.end()),
lower_case_collect_headers);
}
std::shared_ptr<HttpContainer> start(const std::string &url, const std::string &method, const std::string &body,
const std::vector<Header> &request_headers,
const std::vector<std::string> &lower_case_collect_headers) {
return this->perform(url, method, body, request_headers, lower_case_collect_headers);
}
protected:
virtual std::shared_ptr<HttpContainer> perform(const std::string &url, const std::string &method,
const std::string &body, const std::list<Header> &request_headers,
const std::string &body, const std::vector<Header> &request_headers,
const std::vector<std::string> &lower_case_collect_headers) = 0;
const char *useragent_{nullptr};
bool follow_redirects_{};
@@ -436,13 +494,10 @@ template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> {
auto f = std::bind(&HttpRequestSendAction<Ts...>::encode_json_func_, this, x..., std::placeholders::_1);
body = json::build_json(f);
}
std::list<Header> request_headers;
for (const auto &item : this->request_headers_) {
auto val = item.second;
Header header;
header.name = item.first;
header.value = val.value(x...);
request_headers.push_back(header);
std::vector<Header> request_headers;
request_headers.reserve(this->request_headers_.size());
for (const auto &[key, val] : this->request_headers_) {
request_headers.push_back({key, val.value(x...)});
}
auto container = this->parent_->start(this->url_.value(x...), this->method_.value(x...), body, request_headers,

View File

@@ -26,7 +26,7 @@ static constexpr int ESP8266_SSL_ERR_OOM = -1000;
std::shared_ptr<HttpContainer> HttpRequestArduino::perform(const std::string &url, const std::string &method,
const std::string &body,
const std::list<Header> &request_headers,
const std::vector<Header> &request_headers,
const std::vector<std::string> &lower_case_collect_headers) {
if (!network::is_connected()) {
this->status_momentary_error("failed", 1000);

View File

@@ -49,7 +49,7 @@ class HttpContainerArduino : public HttpContainer {
class HttpRequestArduino : public HttpRequestComponent {
protected:
std::shared_ptr<HttpContainer> perform(const std::string &url, const std::string &method, const std::string &body,
const std::list<Header> &request_headers,
const std::vector<Header> &request_headers,
const std::vector<std::string> &lower_case_collect_headers) override;
};

View File

@@ -18,7 +18,7 @@ static const char *const TAG = "http_request.host";
std::shared_ptr<HttpContainer> HttpRequestHost::perform(const std::string &url, const std::string &method,
const std::string &body,
const std::list<Header> &request_headers,
const std::vector<Header> &request_headers,
const std::vector<std::string> &lower_case_collect_headers) {
if (!network::is_connected()) {
this->status_momentary_error("failed", 1000);

View File

@@ -19,7 +19,7 @@ class HttpContainerHost : public HttpContainer {
class HttpRequestHost : public HttpRequestComponent {
public:
std::shared_ptr<HttpContainer> perform(const std::string &url, const std::string &method, const std::string &body,
const std::list<Header> &request_headers,
const std::vector<Header> &request_headers,
const std::vector<std::string> &lower_case_collect_headers) override;
void set_ca_path(const char *ca_path) { this->ca_path_ = ca_path; }

View File

@@ -54,7 +54,7 @@ esp_err_t HttpRequestIDF::http_event_handler(esp_http_client_event_t *evt) {
std::shared_ptr<HttpContainer> HttpRequestIDF::perform(const std::string &url, const std::string &method,
const std::string &body,
const std::list<Header> &request_headers,
const std::vector<Header> &request_headers,
const std::vector<std::string> &lower_case_collect_headers) {
if (!network::is_connected()) {
this->status_momentary_error("failed", 1000);

View File

@@ -37,7 +37,7 @@ class HttpRequestIDF : public HttpRequestComponent {
protected:
std::shared_ptr<HttpContainer> perform(const std::string &url, const std::string &method, const std::string &body,
const std::list<Header> &request_headers,
const std::vector<Header> &request_headers,
const std::vector<std::string> &lower_case_collect_headers) override;
// if zero ESP-IDF will use DEFAULT_HTTP_BUF_SIZE
uint16_t buffer_size_rx_{};

View File

@@ -105,8 +105,7 @@ uint8_t OtaHttpRequestComponent::do_ota_() {
// we will compute MD5 on the fly for verification -- Arduino OTA seems to ignore it
md5_receive.init();
ESP_LOGV(TAG, "MD5Digest initialized\n"
"OTA backend begin");
ESP_LOGV(TAG, "MD5Digest initialized, OTA backend begin");
auto backend = ota::make_ota_backend();
auto error_code = backend->begin(container->content_length);
if (error_code != ota::OTA_RESPONSE_OK) {

View File

@@ -24,8 +24,29 @@ namespace http_request {
static const char *const TAG = "http_request.update";
static const size_t MAX_READ_SIZE = 256;
static constexpr uint32_t INITIAL_CHECK_INTERVAL_ID = 0;
static constexpr uint32_t INITIAL_CHECK_INTERVAL_MS = 10000;
static constexpr uint8_t INITIAL_CHECK_MAX_ATTEMPTS = 6;
void HttpRequestUpdate::setup() { this->ota_parent_->add_state_listener(this); }
void HttpRequestUpdate::setup() {
this->ota_parent_->add_state_listener(this);
// Check periodically until network is ready
// Only if update interval is > total retry window to avoid redundant checks
if (this->get_update_interval() != SCHEDULER_DONT_RUN &&
this->get_update_interval() > INITIAL_CHECK_INTERVAL_MS * INITIAL_CHECK_MAX_ATTEMPTS) {
this->initial_check_remaining_ = INITIAL_CHECK_MAX_ATTEMPTS;
this->set_interval(INITIAL_CHECK_INTERVAL_ID, INITIAL_CHECK_INTERVAL_MS, [this]() {
bool connected = network::is_connected();
if (--this->initial_check_remaining_ == 0 || connected) {
this->cancel_interval(INITIAL_CHECK_INTERVAL_ID);
if (connected) {
this->update();
}
}
});
}
}
void HttpRequestUpdate::on_ota_state(ota::OTAState state, float progress, uint8_t error) {
if (state == ota::OTAState::OTA_IN_PROGRESS) {
@@ -45,6 +66,7 @@ void HttpRequestUpdate::update() {
ESP_LOGD(TAG, "Network not connected, skipping update check");
return;
}
this->cancel_interval(INITIAL_CHECK_INTERVAL_ID);
#ifdef USE_ESP32
xTaskCreate(HttpRequestUpdate::update_task, "update_task", 8192, (void *) this, 1, &this->update_task_handle_);
#else

View File

@@ -40,6 +40,7 @@ class HttpRequestUpdate final : public update::UpdateEntity, public PollingCompo
#ifdef USE_ESP32
TaskHandle_t update_task_handle_{nullptr};
#endif
uint8_t initial_check_remaining_{0};
};
} // namespace http_request

View File

@@ -7,7 +7,7 @@ namespace esphome {
namespace ili9xxx {
// clang-format off
static const uint8_t PROGMEM INITCMD_M5STACK[] = {
static constexpr uint8_t PROGMEM INITCMD_M5STACK[] = {
0xEF, 3, 0x03, 0x80, 0x02,
0xCF, 3, 0x00, 0xC1, 0x30,
0xED, 4, 0x64, 0x03, 0x12, 0x81,
@@ -37,7 +37,7 @@ static const uint8_t PROGMEM INITCMD_M5STACK[] = {
0x00 // End of list
};
static const uint8_t PROGMEM INITCMD_M5CORE[] = {
static constexpr uint8_t PROGMEM INITCMD_M5CORE[] = {
ILI9XXX_SETEXTC, 3, 0xFF,0x93,0x42, // Turn on the external command
ILI9XXX_PWCTR1 , 2, 0x12, 0x12,
ILI9XXX_PWCTR2 , 1, 0x03,
@@ -56,7 +56,7 @@ static const uint8_t PROGMEM INITCMD_M5CORE[] = {
static const uint8_t PROGMEM INITCMD_ILI9341[] = {
static constexpr uint8_t PROGMEM INITCMD_ILI9341[] = {
0xEF, 3, 0x03, 0x80, 0x02,
0xCF, 3, 0x00, 0xC1, 0x30,
0xED, 4, 0x64, 0x03, 0x12, 0x81,
@@ -86,7 +86,7 @@ static const uint8_t PROGMEM INITCMD_ILI9341[] = {
0x00 // End of list
};
static const uint8_t PROGMEM INITCMD_ILI9481[] = {
static constexpr uint8_t PROGMEM INITCMD_ILI9481[] = {
ILI9XXX_SLPOUT , 0x80, // Exit sleep mode
ILI9XXX_PWSET , 3, 0x07, 0x41, 0x1D,
ILI9XXX_VMCTR , 3, 0x00, 0x1C, 0x1F,
@@ -105,7 +105,7 @@ static const uint8_t PROGMEM INITCMD_ILI9481[] = {
0x00 // end
};
static const uint8_t PROGMEM INITCMD_ILI9481_18[] = {
static constexpr uint8_t PROGMEM INITCMD_ILI9481_18[] = {
ILI9XXX_SLPOUT , 0x80, // Exit sleep mode
ILI9XXX_PWSET , 3, 0x07, 0x41, 0x1D,
ILI9XXX_VMCTR , 3, 0x00, 0x1C, 0x1F,
@@ -124,7 +124,7 @@ static const uint8_t PROGMEM INITCMD_ILI9481_18[] = {
0x00 // end
};
static const uint8_t PROGMEM INITCMD_ILI9486[] = {
static constexpr uint8_t PROGMEM INITCMD_ILI9486[] = {
ILI9XXX_SLPOUT, 0x80,
ILI9XXX_PIXFMT, 1, 0x55,
ILI9XXX_PWCTR3, 1, 0x44,
@@ -173,7 +173,7 @@ static const uint8_t INITCMD_WAVESHARE_RES_3_5[] = {
0x00 // End of list
};
static const uint8_t PROGMEM INITCMD_ILI9488_A[] = {
static constexpr uint8_t PROGMEM INITCMD_ILI9488_A[] = {
ILI9XXX_GMCTRP1,15, 0x00, 0x03, 0x09, 0x08, 0x16, 0x0A, 0x3F, 0x78, 0x4C, 0x09, 0x0A, 0x08, 0x16, 0x1A, 0x0F,
ILI9XXX_GMCTRN1,15, 0x00, 0x16, 0x19, 0x03, 0x0F, 0x05, 0x32, 0x45, 0x46, 0x04, 0x0E, 0x0D, 0x35, 0x37, 0x0F,
@@ -206,7 +206,7 @@ static const uint8_t PROGMEM INITCMD_ILI9488_A[] = {
0x00 // end
};
static const uint8_t PROGMEM INITCMD_ST7796[] = {
static constexpr uint8_t PROGMEM INITCMD_ST7796[] = {
// This ST7796S initilization routine was copied from https://github.com/prenticedavid/Adafruit_ST7796S_kbv/blob/master/Adafruit_ST7796S_kbv.cpp
ILI9XXX_SWRESET, 0x80, // Soft reset, then delay 150 ms
ILI9XXX_CSCON, 1, 0xC3, // ?? Unlock Manufacturer
@@ -226,7 +226,7 @@ static const uint8_t PROGMEM INITCMD_ST7796[] = {
0x00 // End of list
};
static const uint8_t PROGMEM INITCMD_S3BOX[] = {
static constexpr uint8_t PROGMEM INITCMD_S3BOX[] = {
0xEF, 3, 0x03, 0x80, 0x02,
0xCF, 3, 0x00, 0xC1, 0x30,
0xED, 4, 0x64, 0x03, 0x12, 0x81,
@@ -256,7 +256,7 @@ static const uint8_t PROGMEM INITCMD_S3BOX[] = {
0x00 // End of list
};
static const uint8_t PROGMEM INITCMD_S3BOXLITE[] = {
static constexpr uint8_t PROGMEM INITCMD_S3BOXLITE[] = {
0xEF, 3, 0x03, 0x80, 0x02,
0xCF, 3, 0x00, 0xC1, 0x30,
0xED, 4, 0x64, 0x03, 0x12, 0x81,
@@ -286,7 +286,7 @@ static const uint8_t PROGMEM INITCMD_S3BOXLITE[] = {
0x00 // End of list
};
static const uint8_t PROGMEM INITCMD_ST7789V[] = {
static constexpr uint8_t PROGMEM INITCMD_ST7789V[] = {
ILI9XXX_SLPOUT , 0x80, // Exit Sleep
ILI9XXX_DISPON , 0x80, // Display on
ILI9XXX_MADCTL , 1, 0x08, // Memory Access Control, BGR
@@ -313,7 +313,7 @@ static const uint8_t PROGMEM INITCMD_ST7789V[] = {
0x00 // End of list
};
static const uint8_t PROGMEM INITCMD_GC9A01A[] = {
static constexpr uint8_t PROGMEM INITCMD_GC9A01A[] = {
0xEF, 0,
0xEB, 1, 0x14, // ?
0xFE, 0,
@@ -367,7 +367,7 @@ static const uint8_t PROGMEM INITCMD_GC9A01A[] = {
0x00 // End of list
};
static const uint8_t PROGMEM INITCMD_GC9D01N[] = {
static constexpr uint8_t PROGMEM INITCMD_GC9D01N[] = {
// Enable Inter_command
0xFE, 0, // Inter Register Enable 1 (FEh)
0xEF, 0, // Inter Register Enable 2 (EFh)
@@ -426,7 +426,7 @@ static const uint8_t PROGMEM INITCMD_GC9D01N[] = {
0x00 // End of list
};
static const uint8_t PROGMEM INITCMD_ST7735[] = {
static constexpr uint8_t PROGMEM INITCMD_ST7735[] = {
ILI9XXX_SWRESET, 0, // Soft reset, then delay 10ms
ILI9XXX_DELAY(10),
ILI9XXX_SLPOUT , 0, // Exit Sleep, delay

View File

@@ -362,10 +362,8 @@ bool INA2XX::configure_shunt_() {
ESP_LOGW(TAG, "Shunt value too high");
}
this->shunt_cal_ &= 0x7FFF;
ESP_LOGV(TAG,
"Given Rshunt=%f Ohm and Max_current=%.3f\n"
"New CURRENT_LSB=%f, SHUNT_CAL=%u",
this->shunt_resistance_ohm_, this->max_current_a_, this->current_lsb_, this->shunt_cal_);
ESP_LOGV(TAG, "Rshunt=%f Ohm, max current=%.3f A, current LSB=%f, shunt cal=%u", this->shunt_resistance_ohm_,
this->max_current_a_, this->current_lsb_, this->shunt_cal_);
return this->write_unsigned_16_(RegisterMap::REG_SHUNT_CAL, this->shunt_cal_);
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include <queue>
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/uart/uart.h"
#include "esphome/core/component.h"

View File

@@ -489,11 +489,8 @@ bool LD2410Component::handle_ack_data_() {
this->out_pin_level_ = this->buffer_data_[12];
const auto *light_function_str = find_str(LIGHT_FUNCTIONS_BY_UINT, this->light_function_);
const auto *out_pin_level_str = find_str(OUT_PIN_LEVELS_BY_UINT, this->out_pin_level_);
ESP_LOGV(TAG,
"Light function: %s\n"
"Light threshold: %u\n"
"Out pin level: %s",
light_function_str, this->light_threshold_, out_pin_level_str);
ESP_LOGV(TAG, "Light function: %s, threshold: %u, out pin level: %s", light_function_str, this->light_threshold_,
out_pin_level_str);
#ifdef USE_SELECT
if (this->light_function_select_ != nullptr) {
this->light_function_select_->publish_state(light_function_str);
@@ -608,8 +605,9 @@ void LD2410Component::readline_(int readch) {
// We should never get here, but just in case...
ESP_LOGW(TAG, "Max command length exceeded; ignoring");
this->buffer_pos_ = 0;
return;
}
if (this->buffer_pos_ < 4) {
if (this->buffer_pos_ < HEADER_FOOTER_SIZE) {
return; // Not enough data to process yet
}
if (ld2410::validate_header_footer(DATA_FRAME_FOOTER, &this->buffer_data_[this->buffer_pos_ - 4])) {

View File

@@ -33,8 +33,10 @@ namespace esphome::ld2410 {
using namespace ld24xx;
static constexpr uint8_t MAX_LINE_LENGTH = 46; // Max characters for serial buffer
static constexpr uint8_t TOTAL_GATES = 9; // Total number of gates supported by the LD2410
// Engineering data frame is 45 bytes; +1 for null terminator, +4 so that a frame footer always
// lands inside the buffer during footer-based resynchronization after losing sync.
static constexpr uint8_t MAX_LINE_LENGTH = 50;
static constexpr uint8_t TOTAL_GATES = 9; // Total number of gates supported by the LD2410
class LD2410Component : public Component, public uart::UARTDevice {
#ifdef USE_BINARY_SENSOR

View File

@@ -530,10 +530,7 @@ bool LD2412Component::handle_ack_data_() {
this->light_function_ = this->buffer_data_[10];
this->light_threshold_ = this->buffer_data_[11];
const auto *light_function_str = find_str(LIGHT_FUNCTIONS_BY_UINT, this->light_function_);
ESP_LOGV(TAG,
"Light function: %s\n"
"Light threshold: %u",
light_function_str, this->light_threshold_);
ESP_LOGV(TAG, "Light function: %s, threshold: %u", light_function_str, this->light_threshold_);
#ifdef USE_SELECT
if (this->light_function_select_ != nullptr) {
this->light_function_select_->publish_state(light_function_str);

View File

@@ -21,7 +21,9 @@
namespace esphome::ld2420 {
static constexpr uint8_t CALIBRATE_SAMPLES = 64;
static constexpr uint8_t MAX_LINE_LENGTH = 46; // Max characters for serial buffer
// Energy frame is 45 bytes; +1 for null terminator, +4 so that a frame footer always lands
// inside the buffer during footer-based resynchronization after losing sync.
static constexpr uint8_t MAX_LINE_LENGTH = 50;
static constexpr uint8_t TOTAL_GATES = 16;
enum OpMode : uint8_t {

View File

@@ -776,8 +776,9 @@ void LD2450Component::readline_(int readch) {
// We should never get here, but just in case...
ESP_LOGW(TAG, "Max command length exceeded; ignoring");
this->buffer_pos_ = 0;
return;
}
if (this->buffer_pos_ < 4) {
if (this->buffer_pos_ < HEADER_FOOTER_SIZE) {
return; // Not enough data to process yet
}
if (this->buffer_data_[this->buffer_pos_ - 2] == DATA_FRAME_FOOTER[0] &&

View File

@@ -1,5 +1,6 @@
#pragma once
#include "esphome/core/automation.h"
#include "esphome/core/defines.h"
#include "esphome/core/component.h"
#ifdef USE_SENSOR
@@ -37,9 +38,11 @@ using namespace ld24xx;
// Constants
static constexpr uint8_t DEFAULT_PRESENCE_TIMEOUT = 5; // Timeout to reset presense status 5 sec.
static constexpr uint8_t MAX_LINE_LENGTH = 41; // Max characters for serial buffer
static constexpr uint8_t MAX_TARGETS = 3; // Max 3 Targets in LD2450
static constexpr uint8_t MAX_ZONES = 3; // Max 3 Zones in LD2450
// Zone query response is 40 bytes; +1 for null terminator, +4 so that a frame footer always
// lands inside the buffer during footer-based resynchronization after losing sync.
static constexpr uint8_t MAX_LINE_LENGTH = 45;
static constexpr uint8_t MAX_TARGETS = 3; // Max 3 Targets in LD2450
static constexpr uint8_t MAX_ZONES = 3; // Max 3 Zones in LD2450
enum Direction : uint8_t {
DIRECTION_APPROACHING = 0,

View File

@@ -130,10 +130,8 @@ void LEDCOutput::setup() {
}
int hpoint = ledc_angle_to_htop(this->phase_angle_, this->bit_depth_);
ESP_LOGV(TAG,
"Configured frequency %f with a bit depth of %u bits\n"
"Angle of %.1f° results in hpoint %u",
this->frequency_, this->bit_depth_, this->phase_angle_, hpoint);
ESP_LOGV(TAG, "Configured frequency %f with bit depth %u, angle %.1f° hpoint %u", this->frequency_, this->bit_depth_,
this->phase_angle_, hpoint);
ledc_channel_config_t chan_conf{};
chan_conf.gpio_num = this->pin_->get_pin();

View File

@@ -275,6 +275,146 @@ BASE_SCHEMA.add_extra(_detect_variant)
BASE_SCHEMA.add_extra(_update_core_data)
def _configure_lwip(config: dict) -> None:
"""Configure lwIP options for LibreTiny platforms.
The BK/RTL/LN SDKs each ship different lwIP defaults. BK72XX defaults are
wildly oversized for ESPHome's IoT use case, causing OOM on BK7231N.
RTL87XX and LN882H have more conservative defaults but still need tuning
for ESPHome's socket usage patterns.
See https://github.com/esphome/esphome/issues/14095
Comparison of SDK defaults vs ESPHome targets (TCP_MSS=1460 on all LT):
Setting ESP8266 ESP32 BK SDK RTL SDK LN SDK New
────────────────────────────────────────────────────────────────────────────
TCP_SND_BUF 2×MSS 4×MSS 10×MSS 5×MSS 7×MSS 4×MSS
TCP_WND 4×MSS 4×MSS 3/10×MSS 2×MSS 3×MSS 4×MSS
MEM_LIBC_MALLOC 1 1 0 0 1 1
MEMP_MEM_MALLOC 1 1 0 0 0 1
MEM_SIZE N/A* N/A* 16/32KB 5KB N/A* N/A* BK
PBUF_POOL_SIZE 10 16 3/10 20 20 10 BK
MAX_SOCKETS_TCP 5 16 12 —** —** dynamic
MAX_SOCKETS_UDP 4 16 22 —** —** dynamic
TCP_SND_QUEUELEN ~8 17 20 20 35 17
MEMP_NUM_TCP_SEG 10 16 40 20 =qlen 17
MEMP_NUM_TCP_PCB 5 16 12 10 8 =TCP
MEMP_NUM_TCP_PCB_LISTEN 4 16 4 5 3 dynamic
MEMP_NUM_UDP_PCB 4 16 25*** 7**** 7**** =UDP
MEMP_NUM_NETCONN 0 10 38 4***** =sum =sum
MEMP_NUM_NETBUF 0 2 16 2***** 8 4
MEMP_NUM_TCPIP_MSG_INPKT 4 8 16 8***** 12 8
* ESP8266/ESP32/LN882H use MEM_LIBC_MALLOC=1 (system heap, no dedicated pool).
ESP8266/ESP32 also use MEMP_MEM_MALLOC=1 (MEMP pools from heap, not static).
** RTL/LN SDKs don't define MAX_SOCKETS_TCP/UDP (LibreTiny-specific).
*** BK LT overlay: MAX_SOCKETS_UDP+2+1 = 25.
**** RTL/LN LT overlay overrides to flat 7.
***** Not defined in RTL SDK — lwIP opt.h defaults shown.
"dynamic" = auto-calculated from component socket registrations via
socket.get_socket_counts() with minimums of 8 TCP / 6 UDP.
"""
from esphome.components.socket import (
MIN_TCP_LISTEN_SOCKETS,
MIN_TCP_SOCKETS,
MIN_UDP_SOCKETS,
get_socket_counts,
)
sc = get_socket_counts()
# Apply platform minimums — ensure headroom for ESPHome's needs
tcp_sockets = max(MIN_TCP_SOCKETS, sc.tcp)
udp_sockets = max(MIN_UDP_SOCKETS, sc.udp)
# Listening sockets — registered by components (api, ota, web_server_base, etc.)
# Not all components register yet, so ensure a minimum for baseline operation.
listening_tcp = max(MIN_TCP_LISTEN_SOCKETS, sc.tcp_listen)
# TCP_SND_BUF: ESPAsyncWebServer allocates malloc(tcp_sndbuf()) per
# response chunk. At 10×MSS=14.6KB (BK default) this causes OOM (#14095).
# 4×MSS=5,840 matches ESP32. RTL(5×) and LN(7×) are close already.
tcp_snd_buf = "(4*TCP_MSS)" # BK: 10×MSS, RTL: 5×MSS, LN: 7×MSS
# TCP_WND: receive window. 4×MSS matches ESP32.
# RTL SDK uses only 2×MSS; increasing to 4× is safe and improves throughput.
tcp_wnd = "(4*TCP_MSS)" # BK: 10×MSS, RTL: 2×MSS, LN: 3×MSS
# TCP_SND_QUEUELEN: max pbufs queued for send buffer
# ESP-IDF formula: (4 * TCP_SND_BUF + (TCP_MSS - 1)) / TCP_MSS
# With 4×MSS: (4*5840 + 1459) / 1460 = 17 — match ESP32
tcp_snd_queuelen = 17 # BK: 20, RTL: 20, LN: 35
# MEMP_NUM_TCP_SEG: segment pool, must be >= TCP_SND_QUEUELEN (lwIP sanity check)
memp_num_tcp_seg = tcp_snd_queuelen # BK: 40, RTL: 20, LN: =qlen
lwip_opts: list[str] = [
# Disable statistics — not needed for production, saves RAM
"LWIP_STATS=0", # BK: 1, RTL: 0 already, LN: 0 already
"MEM_STATS=0",
"MEMP_STATS=0",
# TCP send buffer — 4×MSS matches ESP32
f"TCP_SND_BUF={tcp_snd_buf}",
# TCP receive window — 4×MSS matches ESP32
f"TCP_WND={tcp_wnd}",
# Socket counts — auto-calculated from component registrations
f"MAX_SOCKETS_TCP={tcp_sockets}",
f"MAX_SOCKETS_UDP={udp_sockets}",
# Listening sockets — BK SDK uses this to derive MEMP_NUM_TCP_PCB_LISTEN;
# RTL/LN don't use it, but we set MEMP_NUM_TCP_PCB_LISTEN explicitly below.
f"MAX_LISTENING_SOCKETS_TCP={listening_tcp}",
# Queued segment limits — derived from 4×MSS buffer size
f"TCP_SND_QUEUELEN={tcp_snd_queuelen}",
f"MEMP_NUM_TCP_SEG={memp_num_tcp_seg}", # must be >= queuelen
# PCB pools — active connections + listening sockets
f"MEMP_NUM_TCP_PCB={tcp_sockets}", # BK: 12, RTL: 10, LN: 8
f"MEMP_NUM_TCP_PCB_LISTEN={listening_tcp}", # BK: =MAX_LISTENING, RTL: 5, LN: 3
# UDP PCB pool — includes wifi.lwip_internal (DHCP + DNS)
f"MEMP_NUM_UDP_PCB={udp_sockets}", # BK: 25, RTL/LN: 7 via LT
# Netconn pool — each socket (active + listening) needs a netconn
f"MEMP_NUM_NETCONN={tcp_sockets + udp_sockets + listening_tcp}",
# Netbuf pool
"MEMP_NUM_NETBUF=4", # BK: 16, RTL: 2 (opt.h), LN: 8
# Inbound message pool
"MEMP_NUM_TCPIP_MSG_INPKT=8", # BK: 16, RTL: 8 (opt.h), LN: 12
]
# Use system heap for all lwIP allocations on all LibreTiny platforms.
# - MEM_LIBC_MALLOC=1: Use system heap instead of dedicated lwIP heap.
# LN882H already ships with this. BK SDK defaults to a 16/32KB dedicated
# pool that fragments during OTA. RTL SDK defaults to a 5KB pool.
# All three SDKs wire malloc → pvPortMalloc (FreeRTOS thread-safe heap).
# - MEMP_MEM_MALLOC=1: Allocate MEMP pools from heap on demand instead
# of static arrays. Saves ~20KB RAM on BK72XX. Safe because WiFi
# receive paths run in task context, not ISR context. ESP32 and ESP8266
# both ship with MEMP_MEM_MALLOC=1.
lwip_opts.append("MEM_LIBC_MALLOC=1")
lwip_opts.append("MEMP_MEM_MALLOC=1")
# BK72XX-specific: PBUF_POOL_SIZE override
# BK SDK "reduced plan" sets this to only 3 — too few for multiple
# concurrent connections (API + web_server + OTA). BK default plan
# uses 10; match that. RTL(20) and LN(20) need no override.
# With MEMP_MEM_MALLOC=1, this is a max count (allocated on demand).
if CORE.is_bk72xx:
lwip_opts.append("PBUF_POOL_SIZE=10")
tcp_min = " (min)" if tcp_sockets > sc.tcp else ""
udp_min = " (min)" if udp_sockets > sc.udp else ""
listen_min = " (min)" if listening_tcp > sc.tcp_listen else ""
_LOGGER.info(
"Configuring lwIP: TCP=%d%s [%s], UDP=%d%s [%s], TCP_LISTEN=%d%s [%s]",
tcp_sockets,
tcp_min,
sc.tcp_details,
udp_sockets,
udp_min,
sc.udp_details,
listening_tcp,
listen_min,
sc.tcp_listen_details,
)
cg.add_platformio_option("custom_options.lwip", lwip_opts)
# pylint: disable=use-dict-literal
async def component_to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
@@ -389,11 +529,12 @@ async def component_to_code(config):
"custom_options.sys_config#h", _BK7231N_SYS_CONFIG_OPTIONS
)
# Disable LWIP statistics to save RAM - not needed in production
# Must explicitly disable all sub-stats to avoid redefinition warnings
cg.add_platformio_option(
"custom_options.lwip",
["LWIP_STATS=0", "MEM_STATS=0", "MEMP_STATS=0"],
)
# Tune lwIP for ESPHome's actual needs.
# The SDK defaults (TCP_SND_BUF=10*MSS, MAX_SOCKETS_TCP=12, MEM_SIZE=32KB)
# are wildly oversized for an IoT device. ESPAsyncWebServer allocates
# malloc(tcp_sndbuf()) per response chunk — at 14.6KB this causes silent
# OOM on memory-constrained chips like BK7231N.
# See https://github.com/esphome/esphome/issues/14095
_configure_lwip(config)
await cg.register_component(var, config)

View File

@@ -101,6 +101,8 @@ CONF_INITIAL_LEVEL = "initial_level"
CONF_LOGGER_ID = "logger_id"
CONF_RUNTIME_TAG_LEVELS = "runtime_tag_levels"
CONF_TASK_LOG_BUFFER_SIZE = "task_log_buffer_size"
CONF_WAIT_FOR_CDC = "wait_for_cdc"
CONF_EARLY_MESSAGE = "early_message"
UART_SELECTION_ESP32 = {
VARIANT_ESP32: [UART0, UART1, UART2],
@@ -208,6 +210,12 @@ def validate_initial_no_higher_than_global(config):
return config
def validate_wait_for_cdc(config):
if config.get(CONF_WAIT_FOR_CDC) and config.get(CONF_HARDWARE_UART) != USB_CDC:
raise cv.Invalid("wait_for_cdc requires hardware_uart: USB_CDC")
return config
Logger = logger_ns.class_("Logger", cg.Component)
LoggerMessageTrigger = logger_ns.class_(
"LoggerMessageTrigger",
@@ -300,10 +308,18 @@ CONFIG_SCHEMA = cv.All(
cv.SplitDefault(
CONF_ESP8266_STORE_LOG_STRINGS_IN_FLASH, esp8266=True
): cv.All(cv.only_on_esp8266, cv.boolean),
cv.SplitDefault(CONF_WAIT_FOR_CDC, nrf52=False): cv.All(
cv.only_on(PLATFORM_NRF52),
cv.boolean,
),
cv.SplitDefault(CONF_EARLY_MESSAGE, nrf52=False): cv.All(
cv.only_on(PLATFORM_NRF52), cv.boolean
),
}
).extend(cv.COMPONENT_SCHEMA),
validate_local_no_higher_than_global,
validate_initial_no_higher_than_global,
validate_wait_for_cdc,
)
@@ -313,10 +329,11 @@ async def to_code(config):
level = config[CONF_LEVEL]
CORE.data.setdefault(CONF_LOGGER, {})[CONF_LEVEL] = level
initial_level = LOG_LEVELS[config.get(CONF_INITIAL_LEVEL, level)]
tx_buffer_size = config[CONF_TX_BUFFER_SIZE]
cg.add_define("ESPHOME_LOGGER_TX_BUFFER_SIZE", tx_buffer_size)
log = cg.new_Pvariable(
config[CONF_ID],
baud_rate,
config[CONF_TX_BUFFER_SIZE],
)
if CORE.is_esp32:
cg.add(log.create_pthread_key())
@@ -425,13 +442,21 @@ async def to_code(config):
except cv.Invalid:
pass
if config.get(CONF_WAIT_FOR_CDC):
cg.add_define("USE_LOGGER_WAIT_FOR_CDC")
if config.get(CONF_EARLY_MESSAGE):
cg.add_define("USE_LOGGER_EARLY_MESSAGE")
if CORE.is_nrf52:
# esphome implement own fatal error handler which save PC/LR before reset
zephyr_add_prj_conf("RESET_ON_FATAL_ERROR", False)
zephyr_add_prj_conf("THREAD_LOCAL_STORAGE", True)
if config[CONF_HARDWARE_UART] == UART0:
zephyr_add_overlay("""&uart0 { status = "okay";};""")
if config[CONF_HARDWARE_UART] == UART1:
zephyr_add_overlay("""&uart1 { status = "okay";};""")
if config[CONF_HARDWARE_UART] == USB_CDC:
cg.add_define("USE_LOGGER_UART_SELECTION_USB_CDC")
zephyr_add_prj_conf("UART_LINE_CTRL", True)
zephyr_add_cdc_acm(config, 0)

View File

@@ -75,18 +75,13 @@ struct LogBuffer {
*p++ = ':';
// Format line number without modulo operations
// Format line number using subtraction loops (no division - important for ESP8266 which lacks hardware divider)
if (line > 999) [[unlikely]] {
int thousands = line / 1000;
*p++ = '0' + thousands;
line -= thousands * 1000;
write_digit(p, line, 1000);
}
int hundreds = line / 100;
int remainder = line - hundreds * 100;
int tens = remainder / 10;
*p++ = '0' + hundreds;
*p++ = '0' + tens;
*p++ = '0' + (remainder - tens * 10);
write_digit(p, line, 100);
write_digit(p, line, 10);
*p++ = '0' + line;
*p++ = ']';
#if defined(USE_ESP32) || defined(USE_LIBRETINY) || defined(USE_ZEPHYR) || defined(USE_HOST)
@@ -162,6 +157,15 @@ struct LogBuffer {
this->process_vsnprintf_result_(vsnprintf_P(this->current_(), this->remaining_(), format, args));
}
#endif
// Extract one decimal digit via subtraction (no division - important for ESP8266)
static inline void ESPHOME_ALWAYS_INLINE write_digit(char *&p, int &value, int divisor) {
char d = '0';
while (value >= divisor) {
d++;
value -= divisor;
}
*p++ = d;
}
// Write ANSI color escape sequence to buffer, updates pointer in place
// Caller is responsible for ensuring buffer has sufficient space
void write_ansi_color_(char *&p, uint8_t level) {

Some files were not shown because too many files have changed in this diff Show More