Skip to content

Commit 9ce0cac

Browse files
authored
Extend list of default patterns. Increase version to 1.1.0 (#8)
1 parent e58db1b commit 9ce0cac

9 files changed

Lines changed: 42 additions & 55 deletions

File tree

README.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,17 @@ parser.load_default_patterns();
2626

2727
Built-in patterns
2828

29-
| Name | Priority | Typical use |
30-
|-------|---------:|-------------------------------------------|
31-
| `T1` | 10 | class ID, tagged OBIS, scaler, value |
32-
| `T2` | 20 | tagged OBIS, value, scaler-unit structure |
33-
| `T3` | 30 | value first, class ID, scaler-unit, OBIS |
34-
| `ADV` | 40 | untagged ZPA/Aidon-style layouts |
29+
| Name | Pattern | Priority | Typical use |
30+
|------------------------------------------|------------------|---------:|-------------------------------------------|
31+
| `classId-taggedObis-scaler-value` | `TC,TO,TS,TV` | 10 | class ID, tagged OBIS, scaler, value |
32+
| `taggedObis-value-scalerUnit` | `TO,TV,TSU` | 20 | tagged OBIS, value, scaler-unit structure |
33+
| `value-classId-scalerUnit-taggedObis` | `TV,TC,TSU,TO` | 30 | value first, class ID, scaler-unit, OBIS |
34+
| `zpaAidon-untaggedLayout` | `ADV` | 40 | untagged ZPA/Aidon-style layouts |
35+
| `structuredObis-value-scalerUnit` | `S(TO, TV, TSU)` | 50 | OBIS, value, scaler-unit structure |
36+
| `structuredObis-value` | `S(TO, TV)` | 60 | OBIS and value structure |
37+
| `flatObis-valuePair` | `TO, TV` | 70 | flat OBIS + value pairs |
38+
| `firstElement-dateTime` | `F, S(TO, TDTM)` | 80 | first-element date-time structure |
39+
| `swappedTagObis-value-scalerUnit` | `TOW, TV, TSU` | 90 | swapped-tag OBIS, value, scaler-unit |
3540

3641
Register a custom pattern when your meter emits a different structure
3742

build-linux.sh

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
#!/usr/bin/env bash
2-
# This script requires clang and g++-13 to be installed:
2+
# This script requires clang to be installed:
33
# sudo apt-get update && sudo apt-get install -y clang
4-
# sudo add-apt-repository ppa:ubuntu-toolchain-r/test
5-
# sudo apt-get install -y g++-13
64

75
set -o xtrace -o errexit -o nounset -o pipefail
86

@@ -23,8 +21,6 @@ build_and_test() {
2321
ctest --test-dir "$buildDir/${target}-$build_type"
2422
}
2523

26-
export CC=gcc-13
27-
export CXX=g++-13
2824
build_and_test Debug linux-gcc
2925
build_and_test Release linux-gcc
3026

idf_component.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version: "1.0.0"
1+
version: "1.1.0"
22
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"
33
url: "https://github.com/esphome-libs/dlms_parser"
44
files:

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dlms_parser",
3-
"version": "1.0.2",
3+
"version": "1.1.0",
44
"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",
55
"keywords": [
66
"dlms",

src/dlms_parser/dlms_parser.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,16 @@ void DlmsParser::set_authentication_key(const Aes128GcmAuthenticationKey& key) c
3737
}
3838

3939
void DlmsParser::load_default_patterns() {
40-
axdr_parser_.register_pattern("T1", "TC,TO,TS,TV", 10);
41-
axdr_parser_.register_pattern("T2", "TO,TV,TSU", 20);
42-
axdr_parser_.register_pattern("T3", "TV,TC,TSU,TO", 30);
43-
axdr_parser_.register_pattern("ADV", "ADV", 40);
40+
axdr_parser_.clear_patterns();
41+
axdr_parser_.register_pattern("classId-taggedObis-scaler-value", "TC,TO,TS,TV", 10);
42+
axdr_parser_.register_pattern("taggedObis-value-scalerUnit", "TO,TV,TSU", 20);
43+
axdr_parser_.register_pattern("value-classId-scalerUnit-taggedObis", "TV,TC,TSU,TO", 30);
44+
axdr_parser_.register_pattern("zpaAidon-untaggedLayout", "ADV", 40);
45+
axdr_parser_.register_pattern("structuredObis-value-scalerUnit", "S(TO, TV, TSU)", 50);
46+
axdr_parser_.register_pattern("structuredObis-value", "S(TO, TV)", 60);
47+
axdr_parser_.register_pattern("flatObis-valuePair", "TO, TV", 70);
48+
axdr_parser_.register_pattern("firstElement-dateTime", "F, S(TO, TDTM)", 80);
49+
axdr_parser_.register_pattern("swappedTagObis-value-scalerUnit", "TOW, TV, TSU", 90);
4450
}
4551

4652
void DlmsParser::register_pattern(const char* dsl) {

tests/expected/hdlc_lgz_e450_2.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,12 @@ const auto hdlc_lgz_e450_2_key = dlms_parser::Aes128GcmDecryptionKey::from_bytes
4646
0xE1, 0xC0, 0xBA, 0x04, 0x8F, 0xA9, 0xA0, 0x23,
4747
}).value();
4848

