velbus-aio 2021.8.7__py3-none-any.whl → 2025.11.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. scripts/parse_specs.py +156 -0
  2. velbus_aio-2025.11.0.dist-info/METADATA +71 -0
  3. velbus_aio-2025.11.0.dist-info/RECORD +194 -0
  4. {velbus_aio-2021.8.7.dist-info → velbus_aio-2025.11.0.dist-info}/WHEEL +1 -1
  5. velbus_aio-2025.11.0.dist-info/top_level.txt +3 -0
  6. velbusaio/channels.py +443 -109
  7. velbusaio/command_registry.py +126 -13
  8. velbusaio/const.py +36 -12
  9. velbusaio/controller.py +252 -177
  10. velbusaio/discovery.py +2 -2
  11. velbusaio/exceptions.py +22 -0
  12. velbusaio/handler.py +311 -145
  13. velbusaio/helpers.py +6 -18
  14. velbusaio/message.py +46 -132
  15. velbusaio/messages/__init__.py +12 -2
  16. velbusaio/messages/blind_status.py +16 -25
  17. velbusaio/messages/bus_active.py +3 -9
  18. velbusaio/messages/bus_error_counter_status.py +3 -4
  19. velbusaio/messages/bus_error_counter_status_request.py +3 -4
  20. velbusaio/messages/bus_off.py +3 -4
  21. velbusaio/messages/channel_name_part1.py +49 -33
  22. velbusaio/messages/channel_name_part2.py +49 -33
  23. velbusaio/messages/channel_name_part3.py +49 -33
  24. velbusaio/messages/channel_name_request.py +26 -12
  25. velbusaio/messages/clear_led.py +3 -4
  26. velbusaio/messages/counter_status.py +3 -17
  27. velbusaio/messages/counter_status_request.py +6 -6
  28. velbusaio/messages/counter_value.py +44 -0
  29. velbusaio/messages/cover_down.py +4 -29
  30. velbusaio/messages/cover_off.py +5 -29
  31. velbusaio/messages/cover_position.py +4 -19
  32. velbusaio/messages/cover_up.py +4 -27
  33. velbusaio/messages/dali_device_settings.py +178 -0
  34. velbusaio/messages/dali_device_settings_request.py +53 -0
  35. velbusaio/messages/dali_dim_value_status.py +44 -0
  36. velbusaio/messages/dimmer_channel_status.py +6 -19
  37. velbusaio/messages/dimmer_status.py +14 -31
  38. velbusaio/messages/edge_set_color.py +114 -0
  39. velbusaio/messages/edge_set_custom_color.py +56 -0
  40. velbusaio/messages/fast_blinking_led.py +3 -4
  41. velbusaio/messages/forced_off.py +3 -4
  42. velbusaio/messages/forced_on.py +3 -4
  43. velbusaio/messages/interface_status_request.py +3 -4
  44. velbusaio/messages/ir_receiver_status.py +18 -0
  45. velbusaio/messages/kwh_status.py +3 -19
  46. velbusaio/messages/light_value_request.py +3 -4
  47. velbusaio/messages/memo_text.py +3 -5
  48. velbusaio/messages/memory_data.py +3 -16
  49. velbusaio/messages/memory_data_block.py +3 -4
  50. velbusaio/messages/memory_dump_request.py +3 -4
  51. velbusaio/messages/module_status.py +107 -55
  52. velbusaio/messages/module_status_request.py +7 -6
  53. velbusaio/messages/module_subtype.py +11 -19
  54. velbusaio/messages/module_type.py +132 -21
  55. velbusaio/messages/module_type_request.py +1 -0
  56. velbusaio/messages/psu_load.py +56 -0
  57. velbusaio/messages/psu_values.py +53 -0
  58. velbusaio/messages/push_button_status.py +3 -16
  59. velbusaio/messages/raw.py +74 -0
  60. velbusaio/messages/read_data_block_from_memory.py +3 -4
  61. velbusaio/messages/read_data_from_memory.py +3 -4
  62. velbusaio/messages/realtime_clock_status_request.py +3 -4
  63. velbusaio/messages/receive_buffer_full.py +3 -4
  64. velbusaio/messages/receive_ready.py +3 -4
  65. velbusaio/messages/relay_status.py +13 -42
  66. velbusaio/messages/restore_dimmer.py +33 -24
  67. velbusaio/messages/select_program.py +35 -0
  68. velbusaio/messages/sensor_settings_request.py +3 -4
  69. velbusaio/messages/sensor_temp_request.py +3 -4
  70. velbusaio/messages/sensor_temperature.py +15 -19
  71. velbusaio/messages/set_date.py +10 -30
  72. velbusaio/messages/set_daylight_saving.py +8 -24
  73. velbusaio/messages/set_dimmer.py +43 -41
  74. velbusaio/messages/set_led.py +3 -4
  75. velbusaio/messages/set_realtime_clock.py +10 -30
  76. velbusaio/messages/set_temperature.py +3 -4
  77. velbusaio/messages/slider_status.py +16 -20
  78. velbusaio/messages/slow_blinking_led.py +3 -4
  79. velbusaio/messages/start_relay_blinking_timer.py +3 -4
  80. velbusaio/messages/start_relay_timer.py +3 -4
  81. velbusaio/messages/switch_relay_off.py +3 -16
  82. velbusaio/messages/switch_relay_on.py +3 -16
  83. velbusaio/messages/switch_to_comfort.py +4 -15
  84. velbusaio/messages/switch_to_day.py +4 -15
  85. velbusaio/messages/switch_to_night.py +4 -15
  86. velbusaio/messages/switch_to_safe.py +4 -15
  87. velbusaio/messages/temp_sensor_settings_part1.py +3 -4
  88. velbusaio/messages/temp_sensor_settings_part2.py +27 -0
  89. velbusaio/messages/temp_sensor_settings_part3.py +27 -0
  90. velbusaio/messages/temp_sensor_settings_part4.py +27 -0
  91. velbusaio/messages/temp_sensor_settings_request.py +3 -4
  92. velbusaio/messages/temp_sensor_status.py +34 -35
  93. velbusaio/messages/temp_set_cooling.py +3 -13
  94. velbusaio/messages/temp_set_heating.py +3 -13
  95. velbusaio/messages/update_led_status.py +3 -4
  96. velbusaio/messages/very_fast_blinking_led.py +3 -4
  97. velbusaio/messages/write_data_to_memory.py +3 -4
  98. velbusaio/messages/write_memory_block.py +3 -4
  99. velbusaio/messages/write_module_address_and_serial_number.py +3 -4
  100. velbusaio/module.py +680 -158
  101. velbusaio/module_spec/01.json +62 -0
  102. velbusaio/module_spec/02.json +16 -0
  103. velbusaio/module_spec/03.json +23 -0
  104. velbusaio/module_spec/04.json +283 -0
  105. velbusaio/module_spec/05.json +54 -0
  106. velbusaio/module_spec/06.json +110 -0
  107. velbusaio/module_spec/07.json +16 -0
  108. velbusaio/module_spec/08.json +38 -0
  109. velbusaio/module_spec/09.json +30 -0
  110. velbusaio/module_spec/0A.json +58 -0
  111. velbusaio/module_spec/0B.json +58 -0
  112. velbusaio/module_spec/0C.json +18 -0
  113. velbusaio/module_spec/0E.json +25 -0
  114. velbusaio/module_spec/0F.json +16 -0
  115. velbusaio/module_spec/10.json +111 -0
  116. velbusaio/module_spec/11.json +111 -0
  117. velbusaio/module_spec/12.json +73 -0
  118. velbusaio/module_spec/13.json +4 -0
  119. velbusaio/module_spec/14.json +16 -0
  120. velbusaio/module_spec/15.json +83 -0
  121. velbusaio/module_spec/16.json +129 -0
  122. velbusaio/module_spec/17.json +129 -0
  123. velbusaio/module_spec/18.json +129 -0
  124. velbusaio/module_spec/1A.json +79 -0
  125. velbusaio/module_spec/1B.json +107 -0
  126. velbusaio/module_spec/1D.json +89 -0
  127. velbusaio/module_spec/1E.json +306 -0
  128. velbusaio/module_spec/1F.json +178 -0
  129. velbusaio/module_spec/20.json +178 -0
  130. velbusaio/module_spec/21.json +326 -0
  131. velbusaio/module_spec/22.json +426 -0
  132. velbusaio/module_spec/23.json +129 -0
  133. velbusaio/module_spec/24.json +30 -0
  134. velbusaio/module_spec/25.json +3 -0
  135. velbusaio/module_spec/28.json +454 -0
  136. velbusaio/module_spec/29.json +235 -0
  137. velbusaio/module_spec/2A.json +239 -0
  138. velbusaio/module_spec/2B.json +239 -0
  139. velbusaio/module_spec/2C.json +257 -0
  140. velbusaio/module_spec/2D.json +270 -0
  141. velbusaio/module_spec/2E.json +215 -0
  142. velbusaio/module_spec/2F.json +211 -0
  143. velbusaio/module_spec/30.json +58 -0
  144. velbusaio/module_spec/31.json +465 -0
  145. velbusaio/module_spec/32.json +385 -0
  146. velbusaio/module_spec/33.json +249 -0
  147. velbusaio/module_spec/34.json +313 -0
  148. velbusaio/module_spec/35.json +313 -0
  149. velbusaio/module_spec/36.json +313 -0
  150. velbusaio/module_spec/37.json +333 -0
  151. velbusaio/module_spec/38.json +111 -0
  152. velbusaio/module_spec/39.json +4 -0
  153. velbusaio/module_spec/3A.json +306 -0
  154. velbusaio/module_spec/3B.json +306 -0
  155. velbusaio/module_spec/3C.json +306 -0
  156. velbusaio/module_spec/3D.json +454 -0
  157. velbusaio/module_spec/3E.json +302 -0
  158. velbusaio/module_spec/3F.json +4 -0
  159. velbusaio/module_spec/40.json +4 -0
  160. velbusaio/module_spec/41.json +241 -0
  161. velbusaio/module_spec/42.json +4 -0
  162. velbusaio/module_spec/43.json +23 -0
  163. velbusaio/module_spec/44.json +38 -0
  164. velbusaio/module_spec/45.json +4 -0
  165. velbusaio/module_spec/48.json +111 -0
  166. velbusaio/module_spec/49.json +111 -0
  167. velbusaio/module_spec/4A.json +89 -0
  168. velbusaio/module_spec/4B.json +138 -0
  169. velbusaio/module_spec/4C.json +129 -0
  170. velbusaio/module_spec/4D.json +108 -0
  171. velbusaio/module_spec/4E.json +787 -0
  172. velbusaio/module_spec/4F.json +114 -0
  173. velbusaio/module_spec/50.json +114 -0
  174. velbusaio/module_spec/51.json +114 -0
  175. velbusaio/module_spec/52.json +456 -0
  176. velbusaio/module_spec/54.json +270 -0
  177. velbusaio/module_spec/55.json +270 -0
  178. velbusaio/module_spec/56.json +270 -0
  179. velbusaio/module_spec/57.json +260 -0
  180. velbusaio/module_spec/5A.json +4 -0
  181. velbusaio/module_spec/5B.json +4 -0
  182. velbusaio/module_spec/5C.json +90 -0
  183. velbusaio/module_spec/5F.json +78 -0
  184. velbusaio/module_spec/60.json +4 -0
  185. velbusaio/module_spec/61.json +89 -0
  186. velbusaio/module_spec/broadcast.json +67 -0
  187. velbusaio/module_spec/ignore.json +22 -0
  188. velbusaio/protocol.py +243 -0
  189. velbusaio/py.typed +0 -0
  190. velbusaio/raw_message.py +149 -0
  191. velbusaio/util.py +55 -0
  192. velbusaio/vlp_reader.py +249 -0
  193. velbus_aio-2021.8.7.dist-info/METADATA +0 -66
  194. velbus_aio-2021.8.7.dist-info/RECORD +0 -90
  195. velbus_aio-2021.8.7.dist-info/top_level.txt +0 -1
  196. velbusaio/messages/meteo_raw.py +0 -52
  197. velbusaio/module_registry.py +0 -64
  198. velbusaio/moduleprotocol/protocol.json +0 -25540
  199. velbusaio/parser.py +0 -142
  200. {velbus_aio-2021.8.7.dist-info → velbus_aio-2025.11.0.dist-info/licenses}/LICENSE +0 -0
