[components] Read UART bytes with read_available and discard_available (#21084)

This commit is contained in:
J. Nick Koston
2026-10-18 13:59:09 -10:00
committed by GitHub
parent 2dcb97774d
commit a70d75e469
30 changed files with 189 additions and 263 deletions
+3 -5
View File
@@ -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_() {
+3 -5
View File
@@ -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_() {
@@ -68,32 +68,32 @@ void AdalightLightEffect::apply(light::AddressableLight &it, const Color &curren
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) {
+6 -8
View File
@@ -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) {
@@ -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) {
+19 -18
View File
@@ -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;
+4 -9
View File
@@ -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) {
+35 -34
View File
@@ -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_() {
+1 -7
View File
@@ -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) {
+2 -3
View File
@@ -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) {
@@ -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) {
@@ -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));
}
}
});
}
/**
+3 -6
View File
@@ -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_() {
+1 -4
View File
@@ -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_();
}
+1 -5
View File
@@ -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);
}
+5 -15
View File
@@ -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);
-1
View File
@@ -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);
+3 -3
View File
@@ -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 {
+22 -20
View File
@@ -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<bool> PMSX003Component::check_byte_() {
+20 -17
View File
@@ -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) {
+2 -5
View File
@@ -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_)) {
+2 -4
View File
@@ -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) {
+9 -10
View File
@@ -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() {
+1 -5
View File
@@ -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<char, STATE_BUFFER_SIZE> buffer) {
+1 -3
View File
@@ -13,9 +13,7 @@ void SystaBus::dump_config() { ESP_LOGCONFIG(TAG, "SystaBus:"); }
static bool checksum(std::span<const uint8_t> 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) {
@@ -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
+2 -4
View File
@@ -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
@@ -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) &&
+12 -18
View File
@@ -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<size_t>(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<uint8_t> &message) {
+1 -7
View File
@@ -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); }