49-
// 16 flat TO,TV pairs
50-
constexpr size_t hdlc_lgz_e450_2_expected_count = 16;
49+
// 16 flat TO,TV pairs and 1 datetime
50+
constexpr size_t hdlc_lgz_e450_2_expected_count = 17;
5151

52-
const std::map<std::string, std::string> hdlc_lgz_e450_2_expected_strings = {};
52+
const std::map<std::string, std::string> hdlc_lgz_e450_2_expected_strings = {
53+
{"0.0.0.0.0.0", "2023-11-10 10:58:50"}, // DateTime
54+
};
5355

5456
const std::map<std::string, float> hdlc_lgz_e450_2_expected_floats = {
5557
{"1.0.1.8.0.255", 12048950.0f}, // Active energy+ total

tests/expected/mbus_netz_noe_p1.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ const auto mbus_netz_noe_p1_key = dlms_parser::Aes128GcmDecryptionKey::from_byte
4242
}).value();
4343

4444
// 11 T2 objects + 1 meter number (L, TSTR) = 12 total
45-
constexpr size_t mbus_netz_noe_p1_expected_count = 12;
45+
constexpr size_t mbus_netz_noe_p1_expected_count = 13;
4646

4747
const std::map<std::string, std::string> mbus_netz_noe_p1_expected_strings = {
48+
{"0.0.0.0.0.0", "2021-09-27 09:47:15.00 -02:00"}, // DateTime
4849
{"0.0.96.1.0.255", "181220000009"}, // Meter number (last element, default OBIS from pattern)
4950
};
5051

tests/expected/raw_energomera.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ const uint8_t raw_energomera_frame[] = {
3131
0x00, 0x03,
3232
};
3333

34-
// 7 objects matched by T1 pattern inside ARRAY(7) of STRUCTURE(6) elements
35-
constexpr size_t raw_energomera_expected_count = 7;
34+
// 7 objects matched by T1 pattern inside ARRAY(7) of STRUCTURE(6) elements and 1 object matched by "Obis-Value"
35+
constexpr size_t raw_energomera_expected_count = 8;
3636

3737
const std::map<std::string, std::string> raw_energomera_expected_strings = {};
3838

@@ -44,6 +44,7 @@ const std::map<std::string, float> raw_energomera_expected_floats = {
4444
{"0.0.97.98.0.255", 0.0f}, // class=1, scaler=2
4545
{"0.0.97.98.10.255", 0.0f}, // class=1, scaler=2
4646
{"0.0.96.5.135.255", 0.0f}, // class=1, scaler=2
47+
{"0.0.99.98.4.255", 3.0f}
4748
};
4849

4950
} // namespace dlms::test_data

