velbus-aio 2024.7.5__py3-none-any.whl → 2024.10.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.

Potentially problematic release.


This version of velbus-aio might be problematic. Click here for more details.

Files changed (96) hide show
  1. {velbus_aio-2024.7.5.dist-info → velbus_aio-2024.10.0.dist-info}/METADATA +8 -5
  2. {velbus_aio-2024.7.5.dist-info → velbus_aio-2024.10.0.dist-info}/RECORD +95 -15
  3. {velbus_aio-2024.7.5.dist-info → velbus_aio-2024.10.0.dist-info}/WHEEL +1 -1
  4. velbusaio/channels.py +2 -2
  5. velbusaio/command_registry.py +6 -5
  6. velbusaio/const.py +1 -1
  7. velbusaio/controller.py +8 -5
  8. velbusaio/handler.py +73 -59
  9. velbusaio/messages/__init__.py +2 -2
  10. velbusaio/messages/edge_set_color.py +1 -0
  11. velbusaio/module.py +47 -29
  12. velbusaio/module_spec/01.json +50 -0
  13. velbusaio/module_spec/02.json +11 -0
  14. velbusaio/module_spec/03.json +18 -0
  15. velbusaio/module_spec/05.json +36 -0
  16. velbusaio/module_spec/06.json +101 -0
  17. velbusaio/module_spec/07.json +11 -0
  18. velbusaio/module_spec/08.json +26 -0
  19. velbusaio/module_spec/09.json +24 -0
  20. velbusaio/module_spec/0A.json +46 -0
  21. velbusaio/module_spec/0B.json +46 -0
  22. velbusaio/module_spec/0C.json +13 -0
  23. velbusaio/module_spec/0E.json +25 -0
  24. velbusaio/module_spec/0F.json +11 -0
  25. velbusaio/module_spec/10.json +100 -0
  26. velbusaio/module_spec/11.json +100 -0
  27. velbusaio/module_spec/12.json +63 -0
  28. velbusaio/module_spec/13.json +4 -0
  29. velbusaio/module_spec/14.json +11 -0
  30. velbusaio/module_spec/15.json +80 -0
  31. velbusaio/module_spec/16.json +119 -0
  32. velbusaio/module_spec/17.json +119 -0
  33. velbusaio/module_spec/18.json +119 -0
  34. velbusaio/module_spec/1A.json +73 -0
  35. velbusaio/module_spec/1B.json +100 -0
  36. velbusaio/module_spec/1D.json +83 -0
  37. velbusaio/module_spec/1E.json +295 -0
  38. velbusaio/module_spec/1F.json +167 -0
  39. velbusaio/module_spec/20.json +167 -0
  40. velbusaio/module_spec/21.json +291 -0
  41. velbusaio/module_spec/22.json +323 -0
  42. velbusaio/module_spec/23.json +129 -0
  43. velbusaio/module_spec/25.json +3 -0
  44. velbusaio/module_spec/28.json +419 -0
  45. velbusaio/module_spec/29.json +228 -0
  46. velbusaio/module_spec/2A.json +239 -0
  47. velbusaio/module_spec/2B.json +239 -0
  48. velbusaio/module_spec/2C.json +257 -0
  49. velbusaio/module_spec/2D.json +295 -0
  50. velbusaio/module_spec/2E.json +212 -0
  51. velbusaio/module_spec/2F.json +208 -0
  52. velbusaio/module_spec/30.json +46 -0
  53. velbusaio/module_spec/31.json +465 -0
  54. velbusaio/module_spec/32.json +357 -0
  55. velbusaio/module_spec/33.json +239 -0
  56. velbusaio/module_spec/34.json +157 -0
  57. velbusaio/module_spec/35.json +157 -0
  58. velbusaio/module_spec/36.json +157 -0
  59. velbusaio/module_spec/37.json +297 -0
  60. velbusaio/module_spec/38.json +102 -0
  61. velbusaio/module_spec/39.json +4 -0
  62. velbusaio/module_spec/3A.json +295 -0
  63. velbusaio/module_spec/3B.json +295 -0
  64. velbusaio/module_spec/3C.json +295 -0
  65. velbusaio/module_spec/3D.json +419 -0
  66. velbusaio/module_spec/3E.json +295 -0
  67. velbusaio/module_spec/3F.json +4 -0
  68. velbusaio/module_spec/40.json +4 -0
  69. velbusaio/module_spec/41.json +233 -0
  70. velbusaio/module_spec/42.json +4 -0
  71. velbusaio/module_spec/43.json +11 -0
  72. velbusaio/module_spec/44.json +26 -0
  73. velbusaio/module_spec/45.json +4 -0
  74. velbusaio/module_spec/48.json +100 -0
  75. velbusaio/module_spec/49.json +100 -0
  76. velbusaio/module_spec/4A.json +4 -0
  77. velbusaio/module_spec/4B.json +118 -0
  78. velbusaio/module_spec/4C.json +119 -0
  79. velbusaio/module_spec/4D.json +108 -0
  80. velbusaio/module_spec/4E.json +443 -0
  81. velbusaio/module_spec/4F.json +89 -0
  82. velbusaio/module_spec/50.json +89 -0
  83. velbusaio/module_spec/51.json +89 -0
  84. velbusaio/module_spec/52.json +189 -0
  85. velbusaio/module_spec/54.json +4 -0
  86. velbusaio/module_spec/55.json +4 -0
  87. velbusaio/module_spec/56.json +4 -0
  88. velbusaio/module_spec/57.json +222 -0
  89. velbusaio/module_spec/5A.json +4 -0
  90. velbusaio/module_spec/5C.json +87 -0
  91. velbusaio/module_spec/5F.json +66 -0
  92. velbusaio/module_spec/broadcast.json +67 -0
  93. velbusaio/protocol.py +1 -1
  94. velbusaio/protocol.json +0 -10194
  95. {velbus_aio-2024.7.5.dist-info → velbus_aio-2024.10.0.dist-info}/LICENSE +0 -0
  96. {velbus_aio-2024.7.5.dist-info → velbus_aio-2024.10.0.dist-info}/top_level.txt +0 -0
