mirror of
https://github.com/esphome/esphome.git
synced 2026-10-19 20:49:35 +00:00
[components] Read UART bytes with read_available and discard_available (#21084)
This commit is contained in:
@@ -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_() {
|
||||
|
||||
@@ -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 ¤
|
||||
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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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_() {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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_() {
|
||||
|
||||
@@ -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_();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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_() {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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_)) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) &&
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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); }
|
||||
|
||||
Reference in New Issue
Block a user