Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
version: "1.2.0"
description: "A C++20 library for parsing DLMS/COSEM push telegrams from electricity meters. It is designed for embedded and integration-heavy environments such as ESPHome"
url: "https://github.com/esphome-libs/dlms_parser"
files:
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dlms_parser",
"version": "1.2.0",
"version": "1.3.0",
"description": "A C++20 library for parsing DLMS/COSEM push telegrams from electricity meters. It is designed for embedded and integration-heavy environments such as ESPHome",
"keywords": [
"dlms",
Expand Down
11 changes: 11 additions & 0 deletions src/dlms_parser/dlms_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ static void log_span_as_hex(const LogLevel level, const std::span<const uint8_t>
}
}

static bool is_mbus_short_frame(const std::span<const uint8_t> data) {
if (data.size() < 5 || data[0] != 0x10 || data[4] != 0x16) return false;
return static_cast<uint8_t>(data[1] + data[2]) == data[3];
}

DlmsParser::DlmsParser(Aes128GcmDecryptor* decryptor) : decryptor_(decryptor) {}

void DlmsParser::set_skip_crc_check(const bool skip) {
Expand Down Expand Up @@ -72,6 +77,12 @@ ParseResult DlmsParser::parse(std::span<uint8_t> buf, const DlmsDataCallback& co
log_span_as_hex(LogLevel::VERY_VERBOSE, buf);
Logger::log(LogLevel::VERY_VERBOSE, "============");

if (is_mbus_short_frame(buf)) {
Logger::log(LogLevel::VERBOSE, "Skipping M-Bus short frame prefix");
buf = buf.subspan(5);
if (buf.empty()) return {};
}

std::span<uint8_t> decoded;

// Step 1: Frame decode (auto-detect HDLC / MBus / RAW from first byte)
Expand Down
11 changes: 11 additions & 0 deletions tests/test_meter_dumps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,17 @@ TEST_CASE("Integration: HDLC") {
);
}

SUBCASE("Iskra 550 (3 segmented frames) with leading M-Bus short frame") {
std::vector<uint8_t> frame{0x10, 0x40, 0x01, 0x41, 0x16};
frame.insert(frame.end(), std::begin(dlms::test_data::iskra550_raw_frame), std::end(dlms::test_data::iskra550_raw_frame));
run_meter_test(
frame,
dlms::test_data::iskra550_expected_count,
dlms::test_data::iskra550_expected_strings,
dlms::test_data::iskra550_expected_floats
);
}

SUBCASE("Iskra 550 (3 segmented frames) and the same data at the end. Should ignore the duplicated part") {
std::vector<uint8_t> duplicated_frame(std::begin(dlms::test_data::iskra550_raw_frame), std::end(dlms::test_data::iskra550_raw_frame));
duplicated_frame.insert(duplicated_frame.end(), std::begin(dlms::test_data::iskra550_raw_frame), std::end(dlms::test_data::iskra550_raw_frame));
Expand Down
Loading