From 62da60df477d3efcf9fcb80de6978b7ff44749f9 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Wed, 25 Feb 2026 14:19:20 -0500 Subject: [PATCH 1/8] [ld2420] Fix sizeof vs value bug in register memcpy (#14286) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- esphome/components/ld2420/ld2420.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/ld2420/ld2420.cpp b/esphome/components/ld2420/ld2420.cpp index cf78a1a460..b653f4ae88 100644 --- a/esphome/components/ld2420/ld2420.cpp +++ b/esphome/components/ld2420/ld2420.cpp @@ -590,7 +590,7 @@ void LD2420Component::handle_ack_data_(uint8_t *buffer, int len) { for (uint16_t index = 0; index < (CMD_REG_DATA_REPLY_SIZE * // NOLINT ((buffer[CMD_FRAME_DATA_LENGTH] - 4) / CMD_REG_DATA_REPLY_SIZE)); index += CMD_REG_DATA_REPLY_SIZE) { - memcpy(&this->cmd_reply_.data[reg_element], &buffer[data_pos + index], sizeof(CMD_REG_DATA_REPLY_SIZE)); + memcpy(&this->cmd_reply_.data[reg_element], &buffer[data_pos + index], CMD_REG_DATA_REPLY_SIZE); byteswap(this->cmd_reply_.data[reg_element]); reg_element++; } @@ -729,9 +729,9 @@ void LD2420Component::set_reg_value(uint16_t reg, uint16_t value) { cmd_frame.data_length = 0; cmd_frame.header = CMD_FRAME_HEADER; cmd_frame.command = CMD_WRITE_REGISTER; - memcpy(&cmd_frame.data[cmd_frame.data_length], ®, sizeof(CMD_REG_DATA_REPLY_SIZE)); + memcpy(&cmd_frame.data[cmd_frame.data_length], ®, CMD_REG_DATA_REPLY_SIZE); cmd_frame.data_length += 2; - memcpy(&cmd_frame.data[cmd_frame.data_length], &value, sizeof(CMD_REG_DATA_REPLY_SIZE)); + memcpy(&cmd_frame.data[cmd_frame.data_length], &value, CMD_REG_DATA_REPLY_SIZE); cmd_frame.data_length += 2; cmd_frame.footer = CMD_FRAME_FOOTER; ESP_LOGV(TAG, "Sending write register %4X command: %2X data = %4X", reg, cmd_frame.command, value); From e601162cdd0500581cb838b8fd588fca3e3bba8e Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Wed, 25 Feb 2026 14:21:00 -0500 Subject: [PATCH 2/8] [lcd_base] Fix millis() truncation to uint8_t (#14289) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- esphome/components/lcd_base/lcd_display.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/lcd_base/lcd_display.cpp b/esphome/components/lcd_base/lcd_display.cpp index d3434cce10..cd08a739eb 100644 --- a/esphome/components/lcd_base/lcd_display.cpp +++ b/esphome/components/lcd_base/lcd_display.cpp @@ -45,7 +45,7 @@ void LCDDisplay::setup() { // TODO dotsize // Commands can only be sent 40ms after boot-up, so let's wait if we're close - const uint8_t now = millis(); + const uint32_t now = millis(); if (now < 40) delay(40u - now); From df77213f2cb21a31e62ff0a9570d7af73e8f431b Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Wed, 25 Feb 2026 14:27:00 -0500 Subject: [PATCH 3/8] [shelly_dimmer] Fix millis overflow in ACK timeout check (#14288) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- esphome/components/shelly_dimmer/stm32flash.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome/components/shelly_dimmer/stm32flash.cpp b/esphome/components/shelly_dimmer/stm32flash.cpp index b052c0cee9..a1a933bcab 100644 --- a/esphome/components/shelly_dimmer/stm32flash.cpp +++ b/esphome/components/shelly_dimmer/stm32flash.cpp @@ -149,7 +149,7 @@ stm32_err_t stm32_get_ack_timeout(const stm32_unique_ptr &stm, uint32_t timeout) do { yield(); if (!stream->available()) { - if (millis() < start_time + timeout) + if (millis() - start_time < timeout) continue; ESP_LOGD(TAG, "Failed to read ACK timeout=%i", timeout); return STM32_ERR_UNKNOWN; @@ -212,7 +212,7 @@ stm32_err_t stm32_resync(const stm32_unique_ptr &stm) { static_assert(sizeof(buf) == BUFFER_SIZE, "Buf expected to be 2 bytes"); uint8_t ack; - while (t1 < t0 + STM32_RESYNC_TIMEOUT) { + while (t1 - t0 < STM32_RESYNC_TIMEOUT) { stream->write_array(buf, BUFFER_SIZE); stream->flush(); if (!stream->read_array(&ack, 1)) { From 3f558f63d8fec863d51e05e44a8dcee406d278c1 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Wed, 25 Feb 2026 14:28:47 -0500 Subject: [PATCH 4/8] [bl0942] Fix millis overflow in packet timeout check (#14285) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- esphome/components/bl0942/bl0942.cpp | 8 ++++---- esphome/components/bl0942/bl0942.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/esphome/components/bl0942/bl0942.cpp b/esphome/components/bl0942/bl0942.cpp index b408c5549c..16ad33141d 100644 --- a/esphome/components/bl0942/bl0942.cpp +++ b/esphome/components/bl0942/bl0942.cpp @@ -52,12 +52,12 @@ void BL0942::loop() { return; } if (avail < sizeof(buffer)) { - if (!this->rx_start_) { + if (!this->rx_start_.has_value()) { this->rx_start_ = millis(); - } else if (millis() > this->rx_start_ + PKT_TIMEOUT_MS) { + } else if (millis() - *this->rx_start_ > PKT_TIMEOUT_MS) { ESP_LOGW(TAG, "Junk on wire. Throwing away partial message (%zu bytes)", avail); this->read_array((uint8_t *) &buffer, avail); - this->rx_start_ = 0; + this->rx_start_.reset(); } return; } @@ -67,7 +67,7 @@ void BL0942::loop() { this->received_package_(&buffer); } } - this->rx_start_ = 0; + this->rx_start_.reset(); } bool BL0942::validate_checksum_(DataPacket *data) { diff --git a/esphome/components/bl0942/bl0942.h b/esphome/components/bl0942/bl0942.h index 10b29a72c6..3c013f86e7 100644 --- a/esphome/components/bl0942/bl0942.h +++ b/esphome/components/bl0942/bl0942.h @@ -140,7 +140,7 @@ class BL0942 : public PollingComponent, public uart::UARTDevice { uint8_t address_ = 0; bool reset_ = false; LineFrequency line_freq_ = LINE_FREQUENCY_50HZ; - uint32_t rx_start_ = 0; + optional rx_start_{}; uint32_t prev_cf_cnt_ = 0; bool validate_checksum_(DataPacket *data); From d1a636a5c3227d08eed01f704e26f172394eba64 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Wed, 25 Feb 2026 14:34:38 -0500 Subject: [PATCH 5/8] [rtttl] Fix speaker playback bugs (#14280) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- esphome/components/rtttl/rtttl.cpp | 21 +++++++++++---------- esphome/components/rtttl/rtttl.h | 6 +++--- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/esphome/components/rtttl/rtttl.cpp b/esphome/components/rtttl/rtttl.cpp index 6e86405b74..ab95067f45 100644 --- a/esphome/components/rtttl/rtttl.cpp +++ b/esphome/components/rtttl/rtttl.cpp @@ -139,9 +139,10 @@ void Rtttl::loop() { x++; } if (x > 0) { - int send = this->speaker_->play((uint8_t *) (&sample), x * 2); - if (send != x * 4) { - this->samples_sent_ -= (x - (send / 2)); + size_t bytes_to_send = x * sizeof(SpeakerSample); + size_t send = this->speaker_->play((uint8_t *) (&sample), bytes_to_send); + if (send != bytes_to_send) { + this->samples_sent_ -= (x - (send / sizeof(SpeakerSample))); } return; } @@ -201,9 +202,9 @@ void Rtttl::loop() { bool need_note_gap = false; if (note) { auto note_index = (scale - 4) * 12 + note; - if (note_index < 0 || note_index >= (int) sizeof(NOTES)) { + if (note_index < 0 || note_index >= (int) (sizeof(NOTES) / sizeof(NOTES[0]))) { ESP_LOGE(TAG, "Note out of range (note: %d, scale: %d, index: %d, max: %d)", note, scale, note_index, - (int) sizeof(NOTES)); + (int) (sizeof(NOTES) / sizeof(NOTES[0]))); this->finish_(); return; } @@ -221,7 +222,7 @@ void Rtttl::loop() { #ifdef USE_OUTPUT if (this->output_ != nullptr) { - if (need_note_gap) { + if (need_note_gap && this->note_duration_ > DOUBLE_NOTE_GAP_MS) { this->output_->set_level(0.0); delay(DOUBLE_NOTE_GAP_MS); this->note_duration_ -= DOUBLE_NOTE_GAP_MS; @@ -240,9 +241,9 @@ void Rtttl::loop() { this->samples_sent_ = 0; this->samples_gap_ = 0; this->samples_per_wave_ = 0; - this->samples_count_ = (this->sample_rate_ * this->note_duration_) / 1600; //(ms); + this->samples_count_ = (this->sample_rate_ * this->note_duration_) / 1000; if (need_note_gap) { - this->samples_gap_ = (this->sample_rate_ * DOUBLE_NOTE_GAP_MS) / 1600; //(ms); + this->samples_gap_ = (this->sample_rate_ * DOUBLE_NOTE_GAP_MS) / 1000; } if (this->output_freq_ != 0) { // make sure there is enough samples to add a full last sinus. @@ -279,7 +280,7 @@ void Rtttl::play(std::string rtttl) { this->note_duration_ = 0; int bpm = 63; - uint8_t num; + uint16_t num; // Get name this->position_ = this->rtttl_.find(':'); @@ -395,7 +396,7 @@ void Rtttl::finish_() { sample[0].right = 0; sample[1].left = 0; sample[1].right = 0; - this->speaker_->play((uint8_t *) (&sample), 8); + this->speaker_->play((uint8_t *) (&sample), sizeof(sample)); this->speaker_->finish(); this->set_state_(State::STOPPING); } diff --git a/esphome/components/rtttl/rtttl.h b/esphome/components/rtttl/rtttl.h index 6f5df07766..4d4a652c51 100644 --- a/esphome/components/rtttl/rtttl.h +++ b/esphome/components/rtttl/rtttl.h @@ -46,8 +46,8 @@ class Rtttl : public Component { } protected: - inline uint8_t get_integer_() { - uint8_t ret = 0; + inline uint16_t get_integer_() { + uint16_t ret = 0; while (isdigit(this->rtttl_[this->position_])) { ret = (ret * 10) + (this->rtttl_[this->position_++] - '0'); } @@ -87,7 +87,7 @@ class Rtttl : public Component { #ifdef USE_OUTPUT /// The output to write the sound to. - output::FloatOutput *output_; + output::FloatOutput *output_{nullptr}; #endif // USE_OUTPUT #ifdef USE_SPEAKER From 5dffceda59542cf5abca89415bc6944b94b97793 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Wed, 25 Feb 2026 14:35:27 -0500 Subject: [PATCH 6/8] [hmc5883l] Fix wrong gain for 88uT range (#14281) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- esphome/components/hmc5883l/hmc5883l.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/hmc5883l/hmc5883l.cpp b/esphome/components/hmc5883l/hmc5883l.cpp index b62381a287..bee5282125 100644 --- a/esphome/components/hmc5883l/hmc5883l.cpp +++ b/esphome/components/hmc5883l/hmc5883l.cpp @@ -95,7 +95,7 @@ void HMC5883LComponent::update() { float mg_per_bit; switch (this->range_) { case HMC5883L_RANGE_88_UT: - mg_per_bit = 0.073f; + mg_per_bit = 0.73f; break; case HMC5883L_RANGE_130_UT: mg_per_bit = 0.92f; From d61e2f9c29543e19c79b6accaf94a47b11cf87ab Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Wed, 25 Feb 2026 15:06:13 -0500 Subject: [PATCH 7/8] [light] Fix millis overflow in transition progress and flash timing (#14292) Co-authored-by: J. Nick Koston Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- esphome/components/light/light_transformer.h | 7 +++---- esphome/components/light/transformers.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/esphome/components/light/light_transformer.h b/esphome/components/light/light_transformer.h index 079c2d2ae0..b9535c834c 100644 --- a/esphome/components/light/light_transformer.h +++ b/esphome/components/light/light_transformer.h @@ -44,12 +44,11 @@ class LightTransformer { /// The progress of this transition, on a scale of 0 to 1. float get_progress_() { uint32_t now = esphome::millis(); - if (now < this->start_time_) - return 0.0f; - if (now >= this->start_time_ + this->length_) + uint32_t elapsed = now - this->start_time_; + if (elapsed >= this->length_) return 1.0f; - return clamp((now - this->start_time_) / float(this->length_), 0.0f, 1.0f); + return clamp(elapsed / float(this->length_), 0.0f, 1.0f); } uint32_t start_time_; diff --git a/esphome/components/light/transformers.h b/esphome/components/light/transformers.h index a26713b723..b6e5e08f2b 100644 --- a/esphome/components/light/transformers.h +++ b/esphome/components/light/transformers.h @@ -78,7 +78,7 @@ class LightFlashTransformer : public LightTransformer { optional apply() override { optional result = {}; - if (this->transformer_ == nullptr && millis() > this->start_time_ + this->length_ - this->transition_length_) { + if (this->transformer_ == nullptr && millis() - this->start_time_ > this->length_ - this->transition_length_) { // second transition back to start value this->transformer_ = this->state_.get_output()->create_default_transition(); this->transformer_->setup(this->state_.current_values, this->get_start_values(), this->transition_length_); From 3dcc9ab76537dc884dbc93924e5190fd12c14bef Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Wed, 25 Feb 2026 15:08:04 -0500 Subject: [PATCH 8/8] [ble_presence] Fix millis overflow in presence timeout check (#14293) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- esphome/components/ble_presence/ble_presence_device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/ble_presence/ble_presence_device.h b/esphome/components/ble_presence/ble_presence_device.h index 70ecc67c32..f2f0a3ed19 100644 --- a/esphome/components/ble_presence/ble_presence_device.h +++ b/esphome/components/ble_presence/ble_presence_device.h @@ -101,7 +101,7 @@ class BLEPresenceDevice : public binary_sensor::BinarySensorInitiallyOff, } void loop() override { - if (this->found_ && this->last_seen_ + this->timeout_ < millis()) + if (this->found_ && millis() - this->last_seen_ > this->timeout_) this->set_found_(false); } void dump_config() override;