Coverage for tests/tests/test_parser_helpers.py: 0%
63 statements
« prev ^ index » next coverage.py v7.11.3, created at 2026-01-05 21:46 +0100
« prev ^ index » next coverage.py v7.11.3, created at 2026-01-05 21:46 +0100
1#!/usr/bin/env python3
2"""RAMSES RF - Test the various helper APIs."""
4# TODO: add test for ramses_tx.frame.pkt_header()
6from ramses_rf.system.zones import _transform
7from ramses_tx.command import Command
8from ramses_tx.exceptions import CommandInvalid, PacketInvalid
9from ramses_tx.helpers import (
10 hex_from_bool,
11 hex_from_double,
12 hex_from_dtm,
13 hex_from_dts,
14 hex_from_flag8,
15 hex_from_percent,
16 # hex_from_str,
17 hex_from_temp,
18 hex_to_bool,
19 # hex_to_date,
20 hex_to_double,
21 hex_to_dtm,
22 hex_to_dts,
23 hex_to_flag8,
24 hex_to_percent,
25 # hex_to_str,
26 hex_to_temp,
27)
28from ramses_tx.packet import Packet
30from .helpers import TEST_DIR
32WORK_DIR = f"{TEST_DIR}/parser_helpers"
35def test_helper_demand_transform() -> None:
36 assert [x[1] for x in TRANSFORMS] == [_transform(x[0]) for x in TRANSFORMS]
39def test_helper_field_parsers() -> None:
40 for val in ("FF", "00", "C8"):
41 assert val == hex_from_bool(hex_to_bool(val))
43 for val in ("7FFF", "0000", "0001", "0010", "0100", "1000"):
44 assert val == hex_from_double(hex_to_double(val))
45 assert val == hex_from_double(hex_to_double(val, factor=100), factor=100)
47 for val in (
48 "FF" * 6,
49 "FF" * 7,
50 "00141B0A07E3",
51 "00110E0507E5",
52 "0400041C0A07E3",
53 ):
54 assert val == hex_from_dtm(hex_to_dtm(val), incl_seconds=(len(val) == 14))
56 for val in ("00000000007F",):
57 assert val == hex_from_dts(hex_to_dts(val))
59 for val in ("00", "01", "08", "10", "E0", "CC", "FF"):
60 assert val == hex_from_flag8(hex_to_flag8(val))
61 assert val == hex_from_flag8(hex_to_flag8(val, lsb=True), lsb=True)
63 for val in ("7FFF", "7EFF", "0000", "0010", "0200", "D000"):
64 assert val == hex_from_temp(hex_to_temp(val))
66 for tmp in (None, False, -127.99, -100, -22.5, -1.53, 0, 1.53, 22.5, 100, 127.98):
67 assert tmp == hex_to_temp(hex_from_temp(tmp))
69 for cent in (None, 0, 0.05, 0.1, 0.5, 0.95, 1.0):
70 assert cent == hex_to_percent(hex_from_percent(cent))
73def _test_pkt_dev_class() -> None:
74 """Check that the device class is correctly inferred from the packet.
76 Some packets (not all) can be used to determine the domain (Heat vs HVAC) and
77 class (e.g. BDR, CTL, FAN, etc)of the source device.
78 """
80 def proc_log_line(log_line: str) -> None:
81 if "#" not in log_line:
82 return
83 pkt_line, pkt_eval = log_line.split("#", maxsplit=1)
85 if not pkt_line[27:].strip():
86 return
88 pkt = Packet.from_file(pkt_line[:26], pkt_line[27:])
90 assert pkt.src.type == eval(pkt_eval) # TODO: finish this test
92 with open(f"{WORK_DIR}/pkt_dev_class.log") as f:
93 while line := (f.readline()):
94 if line.strip():
95 proc_log_line(line)
98def test_pkt_addr_sets() -> None:
99 """Check that the address set is correctly inferred from the packet."""
101 def proc_log_line(log_line: str) -> None:
102 if "#" not in log_line:
103 return
104 pkt_line, pkt_eval = log_line.split("#", maxsplit=1)
106 if not pkt_line[27:].strip():
107 return
108 expected = eval(pkt_eval)
110 try:
111 cmd = Command(pkt_line[31:].rstrip())
112 cmd._validate(strict_checking=True)
113 except (CommandInvalid, PacketInvalid) as err:
114 assert err.__class__ == expected.__class__
115 assert err.message and err.message.startswith(expected.message)
116 return
118 res = {"src": cmd.src.id, "dst": cmd.dst.id, "set": [a.id for a in cmd._addrs]}
119 assert res == expected
121 with open(f"{WORK_DIR}/pkt_addr_set.log") as f:
122 while line := (f.readline()):
123 if (line := line.strip()) and line[:1] != "#":
124 proc_log_line(line)
127TRANSFORMS = [
128 (0.000, 0),
129 (0.220, 0),
130 (0.230, 0),
131 (0.260, 0),
132 # (0.295, 0), # needs confirming
133 (0.300, 0),
134 # (0.305, 0), # needs confirming
135 (0.310, 0.01),
136 (0.340, 0.03),
137 (0.350, 0.04),
138 (0.370, 0.05),
139 (0.380, 0.06),
140 (0.390, 0.07),
141 (0.400, 0.08),
142 (0.410, 0.08),
143 (0.420, 0.09),
144 (0.430, 0.10),
145 (0.450, 0.11),
146 (0.470, 0.13),
147 (0.480, 0.14),
148 (0.530, 0.17),
149 (0.540, 0.18),
150 (0.550, 0.19),
151 (0.560, 0.20),
152 (0.575, 0.21),
153 (0.610, 0.23),
154 (0.620, 0.24),
155 (0.650, 0.26),
156 (0.660, 0.27),
157 (0.680, 0.29),
158 (0.690, 0.29),
159 # (0.695, 0.30), # needs confirming
160 (0.700, 0.30),
161 # (0.705, 0.31), # needs confirming
162 (0.720, 0.35),
163 (0.740, 0.39),
164 (0.760, 0.44),
165 (0.770, 0.46),
166 (0.790, 0.51),
167 (0.800, 0.53),
168 (0.820, 0.58),
169 (0.830, 0.60),
170 (0.840, 0.63),
171 (0.930, 0.84),
172 (0.950, 0.88),
173 # (0.995, 0.99), # needs confirming
174 (1.000, 1.0),
175]