Fix CRC error during DSMR chunked message reading (#2622)

* DSMR chunk size from 50 to 500

* Still a few CRC errors with 500, upping to 1024.

* Adding timers to measure how long processing DSMR takes

* Handle chunked output from smart meter.

* Cleaning up and commenting the new chunk handling code

* Remove debug code.

* Fixing clang-tidy issues.

* Implementing chunked reading support for encrypted telegrams.

* Remove redundant extra delay for encrypted reader

* Beware not to flush crypted telegram headers

* Use insane data timeout for testing

* Improve logging

* Make clang-tidy happy

Co-authored-by: Maurice Makaay <mmakaay1@xs4all.net>
Co-authored-by: Maurice Makaay <account-github@makaay.nl>
This commit is contained in:
Maurice Makaay
2021-11-06 22:52:04 +01:00
committed by GitHub
parent d536509a63
commit b450d4c734
2 changed files with 71 additions and 47 deletions
+12 -2
View File
@@ -17,8 +17,7 @@ namespace esphome {
namespace dsmr {
static constexpr uint32_t MAX_TELEGRAM_LENGTH = 1500;
static constexpr uint32_t MAX_BYTES_PER_LOOP = 50;
static constexpr uint32_t POLL_TIMEOUT = 1000;
static constexpr uint32_t READ_TIMEOUT_MS = 200;
using namespace ::dsmr::fields;
@@ -86,6 +85,17 @@ class Dsmr : public Component, public uart::UARTDevice {
void receive_telegram_();
void receive_encrypted_();
/// Wait for UART data to become available within the read timeout.
///
/// The smart meter might provide data in chunks, causing available() to
/// return 0. When we're already reading a telegram, then we don't return
/// right away (to handle further data in an upcoming loop) but wait a
/// little while using this method to see if more data are incoming.
/// By not returning, we prevent other components from taking so much
/// time that the UART RX buffer overflows and bytes of the telegram get
/// lost in the process.
bool available_within_timeout_();
// Telegram buffer
char telegram_[MAX_TELEGRAM_LENGTH];
int telegram_len_{0};