velbusaio/message.py CHANGED
@@ -1,19 +1,13 @@
1
1
  """
2
2
  The velbus abstract message class
3
3
  """
4
+
4
5
  from __future__ import annotations
5
6
 
7
+ import enum
6
8
  import json
7
9
 
8
- from velbusaio.const import (
9
- ETX,
10
- PRIORITY_FIRMWARE,
11
- PRIORITY_HIGH,
12
- PRIORITY_LOW,
13
- RTR,
14
- STX,
15
- )
16
- from velbusaio.helpers import checksum
10
+ from velbusaio.const import PRIORITY_FIRMWARE, PRIORITY_HIGH, PRIORITY_LOW
17
11
 
18
12
 
19
13
  class ParserError(Exception):
@@ -27,35 +21,27 @@ class Message:
27
21
  Base Velbus message
28
22
  """
29
23
 
30
- def __init__(self, address: int = None) -> None:
24
+ def __init__(self, address: int = 0) -> None:
31
25
  self.priority = PRIORITY_LOW
32
- self.address = None
33
- self.rtr = False
26
+ self.address: int = 0
27
+ self.rtr: bool = False
34
28
  self.data = bytearray()
35
29
  self.set_defaults(address)
36
30
 
37
- def set_attributes(self, priority: int, address: int, rtr: int) -> None:
38
- """
39
- :return: None
40
- """
31
+ def set_attributes(self, priority: int, address: int, rtr: bool) -> None:
41
32
  self.priority = priority
42
33
  self.address = address
43
34
  self.rtr = rtr
44
35
 
45
- def populate(self, priority, address: int, rtr: int, data: int) -> None:
46
- """
47
- :return: None
48
- """
36
+ def populate(self, priority: int, address: int, rtr: bool, data: int) -> None:
49
37
  raise NotImplementedError
50
38
 
51
- def set_defaults(self, address) -> None:
39
+ def set_defaults(self, address: int | None) -> None:
52
40
  """
