velbus-aio 2023.12.0__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 (192) hide show
  1. scripts/parse_specs.py +156 -0
  2. {velbus_aio-2023.12.0.dist-info → velbus_aio-2025.11.0.dist-info}/METADATA +24 -8
  3. velbus_aio-2025.11.0.dist-info/RECORD +194 -0
  4. {velbus_aio-2023.12.0.dist-info → velbus_aio-2025.11.0.dist-info}/WHEEL +1 -1
  5. {velbus_aio-2023.12.0.dist-info → velbus_aio-2025.11.0.dist-info}/top_level.txt +1 -0
  6. velbusaio/channels.py +35 -14
  7. velbusaio/command_registry.py +32 -5
  8. velbusaio/const.py +10 -2
  9. velbusaio/controller.py +183 -145
  10. velbusaio/handler.py +286 -154
  11. velbusaio/helpers.py +2 -1
  12. velbusaio/message.py +14 -8
  13. velbusaio/messages/__init__.py +6 -2
  14. velbusaio/messages/blind_status.py +4 -2
  15. velbusaio/messages/bus_active.py +1 -0
  16. velbusaio/messages/bus_error_counter_status.py +1 -0
  17. velbusaio/messages/bus_error_counter_status_request.py +1 -0
  18. velbusaio/messages/bus_off.py +1 -0
  19. velbusaio/messages/channel_name_part1.py +18 -0
  20. velbusaio/messages/channel_name_part2.py +18 -0
  21. velbusaio/messages/channel_name_part3.py +18 -0
  22. velbusaio/messages/channel_name_request.py +2 -1
  23. velbusaio/messages/clear_led.py +1 -0
  24. velbusaio/messages/counter_status.py +1 -0
  25. velbusaio/messages/counter_status_request.py +1 -0
  26. velbusaio/messages/counter_value.py +44 -0
  27. velbusaio/messages/cover_down.py +2 -1
  28. velbusaio/messages/cover_off.py +2 -3
  29. velbusaio/messages/cover_position.py +3 -4
  30. velbusaio/messages/cover_up.py +2 -1
  31. velbusaio/messages/dali_device_settings.py +2 -1
  32. velbusaio/messages/dali_device_settings_request.py +2 -1
  33. velbusaio/messages/dali_dim_value_status.py +4 -1
  34. velbusaio/messages/dimmer_channel_status.py +5 -1
  35. velbusaio/messages/dimmer_status.py +13 -1
  36. velbusaio/messages/edge_set_color.py +1 -0
  37. velbusaio/messages/edge_set_custom_color.py +1 -0
  38. velbusaio/messages/fast_blinking_led.py +1 -0
  39. velbusaio/messages/forced_off.py +1 -0
  40. velbusaio/messages/forced_on.py +1 -0
  41. velbusaio/messages/interface_status_request.py +1 -0
  42. velbusaio/messages/ir_receiver_status.py +1 -0
  43. velbusaio/messages/kwh_status.py +1 -0
  44. velbusaio/messages/light_value_request.py +1 -0
  45. velbusaio/messages/memo_text.py +1 -0
  46. velbusaio/messages/memory_data.py +1 -0
  47. velbusaio/messages/memory_data_block.py +1 -0
  48. velbusaio/messages/memory_dump_request.py +1 -0
  49. velbusaio/messages/module_status.py +13 -0
  50. velbusaio/messages/module_status_request.py +5 -2
  51. velbusaio/messages/module_subtype.py +4 -3
  52. velbusaio/messages/module_type.py +17 -7
  53. velbusaio/messages/module_type_request.py +1 -0
  54. velbusaio/messages/psu_load.py +56 -0
  55. velbusaio/messages/psu_values.py +53 -0
  56. velbusaio/messages/push_button_status.py +1 -0
  57. velbusaio/messages/raw.py +1 -0
  58. velbusaio/messages/read_data_block_from_memory.py +1 -0
  59. velbusaio/messages/read_data_from_memory.py +1 -0
  60. velbusaio/messages/realtime_clock_status_request.py +1 -0
  61. velbusaio/messages/receive_buffer_full.py +1 -0
  62. velbusaio/messages/receive_ready.py +1 -0
  63. velbusaio/messages/relay_status.py +1 -0
  64. velbusaio/messages/restore_dimmer.py +16 -2
  65. velbusaio/messages/select_program.py +1 -0
  66. velbusaio/messages/sensor_settings_request.py +1 -0
  67. velbusaio/messages/sensor_temp_request.py +1 -0
  68. velbusaio/messages/sensor_temperature.py +1 -0
  69. velbusaio/messages/set_date.py +5 -10
  70. velbusaio/messages/set_daylight_saving.py +3 -6
  71. velbusaio/messages/set_dimmer.py +22 -13
  72. velbusaio/messages/set_led.py +1 -0
  73. velbusaio/messages/set_realtime_clock.py +5 -10
  74. velbusaio/messages/set_temperature.py +1 -0
  75. velbusaio/messages/slider_status.py +15 -1
  76. velbusaio/messages/slow_blinking_led.py +1 -0
  77. velbusaio/messages/start_relay_blinking_timer.py +1 -0
  78. velbusaio/messages/start_relay_timer.py +1 -0
  79. velbusaio/messages/switch_relay_off.py +1 -0
  80. velbusaio/messages/switch_relay_on.py +1 -0
  81. velbusaio/messages/switch_to_comfort.py +1 -0
  82. velbusaio/messages/switch_to_day.py +1 -0
  83. velbusaio/messages/switch_to_night.py +1 -0
  84. velbusaio/messages/switch_to_safe.py +1 -0
  85. velbusaio/messages/temp_sensor_settings_part1.py +1 -0
  86. velbusaio/messages/temp_sensor_settings_part2.py +1 -0
  87. velbusaio/messages/temp_sensor_settings_part3.py +1 -0
  88. velbusaio/messages/temp_sensor_settings_part4.py +1 -0
  89. velbusaio/messages/temp_sensor_settings_request.py +1 -0
  90. velbusaio/messages/temp_sensor_status.py +1 -0
  91. velbusaio/messages/temp_set_cooling.py +1 -0
  92. velbusaio/messages/temp_set_heating.py +1 -0
  93. velbusaio/messages/update_led_status.py +1 -0
  94. velbusaio/messages/very_fast_blinking_led.py +1 -0
  95. velbusaio/messages/write_data_to_memory.py +1 -0
  96. velbusaio/messages/write_memory_block.py +1 -0
  97. velbusaio/messages/write_module_address_and_serial_number.py +1 -0
  98. velbusaio/module.py +214 -102
  99. velbusaio/module_spec/01.json +62 -0
  100. velbusaio/module_spec/02.json +16 -0
  101. velbusaio/module_spec/03.json +23 -0
  102. velbusaio/module_spec/04.json +283 -0
  103. velbusaio/module_spec/05.json +54 -0
  104. velbusaio/module_spec/06.json +110 -0
  105. velbusaio/module_spec/07.json +16 -0
  106. velbusaio/module_spec/08.json +38 -0
  107. velbusaio/module_spec/09.json +30 -0
  108. velbusaio/module_spec/0A.json +58 -0
  109. velbusaio/module_spec/0B.json +58 -0
  110. velbusaio/module_spec/0C.json +18 -0
  111. velbusaio/module_spec/0E.json +25 -0
  112. velbusaio/module_spec/0F.json +16 -0
  113. velbusaio/module_spec/10.json +111 -0
  114. velbusaio/module_spec/11.json +111 -0
  115. velbusaio/module_spec/12.json +73 -0
  116. velbusaio/module_spec/13.json +4 -0
  117. velbusaio/module_spec/14.json +16 -0
  118. velbusaio/module_spec/15.json +83 -0
  119. velbusaio/module_spec/16.json +129 -0
  120. velbusaio/module_spec/17.json +129 -0
  121. velbusaio/module_spec/18.json +129 -0
  122. velbusaio/module_spec/1A.json +79 -0
  123. velbusaio/module_spec/1B.json +107 -0
  124. velbusaio/module_spec/1D.json +89 -0
  125. velbusaio/module_spec/1E.json +306 -0
  126. velbusaio/module_spec/1F.json +178 -0
  127. velbusaio/module_spec/20.json +178 -0
  128. velbusaio/module_spec/21.json +326 -0
  129. velbusaio/module_spec/22.json +426 -0
  130. velbusaio/module_spec/23.json +129 -0
  131. velbusaio/module_spec/24.json +30 -0
  132. velbusaio/module_spec/25.json +3 -0
  133. velbusaio/module_spec/28.json +454 -0
  134. velbusaio/module_spec/29.json +235 -0
  135. velbusaio/module_spec/2A.json +239 -0
  136. velbusaio/module_spec/2B.json +239 -0
  137. velbusaio/module_spec/2C.json +257 -0
  138. velbusaio/module_spec/2D.json +270 -0
  139. velbusaio/module_spec/2E.json +215 -0
  140. velbusaio/module_spec/2F.json +211 -0
  141. velbusaio/module_spec/30.json +58 -0
  142. velbusaio/module_spec/31.json +465 -0
  143. velbusaio/module_spec/32.json +385 -0
  144. velbusaio/module_spec/33.json +249 -0
  145. velbusaio/module_spec/34.json +313 -0
  146. velbusaio/module_spec/35.json +313 -0
  147. velbusaio/module_spec/36.json +313 -0
  148. velbusaio/module_spec/37.json +333 -0
  149. velbusaio/module_spec/38.json +111 -0
  150. velbusaio/module_spec/39.json +4 -0
  151. velbusaio/module_spec/3A.json +306 -0
  152. velbusaio/module_spec/3B.json +306 -0
  153. velbusaio/module_spec/3C.json +306 -0
  154. velbusaio/module_spec/3D.json +454 -0
  155. velbusaio/module_spec/3E.json +302 -0
  156. velbusaio/module_spec/3F.json +4 -0
  157. velbusaio/module_spec/40.json +4 -0
  158. velbusaio/module_spec/41.json +241 -0
  159. velbusaio/module_spec/42.json +4 -0
  160. velbusaio/module_spec/43.json +23 -0
  161. velbusaio/module_spec/44.json +38 -0
  162. velbusaio/module_spec/45.json +4 -0
  163. velbusaio/module_spec/48.json +111 -0
  164. velbusaio/module_spec/49.json +111 -0
  165. velbusaio/module_spec/4A.json +89 -0
  166. velbusaio/module_spec/4B.json +138 -0
  167. velbusaio/module_spec/4C.json +129 -0
  168. velbusaio/module_spec/4D.json +108 -0
  169. velbusaio/module_spec/4E.json +787 -0
  170. velbusaio/module_spec/4F.json +114 -0
  171. velbusaio/module_spec/50.json +114 -0
  172. velbusaio/module_spec/51.json +114 -0
  173. velbusaio/module_spec/52.json +456 -0
  174. velbusaio/module_spec/54.json +270 -0
  175. velbusaio/module_spec/55.json +270 -0
  176. velbusaio/module_spec/56.json +270 -0
  177. velbusaio/module_spec/57.json +260 -0
  178. velbusaio/module_spec/5A.json +4 -0
  179. velbusaio/module_spec/5B.json +4 -0
  180. velbusaio/module_spec/5C.json +90 -0
  181. velbusaio/module_spec/5F.json +78 -0
  182. velbusaio/module_spec/60.json +4 -0
  183. velbusaio/module_spec/61.json +89 -0
  184. velbusaio/module_spec/broadcast.json +67 -0
  185. velbusaio/module_spec/ignore.json +22 -0
  186. velbusaio/protocol.py +34 -17
  187. velbusaio/raw_message.py +6 -6
  188. velbusaio/util.py +4 -0
  189. velbusaio/vlp_reader.py +249 -0
  190. velbus_aio-2023.12.0.dist-info/RECORD +0 -103
  191. velbusaio/moduleprotocol/protocol.json +0 -26507
  192. {velbus_aio-2023.12.0.dist-info → velbus_aio-2025.11.0.dist-info/licenses}/LICENSE +0 -0