tests/test_meter_dumps.cpp

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,7 @@ TEST_CASE("Integration: RAW APDU") {
159159
dlms::test_data::raw_salzburg_netz_frame,
160160
dlms::test_data::raw_salzburg_netz_expected_count,
161161
dlms::test_data::raw_salzburg_netz_expected_strings,
162-
dlms::test_data::raw_salzburg_netz_expected_floats,
163-
[](dlms_parser::DlmsParser& p) {
164-
p.register_pattern("TO, TDTM");
165-
p.register_pattern("S(TO, TV)");
166-
}
162+
dlms::test_data::raw_salzburg_netz_expected_floats
167163
);
168164
}
169165

@@ -188,8 +184,7 @@ TEST_CASE("Integration: HDLC") {
188184
dlms::test_data::iskra550_raw_frame,
189185
dlms::test_data::iskra550_expected_count,
190186
dlms::test_data::iskra550_expected_strings,
191-
dlms::test_data::iskra550_expected_floats,
192-
[](dlms_parser::DlmsParser& p) { p.register_pattern("S(TO, TV)"); }
187+
dlms::test_data::iskra550_expected_floats
193188
);
194189
}
195190

@@ -200,8 +195,7 @@ TEST_CASE("Integration: HDLC") {
200195
duplicated_frame,
201196
dlms::test_data::iskra550_expected_count,
202197
dlms::test_data::iskra550_expected_strings,
203-
dlms::test_data::iskra550_expected_floats,
204-
[](dlms_parser::DlmsParser& p) { p.register_pattern("S(TO, TV)"); }
198+
dlms::test_data::iskra550_expected_floats
205199
);
206200
}
207201

@@ -220,11 +214,7 @@ TEST_CASE("Integration: HDLC") {
220214
dlms::test_data::norway_han_1phase_raw_frame,
221215
dlms::test_data::norway_han_1phase_expected_count,
222216
dlms::test_data::norway_han_1phase_expected_strings,
223-
dlms::test_data::norway_han_1phase_expected_floats,
224-
[](dlms_parser::DlmsParser& p) {
225-
p.register_pattern("S(TO, TV, TSU)");
226-
p.register_pattern("S(TO, TV)");
227-
}
217+
dlms::test_data::norway_han_1phase_expected_floats
228218
);
229219
}
230220

@@ -233,11 +223,7 @@ TEST_CASE("Integration: HDLC") {
233223
dlms::test_data::norway_han_3phase_raw_frame,
234224
dlms::test_data::norway_han_3phase_expected_count,
235225
dlms::test_data::norway_han_3phase_expected_strings,
236-
dlms::test_data::norway_han_3phase_expected_floats,
237-
[](dlms_parser::DlmsParser& p) {
238-
p.register_pattern("DateTime", "F, S(TO, TDTM)");
239-
p.register_pattern("Obis-Value-Scaler-Unit", "S(TO, TV, TSU)");
240-
}
226+
dlms::test_data::norway_han_3phase_expected_floats
241227
);
242228
}
243229