53
41
  Set defaults
54
42
 
55
43
  If a message has different than low priority or NO_RTR set,
56
44
  then this method needs override in subclass
57
-
58
- :return: None
59
45
  """
60
46
  if address is not None:
61
47
  self.set_address(address)
@@ -63,65 +49,44 @@ class Message:
63
49
  self.set_no_rtr()
64
50
 
65
51
  def set_address(self, address: int) -> None:
66
- """
67
- :return: None
68
- """
69
52
  self.address = address
70
53
 
71
- def to_binary(self):
72
- """
73
- :return: bytes
74
- """
75
- data_bytes = self.data_to_binary()
76
- if self.rtr:
77
- rtr_and_size = RTR | len(data_bytes)
78
- else:
79
- rtr_and_size = len(data_bytes)
80
- header = bytearray([STX, self.priority, self.address, rtr_and_size])
81
- checksum_string = checksum(header + data_bytes)
82
- return (
83
- header
84
- + data_bytes
85
- + bytearray.fromhex(f"{checksum_string:02x}")
86
- + bytearray([ETX])
87
- )
88
-
89
- def data_to_binary(self):
90
- """
91
- :return: bytes
92
- """
93
- raise NotImplementedError
54
+ def data_to_binary(self) -> bytes:
55
+ raise NotImplementedError()
94
56
 
95
- def to_json_basic(self):
57
+ def to_json_basic(self) -> dict:
96
58
  """