scripts/parse_specs.py ADDED
@@ -0,0 +1,156 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Validate module spec JSON files.
4
+
5
+ This script checks all JSON files under velbusaio/module_spec/*.json and fails
6
+ if any module spec declares a channel with "Editable": "yes" but the module
7
+ spec does not contain the corresponding memory location under
8
+ "Memory" -> "Channels" for that channel.
9
+
10
+ This version fixes an AttributeError caused by MODULE_SPEC_DIR being a string
11
+ instead of a pathlib.Path and makes locating the module_spec directory more
12
+ robust (walks up from the script location to find the repo root).
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import json
18
+ import sys
19
+ from pathlib import Path
20
+ from typing import Any, List, Optional
21
+
22
+ # How many directory levels to walk up from this script to try to find the repo root
23
+ _MAX_UP_LEVELS = 6
24
+
25
+
26
+ def h2(n: int) -> str:
27
+ """Format an integer as the two-digit uppercase hex used in specs (e.g. 1 -> '01')."""
28
+ return f"{int(n):02X}"
29
+
30
+
31
+ def load_json(path: Path) -> Any:
32
+ with path.open("r", encoding="utf-8") as fh:
33
+ return json.load(fh)
34
+
35
+
36
+ def locate_module_spec_dir(start: Path | None = None) -> Path | None:
37
+ """
38
+ Locate velbusaio/module_spec by walking up from start (defaults to this script's dir).
39
+ Returns a pathlib.Path if found, otherwise None.
40
+ """
41
+ if start is None:
42
+ start = Path(__file__).resolve().parent
43
+
44
+ p = start
45
+ for _ in range(_MAX_UP_LEVELS):
46
+ candidate = p / "velbusaio" / "module_spec"
47
+ if candidate.is_dir():
48
+ return candidate
49
+ p = p.parent
50
+ return None
51
+
52
+
53
+ def validate_spec(path: Path) -> list[str]:
54
+ errors: list[str] = []
55
+ warnings: list[str] = []
56
+ try:
57
+ spec = load_json(path)
58
+ except Exception as exc:
59
+ errors.append(f"{path}: failed to load JSON: {exc}")
60
+ return errors
61
+
62
+ channels = spec.get("Channels", {})
63
+ memory = spec.get("Memory")
64
+
65
+ for chan_key, chan_data in channels.items():
66
+ try:
67
+ chan_num = int(chan_key)
68
+ except Exception:
69
+ errors.append(f"{path}: channel key '{chan_key}' is not an integer")
70
+ continue
71
+
72
+ editable = chan_data.get("Editable", "") == "yes"
73
+
74
+ if memory is None:
75
+ errors.append(
76
+ f"{path}: channel {chan_num} (editable) but module spec is missing top-level 'Memory'"
77
+ )
78
+ continue
79
+
80
+ mem_channels = memory.get("Channels")
81
+ if mem_channels is None:
82
+ warnings.append(
83
+ f"{path}: channel {chan_num} (editable) but 'Memory' does not contain 'Channels'"
84
+ )
85
+ continue
86
+
87
+ possible_key = str(chan_num).zfill(2)
88
+
89
+ if possible_key not in mem_channels and editable:
90
+ errors.append(
91
+ f"{path}: channel {chan_num} (editable) but no memory location found in Memory->Channels for key {possible_key}"
92
+ )
93
+
94
+ ctype = chan_data.get("Type", "")
95
+ if ctype in [
96
+ "Blind",
97
+ "Button",
98
+ "ButtonCounter",
99
+ "Dimmer",
100
+ "Temperature",
101
+ "Relay",
102
+ ]:
103
+ if chan_data.get("Editable", "") == "":
104
+ errors.append(
105
+ f"{path}: channel {chan_num} of type {ctype} but editable field is missing"
106
+ )
107
+ if chan_data.get("Editable", "") == "yes":
108
+ if mem_channels is None or possible_key not in mem_channels:
109
+ errors.append(
110
+ f"{path}: channel {chan_num} of type {ctype} is editable but no memory location found in Memory->Channels for key {possible_key}"
111
+ )
112
+
113
+ return errors
114
+
115
+
116
+ def main(argv: list[str] | None = None) -> int:
117
+ argv = argv or sys.argv[1:]
118
+
119
+ # optional first arg: path to repo root (or path that contains velbusaio/module_spec)
120
+ start_path = None
121
+ if len(argv) >= 1 and argv[0].strip():
122
+ start_path = Path(argv[0]).resolve()
123
+
124
+ module_spec_dir = locate_module_spec_dir(start_path)
125
+ if module_spec_dir is None:
126
+ print(
127
+ "Could not find velbusaio/module_spec directory. "
128
+ "Run the script from the repo or provide the repo path as the first argument.",
129
+ file=sys.stderr,
130
+ )
131
+ return 1
132
+
133
+ spec_files = sorted(module_spec_dir.glob("*.json"))
134
+ if not spec_files:
135
+ print(
136
+ f"No module spec JSON files found under {module_spec_dir}", file=sys.stderr
137
+ )
138
+ return 1
139
+
140
+ all_errors: list[str] = []
141
+ for p in spec_files:
142
+ errs = validate_spec(p)
143
+ all_errors.extend(errs)
144
+
145
+ if all_errors:
146
+ print("Module spec validation failed. Problems found:")
147
+ for e in all_errors:
148
+ print(f" - {e}")
149
+ return 1
150
+
151
+ print("Module spec validation passed: all editable channels have memory locations.")
152
+ return 0
153
+
154
+
155
+ if __name__ == "__main__":
156
+ raise SystemExit(main())
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: velbus-aio
3
- Version: 2023.12.0
3
+ Version: 2025.11.0
4
4
  Summary: Open-source home automation platform running on Python 3.
5
5
  Author-email: Maikel Punie <maikel.punie@gmail.com>
6
6
  License: MIT
@@ -13,23 +13,39 @@ Classifier: Intended Audience :: Developers
13
13
  Classifier: License :: OSI Approved :: MIT License
14
14
  Classifier: Natural Language :: English
15
15
  Classifier: Operating System :: OS Independent
16
- Classifier: Programming Language :: Python
17
- Classifier: Programming Language :: Python :: 3.8
18
16
  Classifier: Programming Language :: Python :: 3.9
19
17
  Classifier: Programming Language :: Python :: 3.10
20
18
  Classifier: Programming Language :: Python :: 3.11
21
19
  Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
22
  Classifier: Topic :: Home Automation
23
23
  Classifier: Topic :: Software Development :: Libraries
24
24
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
- Requires-Python: >=3.8.0
25
+ Requires-Python: >=3.9.0
26
26
  Description-Content-Type: text/markdown
27
27
  License-File: LICENSE
28
- Requires-Dist: pyserial >=3.5.0
29
- Requires-Dist: pyserial-asyncio >=0.5
30
- Requires-Dist: backoff >=1.10.0
28
+ Requires-Dist: pyserial>=3.5.0
29
+ Requires-Dist: pyserial-asyncio_fast>=0.11
30
+ Requires-Dist: backoff>=1.10.0
31
+ Requires-Dist: aiofile
32
+ Requires-Dist: beautifulsoup4
33
+ Requires-Dist: lxml
34
+ Dynamic: license-file
31
35
 
32
36
  ![CI](https://github.com/Cereal2nd/velbus-aio/actions/workflows/main.yml/badge.svg)
37
+ [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/Cereal2nd/velbus-aio/master.svg)](https://results.pre-commit.ci/latest/github/Cereal2nd/velbus-aio/master)
38
+ [![PyPI version](https://badge.fury.io/py/velbus-aio.svg)](https://badge.fury.io/py/velbus-aio)
39
+ [![Supported Python versions](https://img.shields.io/pypi/pyversions/velbus-aio.svg)](https://github.com/Cereal2nd/velbus-aio)
40
+ [![License](https://img.shields.io/github/license/Cereal2nd/velbus-aio)](https://github.com/cereal2nd/velbus-aio/blob/master/LICENSE)
41
+ [![Downloads](https://pepy.tech/badge/velbus-aio)](https://pepy.tech/project/velbus-aio)
42
+ [![Downloads](https://pepy.tech/badge/velbus-aio/month)](https://pepy.tech/project/velbus-aio)
43
+ [![Downloads](https://pepy.tech/badge/velbus-aio/week)](https://pepy.tech/project/velbus-aio)
44
+ [![Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
45
+
46
+ > This project requires financial support, but it is free for you to use. You can join those helping to keep the lights on at:
47
+ >
48
+ > [<img src="https://raw.githubusercontent.com/Cereal2nd/hassio-velbusd/refs/heads/main/images/bmc-button.svg" width=150 height=40 style="margin: 5px"/>](https://buymeacoffee.com/cereal2nd) [<img src="https://raw.githubusercontent.com/Cereal2nd/hassio-velbusd/refs/heads/main/images/github-sponsors-button.svg" width=150 height=40 style="margin: 5px"/>](https://github.com/sponsors/Cereal2nd/)
33
49
 
34
50
  # velbus-aio
35
51
 
@@ -0,0 +1,194 @@
1
+ scripts/parse_specs.py,sha256=LAz2yIoL9QqHgz9v_QRce-Mtma8LjzePBnxzkfjyrCY,4884
2
+ velbus_aio-2025.11.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
3
+ velbusaio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ velbusaio/channels.py,sha256=PLGqyVU-KZ8L-qdtiovL9Whj2zDzsAwFz8hRpNJ5s74,23566
5
+ velbusaio/command_registry.py,sha256=dFgkbtN2Kj3AlYENsSIL5afMF_rvhDUoPWKriSHw9L4,5447
6
+ velbusaio/const.py,sha256=aHClMaMS6NINTCrjeRwLbVzdvS91VgFKM8j61ks5tn0,1862
7
+ velbusaio/controller.py,sha256=hlsdD7WWKP4kpaMkuRsW-qIrj9YEFtz-2Yjeoa53w3Q,10570
8
+ velbusaio/discovery.py,sha256=Px6qoZl4QhF17aMz6JxstCORBpLzZGWEK9h4Vyvg57o,1649
9
+ velbusaio/exceptions.py,sha256=FHkXaM3dK5Gkk-QGAf9dLE3FPlCU2FRZWUyY-4KRNnA,515
10
+ velbusaio/handler.py,sha256=6-ZSJH6ts0gpOYy0_h61oSkWqlU8gcJVNs6i5PhXL3s,14042
11
+ velbusaio/helpers.py,sha256=iqpoereRH4JY5WAkozIqWvXWyRmhko-J-UGXDylFyEM,2537
12
+ velbusaio/message.py,sha256=Qzdx6Qrk-DptRnkdfirp5jEKA4hoANtPHfAxvWHzpvU,5305
13
+ velbusaio/module.py,sha256=YDMXhbyrmXSBcI4HEGw54by5DG0DgR10i2sNDiHr738,40082
14
+ velbusaio/protocol.py,sha256=59Qdw2bZ9wL4_XmxvqRD8R1LJoWfrwRRaCOM3KGa0x0,8808
15
+ velbusaio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ velbusaio/raw_message.py,sha256=ODoTPVAvyXXQSMXxtQO1U5OxcoQ4W8JJN5fotEDGSTo,4690
17
+ velbusaio/util.py,sha256=FW6YCiPYWOCgqHDs8-LbzME0h81mqftYVG0qqZ-oo7Y,1568
18
+ velbusaio/vlp_reader.py,sha256=RCSn4Ix_T5c8Z1sBsuTsM7pxCAcCL72FpCpuVZCx5xE,9067
19
+ velbusaio/messages/__init__.py,sha256=2Zgrk4VBoSJXKYhwS18gxuiE96jDvnpBBjeYI1yHjqs,6072
20
+ velbusaio/messages/blind_status.py,sha256=gxgaxbQSjZUgIb4SW-LbvDFOvZp9l-zYfaQwFCyhmPo,3509
21
+ velbusaio/messages/bus_active.py,sha256=AB1mEvbMXRuOaC2CQ7hzKSLmbaJnyFqqXrARi-aSdtg,749
22
+ velbusaio/messages/bus_error_counter_status.py,sha256=x0RIzil6IcXWq6GHEFYDkSAergNF51JQYyetDXjvvzY,1178
23
+ velbusaio/messages/bus_error_counter_status_request.py,sha256=zjX3k8MKgR9FO253a7bIlO-ba6SHmLi2WZT6ayAicrw,703
24
+ velbusaio/messages/bus_off.py,sha256=z0PmNZyTlwee6jXnzgK4zHhFvevAXNboDrEEQvyLLfc,679
25
+ velbusaio/messages/channel_name_part1.py,sha256=iQvv6E9Zfq338CLgYJJ8xBOmbGvehHmhGTa9nXdeh_c,2950
26
+ velbusaio/messages/channel_name_part2.py,sha256=O3VSVgGnnGL273OHJZ9ZwH32kPqr-fp1Fd3DE5Nh1gE,2950
27
+ velbusaio/messages/channel_name_part3.py,sha256=EmIbS-QUc-gJxp1BFgUQLgx6vxZUPY7wiwcB0bBoWuM,2951
28
+ velbusaio/messages/channel_name_request.py,sha256=t8Tpx9l4XLgF6cDwUylXk0r8vmNG2QrXJq9F4TwAaBg,2378
29
+ velbusaio/messages/clear_led.py,sha256=AcGRCD0OdlHcFonvHA075nVwvOtZ6KfyjrXeE6A7DZA,912
30
+ velbusaio/messages/counter_status.py,sha256=UgSRw-pipFb8C2DxauHw8Pjem1qTvzUFpiahui73-Is,1240
31
+ velbusaio/messages/counter_status_request.py,sha256=VLFaI7MFnTCH1s8acfKlcAGscJElwxYRC56eT3bbB7Y,919
32
+ velbusaio/messages/counter_value.py,sha256=rfde3vhMDOZuMwmc32VGn_Dbqj_4gi6QRJyh33e-tIE,1261
33
+ velbusaio/messages/cover_down.py,sha256=0q805ghMmdeFbNLPXZ9TIqsn4QUiwaET4W6j0XEe58E,2566
34
+ velbusaio/messages/cover_off.py,sha256=kzzZKSXiLJJdrXPmIx0dFwR99j6PS6VVpmZp8BbrEY4,2257
35
+ velbusaio/messages/cover_position.py,sha256=ZgUtZtCNSUv_g2BriTveULGWriIvt1CCLC3ItIYQGcc,1282
36
+ velbusaio/messages/cover_up.py,sha256=iFPCWuRhIc54oMQAFz5DZsUW23673_nNHoPFJC_HA_c,2561
37
+ velbusaio/messages/dali_device_settings.py,sha256=KzJ7OFkFRPuCXSOThuplM48J_kH0I3RE82ZRCpmiqYA,4870
38
+ velbusaio/messages/dali_device_settings_request.py,sha256=InTnrwLD7l9gCHXKlJ69FHMXcejtYMUZBtnffx9nDQU,1476
39
+ velbusaio/messages/dali_dim_value_status.py,sha256=Ki-GI_vrmTOOqnOLc04ONRnQ_QFvW6Nzp4jmM-eYgxc,1108
40
+ velbusaio/messages/dimmer_channel_status.py,sha256=5WIrBExtihX8qgZjYOthorfdyMVluNOAChZzglPcxgQ,2525
41
+ velbusaio/messages/dimmer_status.py,sha256=AikJN-jfdFy8rXrGMSMfrhFcYE1yHlorffxk-bcKCXU,3067
42
+ velbusaio/messages/edge_set_color.py,sha256=YhxTv-WtDrZ_O67Ro6V-bcHrxj3tyBI1GuzTI5LkIVw,3306
43
+ velbusaio/messages/edge_set_custom_color.py,sha256=Lz-7prBveqPwuDWv2Mn13X9TAXGBEquw8xz2_y9NtTk,1338
44
+ velbusaio/messages/fast_blinking_led.py,sha256=_AaG6NcjzG_cBNARogzu56l7DNpGU11XGrDHIkMuKss,909
45
+ velbusaio/messages/forced_off.py,sha256=RhYRkd7bbq4Nvg2mOp8Vmg3zvhyGeXYeAYJC8iQ_Bzw,591
46
+ velbusaio/messages/forced_on.py,sha256=38ZDMP70wcZ2I0w0w6HUROakhdl8bhVNELGpMCDqo6E,590
47
+ velbusaio/messages/interface_status_request.py,sha256=V0qfK1FM-uTT3ChXPiUOY0FdHJIB5rp4vLbOFjzgZMQ,695
48
+ velbusaio/messages/ir_receiver_status.py,sha256=EfCSaB0FRy1h1ofjRa-kim-oPnwWeHDmaw8XATRpJFE,375
49
+ velbusaio/messages/kwh_status.py,sha256=qUeHfA_66MCGUw3A-Kz9bMaw-WUZYJvc-vEcru51KiY,1414
50
+ velbusaio/messages/light_value_request.py,sha256=ysejBpgiifSCFHh88sKvou7f1BSqchCmTMAT3kjAGX0,599
51
+ velbusaio/messages/memo_text.py,sha256=RwAjm14oths6rmsjC8WFFS7uOD9UHRue1UxTd4AuQHU,1031
52
+ velbusaio/messages/memory_data.py,sha256=kH_jTCZCyivRnD3DJeiWKDTG01Vk91LbdRXVjj8WHBU,1031
53
+ velbusaio/messages/memory_data_block.py,sha256=3QufrOahEkIhJjivWtOXp62YuVaUwx6trA-OQls6ohQ,1045
54
+ velbusaio/messages/memory_dump_request.py,sha256=xrPsdpygD9DUF3lp-BzJacuq1dNkqz2wtHpqu_F1zVM,699
55
+ velbusaio/messages/module_status.py,sha256=Y2OQUzijtA27snTEVHlyoOrcaLQbSq_3KHKAVDLGR_o,6662
56
+ velbusaio/messages/module_status_request.py,sha256=1gwFXDOooYg7vaVPrPfM_tA1Ph7c_vigPbSyQQDnllw,1082
57
+ velbusaio/messages/module_subtype.py,sha256=KG-OC0eW-ZRnP1P8EWmcay6O-no6Mn2cklEjokaIW9M,1487
58
+ velbusaio/messages/module_type.py,sha256=7sye6R4TI5xMkp9vuelTDyUHobEOCe4DY_mLi9pFoac,4394
59
+ velbusaio/messages/module_type_request.py,sha256=fntMYCF1WVwSseCy3zRoZQH6JeGz8JDfTkwHC3AvcB4,754
60
+ velbusaio/messages/psu_load.py,sha256=001KIz84CbnC54gHxhfAiNbcEMRpVUBzDwQ7T-yxY8s,1232
61
+ velbusaio/messages/psu_values.py,sha256=Yd_ndU8yIei7CoL2NV6FHCefO5h_gzRsPNUYxGUGP0o,1300
62
+ velbusaio/messages/push_button_status.py,sha256=SRFLvNC00FdKDTSb4kNVSHeXI1i5Ey5ENxpsB3B8FuU,1554
63
+ velbusaio/messages/raw.py,sha256=pepZSUVY-ro5jv3ZyO6BI3ap5RZ2g_Bd9dlbaICFldQ,1964
64
+ velbusaio/messages/read_data_block_from_memory.py,sha256=GQwnO71rwPTFgu4YyB4FNQs4_G4dAOGuAsBqwBzmpXs,975
65
+ velbusaio/messages/read_data_from_memory.py,sha256=0Sy9x-7HmkazohpUqFT-647EUmCL8swIgcCpb93a-Fg,978
66
+ velbusaio/messages/realtime_clock_status_request.py,sha256=cDhA8lkCfvHtYwKIQ-bewCfg6xS6Uo4Ruj8KF6aGvDs,608
67
+ velbusaio/messages/receive_buffer_full.py,sha256=Xg4zy6rM-3Zxp3wjRRpVXA3UsFIiUZA0l-vU8c_Y33Q,858
68
+ velbusaio/messages/receive_ready.py,sha256=BjIu-zWlrBGV2BF1BdKF6jUbfzNLAUblq3SRTtF_0rg,687
69
+ velbusaio/messages/relay_status.py,sha256=du16mnJXIzbDSsaIJnoN5KkdqsloOgNkfoFuu3x_F5Y,2837
70
+ velbusaio/messages/restore_dimmer.py,sha256=1ZmGaTRTbqo4kNrXU8Bhla0O2FbHMlQ59AMwUDM1kJM,1931
71
+ velbusaio/messages/select_program.py,sha256=9jLhsCuYGQsw-FMxpmNljPZifGeE_oJ6A5bgCRI2JJ0,835
72
+ velbusaio/messages/sensor_settings_request.py,sha256=Uwywf0JGwBwc_2ZlfxVJicm3oUlWBNEcclcHA2_Mv5I,819
73
+ velbusaio/messages/sensor_temp_request.py,sha256=bTChj9udOjIww9vJ2SWmMtbry_8jLDvbWSAy_ZPmrb4,599
74
+ velbusaio/messages/sensor_temperature.py,sha256=ThA_4FFhQutCSt8147yCy7ocUFfizWaUV2JHoNzesNc,1558
75
+ velbusaio/messages/set_date.py,sha256=jcWb8c5mB71HNBwLCQ9ocEPSHQdZP0yfGJL4_swsRWQ,1359
76
+ velbusaio/messages/set_daylight_saving.py,sha256=CpoKrSt62UzzNxl8SDcpDcb0GKnLcD1f73-ULzqDEzU,1049
77
+ velbusaio/messages/set_dimmer.py,sha256=iYg4OS1xm2w5sHumSY9-42RRD4Z7F7zHjeetKMEL8PI,2153
78
+ velbusaio/messages/set_led.py,sha256=X8tIDzJgtf5EsH92rjoUyrECNFW-ECgAQoQ9TnvJEQk,900
79
+ velbusaio/messages/set_realtime_clock.py,sha256=h34pCvyPm7tSQ5BdB8yC8SRulrtldeX-ZJFv3Wcvdk0,1209
80
+ velbusaio/messages/set_temperature.py,sha256=78LfGOBZo2bw7eF38uyXOjUcJrsSvQPDW2qbXLOYd0o,959
81
+ velbusaio/messages/slider_status.py,sha256=zu_Flw-akKFRefvfojVR4NJPGnWSXYHjYTlyMq_cc7Q,1527
82
+ velbusaio/messages/slow_blinking_led.py,sha256=UktzpRtyM4mR7_KQuNjqenPEeM3P1vgTyMW8dnVwylQ,909
83
+ velbusaio/messages/start_relay_blinking_timer.py,sha256=AUqeXzQlxoW-jxG0YR7Lqt8QfDC1qX3u_MVSMkI783E,1298
84
+ velbusaio/messages/start_relay_timer.py,sha256=FZP4hL3t0rNF_b8GluAM_IymBRkp86epx2rJ29LXpyQ,1290
85
+ velbusaio/messages/switch_relay_off.py,sha256=zmFQP2M0dNKDIljAba0jswKCXsML1psBjfrQtmHuzPM,1099
86
+ velbusaio/messages/switch_relay_on.py,sha256=gMXV8F2rdFQMLKu3Rd1QXHqpb8RWsgcVqwnTt3C28y8,1098
87
+ velbusaio/messages/switch_to_comfort.py,sha256=_avZVz-OkEYe05syirB2N0d8IdgfxElRncNajRWMg_Y,791
88
+ velbusaio/messages/switch_to_day.py,sha256=c9ZQIfE6_tCSUksj1V_M8Pbo48-H7rbPriEtDmX6Shk,787
89
+ velbusaio/messages/switch_to_night.py,sha256=K-_19ZnnlJCOZJkEqWJ3antwHlHEjE7L5BA_H4vd99I,789
90
+ velbusaio/messages/switch_to_safe.py,sha256=5G6ZYdmi_-9W9KB-_SofUfco6ppWb802cChXHq4O6Gg,788
91
+ velbusaio/messages/temp_sensor_settings_part1.py,sha256=QBIzzfj7tB_9LQRlY92ac5IMGnEcgsvQPsyv9CHms9E,605
92
+ velbusaio/messages/temp_sensor_settings_part2.py,sha256=H7JxqsfBmIk05iTtpWfDidvyf-kGMj1YEJ-VouvAHnE,584
93
+ velbusaio/messages/temp_sensor_settings_part3.py,sha256=e9YUkcn11sRwcmvCCOzm87irJ5pdt81S3I1qGZBcTe0,584
94
+ velbusaio/messages/temp_sensor_settings_part4.py,sha256=b9s2-tj-q-ct0--_uvDOJx7JQtZ3hPShRyD5_oFGmGY,584
95
+ velbusaio/messages/temp_sensor_settings_request.py,sha256=kZG3QeHQdA-QEvp3newPGvNW8qhIrJAVcqTY1sZqtvQ,607
96
+ velbusaio/messages/temp_sensor_status.py,sha256=FnY5qFKli2P9xnpVKgysN_nOE_vx86G77Ql93vyTPEY,3828
97
+ velbusaio/messages/temp_set_cooling.py,sha256=_KzrPPdQNYLF6V8-KNehk6D82IQXNCe2obkct_QxX_c,724
98
+ velbusaio/messages/temp_set_heating.py,sha256=Au6b3Y3vpwwdfCJzO5DLOPPVJ98DBrO5_hxMtc165Ho,724
99
+ velbusaio/messages/update_led_status.py,sha256=77wRc3sQl_wXrGvGw9r9-KY17NE5mxTJYgvHWQ5DrRU,1301
100
+ velbusaio/messages/very_fast_blinking_led.py,sha256=vlMEern8PoOvtO5JaAk9erMR4IKJoWUeHJcD69S3B14,913
101
+ velbusaio/messages/write_data_to_memory.py,sha256=gr6bi4SzK8Mw8fnp8yV-STq5jts7NoeV7zZgdptH5Vs,1039
102
+ velbusaio/messages/write_memory_block.py,sha256=zGnNxx_M66HpBQ8S7kagtNw8_qSRHsOLk1MuiS0uygM,1032
103
+ velbusaio/messages/write_module_address_and_serial_number.py,sha256=6y57j-md3btNtQddX5CUREtSs1Dzgkd953sQPZ3Pioo,1597
104
+ velbusaio/module_spec/01.json,sha256=Kcx8uZekXtH31W_2bNRIJluT5-KDMSkR-Z_49sYAIhU,1195
105
+ velbusaio/module_spec/02.json,sha256=AxJRFxljbwckAgLaQPIA-Us2_Fzk9hT27qDYW7i-1jw,225
106
+ velbusaio/module_spec/03.json,sha256=QDW7jXqMPxpQeY5Mm_8QoAnFaFFizxVSj40Fj1IGFnU,322
107
+ velbusaio/module_spec/04.json,sha256=wT0SEO3BNm7xmu9XlSk_BEgc4yE0PfxZlewmBU9G18s,4955
108
+ velbusaio/module_spec/05.json,sha256=aeoJdAwq5iVObsQkz5sCEeqF_zMXdTxofXLGx34XGG0,1065
109
+ velbusaio/module_spec/06.json,sha256=RgZ7VuIxlO_imhyQzu5EEZttzC7Wu9kgmeIV2BHQIks,3312
110
+ velbusaio/module_spec/07.json,sha256=oGvDuMqjBDBodkWuC7WZJU1GvqeqT_bgyymVPZMbDv8,228
111
+ velbusaio/module_spec/08.json,sha256=uRBrnaVxAojLswPCQJYbMD9W2N0lXgL6UjVNvzZlJqo,689
112
+ velbusaio/module_spec/09.json,sha256=uYDIX0Xe3IXI1IqJYznXlHYfSD1jvi76yJ7SVCHtik8,470
113
+ velbusaio/module_spec/0A.json,sha256=pgEYO_3okZafi50r3E4AIz5LXhb1SRqn0aVb1V2bTpE,1122
114
+ velbusaio/module_spec/0B.json,sha256=5BcyqpvWYduDTliR1sGgODGt_XhBVjPk2s4DrBBbCDg,1110
115
+ velbusaio/module_spec/0C.json,sha256=3TfriQu90L4Q3KUfKjQIQfc3sxB8QCFus-EtKy4FMtw,303
116
+ velbusaio/module_spec/0E.json,sha256=GUDHxwyVrD4cz8rqWjj-Ikl42CtnZhjmYq7dgM7t_W4,746
117
+ velbusaio/module_spec/0F.json,sha256=GUDrC6WcA3j5KgrU-VeuxPZE7YbOfxsYelKKosg0B-c,243
118
+ velbusaio/module_spec/10.json,sha256=6i2a83HyC0GMN5tL0I2_qpNdqn6gkqq6lJ11Jhz4ZMA,3369
119
+ velbusaio/module_spec/11.json,sha256=gyeaJ0MrtSzpkSKR06zXQQMVOYeQmhekzSpzQh2K3Hc,3366
120
+ velbusaio/module_spec/12.json,sha256=4MNE5nMZBji6lc4ie5EYq6eQvxEMDdKjH1C4PEhc_ng,1991
121
+ velbusaio/module_spec/13.json,sha256=reXGXbaTfVVmLekrXHlfzjsV424bb0ozG7q-PxDv27U,68
122
+ velbusaio/module_spec/14.json,sha256=vvje3EB01f8xy7KzwhyR_TyHCTdaHQGNm6w8uFPK3Qc,228
123
+ velbusaio/module_spec/15.json,sha256=_9HOT4C81QzcO4I-YXtmgNLf7bLtkMX8XkSB2cN9Res,2747
124
+ velbusaio/module_spec/16.json,sha256=SZ_UfFldhp3YKtrOVOz9YqQQTB-Nc24zlIin5dbB2Vw,3683
125
+ velbusaio/module_spec/17.json,sha256=bLZ7JDt58vZUxPT6JY1xYeWWb1-jHkOhpBRUghjkQSA,3714
126
+ velbusaio/module_spec/18.json,sha256=zaB0mppCAlG3bjgADdSpWkZyhoavaFWRzwj4Qzukazg,3708
127
+ velbusaio/module_spec/1A.json,sha256=6pXfr-NosBYZM_7oJP6GbR9bN4s02P_hYfzSxF61WVY,2705
128
+ velbusaio/module_spec/1B.json,sha256=u4cSacyCZjL0_GKjh_tEqkWjUNyhk1vyEQ4Q-uVLnLc,3308
129
+ velbusaio/module_spec/1D.json,sha256=LVpquowsxETbGB-h5ynF-kYkgbNZJjRPUGnEj2Xfk50,2841
130
+ velbusaio/module_spec/1E.json,sha256=aAaSAPvneeXn-27l22Gy0Dy1xEy5dsi62-lTf7ePpYo,5547
131
+ velbusaio/module_spec/1F.json,sha256=rZoqlrdXkmkx1k8Xznu0RXu3tyAszonVcxjFlbtgLRo,4635
132
+ velbusaio/module_spec/20.json,sha256=vb8jfFM0RFlT3s3GmshQ-xU4t9VHvOKlGO1tgHvFPkQ,4642
133
+ velbusaio/module_spec/21.json,sha256=ZzdbEGcW0P_kZRbUPA-zsAA9dZ9N_0ydvI3MyBCKXx0,7664
134
+ velbusaio/module_spec/22.json,sha256=uQ4Jkj5480Hw_57jhvGD125kDhPJti12NkakVGfgN8A,8680
135
+ velbusaio/module_spec/23.json,sha256=3jCtHfqaqHNVZ6QyG499ZKaIQyTqmTxqqLujmgTW4RY,3593
136
+ velbusaio/module_spec/24.json,sha256=BqE211q_8k1xN7LdV5UjZ332HopvIEfUVAecN6YbEWM,568
137
+ velbusaio/module_spec/25.json,sha256=H87YnDGlgnEJzokWZkrfDtGGE-3JRJEYDRnKTlL69eE,24
138
+ velbusaio/module_spec/28.json,sha256=gED0Nk9TzzmoxzUGp_f30s0YJoUS7waywlOCdPl6dg8,8561
139
+ velbusaio/module_spec/29.json,sha256=q-X-O4POUbPWw6GZcrUxYfM4nT2Xqc0UeUOg05Lvks0,4157
140
+ velbusaio/module_spec/2A.json,sha256=RJIqQh-aqvtB4DifBe8oiaaC47tf_r8mAMX1iJ_O3yc,4170
141
+ velbusaio/module_spec/2B.json,sha256=lxzrmcWLz9KHMLVbiMSfzqH7rS8Ww3De11k5pJErUlo,4173
142
+ velbusaio/module_spec/2C.json,sha256=84VjlZ9j5DREO72wAhdDAF9hXRBvntGCZWbwXxVWkQk,4486
143
+ velbusaio/module_spec/2D.json,sha256=oQCZdL84pkv8b73tZC9sO6RPD7ZuZdIRQlfnhVQmu3c,4808
144
+ velbusaio/module_spec/2E.json,sha256=vTFTEsUJxggTVXyd5FGb-gUlXJogf4BjHj2490aoVFs,3703
145
+ velbusaio/module_spec/2F.json,sha256=xCCh56q9ngY8XFsm344fJKgl36xC9C23YTyRpwwDH34,3644
146
+ velbusaio/module_spec/30.json,sha256=ge9H8PZWEyJCR3Ceb_O3xTY2PCjDnBO4tq8Mq437x58,1113
147
+ velbusaio/module_spec/31.json,sha256=o9AqfLTdjQkSd77t97A-ttQxWLEJVyKG22Ie50vsRIY,8291
148
+ velbusaio/module_spec/32.json,sha256=bBf98T3Fk_S8gCAn2R3DeWkHDDAQGM_sNjS4HJVGh4M,6814
149
+ velbusaio/module_spec/33.json,sha256=_ZFyGZRpF6WvGmuMOgWgEXuSFEt81pH_LbB8B717drQ,4341
150
+ velbusaio/module_spec/34.json,sha256=rbMU3hKkNHsY5lTttP_2-7CC7dhUmG8XnbJ79lZidj8,5667
151
+ velbusaio/module_spec/35.json,sha256=5VlXV490o4RLn3fdkE7zF_tp2R3zuPxced8DBevdw1I,5664
152
+ velbusaio/module_spec/36.json,sha256=xA6KPxZBQEGpIK2rF17ajv81mgP-uP47capk0ALdwdk,5658
153
+ velbusaio/module_spec/37.json,sha256=D9VOFdjRvfS7gCVERdk_Oq6YEkr3KCSSM7hBySmveUc,7813
154
+ velbusaio/module_spec/38.json,sha256=yphbnujqz83_YR6Fwioaqw8ubHCdeF2qbwM5fhXUfYM,2120
155
+ velbusaio/module_spec/39.json,sha256=JkSmbb9uQ43VB0Aacif-lnHYj9-P-oFsOeGblu3sHRQ,71
156
+ velbusaio/module_spec/3A.json,sha256=ZaE5mn1e0_5Zag7ejSlQBn-501tUnxSs7oleGWTyf-w,5556
157
+ velbusaio/module_spec/3B.json,sha256=B__bRk1Pdw1rw79F2gkWRiujBGRJs_miV-p6b6MkchE,5553
158
+ velbusaio/module_spec/3C.json,sha256=hHG0JDSs5e5X4H4oNGGg1qRGuInBupCl-JT31PoY7JI,5547
159
+ velbusaio/module_spec/3D.json,sha256=LNCmtB5HewEJ2mSiMagk_g0zVS-uGqkWcZAzADrZmZE,8570
160
+ velbusaio/module_spec/3E.json,sha256=2IcYtfiNXATaRMtFMBoMAhUA5ihEMfdISSpypWLdI2U,5434
161
+ velbusaio/module_spec/3F.json,sha256=o9p-zOhyyAgOrZT8JYok4qKsIDmYQS62v1HsqI_-SMU,70
162
+ velbusaio/module_spec/40.json,sha256=JkSmbb9uQ43VB0Aacif-lnHYj9-P-oFsOeGblu3sHRQ,71
163
+ velbusaio/module_spec/41.json,sha256=gdcY5w7vWoBZoOoy2iR266OaPac0KesSIdIex2TYe4k,4297
164
+ velbusaio/module_spec/42.json,sha256=0zSbvyG6I2O3XAhv28R_v0IQvd_h4xLQIJDXVInYR6g,59
165
+ velbusaio/module_spec/43.json,sha256=PGkifNobL0j436ogxY7UGwEh0k-F6HTtA1Rg-GgdofA,420
166
+ velbusaio/module_spec/44.json,sha256=W5jbuMT-_knS54HEvCr7clGxsT1jBz0o-VLGc9CHM60,716
167
+ velbusaio/module_spec/45.json,sha256=aAlc4ANbdDXJs7YhXm06te-gN43uaL80DS9qoinS2cQ,71
168
+ velbusaio/module_spec/48.json,sha256=An7Ovt7ZUieQjCIYEHw5RaXsIYLzIOh2KPTVWJQ72js,3372
169
+ velbusaio/module_spec/49.json,sha256=5lgo_9xNgtpniWsdbdmRHZTk7tpnSsvOuWa9jU3zRxU,3369
170
+ velbusaio/module_spec/4A.json,sha256=Qh3BUib_QAvg-BtjTdpvvEWVyDj1gRHZQo2-h19JG5s,2845
171
+ velbusaio/module_spec/4B.json,sha256=8Q0PFVXED1QBIQGSqaP0Gi2WU3Uh_3HyC05jpWrmuZw,3888
172
+ velbusaio/module_spec/4C.json,sha256=fOlTPNsxgt50cgo-dCwvbZheJJqkwvgcxqTi-sMLFEU,3688
173
+ velbusaio/module_spec/4D.json,sha256=9Lho_3m4H5SBhx363zCDN3HnA8zLlygIi0EgXyOolF8,3213
174
+ velbusaio/module_spec/4E.json,sha256=uRK3hhH8Tp115f_7TxMZQGmCLq3qJv8i6qK070TGV4w,16411
175
+ velbusaio/module_spec/4F.json,sha256=gfXGXEeAZ6OCjrlogMiwXPU0rdrygFQFe8QiA42ulm0,2204
176
+ velbusaio/module_spec/50.json,sha256=SAAFJi3aV7S1HCkn4Td4GEXgQd5tqKpTjGGrc79o2Ws,2201
177
+ velbusaio/module_spec/51.json,sha256=nUOsEf-nlpqaECAQ-pMgFXTVH94Gv4QAVFRNPlTnzi8,2195
178
+ velbusaio/module_spec/52.json,sha256=vrMkTkZ5A0z_Of2XQIhg2tgudcD3hEPEqWuO-Hva7gA,8577
179
+ velbusaio/module_spec/54.json,sha256=js3tuBJdsMUyOlyKgg2BRZ5jiO5T4CPvXx0kM6W71to,4865
180
+ velbusaio/module_spec/55.json,sha256=75vupZ7uS6pVfaef3-p0UtF3voNmnC94VboXsJlQs1E,4862
181
+ velbusaio/module_spec/56.json,sha256=38MpugJqU7Stxmbi2ZvasIfPcsLs9dRhO2SdaW2uDJo,4856
182
+ velbusaio/module_spec/57.json,sha256=nZoBuIKeO5WO7OTduFTDTwVhrQHZBuqEx4rYELR3eL8,5211
183
+ velbusaio/module_spec/5A.json,sha256=V_yhMdGrNxFE7J_CXJmngN-yYBz2V_tqXkKCCwI7HCE,52
184
+ velbusaio/module_spec/5B.json,sha256=Z-zYxcnSbPPHEyvh4P_V7USq_Zbrcj9AasB-g7KqWAs,74
185
+ velbusaio/module_spec/5C.json,sha256=oB5EdUHrYZwR6FV0qO2Ux15ta366GtycGSEpChPvDgY,1635
186
+ velbusaio/module_spec/5F.json,sha256=l0IxHeaM9ip9P23_VJ2GjUYsg21uSYfEGhN0ROizcK0,1507
187
+ velbusaio/module_spec/60.json,sha256=Teih3jAybl5AELjY3gFbZrFN0RIMSU1yuvdsYZlMvTo,74
188
+ velbusaio/module_spec/61.json,sha256=RUMK2ji4J35-tJMVCMsEW4crK1gH9BaXTXkSpfmFVig,2844
189
+ velbusaio/module_spec/broadcast.json,sha256=L2Sc9FhZ7NOuu7K5g5jAhvUQGDP6a2CKrg-uWh_v-sA,2250
190
+ velbusaio/module_spec/ignore.json,sha256=WenWeTXN4gHppgf4CzSa_mmnzBi_-f2IM2yeFIdB2cc,384
191
+ velbus_aio-2025.11.0.dist-info/METADATA,sha256=iMq_6ZZTbZPuABzkvVWsQKP29tmd_Oi8vvm1cq410QU,4621
192
+ velbus_aio-2025.11.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
193
+ velbus_aio-2025.11.0.dist-info/top_level.txt,sha256=cCUKBEDoGI2tmgcbkWr2XHrykO7DfyGA_75RUegyQQk,23
194
+ velbus_aio-2025.11.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
velbusaio/channels.py CHANGED
@@ -1,6 +1,7 @@
1
1
  """
2
2
  author: Maikel Punie <maikel.punie@gmail.com>
3
3
  """
4
+
4
5
  from __future__ import annotations
5
6
 
6
7
  import asyncio
@@ -18,7 +19,7 @@ from velbusaio.const import (
18
19
  VOLUME_LITERS_HOUR,
19
20
  )
20
21
  from velbusaio.message import Message
21
- from velbusaio.messages.edge_set_color import SetEdgeColorMessage, CustomColorPriority
22
+ from velbusaio.messages.edge_set_color import CustomColorPriority, SetEdgeColorMessage
22
23
  from velbusaio.messages.module_status import PROGRAM_SELECTION
23
24
 
24
25
  if TYPE_CHECKING:
@@ -37,12 +38,14 @@ class Channel:
37
38
  num: int,
38
39
  name: str,
39
40
  nameEditable: bool,
41
+ subDevice: bool,
40
42
  writer: Callable[[Message], Awaitable[None]],
41
43
  address: int,
42
44
  ):
43
45
  self._num = num
44
46
  self._module = module
45
47
  self._name = name
48
+ self._subDevice = subDevice
46
49
  if not nameEditable:
47
50
  self._is_loaded = True
48
51
  else:
@@ -79,6 +82,8 @@ class Channel:
79
82
  return self._num
80
83
 
81
84
  def get_full_name(self) -> str:
85
+ if self._subDevice:
86
+ return f"{self._module.get_name()} ({self._module.get_type_name()}) - {self._name}"
82
87
  return f"{self._module.get_name()} ({self._module.get_type_name()})"
83
88
 
84
89
  def is_loaded(self) -> bool:
@@ -93,6 +98,9 @@ class Channel:
93
98
  def is_temperature(self) -> bool:
94
99
  return False
95
100
 
101
+ def is_sub_device(self) -> bool:
102
+ return self._subDevice
103
+
96
104
  def get_name(self) -> str:
97
105
  """
98
106
  :return: the channel name
@@ -135,17 +143,15 @@ class Channel:
135
143
  if k != "_writer" and k != "_on_status_update" and k != "_name_parts"
136
144
  }
137
145
 
138
- def to_json(self) -> dict:
139
- d = self.__dict__
140
- return {
141
- k: d[k]
142
- for k in d
143
- if k != "_writer"
144
- and k != "_on_status_update"
145
- and k != "_name_parts"
146
- and k != "_module"
147
- and k != "__name__"
146
+ def to_cache(self) -> dict:
147
+ dst = {
148
+ "name": self._name,
149
+ "type": type(self).__name__,
150
+ "subdevice": self._subDevice,
148
151
  }
152
+ if hasattr(self, "_Unit"):
153
+ dst["Unit"] = self._Unit
154
+ return dst
149
155
 
150
156
  def __setstate__(self, state):
151
157
  self.__dict__.update(state)
@@ -155,7 +161,7 @@ class Channel:
155
161
  def __repr__(self) -> str:
156
162
  items = []
157
163
  for k, v in self.__dict__.items():
158
- if k not in ["_module", "_writer", "_name_parts"]:
164
+ if k not in ["_module", "_writer", "_name_parts", "_class"]:
159
165
  items.append(f"{k} = {v!r}")
160
166
  return "{}[{}]".format(type(self), ", ".join(items))
161
167
 
@@ -191,6 +197,9 @@ class Channel:
191
197
  def on_status_update(self, meth: Callable[[], Awaitable[None]]) -> None:
192
198
  self._on_status_update.append(meth)
193
199
 
200
+ def remove_on_status_update(self, meth: Callable[[], Awaitable[None]]) -> None:
201
+ self._on_status_update.remove(meth)
202
+
194
203
  def get_counter_state(self) -> int:
195
204
  raise NotImplementedError()
196
205
 
@@ -276,6 +285,10 @@ class Blind(Channel):
276
285
 
277
286
  async def set_position(self, position: int) -> None:
278
287
  # may not be supported by the module
288
+ if position == 100:
289
+ # at least VMB1BLS ignores command 0x1C with position 0x64
290
+ await self.close()
291
+ return
279
292
  cls = commandRegistry.get_command(0x1C, self._module.get_type())
280
293
  msg = cls(self._address)
281
294
  msg.channel = self._num
@@ -366,6 +379,8 @@ class ButtonCounter(Button):
366
379
  _pulses = None
367
380
  _counter = None
368
381
  _delay = None
382
+ _power = None
383
+ _energy = None
369
384
 
370
385
  def get_categories(self) -> list[str]:
371
386
  if self._counter:
@@ -378,11 +393,13 @@ class ButtonCounter(Button):
378
393
  return False
379
394
 
380
395
  def get_state(self) -> int:
381
- val = 0
396
+ if self._energy:
397
+ return self._energy
382
398
  # if we don't know the delay
383
399
  # or we don't know the unit
384
400
  # or the delay is the max value
385
401
  # we always return 0
402
+ val = 0
386
403
  if not self._delay or not self._Unit or self._delay == 0xFFFF:
387
404
  return round(0, 2)
388
405
  if self._Unit == VOLUME_LITERS_HOUR:
@@ -405,6 +422,8 @@ class ButtonCounter(Button):
405
422
  return None
406
423
 
407
424
  def get_counter_state(self) -> int:
425
+ if self._power:
426
+ return self._power
408
427
  return round((self._counter / self._pulses), 2)
409
428
 
410
429
  def get_counter_unit(self) -> str:
@@ -449,11 +468,12 @@ class Dimmer(Channel):
449
468
  num: int,
450
469
  name: str,
451
470
  nameEditable: bool,
471
+ subDevice: bool,
452
472
  writer: Callable[[Message], Awaitable[None]],
453
473
  address: int,
454
474
  slider_scale: int = 100,
455
475
  ):
456
- super().__init__(module, num, name, nameEditable, writer, address)
476
+ super().__init__(module, num, name, nameEditable, subDevice, writer, address)
457
477
 
458
478
  self.slider_scale = slider_scale
459
479
  # VMB4DC has dim values 0(off), 1-99(dimmed), 100(full on)
@@ -509,6 +529,7 @@ class Temperature(Channel):
509
529
  _min = None
510
530
  _target = 0
511
531
  _cmode = None
532
+ _cool_mode = None
512
533
  _cstatus = None
513
534
  _thermostat = False
514
535
  _sleep_timer = 0