velbusaio/module.py CHANGED
@@ -4,14 +4,17 @@ This represents a velbus module
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
+ import json
7
8
  import logging
9
+ import os
8
10
  import pathlib
9
11
  import struct
10
12
  import sys
11
- import json
12
- import os
13
13
  from typing import Awaitable, Callable
14
14
 
15
+ import pkg_resources
16
+ from aiofile import async_open
17
+
15
18
  from velbusaio.channels import (
16
19
  Blind,
17
20
  Button,
@@ -25,19 +28,20 @@ from velbusaio.channels import (
25
28
  SelectedProgram,
26
29
  Sensor,
27
30
  SensorNumber,
28
- Temperature,
29
- ThermostatChannel,
30
31
  )
32
+ from velbusaio.channels import Temperature
33
+ from velbusaio.channels import Temperature as TemperatureChannelType
34
+ from velbusaio.channels import ThermostatChannel
31
35
  from velbusaio.command_registry import commandRegistry
32
36
  from velbusaio.const import (
33
37
  CHANNEL_LIGHT_VALUE,
34
38
  CHANNEL_MEMO_TEXT,
35
39
  CHANNEL_SELECTED_PROGRAM,
36
40
  PRIORITY_LOW,
41
+ SCAN_MODULEINFO_TIMEOUT_INITIAL,
37
42
  )
38
- from velbusaio.helpers import handle_match, keys_exists
43
+ from velbusaio.helpers import h2, handle_match, keys_exists
39
44
  from velbusaio.message import Message
40
- from velbusaio.messages.dali_device_settings import DaliDeviceSettingMsg
41
45
  from velbusaio.messages.blind_status import BlindStatusMessage, BlindStatusNgMessage
42
46
  from velbusaio.messages.channel_name_part1 import (
43
47
  ChannelNamePart1Message,
@@ -61,6 +65,7 @@ from velbusaio.messages.channel_name_request import ChannelNameRequestMessage
61
65
  from velbusaio.messages.clear_led import ClearLedMessage
62
66
  from velbusaio.messages.counter_status import CounterStatusMessage
63
67
  from velbusaio.messages.counter_status_request import CounterStatusRequestMessage
68
+ from velbusaio.messages.dali_device_settings import DaliDeviceSettingMsg
64
69
  from velbusaio.messages.dali_device_settings import DeviceType as DaliDeviceType
65
70
  from velbusaio.messages.dali_device_settings import DeviceTypeMsg as DaliDeviceTypeMsg
66
71
  from velbusaio.messages.dali_device_settings import MemberOfGroupMsg
@@ -73,7 +78,6 @@ from velbusaio.messages.dimmer_channel_status import DimmerChannelStatusMessage
73
78
  from velbusaio.messages.dimmer_status import DimmerStatusMessage
74
79
  from velbusaio.messages.fast_blinking_led import FastBlinkingLedMessage
75
80
  from velbusaio.messages.memory_data import MemoryDataMessage
76
- from velbusaio.messages.raw import MeteoRawMessage, SensorRawMessage
77
81
  from velbusaio.messages.module_status import (
78
82
  ModuleStatusGP4PirMessage,
79
83
  ModuleStatusMessage,
@@ -82,6 +86,7 @@ from velbusaio.messages.module_status import (
82
86
  )
83
87
  from velbusaio.messages.module_status_request import ModuleStatusRequestMessage
84
88
  from velbusaio.messages.push_button_status import PushButtonStatusMessage
89
+ from velbusaio.messages.raw import MeteoRawMessage, SensorRawMessage
85
90
  from velbusaio.messages.read_data_from_memory import ReadDataFromMemoryMessage
86
91
  from velbusaio.messages.relay_status import RelayStatusMessage, RelayStatusMessage2
87
92
  from velbusaio.messages.sensor_temperature import SensorTemperatureMessage
@@ -90,7 +95,6 @@ from velbusaio.messages.slider_status import SliderStatusMessage
90
95
  from velbusaio.messages.slow_blinking_led import SlowBlinkingLedMessage
91
96
  from velbusaio.messages.temp_sensor_status import TempSensorStatusMessage
92
97
  from velbusaio.messages.update_led_status import UpdateLedStatusMessage
93
- from velbusaio.channels import Temperature as TemperatureChannelType
94
98
 
95
99
 
96
100
  class Module:
@@ -103,7 +107,6 @@ class Module:
103
107
  cls,
104
108
  module_address: int,
105
109
  module_type: int,
106
- module_data: dict,
107
110
  serial: int | None = None,
108
111
  memorymap: int | None = None,
109
112
  build_year: int | None = None,
@@ -114,7 +117,6 @@ class Module:
114
117
  return VmbDali(
115
118
  module_address,
116
119
  module_type,
117
- module_data,
118
120
  serial,
119
121
  memorymap,
120
122
  build_year,
@@ -125,7 +127,6 @@ class Module:
125
127
  return Module(
126
128
  module_address,
127
129
  module_type,
128
- module_data,
129
130
  serial,
130
131
  memorymap,
131
132
  build_year,
@@ -137,7 +138,6 @@ class Module:
137
138
  self,
138
139
  module_address: int,
139
140
  module_type: int,
140
- module_data: dict,
141
141
  serial: int | None = None,
142
142
  memorymap: int | None = None,
143
143
  build_year: int | None = None,
@@ -145,8 +145,8 @@ class Module:
145
145
  cache_dir: str | None = None,
146
146
  ) -> None:
147
147
  self._address = module_address
148
- self._type = module_type
149
- self._data = module_data
148
+ self._type = int(module_type)
149
+ self._data = {}
150
150
 
151
151
  self._name = {}
152
152
  self._sub_address = {}
@@ -159,8 +159,25 @@ class Module:
159
159
  self._channels = {}
160
160
  self.loaded = False
161
161
 
162
- def initialize(self, writer: Callable[[Message], Awaitable[None]]) -> None:
162
+ def get_initial_timeout(self) -> int:
163
+ return SCAN_MODULEINFO_TIMEOUT_INITIAL
164
+
165
+ async def initialize(self, writer: Callable[[Message], Awaitable[None]]) -> None:
163
166
  self._log = logging.getLogger("velbus-module")
167
+ # load the protocol data
168
+ try:
169
+ async with async_open(
170
+ pkg_resources.resource_filename(
171
+ __name__, f"module_spec/{h2(self._type)}.json"
172
+ )
173
+ ) as protocol_file:
174
+ self._data = json.loads(await protocol_file.read())
175
+ self._log.debug(f"Module spec {h2(self._type)} loaded")
176
+ except FileNotFoundError:
177
+ self._log.warning(f"No module spec for {h2(self._type)}")
178
+ self._data = {}
179
+
180
+ # set some params from the velbus controller
164
181
  self._writer = writer
165
182
  for chan in self._channels.values():
166
183
  chan._writer = writer
@@ -185,9 +202,9 @@ class Module:
185
202
  ):
186
203
  del self._channels[i]
187
204
 
188
- def _cache(self) -> None:
205
+ async def _cache(self) -> None:
189
206
  cfile = pathlib.Path(f"{self._cache_dir}/{self._address}.json")
190
- with cfile.open("w") as fl:
207
+ with open(cfile, "w") as fl:
191
208
  json.dump(self.to_cache(), fl, indent=4)
192
209
 
193
210
  def __getstate__(self) -> dict:
@@ -265,6 +282,7 @@ class Module:
265
282
  ),
266
283
  ):
267
284
  self._process_channel_name_message(1, message)
285
+ await self._cache()
268
286
  elif isinstance(
269
287
  message,
270
288
  (
@@ -274,6 +292,7 @@ class Module:
274
292
  ),
275
293
  ):
276
294
  self._process_channel_name_message(2, message)
295
+ await self._cache()
277
296
  elif isinstance(
278
297
  message,
279
298
  (
@@ -283,6 +302,7 @@ class Module:
283
302
  ),
284
303
  ):
285
304
  self._process_channel_name_message(3, message)
305
+ await self._cache()
286
306
  elif isinstance(message, MemoryDataMessage):
287
307
  await self._process_memory_data_message(message)
288
308
  elif isinstance(message, (RelayStatusMessage, RelayStatusMessage2)):
@@ -511,8 +531,6 @@ class Module:
511
531
  message.sensor, {"cur": message.value, "unit": message.unit}
512
532
  )
