1
0
mirror of https://github.com/esphome/esphome.git synced 2024-10-05 18:30:57 +01:00

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_() {
while (available()) {
int count = MAX_BYTES_PER_LOOP;
while (available() && count-- > 0) {
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");
header_found_ = true;
footer_found_ = false;
telegram_len_ = 0;
}
if (!header_found_)
continue;
if (telegram_len_ >= MAX_TELEGRAM_LENGTH) { // Buffer overflow
// Check for buffer overflow.
if (telegram_len_ >= MAX_TELEGRAM_LENGTH) {
header_found_ = false;
footer_found_ = false;
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'))
telegram_len_--;
// Store the byte in the buffer.
telegram_[telegram_len_] = c;
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");
footer_found_ = true;
} else {
if (footer_found_ && c == 10) { // last \n after footer
header_found_ = false;
// Parse message
if (parse_telegram())
return;
}
continue;
}
// Check for the end of the hex checksum, i.e. a newline.
if (footer_found_ && c == '\n') {
header_found_ = false;
// Parse the telegram and publish sensor values.
if (parse_telegram())
return;
}
}
}

View File

@ -17,6 +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;
using namespace ::dsmr::fields;