@@ -249,9 +235,6 @@ TEST_CASE("Integration: HDLC") {
249235
dlms::test_data::hdlc_landis_gyr_zmf100_expected_floats,
250236
[](dlms_parser::DlmsParser& p) {
251237
p.set_skip_crc_check(true);
252-
p.register_pattern("S(TO, TDTM)");
253-
p.register_pattern("S(TO, TV)");
254-
p.register_pattern("TOW, TV, TSU");
255238
}
256239
);
257240
}
@@ -274,7 +257,6 @@ TEST_CASE("Integration: HDLC") {
274257
[](dlms_parser::DlmsParser& p) {
275258
p.set_decryption_key(dlms::test_data::hdlc_landis_gyr_e450_key);
276259
p.register_pattern("DateTime", "F, TDTM");
277-
p.register_pattern("Obis-Value Pair","TO, TV");
278260
}
279261
);
280262
}
@@ -288,7 +270,6 @@ TEST_CASE("Integration: HDLC") {
288270
[](dlms_parser::DlmsParser& p) {
289271
p.set_decryption_key(dlms::test_data::hdlc_landis_gyr_e450_key);
290272
p.register_pattern("DateTime", "F, TDTM");
291-
p.register_pattern("Obis-Value Pair", "TO, TV");
292273
}
293274
);
294275
}
@@ -302,7 +283,6 @@ TEST_CASE("Integration: HDLC") {
302283
[](dlms_parser::DlmsParser& p) {
303284
p.set_decryption_key(dlms::test_data::hdlc_landis_gyr_e450_key);
304285
p.register_pattern("DateTime", "F, TDTM");
305-
p.register_pattern("Obis-Value Pair", "TO, TV");
306286
}
307287
);
308288
}
@@ -315,7 +295,7 @@ TEST_CASE("Integration: HDLC") {
315295
dlms::test_data::hdlc_lgz_e450_2_expected_floats,
316296
[](dlms_parser::DlmsParser& p) {
317297
p.set_decryption_key(dlms::test_data::hdlc_lgz_e450_2_key);
318-
p.register_pattern("TO, TV");
298+
p.register_pattern("DateTime", "F, TDTM");
319299
}
320300
);
321301
}
@@ -329,7 +309,6 @@ TEST_CASE("Integration: HDLC") {
329309
[](dlms_parser::DlmsParser& p) {
330310
p.set_decryption_key(dlms::test_data::hdlc_kamstrup_omnipower_key);
331311
p.register_pattern("Obis List Ver", "F, TSTR");
332-
p.register_pattern("Code-Value Pair", "TO, TV");
333312
}
334313
);
335314
}
@@ -344,7 +323,6 @@ TEST_CASE("Integration: HDLC") {
344323
p.set_decryption_key(dlms::test_data::hdlc_kamstrup_omnipower_key);
345324
p.set_authentication_key(dlms::test_data::hdlc_kamstrup_omnipower_auth_key);
346325
p.register_pattern("Obis List Ver", "F, TSTR");
347-
p.register_pattern("Code-Value Pair", "TO, TV");
348326
}
349327
);
350328
}
@@ -359,7 +337,6 @@ TEST_CASE("Integration: HDLC") {
359337
p.set_decryption_key(dlms::test_data::hdlc_kamstrup_omnipower_key);
360338
p.set_authentication_key(dlms::test_data::hdlc_kamstrup_omnipower_auth_key);
361339
p.register_pattern("Obis List Ver", "F, TSTR");
362-
p.register_pattern("Code-Value Pair", "TO, TV");
363340
}
364341
);
365342
}
@@ -374,7 +351,6 @@ TEST_CASE("Integration: HDLC") {
374351
p.set_decryption_key(dlms::test_data::hdlc_kamstrup_omnipower_key);
375352
p.set_authentication_key(dlms::test_data::hdlc_kamstrup_omnipower_auth_key);
376353
p.register_pattern("Obis List Ver", "F, TSTR");
377-
p.register_pattern("Code-Value Pair", "TO, TV");
378354
}
379355
);
380356
}
@@ -418,7 +394,7 @@ TEST_CASE("Integration: MBus") {
418394
p.set_decryption_key(dlms::test_data::mbus_netz_noe_p1_key);
419395
const uint8_t meter_obis[] = {0, 0, 96, 1, 0, 255}; // 0.0.96.1.0.255
420396
p.register_pattern("MeterID", "L, TSTR", 0, meter_obis);
421-
p.register_pattern("Obis-Value-Scaler-Unit", "S(TO, TV, TSU)");
397+
p.register_pattern("DateTime", "F, TDTM");
422398
}
423399
);
424400
}
@@ -435,7 +411,7 @@ TEST_CASE("Integration: MBus") {
435411
p.set_decryption_key(dlms::test_data::mbus_netz_noe_p1_key);
436412
const uint8_t meter_obis[] = { 0, 0, 96, 1, 0, 255 }; // 0.0.96.1.0.255
437413
p.register_pattern("MeterID", "L, TSTR", 0, meter_obis);
438-
p.register_pattern("Obis-Value-Scaler-Unit", "S(TO, TV, TSU)");
414+
p.register_pattern("DateTime", "F, TDTM");
439415
}
440416
);
441417
}

0 commit comments

Comments
 (0)