513
533
 
514
- self._cache()
515
-
516
534
  async def _update_channel(self, channel: int, updates: dict):
517
535
  try:
518
536
  await self._channels[channel].update(updates)
@@ -533,12 +551,12 @@ class Module:
533
551
  # see if we have a cache
534
552
  try:
535
553
  cfile = pathlib.Path(f"{self._cache_dir}/{self._address}.json")
536
- with cfile.open("r") as fl:
537
- cache = json.load(fl)
554
+ async with async_open(cfile, "r") as fl:
555
+ cache = json.loads(await fl.read())
538
556
  except OSError:
539
557
  cache = {}
540
558
  # load default channels
541
- await self.__load_default_channels()
559
+ await self._load_default_channels()
542
560
 
543
561
  # load the data from memory ( the stuff that we need)
544
562
  if "name" in cache and cache["name"] != "":
@@ -640,7 +658,7 @@ class Module:
640
658
  )
641
659
  return int(channel)
642
660
 
643
- def is_loaded(self) -> bool:
661
+ async def is_loaded(self) -> bool:
644
662
  """
645
663
  Check if all name messages have been received
646
664
  """
@@ -658,7 +676,7 @@ class Module:
658
676
  return False
659
677
  # set that we finished the module loading
660
678
  self.loaded = True
