Compare commits

...
Author SHA1 Message Date
J. Nick Koston 836396cbc8 [packet_interface] Use the new codegen and runtime helpers 2026-10-21 14:55:49 -10:00
J. Nick Koston defc2d6bf4 Merge remote-tracking branch 'origin/dev' into s2/clydebarrow/packet-interface-01 2026-10-21 14:39:56 -10:00
Jesse Hills 7133d02d4c [core] Remove dead generated_files logic from copy_src_tree (#21312) 2026-10-22 11:52:03 +13:00
J. Nick Koston e2d261e744 [web_server] Read flash state strings PROGMEM-aware on ESP8266 (#21316) 2026-10-21 12:06:44 -10:00
Darafei PraliaskouskiandJ. Nick Koston 6e054555ac [const][heatpumpir][mitsubishi] Move horizontal_default/vertical_default to shared constants (#21309)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-10-21 21:47:22 +00:00
esphome[bot] 4fd3e41ee7 Bump aioesphomeapi from 46.15.1 to 46.16.0 (#21311) 2026-10-21 21:47:16 +00:00
J. Nick Koston 4280ac9659 [core] Move the remaining components to flash-safe entity names and deprecate get_name() (#20615) 2026-10-22 10:07:14 +13:00
J. Nick Kostonandpre-commit-ci-lite[bot] 211dcfa325 [core] Keep entity names in flash on ESP8266 (#20423)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2026-10-22 10:07:14 +13:00
c74a9da996 [veml6040] Add VEML6040 RGBW colour sensor (#20812)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-10-21 10:54:25 -10:00
Jonathan Swoboda b67ac5d0be [esp32_hosted] Keep the OTA watchdog timeout through the coprocessor end call (#21300) 2026-10-21 16:41:28 -04:00
9c4edc767b [core] Update paho-mqtt to v2.1.0 (#18402)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-10-21 10:30:55 -10:00
esphome[bot] 04432d3fd7 Bump aioesphomeapi from 46.14.0 to 46.15.1 (#21298) 2026-10-21 20:23:00 +00:00
J. Nick Koston 63b610bf17 [tests] Wait for the ld2410 query ACK log line instead of asserting it arrived (#21191) 2026-10-21 10:13:22 -10:00
J. Nick Koston 62c9e05541 [tests] Wait for the template sensor's first reading before the Home Assistant service tests (#21302) 2026-10-21 09:56:20 -10:00
esphome[bot] 671ac3e0bc Bump bundled esphome-device-builder to 1.26.0 (#21299) 2026-10-21 09:45:18 -10:00
dependabot[bot] 6671ded245 Bump platformdirs from 4.13.3 to 4.13.4 (#21297)
Signed-off-by: dependabot[bot] <support@github.com>
2026-10-21 19:32:36 +00:00
dependabot[bot] 9010c4bb2e Bump filelock from 4.2.1 to 4.2.2 (#21295)
Signed-off-by: dependabot[bot] <support@github.com>
2026-10-21 19:32:16 +00:00
J. Nick Koston e0a48ff683 [waveshare_epaper] Set removal of the deprecated component for 2027.5.0 (#20692) 2026-10-21 19:06:38 +00:00
e3d7b957a7 [mqtt] increase TLS options and compatibility (#14318)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-10-21 19:02:31 +00:00
J. Nick Koston 9ab230f98d [speaker] Build the pipeline task names on the stack (#21203) 2026-10-21 08:41:59 -10:00
clydebarrowandClaude Opus 5.5 982eda4bab [packet_interface] Use the shared max_packet_size constant
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:40:26 +11:00
clydebarrowandClaude Code fd78282aa2 [packet_interface] Set the packet size when a link is constructed
max_packet_size was a default with a setter that code generation called
after construction, so it could be raised above the size of a link's
buffer. It is now a constructor parameter, and a link with a fixed buffer
takes the buffer as a std::span, so its size is the link's limit and the
two cannot differ.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-19 14:40:08 +11:00
clydebarrowandClaude Opus 5.5 ed6c54efcb [uart] Limit a received packet to the receive buffer
The receive buffer is sized by code generation to max_packet_size, but
set_max_packet_size() can raise the limit afterwards, and the received
bytes would then overflow the buffer. The link now takes the buffer as a
span and stops at its size too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:40:08 +11:00
clydebarrowandClaude Opus 5.5 333090f803 [packet_interface] Keep App alive across the bridge tests
The test main constructs App once, and later tests and its listener use
it, so the fixture now replaces App in SetUp and constructs it again in
TearDown, instead of constructing over a live App and leaving it
destroyed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:40:08 +11:00
clydebarrowandClaude Opus 5.5 627a418d88 [core] Join list entries from several unit test benchmark.yaml files
Each test directory's benchmark.yaml was merged by top-level key, keeping
the first value, so when several directories added entries to one
platform component only the first directory's survived. In a combined
run the UDP link was then left out of the build and its test failed to
compile. Lists are now joined.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:40:08 +11:00
clydebarrowandClaude Opus 5.5 14ba5b9c5f [packet_interface] Test the packet_transport bridge
A fake link with a layer stacked on it checks that the bridge sends
through the top of the stack, passes a packet in one buffer to
packet_transport, and drops a packet split across buffers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:40:08 +11:00
clydebarrowandClaude Opus 5.5 726c30dccd [packet_interface] Remove PacketBuffer::to_vector()
It allocated a vector for each call, which invites heap churn. Only the
tests used it; they now have a local helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:40:08 +11:00
clydebarrowandClaude Opus 5.5 574e9f4687 [packet_interface] Keep the UART receive buffer in static memory, fix clang-tidy
- Code generation declares the UART link's receive buffer as a static
  array of max_packet_size bytes, so it is not allocated at run time
- Move the increment out of the condition in note_received_()
- Initialise the UART transmit copy buffer

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:40:08 +11:00
clydebarrow bfb4b3ddfe Remove redundant include and property 2026-10-19 14:40:08 +11:00
clydebarrow cedafa5208 Fixes from code review 2026-10-19 14:40:08 +11:00
clydebarrowandClaude Opus 5.5 95f972d3c5 [packet_interface] Add packet interface component
A packet interface moves packets over a channel, with a uart link and a
packet_transport platform that uses any packet interface. Later layers
stack on the same base class.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:40:08 +11:00
200 changed files with 3243 additions and 750 deletions
+4
View File
@@ -458,6 +458,8 @@ esphome/components/openthread/* @mrene
esphome/components/opt3001/* @ccutrer
esphome/components/ota/* @esphome/core
esphome/components/output/* @esphome/core
esphome/components/packet_interface/* @clydebarrow
esphome/components/packet_interface/packet_transport/* @clydebarrow
esphome/components/packet_transport/* @clydebarrow
esphome/components/pca6416a/* @Mat931
esphome/components/pca9505/* @ajfriesen @ssieb
@@ -677,6 +679,7 @@ esphome/components/tuya/water_heater/* @iago-veiga
esphome/components/uart/* @esphome/core
esphome/components/uart/button/* @ssieb
esphome/components/uart/event/* @eoasmxd
esphome/components/uart/packet_interface/* @clydebarrow
esphome/components/uart/packet_transport/* @clydebarrow
esphome/components/uart_mux/* @kbx81
esphome/components/uart_tcp/* @Bascht74
@@ -695,6 +698,7 @@ esphome/components/usb_uart/* @clydebarrow
esphome/components/valve/* @esphome/core
esphome/components/vbus/* @ssieb
esphome/components/veml3235/* @kbx81
esphome/components/veml6040/* @aalaei
esphome/components/veml7700/* @latonita
esphome/components/version/* @esphome/core
esphome/components/vevor_dtx/* @Bofr5555
+1 -1
View File
@@ -22,7 +22,7 @@ RUN \
-r /requirements.txt
# Install the ESPHome Device Builder dashboard.
RUN uv pip install --no-cache-dir esphome-device-builder==1.25.0
RUN uv pip install --no-cache-dir esphome-device-builder==1.26.0
RUN \
platformio settings set enable_telemetry No \
@@ -10,7 +10,7 @@ void AbsoluteHumidityComponent::setup() {
this->temperature_ = state;
this->enable_loop();
});
ESP_LOGD(TAG, " Added callback for temperature '%s'", this->temperature_sensor_->get_name().c_str());
ESP_LOGD(TAG, " Added callback for temperature '%s'", LOG_STR_ARG(this->temperature_sensor_->get_log_name()));
// Get initial value
if (this->temperature_sensor_->has_state()) {
this->temperature_ = this->temperature_sensor_->get_state();
@@ -20,7 +20,7 @@ void AbsoluteHumidityComponent::setup() {
this->humidity_ = state;
this->enable_loop();
});
ESP_LOGD(TAG, " Added callback for relative humidity '%s'", this->humidity_sensor_->get_name().c_str());
ESP_LOGD(TAG, " Added callback for relative humidity '%s'", LOG_STR_ARG(this->humidity_sensor_->get_log_name()));
// Get initial value
if (this->humidity_sensor_->has_state()) {
this->humidity_ = this->humidity_sensor_->get_state();
@@ -49,7 +49,8 @@ void AbsoluteHumidityComponent::dump_config() {
"Sources\n"
" Temperature: '%s'\n"
" Relative Humidity: '%s'",
this->temperature_sensor_->get_name().c_str(), this->humidity_sensor_->get_name().c_str());
LOG_STR_ARG(this->temperature_sensor_->get_log_name()),
LOG_STR_ARG(this->humidity_sensor_->get_log_name()));
}
void AbsoluteHumidityComponent::loop() {
+1 -1
View File
@@ -66,7 +66,7 @@ template class Aggregator<uint32_t>;
void ADCSensor::update() {
float value_v = this->sample();
ESP_LOGV(TAG, "'%s': Voltage=%.4fV", this->get_name().c_str(), value_v);
ESP_LOGV(TAG, "'%s': Voltage=%.4fV", LOG_STR_ARG(this->get_log_name()), value_v);
this->publish_state(value_v);
}
@@ -13,7 +13,7 @@ float ADS1115Sensor::sample() {
void ADS1115Sensor::update() {
float v = this->sample();
if (!std::isnan(v)) {
ESP_LOGD(TAG, "'%s': Got Voltage=%fV", this->get_name().c_str(), v);
ESP_LOGD(TAG, "'%s': Got Voltage=%fV", LOG_STR_ARG(this->get_log_name()), v);
this->publish_state(v);
}
}
@@ -21,7 +21,7 @@ float ADS1118Sensor::sample() {
void ADS1118Sensor::update() {
float v = this->sample();
if (!std::isnan(v)) {
ESP_LOGD(TAG, "'%s': Got Voltage=%fV", this->get_name().c_str(), v);
ESP_LOGD(TAG, "'%s': Got Voltage=%fV", LOG_STR_ARG(this->get_log_name()), v);
this->publish_state(v);
}
}
@@ -31,7 +31,7 @@ void AlarmControlPanel::publish_state(AlarmControlPanelState state) {
this->last_update_ = millis();
if (state != this->current_state_) {
auto prev_state = this->current_state_;
ESP_LOGV(TAG, "'%s' >> %s (was %s)", this->get_name().c_str(),
ESP_LOGV(TAG, "'%s' >> %s (was %s)", LOG_STR_ARG(this->get_log_name()),
LOG_STR_ARG(alarm_control_panel_state_to_string(state)),
LOG_STR_ARG(alarm_control_panel_state_to_string(prev_state)));
this->current_state_ = state;
+16 -13
View File
@@ -30,9 +30,9 @@ void Am43Component::loop() {
auto status =
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_,
packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
ESP_LOGI(TAG, "[%s] Logging into AM43", this->get_name().c_str());
ESP_LOGI(TAG, "[%s] Logging into AM43", LOG_STR_ARG(this->get_log_name()));
if (status) {
ESP_LOGW(TAG, "[%s] Error writing set_pin to device, error = %d", this->get_name().c_str(), status);
ESP_LOGW(TAG, "[%s] Error writing set_pin to device, error = %d", LOG_STR_ARG(this->get_log_name()), status);
} else {
this->logged_in_ = true;
}
@@ -50,7 +50,7 @@ CoverTraits Am43Component::get_traits() {
void Am43Component::control(const CoverCall &call) {
if (this->node_state != espbt::ClientState::ESTABLISHED) {
ESP_LOGW(TAG, "[%s] Cannot send cover control, not connected", this->get_name().c_str());
ESP_LOGW(TAG, "[%s] Cannot send cover control, not connected", LOG_STR_ARG(this->get_log_name()));
return;
}
if (call.get_stop()) {
@@ -59,7 +59,7 @@ void Am43Component::control(const CoverCall &call) {
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_,
packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
if (status) {
ESP_LOGW(TAG, "[%s] Error writing stop command to device, error = %d", this->get_name().c_str(), status);
ESP_LOGW(TAG, "[%s] Error writing stop command to device, error = %d", LOG_STR_ARG(this->get_log_name()), status);
}
}
auto opt_pos = call.get_position();
@@ -73,7 +73,8 @@ void Am43Component::control(const CoverCall &call) {
esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_,
packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
if (status) {
ESP_LOGW(TAG, "[%s] Error writing set_position command to device, error = %d", this->get_name().c_str(), status);
ESP_LOGW(TAG, "[%s] Error writing set_position command to device, error = %d", LOG_STR_ARG(this->get_log_name()),
status);
}
}
}
@@ -89,9 +90,9 @@ void Am43Component::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
auto *chr = this->parent_->get_characteristic(AM43_SERVICE_UUID, AM43_CHARACTERISTIC_UUID);
if (chr == nullptr) {
if (this->parent_->get_characteristic(AM43_TUYA_SERVICE_UUID, AM43_TUYA_CHARACTERISTIC_UUID) != nullptr) {
ESP_LOGE(TAG, "[%s] Detected a Tuya AM43 which is not supported, sorry.", this->get_name().c_str());
ESP_LOGE(TAG, "[%s] Detected a Tuya AM43 which is not supported, sorry.", LOG_STR_ARG(this->get_log_name()));
} else {
ESP_LOGE(TAG, "[%s] No control service found at device, not an AM43..?", this->get_name().c_str());
ESP_LOGE(TAG, "[%s] No control service found at device, not an AM43..?", LOG_STR_ARG(this->get_log_name()));
}
break;
}
@@ -100,7 +101,8 @@ void Am43Component::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
auto status = esp_ble_gattc_register_for_notify(this->parent_->get_gattc_if(), this->parent_->get_remote_bda(),
chr->handle);
if (status) {
ESP_LOGW(TAG, "[%s] esp_ble_gattc_register_for_notify failed, status=%d", this->get_name().c_str(), status);
ESP_LOGW(TAG, "[%s] esp_ble_gattc_register_for_notify failed, status=%d", LOG_STR_ARG(this->get_log_name()),
status);
}
break;
}
@@ -126,25 +128,26 @@ void Am43Component::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
if (this->decoder_->has_pin_response()) {
if (this->decoder_->pin_ok_) {
ESP_LOGI(TAG, "[%s] AM43 pin accepted.", this->get_name().c_str());
ESP_LOGI(TAG, "[%s] AM43 pin accepted.", LOG_STR_ARG(this->get_log_name()));
auto *packet = this->encoder_->get_position_request();
auto status = esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(),
this->char_handle_, packet->length, packet->data,
ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
if (status) {
ESP_LOGW(TAG, "[%s] Error writing set_position to device, error = %d", this->get_name().c_str(), status);
ESP_LOGW(TAG, "[%s] Error writing set_position to device, error = %d", LOG_STR_ARG(this->get_log_name()),
status);
}
} else {
ESP_LOGW(TAG, "[%s] AM43 pin rejected!", this->get_name().c_str());
ESP_LOGW(TAG, "[%s] AM43 pin rejected!", LOG_STR_ARG(this->get_log_name()));
}
}
if (this->decoder_->has_set_position_response() && !this->decoder_->set_position_ok_) {
ESP_LOGW(TAG, "[%s] Got nack after sending set_position. Bad pin?", this->get_name().c_str());
ESP_LOGW(TAG, "[%s] Got nack after sending set_position. Bad pin?", LOG_STR_ARG(this->get_log_name()));
}
if (this->decoder_->has_set_state_response() && !this->decoder_->set_state_ok_) {
ESP_LOGW(TAG, "[%s] Got nack after sending set_state. Bad pin?", this->get_name().c_str());
ESP_LOGW(TAG, "[%s] Got nack after sending set_state. Bad pin?", LOG_STR_ARG(this->get_log_name()));
}
break;
}
+5 -3
View File
@@ -67,8 +67,9 @@ 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..?", this->get_name().c_str());
ESP_LOGW(TAG, "[%s] Note, this component does not currently support Anova Nano.", this->get_name().c_str());
ESP_LOGW(TAG, "[%s] No control service found at device, not an Anova..?", LOG_STR_ARG(this->get_log_name()));
ESP_LOGW(TAG, "[%s] Note, this component does not currently support Anova Nano.",
LOG_STR_ARG(this->get_log_name()));
break;
}
this->char_handle_ = chr->handle;
@@ -76,7 +77,8 @@ void Anova::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_
auto status = esp_ble_gattc_register_for_notify(this->parent_->get_gattc_if(), this->parent_->get_remote_bda(),
chr->handle);
if (status) {
ESP_LOGW(TAG, "[%s] esp_ble_gattc_register_for_notify failed, status=%d", this->get_name().c_str(), status);
ESP_LOGW(TAG, "[%s] esp_ble_gattc_register_for_notify failed, status=%d", LOG_STR_ARG(this->get_log_name()),
status);
}
break;
}
+26 -26
View File
@@ -555,7 +555,7 @@ message ListEntitiesBinarySensorResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string device_class = 5 [(max_data_length) = 47];
@@ -589,7 +589,7 @@ message ListEntitiesCoverResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
bool assumed_state = 5;
@@ -673,7 +673,7 @@ message ListEntitiesFanResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
bool supports_oscillation = 5;
@@ -761,7 +761,7 @@ message ListEntitiesLightResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
repeated ColorMode supported_color_modes = 12 [(container_pointer_no_template) = "light::ColorModeMask"];
@@ -866,7 +866,7 @@ message ListEntitiesSensorResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
@@ -907,7 +907,7 @@ message ListEntitiesSwitchResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
@@ -952,7 +952,7 @@ message ListEntitiesTextSensorResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
@@ -1223,7 +1223,7 @@ message ListEntitiesCameraResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
bool disabled_by_default = 5;
string icon = 6 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
@@ -1315,7 +1315,7 @@ message ListEntitiesClimateResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
bool supports_current_temperature = 5; // Deprecated: use feature_flags
@@ -1430,7 +1430,7 @@ message ListEntitiesWaterHeaterResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
string icon = 4 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 5;
EntityCategory entity_category = 6;
@@ -1510,7 +1510,7 @@ message ListEntitiesNumberResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
@@ -1559,7 +1559,7 @@ message ListEntitiesSelectResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
@@ -1603,7 +1603,7 @@ message ListEntitiesSirenResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
@@ -1668,7 +1668,7 @@ message ListEntitiesLockResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
@@ -1717,7 +1717,7 @@ message ListEntitiesButtonResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
@@ -1784,7 +1784,7 @@ message ListEntitiesMediaPlayerResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
@@ -2376,7 +2376,7 @@ message ListEntitiesAlarmControlPanelResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 6;
@@ -2423,7 +2423,7 @@ message ListEntitiesTextResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 6;
@@ -2471,7 +2471,7 @@ message ListEntitiesDateResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
@@ -2518,7 +2518,7 @@ message ListEntitiesTimeResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
@@ -2565,7 +2565,7 @@ message ListEntitiesEventResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
@@ -2596,7 +2596,7 @@ message ListEntitiesValveResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
@@ -2651,7 +2651,7 @@ message ListEntitiesDateTimeResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
@@ -2694,7 +2694,7 @@ message ListEntitiesUpdateResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
reserved 4; // Deprecated: was string unique_id
string icon = 5 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
@@ -2794,7 +2794,7 @@ message ListEntitiesInfraredResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
string icon = 4 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 5;
EntityCategory entity_category = 6;
@@ -2863,7 +2863,7 @@ message ListEntitiesRadioFrequencyResponse {
string object_id = 1 [(max_data_length) = 120, (force) = true];
fixed32 key = 2 [(force) = true];
string name = 3 [(max_data_length) = 120, (force) = true];
string name = 3 [(max_data_length) = 120, (force) = true, (progmem) = true];
string icon = 4 [(field_ifdef) = "USE_ENTITY_ICON", (max_data_length) = 63];
bool disabled_by_default = 5;
EntityCategory entity_category = 6;
+1 -1
View File
@@ -485,7 +485,7 @@ uint16_t APIConnection::fill_and_encode_entity_info(EntityBase *entity, InfoResp
msg.key = entity->get_object_id_hash();
if (entity->has_own_name()) {
msg.name = entity->get_name();
msg.name = entity->get_name_progmem();
}
// Set common EntityBase properties
+26 -26
View File
@@ -403,7 +403,7 @@ uint8_t *ListEntitiesBinarySensorResponse::encode_msg(const void *self,
const auto &msg = *static_cast<const ListEntitiesBinarySensorResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.device_class);
pos = ProtoEncode::encode_bool(pos PROTO_ENCODE_DEBUG_ARG, 6, msg.is_status_binary_sensor);
pos = ProtoEncode::encode_bool(pos PROTO_ENCODE_DEBUG_ARG, 7, msg.disabled_by_default);
@@ -461,7 +461,7 @@ uint8_t *ListEntitiesCoverResponse::encode_msg(const void *self, uint8_t *__rest
const auto &msg = *static_cast<const ListEntitiesCoverResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_bool(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.assumed_state);
pos = ProtoEncode::encode_bool(pos PROTO_ENCODE_DEBUG_ARG, 6, msg.supports_position);
pos = ProtoEncode::encode_bool(pos PROTO_ENCODE_DEBUG_ARG, 7, msg.supports_tilt);
@@ -560,7 +560,7 @@ uint8_t *ListEntitiesFanResponse::encode_msg(const void *self, uint8_t *__restri
const auto &msg = *static_cast<const ListEntitiesFanResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_bool(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.supports_oscillation);
pos = ProtoEncode::encode_bool(pos PROTO_ENCODE_DEBUG_ARG, 6, msg.supports_speed);
pos = ProtoEncode::encode_bool(pos PROTO_ENCODE_DEBUG_ARG, 7, msg.supports_direction);
@@ -680,7 +680,7 @@ uint8_t *ListEntitiesLightResponse::encode_msg(const void *self, uint8_t *__rest
const auto &msg = *static_cast<const ListEntitiesLightResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
for (const auto &it : *msg.supported_color_modes) {
pos = ProtoEncode::encode_uint32_force(pos PROTO_ENCODE_DEBUG_ARG, 12, static_cast<uint32_t>(it));
}
@@ -886,7 +886,7 @@ uint8_t *ListEntitiesSensorResponse::encode_msg(const void *self, uint8_t *__res
const auto &msg = *static_cast<const ListEntitiesSensorResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.icon);
#endif
@@ -954,7 +954,7 @@ uint8_t *ListEntitiesSwitchResponse::encode_msg(const void *self, uint8_t *__res
const auto &msg = *static_cast<const ListEntitiesSwitchResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.icon);
#endif
@@ -1030,7 +1030,7 @@ uint8_t *ListEntitiesTextSensorResponse::encode_msg(const void *self,
const auto &msg = *static_cast<const ListEntitiesTextSensorResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.icon);
#endif
@@ -1476,7 +1476,7 @@ uint8_t *ListEntitiesCameraResponse::encode_msg(const void *self, uint8_t *__res
const auto &msg = *static_cast<const ListEntitiesCameraResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_bool(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.disabled_by_default);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 6, msg.icon);
@@ -1542,7 +1542,7 @@ uint8_t *ListEntitiesClimateResponse::encode_msg(const void *self, uint8_t *__re
const auto &msg = *static_cast<const ListEntitiesClimateResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_bool(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.supports_current_temperature);
pos = ProtoEncode::encode_bool(pos PROTO_ENCODE_DEBUG_ARG, 6, msg.supports_two_point_target_temperature);
for (const auto &it : *msg.supported_modes) {
@@ -1779,7 +1779,7 @@ uint8_t *ListEntitiesWaterHeaterResponse::encode_msg(const void *self,
const auto &msg = *static_cast<const ListEntitiesWaterHeaterResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 4, msg.icon);
#endif
@@ -1906,7 +1906,7 @@ uint8_t *ListEntitiesNumberResponse::encode_msg(const void *self, uint8_t *__res
const auto &msg = *static_cast<const ListEntitiesNumberResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.icon);
#endif
@@ -1997,7 +1997,7 @@ uint8_t *ListEntitiesSelectResponse::encode_msg(const void *self, uint8_t *__res
const auto &msg = *static_cast<const ListEntitiesSelectResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.icon);
#endif
@@ -2076,7 +2076,7 @@ uint8_t *ListEntitiesSirenResponse::encode_msg(const void *self, uint8_t *__rest
const auto &msg = *static_cast<const ListEntitiesSirenResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.icon);
#endif
@@ -2178,7 +2178,7 @@ uint8_t *ListEntitiesLockResponse::encode_msg(const void *self, uint8_t *__restr
const auto &msg = *static_cast<const ListEntitiesLockResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.icon);
#endif
@@ -2261,7 +2261,7 @@ uint8_t *ListEntitiesButtonResponse::encode_msg(const void *self, uint8_t *__res
const auto &msg = *static_cast<const ListEntitiesButtonResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.icon);
#endif
@@ -2330,7 +2330,7 @@ uint8_t *ListEntitiesMediaPlayerResponse::encode_msg(const void *self,
const auto &msg = *static_cast<const ListEntitiesMediaPlayerResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.icon);
#endif
@@ -3175,7 +3175,7 @@ uint8_t *ListEntitiesAlarmControlPanelResponse::encode_msg(const void *self,
const auto &msg = *static_cast<const ListEntitiesAlarmControlPanelResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.icon);
#endif
@@ -3255,7 +3255,7 @@ uint8_t *ListEntitiesTextResponse::encode_msg(const void *self, uint8_t *__restr
const auto &msg = *static_cast<const ListEntitiesTextResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.icon);
#endif
@@ -3334,7 +3334,7 @@ uint8_t *ListEntitiesDateResponse::encode_msg(const void *self, uint8_t *__restr
const auto &msg = *static_cast<const ListEntitiesDateResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.icon);
#endif
@@ -3415,7 +3415,7 @@ uint8_t *ListEntitiesTimeResponse::encode_msg(const void *self, uint8_t *__restr
const auto &msg = *static_cast<const ListEntitiesTimeResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.icon);
#endif
@@ -3496,7 +3496,7 @@ uint8_t *ListEntitiesEventResponse::encode_msg(const void *self, uint8_t *__rest
const auto &msg = *static_cast<const ListEntitiesEventResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.icon);
#endif
@@ -3558,7 +3558,7 @@ uint8_t *ListEntitiesValveResponse::encode_msg(const void *self, uint8_t *__rest
const auto &msg = *static_cast<const ListEntitiesValveResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.icon);
#endif
@@ -3646,7 +3646,7 @@ uint8_t *ListEntitiesDateTimeResponse::encode_msg(const void *self,
const auto &msg = *static_cast<const ListEntitiesDateTimeResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.icon);
#endif
@@ -3719,7 +3719,7 @@ uint8_t *ListEntitiesUpdateResponse::encode_msg(const void *self, uint8_t *__res
const auto &msg = *static_cast<const ListEntitiesUpdateResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 5, msg.icon);
#endif
@@ -3873,7 +3873,7 @@ uint8_t *ListEntitiesInfraredResponse::encode_msg(const void *self,
const auto &msg = *static_cast<const ListEntitiesInfraredResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 4, msg.icon);
#endif
@@ -3989,7 +3989,7 @@ uint8_t *ListEntitiesRadioFrequencyResponse::encode_msg(const void *self,
const auto &msg = *static_cast<const ListEntitiesRadioFrequencyResponse *>(self);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 10, msg.object_id);
pos = ProtoEncode::write_tag_and_fixed32(pos PROTO_ENCODE_DEBUG_ARG, 21, msg.key);
pos = ProtoEncode::encode_short_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
pos = ProtoEncode::encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, 26, msg.name);
#ifdef USE_ENTITY_ICON
pos = ProtoEncode::encode_string(pos PROTO_ENCODE_DEBUG_ARG, 4, msg.icon);
#endif
+1 -1
View File
@@ -399,7 +399,7 @@ class InfoResponseProtoMessage : public ProtoMessage {
public:
StringRef object_id{};
uint32_t key{0};
StringRef name{};
ProgmemStringRef name{};
bool disabled_by_default{false};
#ifdef USE_ENTITY_ICON
StringRef icon{nullptr, 0}; // null until set, encode only
+26 -26
View File
@@ -1191,7 +1191,7 @@ const char *ListEntitiesBinarySensorResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesBinarySensorResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
dump_field(out, ESPHOME_PSTR("device_class"), this->device_class);
dump_field(out, ESPHOME_PSTR("is_status_binary_sensor"), this->is_status_binary_sensor);
dump_field(out, ESPHOME_PSTR("disabled_by_default"), this->disabled_by_default);
@@ -1220,7 +1220,7 @@ const char *ListEntitiesCoverResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesCoverResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
dump_field(out, ESPHOME_PSTR("assumed_state"), this->assumed_state);
dump_field(out, ESPHOME_PSTR("supports_position"), this->supports_position);
dump_field(out, ESPHOME_PSTR("supports_tilt"), this->supports_tilt);
@@ -1266,7 +1266,7 @@ const char *ListEntitiesFanResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesFanResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
dump_field(out, ESPHOME_PSTR("supports_oscillation"), this->supports_oscillation);
dump_field(out, ESPHOME_PSTR("supports_speed"), this->supports_speed);
dump_field(out, ESPHOME_PSTR("supports_direction"), this->supports_direction);
@@ -1321,7 +1321,7 @@ const char *ListEntitiesLightResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesLightResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
for (const auto &it : *this->supported_color_modes) {
dump_field(out, ESPHOME_PSTR("supported_color_modes"), static_cast<enums::ColorMode>(it), 4);
}
@@ -1400,7 +1400,7 @@ const char *ListEntitiesSensorResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesSensorResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -1432,7 +1432,7 @@ const char *ListEntitiesSwitchResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesSwitchResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -1470,7 +1470,7 @@ const char *ListEntitiesTextSensorResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesTextSensorResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -1701,7 +1701,7 @@ const char *ListEntitiesCameraResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesCameraResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
dump_field(out, ESPHOME_PSTR("disabled_by_default"), this->disabled_by_default);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
@@ -1734,7 +1734,7 @@ const char *ListEntitiesClimateResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesClimateResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
dump_field(out, ESPHOME_PSTR("supports_current_temperature"), this->supports_current_temperature);
dump_field(out, ESPHOME_PSTR("supports_two_point_target_temperature"), this->supports_two_point_target_temperature);
for (const auto &it : *this->supported_modes) {
@@ -1832,7 +1832,7 @@ const char *ListEntitiesWaterHeaterResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesWaterHeaterResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -1886,7 +1886,7 @@ const char *ListEntitiesNumberResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesNumberResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -1928,7 +1928,7 @@ const char *ListEntitiesSelectResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesSelectResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -1967,7 +1967,7 @@ const char *ListEntitiesSirenResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesSirenResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -2014,7 +2014,7 @@ const char *ListEntitiesLockResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesLockResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -2055,7 +2055,7 @@ const char *ListEntitiesButtonResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesButtonResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -2090,7 +2090,7 @@ const char *ListEntitiesMediaPlayerResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesMediaPlayerResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -2480,7 +2480,7 @@ const char *ListEntitiesAlarmControlPanelResponse::dump_to(DumpBuffer &out) cons
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesAlarmControlPanelResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -2519,7 +2519,7 @@ const char *ListEntitiesTextResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesTextResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -2559,7 +2559,7 @@ const char *ListEntitiesDateResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesDateResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -2599,7 +2599,7 @@ const char *ListEntitiesTimeResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesTimeResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -2639,7 +2639,7 @@ const char *ListEntitiesEventResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesEventResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -2669,7 +2669,7 @@ const char *ListEntitiesValveResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesValveResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -2711,7 +2711,7 @@ const char *ListEntitiesDateTimeResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesDateTimeResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -2747,7 +2747,7 @@ const char *ListEntitiesUpdateResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesUpdateResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -2810,7 +2810,7 @@ const char *ListEntitiesInfraredResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesInfraredResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
@@ -2868,7 +2868,7 @@ const char *ListEntitiesRadioFrequencyResponse::dump_to(DumpBuffer &out) const {
MessageDumpHelper helper(out, ESPHOME_PSTR("ListEntitiesRadioFrequencyResponse"));
dump_field(out, ESPHOME_PSTR("object_id"), this->object_id);
dump_field(out, ESPHOME_PSTR("key"), this->key);
dump_field(out, ESPHOME_PSTR("name"), this->name);
dump_progmem_string_field(out, ESPHOME_PSTR("name"), this->name);
#ifdef USE_ENTITY_ICON
dump_field(out, ESPHOME_PSTR("icon"), this->icon);
#endif
+5
View File
@@ -409,6 +409,10 @@ class ProtoEncode {
/// Tag must be a single-byte varint (< 128). Always encodes (no zero check).
[[nodiscard]] static inline uint8_t *encode_short_string_force(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM,
uint8_t tag, const StringRef &ref) {
#ifdef USE_ESP8266
// memcpy_P reads RAM too, and sharing the progmem copy is smaller than an inline memcpy
return encode_short_progmem_string_force(pos PROTO_ENCODE_DEBUG_ARG, tag, ProgmemStringRef(ref));
#else
#ifdef ESPHOME_DEBUG_API
assert(ref.size() < 128 && "encode_short_string_force: string exceeds max_data_length < 128");
#endif
@@ -417,6 +421,7 @@ class ProtoEncode {
pos[1] = static_cast<uint8_t>(ref.size());
std::memcpy(pos + 2, ref.c_str(), ref.size());
return pos + 2 + ref.size();
#endif
}
/// encode_short_string_force for a string that may be in flash (PROGMEM).
[[nodiscard]] static inline uint8_t *encode_short_progmem_string_force(
+2 -2
View File
@@ -30,10 +30,10 @@ void AQISensor::dump_config() {
ESP_LOGCONFIG(TAG, " Extended Range: %s",
this->extended_range_ ? LOG_STR_LITERAL("enabled") : LOG_STR_LITERAL("disabled"));
if (this->pm_2_5_sensor_ != nullptr) {
ESP_LOGCONFIG(TAG, " PM2.5 Sensor: '%s'", this->pm_2_5_sensor_->get_name().c_str());
ESP_LOGCONFIG(TAG, " PM2.5 Sensor: '%s'", LOG_STR_ARG(this->pm_2_5_sensor_->get_log_name()));
}
if (this->pm_10_0_sensor_ != nullptr) {
ESP_LOGCONFIG(TAG, " PM10 Sensor: '%s'", this->pm_10_0_sensor_->get_name().c_str());
ESP_LOGCONFIG(TAG, " PM10 Sensor: '%s'", LOG_STR_ARG(this->pm_10_0_sensor_->get_log_name()));
}
LOG_SENSOR(" ", "AQI", this);
}
+2 -2
View File
@@ -639,7 +639,7 @@ float ATM90E32Component::get_chip_temperature_() {
void ATM90E32Component::press_calibration_button(EntityBase *entity, void (ATM90E32Component::*action)(),
const LogString *hint, const LogString *hint2) {
ESP_LOGI(TAG, "%s", entity->get_name().c_str());
ESP_LOGI(TAG, "%s", LOG_STR_ARG(entity->get_log_name()));
if (hint != nullptr) {
ESP_LOGI(TAG, "%s", LOG_STR_ARG(hint));
}
@@ -1295,7 +1295,7 @@ void ATM90E32Component::check_phase_status() {
if (!status.empty()) {
status.pop_back(); // remove space
status.pop_back(); // remove semicolon
ESP_LOGW(TAG, "%s: %s", sensor->get_name().c_str(), status.c_str());
ESP_LOGW(TAG, "%s: %s", LOG_STR_ARG(sensor->get_log_name()), status.c_str());
sensor->publish_state(status);
} else {
sensor->publish_state("Okay");
@@ -211,7 +211,7 @@ void BedJetClimate::control(const ClimateCall &call) {
} else if (fan_mode == CLIMATE_FAN_HIGH) {
result = this->parent_->set_fan_speed(75);
} else {
ESP_LOGW(TAG, "[%s] Unsupported fan mode: %s", this->get_name().c_str(),
ESP_LOGW(TAG, "[%s] Unsupported fan mode: %s", LOG_STR_ARG(this->get_log_name()),
LOG_STR_ARG(climate_fan_mode_to_string(fan_mode)));
return;
}
@@ -223,7 +223,7 @@ void BedJetClimate::control(const ClimateCall &call) {
auto fan_mode = call.get_custom_fan_mode();
auto fan_index = bedjet_fan_speed_to_step(fan_mode.c_str());
if (fan_index <= 19) {
ESP_LOGV(TAG, "[%s] Converted fan mode %.*s to bedjet fan step %d", this->get_name().c_str(),
ESP_LOGV(TAG, "[%s] Converted fan mode %.*s to bedjet fan step %d", LOG_STR_ARG(this->get_log_name()),
(int) fan_mode.size(), fan_mode.c_str(), fan_index);
bool result = this->parent_->set_fan_index(fan_index);
if (result) {
@@ -236,7 +236,7 @@ void BedJetClimate::control(const ClimateCall &call) {
void BedJetClimate::on_bedjet_state(bool is_ready) {}
void BedJetClimate::on_status(const BedjetStatusPacket *data) {
ESP_LOGV(TAG, "[%s] Handling on_status with data=%p", this->get_name().c_str(), (void *) data);
ESP_LOGV(TAG, "[%s] Handling on_status with data=%p", LOG_STR_ARG(this->get_log_name()), (void *) data);
auto converted_temp = bedjet_temp_to_c(data->target_temp_step);
if (converted_temp > 0)
@@ -310,11 +310,11 @@ void BedJetClimate::on_status(const BedjetStatusPacket *data) {
break;
default:
ESP_LOGW(TAG, "[%s] Unexpected mode: 0x%02X", this->get_name().c_str(), data->mode);
ESP_LOGW(TAG, "[%s] Unexpected mode: 0x%02X", LOG_STR_ARG(this->get_log_name()), data->mode);
break;
}
ESP_LOGV(TAG, "[%s] After on_status, new mode=%s", this->get_name().c_str(),
ESP_LOGV(TAG, "[%s] After on_status, new mode=%s", LOG_STR_ARG(this->get_log_name()),
LOG_STR_ARG(climate_mode_to_string(this->mode)));
// FIXME: compare new state to previous state.
this->publish_state();
@@ -351,11 +351,11 @@ bool BedJetClimate::update_status_() {
}
void BedJetClimate::update() {
ESP_LOGD(TAG, "[%s] update()", this->get_name().c_str());
ESP_LOGD(TAG, "[%s] update()", LOG_STR_ARG(this->get_log_name()));
// TODO: if the hub component is already polling, do we also need to include polling?
// We're already going to get on_status() at the hub's polling interval.
auto result = this->update_status_();
ESP_LOGD(TAG, "[%s] update_status result=%s", this->get_name().c_str(), result ? "true" : "false");
ESP_LOGD(TAG, "[%s] update_status result=%s", LOG_STR_ARG(this->get_log_name()), result ? "true" : "false");
}
} // namespace esphome::bedjet
+3 -3
View File
@@ -53,7 +53,7 @@ void BedJetFan::control(const fan::FanCall &call) {
}
void BedJetFan::on_status(const BedjetStatusPacket *data) {
ESP_LOGVV(TAG, "[%s] Handling on_status with data=%p", this->get_name().c_str(), (void *) data);
ESP_LOGVV(TAG, "[%s] Handling on_status with data=%p", LOG_STR_ARG(this->get_log_name()), (void *) data);
bool did_change = false;
bool new_state = data->mode != MODE_STANDBY && data->mode != MODE_WAIT;
@@ -96,11 +96,11 @@ bool BedJetFan::update_status_() {
}
void BedJetFan::update() {
ESP_LOGD(TAG, "[%s] update()", this->get_name().c_str());
ESP_LOGD(TAG, "[%s] update()", LOG_STR_ARG(this->get_log_name()));
// TODO: if the hub component is already polling, do we also need to include polling?
// We're already going to get on_status() at the hub's polling interval.
auto result = this->update_status_();
ESP_LOGD(TAG, "[%s] update_status result=%s", this->get_name().c_str(), result ? "true" : "false");
ESP_LOGD(TAG, "[%s] update_status result=%s", LOG_STR_ARG(this->get_log_name()), result ? "true" : "false");
}
/** Resets states to defaults. */
+1 -1
View File
@@ -151,7 +151,7 @@ void BH1750Sensor::loop() {
break;
}
ESP_LOGV(TAG, "'%s': Illuminance=%.1flx", this->get_name().c_str(), lx);
ESP_LOGV(TAG, "'%s': Illuminance=%.1flx", LOG_STR_ARG(this->get_log_name()), lx);
this->status_clear_warning();
this->publish_state(lx);
this->state_ = IDLE;
@@ -36,7 +36,7 @@ bool BinarySensor::set_new_state(const optional<bool> &new_state) {
#if defined(USE_BINARY_SENSOR) && defined(USE_CONTROLLER_REGISTRY)
ControllerRegistry::notify_binary_sensor_update(this);
#endif
ESP_LOGV(TAG, "'%s' >> %s", this->get_name().c_str(), ONOFFMAYBE(new_state));
ESP_LOGV(TAG, "'%s' >> %s", LOG_STR_ARG(this->get_log_name()), ONOFFMAYBE(new_state));
return true;
}
return false;
@@ -47,7 +47,7 @@ void BinarySensorMap::process_group_() {
}
} else if (this->last_mask_ != 0ULL) {
// no buttons are pressed and the states have changed since last run, so publish NAN
ESP_LOGV(TAG, "'%s' - No binary sensor active, publishing NAN", this->name_.c_str());
ESP_LOGV(TAG, "'%s' - No binary sensor active, publishing NAN", LOG_STR_ARG(this->get_log_name()));
this->publish_state(NAN);
}
+1 -1
View File
@@ -192,7 +192,7 @@ float BL0940::update_temp_(sensor::Sensor *sensor, uint16_le_t temperature) cons
if (sensor != nullptr) {
if (sensor->has_state() && std::abs(converted_temp - sensor->get_state()) > max_temperature_diff_) {
ESP_LOGD(TAG, "Invalid temperature change. Sensor: '%s', Old temperature: %f, New temperature: %f",
sensor->get_name().c_str(), sensor->get_state(), converted_temp);
LOG_STR_ARG(sensor->get_log_name()), sensor->get_state(), converted_temp);
return 0.0f;
}
sensor->publish_state(converted_temp);
@@ -63,7 +63,7 @@ void BLEClientRSSISensor::gap_event_handler(esp_gap_ble_cb_event_t event, esp_bl
void BLEClientRSSISensor::update() {
if (this->node_state != espbt::ClientState::ESTABLISHED) {
ESP_LOGW(TAG, "[%s] Cannot poll, not connected", this->get_name().c_str());
ESP_LOGW(TAG, "[%s] Cannot poll, not connected", LOG_STR_ARG(this->get_log_name()));
this->should_update_ = true;
return;
}
@@ -37,13 +37,13 @@ void BLESensor::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t ga
switch (event) {
case ESP_GATTC_OPEN_EVT: {
if (param->open.status == ESP_GATT_OK) {
ESP_LOGI(TAG, "[%s] Connected successfully!", this->get_name().c_str());
ESP_LOGI(TAG, "[%s] Connected successfully!", LOG_STR_ARG(this->get_log_name()));
break;
}
break;
}
case ESP_GATTC_CLOSE_EVT: {
ESP_LOGW(TAG, "[%s] Disconnected!", this->get_name().c_str());
ESP_LOGW(TAG, "[%s] Disconnected!", LOG_STR_ARG(this->get_log_name()));
this->status_set_warning();
this->publish_state(NAN);
break;
@@ -102,10 +102,10 @@ void BLESensor::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t ga
}
case ESP_GATTC_NOTIFY_EVT: {
if (param->notify.value_len == 0) {
ESP_LOGW(TAG, "[%s] ESP_GATTC_NOTIFY_EVT: empty value", this->get_name().c_str());
ESP_LOGW(TAG, "[%s] ESP_GATTC_NOTIFY_EVT: empty value", LOG_STR_ARG(this->get_log_name()));
break;
}
ESP_LOGD(TAG, "[%s] ESP_GATTC_NOTIFY_EVT: handle=0x%x, value=0x%x", this->get_name().c_str(),
ESP_LOGD(TAG, "[%s] ESP_GATTC_NOTIFY_EVT: handle=0x%x, value=0x%x", LOG_STR_ARG(this->get_log_name()),
param->notify.handle, param->notify.value[0]);
if (param->notify.handle != this->handle)
break;
@@ -143,11 +143,11 @@ float BLESensor::parse_data_(uint8_t *value, uint16_t value_len) {
void BLESensor::update() {
if (this->node_state != espbt::ClientState::ESTABLISHED) {
ESP_LOGW(TAG, "[%s] Cannot poll, not connected", this->get_name().c_str());
ESP_LOGW(TAG, "[%s] Cannot poll, not connected", LOG_STR_ARG(this->get_log_name()));
return;
}
if (this->handle == 0) {
ESP_LOGW(TAG, "[%s] Cannot poll, no service or characteristic found", this->get_name().c_str());
ESP_LOGW(TAG, "[%s] Cannot poll, no service or characteristic found", LOG_STR_ARG(this->get_log_name()));
return;
}
@@ -156,7 +156,7 @@ void BLESensor::update() {
if (status) {
this->status_set_warning();
this->publish_state(NAN);
ESP_LOGW(TAG, "[%s] Error sending read request for sensor, status=%d", this->get_name().c_str(), status);
ESP_LOGW(TAG, "[%s] Error sending read request for sensor, status=%d", LOG_STR_ARG(this->get_log_name()), status);
}
}
@@ -38,7 +38,7 @@ void BLETextSensor::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
switch (event) {
case ESP_GATTC_OPEN_EVT: {
if (param->open.status == ESP_GATT_OK) {
ESP_LOGI(TAG, "[%s] Connected successfully!", this->get_name().c_str());
ESP_LOGI(TAG, "[%s] Connected successfully!", LOG_STR_ARG(this->get_log_name()));
break;
}
break;
@@ -104,10 +104,10 @@ void BLETextSensor::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
if (param->notify.handle != this->handle)
break;
if (param->notify.value_len == 0) {
ESP_LOGW(TAG, "[%s] ESP_GATTC_NOTIFY_EVT: empty value", this->get_name().c_str());
ESP_LOGW(TAG, "[%s] ESP_GATTC_NOTIFY_EVT: empty value", LOG_STR_ARG(this->get_log_name()));
break;
}
ESP_LOGV(TAG, "[%s] ESP_GATTC_NOTIFY_EVT: handle=0x%x, value=0x%x", this->get_name().c_str(),
ESP_LOGV(TAG, "[%s] ESP_GATTC_NOTIFY_EVT: handle=0x%x, value=0x%x", LOG_STR_ARG(this->get_log_name()),
param->notify.handle, param->notify.value[0]);
this->publish_state(reinterpret_cast<const char *>(param->notify.value), param->notify.value_len);
break;
@@ -124,11 +124,11 @@ void BLETextSensor::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
void BLETextSensor::update() {
if (this->node_state != espbt::ClientState::ESTABLISHED) {
ESP_LOGW(TAG, "[%s] Cannot poll, not connected", this->get_name().c_str());
ESP_LOGW(TAG, "[%s] Cannot poll, not connected", LOG_STR_ARG(this->get_log_name()));
return;
}
if (this->handle == 0) {
ESP_LOGW(TAG, "[%s] Cannot poll, no service or characteristic found", this->get_name().c_str());
ESP_LOGW(TAG, "[%s] Cannot poll, no service or characteristic found", LOG_STR_ARG(this->get_log_name()));
return;
}
@@ -137,7 +137,7 @@ void BLETextSensor::update() {
if (status) {
this->status_set_warning();
this->publish_state("");
ESP_LOGW(TAG, "[%s] Error sending read request for sensor, status=%d", this->get_name().c_str(), status);
ESP_LOGW(TAG, "[%s] Error sending read request for sensor, status=%d", LOG_STR_ARG(this->get_log_name()), status);
}
}
+1 -1
View File
@@ -14,7 +14,7 @@ void log_button(const char *tag, const char *prefix, const char *type, Button *o
}
void Button::press() {
ESP_LOGV(TAG, "'%s' Pressed.", this->get_name().c_str());
ESP_LOGV(TAG, "'%s' Pressed.", LOG_STR_ARG(this->get_log_name()));
this->press_action();
this->press_callback_.call();
}
+10 -7
View File
@@ -46,7 +46,7 @@ constexpr StringToUint8 CLIMATE_SWING_MODES_BY_STR[] = {
void ClimateCall::perform() {
this->parent_->control_callback_.call(*this);
ESP_LOGV(TAG, "'%s' - Setting", this->parent_->get_name().c_str());
ESP_LOGV(TAG, "'%s' - Setting", LOG_STR_ARG(this->parent_->get_log_name()));
this->validate_();
if (this->mode_.has_value()) {
const LogString *mode_s = climate_mode_to_string(*this->mode_);
@@ -183,7 +183,7 @@ ClimateCall &ClimateCall::set_mode(const char *mode, size_t len) {
return *this;
}
}
ESP_LOGW(TAG, "'%s' - Unrecognized mode %.*s", this->parent_->get_name().c_str(), (int) len, mode);
ESP_LOGW(TAG, "'%s' - Unrecognized mode %.*s", LOG_STR_ARG(this->parent_->get_log_name()), (int) len, mode);
return *this;
}
@@ -214,7 +214,8 @@ ClimateCall &ClimateCall::set_fan_mode(const char *custom_fan_mode, size_t len)
this->fan_mode_.reset();
return *this;
}
ESP_LOGW(TAG, "'%s' - Unrecognized fan mode %.*s", this->parent_->get_name().c_str(), (int) len, custom_fan_mode);
ESP_LOGW(TAG, "'%s' - Unrecognized fan mode %.*s", LOG_STR_ARG(this->parent_->get_log_name()), (int) len,
custom_fan_mode);
return *this;
}
@@ -252,7 +253,8 @@ ClimateCall &ClimateCall::set_preset(const char *custom_preset, size_t len) {
this->preset_.reset();
return *this;
}
ESP_LOGW(TAG, "'%s' - Unrecognized preset %.*s", this->parent_->get_name().c_str(), (int) len, custom_preset);
ESP_LOGW(TAG, "'%s' - Unrecognized preset %.*s", LOG_STR_ARG(this->parent_->get_log_name()), (int) len,
custom_preset);
return *this;
}
@@ -280,7 +282,8 @@ ClimateCall &ClimateCall::set_swing_mode(const char *swing_mode, size_t len) {
return *this;
}
}
ESP_LOGW(TAG, "'%s' - Unrecognized swing mode %.*s", this->parent_->get_name().c_str(), (int) len, swing_mode);
ESP_LOGW(TAG, "'%s' - Unrecognized swing mode %.*s", LOG_STR_ARG(this->parent_->get_log_name()), (int) len,
swing_mode);
return *this;
}
@@ -428,7 +431,7 @@ void Climate::save_state_(const ClimateTraits &traits) {
void Climate::publish_state() {
this->set_has_state(true);
ESP_LOGV(TAG, "'%s' >>", this->name_.c_str());
ESP_LOGV(TAG, "'%s' >>", LOG_STR_ARG(this->get_log_name()));
auto traits = this->get_traits();
ESP_LOGV(TAG, " Mode: %s", LOG_STR_ARG(climate_mode_to_string(this->mode)));
@@ -547,7 +550,7 @@ void ClimateDeviceRestoreState::apply(Climate *climate) {
if (traits.supports_mode(this->mode)) {
climate->mode = this->mode;
} else {
ESP_LOGW(TAG, "'%s' - Saved mode %s is no longer supported, keeping %s", climate->get_name().c_str(),
ESP_LOGW(TAG, "'%s' - Saved mode %s is no longer supported, keeping %s", LOG_STR_ARG(climate->get_log_name()),
LOG_STR_ARG(climate_mode_to_string(this->mode)), LOG_STR_ARG(climate_mode_to_string(climate->mode)));
}
if (traits.has_feature_flags(CLIMATE_SUPPORTS_TWO_POINT_TARGET_TEMPERATURE |
@@ -30,14 +30,14 @@ void CombinationOneParameterComponent::add_source(Sensor *sensor, float value) {
void CombinationNoParameterComponent::log_source_sensors() {
ESP_LOGCONFIG(TAG, " Source Sensors:");
for (const auto &sensor : this->sensors_) {
ESP_LOGCONFIG(TAG, " - %s", sensor->get_name().c_str());
ESP_LOGCONFIG(TAG, " - %s", LOG_STR_ARG(sensor->get_log_name()));
}
}
void CombinationOneParameterComponent::log_source_sensors() {
ESP_LOGCONFIG(TAG, " Source Sensors:");
for (const auto &source : this->sensor_sources_) {
ESP_LOGCONFIG(TAG, " - %s", source.sensor->get_name().c_str());
ESP_LOGCONFIG(TAG, " - %s", LOG_STR_ARG(source.sensor->get_log_name()));
}
}
+2
View File
@@ -40,6 +40,7 @@ CONF_GREEN_CHANNEL = "green_channel"
CONF_GYROSCOPE_ODR = "gyroscope_odr"
CONF_GYROSCOPE_RANGE = "gyroscope_range"
CONF_HOLD_STATE = "hold_state"
CONF_HORIZONTAL_DEFAULT = "horizontal_default"
CONF_HOST = "host"
CONF_HUMIDITY_SOURCE = "humidity_source"
CONF_IAQ = "iaq"
@@ -81,6 +82,7 @@ CONF_TARGET_COUNT = "target_count"
CONF_USE_PSRAM = "use_psram"
CONF_VALUE_TYPE = "value_type"
CONF_VERIFY_SSL = "verify_ssl"
CONF_VERTICAL_DEFAULT = "vertical_default"
CONF_VOC_INDEX = "voc_index"
CONF_VOLUME_INCREMENT = "volume_increment"
CONF_VOLUME_INITIAL = "volume_initial"
+4 -4
View File
@@ -39,7 +39,7 @@ CoverCall &CoverCall::set_command(const char *command) {
} else if (ESPHOME_strcasecmp_P(command, ESPHOME_PSTR("TOGGLE")) == 0) {
this->set_command_toggle();
} else {
ESP_LOGW(TAG, "'%s' - Unrecognized command %s", this->parent_->get_name().c_str(), command);
ESP_LOGW(TAG, "'%s' - Unrecognized command %s", LOG_STR_ARG(this->parent_->get_log_name()), command);
}
return *this;
}
@@ -68,7 +68,7 @@ CoverCall &CoverCall::set_tilt(float tilt) {
return *this;
}
void CoverCall::perform() {
ESP_LOGV(TAG, "'%s' - Setting", this->parent_->get_name().c_str());
ESP_LOGV(TAG, "'%s' - Setting", LOG_STR_ARG(this->parent_->get_log_name()));
auto traits = this->parent_->get_traits();
this->validate_();
if (this->stop_) {
@@ -94,7 +94,7 @@ const optional<float> &CoverCall::get_tilt() const { return this->tilt_; }
const optional<bool> &CoverCall::get_toggle() const { return this->toggle_; }
void CoverCall::validate_() {
auto traits = this->parent_->get_traits();
const char *name = this->parent_->get_name().c_str();
const char *name = LOG_STR_ARG(this->parent_->get_log_name());
if (this->position_.has_value()) {
auto pos = *this->position_;
@@ -139,7 +139,7 @@ void Cover::publish_state(bool save) {
this->position = clamp(this->position, 0.0f, 1.0f);
this->tilt = clamp(this->tilt, 0.0f, 1.0f);
ESP_LOGV(TAG, "'%s' >>", this->name_.c_str());
ESP_LOGV(TAG, "'%s' >>", LOG_STR_ARG(this->get_log_name()));
auto traits = this->get_traits();
if (traits.get_supports_position()) {
ESP_LOGV(TAG, " Position: %.0f%%", this->position * 100.0f);
@@ -40,7 +40,8 @@ void CTClampSensor::update() {
if (rms_ac_squared > 0)
rms_ac = std::sqrt(rms_ac_squared);
ESP_LOGD(TAG, "'%s' - Raw AC Value: %.3fA after %" PRIu32 " different samples (%" PRIu32 " SPS)",
this->name_.c_str(), rms_ac, this->num_samples_, 1000 * this->num_samples_ / this->sample_duration_);
LOG_STR_ARG(this->get_log_name()), rms_ac, this->num_samples_,
1000 * this->num_samples_ / this->sample_duration_);
this->publish_state(rms_ac);
});
@@ -70,20 +70,20 @@ void CurrentBasedCover::loop() {
this->direction_idle_();
this->malfunction_trigger_.trigger();
ESP_LOGI(TAG, "'%s' - Malfunction detected during opening. Current flow detected in close circuit",
this->name_.c_str());
LOG_STR_ARG(this->get_log_name()));
} else if (this->is_opening_blocked_()) { // Blocked
ESP_LOGD(TAG, "'%s' - Obstacle detected during opening.", this->name_.c_str());
ESP_LOGD(TAG, "'%s' - Obstacle detected during opening.", LOG_STR_ARG(this->get_log_name()));
this->direction_idle_();
if (this->obstacle_rollback_ != 0) {
this->set_timeout(ROLLBACK_TIMEOUT_ID, 300, [this]() {
ESP_LOGD(TAG, "'%s' - Rollback.", this->name_.c_str());
ESP_LOGD(TAG, "'%s' - Rollback.", LOG_STR_ARG(this->get_log_name()));
this->target_position_ = clamp(this->position - this->obstacle_rollback_, 0.0F, 1.0F);
this->start_direction_(COVER_OPERATION_CLOSING);
});
}
} else if (this->is_initial_delay_finished_() && !this->is_opening_()) { // End reached
auto dur = (now - this->start_dir_time_) / 1e3f;
ESP_LOGD(TAG, "'%s' - Open position reached. Took %.1fs.", this->name_.c_str(), dur);
ESP_LOGD(TAG, "'%s' - Open position reached. Took %.1fs.", LOG_STR_ARG(this->get_log_name()), dur);
this->direction_idle_(COVER_OPEN);
}
} else if (this->current_operation == COVER_OPERATION_CLOSING) {
@@ -91,25 +91,25 @@ void CurrentBasedCover::loop() {
this->direction_idle_();
this->malfunction_trigger_.trigger();
ESP_LOGI(TAG, "'%s' - Malfunction detected during closing. Current flow detected in open circuit",
this->name_.c_str());
LOG_STR_ARG(this->get_log_name()));
} else if (this->is_closing_blocked_()) { // Blocked
ESP_LOGD(TAG, "'%s' - Obstacle detected during closing.", this->name_.c_str());
ESP_LOGD(TAG, "'%s' - Obstacle detected during closing.", LOG_STR_ARG(this->get_log_name()));
this->direction_idle_();
if (this->obstacle_rollback_ != 0) {
this->set_timeout(ROLLBACK_TIMEOUT_ID, 300, [this]() {
ESP_LOGD(TAG, "'%s' - Rollback.", this->name_.c_str());
ESP_LOGD(TAG, "'%s' - Rollback.", LOG_STR_ARG(this->get_log_name()));
this->target_position_ = clamp(this->position + this->obstacle_rollback_, 0.0F, 1.0F);
this->start_direction_(COVER_OPERATION_OPENING);
});
}
} else if (this->is_initial_delay_finished_() && !this->is_closing_()) { // End reached
auto dur = (now - this->start_dir_time_) / 1e3f;
ESP_LOGD(TAG, "'%s' - Close position reached. Took %.1fs.", this->name_.c_str(), dur);
ESP_LOGD(TAG, "'%s' - Close position reached. Took %.1fs.", LOG_STR_ARG(this->get_log_name()), dur);
this->direction_idle_(COVER_CLOSED);
}
}
if (now - this->start_dir_time_ > this->max_duration_) {
ESP_LOGD(TAG, "'%s' - Max duration reached. Stopping cover.", this->name_.c_str());
ESP_LOGD(TAG, "'%s' - Max duration reached. Stopping cover.", LOG_STR_ARG(this->get_log_name()));
this->direction_idle_();
}
@@ -54,7 +54,7 @@ void DallasTemperatureSensor::update() {
}
float tempc = this->get_temp_c_();
ESP_LOGD(TAG, "'%s': Got Temperature=%f°C", this->get_name().c_str(), tempc);
ESP_LOGD(TAG, "'%s': Got Temperature=%f°C", LOG_STR_ARG(this->get_log_name()), tempc);
this->publish_state(tempc);
});
}
@@ -66,7 +66,7 @@ bool DallasTemperatureSensor::read_scratch_pad_() {
i = this->bus_->read8();
}
} else {
ESP_LOGW(TAG, "'%s' - reading scratch pad failed bus reset", this->get_name().c_str());
ESP_LOGW(TAG, "'%s' - reading scratch pad failed bus reset", LOG_STR_ARG(this->get_log_name()));
this->status_set_warning(LOG_STR("bus reset failed"));
}
return success;
+2 -2
View File
@@ -30,7 +30,7 @@ void DateEntity::publish_state() {
return;
}
this->set_has_state(true);
ESP_LOGV(TAG, "'%s' >> %d-%d-%d", this->get_name().c_str(), this->year_, this->month_, this->day_);
ESP_LOGV(TAG, "'%s' >> %d-%d-%d", LOG_STR_ARG(this->get_log_name()), this->year_, this->month_, this->day_);
this->state_callback_.call();
#if defined(USE_DATETIME_DATE) && defined(USE_CONTROLLER_REGISTRY)
ControllerRegistry::notify_date_update(this);
@@ -81,7 +81,7 @@ void DateCall::validate_() {
void DateCall::perform() {
this->validate_();
ESP_LOGV(TAG, "'%s' - Setting", this->parent_->get_name().c_str());
ESP_LOGV(TAG, "'%s' - Setting", LOG_STR_ARG(this->parent_->get_log_name()));
if (this->year_.has_value()) {
ESP_LOGV(TAG, " Year: %d", *this->year_);
@@ -45,7 +45,7 @@ void DateTimeEntity::publish_state() {
return;
}
this->set_has_state(true);
ESP_LOGV(TAG, "'%s' >> %04u-%02u-%02u %02d:%02d:%02d", this->get_name().c_str(), this->year_, this->month_,
ESP_LOGV(TAG, "'%s' >> %04u-%02u-%02u %02d:%02d:%02d", LOG_STR_ARG(this->get_log_name()), this->year_, this->month_,
this->day_, this->hour_, this->minute_, this->second_);
this->state_callback_.call();
#if defined(USE_DATETIME_DATETIME) && defined(USE_CONTROLLER_REGISTRY)
@@ -125,7 +125,7 @@ void DateTimeCall::validate_() {
void DateTimeCall::perform() {
this->validate_();
ESP_LOGV(TAG, "'%s' - Setting", this->parent_->get_name().c_str());
ESP_LOGV(TAG, "'%s' - Setting", LOG_STR_ARG(this->parent_->get_log_name()));
if (this->year_.has_value()) {
ESP_LOGV(TAG, " Year: %d", *this->year_);
+2 -2
View File
@@ -26,7 +26,7 @@ void TimeEntity::publish_state() {
return;
}
this->set_has_state(true);
ESP_LOGV(TAG, "'%s' >> %02d:%02d:%02d", this->get_name().c_str(), this->hour_, this->minute_, this->second_);
ESP_LOGV(TAG, "'%s' >> %02d:%02d:%02d", LOG_STR_ARG(this->get_log_name()), this->hour_, this->minute_, this->second_);
this->state_callback_.call();
#if defined(USE_DATETIME_TIME) && defined(USE_CONTROLLER_REGISTRY)
ControllerRegistry::notify_time_update(this);
@@ -50,7 +50,7 @@ void TimeCall::validate_() {
void TimeCall::perform() {
this->validate_();
ESP_LOGV(TAG, "'%s' - Setting", this->parent_->get_name().c_str());
ESP_LOGV(TAG, "'%s' - Setting", LOG_STR_ARG(this->parent_->get_log_name()));
if (this->hour_.has_value()) {
ESP_LOGV(TAG, " Hour: %d", *this->hour_);
}
+4 -3
View File
@@ -36,7 +36,8 @@ void DewPointComponent::dump_config() {
"Sources\n"
" Temperature: '%s'\n"
" Humidity: '%s'",
this->temperature_sensor_->get_name().c_str(), this->humidity_sensor_->get_name().c_str());
LOG_STR_ARG(this->temperature_sensor_->get_log_name()),
LOG_STR_ARG(this->humidity_sensor_->get_log_name()));
}
float DewPointComponent::get_setup_priority() const { return setup_priority::DATA; }
@@ -75,8 +76,8 @@ void DewPointComponent::loop() {
// Publish the calculated dew point
this->publish_state(dew_point);
ESP_LOGD(TAG, "'%s' >> %.1f°C (T: %.1f°C, RH: %.1f%%)", this->get_name().c_str(), dew_point, this->temperature_value_,
this->humidity_value_);
ESP_LOGD(TAG, "'%s' >> %.1f°C (T: %.1f°C, RH: %.1f%%)", LOG_STR_ARG(this->get_log_name()), dew_point,
this->temperature_value_, this->humidity_value_);
}
} // namespace esphome::dew_point
@@ -36,7 +36,7 @@ void DutyCycleSensor::update() {
const float total_time = float(now - this->last_update_);
const float value = (on_time * 100.0f) / total_time;
ESP_LOGD(TAG, "'%s' Got duty cycle=%.1f%%", this->get_name().c_str(), value);
ESP_LOGD(TAG, "'%s' Got duty cycle=%.1f%%", LOG_STR_ARG(this->get_log_name()), value);
this->publish_state(value);
}
this->last_update_ = now;
+3 -3
View File
@@ -70,20 +70,20 @@ void EndstopCover::loop() {
if (this->current_operation == COVER_OPERATION_OPENING && this->is_open_()) {
float dur = (now - this->start_dir_time_) / 1e3f;
ESP_LOGD(TAG, "'%s' - Open endstop reached. Took %.1fs.", this->name_.c_str(), dur);
ESP_LOGD(TAG, "'%s' - Open endstop reached. Took %.1fs.", LOG_STR_ARG(this->get_log_name()), dur);
this->start_direction_(COVER_OPERATION_IDLE);
this->position = COVER_OPEN;
this->publish_state();
} else if (this->current_operation == COVER_OPERATION_CLOSING && this->is_closed_()) {
float dur = (now - this->start_dir_time_) / 1e3f;
ESP_LOGD(TAG, "'%s' - Close endstop reached. Took %.1fs.", this->name_.c_str(), dur);
ESP_LOGD(TAG, "'%s' - Close endstop reached. Took %.1fs.", LOG_STR_ARG(this->get_log_name()), dur);
this->start_direction_(COVER_OPERATION_IDLE);
this->position = COVER_CLOSED;
this->publish_state();
} else if (now - this->start_dir_time_ > this->max_duration_) {
ESP_LOGD(TAG, "'%s' - Max duration reached. Stopping cover.", this->name_.c_str());
ESP_LOGD(TAG, "'%s' - Max duration reached. Stopping cover.", LOG_STR_ARG(this->get_log_name()));
this->start_direction_(COVER_OPERATION_IDLE);
this->publish_state();
}
@@ -132,9 +132,9 @@ void ESP32Camera::dump_config() {
" External Clock: Pin:%d Frequency:%u\n"
" I2C Pins: SDA:%d SCL:%d\n"
" Reset Pin: %d",
this->name_.c_str(), YESNO(this->is_internal()), conf.pin_d0, conf.pin_d1, conf.pin_d2, conf.pin_d3,
conf.pin_d4, conf.pin_d5, conf.pin_d6, conf.pin_d7, conf.pin_vsync, conf.pin_href, conf.pin_pclk,
conf.pin_xclk, conf.xclk_freq_hz, conf.pin_sccb_sda, conf.pin_sccb_scl, conf.pin_reset);
LOG_STR_ARG(this->get_log_name()), YESNO(this->is_internal()), conf.pin_d0, conf.pin_d1, conf.pin_d2,
conf.pin_d3, conf.pin_d4, conf.pin_d5, conf.pin_d6, conf.pin_d7, conf.pin_vsync, conf.pin_href,
conf.pin_pclk, conf.pin_xclk, conf.xclk_freq_hz, conf.pin_sccb_sda, conf.pin_sccb_scl, conf.pin_reset);
ESP_LOGCONFIG(TAG, " Resolution: %s", frame_size_to_str(this->config_.frame_size));
ESP_LOGCONFIG(TAG, " Pixel Format: %s", pixel_format_to_str(this->config_.pixel_format));
@@ -26,9 +26,14 @@ ESPHOME_LOG_TAG(TAG, "esp32_hosted.update");
// Older coprocessor firmware versions have a 1500-byte limit per RPC call
constexpr size_t CHUNK_SIZE = 1500;
// OTA begin blocks while the coprocessor erases its partition
// OTA begin blocks while the coprocessor erases its partition, end while it validates the image
constexpr uint32_t OTA_WDT_TIMEOUT_MS = 60000;
static esp_err_t ota_end_guarded() {
watchdog::WatchdogManager wdt(OTA_WDT_TIMEOUT_MS);
return esp_hosted_slave_ota_end(); // NOLINT
}
#ifdef USE_ESP32_HOSTED_HTTP_UPDATE
// Interval/timeout IDs (uint32_t to avoid string comparison)
constexpr uint32_t INITIAL_CHECK_INTERVAL_ID = 0;
@@ -380,7 +385,7 @@ bool Esp32HostedUpdate::stream_firmware_to_coprocessor_() {
} else {
ESP_LOGE(TAG, "Error reading firmware data: %d", read_or_error);
}
esp_hosted_slave_ota_end(); // NOLINT
ota_end_guarded();
container->end();
this->status_set_error(LOG_STR("Download failed"));
return false;
@@ -390,7 +395,7 @@ bool Esp32HostedUpdate::stream_firmware_to_coprocessor_() {
err = esp_hosted_slave_ota_write(buffer, read_or_error); // NOLINT
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to write OTA data: %s", esp_err_to_name(err));
esp_hosted_slave_ota_end(); // NOLINT
ota_end_guarded();
container->end();
this->status_set_error(LOG_STR("Failed to write OTA data"));
return false;
@@ -402,7 +407,7 @@ bool Esp32HostedUpdate::stream_firmware_to_coprocessor_() {
hasher.calculate();
if (!hasher.equals_bytes(this->firmware_sha256_.data())) {
ESP_LOGE(TAG, "SHA256 mismatch");
esp_hosted_slave_ota_end(); // NOLINT
ota_end_guarded();
this->status_set_error(LOG_STR("SHA256 verification failed"));
return false;
}
@@ -451,7 +456,7 @@ bool Esp32HostedUpdate::write_embedded_firmware_to_coprocessor_() {
err = esp_hosted_slave_ota_write(chunk, chunk_size); // NOLINT
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to write OTA data: %s", esp_err_to_name(err));
esp_hosted_slave_ota_end(); // NOLINT
ota_end_guarded();
this->status_set_error(LOG_STR("Failed to write OTA data"));
return false;
}
@@ -494,7 +499,7 @@ void Esp32HostedUpdate::perform(bool force) {
}
// End OTA and activate new firmware
esp_err_t end_err = esp_hosted_slave_ota_end(); // NOLINT
esp_err_t end_err = ota_end_guarded();
if (end_err != ESP_OK) {
ESP_LOGE(TAG, "Failed to end OTA: %s", esp_err_to_name(end_err));
this->state_ = prev_state;
@@ -341,13 +341,13 @@ void ESP32TouchComponent::loop() {
child->publish_state(new_state);
#ifdef USE_ESP32_VARIANT_ESP32
ESP_LOGV(TAG, "Touch Pad '%s' state: %s (value: %" PRIu32 ", threshold: %" PRIu32 ")",
child->get_name().c_str(), ONOFF(new_state), value, child->get_threshold());
LOG_STR_ARG(child->get_log_name()), ONOFF(new_state), value, child->get_threshold());
#else
if (new_state) {
ESP_LOGV(TAG, "Touch Pad '%s' state: ON (value: %" PRIu32 ", benchmark: %" PRIu32 ", threshold: %" PRIu32 ")",
child->get_name().c_str(), value, benchmark, child->get_threshold());
LOG_STR_ARG(child->get_log_name()), value, benchmark, child->get_threshold());
} else {
ESP_LOGV(TAG, "Touch Pad '%s' state: OFF", child->get_name().c_str());
ESP_LOGV(TAG, "Touch Pad '%s' state: OFF", LOG_STR_ARG(child->get_log_name()));
}
#endif
}
@@ -470,7 +470,8 @@ void ESP32TouchComponent::process_setup_mode_logging_(uint32_t now) {
child->value_ = smooth_value;
#ifdef USE_ESP32_VARIANT_ESP32
ESP_LOGD(TAG, "Touch Pad '%s' (Ch%d): %" PRIu32, child->get_name().c_str(), child->channel_id_, smooth_value);
ESP_LOGD(TAG, "Touch Pad '%s' (Ch%d): %" PRIu32, LOG_STR_ARG(child->get_log_name()), child->channel_id_,
smooth_value);
#else
uint32_t benchmark = 0;
touch_channel_read_data(child->chan_handle_, TOUCH_CHAN_DATA_TYPE_BENCHMARK, &benchmark);
@@ -479,7 +480,7 @@ void ESP32TouchComponent::process_setup_mode_logging_(uint32_t now) {
ESP_LOGD(TAG,
"Touch Pad '%s' (Ch%d): value=%" PRIu32 ", benchmark=%" PRIu32 ", difference=%" PRId32
" (set threshold < %" PRId32 " to detect touch)",
child->get_name().c_str(), child->channel_id_, smooth_value, benchmark, difference, difference);
LOG_STR_ARG(child->get_log_name()), child->channel_id_, smooth_value, benchmark, difference, difference);
#endif
}
this->setup_mode_last_log_print_ = now;
@@ -491,7 +492,7 @@ void ESP32TouchComponent::publish_initial_state_if_needed_(ESP32TouchBinarySenso
if (now > INITIAL_STATE_DELAY_MS) {
child->publish_initial_state(false);
child->initial_state_published_ = true;
ESP_LOGV(TAG, "Touch Pad '%s' state: OFF (initial)", child->get_name().c_str());
ESP_LOGV(TAG, "Touch Pad '%s' state: OFF (initial)", LOG_STR_ARG(child->get_log_name()));
}
}
}
+2 -2
View File
@@ -17,11 +17,11 @@ void Event::trigger(const char *event_type) {
}
}
if (found == nullptr) {
ESP_LOGE(TAG, "'%s': invalid event type for trigger(): %s", this->get_name().c_str(), event_type);
ESP_LOGE(TAG, "'%s': invalid event type for trigger(): %s", LOG_STR_ARG(this->get_log_name()), event_type);
return;
}
this->last_event_type_ = found;
ESP_LOGV(TAG, "'%s' >> '%s'", this->get_name().c_str(), this->last_event_type_);
ESP_LOGV(TAG, "'%s' >> '%s'", LOG_STR_ARG(this->get_log_name()), this->last_event_type_);
this->event_callback_.call(StringRef(found));
#if defined(USE_EVENT) && defined(USE_CONTROLLER_REGISTRY)
ControllerRegistry::notify_event(this);
+7 -6
View File
@@ -42,14 +42,15 @@ FanCall &FanCall::set_preset_mode(const char *preset_mode, size_t len) {
this->preset_mode_ = validated_mode; // Store pointer from traits
} else {
// Preset mode not found in traits - log warning and don't set
ESP_LOGW(TAG, "%s: Preset mode '%.*s' not supported", this->parent_.get_name().c_str(), (int) len, preset_mode);
ESP_LOGW(TAG, "%s: Preset mode '%.*s' not supported", LOG_STR_ARG(this->parent_.get_log_name()), (int) len,
preset_mode);
this->preset_mode_ = nullptr;
}
return *this;
}
void FanCall::perform() {
ESP_LOGV(TAG, "'%s' - Setting:", this->parent_.get_name().c_str());
ESP_LOGV(TAG, "'%s' - Setting:", LOG_STR_ARG(this->parent_.get_log_name()));
this->validate_();
if (this->binary_state_.has_value()) {
ESP_LOGV(TAG, " State: %s", ONOFF(*this->binary_state_));
@@ -93,17 +94,17 @@ void FanCall::validate_() {
}
if (this->oscillating_.has_value() && !traits.supports_oscillation()) {
ESP_LOGW(TAG, "%s: Oscillation not supported", this->parent_.get_name().c_str());
ESP_LOGW(TAG, "%s: Oscillation not supported", LOG_STR_ARG(this->parent_.get_log_name()));
this->oscillating_.reset();
}
if (this->speed_.has_value() && !traits.supports_speed()) {
ESP_LOGW(TAG, "%s: Speed control not supported", this->parent_.get_name().c_str());
ESP_LOGW(TAG, "%s: Speed control not supported", LOG_STR_ARG(this->parent_.get_log_name()));
this->speed_.reset();
}
if (this->direction_.has_value() && !traits.supports_direction()) {
ESP_LOGW(TAG, "%s: Direction control not supported", this->parent_.get_name().c_str());
ESP_LOGW(TAG, "%s: Direction control not supported", LOG_STR_ARG(this->parent_.get_log_name()));
this->direction_.reset();
}
}
@@ -207,7 +208,7 @@ void Fan::publish_state() {
ESP_LOGV(TAG,
"'%s' >>\n"
" State: %s",
this->name_.c_str(), ONOFF(this->state));
LOG_STR_ARG(this->get_log_name()), ONOFF(this->state));
if (traits.supports_speed()) {
ESP_LOGV(TAG, " Speed: %d", this->speed);
}
+10 -10
View File
@@ -98,7 +98,7 @@ void FeedbackCover::set_open_sensor(binary_sensor::BinarySensor *open_feedback)
// setup callbacks to react to sensor changes
open_feedback->add_on_state_callback([this](bool state) {
ESP_LOGD(TAG, "'%s' - Open feedback '%s'.", this->name_.c_str(),
ESP_LOGD(TAG, "'%s' - Open feedback '%s'.", LOG_STR_ARG(this->get_log_name()),
state ? LOG_STR_LITERAL("STARTED") : LOG_STR_LITERAL("ENDED"));
this->recompute_position_();
if (!state && this->infer_endstop_ && this->current_trigger_operation_ == COVER_OPERATION_OPENING) {
@@ -112,7 +112,7 @@ void FeedbackCover::set_close_sensor(binary_sensor::BinarySensor *close_feedback
this->close_feedback_ = close_feedback;
close_feedback->add_on_state_callback([this](bool state) {
ESP_LOGD(TAG, "'%s' - Close feedback '%s'.", this->name_.c_str(),
ESP_LOGD(TAG, "'%s' - Close feedback '%s'.", LOG_STR_ARG(this->get_log_name()),
state ? LOG_STR_LITERAL("STARTED") : LOG_STR_LITERAL("ENDED"));
this->recompute_position_();
if (!state && this->infer_endstop_ && this->current_trigger_operation_ == COVER_OPERATION_CLOSING) {
@@ -151,7 +151,7 @@ void FeedbackCover::endstop_reached_(bool open_endstop) {
// from a position slightly past the endpoint
if (this->current_trigger_operation_ == (open_endstop ? COVER_OPERATION_OPENING : COVER_OPERATION_CLOSING)) {
float dur = (now - this->start_dir_time_) / 1e3f;
ESP_LOGD(TAG, "'%s' - %s endstop reached. Took %.1fs.", this->name_.c_str(),
ESP_LOGD(TAG, "'%s' - %s endstop reached. Took %.1fs.", LOG_STR_ARG(this->get_log_name()),
open_endstop ? LOG_STR_LITERAL("Open") : LOG_STR_LITERAL("Close"), dur);
// if there is no external mechanism, stop the cover
@@ -198,7 +198,7 @@ void FeedbackCover::set_close_obstacle_sensor(binary_sensor::BinarySensor *close
close_obstacle->add_on_state_callback([this](bool state) {
if (state && (this->current_operation == COVER_OPERATION_CLOSING ||
this->current_trigger_operation_ == COVER_OPERATION_CLOSING)) {
ESP_LOGD(TAG, "'%s' - Close obstacle detected.", this->name_.c_str());
ESP_LOGD(TAG, "'%s' - Close obstacle detected.", LOG_STR_ARG(this->get_log_name()));
this->start_direction_(COVER_OPERATION_IDLE);
if (this->obstacle_rollback_) {
@@ -215,7 +215,7 @@ void FeedbackCover::set_open_obstacle_sensor(binary_sensor::BinarySensor *open_o
open_obstacle->add_on_state_callback([this](bool state) {
if (state && (this->current_operation == COVER_OPERATION_OPENING ||
this->current_trigger_operation_ == COVER_OPERATION_OPENING)) {
ESP_LOGD(TAG, "'%s' - Open obstacle detected.", this->name_.c_str());
ESP_LOGD(TAG, "'%s' - Open obstacle detected.", LOG_STR_ARG(this->get_log_name()));
this->start_direction_(COVER_OPERATION_IDLE);
if (this->obstacle_rollback_) {
@@ -251,7 +251,7 @@ void FeedbackCover::loop() {
this->start_overshoot_time_ = now;
} else if (now - this->start_overshoot_time_ > this->overshoot_duration_ ||
now - this->start_dir_time_ > this->max_duration_) {
ESP_LOGD(TAG, "'%s' - Overshoot duration reached. Stopping cover.", this->name_.c_str());
ESP_LOGD(TAG, "'%s' - Overshoot duration reached. Stopping cover.", LOG_STR_ARG(this->get_log_name()));
this->start_direction_(COVER_OPERATION_IDLE);
}
#endif
@@ -259,7 +259,7 @@ void FeedbackCover::loop() {
this->start_direction_(COVER_OPERATION_IDLE);
}
} else if (now - this->start_dir_time_ > this->max_duration_) {
ESP_LOGD(TAG, "'%s' - Max duration reached. Stopping cover.", this->name_.c_str());
ESP_LOGD(TAG, "'%s' - Max duration reached. Stopping cover.", LOG_STR_ARG(this->get_log_name()));
this->start_direction_(COVER_OPERATION_IDLE);
}
}
@@ -390,7 +390,7 @@ void FeedbackCover::start_direction_(CoverOperation dir) {
// check if there is an obstacle to start the new operation -> abort without any change
// the case when an obstacle appears while moving is handled in the callback
if (obstacle != nullptr && obstacle->state) {
ESP_LOGD(TAG, "'%s' - %s obstacle detected. Action not started.", this->name_.c_str(),
ESP_LOGD(TAG, "'%s' - %s obstacle detected. Action not started.", LOG_STR_ARG(this->get_log_name()),
dir == COVER_OPERATION_OPENING ? LOG_STR_LITERAL("Open") : LOG_STR_LITERAL("Close"));
return;
}
@@ -401,13 +401,13 @@ void FeedbackCover::start_direction_(CoverOperation dir) {
if (this->direction_change_waittime_.has_value() && dir != COVER_OPERATION_IDLE &&
this->current_operation != COVER_OPERATION_IDLE && dir != this->current_operation) {
const uint32_t waittime = *this->direction_change_waittime_;
ESP_LOGD(TAG, "'%s' - Reversing direction.", this->name_.c_str());
ESP_LOGD(TAG, "'%s' - Reversing direction.", LOG_STR_ARG(this->get_log_name()));
this->start_direction_(COVER_OPERATION_IDLE);
this->set_timeout(DIRECTION_CHANGE_TIMEOUT_ID, waittime, [this, dir]() { this->start_direction_(dir); });
} else {
this->set_current_operation_(dir, true);
this->prev_command_trigger_ = trig;
ESP_LOGD(TAG, "'%s' - Firing '%s' trigger.", this->name_.c_str(),
ESP_LOGD(TAG, "'%s' - Firing '%s' trigger.", LOG_STR_ARG(this->get_log_name()),
dir == COVER_OPERATION_OPENING ? LOG_STR_LITERAL("OPEN")
: dir == COVER_OPERATION_CLOSING ? LOG_STR_LITERAL("CLOSE")
: LOG_STR_LITERAL("STOP"));
@@ -28,7 +28,7 @@ void GPIOSwitch::dump_config() {
for (auto *lock : this->interlock_) {
if (lock == this)
continue;
ESP_LOGCONFIG(TAG, " %s", lock->get_name().c_str());
ESP_LOGCONFIG(TAG, " %s", LOG_STR_ARG(lock->get_log_name()));
}
}
#endif
+3 -3
View File
@@ -58,7 +58,7 @@ void HE60rCover::endstop_reached_(CoverOperation operation) {
this->current_operation = COVER_OPERATION_IDLE;
if (this->last_command_ == operation) {
float dur = (float) (now - this->start_dir_time_) / 1e3f;
ESP_LOGD(TAG, "'%s' - %s endstop reached. Took %.1fs.", this->name_.c_str(),
ESP_LOGD(TAG, "'%s' - %s endstop reached. Took %.1fs.", LOG_STR_ARG(this->get_log_name()),
operation == COVER_OPERATION_OPENING ? LOG_STR_LITERAL("Open") : LOG_STR_LITERAL("Close"), dur);
}
this->publish_state();
@@ -207,7 +207,7 @@ void HE60rCover::start_direction_(CoverOperation dir) {
this->last_command_ = dir;
if (this->current_operation == dir)
return;
ESP_LOGD(TAG, "'%s' - Direction '%s' requested.", this->name_.c_str(),
ESP_LOGD(TAG, "'%s' - Direction '%s' requested.", LOG_STR_ARG(this->get_log_name()),
dir == COVER_OPERATION_OPENING ? LOG_STR_LITERAL("OPEN")
: dir == COVER_OPERATION_CLOSING ? LOG_STR_LITERAL("CLOSE")
: LOG_STR_LITERAL("STOP"));
@@ -223,7 +223,7 @@ void HE60rCover::start_direction_(CoverOperation dir) {
// just stop and reverse
this->toggles_needed_ = 2;
}
ESP_LOGD(TAG, "'%s' - Reversing direction.", this->name_.c_str());
ESP_LOGD(TAG, "'%s' - Reversing direction.", LOG_STR_ARG(this->get_log_name()));
}
this->start_dir_time_ = millis();
}
+1 -2
View File
@@ -1,5 +1,6 @@
import esphome.codegen as cg
from esphome.components import climate_ir
from esphome.components.const import CONF_HORIZONTAL_DEFAULT, CONF_VERTICAL_DEFAULT
import esphome.config_validation as cv
from esphome.const import (
CONF_MAX_TEMPERATURE,
@@ -76,13 +77,11 @@ PROTOCOLS = {
"r51m": Protocol.PROTOCOL_R51M,
}
CONF_HORIZONTAL_DEFAULT = "horizontal_default"
HorizontalDirections = heatpumpir_ns.enum("HorizontalDirections")
HORIZONTAL_DIRECTIONS = HorizontalDirections.options(
"auto", "middle", "left", "mleft", "mright", "right", prefix="HORIZONTAL_DIRECTION_"
)
CONF_VERTICAL_DEFAULT = "vertical_default"
VerticalDirections = heatpumpir_ns.enum("VerticalDirections")
VERTICAL_DIRECTIONS = VerticalDirections.options(
"auto", "up", "mup", "middle", "mdown", "down", prefix="VERTICAL_DIRECTION_"
@@ -27,7 +27,7 @@ void HomeassistantButton::press_action() {
#ifdef USE_API_WIZARD_LINKED_INPUTS
if (this->entity_id_[0] == '\0') {
ESP_LOGW(TAG, "'%s': No entity ID set yet", this->get_name().c_str());
ESP_LOGW(TAG, "'%s': No entity ID set yet", LOG_STR_ARG(this->get_log_name()));
return;
}
#endif
@@ -408,7 +408,7 @@ void HomeassistantLight::write_state(LightState *state) {
}
#ifdef USE_API_WIZARD_LINKED_INPUTS
if (this->entity_id_[0] == '\0') {
ESP_LOGW(TAG, "'%s': No entity ID set yet", state->get_name().c_str());
ESP_LOGW(TAG, "'%s': No entity ID set yet", LOG_STR_ARG(state->get_log_name()));
this->fall_back_();
return;
}
@@ -32,7 +32,7 @@ void HomeassistantNumber::min_retrieved_(StringRef min) {
ESP_LOGE(TAG, "'%s': Can't convert 'min' value '%s' to number!", this->entity_id_, min.c_str());
return;
}
ESP_LOGD(TAG, "'%s': Min retrieved: %s", get_name().c_str(), min.c_str());
ESP_LOGD(TAG, "'%s': Min retrieved: %s", LOG_STR_ARG(this->get_log_name()), min.c_str());
this->traits.set_min_value(min_value.value());
}
@@ -42,7 +42,7 @@ void HomeassistantNumber::max_retrieved_(StringRef max) {
ESP_LOGE(TAG, "'%s': Can't convert 'max' value '%s' to number!", this->entity_id_, max.c_str());
return;
}
ESP_LOGD(TAG, "'%s': Max retrieved: %s", get_name().c_str(), max.c_str());
ESP_LOGD(TAG, "'%s': Max retrieved: %s", LOG_STR_ARG(this->get_log_name()), max.c_str());
this->traits.set_max_value(max_value.value());
}
@@ -52,7 +52,7 @@ void HomeassistantNumber::step_retrieved_(StringRef step) {
ESP_LOGE(TAG, "'%s': Can't convert 'step' value '%s' to number!", this->entity_id_, step.c_str());
return;
}
ESP_LOGD(TAG, "'%s': Step Retrieved %s", get_name().c_str(), step.c_str());
ESP_LOGD(TAG, "'%s': Step Retrieved %s", LOG_STR_ARG(this->get_log_name()), step.c_str());
this->traits.set_step(step_value.value());
}
@@ -83,7 +83,7 @@ void HomeassistantNumber::control(float value) {
#ifdef USE_API_WIZARD_LINKED_INPUTS
if (this->entity_id_[0] == '\0') {
ESP_LOGW(TAG, "'%s': No entity ID set yet", this->get_name().c_str());
ESP_LOGW(TAG, "'%s': No entity ID set yet", LOG_STR_ARG(this->get_log_name()));
return;
}
#endif
@@ -123,7 +123,7 @@ void HomeassistantSelect::control(size_t index) {
#ifdef USE_API_WIZARD_LINKED_INPUTS
if (this->entity_id_[0] == '\0') {
ESP_LOGW(TAG, "'%s': No entity ID set yet", this->get_name().c_str());
ESP_LOGW(TAG, "'%s': No entity ID set yet", LOG_STR_ARG(this->get_log_name()));
return;
}
#endif
@@ -43,7 +43,7 @@ void HomeassistantSwitch::write_state(bool state) {
#ifdef USE_API_WIZARD_LINKED_INPUTS
if (this->entity_id_[0] == '\0') {
ESP_LOGW(TAG, "'%s': No entity ID set yet", this->get_name().c_str());
ESP_LOGW(TAG, "'%s': No entity ID set yet", LOG_STR_ARG(this->get_log_name()));
return;
}
#endif
@@ -82,7 +82,7 @@ void HomeassistantText::control(const std::string &value) {
#ifdef USE_API_WIZARD_LINKED_INPUTS
if (this->entity_id_[0] == '\0') {
ESP_LOGW(TAG, "'%s': No entity ID set yet", this->get_name().c_str());
ESP_LOGW(TAG, "'%s': No entity ID set yet", LOG_STR_ARG(this->get_log_name()));
return;
}
#endif
+1 -1
View File
@@ -25,7 +25,7 @@ void HX711Sensor::update() {
uint32_t result;
if (this->read_sensor_(&result)) {
int32_t value = static_cast<int32_t>(result);
ESP_LOGD(TAG, "'%s': Got value %" PRId32, this->name_.c_str(), value);
ESP_LOGD(TAG, "'%s': Got value %" PRId32, LOG_STR_ARG(this->get_log_name()), value);
this->publish_state(value);
}
}
+1 -1
View File
@@ -11,7 +11,7 @@ void Infrared::dump_config() {
"Infrared '%s'\n"
" Supports Transmitter: %s\n"
" Supports Receiver: %s",
this->get_name().c_str(), YESNO(this->get_supports_transmitter()),
LOG_STR_ARG(this->get_log_name()), YESNO(this->get_supports_transmitter()),
YESNO(this->get_supports_receiver()));
}
+4 -3
View File
@@ -143,7 +143,7 @@ bool IrRfEntity::expect_api_reply_(api::APIConnection *conn) {
if (this->api_reply_ == ApiReply::API_REPLY_WAITING)
this->finish_api_reply_(false);
if (this->api_reply_ != ApiReply::API_REPLY_NONE && !this->send_api_reply_()) {
ESP_LOGW(TAG, "'%s': transmit %s", this->get_name().c_str(), LOG_STR_LITERAL("refused, reply still owed"));
ESP_LOGW(TAG, "'%s': transmit %s", LOG_STR_ARG(this->get_log_name()), LOG_STR_LITERAL("refused, reply still owed"));
this->refuse_api_call_(conn);
return false;
}
@@ -198,13 +198,14 @@ void IrRfEntity::loop() {
if (this->api_reply_ != ApiReply::API_REPLY_WAITING) {
if (this->send_api_reply_() || remaining > 0)
return;
ESP_LOGW(TAG, "'%s': transmit %s", this->get_name().c_str(), LOG_STR_LITERAL("reply dropped, client not reading"));
ESP_LOGW(TAG, "'%s': transmit %s", LOG_STR_ARG(this->get_log_name()),
LOG_STR_LITERAL("reply dropped, client not reading"));
this->clear_api_reply_();
return;
}
if (remaining > 0)
return;
ESP_LOGW(TAG, "'%s': transmit %s", this->get_name().c_str(), LOG_STR_LITERAL("never reported completion"));
ESP_LOGW(TAG, "'%s': transmit %s", LOG_STR_ARG(this->get_log_name()), LOG_STR_LITERAL("never reported completion"));
this->finish_api_reply_(false);
}
@@ -17,7 +17,7 @@ void IrRfProxy::dump_config() {
"IR Proxy '%s'\n"
" Supports Transmitter: %s\n"
" Supports Receiver: %s",
this->get_name().c_str(), YESNO(this->get_supports_transmitter()),
LOG_STR_ARG(this->get_log_name()), YESNO(this->get_supports_transmitter()),
YESNO(this->get_supports_receiver()));
if (this->is_rf()) {
@@ -44,7 +44,7 @@ void RfProxy::dump_config() {
"RF Proxy '%s'\n"
" Supports Transmitter: %s\n"
" Supports Receiver: %s",
this->get_name().c_str(), YESNO(this->get_supports_transmitter()),
LOG_STR_ARG(this->get_log_name()), YESNO(this->get_supports_transmitter()),
YESNO(this->get_supports_receiver()));
const auto &traits = this->traits_;
+4 -4
View File
@@ -15,7 +15,7 @@ void PolygonZone::setup() {
if (saved.is_valid()) {
this->polygon_ = saved;
} else {
ESP_LOGW(TAG, "'%s': saved polygon is invalid; zone disabled", this->get_name().c_str());
ESP_LOGW(TAG, "'%s': saved polygon is invalid; zone disabled", LOG_STR_ARG(this->get_log_name()));
}
}
// Presence stays unknown until the first radar frame
@@ -33,11 +33,11 @@ void PolygonZone::dump_config() {
void PolygonZone::control(const std::string &value) {
Polygon polygon;
if (!polygon.parse(value.c_str(), value.size())) {
ESP_LOGW(TAG, "'%s': invalid polygon '%s'; expected 'x,y;x,y;...' with %u to %u points", this->get_name().c_str(),
value.c_str(), MIN_POLYGON_POINTS, MAX_POLYGON_POINTS);
ESP_LOGW(TAG, "'%s': invalid polygon '%s'; expected 'x,y;x,y;...' with %u to %u points",
LOG_STR_ARG(this->get_log_name()), value.c_str(), MIN_POLYGON_POINTS, MAX_POLYGON_POINTS);
} else if (!this->pref_.save(&polygon)) {
// On ESP8266, the space for saved settings is small and can run out with several zones
ESP_LOGW(TAG, "'%s': could not save the polygon; keeping the previous one", this->get_name().c_str());
ESP_LOGW(TAG, "'%s': could not save the polygon; keeping the previous one", LOG_STR_ARG(this->get_log_name()));
} else {
this->polygon_ = polygon;
// A target seen inside the previous polygon must not keep the new one on
+2 -2
View File
@@ -1041,8 +1041,8 @@ void LD6002BComponent::publish_number_clamped_(number::Number *number, float val
// Outside the declared range the user cannot write the value back, so publish
// what they can reach and say what the module actually sent.
if (value < min_value || value > max_value) {
ESP_LOGW(TAG, "'%s': module reported %.1f, clamped to %.1f..%.1f", number->get_name().c_str(), value, min_value,
max_value);
ESP_LOGW(TAG, "'%s': module reported %.1f, clamped to %.1f..%.1f", LOG_STR_ARG(number->get_log_name()), value,
min_value, max_value);
value = std::clamp(value, min_value, max_value);
}
number->publish_state(value);
@@ -132,7 +132,7 @@ void AddressableLight::call_setup() {
#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
this->set_interval(5000, [this]() {
const char *name = this->state_parent_ == nullptr ? "" : this->state_parent_->get_name().c_str();
const char *name = this->state_parent_ == nullptr ? "" : LOG_STR_ARG(this->state_parent_->get_log_name());
ESP_LOGVV(TAG, "Addressable Light '%s' (effect_active=%s)", name, YESNO(this->effect_active_));
for (int i = 0; i < this->size(); i++) {
auto color = this->get(i);
+8 -8
View File
@@ -74,7 +74,7 @@ static void log_percent(const LogString *param, float value) {
#endif
void LightCall::perform() {
const char *name = this->parent_->get_name().c_str();
const char *name = LOG_STR_ARG(this->parent_->get_log_name());
LightColorValues v = this->validate_();
const bool publish = this->get_publish_();
@@ -182,7 +182,7 @@ void LightCall::perform() {
}
void LightCall::log_and_clear_unsupported_(FieldFlags flag, const LogString *feature, bool use_color_mode_log) {
auto *name = this->parent_->get_name().c_str();
auto *name = LOG_STR_ARG(this->parent_->get_log_name());
if (use_color_mode_log) {
log_color_mode_not_supported(name, feature);
} else {
@@ -192,7 +192,7 @@ void LightCall::log_and_clear_unsupported_(FieldFlags flag, const LogString *fea
}
LightColorValues LightCall::validate_() {
auto *name = this->parent_->get_name().c_str();
auto *name = LOG_STR_ARG(this->parent_->get_log_name());
auto traits = this->parent_->get_traits();
// Snapshot before the adjustments below add flags of their own
@@ -446,7 +446,7 @@ void LightCall::transform_parameters_(const LightTraits &traits) {
!(this->color_mode_ & ColorCapability::COLOR_TEMPERATURE) && //
min_mireds > 0.0f && max_mireds > 0.0f) {
ESP_LOGV(TAG, "'%s': setting cold/warm white channels using white/color temperature values",
this->parent_->get_name().c_str());
LOG_STR_ARG(this->parent_->get_log_name()));
// Only compute cold_white/warm_white from color_temperature if they're not already explicitly set.
// This is important for state restoration, where both color_temperature and cold_white/warm_white
// are restored from flash - we want to preserve the saved cold_white/warm_white values.
@@ -492,7 +492,7 @@ ColorMode LightCall::compute_color_mode_(const LightTraits &traits) {
// Don't change if the current mode is in the intersection (suitable AND supported)
if (ColorModeMask::mask_contains(intersection, current_mode)) {
ESP_LOGV(TAG, "'%s': color mode not specified; retaining %s", this->parent_->get_name().c_str(),
ESP_LOGV(TAG, "'%s': color mode not specified; retaining %s", LOG_STR_ARG(this->parent_->get_log_name()),
LOG_STR_ARG(color_mode_to_human(current_mode)));
return current_mode;
}
@@ -500,7 +500,7 @@ ColorMode LightCall::compute_color_mode_(const LightTraits &traits) {
// Use the preferred suitable mode.
if (intersection != 0) {
ColorMode mode = ColorModeMask::first_value_from_mask(intersection);
ESP_LOGV(TAG, "'%s': color mode not specified; using %s", this->parent_->get_name().c_str(),
ESP_LOGV(TAG, "'%s': color mode not specified; using %s", LOG_STR_ARG(this->parent_->get_log_name()),
LOG_STR_ARG(color_mode_to_human(mode)));
return mode;
}
@@ -508,7 +508,7 @@ ColorMode LightCall::compute_color_mode_(const LightTraits &traits) {
// There's no supported mode for this call, so warn, use the current more or a mode at random and let validation strip
// out whatever we don't support.
auto color_mode = current_mode != ColorMode::UNKNOWN ? current_mode : *supported_modes.begin();
ESP_LOGW(TAG, "'%s': no suitable color mode supported; defaulting to %s", this->parent_->get_name().c_str(),
ESP_LOGW(TAG, "'%s': no suitable color mode supported; defaulting to %s", LOG_STR_ARG(this->parent_->get_log_name()),
LOG_STR_ARG(color_mode_to_human(color_mode)));
return color_mode;
}
@@ -587,7 +587,7 @@ LightCall &LightCall::set_effect(const char *effect, size_t len) {
}
}
if (!found) {
ESP_LOGW(TAG, "'%s': no such effect '%.*s'", this->parent_->get_name().c_str(), (int) len, effect);
ESP_LOGW(TAG, "'%s': no such effect '%.*s'", LOG_STR_ARG(this->parent_->get_log_name()), (int) len, effect);
}
return *this;
}
+1 -1
View File
@@ -91,7 +91,7 @@ void LightState::setup() {
call.perform();
}
void LightState::dump_config() {
ESP_LOGCONFIG(TAG, "Light '%s'", this->get_name().c_str());
ESP_LOGCONFIG(TAG, "Light '%s'", LOG_STR_ARG(this->get_log_name()));
auto traits = this->get_traits();
if (traits.supports_color_capability(ColorCapability::BRIGHTNESS)) {
#ifdef USE_LIGHT_GAMMA_LUT
+5 -5
View File
@@ -30,10 +30,10 @@ void Lock::lock() { this->set_state_(LOCK_STATE_LOCKED); }
void Lock::unlock() { this->set_state_(LOCK_STATE_UNLOCKED); }
void Lock::open() {
if (traits.get_supports_open()) {
ESP_LOGD(TAG, "'%s' Opening.", this->get_name().c_str());
ESP_LOGD(TAG, "'%s' Opening.", LOG_STR_ARG(this->get_log_name()));
this->open_latch();
} else {
ESP_LOGW(TAG, "'%s' Does not support Open.", this->get_name().c_str());
ESP_LOGW(TAG, "'%s' Does not support Open.", LOG_STR_ARG(this->get_log_name()));
}
}
void Lock::publish_state(LockState state) {
@@ -42,7 +42,7 @@ void Lock::publish_state(LockState state) {
this->state = state;
this->rtc_.save(&this->state);
ESP_LOGV(TAG, "'%s' >> %s", this->name_.c_str(), LOG_STR_ARG(lock_state_to_string(state)));
ESP_LOGV(TAG, "'%s' >> %s", LOG_STR_ARG(this->get_log_name()), LOG_STR_ARG(lock_state_to_string(state)));
this->state_callback_.call(state);
#if defined(USE_LOCK) && defined(USE_CONTROLLER_REGISTRY)
ControllerRegistry::notify_lock_update(this);
@@ -50,7 +50,7 @@ void Lock::publish_state(LockState state) {
}
void LockCall::perform() {
ESP_LOGV(TAG, "'%s' - Setting", this->parent_->get_name().c_str());
ESP_LOGV(TAG, "'%s' - Setting", LOG_STR_ARG(this->parent_->get_log_name()));
this->validate_();
if (this->state_.has_value()) {
ESP_LOGV(TAG, " State: %s", LOG_STR_ARG(lock_state_to_string(*this->state_)));
@@ -92,7 +92,7 @@ LockCall &LockCall::set_state(const char *state) {
} else if (ESPHOME_strcasecmp_P(state, ESPHOME_PSTR("NONE")) == 0) {
this->set_state(LOCK_STATE_NONE);
} else {
ESP_LOGW(TAG, "'%s' - Unrecognized state %s", this->parent_->get_name().c_str(), state);
ESP_LOGW(TAG, "'%s' - Unrecognized state %s", LOG_STR_ARG(this->parent_->get_log_name()), state);
}
return *this;
}
+8 -8
View File
@@ -91,28 +91,28 @@ bool MAX31856Sensor::has_fault_() {
this->status_set_warning();
if ((faults & MAX31856_FAULT_CJRANGE) == MAX31856_FAULT_CJRANGE) {
ESP_LOGW(TAG, "Cold Junction Out-of-Range: '%s'", this->name_.c_str());
ESP_LOGW(TAG, "Cold Junction Out-of-Range: '%s'", LOG_STR_ARG(this->get_log_name()));
}
if ((faults & MAX31856_FAULT_TCRANGE) == MAX31856_FAULT_TCRANGE) {
ESP_LOGW(TAG, "Thermocouple Out-of-Range: '%s'", this->name_.c_str());
ESP_LOGW(TAG, "Thermocouple Out-of-Range: '%s'", LOG_STR_ARG(this->get_log_name()));
}
if ((faults & MAX31856_FAULT_CJHIGH) == MAX31856_FAULT_CJHIGH) {
ESP_LOGW(TAG, "Cold-Junction High Fault: '%s'", this->name_.c_str());
ESP_LOGW(TAG, "Cold-Junction High Fault: '%s'", LOG_STR_ARG(this->get_log_name()));
}
if ((faults & MAX31856_FAULT_CJLOW) == MAX31856_FAULT_CJLOW) {
ESP_LOGW(TAG, "Cold-Junction Low Fault: '%s'", this->name_.c_str());
ESP_LOGW(TAG, "Cold-Junction Low Fault: '%s'", LOG_STR_ARG(this->get_log_name()));
}
if ((faults & MAX31856_FAULT_TCHIGH) == MAX31856_FAULT_TCHIGH) {
ESP_LOGW(TAG, "Thermocouple Temperature High Fault: '%s'", this->name_.c_str());
ESP_LOGW(TAG, "Thermocouple Temperature High Fault: '%s'", LOG_STR_ARG(this->get_log_name()));
}
if ((faults & MAX31856_FAULT_TCLOW) == MAX31856_FAULT_TCLOW) {
ESP_LOGW(TAG, "Thermocouple Temperature Low Fault: '%s'", this->name_.c_str());
ESP_LOGW(TAG, "Thermocouple Temperature Low Fault: '%s'", LOG_STR_ARG(this->get_log_name()));
}
if ((faults & MAX31856_FAULT_OVUV) == MAX31856_FAULT_OVUV) {
ESP_LOGW(TAG, "Overvoltage or Undervoltage Input Fault: '%s'", this->name_.c_str());
ESP_LOGW(TAG, "Overvoltage or Undervoltage Input Fault: '%s'", LOG_STR_ARG(this->get_log_name()));
}
if ((faults & MAX31856_FAULT_OPEN) == MAX31856_FAULT_OPEN) {
ESP_LOGW(TAG, "Thermocouple Open-Circuit Fault (possibly not connected): '%s'", this->name_.c_str());
ESP_LOGW(TAG, "Thermocouple Open-Circuit Fault (possibly not connected): '%s'", LOG_STR_ARG(this->get_log_name()));
}
return true;
+1 -1
View File
@@ -66,7 +66,7 @@ void MAX31888Sensor::update() {
return;
}
const float temperature = raw * MAX31888_DEGREES_PER_LSB;
ESP_LOGD(TAG, "'%s': Got Temperature=%.3f°C", this->get_name().c_str(), temperature);
ESP_LOGD(TAG, "'%s': Got Temperature=%.3f°C", LOG_STR_ARG(this->get_log_name()), temperature);
this->status_clear_warning();
this->publish_state(temperature);
});
+1 -1
View File
@@ -38,7 +38,7 @@ void MAX6675Sensor::read_data_() {
}
float temperature = float(val >> 3) / 4.0f;
ESP_LOGD(TAG, "'%s': Got temperature=%.1f°C", this->name_.c_str(), temperature);
ESP_LOGD(TAG, "'%s': Got temperature=%.1f°C", LOG_STR_ARG(this->get_log_name()), temperature);
this->publish_state(temperature);
}
+4 -4
View File
@@ -23,7 +23,7 @@ void MCP9808Sensor::setup() {
return;
}
if (manu != MCP9808_MANUF_ID) {
ESP_LOGE(TAG, "Incorrect manufacturer ID (%X) for '%s'", manu, this->name_.c_str());
ESP_LOGE(TAG, "Incorrect manufacturer ID (%X) for '%s'", manu, LOG_STR_ARG(this->get_log_name()));
this->mark_failed(LOG_STR("Wrong chip ID"));
return;
}
@@ -33,13 +33,13 @@ void MCP9808Sensor::setup() {
return;
}
if (dev_id != MCP9808_DEV_ID) {
ESP_LOGE(TAG, "Incorrect device ID (%X) for '%s'", dev_id, this->name_.c_str());
ESP_LOGE(TAG, "Incorrect device ID (%X) for '%s'", dev_id, LOG_STR_ARG(this->get_log_name()));
this->mark_failed(LOG_STR("Wrong chip ID"));
return;
}
}
void MCP9808Sensor::dump_config() {
ESP_LOGCONFIG(TAG, "%s:", this->name_.c_str());
ESP_LOGCONFIG(TAG, "%s:", LOG_STR_ARG(this->get_log_name()));
LOG_I2C_DEVICE(this);
LOG_UPDATE_INTERVAL(this);
LOG_SENSOR(" ", "Temperature", this);
@@ -71,7 +71,7 @@ void MCP9808Sensor::update() {
if (!this->status_comm_result(!std::isnan(temp), nullptr))
return;
ESP_LOGD(TAG, "%s: Got temperature=%.4f°C", this->name_.c_str(), temp);
ESP_LOGD(TAG, "%s: Got temperature=%.4f°C", LOG_STR_ARG(this->get_log_name()), temp);
this->publish_state(temp);
}
@@ -109,7 +109,7 @@ void MediaPlayerCall::validate_() {
}
void MediaPlayerCall::perform() {
ESP_LOGV(TAG, "'%s' - Setting", this->parent_->get_name().c_str());
ESP_LOGV(TAG, "'%s' - Setting", LOG_STR_ARG(this->parent_->get_log_name()));
this->validate_();
if (this->command_.has_value()) {
const char *command_s = media_player_command_to_string(this->command_.value());
@@ -177,7 +177,7 @@ MediaPlayerCall &MediaPlayerCall::set_command(const char *command) {
} else if (ESPHOME_strcasecmp_P(command, ESPHOME_PSTR("GROUP_JOIN")) == 0) {
this->set_command(MEDIA_PLAYER_COMMAND_GROUP_JOIN);
} else {
ESP_LOGW(TAG, "'%s' - Unrecognized command %s", this->parent_->get_name().c_str(), command);
ESP_LOGW(TAG, "'%s' - Unrecognized command %s", LOG_STR_ARG(this->parent_->get_log_name()), command);
}
return *this;
}
+1 -1
View File
@@ -35,7 +35,7 @@ void MiCS5524GasSensor::publish_ratio(float ratio, micsmath::ConversionModel mod
micsmath::clamp_ppm(micsmath::ppm_from_power_law(this->p0_, this->p1_, ratio), this->min_ppm_, this->max_ppm_);
}
#endif
ESP_LOGD(TAG, "'%s': ratio=%.4f -> %.1f ppm", this->get_name().c_str(), ratio, ppm);
ESP_LOGD(TAG, "'%s': ratio=%.4f -> %.1f ppm", LOG_STR_ARG(this->get_log_name()), ratio, ppm);
this->publish_state(ppm);
}
+1 -2
View File
@@ -1,5 +1,6 @@
import esphome.codegen as cg
from esphome.components import climate_ir
from esphome.components.const import CONF_HORIZONTAL_DEFAULT, CONF_VERTICAL_DEFAULT
import esphome.config_validation as cv
from esphome.types import ConfigType
@@ -22,7 +23,6 @@ CONF_SUPPORTS_DRY = "supports_dry"
CONF_SUPPORTS_FAN_ONLY = "supports_fan_only"
CONF_FAHRENHEIT_COMPATIBILITY = "fahrenheit_compatibility"
CONF_HORIZONTAL_DEFAULT = "horizontal_default"
HorizontalDirections = mitsubishi_ns.enum("HorizontalDirections")
HORIZONTAL_DIRECTIONS = HorizontalDirections.options(
"left",
@@ -34,7 +34,6 @@ HORIZONTAL_DIRECTIONS = HorizontalDirections.options(
prefix="HORIZONTAL_DIRECTION_",
)
CONF_VERTICAL_DEFAULT = "vertical_default"
VerticalDirections = mitsubishi_ns.enum("VerticalDirections")
VERTICAL_DIRECTIONS = VerticalDirections.options(
"auto",
+1 -1
View File
@@ -174,7 +174,7 @@ void MLX90614Component::update() {
// Bit 15 set means the device flagged the reading as invalid
const float temperature = (raw & 0x8000) ? NAN : raw * 0.02f - 273.15f;
ESP_LOGD(TAG, "'%s': Got temperature=%.1f°C", sensor->get_name().c_str(), temperature);
ESP_LOGD(TAG, "'%s': Got temperature=%.1f°C", LOG_STR_ARG(sensor->get_log_name()), temperature);
sensor->publish_state(temperature);
return ec;
};
@@ -57,7 +57,8 @@ void ModbusNumber::control(float value) {
bytes.push_back(word_bytes[1]);
}
if (!this->send_raw_frame_deprecated_(std::span<const uint8_t>(bytes.data(), bytes.size()))) {
ESP_LOGW(TAG, "Modbus write for '%s' was refused by the hub; state not published", this->get_name().c_str());
ESP_LOGW(TAG, "Modbus write for '%s' was refused by the hub; state not published",
LOG_STR_ARG(this->get_log_name()));
return;
}
this->publish_state(value);
@@ -82,7 +83,7 @@ void ModbusNumber::control(float value) {
ESP_LOGD(TAG,
"Updating register: connected Sensor=%s start address=0x%X register count=%d new value=%.02f (val=%.02f)",
this->get_name().c_str(), this->start_address, this->entity_count(), value, write_value);
LOG_STR_ARG(this->get_log_name()), this->start_address, this->entity_count(), value, write_value);
bool queued;
if (this->entity_count() == 1 && !this->use_write_multiple_) {
@@ -91,7 +92,8 @@ void ModbusNumber::control(float value) {
queued = this->write_multiple_registers(this->write_address(), data);
}
if (!queued) {
ESP_LOGW(TAG, "Modbus write for '%s' was refused by the hub; state not published", this->get_name().c_str());
ESP_LOGW(TAG, "Modbus write for '%s' was refused by the hub; state not published",
LOG_STR_ARG(this->get_log_name()));
return;
}
this->publish_state(value);
@@ -100,7 +100,8 @@ void ModbusSelect::control(size_t index) {
}
if (!queued) {
ESP_LOGW(TAG, "Modbus write for '%s' was refused by the hub; state not published", this->get_name().c_str());
ESP_LOGW(TAG, "Modbus write for '%s' was refused by the hub; state not published",
LOG_STR_ARG(this->get_log_name()));
return;
}
if (this->optimistic_)
@@ -48,7 +48,7 @@ void ModbusSwitch::parse_and_publish(std::span<const uint8_t> data) {
}
}
ESP_LOGV(TAG, "Publish '%s': new value = %s type = %d address = %X offset = %zx", this->get_name().c_str(),
ESP_LOGV(TAG, "Publish '%s': new value = %s type = %d address = %X offset = %zx", LOG_STR_ARG(this->get_log_name()),
ONOFF(value), (int) this->register_type, this->start_address, offset);
this->publish_state(value);
}
@@ -73,7 +73,8 @@ void ModbusSwitch::write_state(bool state) {
ESP_LOGV_HEX(TAG, data.data(), data.size(), MODBUS_SWITCH_MAX_LOG_BYTES, "Modbus Switch write raw: %s");
// The lambda filled a legacy raw frame (device address + function code + data).
if (!this->send_raw_frame_deprecated_(data)) {
ESP_LOGW(TAG, "Modbus write for '%s' was refused by the hub; state not published", this->get_name().c_str());
ESP_LOGW(TAG, "Modbus write for '%s' was refused by the hub; state not published",
LOG_STR_ARG(this->get_log_name()));
return;
}
this->publish_state(state);
@@ -89,8 +90,8 @@ void ModbusSwitch::write_state(bool state) {
write_value = val.value();
}
ESP_LOGV(TAG, "write_state '%s': new value = %s (wire = %s) type = %d address = %X offset = %x",
this->get_name().c_str(), ONOFF(state), ONOFF(write_value), (int) this->register_type, this->start_address,
this->offset);
LOG_STR_ARG(this->get_log_name()), ONOFF(state), ONOFF(write_value), (int) this->register_type,
this->start_address, this->offset);
bool queued;
if (this->register_type == EntityType::COIL) {
// offset for coil and discrete inputs is the coil/register number not bytes
@@ -109,7 +110,8 @@ void ModbusSwitch::write_state(bool state) {
}
}
if (!queued) {
ESP_LOGW(TAG, "Modbus write for '%s' was refused by the hub; state not published", this->get_name().c_str());
ESP_LOGW(TAG, "Modbus write for '%s' was refused by the hub; state not published",
LOG_STR_ARG(this->get_log_name()));
return;
}
this->publish_state(state);
+62 -26
View File
@@ -1,8 +1,10 @@
from esphome import automation
import esphome.codegen as cg
from esphome.components import logger, network, socket
from esphome.components.const import CONF_VERIFY_SSL
from esphome.components.esp32 import (
add_idf_component,
allow_insecure_tls,
idf_version,
include_builtin_idf_component,
request_tls,
@@ -79,6 +81,7 @@ def AUTO_LOAD():
return ["json"]
CONF_TLS = "tls"
CONF_IDF_SEND_ASYNC = "idf_send_async"
CONF_WAIT_FOR_CONNECTION = "wait_for_connection"
CONF_TRANSPORT = "transport"
@@ -187,26 +190,8 @@ def _validate_transport(value: str) -> str:
def validate_config(value):
transport = value.get(CONF_TRANSPORT)
# A certificate with plain ws is almost certainly a typo for wss
if transport == MQTT_TRANSPORT_WS and (
CONF_CERTIFICATE_AUTHORITY in value or CONF_CLIENT_CERTIFICATE in value
):
raise cv.Invalid(
"transport 'ws' is unencrypted; remove the certificate options "
"or switch to transport 'wss'"
)
# TLS runs only with a CA or over wss, so a client certificate needs one of them
if (
CONF_CLIENT_CERTIFICATE in value
and CONF_CERTIFICATE_AUTHORITY not in value
and transport != MQTT_TRANSPORT_WSS
):
raise cv.Invalid(
"'client_certificate' requires 'certificate_authority' or transport 'wss'"
)
if (
transport not in (MQTT_TRANSPORT_WS, MQTT_TRANSPORT_WSS)
value.get(CONF_TRANSPORT) not in (MQTT_TRANSPORT_WS, MQTT_TRANSPORT_WSS)
and CONF_WS_PATH in value
):
raise cv.Invalid(
@@ -260,6 +245,47 @@ def validate_config(value):
return out
# Keys that only make sense over TLS; any of them switches it on
TLS_IMPLYING_KEYS = frozenset(
{CONF_CERTIFICATE_AUTHORITY, CONF_VERIFY_SSL, CONF_CLIENT_CERTIFICATE}
)
def _derive_tls(config: ConfigType) -> ConfigType:
"""Derive ``tls`` from the certificate options and the transport, reject contradictions, pick the port."""
# skip_cert_cn_check has a default on ESP32, so its value decides, not its presence
if config.get(CONF_VERIFY_SSL) is False and config.get(CONF_SKIP_CERT_CN_CHECK):
raise cv.Invalid(
"'skip_cert_cn_check' has no effect when 'verify_ssl' is false."
)
transport = config.get(CONF_TRANSPORT)
if (
config.keys() & TLS_IMPLYING_KEYS
or config.get(CONF_SKIP_CERT_CN_CHECK)
or transport == MQTT_TRANSPORT_WSS
):
if config.get(CONF_TLS) is False:
raise cv.Invalid(
"'tls' cannot be false when a certificate, 'verify_ssl', "
"'skip_cert_cn_check' or transport 'wss' is set."
)
config[CONF_TLS] = True
# TLS with plain ws is almost certainly a typo for wss
if transport == MQTT_TRANSPORT_WS and config.get(CONF_TLS):
raise cv.Invalid(
"transport 'ws' is unencrypted; remove the TLS options "
"or switch to transport 'wss'"
)
config.setdefault(CONF_PORT, 8883 if config.get(CONF_TLS) else 1883)
return config
_validate_tls = cv.All(
cv.only_when(CONF_CERTIFICATE_AUTHORITY, CONF_VERIFY_SSL, False, negate=True),
_derive_tls,
)
def _consume_mqtt_sockets(config: ConfigType) -> ConfigType:
"""Register socket needs for MQTT component."""
# MQTT needs 1 socket for the broker connection
@@ -283,7 +309,7 @@ CONFIG_SCHEMA = cv.All(
cv.GenerateID(): cv.declare_id(MQTTClientComponent),
cv.Required(CONF_BROKER): cv.string_strict,
cv.Optional(CONF_ENABLE_ON_BOOT, default=True): cv.boolean,
cv.Optional(CONF_PORT, default=1883): cv.port,
cv.Optional(CONF_PORT): cv.port,
cv.Optional(CONF_USERNAME, default=""): cv.string,
cv.Optional(CONF_PASSWORD, default=""): cv.sensitive(),
cv.Optional(CONF_CLEAN_SESSION, default=False): cv.boolean,
@@ -295,6 +321,8 @@ CONFIG_SCHEMA = cv.All(
cv.SplitDefault(CONF_IDF_SEND_ASYNC, esp32=False): cv.All(
cv.boolean, cv.only_on_esp32
),
cv.Optional(CONF_TLS): cv.All(cv.boolean, cv.only_on_esp32),
cv.Optional(CONF_VERIFY_SSL): cv.All(cv.boolean, cv.only_on_esp32),
cv.Optional(CONF_CERTIFICATE_AUTHORITY): cv.All(
cv.string, cv.only_on_esp32
),
@@ -356,6 +384,7 @@ CONFIG_SCHEMA = cv.All(
}
),
validate_config,
_validate_tls,
cv.only_on(
[
PLATFORM_BK72XX,
@@ -497,21 +526,28 @@ async def to_code(config):
# esp-idf only
transport = config.get(CONF_TRANSPORT)
ca = cg.add_optional(var.set_ca_certificate, config.get(CONF_CERTIFICATE_AUTHORITY))
if ca is not None or transport == MQTT_TRANSPORT_WSS:
cg.add(var.set_skip_cert_cn_check(config[CONF_SKIP_CERT_CN_CHECK]))
if config.get(CONF_TLS):
cg.add_define("USE_MQTT_TLS")
if (client_certificate := config.get(CONF_CLIENT_CERTIFICATE)) is not None:
cg.add(var.set_cl_certificate(client_certificate))
cg.add(var.set_cl_key(config[CONF_CLIENT_CERTIFICATE_KEY]))
if config.get(CONF_SKIP_CERT_CN_CHECK):
cg.add(var.set_skip_cert_cn_check(True))
# Trust source: none, the given CA, or the certificate bundle
if config.get(CONF_VERIFY_SSL) is False:
cg.add_define("USE_MQTT_TLS_INSECURE")
allow_insecure_tls()
elif (ca := config.get(CONF_CERTIFICATE_AUTHORITY)) is not None:
cg.add(var.set_ca_certificate(ca))
else:
cg.add_define("USE_MQTT_CERT_BUNDLE")
require_certificate_bundle()
if CORE.is_esp32:
if transport != MQTT_TRANSPORT_TCP:
cg.add(var.set_transport(transport))
if transport in (MQTT_TRANSPORT_WS, MQTT_TRANSPORT_WSS):
cg.add(var.set_ws_path(config.get(CONF_WS_PATH, DEFAULT_WS_PATH)))
# wss without an explicit CA verifies the broker against the bundled roots
if transport == MQTT_TRANSPORT_WSS and ca is None:
require_certificate_bundle()
if CONF_IDF_SEND_ASYNC in config and config[CONF_IDF_SEND_ASYNC]:
cg.add_define("USE_MQTT_IDF_ENQUEUE")
@@ -59,9 +59,9 @@ void MQTTAlarmControlPanelComponent::setup() {
if (!root.isNull()) {
const char *state = root[ESPHOME_F("state")];
if (state == nullptr) {
ESP_LOGW(TAG, "'%s': JSON payload missing 'state' key", this->friendly_name_().c_str());
ESP_LOGW(TAG, "'%s': JSON payload missing 'state' key", LOG_STR_ARG(this->log_name_()));
} else if (!apply_command(call, state)) {
ESP_LOGW(TAG, "'%s': Received unknown state in JSON payload: %s", this->friendly_name_().c_str(), state);
ESP_LOGW(TAG, "'%s': Received unknown state in JSON payload: %s", LOG_STR_ARG(this->log_name_()), state);
} else {
const char *code = root[ESPHOME_F("code")];
if (code != nullptr) {
@@ -70,7 +70,7 @@ void MQTTAlarmControlPanelComponent::setup() {
}
}
} else if (!apply_command(call, payload.c_str())) {
ESP_LOGW(TAG, "'%s': Received unknown command payload %s", this->friendly_name_().c_str(), payload.c_str());
ESP_LOGW(TAG, "'%s': Received unknown command payload %s", LOG_STR_ARG(this->log_name_()), payload.c_str());
}
call.perform();
});
+22 -28
View File
@@ -8,7 +8,7 @@
#include "esphome/core/log.h"
#include "esphome/core/application.h"
#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
#ifdef USE_MQTT_CERT_BUNDLE
#include "esp_crt_bundle.h"
#endif
@@ -43,46 +43,36 @@ bool MQTTBackendESP32::initialize_() {
if (!this->client_id_.empty()) {
mqtt_cfg_.credentials.client_id = this->client_id_.c_str();
}
// Plain TCP keeps upgrading to SSL when a CA certificate is configured
bool uses_tls = false;
#ifdef USE_MQTT_TLS
mqtt_cfg_.broker.verification.skip_cert_common_name_check = this->skip_cert_cn_check_;
mqtt_cfg_.broker.verification.certificate = this->ca_certificate_;
#ifdef USE_MQTT_CERT_BUNDLE
mqtt_cfg_.broker.verification.crt_bundle_attach = esp_crt_bundle_attach;
#endif
// Validation only accepts the client certificate together with its key
mqtt_cfg_.credentials.authentication.certificate = this->cl_certificate_;
mqtt_cfg_.credentials.authentication.key = this->cl_key_;
#endif
// Validation keeps TLS off plain ws, so only the TCP transport has two forms
switch (this->transport_) {
case MQTTTransport::MQTT_TRANSPORT_WS:
mqtt_cfg_.broker.address.transport = MQTT_TRANSPORT_OVER_WS;
break;
case MQTTTransport::MQTT_TRANSPORT_WSS:
mqtt_cfg_.broker.address.transport = MQTT_TRANSPORT_OVER_WSS;
uses_tls = true;
break;
case MQTTTransport::MQTT_TRANSPORT_TCP:
default:
if (this->ca_certificate_.has_value()) {
mqtt_cfg_.broker.address.transport = MQTT_TRANSPORT_OVER_SSL;
uses_tls = true;
} else {
mqtt_cfg_.broker.address.transport = MQTT_TRANSPORT_OVER_TCP;
}
#ifdef USE_MQTT_TLS
mqtt_cfg_.broker.address.transport = MQTT_TRANSPORT_OVER_SSL;
#else
mqtt_cfg_.broker.address.transport = MQTT_TRANSPORT_OVER_TCP;
#endif
break;
}
// Only set for the WebSocket transports
mqtt_cfg_.broker.address.path = this->ws_path_;
if (uses_tls) {
if (this->ca_certificate_.has_value()) {
mqtt_cfg_.broker.verification.certificate = this->ca_certificate_.value().c_str();
#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
} else {
// wss without a CA verifies the broker against the bundled roots, as http_request does
mqtt_cfg_.broker.verification.crt_bundle_attach = esp_crt_bundle_attach;
#endif
}
mqtt_cfg_.broker.verification.skip_cert_common_name_check = this->skip_cert_cn_check_;
if (this->cl_certificate_.has_value() && this->cl_key_.has_value()) {
mqtt_cfg_.credentials.authentication.certificate = this->cl_certificate_.value().c_str();
mqtt_cfg_.credentials.authentication.key = this->cl_key_.value().c_str();
}
}
auto *mqtt_client = esp_mqtt_client_init(&mqtt_cfg_);
if (mqtt_client) {
handler_.reset(mqtt_client);
@@ -91,7 +81,11 @@ bool MQTTBackendESP32::initialize_() {
#if defined(USE_MQTT_IDF_ENQUEUE)
// Create the task only after MQTT client is initialized successfully
// Use larger stack size when TLS is enabled
size_t stack_size = uses_tls ? TASK_STACK_SIZE_TLS : TASK_STACK_SIZE;
#ifdef USE_MQTT_TLS
constexpr size_t stack_size = TASK_STACK_SIZE_TLS;
#else
constexpr size_t stack_size = TASK_STACK_SIZE;
#endif
xTaskCreate(esphome_mqtt_task, "esphome_mqtt", stack_size, (void *) this, TASK_PRIORITY, &this->task_handle_);
if (this->task_handle_ == nullptr) {
ESP_LOGE(TAG, "Failed to create MQTT task");
+12 -7
View File
@@ -214,10 +214,13 @@ class MQTTBackendESP32 final : public MQTTBackend {
void loop() final;
void set_ca_certificate(const std::string &cert) { ca_certificate_ = cert; }
void set_cl_certificate(const std::string &cert) { cl_certificate_ = cert; }
void set_cl_key(const std::string &key) { cl_key_ = key; }
void set_skip_cert_cn_check(bool skip_check) { skip_cert_cn_check_ = skip_check; }
#ifdef USE_MQTT_TLS
// The certificates are string literals from code generation, so only the pointers are kept
void set_ca_certificate(const char *cert) { this->ca_certificate_ = cert; }
void set_cl_certificate(const char *cert) { this->cl_certificate_ = cert; }
void set_cl_key(const char *key) { this->cl_key_ = key; }
void set_skip_cert_cn_check(bool skip_check) { this->skip_cert_cn_check_ = skip_check; }
#endif
void set_transport(MQTTTransport transport) { this->transport_ = transport; }
void set_ws_path(const char *path) { this->ws_path_ = path; }
MQTTTransport get_transport() const { return this->transport_; }
@@ -256,10 +259,12 @@ class MQTTBackendESP32 final : public MQTTBackend {
std::string client_id_;
uint16_t keep_alive_;
bool clean_session_;
optional<std::string> ca_certificate_;
optional<std::string> cl_certificate_;
optional<std::string> cl_key_;
#ifdef USE_MQTT_TLS
const char *ca_certificate_{nullptr};
const char *cl_certificate_{nullptr};
const char *cl_key_{nullptr};
bool skip_cert_cn_check_{false};
#endif
MQTTTransport transport_{MQTTTransport::MQTT_TRANSPORT_TCP};
const char *ws_path_{nullptr};
#if defined(USE_MQTT_IDF_ENQUEUE)
+1 -1
View File
@@ -19,7 +19,7 @@ void MQTTButtonComponent::setup() {
if (payload == "PRESS") {
this->button_->press();
} else {
ESP_LOGW(TAG, "'%s': Received unknown status payload: %s", this->friendly_name_().c_str(), payload.c_str());
ESP_LOGW(TAG, "'%s': Received unknown status payload: %s", LOG_STR_ARG(this->log_name_()), payload.c_str());
this->status_momentary_warning(5000);
}
});
+7
View File
@@ -222,6 +222,13 @@ void MQTTClientComponent::dump_config() {
transport == MQTTTransport::MQTT_TRANSPORT_WSS ? LOG_STR_LITERAL("wss") : LOG_STR_LITERAL("ws"),
this->mqtt_backend_.get_ws_path());
}
#endif
#if defined(USE_MQTT_CERT_BUNDLE)
ESP_LOGCONFIG(TAG, " TLS: certificate bundle");
#elif defined(USE_MQTT_TLS_INSECURE)
ESP_LOGCONFIG(TAG, " TLS: no verification");
#elif defined(USE_MQTT_TLS)
ESP_LOGCONFIG(TAG, " TLS: CA certificate");
#endif
if (this->is_discovery_ip_enabled()) {
ESP_LOGCONFIG(TAG, " Discovery IP enabled");
+3 -1
View File
@@ -147,11 +147,13 @@ class MQTTClientComponent final : public Component {
bool is_discovery_enabled() const;
bool is_discovery_ip_enabled() const;
#ifdef USE_ESP32
#if defined(USE_ESP32) && defined(USE_MQTT_TLS)
void set_ca_certificate(const char *cert) { this->mqtt_backend_.set_ca_certificate(cert); }
void set_cl_certificate(const char *cert) { this->mqtt_backend_.set_cl_certificate(cert); }
void set_cl_key(const char *key) { this->mqtt_backend_.set_cl_key(key); }
void set_skip_cert_cn_check(bool skip_check) { this->mqtt_backend_.set_skip_cert_cn_check(skip_check); }
#endif
#ifdef USE_ESP32
void set_transport(MQTTTransport transport) { this->mqtt_backend_.set_transport(transport); }
void set_ws_path(const char *path) { this->mqtt_backend_.set_ws_path(path); }
#endif
+15 -5
View File
@@ -38,7 +38,7 @@ inline char *append_char(char *p, char c) {
// Function implementation of LOG_MQTT_COMPONENT macro to reduce code size
void log_mqtt_component(const char *tag, MQTTComponent *obj, bool state_topic, bool command_topic) {
ESP_LOGCONFIG(tag, "MQTT %s '%s':", obj->component_type(), obj->friendly_name_().c_str());
ESP_LOGCONFIG(tag, "MQTT %s '%s':", obj->component_type(), LOG_STR_ARG(obj->get_entity()->get_log_name()));
char buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
if (state_topic) {
ESP_LOGCONFIG(tag, " State Topic: '%s'", obj->get_state_topic_to_(buf).c_str());
@@ -187,11 +187,11 @@ bool MQTTComponent::send_discovery_() {
StringRef discovery_topic = this->get_discovery_topic_to_(discovery_topic_buf, discovery_info);
if (discovery_info.clean) {
ESP_LOGV(TAG, "'%s': Cleaning discovery", this->friendly_name_().c_str());
ESP_LOGV(TAG, "'%s': Cleaning discovery", LOG_STR_ARG(this->log_name_()));
return global_mqtt_client->publish(discovery_topic.c_str(), "", 0, this->qos_, true);
}
ESP_LOGV(TAG, "'%s': Sending discovery", this->friendly_name_().c_str());
ESP_LOGV(TAG, "'%s': Sending discovery", LOG_STR_ARG(this->log_name_()));
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
return global_mqtt_client->publish_json(
@@ -208,7 +208,12 @@ bool MQTTComponent::send_discovery_() {
}
// Fields from EntityBase
root[MQTT_NAME] = this->get_entity()->has_own_name() ? this->friendly_name_() : StringRef();
if (this->get_entity()->has_own_name()) {
// ArduinoJson copies flash strings into the document itself
root[MQTT_NAME] = reinterpret_cast<ProgmemStr>(this->get_entity()->get_name_progmem().progmem_ptr());
} else {
root[MQTT_NAME] = StringRef();
}
if (this->is_disabled_by_default_())
root[MQTT_ENABLED_BY_DEFAULT] = false;
@@ -254,9 +259,10 @@ bool MQTTComponent::send_discovery_() {
char object_id_buf[OBJECT_ID_MAX_LEN];
StringRef object_id = this->get_default_object_id_to_(object_id_buf);
if (discovery_info.unique_id_generator == MQTT_MAC_ADDRESS_UNIQUE_ID_GENERATOR) {
char name_buf[ENTITY_NAME_BUF_SIZE];
char friendly_name_hash[9];
buf_append_printf(friendly_name_hash, sizeof(friendly_name_hash), 0, "%08" PRIx32,
fnv1_hash(this->friendly_name_().c_str()));
fnv1_hash(this->get_entity()->get_name_to(name_buf).c_str()));
// Format: mac-component_type-hash (e.g. "aabbccddeeff-sensor-12345678")
// MAC (12) + "-" (1) + domain (max 20) + "-" (1) + hash (8) + null (1) = 43
char unique_id[MAC_ADDRESS_BUFFER_SIZE + ESPHOME_DOMAIN_MAX_LEN + 11];
@@ -400,7 +406,11 @@ void MQTTComponent::schedule_resend_state() { this->resend_state_ = true; }
bool MQTTComponent::is_connected_() const { return global_mqtt_client->is_connected(); }
// Pull these properties from EntityBase if not overridden
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
const StringRef &MQTTComponent::friendly_name_() const { return this->get_entity()->get_name(); }
#pragma GCC diagnostic pop
const LogString *MQTTComponent::log_name_() const { return this->get_entity()->get_log_name(); }
StringRef MQTTComponent::get_default_object_id_to_(std::span<char, OBJECT_ID_MAX_LEN> buf) const {
return this->get_entity()->get_object_id_to(buf);
}
+3 -1
View File
@@ -304,7 +304,9 @@ class MQTTComponent : public Component {
*/
virtual const EntityBase *get_entity() const = 0;
/// Get the friendly name of this MQTT component.
/// Entity name for a "%s" log argument.
const LogString *log_name_() const;
ESPDEPRECATED("Use log_name_() for logging. Removed in 2027.5.0", "2026.11.0")
const StringRef &friendly_name_() const;
/// Get the icon field of this component into a stack buffer
+8 -8
View File
@@ -32,15 +32,15 @@ void MQTTFanComponent::setup() {
auto val = parse_on_off(payload.c_str());
switch (val) {
case PARSE_ON:
ESP_LOGD(TAG, "'%s' Turning Fan ON.", this->friendly_name_().c_str());
ESP_LOGD(TAG, "'%s' Turning Fan ON.", LOG_STR_ARG(this->log_name_()));
this->state_->turn_on().perform();
break;
case PARSE_OFF:
ESP_LOGD(TAG, "'%s' Turning Fan OFF.", this->friendly_name_().c_str());
ESP_LOGD(TAG, "'%s' Turning Fan OFF.", LOG_STR_ARG(this->log_name_()));
this->state_->turn_off().perform();
break;
case PARSE_TOGGLE:
ESP_LOGD(TAG, "'%s' Toggling Fan.", this->friendly_name_().c_str());
ESP_LOGD(TAG, "'%s' Toggling Fan.", LOG_STR_ARG(this->log_name_()));
this->state_->toggle().perform();
break;
case PARSE_NONE:
@@ -56,11 +56,11 @@ void MQTTFanComponent::setup() {
auto val = parse_on_off(payload.c_str(), "forward", "reverse");
switch (val) {
case PARSE_ON:
ESP_LOGD(TAG, "'%s': Setting direction FORWARD", this->friendly_name_().c_str());
ESP_LOGD(TAG, "'%s': Setting direction FORWARD", LOG_STR_ARG(this->log_name_()));
this->state_->make_call().set_direction(fan::FanDirection::FORWARD).perform();
break;
case PARSE_OFF:
ESP_LOGD(TAG, "'%s': Setting direction REVERSE", this->friendly_name_().c_str());
ESP_LOGD(TAG, "'%s': Setting direction REVERSE", LOG_STR_ARG(this->log_name_()));
this->state_->make_call().set_direction(fan::FanDirection::REVERSE).perform();
break;
case PARSE_TOGGLE:
@@ -83,11 +83,11 @@ void MQTTFanComponent::setup() {
auto val = parse_on_off(payload.c_str(), "oscillate_on", "oscillate_off");
switch (val) {
case PARSE_ON:
ESP_LOGD(TAG, "'%s': Setting oscillating ON", this->friendly_name_().c_str());
ESP_LOGD(TAG, "'%s': Setting oscillating ON", LOG_STR_ARG(this->log_name_()));
this->state_->make_call().set_oscillating(true).perform();
break;
case PARSE_OFF:
ESP_LOGD(TAG, "'%s': Setting oscillating OFF", this->friendly_name_().c_str());
ESP_LOGD(TAG, "'%s': Setting oscillating OFF", LOG_STR_ARG(this->log_name_()));
this->state_->make_call().set_oscillating(false).perform();
break;
case PARSE_TOGGLE:
@@ -167,7 +167,7 @@ void MQTTFanComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig
bool MQTTFanComponent::publish_state() {
char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN];
const char *state_s = this->state_->state ? "ON" : "OFF";
ESP_LOGD(TAG, "'%s' Sending state %s.", this->state_->get_name().c_str(), state_s);
ESP_LOGD(TAG, "'%s' Sending state %s.", LOG_STR_ARG(this->state_->get_log_name()), state_s);
this->publish(this->get_state_topic_to_(topic_buf), state_s);
bool failed = false;
if (this->state_->get_traits().supports_direction()) {
+1 -1
View File
@@ -24,7 +24,7 @@ void MQTTLockComponent::setup() {
} else if (ESPHOME_strcasecmp_P(payload.c_str(), ESPHOME_PSTR("OPEN")) == 0) {
this->lock_->open();
} else {
ESP_LOGW(TAG, "'%s': Received unknown status payload: %s", this->friendly_name_().c_str(), payload.c_str());
ESP_LOGW(TAG, "'%s': Received unknown status payload: %s", LOG_STR_ARG(this->log_name_()), payload.c_str());
this->status_momentary_warning(5000);
}
});
+1 -1
View File
@@ -28,7 +28,7 @@ void MQTTSwitchComponent::setup() {
break;
case PARSE_NONE:
default:
ESP_LOGW(TAG, "'%s': Received unknown status payload: %s", this->friendly_name_().c_str(), payload.c_str());
ESP_LOGW(TAG, "'%s': Received unknown status payload: %s", LOG_STR_ARG(this->log_name_()), payload.c_str());
this->status_momentary_warning(5000);
break;
}
+1 -1
View File
@@ -19,7 +19,7 @@ void MQTTUpdateComponent::setup() {
if (payload == "INSTALL") {
this->update_->perform();
} else {
ESP_LOGW(TAG, "'%s': Received unknown update payload: %s", this->friendly_name_().c_str(), payload.c_str());
ESP_LOGW(TAG, "'%s': Received unknown update payload: %s", LOG_STR_ARG(this->log_name_()), payload.c_str());
this->status_momentary_warning(5000);
}
});
+1 -1
View File
@@ -297,7 +297,7 @@ void NAU7802Sensor::update() {
// Get the most recent sample to publish
int32_t result = this->read_value_(ADCO_B2_REG, 3);
ESP_LOGD(TAG, "'%s': Got value %" PRId32, this->name_.c_str(), result);
ESP_LOGD(TAG, "'%s': Got value %" PRId32, LOG_STR_ARG(this->get_log_name()), result);
this->publish_state(result);
}
+1 -1
View File
@@ -21,7 +21,7 @@ void NTC::process_(float value) {
double v = this->a_ + this->b_ * lr + this->c_ * lr * lr * lr;
auto temp = float(1.0 / v - 273.15);
ESP_LOGV(TAG, "'%s' - Temperature: %.1f°C", this->name_.c_str(), temp);
ESP_LOGV(TAG, "'%s' - Temperature: %.1f°C", LOG_STR_ARG(this->get_log_name()), temp);
this->publish_state(temp);
}
+1 -1
View File
@@ -20,7 +20,7 @@ void log_number(const char *tag, const char *prefix, const char *type, Number *o
void Number::publish_state(float state) {
this->set_has_state(true);
this->state = state;
ESP_LOGV(TAG, "'%s' >> %.2f", this->get_name().c_str(), state);
ESP_LOGV(TAG, "'%s' >> %.2f", LOG_STR_ARG(this->get_log_name()), state);
this->state_callback_.call(state);
#if defined(USE_NUMBER) && defined(USE_CONTROLLER_REGISTRY)
ControllerRegistry::notify_number_update(this);
+3 -3
View File
@@ -8,12 +8,12 @@ ESPHOME_LOG_TAG(TAG, "number");
// Helper functions to reduce code size for logging
void NumberCall::log_perform_warning_(const LogString *message) {
ESP_LOGW(TAG, "'%s': %s", this->parent_->get_name().c_str(), LOG_STR_ARG(message));
ESP_LOGW(TAG, "'%s': %s", LOG_STR_ARG(this->parent_->get_log_name()), LOG_STR_ARG(message));
}
void NumberCall::log_perform_warning_value_range_(const LogString *comparison, const LogString *limit_type, float val,
float limit) {
ESP_LOGW(TAG, "'%s': %f %s %s %f", this->parent_->get_name().c_str(), val, LOG_STR_ARG(comparison),
ESP_LOGW(TAG, "'%s': %f %s %s %f", LOG_STR_ARG(this->parent_->get_log_name()), val, LOG_STR_ARG(comparison),
LOG_STR_ARG(limit_type), limit);
}
@@ -48,7 +48,7 @@ NumberCall &NumberCall::with_cycle(bool cycle) {
void NumberCall::perform() {
auto *parent = this->parent_;
const auto *name = parent->get_name().c_str();
const auto *name = LOG_STR_ARG(parent->get_log_name());
const auto &traits = parent->traits;
if (this->operation_ == NUMBER_OP_NONE) {
@@ -10,9 +10,9 @@ void OpenthermSwitch::setup() {
auto restored = this->get_initial_state_with_restore_mode();
bool state = false;
if (!restored.has_value()) {
ESP_LOGD(TAG, "Couldn't restore state for OpenTherm switch '%s'", this->get_name().c_str());
ESP_LOGD(TAG, "Couldn't restore state for OpenTherm switch '%s'", LOG_STR_ARG(this->get_log_name()));
} else {
ESP_LOGD(TAG, "Restored state for OpenTherm switch '%s': %d", this->get_name().c_str(), restored.value());
ESP_LOGD(TAG, "Restored state for OpenTherm switch '%s': %d", LOG_STR_ARG(this->get_log_name()), restored.value());
state = restored.value();
}
this->write_state(state);
+1 -1
View File
@@ -108,7 +108,7 @@ void OPT3001Sensor::update() {
this->publish_state(NAN);
return;
}
ESP_LOGD(TAG, "'%s': Illuminance=%.1flx", this->get_name().c_str(), val);
ESP_LOGD(TAG, "'%s': Illuminance=%.1flx", LOG_STR_ARG(this->get_log_name()), val);
this->publish_state(val);
});
}
@@ -0,0 +1,56 @@
from typing import Any
import esphome.codegen as cg
from esphome.components.const import CONF_MAX_PACKET_SIZE
import esphome.config_validation as cv
from esphome.const import CONF_ID
from esphome.cpp_generator import MockObj, MockObjClass
from esphome.types import ConfigType
CODEOWNERS = ["@clydebarrow"]
DOMAIN = "packet_interface"
IS_PLATFORM_COMPONENT = True
CONF_PACKET_INTERFACE = "packet_interface"
packet_interface_ns = cg.esphome_ns.namespace("packet_interface")
PacketInterface = packet_interface_ns.class_("PacketInterface", cg.Component)
__all__ = [
"CONF_MAX_PACKET_SIZE",
"CONF_PACKET_INTERFACE",
"PacketInterface",
"new_packet_interface",
"packet_interface_ns",
"packet_interface_schema",
]
def packet_interface_schema(
class_: MockObjClass,
default_max_packet_size: int,
max_packet_size_limit: int = 4096,
) -> cv.Schema:
"""Schema for a link platform."""
return cv.Schema(
{
cv.GenerateID(): cv.declare_id(class_),
cv.Optional(
CONF_MAX_PACKET_SIZE, default=default_max_packet_size
): cv.int_range(16, max_packet_size_limit),
}
).extend(cv.COMPONENT_SCHEMA)
async def new_packet_interface(config: ConfigType, *args: Any) -> MockObj:
"""Create the link layer.
The link's constructor takes its maximum packet size, usually as a std::span over a buffer that code generation
sized from the configuration, so the two cannot differ.
Returns the link layer; applications reach the top layer with PacketInterface::top().
"""
var = cg.new_Pvariable(config[CONF_ID], *args)
cg.add(var.set_name(config[CONF_ID].id))
await cg.register_component(var, config)
return var
@@ -0,0 +1,173 @@
#pragma once
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <span>
#include <vector>
namespace esphome::packet_interface {
/**
* A buffer class that efficiently represents a composite buffer with three sections:
* - pre_buffer: A pointer to uint8_t data with a length
* - mid_buffer: A reference to another PacketBuffer (optional)
* - post_buffer: A pointer to uint8_t data with a length
*
* This allows efficient zero-copy composition of buffers without allocating new memory.
*
* WARNING: PacketBuffer holds raw pointers to data. The user must ensure that the data remains valid
* for the lifetime of the PacketBuffer instance. Storing PacketBuffer instances beyond the scope of the data they
* reference will lead to dangling pointers and undefined behavior, so to keep a packet, copy it with copy_to() into a
* buffer allocated in setup().
*/
class PacketBuffer {
public:
PacketBuffer() = default;
// Disable copy semantics - PacketBuffer contains pointers and copying would create dangling references
PacketBuffer(const PacketBuffer &) = delete;
PacketBuffer &operator=(const PacketBuffer &) = delete;
// Enable move semantics
PacketBuffer(PacketBuffer &&) = default;
PacketBuffer &operator=(PacketBuffer &&) = default;
/**
* Construct from a single buffer.
*/
PacketBuffer(const uint8_t *data, size_t length) : pre_buffer_(data), pre_length_(length) {}
/**
* Construct from a vector.
*/
explicit PacketBuffer(const std::vector<uint8_t> &vec) : pre_buffer_(vec.data()), pre_length_(vec.size()) {}
// A temporary vector would leave the buffer dangling
explicit PacketBuffer(std::vector<uint8_t> &&) = delete;
/**
* Construct with pre and post buffers.
*/
PacketBuffer(const uint8_t *pre_data, size_t pre_length, const uint8_t *post_data, size_t post_length)
: pre_buffer_(pre_data), pre_length_(pre_length), post_buffer_(post_data), post_length_(post_length) {}
/**
* Construct with pre, mid, and post buffers.
*/
PacketBuffer(const uint8_t *pre_data, size_t pre_length, const PacketBuffer *mid_buffer, const uint8_t *post_data,
size_t post_length)
: pre_buffer_(pre_data),
pre_length_(pre_length),
mid_buffer_(mid_buffer),
post_buffer_(post_data),
post_length_(post_length) {}
/**
* Get the total size of the buffer.
*/
size_t size() const {
size_t total = this->pre_length_ + this->post_length_;
if (this->mid_buffer_ != nullptr) {
total += this->mid_buffer_->size();
}
return total;
}
/**
* Check if the buffer is empty.
*/
bool empty() const { return this->size() == 0; }
/**
* Check if all the data is held in the pre-buffer, so it can be read as one span.
*/
bool is_contiguous() const { return this->mid_buffer_ == nullptr && this->post_length_ == 0; }
/**
* Get the data as one span. Only valid when is_contiguous() is true.
*/
std::span<const uint8_t> as_span() const { return {this->pre_buffer_, this->pre_length_}; }
/**
* Access a byte at a specific position.
* @param index The position to access
* @return The byte at the specified position, or 0 past the end
*/
uint8_t operator[](size_t index) const {
if (index < this->pre_length_) {
return this->pre_buffer_[index];
}
index -= this->pre_length_;
if (this->mid_buffer_ != nullptr) {
size_t mid_size = this->mid_buffer_->size();
if (index < mid_size) {
return (*this->mid_buffer_)[index];
}
index -= mid_size;
}
return index < this->post_length_ ? this->post_buffer_[index] : 0;
}
/**
* Copy data from the buffer to a destination pointer.
* @param dest Destination pointer
* @param count Number of bytes to copy
* @param offset Offset in the source buffer to start copying from
* @return Number of bytes actually copied
*/
size_t copy_to(uint8_t *dest, size_t count, size_t offset = 0) const {
size_t total_size = this->size();
if (offset >= total_size) {
return 0;
}
size_t available = total_size - offset;
size_t to_copy = count < available ? count : available;
size_t copied = 0;
// Copy from pre_buffer
if (offset < this->pre_length_) {
size_t pre_offset = offset;
size_t pre_available = this->pre_length_ - pre_offset;
size_t pre_copy = to_copy < pre_available ? to_copy : pre_available;
std::memcpy(dest, this->pre_buffer_ + pre_offset, pre_copy);
copied += pre_copy;
dest += pre_copy;
offset += pre_copy;
}
// Copy from mid_buffer
size_t mid_size = this->mid_buffer_ != nullptr ? this->mid_buffer_->size() : 0;
if (copied < to_copy && offset < this->pre_length_ + mid_size) {
size_t mid_offset = offset - this->pre_length_;
size_t mid_available = mid_size - mid_offset;
size_t mid_copy = (to_copy - copied) < mid_available ? (to_copy - copied) : mid_available;
this->mid_buffer_->copy_to(dest, mid_copy, mid_offset);
copied += mid_copy;
dest += mid_copy;
offset += mid_copy;
}
// Copy from post_buffer
if ((copied < to_copy) && (this->post_length_ > 0)) {
size_t post_offset = offset - this->pre_length_ - mid_size;
size_t post_available = this->post_length_ - post_offset;
size_t post_copy = (to_copy - copied) < post_available ? (to_copy - copied) : post_available;
std::memcpy(dest, this->post_buffer_ + post_offset, post_copy);
copied += post_copy;
}
return copied;
}
private:
const uint8_t *pre_buffer_{nullptr};
size_t pre_length_{0};
const PacketBuffer *mid_buffer_{nullptr};
const uint8_t *post_buffer_{nullptr};
size_t post_length_{0};
};
} // namespace esphome::packet_interface
@@ -0,0 +1,39 @@
#include "packet_interface.h"
#include "esphome/core/log.h"
namespace esphome::packet_interface {
ESPHOME_LOG_TAG(TAG, "packet_interface");
// Packets in a row that cannot be understood before the mismatch is logged
static constexpr uint8_t MISMATCH_COUNT = 10;
void PacketInterface::dump_config() {
ESP_LOGCONFIG(TAG,
"Packet Interface '%s':\n"
" Max Packet Size: %zu",
this->name_, this->get_max_packet_size());
}
void PacketInterface::on_receive_from_interface_(const PacketBuffer &data, const PacketMetaData &meta_data) {
#ifdef ESPHOME_LOG_HAS_VERBOSE
static constexpr size_t LOG_BYTES = 24;
uint8_t head[LOG_BYTES];
size_t len = data.copy_to(head, LOG_BYTES);
ESP_LOGV_HEX(TAG, head, len, LOG_BYTES, "%s: received %zu bytes %s", this->name_, data.size());
#endif
this->callback_.call(data, meta_data);
}
void PacketInterface::note_received_(bool understood) {
if (understood) {
this->not_understood_count_ = 0;
} else if (this->not_understood_count_ < MISMATCH_COUNT) {
this->not_understood_count_++;
if (this->not_understood_count_ == MISMATCH_COUNT) {
ESP_LOGW(TAG, "%s: %u packets in a row could not be understood; check that both ends have the same layers",
this->name_, MISMATCH_COUNT);
}
}
}
} // namespace esphome::packet_interface
@@ -0,0 +1,149 @@
#pragma once
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <utility>
#include "esphome/core/string_ref.h"
#include "esphome/core/helpers.h"
#include "esphome/core/component.h"
#include "packet_buffer.h"
namespace esphome::packet_interface {
/// The room left for a packet of \p size bytes after \p used bytes, or 0 if it is too small.
constexpr size_t remaining_packet_size(size_t size, size_t used) { return size > used ? size - used : 0; }
/// What a stack of layers provides, as bits of PacketInterface::get_capabilities().
enum Capability : uint8_t {
CAPABILITY_ENCRYPTION = 1 << 0,
CAPABILITY_RELIABILITY = 1 << 1,
CAPABILITY_SESSION = 1 << 2,
CAPABILITY_ADDRESSING = 1 << 3,
CAPABILITY_FRAGMENTATION = 1 << 4,
};
/**
* A struct to hold metadata about a packet.
* @param info Additional information about the packet
* @param source_address With an addressing layer, the sender of a received packet; 0 if not known
* @param destination_address With an addressing layer, the destination of a packet; when sending, 0 uses the
* configured destination
* @param rssi The RSSI of the packet
* @param snr The SNR of the packet
* @param mac_address The MAC address of the sender/receiver
*/
class PacketMetaData {
public:
StringRef info{};
uint16_t source_address{0};
uint16_t destination_address{0};
float rssi{NAN};
float snr{NAN};
uint8_t mac_address[MAC_ADDRESS_SIZE]{};
};
/**
* A class that will transport data to and from an abstract channel.
*
* The operations defined are:
*
* Transmit: the function send_to_interface() takes a PacketBuffer of bytes, and returns when all data is
* written or buffered for transmission.
*
* Receive: The callbacks for an instance of this class are called with currently received data.
*/
class PacketInterface : public Component {
public:
/**
*
* Method to be implemented by child classes to send data to the interface.
*
* @param data The data to be sent
* @param meta_data Metadata about the packet to be sent
* @return True if the data was queued for transmission, false if it could not be sent
*/
virtual bool send_to_interface(const PacketBuffer &data, const PacketMetaData &meta_data) = 0;
/// The largest packet this layer accepts; fixed when the layer is constructed.
size_t get_max_packet_size() const { return this->max_packet_size_; }
/// How many packets send_to_interface() would accept now, so a layer above can tell before sending a series.
virtual size_t get_send_capacity() const { return SIZE_MAX; }
/// The capabilities of this layer and every layer below it.
uint8_t get_capabilities() const { return this->capabilities_; }
bool has_capability(Capability capability) const { return (this->capabilities_ & capability) != 0; }
/**
* With CAPABILITY_SESSION, the callback is called with true when the peer can be reached, including after it
* restarts, and with false when it is lost. The session layer is always the top layer, so register on top().
* A reliability layer calls it with false when it resets the link and discards data, which the session layer above
* reports as the session lost.
*/
template<typename F> void add_on_session_state_callback(F &&callback) {
this->session_callback_.add(std::forward<F>(callback));
}
/// The topmost layer stacked on this one, or this one if nothing is stacked on it.
PacketInterface *top() {
PacketInterface *layer = this;
while (layer->upper_ != nullptr)
layer = layer->upper_;
return layer;
}
/// Name shown in log messages; a layer takes the name of the link it is stacked on.
void set_name(const char *name) { this->name_ = name; }
const char *get_name() const { return this->name_; }
/**
* Add a listener that will be called when data is received.
*
* @param callback The callback to be called when data is received.
*/
template<typename F> void add_packet_interface_listener(F &&callback) {
this->callback_.add(std::forward<F>(callback));
}
void dump_config() override;
protected:
/// @param max_packet_size The largest packet the layer accepts, set from the layer below or the layer's own buffer
explicit PacketInterface(size_t max_packet_size) : max_packet_size_(max_packet_size) {}
virtual ~PacketInterface() = default;
/**
* This function should be called by implementing classes with received data to be passed to any listeners.
*
* @param data The received data
* @param meta_data Metadata about the received packet
*/
void on_receive_from_interface_(const PacketBuffer &data, const PacketMetaData &meta_data);
/**
* Called by a layer for each received packet it understood, or could not make sense of. A run of packets that
* cannot be understood usually means the peer has different layers configured, which is logged once per run.
*/
void note_received_(bool understood);
/// Called by a layer's constructor to record itself as the layer above \p lower, adding its own capability.
void stack_on_(PacketInterface *lower, Capability capability) {
lower->upper_ = this;
this->inherit_from_(lower, capability);
}
/// Takes the name and capabilities of `lower` without becoming its top, for one of several stacks on a link.
void inherit_from_(PacketInterface *lower, Capability capability) {
this->name_ = lower->name_;
this->capabilities_ = lower->capabilities_ | capability;
// A link that has a session of its own, such as TCP, reports it to whatever is stacked above, as does a
// reliability layer that discards data; the session layer handles the latter itself
if ((lower->has_capability(CAPABILITY_SESSION) || lower->has_capability(CAPABILITY_RELIABILITY)) &&
capability != CAPABILITY_SESSION) {
lower->add_on_session_state_callback([this](bool connected) { this->session_callback_.call(connected); });
}
}
LazyCallbackManager<void(const PacketBuffer &, const PacketMetaData &)> callback_;
LazyCallbackManager<void(bool)> session_callback_;
PacketInterface *upper_{nullptr};
const char *name_{""};
const size_t max_packet_size_;
uint8_t capabilities_{0};
uint8_t not_understood_count_{0};
};
} // namespace esphome::packet_interface
@@ -0,0 +1,28 @@
import esphome.codegen as cg
from esphome.components.packet_transport import (
PacketTransport,
new_packet_transport,
transport_schema,
)
import esphome.config_validation as cv
from esphome.types import ConfigType
from .. import CONF_PACKET_INTERFACE, PacketInterface, packet_interface_ns
CODEOWNERS = ["@clydebarrow"]
DEPENDENCIES = ["packet_interface"]
PacketInterfaceTransport = packet_interface_ns.class_(
"PacketInterfaceTransport", PacketTransport
)
CONFIG_SCHEMA = transport_schema(PacketInterfaceTransport).extend(
{
cv.GenerateID(CONF_PACKET_INTERFACE): cv.use_id(PacketInterface),
}
)
async def to_code(config: ConfigType) -> None:
interface = await cg.get_variable(config[CONF_PACKET_INTERFACE])
await new_packet_transport(config, interface)

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