97
59
  Create JSON structure with generic attributes
98
-
99
- :return: dict
100
60
  """
101
- return {
102
- "name": self.__class__.__name__,
103
- "priority": self.priority,
104
- "address": self.address,
105
- "rtr": self.rtr,
106
- }
61
+ me = {}
62
+ me["name"] = str(self.__class__.__name__)
63
+ me.update(self.__dict__.copy())
64
+ for key in me.copy():
65
+ if key == "name":
66
+ continue
67
+ if callable(getattr(self, key)) or key.startswith("__"):
68
+ del me[key]
69
+ if isinstance(me[key], (bytes, bytearray, enum.Enum)):
70
+ me[key] = str(me[key])
71
+ else:
72
+ try:
73
+ json.dumps(me[key]) # Test if the value is JSON serializable
74
+ except (TypeError, ValueError):
75
+ me[key] = str(me[key]) # Convert non-serializable objects to string
76
+ return me
107
77
 
108
78
  def to_json(self) -> str:
109
79
  """
110
80
  Dump object structure to JSON
111
81
 
112
82
  This method should be overridden in subclasses to include more than just generic attributes
113
-
114
- :return: str
115
83
  """
116
84
  return json.dumps(self.to_json_basic())
117
85
 
118
86
  def __str__(self) -> str:
119
87
  return self.to_json()
120
88
 
121
- def byte_to_channels(self, byte: int) -> str:
122
- """
123
- :return: list(int)
124
- """
89
+ def byte_to_channels(self, byte: int) -> list[int]:
125
90
  # pylint: disable-msg=R0201
126
91
  result = []
127
92
  for offset in range(0, 8):
@@ -129,10 +94,7 @@ class Message:
129
94
  result.append(offset + 1)
130
95
  return result
131
96
 
132
- def channels_to_byte(self, channels) -> int:
133
- """
134
- :return: int
135
- """
97
+ def channels_to_byte(self, channels: list[int]) -> int:
136
98
  # pylint: disable-msg=R0201
137
99
  result = 0
138
100
  for offset in range(0, 8):
@@ -140,113 +102,65 @@ class Message:
140
102
  result = result + (1 << offset)
141
103
  return result
142
104
 
143
- def byte_to_channel(self, byte):
144
- """
145
- :return: int
146
- """
105
+ def byte_to_channel(self, byte: int) -> int:
147
106
  channels = self.byte_to_channels(byte)
148
107
  self.needs_one_channel(channels)
149
108
  return channels[0]
150
109
 
151
- def parser_error(self, message):
152
- """
153
- :return: None
154
- """
110
+ def parser_error(self, message: str) -> None:
155
111
  raise ParserError(self.__class__.__name__ + " " + message)
156
112
 
157
- def needs_rtr(self, rtr):
158
- """
159
- :return: None
160
- """
113
+ def needs_rtr(self, rtr: bool) -> None:
161
114
  if not rtr:
162
115
  self.parser_error("needs rtr set")
163
116
 
164
- def set_rtr(self):
165
- """
166
- :return: None
167
- """
117
+ def set_rtr(self) -> None:
168
118
  self.rtr = True
169
119
 
170
- def needs_no_rtr(self, rtr):
171
- """
172
- :return: None
173
- """
120
+ def needs_no_rtr(self, rtr: bool) -> None:
174
121
  if rtr:
175
122
  self.parser_error("does not need rtr set")
176
123
 
177
- def set_no_rtr(self):
178
- """
179
- :return: None
180
- """
124
+ def set_no_rtr(self) -> None:
181
125
  self.rtr = False
182
126
 
183
- def needs_low_priority(self, priority):
184
- """
185
- :return: None
186
- """
127
+ def needs_low_priority(self, priority: int) -> None:
187
128
  if priority != PRIORITY_LOW:
188
129
  self.parser_error("needs low priority set")
189
130
 
190
- def set_low_priority(self):
191
- """
192
- :return: None
193
- """
131
+ def set_low_priority(self) -> None:
194
132
  self.priority = PRIORITY_LOW
195
133
 
196
- def needs_high_priority(self, priority):
197
- """
198
- :return: None
199
- """
134
+ def needs_high_priority(self, priority: int) -> None:
200
135
  if priority != PRIORITY_HIGH:
201
136
  self.parser_error("needs high priority set")
202
137
 
203
- def set_high_priority(self):
204
- """
205
- :return: None
206
- """
138
+ def set_high_priority(self) -> None:
207
139
  self.priority = PRIORITY_HIGH
208
140
 
209
- def needs_firmware_priority(self, priority):
210
- """
211
- :return: None
212
- """
141
+ def needs_firmware_priority(self, priority: int) -> None:
213
142
  if priority != PRIORITY_FIRMWARE:
214
143
  self.parser_error("needs firmware priority set")
215
144
 
216
- def set_firmware_priority(self):
217
- """
218
- :return: None
219
- """
145
+ def set_firmware_priority(self) -> None:
220
146
  self.priority = PRIORITY_FIRMWARE
221
147
 
222
- def needs_no_data(self, data):
223
- """
224
- :return: None
225
- """
148
+ def needs_no_data(self, data: bytes) -> None:
226
149
  length = len(data)
227
150
  if length != 0:
228
151
  self.parser_error("has data included")
229
152
 
230
- def needs_data(self, data, length):
231
- """
232
- :return: None
233
- """
153
+ def needs_data(self, data: bytes, length: int) -> None:
234
154
  if len(data) < length:
235
155
  self.parser_error(
236
156
  "needs " + str(length) + " bytes of data have " + str(len(data))
237
157
  )
238
158
 
239
- def needs_fixed_byte(self, byte, value):
240
- """
241
- :return: None
242
- """
159
+ def needs_fixed_byte(self, byte: int, value: int) -> None:
243
160
  if byte != value:
244
161
  self.parser_error("expects " + chr(value) + " in byte " + chr(byte))
245
162
 
246
- def needs_one_channel(self, channels):
247
- """
248
- :return: None
249
- """
163
+ def needs_one_channel(self, channels: list[int]) -> None:
250
164
  if (
251
165
  len(channels) != 1
252
166
  or not isinstance(channels[0], int)
@@ -1,6 +1,7 @@
1
1
  """