661
- self._cache()
679
+ await self._cache()
662
680
  return True
663
681
 
664
682
  async def _request_module_status(self) -> None:
@@ -722,7 +740,7 @@ class Module:
722
740
  msg.low_address = addr[1]
723
741
  await self._writer(msg)
724
742
 
725
- async def __load_default_channels(self) -> None:
743
+ async def _load_default_channels(self) -> None:
726
744
  if "Channels" not in self._data:
727
745
  return
728
746
 
@@ -751,7 +769,6 @@ class VmbDali(Module):
751
769
  self,
752
770
  module_address: int,
753
771
  module_type: int,
754
- module_data: dict,
755
772
  serial: int | None = None,
756
773
  memorymap: int | None = None,
757
774
  build_year: int | None = None,
@@ -761,7 +778,6 @@ class VmbDali(Module):
761
778
  super().__init__(
762
779
  module_address,
763
780
  module_type,
764
- module_data,
765
781
  serial,
766
782
  memorymap,
767
783
  build_year,
@@ -770,8 +786,10 @@ class VmbDali(Module):
770
786
  )
771
787
  self.group_members: dict[int, set[int]] = {}
772
788
 
789
+ def get_initial_timeout(self) -> int:
790
+ return 100000
791
+
773
792
  async def _load_default_channels(self) -> None:
