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

Potentially problematic release.


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

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: velbus-aio
3
- Version: 2024.10.0
3
+ Version: 2024.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
@@ -18,10 +18,11 @@ Classifier: Programming Language :: Python :: 3.9
18
18
  Classifier: Programming Language :: Python :: 3.10
19
19
  Classifier: Programming Language :: Python :: 3.11
20
20
  Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
21
22
  Classifier: Topic :: Home Automation
22
23
  Classifier: Topic :: Software Development :: Libraries
23
24
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
- Requires-Python: >=3.8.0
25
+ Requires-Python: >=3.9.0
25
26
  Description-Content-Type: text/markdown
26
27
  License-File: LICENSE
27
28
  Requires-Dist: pyserial>=3.5.0
@@ -31,6 +32,13 @@ Requires-Dist: aiofile
31
32
 
32
33
  ![CI](https://github.com/Cereal2nd/velbus-aio/actions/workflows/main.yml/badge.svg)
33
34
  [![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)
35
+ [![PyPI version](https://badge.fury.io/py/velbus-aio.svg)](https://badge.fury.io/py/velbus-aio)
36
+ [![Supported Python versions](https://img.shields.io/pypi/pyversions/velbus-aio.svg)](https://github.com/Cereal2nd/velbus-aio)
37
+ [![License](https://img.shields.io/github/license/Cereal2nd/velbus-aio)](https://github.com/cereal2nd/velbus-aio/blob/master/LICENSE)
38
+ [![Downloads](https://pepy.tech/badge/velbus-aio)](https://pepy.tech/project/velbus-aio)
39
+ [![Downloads](https://pepy.tech/badge/velbus-aio/month)](https://pepy.tech/project/velbus-aio)
40
+ [![Downloads](https://pepy.tech/badge/velbus-aio/week)](https://pepy.tech/project/velbus-aio)
41
+ [![Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
34
42
 
35
43
  > This project requires financial support, but it is free for you to use. You can join those helping to keep the lights on at:
36
44
  >
@@ -1,35 +1,35 @@
1
1
  velbusaio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- velbusaio/channels.py,sha256=DRA06Qn3mOPzLoXPkV0-mRONTBza0ooE8ERqK98fxGA,22911
3
- velbusaio/command_registry.py,sha256=arn5x2Don1xKKiLxRAhQlD9bpYbr8UbfO0bi-43DpEM,5163
2
+ velbusaio/channels.py,sha256=38AgefFFXJpA9v4ZrRAvoHz3UKuGKEVUgbyYiY1mkho,23278
3
+ velbusaio/command_registry.py,sha256=izhVz8jR37F-L10bxL4ObtZM3kat9AZqVItocbok9_w,5186
4
4
  velbusaio/const.py,sha256=aHClMaMS6NINTCrjeRwLbVzdvS91VgFKM8j61ks5tn0,1862
5
5
  velbusaio/controller.py,sha256=vKoDfEDlQF_L0ZrXU0L4yD61Adxr_qDma-e-dgWYz1w,7607
6
6
  velbusaio/discovery.py,sha256=Px6qoZl4QhF17aMz6JxstCORBpLzZGWEK9h4Vyvg57o,1649
7
7
  velbusaio/exceptions.py,sha256=FHkXaM3dK5Gkk-QGAf9dLE3FPlCU2FRZWUyY-4KRNnA,515
8
- velbusaio/handler.py,sha256=OqMagEnNhxnn7ttA4Ob9dkSDEcNMTkd4zQDc6mn_E-M,11445
8
+ velbusaio/handler.py,sha256=gkRikfrTzekL0hFQSUV0AjVuMoUY1DNONEhbRBKyRko,11901
9
9
  velbusaio/helpers.py,sha256=iqpoereRH4JY5WAkozIqWvXWyRmhko-J-UGXDylFyEM,2537
10
10
  velbusaio/message.py,sha256=_MRuI4XnMcqeduCDJ3AwhAPL1B8VMstFDnjjLo8QuxM,5018
11
- velbusaio/module.py,sha256=SrPU91eqkfxThRH-cds-lC_8ZMb975Inw7lkvBfEmNE,36021
11
+ velbusaio/module.py,sha256=FF_qi7ceg0bjdCJQFRiw4js9cvpTjhRPC75zvG0HTso,37185
12
12
  velbusaio/protocol.py,sha256=RIpdL0vPlL4qE4bC8sEZSD0SRS4tWtR9MdzjTPSd2zs,8002
13
13
  velbusaio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  velbusaio/raw_message.py,sha256=ODoTPVAvyXXQSMXxtQO1U5OxcoQ4W8JJN5fotEDGSTo,4690
15
15
  velbusaio/util.py,sha256=FW6YCiPYWOCgqHDs8-LbzME0h81mqftYVG0qqZ-oo7Y,1568
16
16
  velbusaio/messages/__init__.py,sha256=ZiApo-9boa5fcxzuaTH3dQ2m8nfTVjrG84pL5V6rFbg,5893
17
- velbusaio/messages/blind_status.py,sha256=yzjoYLBxH85tBjihiGzLqebRg1urz0obBA-3q1pqSCE,3418
17
+ velbusaio/messages/blind_status.py,sha256=q2CQgcU1ZsXMyjR2co8Eegj0LZRDfRqvpCTVvjovNWA,3432
18
18
  velbusaio/messages/bus_active.py,sha256=AB1mEvbMXRuOaC2CQ7hzKSLmbaJnyFqqXrARi-aSdtg,749
19
19
  velbusaio/messages/bus_error_counter_status.py,sha256=x0RIzil6IcXWq6GHEFYDkSAergNF51JQYyetDXjvvzY,1178
20
20
  velbusaio/messages/bus_error_counter_status_request.py,sha256=zjX3k8MKgR9FO253a7bIlO-ba6SHmLi2WZT6ayAicrw,703
21
21
  velbusaio/messages/bus_off.py,sha256=z0PmNZyTlwee6jXnzgK4zHhFvevAXNboDrEEQvyLLfc,679
22
- velbusaio/messages/channel_name_part1.py,sha256=_6zpf0niulSVKxr2F1eXXOyfX0159OtOJQyg5HUqQ8I,2883
23
- velbusaio/messages/channel_name_part2.py,sha256=gPg_wShY-PgIDUm7uLB8_6WoA8-RgbRFNhULvCvj9as,2858
24
- velbusaio/messages/channel_name_part3.py,sha256=AIc79eefKok7WwVYKZrwBTEHM1hyjTmqzWjpJquOAl8,2859
22
+ velbusaio/messages/channel_name_part1.py,sha256=zN3rRXBQDLtIwy1ZdQmzNQPWUo1GPf0BQtQzYfiEYdo,2904
23
+ velbusaio/messages/channel_name_part2.py,sha256=O1eS5Eh63GJjNJ0-Z1OMbhU0dc4dutcJ3jl-C49n8Ek,2879
24
+ velbusaio/messages/channel_name_part3.py,sha256=84tLU2ksldBj0ahKC44BJ3uUOU_uLQEjOuw4HNvO4oQ,2880
25
25
  velbusaio/messages/channel_name_request.py,sha256=t8Tpx9l4XLgF6cDwUylXk0r8vmNG2QrXJq9F4TwAaBg,2378
26
26
  velbusaio/messages/clear_led.py,sha256=AcGRCD0OdlHcFonvHA075nVwvOtZ6KfyjrXeE6A7DZA,912
27
27
  velbusaio/messages/counter_status.py,sha256=UgSRw-pipFb8C2DxauHw8Pjem1qTvzUFpiahui73-Is,1240
28
28
  velbusaio/messages/counter_status_request.py,sha256=VLFaI7MFnTCH1s8acfKlcAGscJElwxYRC56eT3bbB7Y,919
29
- velbusaio/messages/cover_down.py,sha256=tdjsRijrEa5oNBZk6uKWUK39k5gIjcWq0kgfOf4f1lQ,2552
30
- velbusaio/messages/cover_off.py,sha256=0RHAJb4et99yAoo8LD85Rzlnhrqr40Wjba-BhzHSr4o,2243
31
- velbusaio/messages/cover_position.py,sha256=PhRocdkbwf8CUfdL8-rZHEDFD2Z9u7DLZOpH3h6gAtg,1268
32
- velbusaio/messages/cover_up.py,sha256=P20AZx8qQScbyV0sxtZOlO03Q8pFO8NunpqIr4mZ6Lw,2547
29
+ velbusaio/messages/cover_down.py,sha256=0q805ghMmdeFbNLPXZ9TIqsn4QUiwaET4W6j0XEe58E,2566
30
+ velbusaio/messages/cover_off.py,sha256=kzzZKSXiLJJdrXPmIx0dFwR99j6PS6VVpmZp8BbrEY4,2257
31
+ velbusaio/messages/cover_position.py,sha256=_BgQz3DqZGirXDthj7xq72hxr51FYv2tyrdCMQkwzIY,1282
32
+ velbusaio/messages/cover_up.py,sha256=iFPCWuRhIc54oMQAFz5DZsUW23673_nNHoPFJC_HA_c,2561
33
33
  velbusaio/messages/dali_device_settings.py,sha256=KzJ7OFkFRPuCXSOThuplM48J_kH0I3RE82ZRCpmiqYA,4870
34
34
  velbusaio/messages/dali_device_settings_request.py,sha256=InTnrwLD7l9gCHXKlJ69FHMXcejtYMUZBtnffx9nDQU,1476
35
35
  velbusaio/messages/dali_dim_value_status.py,sha256=Kgtfb65HCku4OBm6uaxKFpK3VtlYaTemSjMhZqngqkY,1059
@@ -98,19 +98,19 @@ velbusaio/messages/write_module_address_and_serial_number.py,sha256=6y57j-md3btN
98
98
  velbusaio/module_spec/01.json,sha256=HgE7mouKohbnMbT_bPl1yo59py36daqyhyG5ZVVluzA,953
99
99
  velbusaio/module_spec/02.json,sha256=f5xCxEGlqu1lVdMBRu8IDXV1RMXNRgi0cDk_e24UhFc,158
100
100
  velbusaio/module_spec/03.json,sha256=a-nJbRjNfXpJsOAwGPkbQjJpF4QDBjj5N1HZezCWgnU,255
101
- velbusaio/module_spec/05.json,sha256=vhMw5m-9dlUSR6tbBFW9g7vYZHZytElDakPXL_ASubY,667
102
- velbusaio/module_spec/06.json,sha256=CA2ytfVrICIeIP2AWsYBThylN4hW5x5ez8578Ddaqrk,3138
101
+ velbusaio/module_spec/05.json,sha256=0m7xOx3l5Fo4cfC6EqRpAom3fzA_Zz4UCUgEcxLCpYI,823
102
+ velbusaio/module_spec/06.json,sha256=ADducc-VXAa5WMPKEQwRjAZuwfNPswy5RLAJulmCLnY,3242
103
103
  velbusaio/module_spec/07.json,sha256=YLR1SAcSM4PBdghWxKAhGGLomtB5tMWls7JNH7vVNzQ,161
104
- velbusaio/module_spec/08.json,sha256=d4-yNJtjwxyDJHrKzvxgEQt7Y0VyBQqL18Dz6FcglCg,443
104
+ velbusaio/module_spec/08.json,sha256=VxnheRrmMjvk208W2joPOUmi63e8HUximTpG8i62xfM,547
105
105
  velbusaio/module_spec/09.json,sha256=RDzASLWiILU7vNU5sBonI9DhHhiPGC-4NrWH6hp52qg,378
106
106
  velbusaio/module_spec/0A.json,sha256=N7eN0ovOGyWkmm1jkGli_0a1fVRN1cWmIFclHG_JzCU,880
107
107
  velbusaio/module_spec/0B.json,sha256=DDGF-3jGLRcsCgjBwbZdrHO9mUwTFJzLBdlA5bszsmY,868
108
108
  velbusaio/module_spec/0C.json,sha256=lohrBMeic48nV5sbLO8KuJpj2Yz1xUDDtIlYLA0PcEA,236
109
109
  velbusaio/module_spec/0E.json,sha256=Avb1lYqFZvCjWbrQpV9AmrOnrMquYiqIcE7y8SwDxMw,744
110
110
  velbusaio/module_spec/0F.json,sha256=589CrCMqI-8oJScbOX-PzXwQmpeZk9Ugv2RY6UQkM6M,176
111
- velbusaio/module_spec/10.json,sha256=7cjhUlMrJNugZViuG0GT06krB-m0jtlHVvAAn33ACjI,3116
112
- velbusaio/module_spec/11.json,sha256=cCTs3wHrSY4DzHcWTWJFGlf9Wpie37633T5YOScyvKE,3113
113
- velbusaio/module_spec/12.json,sha256=RvNW9OC50EETMznnqSJBFrEoGlU1dG18NhEGY2IVrKU,1763
111
+ velbusaio/module_spec/10.json,sha256=Jf4mYqelpZHcnUqwKH1OXeFUrrtUpvyxn6Ef7LT-ISc,3220
112
+ velbusaio/module_spec/11.json,sha256=RGpdP6ajCRtePzxgP4LgK1_tWQ6EPfwahE8jaJZJim8,3217
113
+ velbusaio/module_spec/12.json,sha256=En3J8Ju3d_G7xVo2zHy_sTWdBjYNollFwsZpeSo7s2o,1867
114
114
  velbusaio/module_spec/13.json,sha256=reXGXbaTfVVmLekrXHlfzjsV424bb0ozG7q-PxDv27U,68
115
115
  velbusaio/module_spec/14.json,sha256=ym2T2jCds-lC7QBZr7mqb0L9PlSmQflwpFnlEDxByjk,161
116
116
  velbusaio/module_spec/15.json,sha256=VDkI3bJRZgpfAsCiEzRJls7Hj7spmaKZ6XR8TjyymAQ,2698
@@ -124,7 +124,7 @@ velbusaio/module_spec/1E.json,sha256=tLisdUarUyS8Fk9oDsQy7TjmlkGs-vHrA8QbU6F7Pz4
124
124
  velbusaio/module_spec/1F.json,sha256=oFb-HIrLBhIr_sPX8ZsIzOtpi_nHyfLkfoP1P0Ewg88,4386
125
125
  velbusaio/module_spec/20.json,sha256=ysngPSzynugxFZGd5bZD76nN1ZbjyiHiA1-HReJYm-Y,4393
126
126
  velbusaio/module_spec/21.json,sha256=Sj-oc76Oi_KAEuwnaLHL8GsbR_ClZHW0yPiD0D7vIOA,6815
127
- velbusaio/module_spec/22.json,sha256=u09uXlE65VIx4iALJo5SUF1hK3fgaOhuw4J1ighFXDM,6150
127
+ velbusaio/module_spec/22.json,sha256=hG1DWaKtqbrgU-cBEI1gyTMIDIqxvPQYpN26541IODQ,6332
128
128
  velbusaio/module_spec/23.json,sha256=3jCtHfqaqHNVZ6QyG499ZKaIQyTqmTxqqLujmgTW4RY,3593
129
129
  velbusaio/module_spec/25.json,sha256=H87YnDGlgnEJzokWZkrfDtGGE-3JRJEYDRnKTlL69eE,24
130
130
  velbusaio/module_spec/28.json,sha256=FHyi0Ax7ve6k-e6vE8oTXsfLT7OqIMTXBtkhU3C7304,7712
@@ -137,7 +137,7 @@ velbusaio/module_spec/2E.json,sha256=VA1J1Sevkgnv-OA1T-mFSeWEg4hTq1LMydryq9S7Dq0
137
137
  velbusaio/module_spec/2F.json,sha256=95h-w7HA_xQpMCZRyFvPjVQP3mCa9AZM4zFNzTSi7vY,3595
138
138
  velbusaio/module_spec/30.json,sha256=WJsy2Uw4oANze8h4eMJilIy5JDoy8yzsm2MJtUMiH9k,871
139
139
  velbusaio/module_spec/31.json,sha256=o9AqfLTdjQkSd77t97A-ttQxWLEJVyKG22Ie50vsRIY,8291
140
- velbusaio/module_spec/32.json,sha256=kZXAfVBSwYf6w9fUfo17-68lpQkM6toYTx6P_aKD7-g,6102
140
+ velbusaio/module_spec/32.json,sha256=otyNI5_SyZW76TUTz0YwA6CIbUKpZk_Y2RFHeCTgPeA,6310
141
141
  velbusaio/module_spec/33.json,sha256=7uEWgRW9_MOEtbJKxA6GPR-sWR-OMYp6snLoTgVzeyQ,4119
142
142
  velbusaio/module_spec/34.json,sha256=h7jjGfZboTC3awV-RhCNggsZn-pz9ZB-lE9Z0SBPsJE,2897
143
143
  velbusaio/module_spec/35.json,sha256=evnYDd_jX2CsvrLtCDrE1Dml5eO7zCaYauoYMAarED0,2894
@@ -157,13 +157,13 @@ velbusaio/module_spec/42.json,sha256=0zSbvyG6I2O3XAhv28R_v0IQvd_h4xLQIJDXVInYR6g
157
157
  velbusaio/module_spec/43.json,sha256=y_e_hGjiUlnNj_Dnw_2pKvrutSlp-mU6OTym9KVPTLQ,178
158
158
  velbusaio/module_spec/44.json,sha256=tYq0Y_dju2VztBX63LdorK3TEmMv0HlfYO_s9cZYJQ8,474
159
159
  velbusaio/module_spec/45.json,sha256=aAlc4ANbdDXJs7YhXm06te-gN43uaL80DS9qoinS2cQ,71
160
- velbusaio/module_spec/48.json,sha256=ejmocqJuZgGg5KWAIKD5m8Msaz3hfdrN2Iy5_mHAXF4,3119
161
- velbusaio/module_spec/49.json,sha256=BBjSLnQ8sFeGgfuUVbigFAZX7wvh5dxRVdZnwvU2doQ,3116
162
- velbusaio/module_spec/4A.json,sha256=1E2BqC7aOC7sC22g9Ep3XPC8Lmc6__JD8yKPhESzRuk,63
163
- velbusaio/module_spec/4B.json,sha256=ZDpirjZS8teOrfV1mYIyG-_9PMeeHr_736hz-P_EO2U,3403
160
+ velbusaio/module_spec/48.json,sha256=WfumNT6fFZxPWV2LjPAk58pcTpL8Phc4Aytglrsed_E,3223
161
+ velbusaio/module_spec/49.json,sha256=5Qu1mKtO_Qemvs11e2U_m-vg_QgWgu96IK2dy1-yaWI,3220
162
+ velbusaio/module_spec/4A.json,sha256=YEa9airi4DpJcKAkHuienkIzRR-AzGJZeQNuuzR0l2Q,2720
163
+ velbusaio/module_spec/4B.json,sha256=2OI1pysdFIsJv1R7M0KtVA4OvYAZFUhqQWAt2h_h_Tc,3611
164
164
  velbusaio/module_spec/4C.json,sha256=l1oMv_JnUEpEIFY1GZMUeXDWPjbUz98tZZ-4VsGxhsM,3464
165
165
  velbusaio/module_spec/4D.json,sha256=9Lho_3m4H5SBhx363zCDN3HnA8zLlygIi0EgXyOolF8,3213
166
- velbusaio/module_spec/4E.json,sha256=5OfV91FVLz6FHwLN34FvkGtBbg5cGeUdXxTdddB2RF0,8675
166
+ velbusaio/module_spec/4E.json,sha256=wDEjpA6nMdV2WUndz2WDdzea3WTcMwMVV6sT_RR2pz4,8883
167
167
  velbusaio/module_spec/4F.json,sha256=ePImVotWcTbCvJ5xYN3hBqwZkGoRFEgFJV4AwXg474A,1631
168
168
  velbusaio/module_spec/50.json,sha256=xmchRD1S_Z4j3aLEafYsAZtW7bOWpWCWvUk-8SU3Zww,1628
169
169
  velbusaio/module_spec/51.json,sha256=8xrdwniKVokfLK9k44JIBr_xJ4H0yh8pN1SuX1-fOc0,1622
@@ -176,8 +176,8 @@ velbusaio/module_spec/5A.json,sha256=V_yhMdGrNxFE7J_CXJmngN-yYBz2V_tqXkKCCwI7HCE
176
176
  velbusaio/module_spec/5C.json,sha256=yw_XlccuFp-buRL_NXThwQLwblVRa0diLpUDm9Exrg0,1586
177
177
  velbusaio/module_spec/5F.json,sha256=ebSwLMUW5A4LCRGOrF-vwxSVvrWZMNUWz10Xrmz7SwM,1259
178
178
  velbusaio/module_spec/broadcast.json,sha256=L2Sc9FhZ7NOuu7K5g5jAhvUQGDP6a2CKrg-uWh_v-sA,2250
179
- velbus_aio-2024.10.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
180
- velbus_aio-2024.10.0.dist-info/METADATA,sha256=OXylu4UVsk3uUjo0d5zmOUnAOWlo_lkDy-OCVLuDRqw,3754
181
- velbus_aio-2024.10.0.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
182
- velbus_aio-2024.10.0.dist-info/top_level.txt,sha256=W0-lSOwD23mm8FqaIe9vY20fKicBMIdUVjF-zmfxRnY,15
183
- velbus_aio-2024.10.0.dist-info/RECORD,,
179
+ velbus_aio-2024.11.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
180
+ velbus_aio-2024.11.0.dist-info/METADATA,sha256=bBUEac4aHNH5XiMhRVlfAmCAvv54bDFg05c5lcV0mYM,4541
181
+ velbus_aio-2024.11.0.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
182
+ velbus_aio-2024.11.0.dist-info/top_level.txt,sha256=W0-lSOwD23mm8FqaIe9vY20fKicBMIdUVjF-zmfxRnY,15
183
+ velbus_aio-2024.11.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.2.0)
2
+ Generator: setuptools (75.5.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
velbusaio/channels.py CHANGED
@@ -38,12 +38,14 @@ class Channel:
38
38
  num: int,
39
39
  name: str,
40
40
  nameEditable: bool,
41
+ subDevice: bool,
41
42
  writer: Callable[[Message], Awaitable[None]],
42
43
  address: int,
43
44
  ):
44
45
  self._num = num
45
46
  self._module = module
46
47
  self._name = name
48
+ self._subDevice = subDevice
47
49
  if not nameEditable:
48
50
  self._is_loaded = True
49
51
  else:
@@ -80,6 +82,8 @@ class Channel:
80
82
  return self._num
81
83
 
82
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}"
83
87
  return f"{self._module.get_name()} ({self._module.get_type_name()})"
84
88
 
85
89
  def is_loaded(self) -> bool:
@@ -94,6 +98,9 @@ class Channel:
94
98
  def is_temperature(self) -> bool:
95
99
  return False
96
100
 
101
+ def is_sub_device(self) -> bool:
102
+ return self._subDevice
103
+
97
104
  def get_name(self) -> str:
98
105
  """
99
106
  :return: the channel name
@@ -137,7 +144,11 @@ class Channel:
137
144
  }
138
145
 
139
146
  def to_cache(self) -> dict:
140
- dst = {"name": self._name, "type": type(self).__name__}
147
+ dst = {
148
+ "name": self._name,
149
+ "type": type(self).__name__,
150
+ "subdevice": self._subDevice,
151
+ }
141
152
  if hasattr(self, "_Unit"):
142
153
  dst["Unit"] = self._Unit
143
154
  return dst
@@ -448,11 +459,12 @@ class Dimmer(Channel):
448
459
  num: int,
449
460
  name: str,
450
461
  nameEditable: bool,
462
+ subDevice: bool,
451
463
  writer: Callable[[Message], Awaitable[None]],
452
464
  address: int,
453
465
  slider_scale: int = 100,
454
466
  ):
455
- super().__init__(module, num, name, nameEditable, writer, address)
467
+ super().__init__(module, num, name, nameEditable, subDevice, writer, address)
456
468
 
457
469
  self.slider_scale = slider_scale
458
470
  # VMB4DC has dim values 0(off), 1-99(dimmed), 100(full on)
@@ -74,6 +74,7 @@ MODULE_DIRECTORY = {
74
74
  0x4B: "VMB8DC-20",
75
75
  0x4C: "VMB6PB-20",
76
76
  0x4D: "VMBPIR-20",
77
+ 0x4E: "VMB8IN-20",
77
78
  0x4F: "VMBEL1-20",
78
79
  0x50: "VMBEL2-20",
79
80
  0x51: "VMBEL4-20",
velbusaio/handler.py CHANGED
@@ -6,14 +6,15 @@ Velbus packet handler
6
6
  from __future__ import annotations
7
7
 
8
8
  import asyncio
9
+ import importlib.resources
9
10
  import json
10
11
  import logging
11
12
  import os
12
13
  import pathlib
13
14
  import pprint
15
+ import sys
14
16
  from typing import TYPE_CHECKING, Awaitable, Callable
15
17
 
16
- import pkg_resources
17
18
  from aiofile import async_open
18
19
 
19
20
  from velbusaio.command_registry import commandRegistry
@@ -53,10 +54,21 @@ class PacketHandler:
53
54
  self._scan_delay_msec = 0
54
55
 
55
56
  async def read_protocol_data(self):
56
- async with async_open(
57
- pkg_resources.resource_filename(__name__, "module_spec/broadcast.json")
58
- ) as protocol_file:
59
- self.broadcast = json.loads(await protocol_file.read())
57
+ if sys.version_info >= (3, 13):
58
+ with importlib.resources.path(
59
+ __name__, "module_spec/broadcast.json"
60
+ ) as fspath:
61
+ async with async_open(fspath) as protocol_file:
62
+ self.broadcast = json.loads(await protocol_file.read())
63
+ else:
64
+ async with async_open(
65
+ str(
66
+ importlib.resources.files(__name__.split(".")[0]).joinpath(
67
+ "module_spec/broadcast.json"
68
+ )
69
+ )
70
+ ) as protocol_file:
71
+ self.broadcast = json.loads(await protocol_file.read())
60
72
 
61
73
  def empty_cache(self) -> bool:
62
74
  if (
@@ -13,7 +13,7 @@ COMMAND_CODE = 0xEC
13
13
  DSTATUS = {0: "off", 1: "up", 2: "down"}
14
14
 
15
15
 
16
- @register(COMMAND_CODE, ["VMB1BLE", "VMB2BLE", "VMB1BLS"])
16
+ @register(COMMAND_CODE, ["VMB1BLE", "VMB2BLE", "VMB1BLS", "VMB2BLE-10"])
17
17
  class BlindStatusNgMessage(Message):
18
18
  """
19
19
  sent by: VMB2BLE
@@ -84,6 +84,7 @@ class ChannelNamePart1Message(Message):
84
84
  "VMBGP4PIR-20",
85
85
  "VMB4LEDPWM-20",
86
86
  "VMB8DC-20",
87
+ "VMB8IN-20",
87
88
  ],
88
89
  )
89
90
  class ChannelNamePart1Message2(ChannelNamePart1Message):
@@ -83,6 +83,7 @@ class ChannelNamePart2Message(Message):
83
83
  "VMBEL4PIR-20",
84
84
  "VMBGP4PIR-20",
85
85
  "VMB8DC-20",
86
+ "VMB8IN-20",
86
87
  ],
87
88
  )
88
89
  class ChannelNamePart2Message2(ChannelNamePart2Message):
@@ -83,6 +83,7 @@ class ChannelNamePart3Message(Message):
83
83
  "VMBEL4PIR-20",
84
84
  "VMBGP4PIR-20",
85
85
  "VMB8DC-20",
86
+ "VMB8IN-20",
86
87
  ],
87
88
  )
88
89
  class ChannelNamePart3Message2(ChannelNamePart3Message):
@@ -12,7 +12,7 @@ from velbusaio.message import Message
12
12
  COMMAND_CODE = 0x06
13
13
 
14
14
 
15
- @register(COMMAND_CODE, ["VMB1BLE", "VMB2BLE", "VMB1BLS"])
15
+ @register(COMMAND_CODE, ["VMB1BLE", "VMB2BLE", "VMB1BLS", "VMB2BLE-10"])
16
16
  class CoverDownMessage(Message):
17
17
  """
18
18
  sent by:
@@ -10,7 +10,7 @@ from velbusaio.message import Message
10
10
  COMMAND_CODE = 0x04
11
11
 
12
12
 
13
- @register(COMMAND_CODE, ["VMB1BLE", "VMB2BLE", "VMB1BLS"])
13
+ @register(COMMAND_CODE, ["VMB1BLE", "VMB2BLE", "VMB1BLS", "VMB2BLE-10"])
14
14
  class CoverOffMessage(Message):
15
15
  """
16
16
  sent by:
@@ -10,7 +10,7 @@ from velbusaio.message import Message
10
10
  COMMAND_CODE = 0x1C
11
11
 
12
12
 
13
- @register(COMMAND_CODE, ["VMB1BLE", "VMB2BLE", "VMB1BLS"])
13
+ @register(COMMAND_CODE, ["VMB1BLE", "VMB2BLE", "VMB1BLS", "VMB2BLE-10"])
14
14
  class CoverPosMessage(Message):
15
15
  """
16
16
  sent by:
@@ -12,7 +12,7 @@ from velbusaio.message import Message
12
12
  COMMAND_CODE = 0x05
13
13
 
14
14
 
15
- @register(COMMAND_CODE, ["VMB1BLE", "VMB2BLE", "VMB1BLS"])
15
+ @register(COMMAND_CODE, ["VMB1BLE", "VMB2BLE", "VMB1BLS", "VMB2BLE-10"])
16
16
  class CoverUpMessage(Message):
17
17
  """
18
18
  sent by:
velbusaio/module.py CHANGED
@@ -4,6 +4,7 @@ This represents a velbus module
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
+ import importlib.resources
7
8
  import json
8
9
  import logging
9
10
  import os
@@ -12,7 +13,6 @@ import struct
12
13
  import sys
13
14
  from typing import Awaitable, Callable
14
15
 
15
- import pkg_resources
16
16
  from aiofile import async_open
17
17
 
18
18
  from velbusaio.channels import (
@@ -166,12 +166,21 @@ class Module:
166
166
  self._log = logging.getLogger("velbus-module")
167
167
  # load the protocol data
168
168
  try:
169
- async with async_open(
170
- pkg_resources.resource_filename(
169
+ if sys.version_info >= (3, 13):
170
+ with importlib.resources.path(
171
171
  __name__, f"module_spec/{h2(self._type)}.json"
172
- )
173
- ) as protocol_file:
174
- self._data = json.loads(await protocol_file.read())
172
+ ) as fspath:
173
+ async with async_open(fspath) as protocol_file:
174
+ self._data = json.loads(await protocol_file.read())
175
+ else:
176
+ async with async_open(
177
+ str(
178
+ importlib.resources.files(__name__.split(".")[0]).joinpath(
179
+ f"module_spec/{h2(self._type)}.json"
180
+ )
181
+ )
182
+ ) as protocol_file:
183
+ self._data = json.loads(await protocol_file.read())
175
184
  self._log.debug(f"Module spec {h2(self._type)} loaded")
176
185
  except FileNotFoundError:
177
186
  self._log.warning(f"No module spec for {h2(self._type)}")
@@ -204,8 +213,8 @@ class Module:
204
213
 
205
214
  async def _cache(self) -> None:
206
215
  cfile = pathlib.Path(f"{self._cache_dir}/{self._address}.json")
207
- with open(cfile, "w") as fl:
208
- json.dump(self.to_cache(), fl, indent=4)
216
+ async with async_open(cfile, "w") as fl:
217
+ await fl.write(json.dumps(self.to_cache(), indent=4))
209
218
 
210
219
  def __getstate__(self) -> dict:
211
220
  d = self.__dict__
@@ -569,6 +578,10 @@ class Module:
569
578
  if "channels" in cache:
570
579
  for num, chan in cache["channels"].items():
571
580
  self._channels[int(num)]._name = chan["name"]
581
+ if "sub_device" in chan:
582
+ self._channels[int(num)]._sub_device = chan["sub_device"]
583
+ else:
584
+ self._channels[int(num)]._sub_device = False
572
585
  if "Unit" in chan:
573
586
  self._channels[int(num)]._Unit = chan["Unit"]
574
587
  self._channels[int(num)]._is_loaded = True
@@ -746,11 +759,20 @@ class Module:
746
759
 
747
760
  for chan, chan_data in self._data["Channels"].items():
748
761
  edit = True
762
+ sub = True
749
763
  if "Editable" not in chan_data or chan_data["Editable"] != "yes":
750
764
  edit = False
765
+ if "Subdevice" not in chan_data or chan_data["Subdevice"] != "yes":
766
+ sub = False
751
767
  cls = getattr(sys.modules[__name__], chan_data["Type"])
752
768
  self._channels[int(chan)] = cls(
753
- self, int(chan), chan_data["Name"], edit, self._writer, self._address
769
+ module=self,
770
+ num=int(chan),
771
+ name=chan_data["Name"],
772
+ nameEditable=edit,
773
+ subDevice=sub,
774
+ writer=self._writer,
775
+ address=self._address,
754
776
  )
755
777
  if chan_data["Type"] == "Temperature":
756
778
  if "Thermostat" in self._data or (
@@ -792,7 +814,13 @@ class VmbDali(Module):
792
814
  async def _load_default_channels(self) -> None:
793
815
  for chan in range(1, 64 + 1):
794
816
  self._channels[chan] = Channel(
795
- self, chan, "placeholder", True, self._writer, self._address
817
+ module=self,
818
+ num=chan,
819
+ name="placeholder",
820
+ nameEditable=True,
821
+ subDevice=True,
822
+ writer=self._writer,
823
+ address=self._address,
796
824
  )
797
825
  # Placeholders will keep this module loading
798
826
  # Until the DaliDeviceSettings messages either delete or replace these placeholder's
@@ -823,6 +851,7 @@ class VmbDali(Module):
823
851
  message.channel,
824
852
  None,
825
853
  True,
854
+ True,
826
855
  self._writer,
827
856
  self._address,
828
857
  slider_scale=254,
@@ -3,32 +3,38 @@
3
3
  "01": {
4
4
  "Editable": "yes",
5
5
  "Name": "Push button 1",
6
- "Type": "Button"
6
+ "Type": "Button",
7
+ "Subdevice": "yes"
7
8
  },
8
9
  "02": {
9
10
  "Editable": "yes",
10
11
  "Name": "Push button 2",
11
- "Type": "Button"
12
+ "Type": "Button",
13
+ "Subdevice": "yes"
12
14
  },
13
15
  "03": {
14
16
  "Editable": "yes",
15
17
  "Name": "Push button 3",
16
- "Type": "Button"
18
+ "Type": "Button",
19
+ "Subdevice": "yes"
17
20
  },
18
21
  "04": {
19
22
  "Editable": "yes",
20
23
  "Name": "Push button 4",
21
- "Type": "Button"
24
+ "Type": "Button",
25
+ "Subdevice": "yes"
22
26
  },
23
27
  "05": {
24
28
  "Editable": "yes",
25
29
  "Name": "Push button 5",
26
- "Type": "Button"
30
+ "Type": "Button",
31
+ "Subdevice": "yes"
27
32
  },
28
33
  "06": {
29
34
  "Editable": "yes",
30
35
  "Name": "Push button 6",
31
- "Type": "Button"
36
+ "Type": "Button",
37
+ "Subdevice": "yes"
32
38
  }
33
39
  },
34
40
  "Info": "6-Channel Input Module",
@@ -3,22 +3,26 @@
3
3
  "01": {
4
4
  "Editable": "yes",
5
5
  "Name": "Dimmer 1",
6
- "Type": "Dimmer"
6
+ "Type": "Dimmer",
7
+ "Subdevice": "yes"
7
8
  },
8
9
  "02": {
9
10
  "Editable": "yes",
10
11
  "Name": "Dimmer 2",
11
- "Type": "Dimmer"
12
+ "Type": "Dimmer",
13
+ "Subdevice": "yes"
12
14
  },
13
15
  "03": {
14
16
  "Editable": "yes",
15
17
  "Name": "Dimmer 3",
16
- "Type": "Dimmer"
18
+ "Type": "Dimmer",
19
+ "Subdevice": "yes"
17
20
  },
18
21
  "04": {
19
22
  "Editable": "yes",
20
23
  "Name": "Dimmer 4",
21
- "Type": "Dimmer"
24
+ "Type": "Dimmer",
25
+ "Subdevice": "yes"
22
26
  },
23
27
  "96": {
24
28
  "Name": "SelectedProgram",
@@ -3,22 +3,26 @@
3
3
  "01": {
4
4
  "Editable": "yes",
5
5
  "Name": "Relay 1",
6
- "Type": "Relay"
6
+ "Type": "Relay",
7
+ "Subdevice": "yes"
7
8
  },
8
9
  "02": {
9
10
  "Editable": "yes",
10
11
  "Name": "Relay 2",
11
- "Type": "Relay"
12
+ "Type": "Relay",
13
+ "Subdevice": "yes"
12
14
  },
13
15
  "03": {
14
16
  "Editable": "yes",
15
17
  "Name": "Relay 3",
16
- "Type": "Relay"
18
+ "Type": "Relay",
19
+ "Subdevice": "yes"
17
20
  },
18
21
  "04": {
19
22
  "Editable": "yes",
20
23
  "Name": "Relay 4",
21
- "Type": "Relay"
24
+ "Type": "Relay",
25
+ "Subdevice": "yes"
22
26
  }
23
27
  },
24
28
  "Info": "4 channel relay module",
@@ -3,22 +3,26 @@
3
3
  "01": {
4
4
  "Editable": "yes",
5
5
  "Name": "Relay 1",
6
- "Type": "Relay"
6
+ "Type": "Relay",
7
+ "Subdevice": "yes"
7
8
  },
8
9
  "02": {
9
10
  "Editable": "yes",
10
11
  "Name": "Relay 2",
11
- "Type": "Relay"
12
+ "Type": "Relay",
13
+ "Subdevice": "yes"
12
14
  },
13
15
  "03": {
14
16
  "Editable": "yes",
15
17
  "Name": "Relay 3",
16
- "Type": "Relay"
18
+ "Type": "Relay",
19
+ "Subdevice": "yes"
17
20
  },
18
21
  "04": {
19
22
  "Editable": "yes",
20
23
  "Name": "Relay 4",
21
- "Type": "Relay"
24
+ "Type": "Relay",
25
+ "Subdevice": "yes"
22
26
  },
23
27
  "05": {
24
28
  "Editable": "yes",
@@ -3,22 +3,26 @@
3
3
  "01": {
4
4
  "Editable": "yes",
5
5
  "Name": "Relay 1",
6
- "Type": "Relay"
6
+ "Type": "Relay",
7
+ "Subdevice": "yes"
7
8
  },
8
9
  "02": {
9
10
  "Editable": "yes",
10
11
  "Name": "Relay 2",
11
- "Type": "Relay"
12
+ "Type": "Relay",
13
+ "Subdevice": "yes"
12
14
  },
13
15
  "03": {
14
16
  "Editable": "yes",
15
17
  "Name": "Relay 3",
16
- "Type": "Relay"
18
+ "Type": "Relay",
19
+ "Subdevice": "yes"
17
20
  },
18
21
  "04": {
19
22
  "Editable": "yes",
20
23
  "Name": "Relay 4",
21
- "Type": "Relay"
24
+ "Type": "Relay",
25
+ "Subdevice": "yes"
22
26
  },
23
27
  "05": {
24
28
  "Editable": "yes",
@@ -3,22 +3,26 @@
3
3
  "01": {
4
4
  "Editable": "yes",
5
5
  "Name": "Dimmer 1",
6
- "Type": "Dimmer"
6
+ "Type": "Dimmer",
7
+ "Subdevice": "yes"
7
8
  },
8
9
  "02": {
9
10
  "Editable": "yes",
10
11
  "Name": "Dimmer 2",
11
- "Type": "Dimmer"
12
+ "Type": "Dimmer",
13
+ "Subdevice": "yes"
12
14
  },
13
15
  "03": {
14
16
  "Editable": "yes",
15
17
  "Name": "Dimmer 3",
16
- "Type": "Dimmer"
18
+ "Type": "Dimmer",
19
+ "Subdevice": "yes"
17
20
  },
18
21
  "04": {
19
22
  "Editable": "yes",
20
23
  "Name": "Dimmer 4",
21
- "Type": "Dimmer"
24
+ "Type": "Dimmer",
25
+ "Subdevice": "yes"
22
26
  }
23
27
  },
24
28
  "Info": "0/1 to 10V dimmer controller module",
@@ -3,37 +3,44 @@
3
3
  "01": {
4
4
  "Editable": "yes",
5
5
  "Name": "Push button 1",
6
- "Type": "ButtonCounter"
6
+ "Type": "ButtonCounter",
7
+ "Subdevice": "yes"
7
8
  },
8
9
  "02": {
9
10
  "Editable": "yes",
10
11
  "Name": "Push button 2",
11
- "Type": "ButtonCounter"
12
+ "Type": "ButtonCounter",
13
+ "Subdevice": "yes"
12
14
  },
13
15
  "03": {
14
16
  "Editable": "yes",
15
17
  "Name": "Push button 3",
16
- "Type": "ButtonCounter"
18
+ "Type": "ButtonCounter",
19
+ "Subdevice": "yes"
17
20
  },
18
21
  "04": {
19
22
  "Editable": "yes",
20
23
  "Name": "Push button 4",
21
- "Type": "ButtonCounter"
24
+ "Type": "ButtonCounter",
25
+ "Subdevice": "yes"
22
26
  },
23
27
  "05": {
24
28
  "Editable": "yes",
25
29
  "Name": "Push button 5",
26
- "Type": "Button"
30
+ "Type": "Button",
31
+ "Subdevice": "yes"
27
32
  },
28
33
  "06": {
29
34
  "Editable": "yes",
30
35
  "Name": "Push button 6",
31
- "Type": "Button"
36
+ "Type": "Button",
37
+ "Subdevice": "yes"
32
38
  },
33
39
  "07": {
34
40
  "Editable": "yes",
35
41
  "Name": "Push button 7",
36
- "Type": "Button"
42
+ "Type": "Button",
43
+ "Subdevice": "yes"
37
44
  },
38
45
  "08": {
39
46
  "Editable": "yes",
@@ -14,35 +14,43 @@
14
14
  "Channels": {
15
15
  "01": {
16
16
  "Name": "Alarm 1",
17
- "Type": "Sensor"
17
+ "Type": "Sensor",
18
+ "Subdevice": "yes"
18
19
  },
19
20
  "02": {
20
21
  "Name": "Alarm 2",
21
- "Type": "Sensor"
22
+ "Type": "Sensor",
23
+ "Subdevice": "yes"
22
24
  },
23
25
  "03": {
24
26
  "Name": "Alarm 3",
25
- "Type": "Sensor"
27
+ "Type": "Sensor",
28
+ "Subdevice": "yes"
26
29
  },
27
30
  "04": {
28
31
  "Name": "Alarm 4",
29
- "Type": "Sensor"
32
+ "Type": "Sensor",
33
+ "Subdevice": "yes"
30
34
  },
31
35
  "05": {
32
36
  "Name": "Alarm 5",
33
- "Type": "Sensor"
37
+ "Type": "Sensor",
38
+ "Subdevice": "yes"
34
39
  },
35
40
  "06": {
36
41
  "Name": "Alarm 6",
37
- "Type": "Sensor"
42
+ "Type": "Sensor",
43
+ "Subdevice": "yes"
38
44
  },
39
45
  "07": {
40
46
  "Name": "Alarm 7",
41
- "Type": "Sensor"
47
+ "Type": "Sensor",
48
+ "Subdevice": "yes"
42
49
  },
43
50
  "08": {
44
51
  "Name": "Alarm 8",
45
- "Type": "Sensor"
52
+ "Type": "Sensor",
53
+ "Subdevice": "yes"
46
54
  },
47
55
  "09": {
48
56
  "Name": "Sensor 1",
@@ -3,22 +3,26 @@
3
3
  "01": {
4
4
  "Editable": "yes",
5
5
  "Name": "Relay 1",
6
- "Type": "Relay"
6
+ "Type": "Relay",
7
+ "Subdevice": "yes"
7
8
  },
8
9
  "02": {
9
10
  "Editable": "yes",
10
11
  "Name": "Relay 2",
11
- "Type": "Relay"
12
+ "Type": "Relay",
13
+ "Subdevice": "yes"
12
14
  },
13
15
  "03": {
14
16
  "Editable": "yes",
15
17
  "Name": "Relay 3",
16
- "Type": "Relay"
18
+ "Type": "Relay",
19
+ "Subdevice": "yes"
17
20
  },
18
21
  "04": {
19
22
  "Editable": "yes",
20
23
  "Name": "Relay 4",
21
- "Type": "Relay"
24
+ "Type": "Relay",
25
+ "Subdevice": "yes"
22
26
  },
23
27
  "05": {
24
28
  "Editable": "yes",
@@ -3,22 +3,26 @@
3
3
  "01": {
4
4
  "Editable": "yes",
5
5
  "Name": "Relay 1",
6
- "Type": "Relay"
6
+ "Type": "Relay",
7
+ "Subdevice": "yes"
7
8
  },
8
9
  "02": {
9
10
  "Editable": "yes",
10
11
  "Name": "Relay 2",
11
- "Type": "Relay"
12
+ "Type": "Relay",
13
+ "Subdevice": "yes"
12
14
  },
13
15
  "03": {
14
16
  "Editable": "yes",
15
17
  "Name": "Relay 3",
16
- "Type": "Relay"
18
+ "Type": "Relay",
19
+ "Subdevice": "yes"
17
20
  },
18
21
  "04": {
19
22
  "Editable": "yes",
20
23
  "Name": "Relay 4",
21
- "Type": "Relay"
24
+ "Type": "Relay",
25
+ "Subdevice": "yes"
22
26
  },
23
27
  "05": {
24
28
  "Editable": "yes",
@@ -1,4 +1,83 @@
1
1
  {
2
+ "Channels": {
3
+ "01": {
4
+ "Name": "Blind 1",
5
+ "Type": "Blind"
6
+ },
7
+ "02": {
8
+ "Name": "Blind 2",
9
+ "Type": "Blind"
10
+ }
11
+ },
2
12
  "Info": "2 channel blind module",
13
+ "Memory": {
14
+ "Address": {
15
+ "004C": { "ModuleName": "0:Start" },
16
+ "004D": { "ModuleName": "1" },
17
+ "004E": { "ModuleName": "2" },
18
+ "004F": { "ModuleName": "3" },
19
+ "0050": { "ModuleName": "4" },
20
+ "0051": { "ModuleName": "5" },
21
+ "0052": { "ModuleName": "6" },
22
+ "0053": { "ModuleName": "7" },
23
+ "0054": { "ModuleName": "8" },
24
+ "0055": { "ModuleName": "9" },
25
+ "0056": { "ModuleName": "10" },
26
+ "0057": { "ModuleName": "11" },
27
+ "0058": { "ModuleName": "12" },
28
+ "0059": { "ModuleName": "13" },
29
+ "005A": { "ModuleName": "14" },
30
+ "005B": { "ModuleName": "15" },
31
+ "005C": { "ModuleName": "16" },
32
+ "005D": { "ModuleName": "17" },
33
+ "005E": { "ModuleName": "18" },
34
+ "005F": { "ModuleName": "19" },
35
+ "0060": { "ModuleName": "20" },
36
+ "0061": { "ModuleName": "21" },
37
+ "0062": { "ModuleName": "22" },
38
+ "0063": { "ModuleName": "23" },
39
+ "0064": { "ModuleName": "24" },
40
+ "0065": { "ModuleName": "25" },
41
+ "0066": { "ModuleName": "26" },
42
+ "0067": { "ModuleName": "27" },
43
+ "0068": { "ModuleName": "28" },
44
+ "0069": { "ModuleName": "29" },
45
+ "006A": { "ModuleName": "30" },
46
+ "006B": { "ModuleName": "31" },
47
+ "006C": { "ModuleName": "32" },
48
+ "006D": { "ModuleName": "33" },
49
+ "006E": { "ModuleName": "34" },
50
+ "006F": { "ModuleName": "35" },
51
+ "0070": { "ModuleName": "36" },
52
+ "0071": { "ModuleName": "37" },
53
+ "0072": { "ModuleName": "38" },
54
+ "0073": { "ModuleName": "39" },
55
+ "0074": { "ModuleName": "40" },
56
+ "0075": { "ModuleName": "41" },
57
+ "0076": { "ModuleName": "42" },
58
+ "0077": { "ModuleName": "43" },
59
+ "0078": { "ModuleName": "44" },
60
+ "0079": { "ModuleName": "45" },
61
+ "007A": { "ModuleName": "46" },
62
+ "007B": { "ModuleName": "47" },
63
+ "007C": { "ModuleName": "48" },
64
+ "007D": { "ModuleName": "49" },
65
+ "007E": { "ModuleName": "50" },
66
+ "007F": { "ModuleName": "51" },
67
+ "0080": { "ModuleName": "52" },
68
+ "0081": { "ModuleName": "53" },
69
+ "0082": { "ModuleName": "54" },
70
+ "0083": { "ModuleName": "55" },
71
+ "0084": { "ModuleName": "56" },
72
+ "0085": { "ModuleName": "57" },
73
+ "0086": { "ModuleName": "58" },
74
+ "0087": { "ModuleName": "59" },
75
+ "0088": { "ModuleName": "60" },
76
+ "0089": { "ModuleName": "61" },
77
+ "008A": { "ModuleName": "62" },
78
+ "008B": { "ModuleName": "64:Save" }
79
+ },
80
+ "ModuleName": "004C-008B"
81
+ },
3
82
  "Type": "VMB2BLE-10"
4
83
  }
@@ -3,42 +3,50 @@
3
3
  "01": {
4
4
  "Editable": "yes",
5
5
  "Name": "Dimmer 1",
6
- "Type": "Dimmer"
6
+ "Type": "Dimmer",
7
+ "Subdevice": "yes"
7
8
  },
8
9
  "02": {
9
10
  "Editable": "yes",
10
11
  "Name": "Dimmer 2",
11
- "Type": "Dimmer"
12
+ "Type": "Dimmer",
13
+ "Subdevice": "yes"
12
14
  },
13
15
  "03": {
14
16
  "Editable": "yes",
15
17
  "Name": "Dimmer 3",
16
- "Type": "Dimmer"
18
+ "Type": "Dimmer",
19
+ "Subdevice": "yes"
17
20
  },
18
21
  "04": {
19
22
  "Editable": "yes",
20
23
  "Name": "Dimmer 4",
21
- "Type": "Dimmer"
24
+ "Type": "Dimmer",
25
+ "Subdevice": "yes"
22
26
  },
23
27
  "05": {
24
28
  "Editable": "yes",
25
29
  "Name": "Dimmer 4",
26
- "Type": "Dimmer"
30
+ "Type": "Dimmer",
31
+ "Subdevice": "yes"
27
32
  },
28
33
  "06": {
29
34
  "Editable": "yes",
30
35
  "Name": "Dimmer 6",
31
- "Type": "Dimmer"
36
+ "Type": "Dimmer",
37
+ "Subdevice": "yes"
32
38
  },
33
39
  "07": {
34
40
  "Editable": "yes",
35
41
  "Name": "Dimmer 7",
36
- "Type": "Dimmer"
42
+ "Type": "Dimmer",
43
+ "Subdevice": "yes"
37
44
  },
38
45
  "08": {
39
46
  "Editable": "yes",
40
47
  "Name": "Dimmer 8",
41
- "Type": "Dimmer"
48
+ "Type": "Dimmer",
49
+ "Subdevice": "yes"
42
50
  },
43
51
  "96": {
44
52
  "Name": "SelectedProgram",
@@ -3,42 +3,50 @@
3
3
  "01": {
4
4
  "Editable": "yes",
5
5
  "Name": "Push button 1",
6
- "Type": "ButtonCounter"
6
+ "Type": "ButtonCounter",
7
+ "Subdevice": "yes"
7
8
  },
8
9
  "02": {
9
10
  "Editable": "yes",
10
11
  "Name": "Push button 2",
11
- "Type": "ButtonCounter"
12
+ "Type": "ButtonCounter",
13
+ "Subdevice": "yes"
12
14
  },
13
15
  "03": {
14
16
  "Editable": "yes",
15
17
  "Name": "Push button 3",
16
- "Type": "ButtonCounter"
18
+ "Type": "ButtonCounter",
19
+ "Subdevice": "yes"
17
20
  },
18
21
  "04": {
19
22
  "Editable": "yes",
20
23
  "Name": "Push button 4",
21
- "Type": "ButtonCounter"
24
+ "Type": "ButtonCounter",
25
+ "Subdevice": "yes"
22
26
  },
23
27
  "05": {
24
28
  "Editable": "yes",
25
29
  "Name": "Push button 5",
26
- "Type": "ButtonCounter"
30
+ "Type": "ButtonCounter",
31
+ "Subdevice": "yes"
27
32
  },
28
33
  "06": {
29
34
  "Editable": "yes",
30
35
  "Name": "Push button 6",
31
- "Type": "ButtonCounter"
36
+ "Type": "ButtonCounter",
37
+ "Subdevice": "yes"
32
38
  },
33
39
  "07": {
34
40
  "Editable": "yes",
35
41
  "Name": "Push button 7",
36
- "Type": "ButtonCounter"
42
+ "Type": "ButtonCounter",
43
+ "Subdevice": "yes"
37
44
  },
38
45
  "08": {
39
46
  "Editable": "yes",
40
47
  "Name": "Push button 8",
41
- "Type": "ButtonCounter"
48
+ "Type": "ButtonCounter",
49
+ "Subdevice": "yes"
42
50
  },
43
51
  "09": {
44
52
  "Editable": "yes",