2
2
  :author: Thomas Delaet <thomas@delaet.org>
3
3
  """
4
+
4
5
  from __future__ import annotations
5
6
 
6
7
  from velbusaio.messages.blind_status import BlindStatusMessage, BlindStatusNgMessage
@@ -32,29 +33,34 @@ from velbusaio.messages.channel_name_request import (
32
33
  from velbusaio.messages.clear_led import ClearLedMessage
33
34
  from velbusaio.messages.counter_status import CounterStatusMessage
34
35
  from velbusaio.messages.counter_status_request import CounterStatusRequestMessage
36
+ from velbusaio.messages.counter_value import CounterValueMessage
35
37
  from velbusaio.messages.cover_down import CoverDownMessage, CoverDownMessage2
36
38
  from velbusaio.messages.cover_off import CoverOffMessage, CoverOffMessage2
37
39
  from velbusaio.messages.cover_position import CoverPosMessage
38
40
  from velbusaio.messages.cover_up import CoverUpMessage, CoverUpMessage2
41
+ from velbusaio.messages.dali_device_settings import DaliDeviceSettingMsg
39
42
  from velbusaio.messages.dimmer_channel_status import DimmerChannelStatusMessage
40
43
  from velbusaio.messages.dimmer_status import DimmerStatusMessage
41
44
  from velbusaio.messages.fast_blinking_led import FastBlinkingLedMessage
42
45
  from velbusaio.messages.forced_off import ForcedOff
43
46
  from velbusaio.messages.forced_on import ForcedOn
44
47
  from velbusaio.messages.interface_status_request import InterfaceStatusRequestMessage
48
+ from velbusaio.messages.ir_receiver_status import IRReceiverStatusMessage
45
49
  from velbusaio.messages.kwh_status import KwhStatusMessage
46
50
  from velbusaio.messages.light_value_request import LightValueRequest
47
51
  from velbusaio.messages.memo_text import MemoTextMessage
48
52
  from velbusaio.messages.memory_data import MemoryDataMessage
49
53
  from velbusaio.messages.memory_data_block import MemoryDataBlockMessage
50
54
  from velbusaio.messages.memory_dump_request import MemoryDumpRequestMessage
51
- from velbusaio.messages.meteo_raw import MeteoRawMessage
52
55
  from velbusaio.messages.module_status import ModuleStatusMessage, ModuleStatusMessage2
53
56
  from velbusaio.messages.module_status_request import ModuleStatusRequestMessage
54
57
  from velbusaio.messages.module_subtype import ModuleSubTypeMessage
55
- from velbusaio.messages.module_type import ModuleTypeMessage
58
+ from velbusaio.messages.module_type import ModuleType2Message, ModuleTypeMessage
56
59
  from velbusaio.messages.module_type_request import ModuleTypeRequestMessage
60
+ from velbusaio.messages.psu_load import PsuLoadMessage
61
+ from velbusaio.messages.psu_values import PsuValuesMessage
57
62
  from velbusaio.messages.push_button_status import PushButtonStatusMessage
63
+ from velbusaio.messages.raw import MeteoRawMessage, SensorRawMessage
58
64
  from velbusaio.messages.read_data_block_from_memory import (
59
65
  ReadDataBlockFromMemoryMessage,
60
66
  )
@@ -64,6 +70,7 @@ from velbusaio.messages.receive_buffer_full import ReceiveBufferFullMessage
64
70
  from velbusaio.messages.receive_ready import ReceiveReadyMessage
65
71
  from velbusaio.messages.relay_status import RelayStatusMessage
66
72
  from velbusaio.messages.restore_dimmer import RestoreDimmerMessage
73
+ from velbusaio.messages.select_program import SelectProgramMessage
67
74
  from velbusaio.messages.sensor_temp_request import SensorTempRequest
68
75
  from velbusaio.messages.sensor_temperature import SensorTemperatureMessage
69
76
  from velbusaio.messages.set_date import SetDate
@@ -83,6 +90,9 @@ from velbusaio.messages.switch_to_day import SwitchToDayMessage
83
90
  from velbusaio.messages.switch_to_night import SwitchToNightMessage
84
91
  from velbusaio.messages.switch_to_safe import SwitchToSafeMessage
85
92
  from velbusaio.messages.temp_sensor_settings_part1 import TempSensorSettingsPart1
93
+ from velbusaio.messages.temp_sensor_settings_part2 import TempSensorSettingsPart2
94
+ from velbusaio.messages.temp_sensor_settings_part3 import TempSensorSettingsPart3
95
+ from velbusaio.messages.temp_sensor_settings_part4 import TempSensorSettingsPart4
86
96
  from velbusaio.messages.temp_sensor_settings_request import TempSensorSettingsRequest
87
97
  from velbusaio.messages.temp_sensor_status import TempSensorStatusMessage
88
98
  from velbusaio.messages.temp_set_cooling import TempSetCoolingMessage
@@ -1,17 +1,19 @@
1
1
  """
