Read unencrypted DSMR telegrams in chunks (#2382)

Co-authored-by: Maurice Makaay <mmakaay1@xs4all.net>
This commit is contained in:
Maurice Makaay 2021-09-24 14:15:22 +02:00 committed by GitHub
parent aea2491fa4
commit 52dd79691b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 12 deletions

View file

@ -20,19 +20,22 @@ void Dsmr::loop() {
} }
void Dsmr::receive_telegram_() { void Dsmr::receive_telegram_() {
while (available()) { int count = MAX_BYTES_PER_LOOP;
while (available() && count-- > 0) {
const char c = read(); const char c = read();
if (c == '/') { // header: forward slash // Find a new telegram header, i.e. forward slash.
if (c == '/') {
ESP_LOGV(TAG, "Header found"); ESP_LOGV(TAG, "Header found");
header_found_ = true; header_found_ = true;
footer_found_ = false; footer_found_ = false;
telegram_len_ = 0; telegram_len_ = 0;
} }
if (!header_found_) if (!header_found_)
continue; continue;
if (telegram_len_ >= MAX_TELEGRAM_LENGTH) { // Buffer overflow
// Check for buffer overflow.
if (telegram_len_ >= MAX_TELEGRAM_LENGTH) {
header_found_ = false; header_found_ = false;
footer_found_ = false; footer_found_ = false;
ESP_LOGE(TAG, "Error: Message larger than buffer"); ESP_LOGE(TAG, "Error: Message larger than buffer");
@ -45,18 +48,22 @@ void Dsmr::receive_telegram_() {
while (c == '(' && (telegram_[telegram_len_ - 1] == '\n' || telegram_[telegram_len_ - 1] == '\r')) while (c == '(' && (telegram_[telegram_len_ - 1] == '\n' || telegram_[telegram_len_ - 1] == '\r'))
telegram_len_--; telegram_len_--;
// Store the byte in the buffer.
telegram_[telegram_len_] = c; telegram_[telegram_len_] = c;
telegram_len_++; telegram_len_++;
if (c == '!') { // footer: exclamation mark
// Check for a footer, i.e. exlamation mark, followed by a hex checksum.
if (c == '!') {
ESP_LOGV(TAG, "Footer found"); ESP_LOGV(TAG, "Footer found");
footer_found_ = true; footer_found_ = true;
} else { continue;
if (footer_found_ && c == 10) { // last \n after footer }
header_found_ = false; // Check for the end of the hex checksum, i.e. a newline.
// Parse message if (footer_found_ && c == '\n') {
if (parse_telegram()) header_found_ = false;
return; // Parse the telegram and publish sensor values.
} if (parse_telegram())
return;
} }
} }
} }

View file

@ -17,6 +17,7 @@ namespace esphome {
namespace dsmr { namespace dsmr {
static constexpr uint32_t MAX_TELEGRAM_LENGTH = 1500; 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 POLL_TIMEOUT = 1000;
using namespace ::dsmr::fields; using namespace ::dsmr::fields;