774
- await super().load()
775
793
  for chan in range(1, 64 + 1):
776
794
  self._channels[chan] = Channel(
777
795
  self, chan, "placeholder", True, self._writer, self._address
@@ -854,7 +872,7 @@ class VmbDali(Module):
854
872
  else:
855
873
  return await super().on_message(message)
856
874
 
857
- self._cache()
875
+ await self._cache()
858
876
 
859
877
  async def _request_channel_name(self) -> None:
860
878
  # Channel names are requested after channel scan
@@ -0,0 +1,50 @@
1
+ {
2
+ "Channels": {
3
+ "01": {
4
+ "Editable": "yes",
5
+ "Name": "Push button 1",
6
+ "Type": "Button"
7
+ },
8
+ "02": {
9
+ "Editable": "yes",
10
+ "Name": "Push button 2",
11
+ "Type": "Button"
12
+ },
13
+ "03": {
14
+ "Editable": "yes",
15
+ "Name": "Push button 3",
16
+ "Type": "Button"
17
+ },
18
+ "04": {
19
+ "Editable": "yes",
20
+ "Name": "Push button 4",
21
+ "Type": "Button"
22
+ },
23
+ "05": {
24
+ "Editable": "yes",
25
+ "Name": "Push button 5",
26
+ "Type": "Button"
27
+ },
28
+ "06": {
29
+ "Editable": "yes",
30
+ "Name": "Push button 6",
31
+ "Type": "Button"
32
+ },
33
+ "07": {
34
+ "Editable": "yes",
35
+ "Name": "Push button 7",
36
+ "Type": "Button"
37
+ },
38
+ "08": {
39
+ "Editable": "yes",
40
+ "Name": "Push button 8",
41
+ "Type": "Button"
42
+ },
43
+ "96": {
44
+ "Name": "SelectedProgram",
45
+ "Type": "SelectedProgram"
46
+ }
47
+ },
48
+ "Info": "8-Channel Push Button Module",
49
+ "Type": "VMB8PB"
50
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "Channels": {
3
+ "01": {
4
+ "Editable": "yes",
5
+ "Name": "Relay",
6
+ "Type": "Relay"
7
+ }
8
+ },
9
+ "Info": "Relay Module",
10
+ "Type": "VMB1RY"
11
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "ChannelNumbers": {
3
+ "Name": {
4
+ "Map": {
5
+ "03": "01"
6
+ }
7
+ }
8
+ },
9
+ "Channels": {
10
+ "01": {
11
+ "Editable": "yes",
12
+ "Name": "Blind",
13
+ "Type": "Blind"
14
+ }
15
+ },
16
+ "Info": "Blind Control Module",
17
+ "Type": "VMB1BL"
18
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "Channels": {
3
+ "01": {
4
+ "Editable": "yes",
5
+ "Name": "Push button 1",
6
+ "Type": "Button"
7
+ },
8
+ "02": {
9
+ "Editable": "yes",
10
+ "Name": "Push button 2",
11
+ "Type": "Button"
12
+ },
13
+ "03": {
14
+ "Editable": "yes",
15
+ "Name": "Push button 3",
16
+ "Type": "Button"
17
+ },
18
+ "04": {
19
+ "Editable": "yes",
20
+ "Name": "Push button 4",
21
+ "Type": "Button"
22
+ },
23
+ "05": {
24
+ "Editable": "yes",
25
+ "Name": "Push button 5",
26
+ "Type": "Button"
27
+ },
28
+ "06": {
29
+ "Editable": "yes",
30
+ "Name": "Push button 6",
31
+ "Type": "Button"
32
+ }
33
+ },
34
+ "Info": "6-Channel Input Module",
35
+ "Type": "VMB6IN"
36
+ }
@@ -0,0 +1,101 @@
1
+ {
2
+ "Channels": {
3
+ "01": {
4
+ "Editable": "yes",
5
+ "Name": "Dimmer 1",
6
+ "Type": "Dimmer"
7
+ },
8
+ "02": {
9
+ "Editable": "yes",
10
+ "Name": "Dimmer 2",
11
+ "Type": "Dimmer"
12
+ },
13
+ "03": {
14
+ "Editable": "yes",
15
+ "Name": "Dimmer 3",
16
+ "Type": "Dimmer"
17
+ },
18
+ "04": {
19
+ "Editable": "yes",
20
+ "Name": "Dimmer 4",
21
+ "Type": "Dimmer"
22
+ },
23
+ "96": {
24
+ "Name": "SelectedProgram",
25
+ "Type": "SelectedProgram"
26
+ }
27
+ },
28
+ "Memory": {
29
+ "Address": {
30
+ "062C": { "ModuleName": "0:Start" },
31
+ "062D": { "ModuleName": "1" },
32
+ "062E": { "ModuleName": "2" },
33
+ "062F": { "ModuleName": "3" },
34
+ "0630": { "ModuleName": "4" },
35
+ "0631": { "ModuleName": "5" },
36
+ "0632": { "ModuleName": "6" },
37
+ "0633": { "ModuleName": "7" },
38
+ "0634": { "ModuleName": "8" },
39
+ "0635": { "ModuleName": "9" },
40
+ "0636": { "ModuleName": "10" },
41
+ "0637": { "ModuleName": "11" },
42
+ "0638": { "ModuleName": "12" },
43
+ "0639": { "ModuleName": "13" },
44
+ "063A": { "ModuleName": "14" },
45
+ "063B": { "ModuleName": "15" },
46
+ "063C": { "ModuleName": "16" },
47
+ "063D": { "ModuleName": "17" },
48
+ "063E": { "ModuleName": "18" },
49
+ "063F": { "ModuleName": "19" },
50
+ "0640": { "ModuleName": "20" },
51
+ "0641": { "ModuleName": "21" },
52
+ "0642": { "ModuleName": "22" },
53
+ "0643": { "ModuleName": "23" },
54
+ "0644": { "ModuleName": "24" },
55
+ "0645": { "ModuleName": "25" },
56
+ "0646": { "ModuleName": "26" },
57
+ "0647": { "ModuleName": "27" },
58
+ "0648": { "ModuleName": "28" },
59
+ "0649": { "ModuleName": "29" },
60
+ "064A": { "ModuleName": "30" },
61
+ "064B": { "ModuleName": "31" },
62
+ "064C": { "ModuleName": "32" },
63
+ "064D": { "ModuleName": "33" },
64
+ "064E": { "ModuleName": "34" },
65
+ "064F": { "ModuleName": "35" },
66
+ "0650": { "ModuleName": "36" },
67
+ "0651": { "ModuleName": "37" },
68
+ "0652": { "ModuleName": "38" },
69
+ "0653": { "ModuleName": "39" },
70
+ "0654": { "ModuleName": "40" },
71
+ "0655": { "ModuleName": "41" },
72
+ "0656": { "ModuleName": "42" },
73
+ "0657": { "ModuleName": "43" },
74
+ "0658": { "ModuleName": "44" },
75
+ "0659": { "ModuleName": "45" },
76
+ "065A": { "ModuleName": "46" },
77
+ "065B": { "ModuleName": "47" },
78
+ "065C": { "ModuleName": "48" },
79
+ "065D": { "ModuleName": "49" },
80
+ "065E": { "ModuleName": "50" },
81
+ "065F": { "ModuleName": "51" },
82
+ "0660": { "ModuleName": "52" },
83
+ "0661": { "ModuleName": "53" },
84
+ "0662": { "ModuleName": "54" },
85
+ "0663": { "ModuleName": "55" },
86
+ "0664": { "ModuleName": "55" },
87
+ "0665": { "ModuleName": "56" },
88
+ "0666": { "ModuleName": "57" },
89
+ "0667": { "ModuleName": "58" },
90
+ "0668": { "ModuleName": "59" },
91
+ "0669": { "ModuleName": "60" },
92
+ "066A": { "ModuleName": "61" },
93
+ "066B": { "ModuleName": "62" },
94
+ "066C": { "ModuleName": "63" },
95
+ "066D": { "ModuleName": "64:save" }
96
+ },
97
+ "ModuleName": "062C-32;064D-32"
98
+ },
99
+ "Info": "4 channel led PWM dimmer module",
100
+ "Type": "VMB4LEDPWM-20"
101
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "Channels": {
3
+ "01": {
4
+ "Editable": "yes",
5
+ "Name": "Dimmer",
6
+ "Type": "Dimmer"
7
+ }
8
+ },
9
+ "Info": "Dimmer module",
10
+ "Type": "VMB1DM"
11
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "Channels": {
3
+ "01": {
4
+ "Editable": "yes",
5
+ "Name": "Relay 1",
6
+ "Type": "Relay"
7
+ },
8
+ "02": {
9
+ "Editable": "yes",
10
+ "Name": "Relay 2",
11
+ "Type": "Relay"
12
+ },
13
+ "03": {
14
+ "Editable": "yes",
15
+ "Name": "Relay 3",
16
+ "Type": "Relay"
17
+ },
18
+ "04": {
19
+ "Editable": "yes",
20
+ "Name": "Relay 4",
21
+ "Type": "Relay"
22
+ }
23
+ },
24
+ "Info": "4 channel relay module",
25
+ "Type": "VMB4RY"
26
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "ChannelNumbers": {
3
+ "Name": {
4
+ "Map": {
5
+ "03": "01",
6
+ "0C": "02"
7
+ }
8
+ }
9
+ },
10
+ "Channels": {
11
+ "01": {
12
+ "Editable": "yes",
13
+ "Name": "Blind 1",
14
+ "Type": "Blind"
15
+ },
16
+ "02": {
17
+ "Editable": "yes",
18
+ "Name": "Blind 2",
19
+ "Type": "Blind"
20
+ }
21
+ },
22
+ "Info": "2-channel Blind Control Module",
23
+ "Type": "VMB2BL"
24
+ }
@@ -0,0 +1,46 @@
1
+ {
2
+ "Channels": {
3
+ "01": {
4
+ "Editable": "yes",
5
+ "Name": "Push button 1",
6
+ "Type": "Button"
7
+ },
8
+ "02": {
9
+ "Editable": "yes",
10
+ "Name": "Push button 2",
11
+ "Type": "Button"
12
+ },
13
+ "03": {
14
+ "Editable": "yes",
15
+ "Name": "Push button 3",
16
+ "Type": "Button"
17
+ },
18
+ "04": {
19
+ "Editable": "yes",
20
+ "Name": "Push button 4",
21
+ "Type": "Button"
22
+ },
23
+ "05": {
24
+ "Editable": "yes",
25
+ "Name": "Push button 5",
26
+ "Type": "Button"
27
+ },
28
+ "06": {
29
+ "Editable": "yes",
30
+ "Name": "Push button 6",
31
+ "Type": "Button"
32
+ },
33
+ "07": {
34
+ "Editable": "yes",
35
+ "Name": "Push button 7",
36
+ "Type": "Button"
37
+ },
38
+ "08": {
39
+ "Editable": "yes",
40
+ "Name": "Push button 8",
41
+ "Type": "Button"
42
+ }
43
+ },
44
+ "Info": "Infrared remote control receiver module",
45
+ "Type": "VMB8IR"
46
+ }
@@ -0,0 +1,46 @@
1
+ {
2
+ "Channels": {
3
+ "01": {
4
+ "Editable": "yes",
5
+ "Name": "Push button 1",
6
+ "Type": "Button"
7
+ },
8
+ "02": {
9
+ "Editable": "yes",
10
+ "Name": "Push button 2",
11
+ "Type": "Button"
12
+ },
13
+ "03": {
14
+ "Editable": "yes",
15
+ "Name": "Push button 3",
16
+ "Type": "Button"
17
+ },
18
+ "04": {
19
+ "Editable": "yes",
20
+ "Name": "Push button 4",
21
+ "Type": "Button"
22
+ },
23
+ "05": {
24
+ "Editable": "yes",
25
+ "Name": "Push button 5",
26
+ "Type": "Button"
27
+ },
28
+ "06": {
29
+ "Editable": "yes",
30
+ "Name": "Push button 6",
31
+ "Type": "Button"
32
+ },
33
+ "07": {
34
+ "Editable": "yes",
35
+ "Name": "Push button 7",
36
+ "Type": "Button"
37
+ },
38
+ "08": {
39
+ "Editable": "yes",
40
+ "Name": "Push button 8",
41
+ "Type": "Button"
42
+ }
43
+ },
44
+ "Info": "PUSH BUTTON AND TIMER PANEL",
45
+ "Type": "VMB4PD"
46
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "Channels": {
3
+ "01": {
4
+ "Editable": "yes",
5
+ "Name": "Temperature",
6
+ "Type": "Temperature"
7
+ }
8
+ },
9
+ "Info": "Temperature Sensor Module",
10
+ "TemperatureChannel": "01",
11
+ "Thermostat": "yes",
12
+ "Type": "VMB1TS"
13
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "Info": "TemperatureController Module",
3
+ "Memory": {
4
+ "Address": {
5
+ "00F0": { "ModuleName": "0:Start" },
6
+ "00F1": { "ModuleName": "1" },
7
+ "00F2": { "ModuleName": "2" },
8
+ "00F3": { "ModuleName": "3" },
9
+ "00F4": { "ModuleName": "4" },
10
+ "00F5": { "ModuleName": "5" },
11
+ "00F6": { "ModuleName": "6" },
12
+ "00F7": { "ModuleName": "7" },
13
+ "00F8": { "ModuleName": "8" },
14
+ "00F9": { "ModuleName": "9" },
15
+ "00FA": { "ModuleName": "10" },
16
+ "00FB": { "ModuleName": "11" },
17
+ "00FC": { "ModuleName": "12" },
18
+ "00FD": { "ModuleName": "13" },
19
+ "00FE": { "ModuleName": "14" },
20
+ "00FF": { "ModuleName": "16:Save" }
21
+ },
22
+ "ModuleName": "00F0-16"
23
+ },
24
+ "Type": "VMB1TC"
25
+ }