2
2
  :author: Tom Dupré <gitd8400@gmail.com>
3
3
  """
4
+
4
5
  from __future__ import annotations
5
6
 
6
7
  import json
7
8
 
8
- from velbusaio.command_registry import register_command
9
+ from velbusaio.command_registry import register
9
10
  from velbusaio.message import Message
10
11
 
11
12
  COMMAND_CODE = 0xEC
12
13
  DSTATUS = {0: "off", 1: "up", 2: "down"}
13
14
 
14
15
 
16
+ @register(COMMAND_CODE, ["VMB1BLE", "VMB2BLE", "VMB1BLS", "VMB2BLE-10"])
15
17
  class BlindStatusNgMessage(Message):
16
18
  """
17
19
  sent by: VMB2BLE
@@ -37,7 +39,7 @@ class BlindStatusNgMessage(Message):
37
39
  self.channel = self.byte_to_channel(data[0])
38
40
  self.timeout = data[1] # Omzetter seconden ????
39
41
  self.status = data[2]
40
- self.position = data[4]
42
+ self.position = data[4] # 0..255 (0=open, 255=closed)
41
43
 
42
44
  def to_json(self):
43
45
  """
@@ -46,21 +48,19 @@ class BlindStatusNgMessage(Message):
46
48
  json_dict = self.to_json_basic()
47
49
  json_dict["channel"] = self.channel
48
50
  json_dict["timeout"] = self.timeout
51
+ json_dict["position"] = self.position
49
52
  json_dict["status"] = DSTATUS[self.status]
50
53
  return json.dumps(json_dict)
51
54
 
52
- def is_up(self):
53
- """
54
- :return: bool
55
- """
55
+ def is_moving_up(self) -> bool:
56
56
  return self.status == 0x01
57
57
 
58
- def is_down(self):
59
- """
60
- :return: bool
61
- """
58
+ def is_moving_down(self) -> bool:
62
59
  return self.status == 0x02
63
60
 
61
+ def is_stopped(self) -> bool:
62
+ return self.status == 0x00
63
+
64
64
  def data_to_binary(self):
65
65
  """
66
66
  :return: bytes
@@ -79,6 +79,7 @@ class BlindStatusNgMessage(Message):
79
79
  )
80
80
 
81
81
 
82
+ @register(COMMAND_CODE, ["VMB1BL", "VMB2BL"])
82
83
  class BlindStatusMessage(Message):
83
84
  """
84
85
  sent by: VMB2BLE
@@ -107,7 +108,7 @@ class BlindStatusMessage(Message):
107
108
  self.channel = self.byte_to_channel(tmp)
108
109
  self.timeout = data[1] # Omzetter seconden ????
109
110
  # 2 bits per channel used
110
- self.status = data[2] >> ((self.channel - 1) * 2)
111
+ self.status = (data[2] >> ((self.channel - 1) * 2)) & 0x03
111
112
 
112
113
  def to_json(self):
113
114
  """
@@ -119,21 +120,11 @@ class BlindStatusMessage(Message):
119
120
  json_dict["status"] = DSTATUS[self.status]
