PRE-M8-T01: add WarmteLink P1 telegram parser
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
from decimal import Decimal
|
||||
from pathlib import Path
|
||||
|
||||
from scripts.p1_probe import IntegrityStatus, TelegramFramer, parse_telegram
|
||||
|
||||
|
||||
FIXTURES = Path(__file__).parent / "fixtures"
|
||||
|
||||
|
||||
def _fixture(name: str) -> bytes:
|
||||
return (FIXTURES / name).read_bytes()
|
||||
|
||||
|
||||
def test_standard_dsmr_fixture_has_a_valid_frame_and_crc():
|
||||
frame = _fixture("dsmr_p1_valid.txt")
|
||||
framer = TelegramFramer()
|
||||
|
||||
assert framer.feed(frame[:23]) == []
|
||||
assert framer.feed(frame[23:]) == [frame]
|
||||
|
||||
telegram = parse_telegram(frame)
|
||||
assert telegram.integrity is IntegrityStatus.VALID
|
||||
assert telegram.header == b"/ISk5\\2MT382-1000"
|
||||
assert telegram.timestamp == "240822120000S"
|
||||
|
||||
|
||||
def test_warmtelink_fixture_is_unverifiable_but_parses_channels_by_obis_code():
|
||||
telegram = parse_telegram(_fixture("warmtelink_p1_7n1.txt"))
|
||||
|
||||
assert telegram.integrity is IntegrityStatus.UNVERIFIABLE
|
||||
assert "missing standard" in telegram.integrity_reason
|
||||
assert [channel.number for channel in telegram.channels] == [1, 2]
|
||||
values = {
|
||||
channel.number: [(field.value, field.unit) for field in channel.readings]
|
||||
for channel in telegram.channels
|
||||
}
|
||||
assert values[1] == [(Decimal("5.900"), "m3")]
|
||||
assert values[2] == [(Decimal("0.017"), "GJ")]
|
||||
|
||||
|
||||
def test_arbitrary_chunk_boundaries_and_field_order_do_not_change_parsing():
|
||||
frame = _fixture("warmtelink_p1_7n1.txt")
|
||||
framer = TelegramFramer()
|
||||
frames = []
|
||||
for byte in frame:
|
||||
frames.extend(framer.feed(bytes([byte])))
|
||||
|
||||
assert frames == [frame]
|
||||
assert parse_telegram(frames[0]).channels == parse_telegram(frame).channels
|
||||
|
||||
|
||||
def test_unknown_fields_are_preserved_verbatim():
|
||||
frame = b")HEADER\n9-9:9.9.9(opaque)(still-opaque)\n!nope\n"
|
||||
|
||||
telegram = parse_telegram(frame)
|
||||
|
||||
assert len(telegram.fields) == 1
|
||||
assert telegram.fields[0].code == "9-9:9.9.9"
|
||||
assert telegram.fields[0].raw_values == ("opaque", "still-opaque")
|
||||
assert telegram.fields[0].value is None
|
||||
|
||||
|
||||
def test_missing_header_and_non_hex_footer_are_unverifiable():
|
||||
telegram = parse_telegram(b")HEADER\n0-0:1.0.0(240822120000S)\n!zzzz\n")
|
||||
|
||||
assert telegram.integrity is IntegrityStatus.UNVERIFIABLE
|
||||
assert telegram.footer == b"zzzz"
|
||||
|
||||
|
||||
def test_crc_mismatch_is_invalid_when_standard_framing_is_present():
|
||||
frame = _fixture("dsmr_p1_valid.txt")
|
||||
invalid = frame[:-5] + b"0000\n"
|
||||
|
||||
telegram = parse_telegram(invalid)
|
||||
|
||||
assert telegram.integrity is IntegrityStatus.INVALID
|
||||
Reference in New Issue
Block a user