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

1#!/usr/bin/env python3 

2"""RAMSES RF - Test the various helper APIs.""" 

3 

4# TODO: add test for ramses_tx.frame.pkt_header() 

5 

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 

29 

30from .helpers import TEST_DIR 

31 

32WORK_DIR = f"{TEST_DIR}/parser_helpers" 

33 

34 

35def test_helper_demand_transform() -> None: 

36 assert [x[1] for x in TRANSFORMS] == [_transform(x[0]) for x in TRANSFORMS] 

37 

38 

39def test_helper_field_parsers() -> None: 

40 for val in ("FF", "00", "C8"): 

41 assert val == hex_from_bool(hex_to_bool(val)) 

42 

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) 

46 

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)) 

55 

56 for val in ("00000000007F",): 

57 assert val == hex_from_dts(hex_to_dts(val)) 

58 

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) 

62 

63 for val in ("7FFF", "7EFF", "0000", "0010", "0200", "D000"): 

64 assert val == hex_from_temp(hex_to_temp(val)) 

65 

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)) 

68 

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)) 

71 

72 

73def _test_pkt_dev_class() -> None: 

74 """Check that the device class is correctly inferred from the packet. 

75 

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 """ 

79 

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) 

84 

85 if not pkt_line[27:].strip(): 

86 return 

87 

88 pkt = Packet.from_file(pkt_line[:26], pkt_line[27:]) 

89 

90 assert pkt.src.type == eval(pkt_eval) # TODO: finish this test 

91 

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) 

96 

97 

98def test_pkt_addr_sets() -> None: 

99 """Check that the address set is correctly inferred from the packet.""" 

100 

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) 

105 

106 if not pkt_line[27:].strip(): 

107 return 

108 expected = eval(pkt_eval) 

109 

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 

117 

118 res = {"src": cmd.src.id, "dst": cmd.dst.id, "set": [a.id for a in cmd._addrs]} 

119 assert res == expected 

120 

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) 

125 

126 

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]