120
121
  return json.dumps(json_dict)
121
122
 
122
- def is_up(self):
123
- """
124
- :return: bool
125
- """
123
+ def is_moving_up(self) -> bool:
126
124
  return self.status == 0x01
127
125
 
128
- def is_down(self):
129
- """
130
- :return: bool
131
- """
126
+ def is_moving_down(self) -> bool:
132
127
  return self.status == 0x02
133
128
 
134
-
135
- register_command(COMMAND_CODE, BlindStatusNgMessage, "VMB1BLE")
136
- register_command(COMMAND_CODE, BlindStatusNgMessage, "VMB2BLE")
137
- register_command(COMMAND_CODE, BlindStatusNgMessage, "VMB1BLS")
138
- register_command(COMMAND_CODE, BlindStatusMessage, "VMB1BL")
139
- register_command(COMMAND_CODE, BlindStatusMessage, "VMB2BL")
129
+ def is_stopped(self) -> bool:
130
+ return self.status == 0x00
@@ -1,20 +1,17 @@
1
1
  """
2
2
  :author: Thomas Delaet <thomas@delaet.org>
3
3
  """
4
+
4
5
  from __future__ import annotations
5
6
 
6
- from velbusaio.command_registry import register_command
7
+ from velbusaio.command_registry import register
7
8
  from velbusaio.message import Message
8
9
 
9
10
  COMMAND_CODE = 0x0A
10
11
 
11
12
 
13
+ @register(COMMAND_CODE)
12
14
  class BusActiveMessage(Message):
13
- """
14
- send by:
15
- received by: VMB1USB
16
- """
17
-
18
15
  def set_defaults(self, address):
19
16
  if address is not None:
20
17
  self.set_address(address)
@@ -32,6 +29,3 @@ class BusActiveMessage(Message):
32
29
  :return: bytes
33
30
  """
34
31
  return bytes([COMMAND_CODE])
35
-
36
-
37
- register_command(COMMAND_CODE, BusActiveMessage)
@@ -1,14 +1,16 @@
1
1
  """
2
2
  :author: Thomas Delaet <thomas@delaet.org>
3
3
  """
4
+
4
5
  from __future__ import annotations
5
6
 
6
- from velbusaio.command_registry import register_command
7
+ from velbusaio.command_registry import register
7
8
  from velbusaio.message import Message
8
9
 
9
10
  COMMAND_CODE = 0xDA
10
11
 
11
12
 
13
+ @register(COMMAND_CODE)
12
14
  class BusErrorCounterStatusMessage(Message):
13
15
  """
14
16
  send by: VMB6IN, VMB4RYLD
@@ -45,6 +47,3 @@ class BusErrorCounterStatusMessage(Message):
45
47
  self.bus_off_counter,
46
48
  ]
47
49
  )
48
-
49
-
50
- register_command(COMMAND_CODE, BusErrorCounterStatusMessage)
@@ -1,14 +1,16 @@
1
1
  """
2
2
  :author: Thomas Delaet <thomas@delaet.org>
3
3
  """
4
+
4
5
  from __future__ import annotations
5
6
 
6
- from velbusaio.command_registry import register_command
7
+ from velbusaio.command_registry import register
7
8
  from velbusaio.message import Message
8
9
 
9
10
  COMMAND_CODE = 0xD9
10
11
 
11
12
 
13
+ @register(COMMAND_CODE)
12
14
  class BusErrorStatusRequestMessage(Message):
13
15
  """
14
16
  send by:
@@ -29,6 +31,3 @@ class BusErrorStatusRequestMessage(Message):
29
31
  :return: bytes
30
32
  """
31
33
  return bytes([COMMAND_CODE])
32
-
33
-
34
- register_command(COMMAND_CODE, BusErrorStatusRequestMessage)
@@ -1,14 +1,16 @@
1
1
  """
2
2
  :author: Thomas Delaet <thomas@delaet.org>
3
3
  """
4
+
4
5
  from __future__ import annotations
5
6
 
6
- from velbusaio.command_registry import register_command
7
+ from velbusaio.command_registry import register
7
8
  from velbusaio.message import Message
8
9
 
9
10
  COMMAND_CODE = 0x09
10
11
 
11
12
 
13
+ @register(COMMAND_CODE)
12
14
  class BusOffMessage(Message):
13
15
  """
14
16
  send by:
@@ -29,6 +31,3 @@ class BusOffMessage(Message):
29
31
  :return: bytes
30
32
  """
31
33
  return bytes([COMMAND_CODE])
32
-
33
-
34
- register_command(COMMAND_CODE, BusOffMessage)
@@ -1,16 +1,16 @@
1
1
  """
2
2
  :author: Thomas Delaet <thomas@delaet.org>
3
3
  """
4
- from __future__ import annotations
5
4
 
6
- import json
5
+ from __future__ import annotations
7
6
 
8
- from velbusaio.command_registry import register_command
7
+ from velbusaio.command_registry import register
9
8
  from velbusaio.message import Message
10
9
 
