From a70d75e46996065603dd4bd797f7287802943afa Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 18 Oct 2026 13:59:09 -1000 Subject: [PATCH] [components] Read UART bytes with read_available and discard_available (#21084) --- esphome/components/a01nyub/a01nyub.cpp | 8 +-- esphome/components/a02yyuw/a02yyuw.cpp | 8 +-- .../adalight/adalight_light_effect.cpp | 42 +++++------ esphome/components/apc1/apc1.cpp | 14 ++-- .../apc_proteous/apc_proteous_cover.cpp | 8 +-- esphome/components/daly_bms/daly_bms.cpp | 37 +++++----- esphome/components/emontx/emontx.cpp | 13 ++-- esphome/components/gcja5/gcja5.cpp | 69 ++++++++++--------- esphome/components/he60r/he60r.cpp | 8 +-- esphome/components/hlw8032/hlw8032.cpp | 5 +- .../hrxl_maxsonar_wr/hrxl_maxsonar_wr.cpp | 7 +- .../components/hydreon_rgxx/hydreon_rgxx.cpp | 8 +-- esphome/components/jsn_sr04t/jsn_sr04t.cpp | 9 +-- esphome/components/ld6002b/ld6002b.cpp | 5 +- esphome/components/nextion/nextion.cpp | 6 +- esphome/components/pipsolar/pipsolar.cpp | 20 ++---- esphome/components/pipsolar/pipsolar.h | 1 - esphome/components/pm1006/pm1006.cpp | 6 +- esphome/components/pmsx003/pmsx003.cpp | 42 +++++------ esphome/components/sds011/sds011.cpp | 37 +++++----- esphome/components/sim800l/sim800l.cpp | 7 +- esphome/components/sml/sml.cpp | 6 +- esphome/components/smt100/smt100.cpp | 19 +++-- esphome/components/sun_gtil2/sun_gtil2.cpp | 6 +- esphome/components/systa_bus/systa_bus.cpp | 4 +- .../uart/binary_sensor/uart_binary_sensor.cpp | 7 +- esphome/components/uart/event/uart_event.cpp | 6 +- .../uponor_smatrix/uponor_smatrix.cpp | 6 +- esphome/components/vbus/vbus.cpp | 30 ++++---- esphome/components/wts01/wts01.cpp | 8 +-- 30 files changed, 189 insertions(+), 263 deletions(-) diff --git a/esphome/components/a01nyub/a01nyub.cpp b/esphome/components/a01nyub/a01nyub.cpp index 8c97169cbf1..84f853c265a 100644 --- a/esphome/components/a01nyub/a01nyub.cpp +++ b/esphome/components/a01nyub/a01nyub.cpp @@ -9,15 +9,13 @@ namespace esphome::a01nyub { ESPHOME_LOG_TAG(TAG, "a01nyub.sensor"); void A01nyubComponent::loop() { - uint8_t data; - while (this->available() > 0) { - this->read_byte(&data); + this->read_available([this](uint8_t data) { if (this->buffer_.empty() && (data != 0xff)) - continue; + return; buffer_.push_back(data); if (this->buffer_.size() == 4) this->check_buffer_(); - } + }); } void A01nyubComponent::check_buffer_() { diff --git a/esphome/components/a02yyuw/a02yyuw.cpp b/esphome/components/a02yyuw/a02yyuw.cpp index 20e8f6c7b56..6b809ad396c 100644 --- a/esphome/components/a02yyuw/a02yyuw.cpp +++ b/esphome/components/a02yyuw/a02yyuw.cpp @@ -9,15 +9,13 @@ namespace esphome::a02yyuw { ESPHOME_LOG_TAG(TAG, "a02yyuw.sensor"); void A02yyuwComponent::loop() { - uint8_t data; - while (this->available() > 0) { - this->read_byte(&data); + this->read_available([this](uint8_t data) { if (this->buffer_.empty() && (data != 0xff)) - continue; + return; buffer_.push_back(data); if (this->buffer_.size() == 4) this->check_buffer_(); - } + }); } void A02yyuwComponent::check_buffer_() { diff --git a/esphome/components/adalight/adalight_light_effect.cpp b/esphome/components/adalight/adalight_light_effect.cpp index e3510d380eb..7e7dca0f2fd 100644 --- a/esphome/components/adalight/adalight_light_effect.cpp +++ b/esphome/components/adalight/adalight_light_effect.cpp @@ -68,32 +68,32 @@ void AdalightLightEffect::apply(light::AddressableLight &it, const Color ¤ blank_all_leds_(it); } - if (this->available() > 0) { - ESP_LOGV(TAG, "Frame: Available (size=%d).", this->available()); + const size_t avail = this->available(); + if (avail > 0) { + ESP_LOGV(TAG, "Frame: Available (size=%zu).", avail); } - while (this->available() != 0) { - uint8_t data; - if (!this->read_byte(&data)) - break; - this->frame_.push_back(data); - this->last_byte_ = now; + this->read_available( + [this, &it, now](uint8_t data) { + this->frame_.push_back(data); + this->last_byte_ = now; - switch (this->parse_frame_(it)) { - case INVALID: - ESP_LOGD(TAG, "Frame: Invalid (size=%zu, first=%d).", this->frame_.size(), this->frame_[0]); - reset_frame_(it); - break; + switch (this->parse_frame_(it)) { + case INVALID: + ESP_LOGD(TAG, "Frame: Invalid (size=%zu, first=%d).", this->frame_.size(), this->frame_[0]); + reset_frame_(it); + break; - case PARTIAL: - break; + case PARTIAL: + break; - case CONSUMED: - ESP_LOGV(TAG, "Frame: Consumed (size=%zu).", this->frame_.size()); - reset_frame_(it); - break; - } - } + case CONSUMED: + ESP_LOGV(TAG, "Frame: Consumed (size=%zu).", this->frame_.size()); + reset_frame_(it); + break; + } + }, + avail); } AdalightLightEffect::Frame AdalightLightEffect::parse_frame_(light::AddressableLight &it) { diff --git a/esphome/components/apc1/apc1.cpp b/esphome/components/apc1/apc1.cpp index dee4bd8d73b..b94f9c52021 100644 --- a/esphome/components/apc1/apc1.cpp +++ b/esphome/components/apc1/apc1.cpp @@ -104,16 +104,14 @@ void APC1Component::loop() { this->rx_index_ = 0; } - while (this->available()) { + this->read_available([this, now](uint8_t byte) { this->last_transmission_ = now; - uint8_t byte; - this->read_byte(&byte); if (this->rx_index_ == 0) { if (byte == APC1_HEADER_1) { this->rx_buffer_[this->rx_index_++] = byte; } - continue; + return; } if (this->rx_index_ == 1) { @@ -122,12 +120,12 @@ void APC1Component::loop() { } else if (byte != APC1_HEADER_1) { this->rx_index_ = 0; } - continue; + return; } this->rx_buffer_[this->rx_index_++] = byte; if (this->rx_index_ < APC1_FRAME_HEADER_SIZE) { - continue; + return; } // The payload carries at least the checksum and must fit the buffer; checking it before the sum keeps a @@ -136,14 +134,14 @@ void APC1Component::loop() { if (payload_len < 2 || payload_len > this->rx_buffer_.size() - APC1_FRAME_HEADER_SIZE) { ESP_LOGW(TAG, "Invalid frame length: %u", payload_len); this->rx_index_ = 0; - continue; + return; } const uint8_t total_len = payload_len + APC1_FRAME_HEADER_SIZE; if (this->rx_index_ == total_len) { this->parse_frame_(total_len); this->rx_index_ = 0; } - } + }); } void APC1Component::parse_frame_(uint16_t total_len) { diff --git a/esphome/components/apc_proteous/apc_proteous_cover.cpp b/esphome/components/apc_proteous/apc_proteous_cover.cpp index c17773da29c..e781cef67d5 100644 --- a/esphome/components/apc_proteous/apc_proteous_cover.cpp +++ b/esphome/components/apc_proteous/apc_proteous_cover.cpp @@ -27,11 +27,7 @@ void APCProteousCover::setup() { } void APCProteousCover::loop() { - uint8_t data; - while (this->available() > 0) { - if (!this->read_byte(&data)) { - continue; - } + this->read_available([this](uint8_t data) { const char *line = this->line_reader_.feed(data); if (this->line_reader_.overflowed()) { // Start over from this byte, so a frame right after unterminated noise is still read @@ -41,7 +37,7 @@ void APCProteousCover::loop() { ESP_LOGVV(TAG, "rx: '%s'", line); this->parse_response_(line); } - } + }); } void APCProteousCover::parse_response_(const char *line) { diff --git a/esphome/components/daly_bms/daly_bms.cpp b/esphome/components/daly_bms/daly_bms.cpp index 04ef798b69e..422f6f1350b 100644 --- a/esphome/components/daly_bms/daly_bms.cpp +++ b/esphome/components/daly_bms/daly_bms.cpp @@ -42,25 +42,26 @@ void DalyBmsComponent::loop() { this->last_transmission_ = now; this->trigger_next_ = true; } - if (available()) + const size_t avail = this->available(); + if (avail > 0) this->last_transmission_ = now; - while (available()) { - uint8_t c; - read_byte(&c); - if (!this->receiving_) { - if (c != 0xa5) - continue; - this->receiving_ = true; - } - this->data_.push_back(c); - if (this->data_.size() == 4) - this->data_count_ = c; - if ((this->data_.size() > 4) and (data_.size() == this->data_count_ + 5)) { - this->decode_data_(this->data_); - this->data_.clear(); - this->receiving_ = false; - } - } + this->read_available( + [this](uint8_t c) { + if (!this->receiving_) { + if (c != 0xa5) + return; + this->receiving_ = true; + } + this->data_.push_back(c); + if (this->data_.size() == 4) + this->data_count_ = c; + if ((this->data_.size() > 4) and (data_.size() == this->data_count_ + 5)) { + this->decode_data_(this->data_); + this->data_.clear(); + this->receiving_ = false; + } + }, + avail); if (this->trigger_next_) { this->trigger_next_ = false; diff --git a/esphome/components/emontx/emontx.cpp b/esphome/components/emontx/emontx.cpp index 888b12f4bf4..1992f36d328 100644 --- a/esphome/components/emontx/emontx.cpp +++ b/esphome/components/emontx/emontx.cpp @@ -111,8 +111,7 @@ void EmonTx::loop() { // Drop what arrived during the pause and resync at the next line start this->was_paused_ = false; uint8_t dropped = 0; - while (this->available() > 0 && this->read_byte(&dropped)) { - } + this->read_available([&dropped](uint8_t byte) { dropped = byte; }); if (dropped == '\n') { this->line_reader_.reset(); } else { @@ -126,16 +125,12 @@ void EmonTx::loop() { } // Read all available data to prevent UART buffer overflow - while (this->available() > 0) { - uint8_t received; - if (!this->read_byte(&received)) - break; - + this->read_available([this](uint8_t received) { size_t len; char *line = this->line_reader_.feed(received, len); this->line_reader_.log_if_overflowed(TAG); if (line == nullptr || len == 0) { - continue; + return; } ESP_LOGD(TAG, "Received line: %s", line); this->data_callbacks_.call(StringRef(line, len)); @@ -149,7 +144,7 @@ void EmonTx::loop() { this->parse_version_line_(line, len); } #endif - } + }); } void EmonTx::parse_json_(const char *data, size_t len) { diff --git a/esphome/components/gcja5/gcja5.cpp b/esphome/components/gcja5/gcja5.cpp index fcb9e832ea8..b908fcd9e15 100644 --- a/esphome/components/gcja5/gcja5.cpp +++ b/esphome/components/gcja5/gcja5.cpp @@ -20,48 +20,49 @@ void GCJA5Component::loop() { this->rx_message_.clear(); } - if (this->available() == 0) { + const size_t avail = this->available(); + if (avail == 0) { return; } // There must now be data waiting this->last_transmission_ = now; - uint8_t val; - while (this->available() != 0) { - this->read_byte(&val); - this->rx_message_.push_back(val); + this->read_available( + [this](uint8_t val) { + this->rx_message_.push_back(val); - // check if rx_message_ has 32 bytes of data - if (this->rx_message_.size() == 32) { - this->parse_data_(); + // check if rx_message_ has 32 bytes of data + if (this->rx_message_.size() == 32) { + this->parse_data_(); - if (this->have_good_data_) { - if (this->pm_1_0_sensor_ != nullptr) - this->pm_1_0_sensor_->publish_state(get_32_bit_uint_(1)); - if (this->pm_2_5_sensor_ != nullptr) - this->pm_2_5_sensor_->publish_state(get_32_bit_uint_(5)); - if (this->pm_10_0_sensor_ != nullptr) - this->pm_10_0_sensor_->publish_state(get_32_bit_uint_(9)); - if (this->pmc_0_3_sensor_ != nullptr) - this->pmc_0_3_sensor_->publish_state(get_16_bit_uint_(13)); - if (this->pmc_0_5_sensor_ != nullptr) - this->pmc_0_5_sensor_->publish_state(get_16_bit_uint_(15)); - if (this->pmc_1_0_sensor_ != nullptr) - this->pmc_1_0_sensor_->publish_state(get_16_bit_uint_(17)); - if (this->pmc_2_5_sensor_ != nullptr) - this->pmc_2_5_sensor_->publish_state(get_16_bit_uint_(21)); - if (this->pmc_5_0_sensor_ != nullptr) - this->pmc_5_0_sensor_->publish_state(get_16_bit_uint_(23)); - if (this->pmc_10_0_sensor_ != nullptr) - this->pmc_10_0_sensor_->publish_state(get_16_bit_uint_(25)); - } else { - this->status_set_warning(); - ESP_LOGV(TAG, "Have 32 bytes but not good data. Skipping."); - } + if (this->have_good_data_) { + if (this->pm_1_0_sensor_ != nullptr) + this->pm_1_0_sensor_->publish_state(get_32_bit_uint_(1)); + if (this->pm_2_5_sensor_ != nullptr) + this->pm_2_5_sensor_->publish_state(get_32_bit_uint_(5)); + if (this->pm_10_0_sensor_ != nullptr) + this->pm_10_0_sensor_->publish_state(get_32_bit_uint_(9)); + if (this->pmc_0_3_sensor_ != nullptr) + this->pmc_0_3_sensor_->publish_state(get_16_bit_uint_(13)); + if (this->pmc_0_5_sensor_ != nullptr) + this->pmc_0_5_sensor_->publish_state(get_16_bit_uint_(15)); + if (this->pmc_1_0_sensor_ != nullptr) + this->pmc_1_0_sensor_->publish_state(get_16_bit_uint_(17)); + if (this->pmc_2_5_sensor_ != nullptr) + this->pmc_2_5_sensor_->publish_state(get_16_bit_uint_(21)); + if (this->pmc_5_0_sensor_ != nullptr) + this->pmc_5_0_sensor_->publish_state(get_16_bit_uint_(23)); + if (this->pmc_10_0_sensor_ != nullptr) + this->pmc_10_0_sensor_->publish_state(get_16_bit_uint_(25)); + } else { + this->status_set_warning(); + ESP_LOGV(TAG, "Have 32 bytes but not good data. Skipping."); + } - this->rx_message_.clear(); - } - } + this->rx_message_.clear(); + } + }, + avail); } bool GCJA5Component::calculate_checksum_() { diff --git a/esphome/components/he60r/he60r.cpp b/esphome/components/he60r/he60r.cpp index 7c67c5ffd3f..a15551f4c1a 100644 --- a/esphome/components/he60r/he60r.cpp +++ b/esphome/components/he60r/he60r.cpp @@ -152,13 +152,7 @@ void HE60rCover::update_() { } void HE60rCover::loop() { - uint8_t data; - - while (this->available() > 0) { - if (this->read_byte(&data)) { - this->process_rx_(data); - } - } + this->read_available([this](uint8_t data) { this->process_rx_(data); }); } void HE60rCover::control(const CoverCall &call) { diff --git a/esphome/components/hlw8032/hlw8032.cpp b/esphome/components/hlw8032/hlw8032.cpp index cbb6b6c628d..eb0a15d6f2f 100644 --- a/esphome/components/hlw8032/hlw8032.cpp +++ b/esphome/components/hlw8032/hlw8032.cpp @@ -30,8 +30,7 @@ static constexpr uint8_t STATE_REG_OVERFLOW_MASK = 0xF; static constexpr uint8_t PACKET_LENGTH = 24; void HLW8032Component::loop() { - while (this->available()) { - uint8_t data = this->read(); + this->read_available([this](uint8_t data) { if (!this->header_found_) { if ((data == STATE_REG_CORRECTION_FUNC_NORMAL) || (data == STATE_REG_CORRECTION_FUNC_FAIL) || (data & STATE_REG_CORRECTION_MASK) == STATE_REG_CORRECTION_MASK) { @@ -57,7 +56,7 @@ void HLW8032Component::loop() { memset(this->raw_data_, 0, PACKET_LENGTH); } } - } + }); } uint32_t HLW8032Component::read_uint24_(uint8_t offset) { diff --git a/esphome/components/hrxl_maxsonar_wr/hrxl_maxsonar_wr.cpp b/esphome/components/hrxl_maxsonar_wr/hrxl_maxsonar_wr.cpp index 5415b7af74f..7317caf6c0d 100644 --- a/esphome/components/hrxl_maxsonar_wr/hrxl_maxsonar_wr.cpp +++ b/esphome/components/hrxl_maxsonar_wr/hrxl_maxsonar_wr.cpp @@ -20,10 +20,7 @@ ESPHOME_LOG_TAG(TAG, "hrxl.maxsonar.wr.sensor"); * The 123 means 123cm */ void HrxlMaxsonarWrComponent::loop() { - uint8_t data; - while (this->available() > 0) { - if (!this->read_byte(&data)) - continue; + this->read_available([this](uint8_t data) { size_t len; const char *line = this->line_reader_.feed(data, len); if (line != nullptr) { @@ -34,7 +31,7 @@ void HrxlMaxsonarWrComponent::loop() { ESP_LOGW(TAG, "Invalid data read from sensor: %s", this->line_reader_.partial()); this->line_reader_.reset(); } - } + }); } void HrxlMaxsonarWrComponent::handle_line_(const char *line, size_t len) { diff --git a/esphome/components/hydreon_rgxx/hydreon_rgxx.cpp b/esphome/components/hydreon_rgxx/hydreon_rgxx.cpp index 4a479874f53..c96e2a41ecb 100644 --- a/esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +++ b/esphome/components/hydreon_rgxx/hydreon_rgxx.cpp @@ -106,18 +106,14 @@ void HydreonRGxxComponent::update() { } void HydreonRGxxComponent::loop() { - uint8_t data; - while (this->available() > 0) { - if (!this->read_byte(&data)) { - continue; - } + this->read_available([this](uint8_t data) { size_t len; const char *line = this->line_reader_.feed(data, len); this->line_reader_.log_if_overflowed(TAG); if (line != nullptr) { this->process_line_(StringRef(line, len)); } - } + }); } /** diff --git a/esphome/components/jsn_sr04t/jsn_sr04t.cpp b/esphome/components/jsn_sr04t/jsn_sr04t.cpp index 0c7dd277381..502874a0022 100644 --- a/esphome/components/jsn_sr04t/jsn_sr04t.cpp +++ b/esphome/components/jsn_sr04t/jsn_sr04t.cpp @@ -14,19 +14,16 @@ void Jsnsr04tComponent::update() { } void Jsnsr04tComponent::loop() { - while (this->available() > 0) { - uint8_t data; - this->read_byte(&data); - + this->read_available([this](uint8_t data) { ESP_LOGV(TAG, "Read byte from sensor: %x", data); if (this->buffer_.empty() && data != 0xFF) - continue; + return; this->buffer_.push_back(data); if (this->buffer_.size() == 4) this->check_buffer_(); - } + }); } void Jsnsr04tComponent::check_buffer_() { diff --git a/esphome/components/ld6002b/ld6002b.cpp b/esphome/components/ld6002b/ld6002b.cpp index 42461228cef..3418d007ae4 100644 --- a/esphome/components/ld6002b/ld6002b.cpp +++ b/esphome/components/ld6002b/ld6002b.cpp @@ -497,10 +497,7 @@ void LD6002BComponent::dump_config() { } void LD6002BComponent::loop() { - while (this->available()) { - uint8_t byte = this->read(); - this->parse_byte_(byte); - } + this->read_available([this](uint8_t byte) { this->parse_byte_(byte); }); this->process_command_queue_(); } diff --git a/esphome/components/nextion/nextion.cpp b/esphome/components/nextion/nextion.cpp index b9194b3f31c..a5ac2325369 100644 --- a/esphome/components/nextion/nextion.cpp +++ b/esphome/components/nextion/nextion.cpp @@ -180,11 +180,7 @@ void Nextion::release_queue_entry_(NextionQueue *nb) { } void Nextion::reset_(bool reset_nextion) { - uint8_t d; - - while (this->available()) { // Clear receive buffer - this->read_byte(&d); - } + this->discard_available(); for (auto *entry : this->nextion_queue_) { this->release_queue_entry_(entry); } diff --git a/esphome/components/pipsolar/pipsolar.cpp b/esphome/components/pipsolar/pipsolar.cpp index ea7ebaed0ae..b5d17cf3c15 100644 --- a/esphome/components/pipsolar/pipsolar.cpp +++ b/esphome/components/pipsolar/pipsolar.cpp @@ -11,20 +11,10 @@ void Pipsolar::setup() { this->command_start_millis_ = 0; } -void Pipsolar::empty_uart_buffer_() { - uint8_t buf[64]; - size_t avail; - while ((avail = this->available()) > 0) { - if (!this->read_array(buf, std::min(avail, sizeof(buf)))) { - break; - } - } -} - void Pipsolar::loop() { // Read message if (this->state_ == STATE_IDLE) { - this->empty_uart_buffer_(); + this->discard_available(); if (this->send_next_command_()) { // command sent @@ -111,7 +101,7 @@ void Pipsolar::loop() { // make sure data and null terminator fit in buffer if (this->read_pos_ >= PIPSOLAR_READ_BUFFER_LENGTH - 1) { this->read_pos_ = 0; - this->empty_uart_buffer_(); + this->discard_available(); ESP_LOGW(TAG, "response data too long, discarding."); done = true; break; @@ -122,7 +112,7 @@ void Pipsolar::loop() { // end of answer if (byte == 0x0D) { this->read_buffer_[this->read_pos_] = 0; - this->empty_uart_buffer_(); + this->discard_available(); if (this->state_ == STATE_POLL) { this->state_ = STATE_POLL_COMPLETE; } @@ -202,7 +192,7 @@ bool Pipsolar::send_next_command_() { } this->state_ = STATE_COMMAND; this->command_start_millis_ = millis(); - this->empty_uart_buffer_(); + this->discard_available(); this->read_pos_ = 0; crc16 = this->pipsolar_crc_(byte_command, length); this->write_str(command); @@ -231,7 +221,7 @@ bool Pipsolar::send_next_poll_() { } this->state_ = STATE_POLL; this->command_start_millis_ = millis(); - this->empty_uart_buffer_(); + this->discard_available(); this->read_pos_ = 0; crc16 = this->pipsolar_crc_(this->enabled_polling_commands_[this->last_polling_command_].command, this->enabled_polling_commands_[this->last_polling_command_].length); diff --git a/esphome/components/pipsolar/pipsolar.h b/esphome/components/pipsolar/pipsolar.h index 4695e39829a..80ca0156a36 100644 --- a/esphome/components/pipsolar/pipsolar.h +++ b/esphome/components/pipsolar/pipsolar.h @@ -206,7 +206,6 @@ class Pipsolar final : public uart::UARTDevice, public PollingComponent { static const size_t COMMAND_TIMEOUT = 5000; static const size_t POLLING_COMMANDS_MAX = 15; void add_polling_command_(const char *command, ENUMPollingCommand polling_command); - void empty_uart_buffer_(); uint8_t check_incoming_crc_(); uint8_t check_incoming_length_(uint8_t length); uint16_t pipsolar_crc_(uint8_t *msg, uint8_t len); diff --git a/esphome/components/pm1006/pm1006.cpp b/esphome/components/pm1006/pm1006.cpp index 2f57c028439..9247cf37bf7 100644 --- a/esphome/components/pm1006/pm1006.cpp +++ b/esphome/components/pm1006/pm1006.cpp @@ -24,8 +24,8 @@ void PM1006Component::update() { } void PM1006Component::loop() { - while (this->available() != 0) { - this->read_byte(&this->data_[this->data_index_]); + this->read_available([this](uint8_t byte) { + this->data_[this->data_index_] = byte; auto check = this->check_byte_(); if (!check.has_value()) { // finished @@ -39,7 +39,7 @@ void PM1006Component::loop() { // next byte this->data_index_++; } - } + }); } uint8_t PM1006Component::pm1006_checksum_(const uint8_t *command_data, uint8_t length) const { diff --git a/esphome/components/pmsx003/pmsx003.cpp b/esphome/components/pmsx003/pmsx003.cpp index efc80e8c650..d7e7e0e22bc 100644 --- a/esphome/components/pmsx003/pmsx003.cpp +++ b/esphome/components/pmsx003/pmsx003.cpp @@ -83,8 +83,7 @@ void PMSX003Component::loop() { if (now - this->fan_on_time_ < STABILISING_MS) return; // consume any command responses that are in the serial buffer - while (this->available()) - this->read_byte(&this->data_[0]); + this->discard_available(); // Trigger a new read this->send_command_(Command::MANUAL_MEASUREMENT, 0); this->state_ = State::WAITING; @@ -100,27 +99,30 @@ void PMSX003Component::loop() { this->data_index_ = 0; } - if (this->available() == 0) + const size_t avail = this->available(); + if (avail == 0) return; this->last_transmission_ = now; - while (this->available() != 0) { - this->read_byte(&this->data_[this->data_index_]); - auto check = this->check_byte_(); - if (!check.has_value()) { - if (this->update_interval_ > STABILISING_MS || now - this->last_update_ >= this->update_interval_) { - this->parse_data_(); - this->last_update_ = now; - } - this->data_index_ = 0; - } else if (!*check) { - // wrong data - this->data_index_ = 0; - } else { - // next byte - this->data_index_++; - } - } + this->read_available( + [this, now](uint8_t byte) { + this->data_[this->data_index_] = byte; + auto check = this->check_byte_(); + if (!check.has_value()) { + if (this->update_interval_ > STABILISING_MS || now - this->last_update_ >= this->update_interval_) { + this->parse_data_(); + this->last_update_ = now; + } + this->data_index_ = 0; + } else if (!*check) { + // wrong data + this->data_index_ = 0; + } else { + // next byte + this->data_index_++; + } + }, + avail); } optional PMSX003Component::check_byte_() { diff --git a/esphome/components/sds011/sds011.cpp b/esphome/components/sds011/sds011.cpp index 147365251b5..08486e55589 100644 --- a/esphome/components/sds011/sds011.cpp +++ b/esphome/components/sds011/sds011.cpp @@ -83,27 +83,30 @@ void SDS011Component::loop() { this->data_index_ = 0; } - if (this->available() == 0) { + const size_t avail = this->available(); + if (avail == 0) { return; } this->last_transmission_ = now; - while (this->available() != 0) { - this->read_byte(&this->data_[this->data_index_]); - auto check = this->check_byte_(); - if (!check.has_value()) { - // finished - this->parse_data_(); - this->data_index_ = 0; - } else if (!*check) { - // wrong data - ESP_LOGV(TAG, "Byte %i of received data frame is invalid.", this->data_index_); - this->data_index_ = 0; - } else { - // next byte - this->data_index_++; - } - } + this->read_available( + [this](uint8_t byte) { + this->data_[this->data_index_] = byte; + auto check = this->check_byte_(); + if (!check.has_value()) { + // finished + this->parse_data_(); + this->data_index_ = 0; + } else if (!*check) { + // wrong data + ESP_LOGV(TAG, "Byte %i of received data frame is invalid.", this->data_index_); + this->data_index_ = 0; + } else { + // next byte + this->data_index_++; + } + }, + avail); } void SDS011Component::sds011_write_command_(const uint8_t *command_data) { diff --git a/esphome/components/sim800l/sim800l.cpp b/esphome/components/sim800l/sim800l.cpp index ba07bc3d6d3..1c23de43abf 100644 --- a/esphome/components/sim800l/sim800l.cpp +++ b/esphome/components/sim800l/sim800l.cpp @@ -422,10 +422,7 @@ void Sim800LComponent::parse_cmd_(std::string message) { void Sim800LComponent::loop() { // Read message - while (this->available()) { - uint8_t byte; - this->read_byte(&byte); - + this->read_available([this](uint8_t byte) { ESP_LOGVV(TAG, "Buffer pos: %u %d", this->line_reader_.length(), byte); // NOLINT if (byte >= 0x7F) @@ -441,7 +438,7 @@ void Sim800LComponent::loop() { } else { this->line_reader_.log_if_overflowed(TAG); } - } + }); if (state_ == STATE_INIT && this->registered_ && (this->call_state_ != 6 // A call is in progress || this->send_pending_ || this->dial_pending_ || this->connect_pending_ || this->disconnect_pending_)) { diff --git a/esphome/components/sml/sml.cpp b/esphome/components/sml/sml.cpp index a4bc4373d7c..6924e2fdd9c 100644 --- a/esphome/components/sml/sml.cpp +++ b/esphome/components/sml/sml.cpp @@ -24,9 +24,7 @@ char Sml::check_start_end_bytes_(uint8_t byte) { } void Sml::loop() { - while (available()) { - const char c = read(); - + this->read_available([this](uint8_t c) { if (this->record_) this->sml_data_.emplace_back(c); @@ -57,7 +55,7 @@ void Sml::loop() { break; }; }; - } + }); } void Sml::process_sml_file_(const BytesView &sml_data) { diff --git a/esphome/components/smt100/smt100.cpp b/esphome/components/smt100/smt100.cpp index 8a8f82b8504..67b3f4faecf 100644 --- a/esphome/components/smt100/smt100.cpp +++ b/esphome/components/smt100/smt100.cpp @@ -11,32 +11,31 @@ void SMT100Component::update() { } void SMT100Component::loop() { - while (this->available() != 0) { - const int readch = this->read(); - if (readch <= 0) - continue; + this->read_available([this](uint8_t readch) { + if (readch == 0) + return; char *line = this->line_reader_.feed(readch); this->line_reader_.log_if_overflowed(TAG); if (line != nullptr && line[0] != '\0') { char *token = strtok(line, ","); if (!token) - continue; + return; int counts = (int) strtol(token, nullptr, 10); token = strtok(nullptr, ","); if (!token) - continue; + return; float permittivity = (float) strtod(token, nullptr); token = strtok(nullptr, ","); if (!token) - continue; + return; float moisture = (float) strtod(token, nullptr); token = strtok(nullptr, ","); if (!token) - continue; + return; float temperature = (float) strtod(token, nullptr); token = strtok(nullptr, ","); if (!token) - continue; + return; float voltage = (float) strtod(token, nullptr); if (this->counts_sensor_ != nullptr) { @@ -59,7 +58,7 @@ void SMT100Component::loop() { voltage_sensor_->publish_state(voltage); } } - } + }); } void SMT100Component::dump_config() { diff --git a/esphome/components/sun_gtil2/sun_gtil2.cpp b/esphome/components/sun_gtil2/sun_gtil2.cpp index f89797cc106..edaac470cb7 100644 --- a/esphome/components/sun_gtil2/sun_gtil2.cpp +++ b/esphome/components/sun_gtil2/sun_gtil2.cpp @@ -39,11 +39,7 @@ static_assert(MESSAGE_SIZE == 350, "Expected the message size to be 350 bytes"); void SunGTIL2::setup() { this->rx_message_.reserve(MESSAGE_SIZE); } void SunGTIL2::loop() { - while (this->available()) { - uint8_t c; - this->read_byte(&c); - this->handle_char_(c); - } + this->read_available([this](uint8_t c) { this->handle_char_(c); }); } const char *SunGTIL2::state_to_string_(uint8_t state, std::span buffer) { diff --git a/esphome/components/systa_bus/systa_bus.cpp b/esphome/components/systa_bus/systa_bus.cpp index 6c780d07a92..884ad986b3a 100644 --- a/esphome/components/systa_bus/systa_bus.cpp +++ b/esphome/components/systa_bus/systa_bus.cpp @@ -13,9 +13,7 @@ void SystaBus::dump_config() { ESP_LOGCONFIG(TAG, "SystaBus:"); } static bool checksum(std::span data) { return sum_bytes(data.data(), data.size()) == 0; } void SystaBus::loop() { - uint8_t c; - while (this->available() && this->read_byte(&c)) - this->handle_byte_(c); + this->read_available([this](uint8_t c) { this->handle_byte_(c); }); } void SystaBus::handle_byte_(uint8_t c) { diff --git a/esphome/components/uart/binary_sensor/uart_binary_sensor.cpp b/esphome/components/uart/binary_sensor/uart_binary_sensor.cpp index 9bf9e726561..67158c82de1 100644 --- a/esphome/components/uart/binary_sensor/uart_binary_sensor.cpp +++ b/esphome/components/uart/binary_sensor/uart_binary_sensor.cpp @@ -14,10 +14,7 @@ void UARTBinarySensorHub::dump_config() { } void UARTBinarySensorHub::loop() { - while (this->available()) { - uint8_t byte; - if (!this->read_byte(&byte)) - break; + this->read_available([this](uint8_t byte) { this->buffer_.push_overwrite(byte); for (const auto &matcher : this->matchers_) { // The byte just read has to be the pattern's last one before the rest is compared @@ -30,7 +27,7 @@ void UARTBinarySensorHub::loop() { this->buffer_.clear(); break; } - } + }); } // Whether the pattern, apart from its last byte, ends the buffer diff --git a/esphome/components/uart/event/uart_event.cpp b/esphome/components/uart/event/uart_event.cpp index 22bcee9c83f..5cbd7ed7829 100644 --- a/esphome/components/uart/event/uart_event.cpp +++ b/esphome/components/uart/event/uart_event.cpp @@ -20,9 +20,7 @@ void UARTEvent::add_event_matcher(const char *event_name, const uint8_t *match_d } void UARTEvent::read_data_() { - while (this->available()) { - uint8_t data; - this->read_byte(&data); + this->read_available([this](uint8_t data) { this->buffer_.push_back(data); bool match_found = false; @@ -42,7 +40,7 @@ void UARTEvent::read_data_() { if (!match_found && this->max_matcher_len_ > 0 && this->buffer_.size() > this->max_matcher_len_) { this->buffer_.erase(this->buffer_.begin()); } - } + }); } } // namespace esphome::uart diff --git a/esphome/components/uponor_smatrix/uponor_smatrix.cpp b/esphome/components/uponor_smatrix/uponor_smatrix.cpp index fd6eda73a0c..8db3c148958 100644 --- a/esphome/components/uponor_smatrix/uponor_smatrix.cpp +++ b/esphome/components/uponor_smatrix/uponor_smatrix.cpp @@ -47,17 +47,15 @@ void UponorSmatrixComponent::loop() { } // Read incoming data - while (this->available()) { + this->read_available([this, now](uint8_t byte) { // The controller polls devices every 10 seconds in some units or continuously in others with around 200 ms between // devices. Remember timestamps so we can send our own packets when the bus is expected to be silent. this->last_rx_ = now; - uint8_t byte; - this->read_byte(&byte); if (this->parse_byte_(byte)) { this->rx_buffer_.clear(); } - } + }); // Send packets during bus silence if (this->rx_buffer_.empty() && (now - this->last_rx_ > 50) && (now - this->last_rx_ < 100) && diff --git a/esphome/components/vbus/vbus.cpp b/esphome/components/vbus/vbus.cpp index 6b6a3393ee4..c45ae6bdaa3 100644 --- a/esphome/components/vbus/vbus.cpp +++ b/esphome/components/vbus/vbus.cpp @@ -28,24 +28,18 @@ static bool checksum(const uint8_t *data, int start, int count) { } void VBus::loop() { - if (!available()) - return; - - while (available()) { - uint8_t c; - read_byte(&c); - + this->read_available([this](uint8_t c) { if (c == 0xaa) { this->state_ = 1; this->buffer_.clear(); - continue; + return; } if (c & 0x80) { this->state_ = 0; - continue; + return; } if (this->state_ == 0) - continue; + return; if (this->state_ == 1) { this->buffer_.push_back(c); @@ -59,7 +53,7 @@ void VBus::loop() { this->state_ = 0; if (!checksum(this->buffer_.data(), 0, 15)) { ESP_LOGE(TAG, "P2 checksum failed"); - continue; + return; } septet_spread(this->buffer_.data(), 7, 6, this->buffer_[13]); uint16_t id = (this->buffer_[8] << 8) + this->buffer_[7]; @@ -70,7 +64,7 @@ void VBus::loop() { if (!checksum(this->buffer_.data(), 0, 9)) { ESP_LOGE(TAG, "P1 checksum failed"); this->state_ = 0; - continue; + return; } this->frames_ = this->buffer_[7]; if (this->frames_) { @@ -86,23 +80,23 @@ void VBus::loop() { ESP_LOGW(TAG, "Unknown protocol 0x%02x, discarding", this->protocol_); this->state_ = 0; } - continue; + return; } if (this->state_ == 2) { this->fbytes_[this->fbcount_++] = c; if (this->fbcount_ < 6) - continue; + return; this->fbcount_ = 0; if (!checksum(this->fbytes_, 0, 6)) { ESP_LOGE(TAG, "frame checksum failed"); - continue; + return; } septet_spread(this->fbytes_, 0, 4, this->fbytes_[4]); for (int i = 0; i < 4; i++) this->buffer_.push_back(this->fbytes_[i]); if (++this->cframe_ < this->frames_) - continue; + return; #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE char hex_buf[format_hex_size(VBUS_MAX_LOG_BYTES)]; size_t log_bytes = std::min(this->buffer_.size(), static_cast(VBUS_MAX_LOG_BYTES)); @@ -112,9 +106,9 @@ void VBus::loop() { for (auto &listener : this->listeners_) listener->on_message(this->command_, this->source_, this->dest_, this->buffer_); this->state_ = 0; - continue; + return; } - } + }); } void VBusListener::on_message(uint16_t command, uint16_t source, uint16_t dest, std::vector &message) { diff --git a/esphome/components/wts01/wts01.cpp b/esphome/components/wts01/wts01.cpp index b7b9e5cfa99..93eb1f3227e 100644 --- a/esphome/components/wts01/wts01.cpp +++ b/esphome/components/wts01/wts01.cpp @@ -12,13 +12,7 @@ constexpr uint8_t HEADER_4 = 0x04; ESPHOME_LOG_TAG(TAG, "wts01"); void WTS01Sensor::loop() { - // Process all available data at once - while (this->available()) { - uint8_t c; - if (this->read_byte(&c)) { - this->handle_char_(c); - } - } + this->read_available([this](uint8_t c) { this->handle_char_(c); }); } void WTS01Sensor::dump_config() { LOG_SENSOR("", "WTS01 Sensor", this); }