velbus-aio 2024.4.0__py3-none-any.whl → 2024.4.1__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.
Potentially problematic release.
This version of velbus-aio might be problematic. Click here for more details.
- {velbus_aio-2024.4.0.dist-info → velbus_aio-2024.4.1.dist-info}/METADATA +1 -1
- {velbus_aio-2024.4.0.dist-info → velbus_aio-2024.4.1.dist-info}/RECORD +20 -20
- velbusaio/channels.py +2 -11
- velbusaio/command_registry.py +12 -1
- velbusaio/const.py +2 -1
- velbusaio/controller.py +38 -68
- velbusaio/handler.py +3 -2
- velbusaio/helpers.py +1 -1
- velbusaio/message.py +0 -1
- velbusaio/messages/cover_off.py +0 -2
- velbusaio/messages/cover_position.py +0 -2
- velbusaio/messages/set_date.py +4 -10
- velbusaio/messages/set_daylight_saving.py +2 -6
- velbusaio/messages/set_realtime_clock.py +4 -10
- velbusaio/module.py +33 -27
- velbusaio/protocol.json +9 -5
- velbusaio/util.py +4 -0
- {velbus_aio-2024.4.0.dist-info → velbus_aio-2024.4.1.dist-info}/LICENSE +0 -0
- {velbus_aio-2024.4.0.dist-info → velbus_aio-2024.4.1.dist-info}/WHEEL +0 -0
- {velbus_aio-2024.4.0.dist-info → velbus_aio-2024.4.1.dist-info}/top_level.txt +0 -0
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
velbusaio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
velbusaio/channels.py,sha256=
|
|
3
|
-
velbusaio/command_registry.py,sha256=
|
|
4
|
-
velbusaio/const.py,sha256=
|
|
5
|
-
velbusaio/controller.py,sha256=
|
|
2
|
+
velbusaio/channels.py,sha256=v7hZoT7X3-fNBAvTKgVpxCY33HhUC9Ga4XTCMqJ3dTA,22799
|
|
3
|
+
velbusaio/command_registry.py,sha256=j9KuLmada41PMEdtfPvLmXVOAZOkBM9zi-3kluwYffk,5140
|
|
4
|
+
velbusaio/const.py,sha256=aysTlQcpACZaDVqoXAjWmaEDGlCB7KT04Rv-SAusPFc,1575
|
|
5
|
+
velbusaio/controller.py,sha256=O9BAOFTb3GjTRX8EOrkIifqWN9GIp9Pm4x6__m5wa7A,8756
|
|
6
6
|
velbusaio/discovery.py,sha256=Px6qoZl4QhF17aMz6JxstCORBpLzZGWEK9h4Vyvg57o,1649
|
|
7
7
|
velbusaio/exceptions.py,sha256=FHkXaM3dK5Gkk-QGAf9dLE3FPlCU2FRZWUyY-4KRNnA,515
|
|
8
|
-
velbusaio/handler.py,sha256=
|
|
9
|
-
velbusaio/helpers.py,sha256=
|
|
10
|
-
velbusaio/message.py,sha256=
|
|
11
|
-
velbusaio/module.py,sha256=
|
|
12
|
-
velbusaio/protocol.json,sha256=
|
|
8
|
+
velbusaio/handler.py,sha256=jTWIV26ibAqs3rcTku81NIHlPUeyWjStSih1Nfx-an0,5946
|
|
9
|
+
velbusaio/helpers.py,sha256=iqpoereRH4JY5WAkozIqWvXWyRmhko-J-UGXDylFyEM,2537
|
|
10
|
+
velbusaio/message.py,sha256=gnhXpA5NAG4qnI9vlxwlWQKETWneDb1lp0P9w_-nxhQ,5020
|
|
11
|
+
velbusaio/module.py,sha256=sHOnGjuV--_aw83yh_Gx5CiRPDOBRr1PemVg5z5YYoQ,35467
|
|
12
|
+
velbusaio/protocol.json,sha256=7PifRZXctU5zSsodDGsUAhnnSsGNlcGcim1gr2su720,250396
|
|
13
13
|
velbusaio/protocol.py,sha256=ofDwJfwyrVQDQ40WX2QdH1nTK-y2HibQPTo5dFY7SkQ,8224
|
|
14
14
|
velbusaio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
velbusaio/raw_message.py,sha256=ODoTPVAvyXXQSMXxtQO1U5OxcoQ4W8JJN5fotEDGSTo,4690
|
|
16
|
-
velbusaio/util.py,sha256=
|
|
16
|
+
velbusaio/util.py,sha256=FW6YCiPYWOCgqHDs8-LbzME0h81mqftYVG0qqZ-oo7Y,1568
|
|
17
17
|
velbusaio/messages/__init__.py,sha256=hLkLhsJ5hcgRnhaoyFWz1g2vphdnjrXURxgwezkDBwU,5893
|
|
18
18
|
velbusaio/messages/blind_status.py,sha256=yzjoYLBxH85tBjihiGzLqebRg1urz0obBA-3q1pqSCE,3418
|
|
19
19
|
velbusaio/messages/bus_active.py,sha256=AB1mEvbMXRuOaC2CQ7hzKSLmbaJnyFqqXrARi-aSdtg,749
|
|
@@ -28,8 +28,8 @@ velbusaio/messages/clear_led.py,sha256=AcGRCD0OdlHcFonvHA075nVwvOtZ6KfyjrXeE6A7D
|
|
|
28
28
|
velbusaio/messages/counter_status.py,sha256=UgSRw-pipFb8C2DxauHw8Pjem1qTvzUFpiahui73-Is,1240
|
|
29
29
|
velbusaio/messages/counter_status_request.py,sha256=VLFaI7MFnTCH1s8acfKlcAGscJElwxYRC56eT3bbB7Y,919
|
|
30
30
|
velbusaio/messages/cover_down.py,sha256=tdjsRijrEa5oNBZk6uKWUK39k5gIjcWq0kgfOf4f1lQ,2552
|
|
31
|
-
velbusaio/messages/cover_off.py,sha256=
|
|
32
|
-
velbusaio/messages/cover_position.py,sha256=
|
|
31
|
+
velbusaio/messages/cover_off.py,sha256=0RHAJb4et99yAoo8LD85Rzlnhrqr40Wjba-BhzHSr4o,2243
|
|
32
|
+
velbusaio/messages/cover_position.py,sha256=PhRocdkbwf8CUfdL8-rZHEDFD2Z9u7DLZOpH3h6gAtg,1268
|
|
33
33
|
velbusaio/messages/cover_up.py,sha256=P20AZx8qQScbyV0sxtZOlO03Q8pFO8NunpqIr4mZ6Lw,2547
|
|
34
34
|
velbusaio/messages/dali_device_settings.py,sha256=KzJ7OFkFRPuCXSOThuplM48J_kH0I3RE82ZRCpmiqYA,4870
|
|
35
35
|
velbusaio/messages/dali_device_settings_request.py,sha256=InTnrwLD7l9gCHXKlJ69FHMXcejtYMUZBtnffx9nDQU,1476
|
|
@@ -67,11 +67,11 @@ velbusaio/messages/select_program.py,sha256=9jLhsCuYGQsw-FMxpmNljPZifGeE_oJ6A5bg
|
|
|
67
67
|
velbusaio/messages/sensor_settings_request.py,sha256=Uwywf0JGwBwc_2ZlfxVJicm3oUlWBNEcclcHA2_Mv5I,819
|
|
68
68
|
velbusaio/messages/sensor_temp_request.py,sha256=bTChj9udOjIww9vJ2SWmMtbry_8jLDvbWSAy_ZPmrb4,599
|
|
69
69
|
velbusaio/messages/sensor_temperature.py,sha256=ThA_4FFhQutCSt8147yCy7ocUFfizWaUV2JHoNzesNc,1558
|
|
70
|
-
velbusaio/messages/set_date.py,sha256=
|
|
71
|
-
velbusaio/messages/set_daylight_saving.py,sha256=
|
|
70
|
+
velbusaio/messages/set_date.py,sha256=jcWb8c5mB71HNBwLCQ9ocEPSHQdZP0yfGJL4_swsRWQ,1359
|
|
71
|
+
velbusaio/messages/set_daylight_saving.py,sha256=CpoKrSt62UzzNxl8SDcpDcb0GKnLcD1f73-ULzqDEzU,1049
|
|
72
72
|
velbusaio/messages/set_dimmer.py,sha256=f2XWLbxoo0Tbj8_DUu28XSiib32VLUDtw8QRzRZBDdA,1975
|
|
73
73
|
velbusaio/messages/set_led.py,sha256=X8tIDzJgtf5EsH92rjoUyrECNFW-ECgAQoQ9TnvJEQk,900
|
|
74
|
-
velbusaio/messages/set_realtime_clock.py,sha256=
|
|
74
|
+
velbusaio/messages/set_realtime_clock.py,sha256=h34pCvyPm7tSQ5BdB8yC8SRulrtldeX-ZJFv3Wcvdk0,1209
|
|
75
75
|
velbusaio/messages/set_temperature.py,sha256=78LfGOBZo2bw7eF38uyXOjUcJrsSvQPDW2qbXLOYd0o,959
|
|
76
76
|
velbusaio/messages/slider_status.py,sha256=AlBI1DJPLUwxOFfPIKYv15bFOnVXm__Tym7AW4xGMxo,1418
|
|
77
77
|
velbusaio/messages/slow_blinking_led.py,sha256=UktzpRtyM4mR7_KQuNjqenPEeM3P1vgTyMW8dnVwylQ,909
|
|
@@ -96,8 +96,8 @@ velbusaio/messages/very_fast_blinking_led.py,sha256=vlMEern8PoOvtO5JaAk9erMR4IKJ
|
|
|
96
96
|
velbusaio/messages/write_data_to_memory.py,sha256=gr6bi4SzK8Mw8fnp8yV-STq5jts7NoeV7zZgdptH5Vs,1039
|
|
97
97
|
velbusaio/messages/write_memory_block.py,sha256=zGnNxx_M66HpBQ8S7kagtNw8_qSRHsOLk1MuiS0uygM,1032
|
|
98
98
|
velbusaio/messages/write_module_address_and_serial_number.py,sha256=6y57j-md3btNtQddX5CUREtSs1Dzgkd953sQPZ3Pioo,1597
|
|
99
|
-
velbus_aio-2024.4.
|
|
100
|
-
velbus_aio-2024.4.
|
|
101
|
-
velbus_aio-2024.4.
|
|
102
|
-
velbus_aio-2024.4.
|
|
103
|
-
velbus_aio-2024.4.
|
|
99
|
+
velbus_aio-2024.4.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
100
|
+
velbus_aio-2024.4.1.dist-info/METADATA,sha256=gQoruLEsogCEK-x7B7ls4F_zLud9p4LJDDiPv2rreJ8,3253
|
|
101
|
+
velbus_aio-2024.4.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
102
|
+
velbus_aio-2024.4.1.dist-info/top_level.txt,sha256=W0-lSOwD23mm8FqaIe9vY20fKicBMIdUVjF-zmfxRnY,15
|
|
103
|
+
velbus_aio-2024.4.1.dist-info/RECORD,,
|
velbusaio/channels.py
CHANGED
|
@@ -136,17 +136,8 @@ class Channel:
|
|
|
136
136
|
if k != "_writer" and k != "_on_status_update" and k != "_name_parts"
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
def
|
|
140
|
-
|
|
141
|
-
return {
|
|
142
|
-
k: d[k]
|
|
143
|
-
for k in d
|
|
144
|
-
if k != "_writer"
|
|
145
|
-
and k != "_on_status_update"
|
|
146
|
-
and k != "_name_parts"
|
|
147
|
-
and k != "_module"
|
|
148
|
-
and k != "__name__"
|
|
149
|
-
}
|
|
139
|
+
def to_cache(self) -> dict:
|
|
140
|
+
return {"name": self._name, "type": type(self).__name__}
|
|
150
141
|
|
|
151
142
|
def __setstate__(self, state):
|
|
152
143
|
self.__dict__.update(state)
|
velbusaio/command_registry.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Command registry.
|
|
2
|
+
|
|
2
3
|
:author: Maikel Punie <maikel.punie@gmail.com> and Thomas Delaet <thomas@delaet.org>
|
|
3
4
|
"""
|
|
4
5
|
|
|
@@ -87,7 +88,10 @@ MODULE_DIRECTORY = {
|
|
|
87
88
|
|
|
88
89
|
|
|
89
90
|
class CommandRegistry:
|
|
91
|
+
"""Command registry class."""
|
|
92
|
+
|
|
90
93
|
def __init__(self, module_directory: dict) -> None:
|
|
94
|
+
"""Init method."""
|
|
91
95
|
self._module_directory = module_directory
|
|
92
96
|
self._default_commands = {}
|
|
93
97
|
self._overrides = {}
|
|
@@ -95,6 +99,7 @@ class CommandRegistry:
|
|
|
95
99
|
def register_command(
|
|
96
100
|
self, command_value: int, command_class: type, module_name: str | None = None
|
|
97
101
|
) -> None:
|
|
102
|
+
"""Register a command."""
|
|
98
103
|
if command_value < 0 or command_value > 255:
|
|
99
104
|
raise ValueError("Command_value should be >=0 and <=255")
|
|
100
105
|
if module_name and module_name not in self._module_directory.values():
|
|
@@ -115,6 +120,7 @@ class CommandRegistry:
|
|
|
115
120
|
def _register_override(
|
|
116
121
|
self, command_value: int, command_class: type, module_type: str
|
|
117
122
|
) -> None:
|
|
123
|
+
"""Register and override."""
|
|
118
124
|
if module_type not in self._overrides:
|
|
119
125
|
self._overrides[module_type] = {}
|
|
120
126
|
if command_value not in self._overrides[module_type]:
|
|
@@ -125,12 +131,14 @@ class CommandRegistry:
|
|
|
125
131
|
)
|
|
126
132
|
|
|
127
133
|
def _register_default(self, command_value: int, command_class: type) -> None:
|
|
134
|
+
"""Register a default command."""
|
|
128
135
|
if command_value not in self._default_commands:
|
|
129
136
|
self._default_commands[command_value] = command_class
|
|
130
137
|
else:
|
|
131
138
|
raise Exception("double registration in command registry")
|
|
132
139
|
|
|
133
140
|
def has_command(self, command_value: int, module_type: int = 0) -> bool:
|
|
141
|
+
"""Find a command."""
|
|
134
142
|
if module_type in self._overrides:
|
|
135
143
|
if command_value in self._overrides[module_type]:
|
|
136
144
|
return True
|
|
@@ -139,6 +147,7 @@ class CommandRegistry:
|
|
|
139
147
|
return False
|
|
140
148
|
|
|
141
149
|
def get_command(self, command_value: int, module_type: int = 0) -> None | type:
|
|
150
|
+
"""Search a command in the registry."""
|
|
142
151
|
if module_type in self._overrides:
|
|
143
152
|
if command_value in self._overrides[module_type]:
|
|
144
153
|
return self._overrides[module_type][command_value]
|
|
@@ -151,6 +160,8 @@ commandRegistry = CommandRegistry(MODULE_DIRECTORY)
|
|
|
151
160
|
|
|
152
161
|
|
|
153
162
|
def register(command_value: int, module_types: list[str] | None = None):
|
|
163
|
+
"""Register decorator."""
|
|
164
|
+
|
|
154
165
|
def inner_register(command_class):
|
|
155
166
|
if module_types:
|
|
156
167
|
for module_type in module_types:
|
velbusaio/const.py
CHANGED
velbusaio/controller.py
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Main interface for the velbusaio lib
|
|
3
|
-
"""
|
|
1
|
+
"""Main interface for the velbusaio lib."""
|
|
4
2
|
|
|
5
3
|
from __future__ import annotations
|
|
6
4
|
|
|
7
5
|
import asyncio
|
|
8
6
|
import logging
|
|
9
7
|
import pathlib
|
|
10
|
-
import pickle
|
|
11
8
|
import re
|
|
12
9
|
import ssl
|
|
10
|
+
import time
|
|
13
11
|
from urllib.parse import urlparse
|
|
14
12
|
|
|
15
13
|
import serial
|
|
@@ -31,15 +29,14 @@ from velbusaio.raw_message import RawMessage
|
|
|
31
29
|
|
|
32
30
|
|
|
33
31
|
class Velbus:
|
|
34
|
-
"""
|
|
35
|
-
A velbus controller
|
|
36
|
-
"""
|
|
32
|
+
"""A velbus controller."""
|
|
37
33
|
|
|
38
34
|
def __init__(
|
|
39
35
|
self,
|
|
40
36
|
dsn: str,
|
|
41
37
|
cache_dir: str = get_cache_dir(),
|
|
42
38
|
) -> None:
|
|
39
|
+
"""Init the Velbus controller."""
|
|
43
40
|
self._log = logging.getLogger("velbus")
|
|
44
41
|
|
|
45
42
|
self._protocol = VelbusProtocol(
|
|
@@ -60,6 +57,7 @@ class Velbus:
|
|
|
60
57
|
pathlib.Path(self._cache_dir).mkdir(parents=True, exist_ok=True)
|
|
61
58
|
|
|
62
59
|
async def _on_message_received(self, msg: RawMessage) -> None:
|
|
60
|
+
"""On message received function."""
|
|
63
61
|
await self._handler.handle(msg)
|
|
64
62
|
|
|
65
63
|
def _on_connection_lost(self, exc: Exception) -> None:
|
|
@@ -69,6 +67,7 @@ class Velbus:
|
|
|
69
67
|
asyncio.ensure_future(self.connect())
|
|
70
68
|
|
|
71
69
|
def _on_end_of_scan(self) -> None:
|
|
70
|
+
"""Notify the scan failure."""
|
|
72
71
|
self._handler.scan_finished()
|
|
73
72
|
|
|
74
73
|
async def add_module(
|
|
@@ -81,31 +80,23 @@ class Velbus:
|
|
|
81
80
|
build_year: int | None = None,
|
|
82
81
|
build_week: int | None = None,
|
|
83
82
|
) -> None:
|
|
84
|
-
"""
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
self.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
data,
|
|
99
|
-
serial=serial,
|
|
100
|
-
build_year=build_year,
|
|
101
|
-
build_week=build_week,
|
|
102
|
-
memorymap=memorymap,
|
|
103
|
-
cache_dir=self._cache_dir,
|
|
104
|
-
)
|
|
105
|
-
self._modules[addr].initialize(self.send)
|
|
106
|
-
await self._modules[addr].load()
|
|
83
|
+
"""Add a found module to the module cache."""
|
|
84
|
+
self._log.info(f"Found module: type:{typ} address:{addr}")
|
|
85
|
+
self._modules[addr] = Module.factory(
|
|
86
|
+
addr,
|
|
87
|
+
typ,
|
|
88
|
+
data,
|
|
89
|
+
serial=serial,
|
|
90
|
+
build_year=build_year,
|
|
91
|
+
build_week=build_week,
|
|
92
|
+
memorymap=memorymap,
|
|
93
|
+
cache_dir=self._cache_dir,
|
|
94
|
+
)
|
|
95
|
+
self._modules[addr].initialize(self.send)
|
|
96
|
+
await self._modules[addr].load()
|
|
107
97
|
|
|
108
98
|
async def add_submodules(self, addr: int, subList: dict[int, int]) -> None:
|
|
99
|
+
"""Add submodules address to module."""
|
|
109
100
|
for sub_num, sub_addr in subList.items():
|
|
110
101
|
if sub_addr == 0xFF:
|
|
111
102
|
continue
|
|
@@ -114,48 +105,30 @@ class Velbus:
|
|
|
114
105
|
self._modules[sub_addr] = self._modules[addr]
|
|
115
106
|
self._modules[addr].cleanupSubChannels()
|
|
116
107
|
|
|
117
|
-
def _load_module_from_cache(self, cache_dir: str, address: int) -> None | Module:
|
|
118
|
-
try:
|
|
119
|
-
cfile = pathlib.Path(f"{cache_dir}/{address}.p")
|
|
120
|
-
with cfile.open("rb") as fl:
|
|
121
|
-
o = pickle.load(fl)
|
|
122
|
-
if isinstance(o, Module):
|
|
123
|
-
return o
|
|
124
|
-
except OSError:
|
|
125
|
-
pass
|
|
126
|
-
return None
|
|
127
|
-
|
|
128
108
|
def get_modules(self) -> dict:
|
|
129
|
-
"""
|
|
130
|
-
Return the module cache
|
|
131
|
-
"""
|
|
109
|
+
"""Return the module cache."""
|
|
132
110
|
return self._modules
|
|
133
111
|
|
|
134
112
|
def get_module(self, addr: str) -> None | Module:
|
|
135
|
-
"""
|
|
136
|
-
|
|
137
|
-
"""
|
|
138
|
-
if addr in self._modules.keys():
|
|
113
|
+
"""Get a module on an address."""
|
|
114
|
+
if addr in self._modules:
|
|
139
115
|
return self._modules[addr]
|
|
140
116
|
return None
|
|
141
117
|
|
|
142
118
|
def get_channels(self, addr: str) -> None | dict:
|
|
143
|
-
"""
|
|
144
|
-
Get the channels for an address
|
|
145
|
-
"""
|
|
119
|
+
"""Get the channels for an address."""
|
|
146
120
|
if addr in self._modules:
|
|
147
121
|
return (self._modules[addr]).get_channels()
|
|
148
122
|
return None
|
|
149
123
|
|
|
150
124
|
async def stop(self) -> None:
|
|
125
|
+
"""Stop the controller."""
|
|
151
126
|
self._closing = True
|
|
152
127
|
self._auto_reconnect = False
|
|
153
128
|
self._protocol.close()
|
|
154
129
|
|
|
155
130
|
async def connect(self, test_connect: bool = False) -> None:
|
|
156
|
-
"""
|
|
157
|
-
Connect to the bus and load all the data
|
|
158
|
-
"""
|
|
131
|
+
"""Connect to the bus and load all the data."""
|
|
159
132
|
auth = None
|
|
160
133
|
# connect to the bus
|
|
161
134
|
if ":" in self._dsn:
|
|
@@ -182,7 +155,7 @@ class Velbus:
|
|
|
182
155
|
)
|
|
183
156
|
|
|
184
157
|
except (ConnectionRefusedError, OSError) as err:
|
|
185
|
-
raise VelbusConnectionFailed
|
|
158
|
+
raise VelbusConnectionFailed from err
|
|
186
159
|
else:
|
|
187
160
|
# serial port
|
|
188
161
|
try:
|
|
@@ -198,7 +171,7 @@ class Velbus:
|
|
|
198
171
|
rtscts=1,
|
|
199
172
|
)
|
|
200
173
|
except (FileNotFoundError, serial.SerialException) as err:
|
|
201
|
-
raise VelbusConnectionFailed
|
|
174
|
+
raise VelbusConnectionFailed from err
|
|
202
175
|
if test_connect:
|
|
203
176
|
return
|
|
204
177
|
# if auth is required send the auth key
|
|
@@ -209,6 +182,7 @@ class Velbus:
|
|
|
209
182
|
await self.scan()
|
|
210
183
|
|
|
211
184
|
async def scan(self) -> None:
|
|
185
|
+
"""Scan the bus."""
|
|
212
186
|
self._handler.scan_started()
|
|
213
187
|
for addr in range(1, 256):
|
|
214
188
|
msg = ModuleTypeRequestMessage(addr)
|
|
@@ -230,9 +204,7 @@ class Velbus:
|
|
|
230
204
|
)
|
|
231
205
|
|
|
232
206
|
async def _check_if_modules_are_loaded(self) -> None:
|
|
233
|
-
"""
|
|
234
|
-
Task to wait until modules are loaded
|
|
235
|
-
"""
|
|
207
|
+
"""Task to wait until modules are loaded."""
|
|
236
208
|
while True:
|
|
237
209
|
mods_loaded = 0
|
|
238
210
|
for mod in (self.get_modules()).values():
|
|
@@ -247,9 +219,7 @@ class Velbus:
|
|
|
247
219
|
await asyncio.sleep(15)
|
|
248
220
|
|
|
249
221
|
async def send(self, msg: Message) -> None:
|
|
250
|
-
"""
|
|
251
|
-
Send a packet
|
|
252
|
-
"""
|
|
222
|
+
"""Send a packet."""
|
|
253
223
|
await self._protocol.send_message(
|
|
254
224
|
RawMessage(
|
|
255
225
|
priority=msg.priority,
|
|
@@ -260,6 +230,7 @@ class Velbus:
|
|
|
260
230
|
)
|
|
261
231
|
|
|
262
232
|
def get_all(self, class_name: str) -> list[Channel]:
|
|
233
|
+
"""Get all channels."""
|
|
263
234
|
lst = []
|
|
264
235
|
for addr, mod in (self.get_modules()).items():
|
|
265
236
|
if addr in self._submodules:
|
|
@@ -270,9 +241,8 @@ class Velbus:
|
|
|
270
241
|
return lst
|
|
271
242
|
|
|
272
243
|
async def sync_clock(self) -> None:
|
|
273
|
-
"""
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
await self.send(
|
|
277
|
-
await self.send(
|
|
278
|
-
await self.send(SetDaylightSaving())
|
|
244
|
+
"""Will send all the needed messages to sync the clock."""
|
|
245
|
+
lclt = time.localtime()
|
|
246
|
+
await self.send(SetRealtimeClock(wday=lclt[6], hour=lclt[3], min=lclt[4]))
|
|
247
|
+
await self.send(SetDate(day=lclt[2], mon=lclt[1], year=lclt[0]))
|
|
248
|
+
await self.send(SetDaylightSaving(ds=not lclt[8]))
|
velbusaio/handler.py
CHANGED
|
@@ -8,7 +8,6 @@ from __future__ import annotations
|
|
|
8
8
|
import asyncio
|
|
9
9
|
import json
|
|
10
10
|
import logging
|
|
11
|
-
import re
|
|
12
11
|
from typing import TYPE_CHECKING, Awaitable, Callable
|
|
13
12
|
import pkg_resources
|
|
14
13
|
|
|
@@ -105,7 +104,9 @@ class PacketHandler:
|
|
|
105
104
|
else:
|
|
106
105
|
self._log.warning(
|
|
107
106
|
"NOT FOUND IN command_registry: addr={} cmd={} packet={}".format(
|
|
108
|
-
address,
|
|
107
|
+
address,
|
|
108
|
+
command_value,
|
|
109
|
+
":".join(format(x, "02x") for x in data),
|
|
109
110
|
)
|
|
110
111
|
)
|
|
111
112
|
elif self._scan_complete:
|
velbusaio/helpers.py
CHANGED
velbusaio/message.py
CHANGED
velbusaio/messages/cover_off.py
CHANGED
velbusaio/messages/set_date.py
CHANGED
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
|
-
import time
|
|
8
|
-
|
|
9
7
|
from velbusaio.command_registry import register
|
|
10
8
|
from velbusaio.message import Message
|
|
11
9
|
|
|
@@ -18,11 +16,11 @@ class SetDate(Message):
|
|
|
18
16
|
received by all modules
|
|
19
17
|
"""
|
|
20
18
|
|
|
21
|
-
def __init__(self, address=0x00) -> None:
|
|
19
|
+
def __init__(self, address=0x00, day=None, mon=None, year=None) -> None:
|
|
22
20
|
Message.__init__(self)
|
|
23
|
-
self._day =
|
|
24
|
-
self._mon =
|
|
25
|
-
self._year =
|
|
21
|
+
self._day = day
|
|
22
|
+
self._mon = mon
|
|
23
|
+
self._year = year
|
|
26
24
|
self.set_defaults(address)
|
|
27
25
|
|
|
28
26
|
def set_defaults(self, address) -> None:
|
|
@@ -30,10 +28,6 @@ class SetDate(Message):
|
|
|
30
28
|
self.set_address(address)
|
|
31
29
|
self.set_low_priority()
|
|
32
30
|
self.set_no_rtr()
|
|
33
|
-
lclt = time.localtime()
|
|
34
|
-
self._day = lclt[2]
|
|
35
|
-
self._mon = lclt[1]
|
|
36
|
-
self._year = lclt[0]
|
|
37
31
|
|
|
38
32
|
def populate(self, priority, address, rtr, data) -> None:
|
|
39
33
|
"""
|
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
|
-
import time
|
|
8
|
-
|
|
9
7
|
from velbusaio.command_registry import register
|
|
10
8
|
from velbusaio.message import Message
|
|
11
9
|
|
|
@@ -18,9 +16,9 @@ class SetDaylightSaving(Message):
|
|
|
18
16
|
received by all modules
|
|
19
17
|
"""
|
|
20
18
|
|
|
21
|
-
def __init__(self, address=0x00) -> None:
|
|
19
|
+
def __init__(self, address=0x00, ds=None) -> None:
|
|
22
20
|
Message.__init__(self)
|
|
23
|
-
self._ds =
|
|
21
|
+
self._ds = ds
|
|
24
22
|
self.set_defaults(address)
|
|
25
23
|
|
|
26
24
|
def set_defaults(self, address) -> None:
|
|
@@ -28,8 +26,6 @@ class SetDaylightSaving(Message):
|
|
|
28
26
|
self.set_address(address)
|
|
29
27
|
self.set_low_priority()
|
|
30
28
|
self.set_no_rtr()
|
|
31
|
-
lclt = time.localtime()
|
|
32
|
-
self._ds = not lclt[8]
|
|
33
29
|
|
|
34
30
|
def populate(self, priority, address, rtr, data) -> None:
|
|
35
31
|
"""
|
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
|
-
import time
|
|
8
|
-
|
|
9
7
|
from velbusaio.command_registry import register
|
|
10
8
|
from velbusaio.message import Message
|
|
11
9
|
|
|
@@ -18,11 +16,11 @@ class SetRealtimeClock(Message):
|
|
|
18
16
|
received by all modules
|
|
19
17
|
"""
|
|
20
18
|
|
|
21
|
-
def __init__(self, address=0x00) -> None:
|
|
19
|
+
def __init__(self, address=0x00, wday=None, hour=None, min=None) -> None:
|
|
22
20
|
Message.__init__(self)
|
|
23
|
-
self._wday =
|
|
24
|
-
self._hour =
|
|
25
|
-
self._min =
|
|
21
|
+
self._wday = wday
|
|
22
|
+
self._hour = hour
|
|
23
|
+
self._min = min
|
|
26
24
|
self.set_defaults(address)
|
|
27
25
|
|
|
28
26
|
def set_defaults(self, address) -> None:
|
|
@@ -30,10 +28,6 @@ class SetRealtimeClock(Message):
|
|
|
30
28
|
self.set_address(address)
|
|
31
29
|
self.set_low_priority()
|
|
32
30
|
self.set_no_rtr()
|
|
33
|
-
lclt = time.localtime()
|
|
34
|
-
self._wday = lclt[6]
|
|
35
|
-
self._hour = lclt[3]
|
|
36
|
-
self._min = lclt[4]
|
|
37
31
|
|
|
38
32
|
def populate(self, priority, address, rtr, data) -> None:
|
|
39
33
|
"""
|
velbusaio/module.py
CHANGED
|
@@ -5,11 +5,10 @@ This represents a velbus module
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
7
|
import logging
|
|
8
|
-
import os
|
|
9
8
|
import pathlib
|
|
10
|
-
import pickle
|
|
11
9
|
import struct
|
|
12
10
|
import sys
|
|
11
|
+
import json
|
|
13
12
|
from typing import Awaitable, Callable
|
|
14
13
|
|
|
15
14
|
from velbusaio.channels import (
|
|
@@ -37,7 +36,7 @@ from velbusaio.const import (
|
|
|
37
36
|
)
|
|
38
37
|
from velbusaio.helpers import handle_match, keys_exists
|
|
39
38
|
from velbusaio.message import Message
|
|
40
|
-
from velbusaio.messages import DaliDeviceSettingMsg
|
|
39
|
+
from velbusaio.messages.dali_device_settings import DaliDeviceSettingMsg
|
|
41
40
|
from velbusaio.messages.blind_status import BlindStatusMessage, BlindStatusNgMessage
|
|
42
41
|
from velbusaio.messages.channel_name_part1 import (
|
|
43
42
|
ChannelNamePart1Message,
|
|
@@ -81,8 +80,6 @@ from velbusaio.messages.module_status import (
|
|
|
81
80
|
ModuleStatusPirMessage,
|
|
82
81
|
)
|
|
83
82
|
from velbusaio.messages.module_status_request import ModuleStatusRequestMessage
|
|
84
|
-
from velbusaio.messages.module_subtype import ModuleSubTypeMessage
|
|
85
|
-
from velbusaio.messages.module_type import ModuleTypeMessage, ModuleType2Message
|
|
86
83
|
from velbusaio.messages.push_button_status import PushButtonStatusMessage
|
|
87
84
|
from velbusaio.messages.read_data_from_memory import ReadDataFromMemoryMessage
|
|
88
85
|
from velbusaio.messages.relay_status import RelayStatusMessage, RelayStatusMessage2
|
|
@@ -188,9 +185,9 @@ class Module:
|
|
|
188
185
|
del self._channels[i]
|
|
189
186
|
|
|
190
187
|
def _cache(self) -> None:
|
|
191
|
-
cfile = pathlib.Path(f"{self._cache_dir}/{self._address}.
|
|
192
|
-
with cfile.open("
|
|
193
|
-
|
|
188
|
+
cfile = pathlib.Path(f"{self._cache_dir}/{self._address}.json")
|
|
189
|
+
with cfile.open("w") as fl:
|
|
190
|
+
json.dump(self.to_cache(), fl, indent=4)
|
|
194
191
|
|
|
195
192
|
def __getstate__(self) -> dict:
|
|
196
193
|
d = self.__dict__
|
|
@@ -201,20 +198,17 @@ class Module:
|
|
|
201
198
|
self.__dict__ = state
|
|
202
199
|
|
|
203
200
|
def __repr__(self) -> str:
|
|
204
|
-
return
|
|
205
|
-
"<{}: {{{}}} @ {{{}}} loaded:{{{}}} loading:{{{}}} channels{{:{}}}>".format(
|
|
206
|
-
self._name,
|
|
207
|
-
self._type,
|
|
208
|
-
self._address,
|
|
209
|
-
self.loaded,
|
|
210
|
-
self._is_loading,
|
|
211
|
-
self._channels,
|
|
212
|
-
)
|
|
213
|
-
)
|
|
201
|
+
return f"<{self._name} type:{self._type} address:{self._address} loaded:{self.loaded} loading:{self._is_loading} channels: {self._channels}>"
|
|
214
202
|
|
|
215
203
|
def __str__(self) -> str:
|
|
216
204
|
return self.__repr__()
|
|
217
205
|
|
|
206
|
+
def to_cache(self) -> dict:
|
|
207
|
+
d = {"name": self._name, "channels": {}}
|
|
208
|
+
for num, chan in self._channels.items():
|
|
209
|
+
d["channels"][num] = chan.to_cache()
|
|
210
|
+
return d
|
|
211
|
+
|
|
218
212
|
def get_addresses(self) -> list:
|
|
219
213
|
"""
|
|
220
214
|
Get all addresses for this module
|
|
@@ -232,7 +226,9 @@ class Module:
|
|
|
232
226
|
return self._type
|
|
233
227
|
|
|
234
228
|
def get_type_name(self) -> str:
|
|
235
|
-
|
|
229
|
+
if "Type" in self._data:
|
|
230
|
+
return self._data["Type"]
|
|
231
|
+
return "UNKNOWN"
|
|
236
232
|
|
|
237
233
|
def get_serial(self) -> str | None:
|
|
238
234
|
return self.serial
|
|
@@ -241,12 +237,7 @@ class Module:
|
|
|
241
237
|
return self._name
|
|
242
238
|
|
|
243
239
|
def get_sw_version(self) -> str:
|
|
244
|
-
return "{}-{}.{}.{}"
|
|
245
|
-
self.serial,
|
|
246
|
-
self.memory_map_version,
|
|
247
|
-
self.build_year,
|
|
248
|
-
self.build_week,
|
|
249
|
-
)
|
|
240
|
+
return f"{self.serial}-{self.memory_map_version}.{self.build_year}.{self.build_week}"
|
|
250
241
|
|
|
251
242
|
def calc_channel_offset(self, address: int) -> int:
|
|
252
243
|
_channel_offset = 0
|
|
@@ -549,14 +540,29 @@ class Module:
|
|
|
549
540
|
self._log.info("Load Module")
|
|
550
541
|
# start the loading
|
|
551
542
|
self._is_loading = True
|
|
543
|
+
# see if we have a cache
|
|
544
|
+
try:
|
|
545
|
+
cfile = pathlib.Path(f"{self._cache_dir}/{self._address}.json")
|
|
546
|
+
with cfile.open("r") as fl:
|
|
547
|
+
cache = json.load(fl)
|
|
548
|
+
except OSError:
|
|
549
|
+
cache = {}
|
|
552
550
|
# load default channels
|
|
553
551
|
await self.__load_default_channels()
|
|
554
552
|
# load the data from memory ( the stuff that we need)
|
|
555
|
-
|
|
553
|
+
if "name" in cache and cache["name"] != "":
|
|
554
|
+
self._name = cache["name"]
|
|
555
|
+
else:
|
|
556
|
+
await self.__load_memory()
|
|
556
557
|
# load the module status
|
|
557
558
|
await self._request_module_status()
|
|
558
559
|
# load the channel names
|
|
559
|
-
|
|
560
|
+
if "channels" in cache:
|
|
561
|
+
for num, chan in cache["channels"].items():
|
|
562
|
+
self._channels[int(num)]._name = chan["name"]
|
|
563
|
+
self._channels[int(num)]._is_loaded = True
|
|
564
|
+
else:
|
|
565
|
+
await self._request_channel_name()
|
|
560
566
|
# load the module specific stuff
|
|
561
567
|
self._load()
|
|
562
568
|
# stop the loading
|
velbusaio/protocol.json
CHANGED
|
@@ -8792,7 +8792,7 @@
|
|
|
8792
8792
|
},
|
|
8793
8793
|
"45": {
|
|
8794
8794
|
"Info": "VMBDALI-20 DALI gateway module",
|
|
8795
|
-
"Type": "VMBDALI"
|
|
8795
|
+
"Type": "VMBDALI-20"
|
|
8796
8796
|
},
|
|
8797
8797
|
"48": {
|
|
8798
8798
|
"Channels": {
|
|
@@ -9361,7 +9361,8 @@
|
|
|
9361
9361
|
}
|
|
9362
9362
|
},
|
|
9363
9363
|
"TemperatureChannel": "09",
|
|
9364
|
-
"ThermostatAddr": "0"
|
|
9364
|
+
"ThermostatAddr": "0",
|
|
9365
|
+
"Type": "VMBEL1-20"
|
|
9365
9366
|
},
|
|
9366
9367
|
"50": {
|
|
9367
9368
|
"AllChannelStatus": "FF",
|
|
@@ -9449,7 +9450,8 @@
|
|
|
9449
9450
|
}
|
|
9450
9451
|
},
|
|
9451
9452
|
"TemperatureChannel": "09",
|
|
9452
|
-
"ThermostatAddr": "0"
|
|
9453
|
+
"ThermostatAddr": "0",
|
|
9454
|
+
"Type": "VMBEL2-20"
|
|
9453
9455
|
},
|
|
9454
9456
|
"51": {
|
|
9455
9457
|
"AllChannelStatus": "FF",
|
|
@@ -9537,7 +9539,8 @@
|
|
|
9537
9539
|
}
|
|
9538
9540
|
},
|
|
9539
9541
|
"TemperatureChannel": "09",
|
|
9540
|
-
"ThermostatAddr": "0"
|
|
9542
|
+
"ThermostatAddr": "0",
|
|
9543
|
+
"Type": "VMBEL4-20"
|
|
9541
9544
|
},
|
|
9542
9545
|
"52": {
|
|
9543
9546
|
"AllChannelStatus": "FF",
|
|
@@ -9725,7 +9728,8 @@
|
|
|
9725
9728
|
}
|
|
9726
9729
|
},
|
|
9727
9730
|
"TemperatureChannel": "33",
|
|
9728
|
-
"ThermostatAddr": "3"
|
|
9731
|
+
"ThermostatAddr": "3",
|
|
9732
|
+
"Type": "VMBELO-20"
|
|
9729
9733
|
},
|
|
9730
9734
|
"54": {
|
|
9731
9735
|
"Info": "1 Button Touch panel",
|
velbusaio/util.py
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|