11
10
  COMMAND_CODE = 0xF0
12
11
 
13
12
 
13
+ @register(COMMAND_CODE)
14
14
  class ChannelNamePart1Message(Message):
15
15
  """
16
16
  send by: VMB6IN, VMB4RYLD
@@ -44,18 +44,54 @@ class ChannelNamePart1Message(Message):
44
44
  self.name, "ascii", "ignore"
45
45
  )
46
46
 
47
- def to_json(self):
48
- """
49
- :return: str
50
- """
51
- json_dict = self.to_json_basic()
52
- json_dict["channel"] = self.channel
53
- return json.dumps(json_dict)
54
-
55
47
 
48
+ @register(
49
+ COMMAND_CODE,
50
+ [
51
+ "VMBGP1",
52
+ "VMBEL1",
53
+ "VMBGP1-2",
54
+ "VMBGP2",
55
+ "VMBEL2",
56
+ "VMBGP2-2",
57
+ "VMBGP4",
58
+ "VMBEL4",
59
+ "VMBGP4-2",
60
+ "VMBGPO",
61
+ "VMBGPOD",
62
+ "VMBGPOD-2",
63
+ "VMBELO",
64
+ "VMBGP4PIR",
65
+ "VMBGP4PIR-2",
66
+ "VMBDMI",
67
+ "VMBDMI-R",
68
+ "VMBIN",
69
+ "VMBKP",
70
+ "VMBELPIR",
71
+ "VMBDALI",
72
+ "VMB4AN",
73
+ "VMB6PB-20",
74
+ "VMBEL1-20",
75
+ "VMBEL2-20",
76
+ "VMBEL4-20",
77
+ "VMBELO-20",
78
+ "VMBGP1-20",
79
+ "VMBGP2-20",
80
+ "VMBGP4-20",
81
+ "VMBGPO-20",
82
+ "VMBDALI-20",
83
+ "VMBEL4PIR-20",
84
+ "VMBGP4PIR-20",
85
+ "VMB4LEDPWM-20",
86
+ "VMB8DC-20",
87
+ "VMB2DC-20",
88
+ "VMB8IN-20",
89
+ "VMBPSUMNGR-20",
90
+ ],
91
+ )
56
92
  class ChannelNamePart1Message2(ChannelNamePart1Message):
57
93
  """
58
- send by: VMBGP*
94
+ send by: VMBGP*, VMBDALI
59
95
  received by:
60
96
  """
61
97
 
@@ -71,6 +107,7 @@ class ChannelNamePart1Message2(ChannelNamePart1Message):
71
107
  self.name = "".join([chr(x) for x in data[1:]])
72
108
 
73
109
 
110
+ @register(COMMAND_CODE, ["VMB1BL", "VMB2BL"])
74
111
  class ChannelNamePart1Message3(ChannelNamePart1Message):
75
112
  """
76
113
  send by: VMBGP*
@@ -87,24 +124,3 @@ class ChannelNamePart1Message3(ChannelNamePart1Message):
87
124
  self.set_attributes(priority, address, rtr)
88
125
  self.channel = (data[0] >> 1) & 0x03
89
126
  self.name = "".join([chr(x) for x in data[1:]])
90
-
91
-
92
- register_command(COMMAND_CODE, ChannelNamePart1Message)
93
- register_command(COMMAND_CODE, ChannelNamePart1Message2, "VMBGP1")
94
- register_command(COMMAND_CODE, ChannelNamePart1Message2, "VMBEL1")
95
- register_command(COMMAND_CODE, ChannelNamePart1Message2, "VMBGP1-2")
96
- register_command(COMMAND_CODE, ChannelNamePart1Message2, "VMBGP2")
97
- register_command(COMMAND_CODE, ChannelNamePart1Message2, "VMBEL2")
98
- register_command(COMMAND_CODE, ChannelNamePart1Message2, "VMBGP2-2")
99
- register_command(COMMAND_CODE, ChannelNamePart1Message2, "VMBGP4")
100
- register_command(COMMAND_CODE, ChannelNamePart1Message2, "VMBEL4")
101
- register_command(COMMAND_CODE, ChannelNamePart1Message2, "VMBGP4-2")
102
- register_command(COMMAND_CODE, ChannelNamePart1Message2, "VMBGPO")
103
- register_command(COMMAND_CODE, ChannelNamePart1Message2, "VMBGPOD")
104
- register_command(COMMAND_CODE, ChannelNamePart1Message2, "VMBGPOD-2")
105
- register_command(COMMAND_CODE, ChannelNamePart1Message2, "VMBELO")
106
- register_command(COMMAND_CODE, ChannelNamePart1Message2, "VMBGP4PIR")
107
- register_command(COMMAND_CODE, ChannelNamePart1Message2, "VMBDMI")
108
- register_command(COMMAND_CODE, ChannelNamePart1Message2, "VMBDMI-R")
109
- register_command(COMMAND_CODE, ChannelNamePart1Message3, "VMB1BL")
110
- register_command(COMMAND_CODE, ChannelNamePart1Message3, "VMB2BL")