conson-xp 1.51.1__py3-none-any.whl → 2.0.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.
- {conson_xp-1.51.1.dist-info → conson_xp-2.0.0.dist-info}/METADATA +1 -11
- {conson_xp-1.51.1.dist-info → conson_xp-2.0.0.dist-info}/RECORD +20 -38
- xp/__init__.py +1 -1
- xp/cli/commands/__init__.py +0 -4
- xp/cli/commands/term/term_commands.py +1 -1
- xp/cli/main.py +0 -3
- xp/models/homekit/homekit_config.py +4 -0
- xp/models/protocol/conbus_protocol.py +30 -25
- xp/models/term/accessory_state.py +1 -1
- xp/services/protocol/__init__.py +2 -3
- xp/services/protocol/conbus_event_protocol.py +5 -5
- xp/services/term/homekit_accessory_driver.py +171 -0
- xp/services/term/homekit_service.py +187 -10
- xp/term/homekit.py +146 -14
- xp/term/homekit.tcss +4 -4
- xp/term/widgets/room_list.py +61 -3
- xp/utils/dependencies.py +34 -154
- xp/cli/commands/homekit/__init__.py +0 -3
- xp/cli/commands/homekit/homekit.py +0 -120
- xp/cli/commands/homekit/homekit_start_commands.py +0 -44
- xp/services/homekit/__init__.py +0 -1
- xp/services/homekit/homekit_cache_service.py +0 -313
- xp/services/homekit/homekit_conbus_service.py +0 -99
- xp/services/homekit/homekit_config_validator.py +0 -327
- xp/services/homekit/homekit_conson_validator.py +0 -130
- xp/services/homekit/homekit_dimminglight.py +0 -189
- xp/services/homekit/homekit_dimminglight_service.py +0 -155
- xp/services/homekit/homekit_hap_service.py +0 -351
- xp/services/homekit/homekit_lightbulb.py +0 -125
- xp/services/homekit/homekit_lightbulb_service.py +0 -91
- xp/services/homekit/homekit_module_service.py +0 -60
- xp/services/homekit/homekit_outlet.py +0 -175
- xp/services/homekit/homekit_outlet_service.py +0 -127
- xp/services/homekit/homekit_service.py +0 -371
- xp/services/protocol/protocol_factory.py +0 -84
- xp/services/protocol/telegram_protocol.py +0 -270
- {conson_xp-1.51.1.dist-info → conson_xp-2.0.0.dist-info}/WHEEL +0 -0
- {conson_xp-1.51.1.dist-info → conson_xp-2.0.0.dist-info}/entry_points.txt +0 -0
- {conson_xp-1.51.1.dist-info → conson_xp-2.0.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: conson-xp
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: XP Protocol Communication Tools
|
|
5
5
|
Author-Email: ldvchosal <ldvchosal@github.com>
|
|
6
6
|
License: MIT License
|
|
@@ -46,7 +46,6 @@ Requires-Dist: pydantic>=2.11
|
|
|
46
46
|
Requires-Dist: HAP-python[QRCode]>=5.0.0
|
|
47
47
|
Requires-Dist: punq>=0.7.0
|
|
48
48
|
Requires-Dist: twisted>=25.5.0
|
|
49
|
-
Requires-Dist: bubus>=1.5.6
|
|
50
49
|
Requires-Dist: psygnal>=0.15.0
|
|
51
50
|
Requires-Dist: textual>=1.0.0
|
|
52
51
|
Requires-Dist: python-statemachine>=2.5.0
|
|
@@ -399,15 +398,6 @@ xp file validate
|
|
|
399
398
|
|
|
400
399
|
xp help
|
|
401
400
|
|
|
402
|
-
xp homekit
|
|
403
|
-
|
|
404
|
-
xp homekit config
|
|
405
|
-
xp homekit config show
|
|
406
|
-
xp homekit config validate
|
|
407
|
-
|
|
408
|
-
xp homekit start
|
|
409
|
-
|
|
410
|
-
|
|
411
401
|
xp module
|
|
412
402
|
xp module categories
|
|
413
403
|
xp module info
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
conson_xp-
|
|
2
|
-
conson_xp-
|
|
3
|
-
conson_xp-
|
|
4
|
-
conson_xp-
|
|
5
|
-
xp/__init__.py,sha256=
|
|
1
|
+
conson_xp-2.0.0.dist-info/METADATA,sha256=tK46Z8_p-HD8WeGz-pDaZ93S9IxsuLrcSPS96yBBA2A,11319
|
|
2
|
+
conson_xp-2.0.0.dist-info/WHEEL,sha256=tsUv_t7BDeJeRHaSrczbGeuK-TtDpGsWi_JfpzD255I,90
|
|
3
|
+
conson_xp-2.0.0.dist-info/entry_points.txt,sha256=1OcdIcDM1hz3ljCXgybaPUh1IOFEwkaTgLIW9u9zGeg,50
|
|
4
|
+
conson_xp-2.0.0.dist-info/licenses/LICENSE,sha256=rxj6woMM-r3YCyGq_UHFtbh7kHTAJgrccH6O-33IDE4,1419
|
|
5
|
+
xp/__init__.py,sha256=kAoWCUKDiEEtQSn6qquI38IMu38W_n_3af1nhKORdzk,181
|
|
6
6
|
xp/cli/__init__.py,sha256=QjnKB1KaI2aIyKlzrnvCwfbBuUj8HNgwNMvNJVQofbI,81
|
|
7
7
|
xp/cli/__main__.py,sha256=l2iKwMdat5rTGd3JWs-uGksnYYDDffp_Npz05QdKEeU,117
|
|
8
|
-
xp/cli/commands/__init__.py,sha256=
|
|
8
|
+
xp/cli/commands/__init__.py,sha256=9TGP3uTxAU-s-kVChvQ-Fn3-HVYj-QpeQ05Is-20HRo,4788
|
|
9
9
|
xp/cli/commands/conbus/__init__.py,sha256=HYaX2__XxwD3Xaw4CzflvL8CwoUa4yR6wOyH8wwyofM,535
|
|
10
10
|
xp/cli/commands/conbus/conbus.py,sha256=GpWq1QS3mKfQFG77nTED-_hsvcnXb3ZIrC6DhfyhzBE,3538
|
|
11
11
|
xp/cli/commands/conbus/conbus_actiontable_commands.py,sha256=EpyLG_6RxhIQY4BWxDXTyo8yzpBwbHfZDOgmRl--R5w,7378
|
|
@@ -26,9 +26,6 @@ xp/cli/commands/conbus/conbus_raw_commands.py,sha256=o1dVZqiRw7J3_8Bge7DJucFyAqt
|
|
|
26
26
|
xp/cli/commands/conbus/conbus_receive_commands.py,sha256=LdxoOUdM5atkC8fFlp-GK7HQ7oxTnjrSFDx-lQ3nme0,1925
|
|
27
27
|
xp/cli/commands/conbus/conbus_scan_commands.py,sha256=QuRT4Vx5TqervCOUsZ4wcxvy7Jwra4hl2-DIt8cDcoE,1828
|
|
28
28
|
xp/cli/commands/file_commands.py,sha256=dx6a4xNxuReXq7dOyL8ebn6lyifzDm0d0OsuDjyr_90,5547
|
|
29
|
-
xp/cli/commands/homekit/__init__.py,sha256=qqwY8ulxTx1S74Mzpb6EKjBLT6fWTNdf9PQ3HKuERKY,50
|
|
30
|
-
xp/cli/commands/homekit/homekit.py,sha256=BoX7BVbgz2fehahe4_jPgEpOSIzKg790-9ADjoSKsKY,3604
|
|
31
|
-
xp/cli/commands/homekit/homekit_start_commands.py,sha256=tfRRAFdTp74RsZ4alqYTvRpfSrSXyFKr5Zdc3prgbuQ,1125
|
|
32
29
|
xp/cli/commands/module_commands.py,sha256=KCbGkt6Zr1i4yrXanb-WXZ08PDChNkMk3Y5B5La8BaM,5406
|
|
33
30
|
xp/cli/commands/reverse_proxy_commands.py,sha256=GFgRoAXU0cf1QNFu3WYNcXdbMndGMaGHtHRkMwePTyc,5485
|
|
34
31
|
xp/cli/commands/server/__init__.py,sha256=iunDmcaax9U-SHymgGzUlPadGdZLFl9LlhXu2mnyb64,49
|
|
@@ -43,8 +40,8 @@ xp/cli/commands/telegram/telegram_parse_commands.py,sha256=xCDRRFgj41RtStvwROfi-
|
|
|
43
40
|
xp/cli/commands/telegram/telegram_version_commands.py,sha256=hAMjSAa7zfMNfNFln63sKeNPcmW89bISkcVs6BgsqOg,1558
|
|
44
41
|
xp/cli/commands/term/__init__.py,sha256=1NNST_8YJfj5LCujQISwQflK6LyEn7mDmZpMpvI9d-o,116
|
|
45
42
|
xp/cli/commands/term/term.py,sha256=gjvsv2OE-F_KNWQrWi04fXQ5cGo0l8P-Ortbb5KTA-A,309
|
|
46
|
-
xp/cli/commands/term/term_commands.py,sha256=
|
|
47
|
-
xp/cli/main.py,sha256=
|
|
43
|
+
xp/cli/commands/term/term_commands.py,sha256=pw-hEddLf89_NKft3JPsZALe-7vtvNeq9upubysqLX8,1799
|
|
44
|
+
xp/cli/main.py,sha256=wr8jCGqgAvre0KFz4wZUWV0IpKa25cs2yLYAAcMoOIw,1906
|
|
48
45
|
xp/cli/utils/__init__.py,sha256=gTGIj60Uai0iE7sr9_TtEpl04fD7krtTzbbigXUsUVU,46
|
|
49
46
|
xp/cli/utils/click_tree.py,sha256=sr4l9RWTCnASkdvkJKnRRxWSQPlF1DbFdBNu9gL7Ekc,1693
|
|
50
47
|
xp/cli/utils/datapoint_type_choice.py,sha256=fGgwZAmY_jwBt4fc1LQfyqhvf-TBOUgL3ph9idIDvAI,1680
|
|
@@ -84,10 +81,10 @@ xp/models/config/__init__.py,sha256=gEZnX9eE3DjFtLtF32riEjJQLypqQRbyPauBI4Cowbs,
|
|
|
84
81
|
xp/models/config/conson_module_config.py,sha256=t1G0LnNNMnjs3ahhz4-Z_5SlEv2FCrcRq13OmvZ2pvA,3009
|
|
85
82
|
xp/models/homekit/__init__.py,sha256=5HDSOClCu0ArK3IICn3_LDMMLBAzLjBxUUSF73bxSSk,34
|
|
86
83
|
xp/models/homekit/homekit_accessory.py,sha256=ANjDWlFxeNTstl7lKdmf6vMOC0wc005vpiD6awRcptA,1052
|
|
87
|
-
xp/models/homekit/homekit_config.py,sha256=
|
|
84
|
+
xp/models/homekit/homekit_config.py,sha256=pgZOnocue60LjV8ce46MyJ3mo5CqLix6TmT64qxPOks,3267
|
|
88
85
|
xp/models/log_entry.py,sha256=tAiNwouCP2d4jKiHJY9a-2iAi8LWTpG-TZsOPDIstlA,4423
|
|
89
86
|
xp/models/protocol/__init__.py,sha256=TJ_CJKchA-xgQiv5vCo_ndBBZjrcaTmjT74bR0T-5Cw,38
|
|
90
|
-
xp/models/protocol/conbus_protocol.py,sha256=
|
|
87
|
+
xp/models/protocol/conbus_protocol.py,sha256=gFaXK1VY74aVQhMH69Dr-dTDbDuQDQGs8vKmXqK_te8,9318
|
|
91
88
|
xp/models/response.py,sha256=z0376hEVNh1Z_R9CtzmKNbJBzCo_Aun2ImI9dTtrVe4,1254
|
|
92
89
|
xp/models/telegram/__init__.py,sha256=-_exhjlRLbBNuPxHC4tLA2SAgf8M0yHJMeyEoQIk9PI,53
|
|
93
90
|
xp/models/telegram/action_type.py,sha256=ys3yInmD97bKotB-nlPdfo8ZPXKaYxzG0CxV9wHK-zo,797
|
|
@@ -106,7 +103,7 @@ xp/models/telegram/telegram.py,sha256=-kNloBlwMJ5w1-FAMSLzBPnyOGUNEBG3SG2d0eTi2P
|
|
|
106
103
|
xp/models/telegram/telegram_type.py,sha256=IjGEosbs7IDqYT7ktn-FcKS-kAJ4eXW-KJGkkoAGysw,428
|
|
107
104
|
xp/models/telegram/timeparam_type.py,sha256=z5EQ32SQjDi7zKshtkvDzqaMfPMUeXCWKEGI5VgvBvU,1142
|
|
108
105
|
xp/models/term/__init__.py,sha256=VVZsEyXBEr-TnBlrFFifZ6PjJHUl2kwnRUZx_kC2Ljg,343
|
|
109
|
-
xp/models/term/accessory_state.py,sha256=
|
|
106
|
+
xp/models/term/accessory_state.py,sha256=doW1upkKxYeYJ8tlnLtN3Y0AAfIC7mrI4dsYNbuAvn8,1653
|
|
110
107
|
xp/models/term/connection_state.py,sha256=oYcst01uH35kO541jGuXMqvJ2iduiHYryUsMK0d89pQ,1807
|
|
111
108
|
xp/models/term/module_state.py,sha256=i7u8y_B5ScMRULQb_kMSD_wwKzbrLHlkECsTgNS46PQ,939
|
|
112
109
|
xp/models/term/protocol_keys_config.py,sha256=tSlkxEwgQuVRYLTaUNd569osQsNCdb9ED4InNgX9rKo,1223
|
|
@@ -143,26 +140,10 @@ xp/services/conbus/conbus_raw_service.py,sha256=OQuV521VOQraf2PGF2B9868vh7sDgmfc
|
|
|
143
140
|
xp/services/conbus/conbus_receive_service.py,sha256=TFf3W65brGsy6QZICpIs0Xy9bgqyL1vgQuhS_eHuIZs,5416
|
|
144
141
|
xp/services/conbus/conbus_scan_service.py,sha256=_Ka0OUDNYhDgZIR49Q0P5GTxJq6RcAAX2DVqEDdtb5U,6888
|
|
145
142
|
xp/services/conbus/write_config_service.py,sha256=BCfmLNPRDpwSwRMRYJvx2FXA8IZsdgmyeTXIYvmb4ys,9004
|
|
146
|
-
xp/services/homekit/__init__.py,sha256=xAMKmln_AmEFdOOJGKWYi96seRlKDQpKx3-hm7XbdIo,36
|
|
147
|
-
xp/services/homekit/homekit_cache_service.py,sha256=z1TB6icEqd1paoilVTewuFL0lXVCQbvrOJkJvvQECJY,11060
|
|
148
|
-
xp/services/homekit/homekit_conbus_service.py,sha256=XPKv7Mit1rn7XLaQZcKmlMMUlyj-o0J2z8XBH3NaEIM,3390
|
|
149
|
-
xp/services/homekit/homekit_config_validator.py,sha256=jf09jHIFbZg7YpDbGsGHT1p4a1vpUED2xR6iZN19cfM,10875
|
|
150
|
-
xp/services/homekit/homekit_conson_validator.py,sha256=tmUxBzytX9FbUWTR1XdbAi_qb_whAdGPSaml98Czszg,3858
|
|
151
|
-
xp/services/homekit/homekit_dimminglight.py,sha256=EzfGhy3zZkbFPfN72Dh_eSb5mJQOpxGi6ZwnyEOSHxU,5819
|
|
152
|
-
xp/services/homekit/homekit_dimminglight_service.py,sha256=0Ve6cXtY7v7JCv7gibOBWjPfCU7KK4Lk6GjIu9_GhyE,5282
|
|
153
|
-
xp/services/homekit/homekit_hap_service.py,sha256=yrlw9I4G3JsaeBqsVLyURlAk9gd6CAKIUSoheOYIioI,12596
|
|
154
|
-
xp/services/homekit/homekit_lightbulb.py,sha256=rN9rNxHZDFl5lom8bvhi3jC3rGgrELhrRWTMg4l6ziQ,3692
|
|
155
|
-
xp/services/homekit/homekit_lightbulb_service.py,sha256=fKK5wvV73On1p0zBH8k30iirHYW0mBRiHEaTEf4Jcnc,2785
|
|
156
|
-
xp/services/homekit/homekit_module_service.py,sha256=3zUwm-Dp-8V0nCU-ssVMZmi_kht_Y_ulVgqRSHoLooY,1548
|
|
157
|
-
xp/services/homekit/homekit_outlet.py,sha256=gh9YFYt4DgOkba4nWKRM40EH878254DErSOK3eneZYk,5258
|
|
158
|
-
xp/services/homekit/homekit_outlet_service.py,sha256=VVeuUas5HROaMwfbc_FO-gVp_mXR8YYBQJeTWh2SSJQ,3840
|
|
159
|
-
xp/services/homekit/homekit_service.py,sha256=mmO9dHd1PAkOLkM7wwbpC0iBnULN4XZxeHUnCMKOL7g,14127
|
|
160
143
|
xp/services/log_file_service.py,sha256=y775InPlpG8Z_uitHt7yrgRG-3vlIuCfdJjiZzPc_MA,10578
|
|
161
144
|
xp/services/module_type_service.py,sha256=ga4WO7dmJEaDKrXPmrJ-72n4UaEZonead23lHBkFN1E,7505
|
|
162
|
-
xp/services/protocol/__init__.py,sha256=
|
|
163
|
-
xp/services/protocol/conbus_event_protocol.py,sha256=
|
|
164
|
-
xp/services/protocol/protocol_factory.py,sha256=gWXQtOdgtOyn0Tu_aydYFd_cTdU-jtsKVuMl-ru133s,2512
|
|
165
|
-
xp/services/protocol/telegram_protocol.py,sha256=hyEMJUUhgQe_2R8CDio8xT5tpLtgoXS8W0aDd7wN48E,9538
|
|
145
|
+
xp/services/protocol/__init__.py,sha256=o5adyCwOrqSf4ADUStor44TFUerYx6QmxGpq4Q0dhSo,631
|
|
146
|
+
xp/services/protocol/conbus_event_protocol.py,sha256=5BmvhZCqDuXekhbTuuOvz1dke6fqsZIJsaWYF8s-mGU,19653
|
|
166
147
|
xp/services/reverse_proxy_service.py,sha256=Xuxo2ajjmTXLg5yd6gRGKHpFPX4-6kpOUg10doZB8vw,15161
|
|
167
148
|
xp/services/server/__init__.py,sha256=QEcCj-jK0goAukJCe15TKYFQfSAzWsduPT_wW0HxZU8,48
|
|
168
149
|
xp/services/server/base_server_service.py,sha256=Yu4sTOtp3a1yc3O3J7J-51i9FdFqG-VWBv9aNf0j-9k,12845
|
|
@@ -185,12 +166,13 @@ xp/services/telegram/telegram_output_service.py,sha256=9deqtcPndRqJ-3XQUWlJhXaVc
|
|
|
185
166
|
xp/services/telegram/telegram_service.py,sha256=jPu0Xrh3IpvqPLyuQT5Vf8HHw00vBingONHdxf_9TkI,13315
|
|
186
167
|
xp/services/telegram/telegram_version_service.py,sha256=oXnZ_K7OQ7xD-GEj3zDYp52KlkqVuHpO4bf7gMlC_w4,10574
|
|
187
168
|
xp/services/term/__init__.py,sha256=BIeOK042bMR-0l6MA80wdW5VuHlpWOXtRER9IG5ilQA,245
|
|
188
|
-
xp/services/term/
|
|
169
|
+
xp/services/term/homekit_accessory_driver.py,sha256=jHhHHOOvzdDjuYys1cUZHcH2uwZy_Y6o5aGAQqXGAVg,5935
|
|
170
|
+
xp/services/term/homekit_service.py,sha256=h1wAguhUG9f8cdolFKsp-V-iZV5x52Wm0L7syKoK6Qs,25183
|
|
189
171
|
xp/services/term/protocol_monitor_service.py,sha256=5YBI0Nu7B7gMhaTbUhL6k9LSRfnCIj6CwrCYHiMHavA,10067
|
|
190
172
|
xp/services/term/state_monitor_service.py,sha256=EK9tNBfamAIV0z0EMsXDYWC-rXv6l6k_bHsC8xyEFSo,17116
|
|
191
173
|
xp/term/__init__.py,sha256=Xg2DhBeI3xQJLfc7_BPWI1por-rUXemyer5OtOt9Cus,51
|
|
192
|
-
xp/term/homekit.py,sha256=
|
|
193
|
-
xp/term/homekit.tcss,sha256=
|
|
174
|
+
xp/term/homekit.py,sha256=A9l9zK6KSBx_Cc8I_AZhAWdQjZYnTGLxkln6CzFn3-Q,8935
|
|
175
|
+
xp/term/homekit.tcss,sha256=A1f5-V3mvxAMZK_ERq8lLjNcOWH0U5tblIBbeL3OYYM,1382
|
|
194
176
|
xp/term/protocol.py,sha256=6MX3mduLei-AgLGaIe8lfOSu4Hi0y3KGePFFM2ssstc,3475
|
|
195
177
|
xp/term/protocol.tcss,sha256=r_KfxrbpycGHLVXqZc6INBBcUJME0hLrAZkF1oqnab4,2126
|
|
196
178
|
xp/term/state.py,sha256=FBpYV_bWYJh9o17qcMx6sHgUARQS-uNOtUt6G7Vs1n8,3274
|
|
@@ -199,14 +181,14 @@ xp/term/widgets/__init__.py,sha256=ftWmN_fmjxy2E8Qfm-YSRmzKfgL0KTBCTpgvYWCPbUY,2
|
|
|
199
181
|
xp/term/widgets/help_menu.py,sha256=KLkdIXfhARLFNEs2lv1u0sYBz9LzOCcDLxbMGzc7e5Y,1812
|
|
200
182
|
xp/term/widgets/modules_list.py,sha256=qAG-n0nK0YdNE9v4C3-sHgxLvF1i1FR7v_GArdaoUQw,7831
|
|
201
183
|
xp/term/widgets/protocol_log.py,sha256=E68QmSMpOFrvrPTo_gOQVfyiDqY5c_y8fkNKnQw6Vwo,2650
|
|
202
|
-
xp/term/widgets/room_list.py,sha256=
|
|
184
|
+
xp/term/widgets/room_list.py,sha256=ecdpK-QOP1Zmi0ntYxpWhik9EQc8wBNNjPirMWhJ7gs,9807
|
|
203
185
|
xp/term/widgets/status_footer.py,sha256=biV3EzfVSgm1T7Ofi88LXsTFCkD5mI_6Cpe-RpuOSxA,3429
|
|
204
186
|
xp/utils/__init__.py,sha256=_avMF_UOkfR3tNeDIPqQ5odmbq5raKkaq1rZ9Cn1CJs,332
|
|
205
187
|
xp/utils/checksum.py,sha256=Px1S3dFGA-_plavBxrq3IqmprNlgtNDunE3whg6Otwg,1722
|
|
206
|
-
xp/utils/dependencies.py,sha256=
|
|
188
|
+
xp/utils/dependencies.py,sha256=DBkzKKsRAw_dzLRlpQxaKKxtnytQA9G_a6YWglQDVlE,20664
|
|
207
189
|
xp/utils/event_helper.py,sha256=zD0K3TPfGEThU9vUNlDtglTai3Cmm30727iwjDZy6Dk,1007
|
|
208
190
|
xp/utils/logging.py,sha256=wJ1d-yg97NiZUrt2F8iDMcmnHVwC-PErcI-7dpyiRDc,3777
|
|
209
191
|
xp/utils/serialization.py,sha256=TS1OwpTOemSvXsCGw3js4JkYYFEqkzrPe8V9QYQefdw,4684
|
|
210
192
|
xp/utils/state_machine.py,sha256=W9AY4ntRZnFeHAa5d43hm37j53uJPlqkRvWTPiBhJ_0,2464
|
|
211
193
|
xp/utils/time_utils.py,sha256=K17godWpL18VEypbTlvNOEDG6R3huYnf29yjkcnwRpU,3796
|
|
212
|
-
conson_xp-
|
|
194
|
+
conson_xp-2.0.0.dist-info/RECORD,,
|
xp/__init__.py
CHANGED
xp/cli/commands/__init__.py
CHANGED
|
@@ -66,8 +66,6 @@ from xp.cli.commands.conbus.conbus_raw_commands import send_raw_telegrams
|
|
|
66
66
|
from xp.cli.commands.conbus.conbus_receive_commands import receive_telegrams
|
|
67
67
|
from xp.cli.commands.conbus.conbus_scan_commands import scan_module
|
|
68
68
|
from xp.cli.commands.file_commands import file
|
|
69
|
-
from xp.cli.commands.homekit.homekit import homekit
|
|
70
|
-
from xp.cli.commands.homekit.homekit_start_commands import homekit_start
|
|
71
69
|
from xp.cli.commands.module_commands import module
|
|
72
70
|
from xp.cli.commands.reverse_proxy_commands import reverse_proxy
|
|
73
71
|
from xp.cli.commands.server.server_commands import server
|
|
@@ -111,8 +109,6 @@ __all__ = [
|
|
|
111
109
|
"linknumber",
|
|
112
110
|
"blink",
|
|
113
111
|
"checksum",
|
|
114
|
-
"homekit",
|
|
115
|
-
"homekit_start",
|
|
116
112
|
"term",
|
|
117
113
|
# Individual command functions
|
|
118
114
|
"protocol_monitor",
|
|
@@ -57,7 +57,7 @@ def homekit_monitor(ctx: Context) -> None:
|
|
|
57
57
|
Start TUI for HomeKit accessory monitoring.
|
|
58
58
|
|
|
59
59
|
Displays HomeKit rooms and accessories with real-time state updates
|
|
60
|
-
in an interactive terminal interface. Press action keys (a-
|
|
60
|
+
in an interactive terminal interface. Press action keys (a-z0-9) to
|
|
61
61
|
toggle accessories.
|
|
62
62
|
|
|
63
63
|
Args:
|
xp/cli/main.py
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
import click
|
|
4
4
|
from click_help_colors import HelpColorsGroup
|
|
5
5
|
|
|
6
|
-
from xp.cli.commands import homekit
|
|
7
|
-
|
|
8
6
|
# Import all conbus command modules to register their commands
|
|
9
7
|
from xp.cli.commands.conbus import conbus_discover_commands # noqa: F401
|
|
10
8
|
from xp.cli.commands.conbus import conbus_export_commands # noqa: F401
|
|
@@ -47,7 +45,6 @@ def cli(ctx: click.Context) -> None:
|
|
|
47
45
|
|
|
48
46
|
# Register all command groups
|
|
49
47
|
cli.add_command(conbus)
|
|
50
|
-
cli.add_command(homekit)
|
|
51
48
|
cli.add_command(telegram)
|
|
52
49
|
cli.add_command(module)
|
|
53
50
|
cli.add_command(file)
|
|
@@ -16,10 +16,14 @@ class NetworkConfig(BaseModel):
|
|
|
16
16
|
Attributes:
|
|
17
17
|
ip: IP address for the network connection.
|
|
18
18
|
port: Port number for the network connection.
|
|
19
|
+
pincode: HomeKit pairing code (format: XXX-XX-XXX).
|
|
20
|
+
accessory_state_file: Path to file for persisting accessory state.
|
|
19
21
|
"""
|
|
20
22
|
|
|
21
23
|
ip: Union[IPvAnyAddress, IPv4Address, IPv6Address, str] = "127.0.0.1"
|
|
22
24
|
port: int = 51826
|
|
25
|
+
pincode: str = "031-45-154"
|
|
26
|
+
accessory_state_file: str = "./accessory.state"
|
|
23
27
|
|
|
24
28
|
|
|
25
29
|
class RoomConfig(BaseModel):
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
|
-
from
|
|
8
|
-
from pydantic import Field
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
9
8
|
|
|
10
9
|
from xp.models.config.conson_module_config import ConsonModuleConfig
|
|
11
10
|
from xp.models.homekit.homekit_config import HomekitAccessoryConfig
|
|
@@ -13,23 +12,25 @@ from xp.models.telegram.datapoint_type import DataPointType
|
|
|
13
12
|
|
|
14
13
|
if TYPE_CHECKING:
|
|
15
14
|
from xp.services.protocol.conbus_event_protocol import ConbusEventProtocol
|
|
16
|
-
from xp.services.protocol.telegram_protocol import TelegramProtocol
|
|
17
15
|
|
|
18
16
|
|
|
19
|
-
class ConnectionMadeEvent(
|
|
17
|
+
class ConnectionMadeEvent(BaseModel):
|
|
20
18
|
"""
|
|
21
19
|
Event dispatched when TCP connection is established.
|
|
22
20
|
|
|
23
21
|
Attributes:
|
|
24
|
-
|
|
22
|
+
model_config: Pydantic model configuration.
|
|
23
|
+
protocol: Reference to the ConbusEventProtocol instance.
|
|
25
24
|
"""
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
model_config = {"arbitrary_types_allowed": True}
|
|
27
|
+
|
|
28
|
+
protocol: ConbusEventProtocol = Field(
|
|
29
|
+
description="Reference to the ConbusEventProtocol instance"
|
|
29
30
|
)
|
|
30
31
|
|
|
31
32
|
|
|
32
|
-
class ConnectionFailedEvent(
|
|
33
|
+
class ConnectionFailedEvent(BaseModel):
|
|
33
34
|
"""
|
|
34
35
|
Event dispatched when TCP connection fails.
|
|
35
36
|
|
|
@@ -40,7 +41,7 @@ class ConnectionFailedEvent(BaseEvent):
|
|
|
40
41
|
reason: str = Field(description="Failure reason")
|
|
41
42
|
|
|
42
43
|
|
|
43
|
-
class SendWriteConfigEvent(
|
|
44
|
+
class SendWriteConfigEvent(BaseModel):
|
|
44
45
|
"""
|
|
45
46
|
Event for sending write config commands.
|
|
46
47
|
|
|
@@ -57,7 +58,7 @@ class SendWriteConfigEvent(BaseEvent):
|
|
|
57
58
|
value: int = Field(description="Set brightness value")
|
|
58
59
|
|
|
59
60
|
|
|
60
|
-
class SendActionEvent(
|
|
61
|
+
class SendActionEvent(BaseModel):
|
|
61
62
|
"""
|
|
62
63
|
Event for sending action commands.
|
|
63
64
|
|
|
@@ -76,7 +77,7 @@ class SendActionEvent(BaseEvent):
|
|
|
76
77
|
off_action: str = Field(description="off action")
|
|
77
78
|
|
|
78
79
|
|
|
79
|
-
class DatapointEvent(
|
|
80
|
+
class DatapointEvent(BaseModel):
|
|
80
81
|
"""
|
|
81
82
|
Base event for datapoint operations.
|
|
82
83
|
|
|
@@ -131,7 +132,7 @@ class ReadDatapointFromProtocolEvent(DatapointEvent):
|
|
|
131
132
|
pass
|
|
132
133
|
|
|
133
134
|
|
|
134
|
-
class ModuleEvent(
|
|
135
|
+
class ModuleEvent(BaseModel):
|
|
135
136
|
"""
|
|
136
137
|
Event dispatched when light bulb set is on.
|
|
137
138
|
|
|
@@ -163,7 +164,7 @@ class LightBulbSetOnEvent(ModuleEvent):
|
|
|
163
164
|
value: bool = Field(description="On or Off the light bulb set")
|
|
164
165
|
|
|
165
166
|
|
|
166
|
-
class LightBulbGetOnEvent(ModuleEvent
|
|
167
|
+
class LightBulbGetOnEvent(ModuleEvent):
|
|
167
168
|
"""Event dispatched when getting light bulb on state."""
|
|
168
169
|
|
|
169
170
|
pass
|
|
@@ -192,7 +193,7 @@ class OutletGetInUseEvent(ModuleEvent):
|
|
|
192
193
|
pass
|
|
193
194
|
|
|
194
195
|
|
|
195
|
-
class OutletSetInUseEvent(ModuleEvent
|
|
196
|
+
class OutletSetInUseEvent(ModuleEvent):
|
|
196
197
|
"""
|
|
197
198
|
Event dispatched when outlet set is on.
|
|
198
199
|
|
|
@@ -239,7 +240,7 @@ class DimmingLightGetBrightnessEvent(ModuleEvent):
|
|
|
239
240
|
pass
|
|
240
241
|
|
|
241
242
|
|
|
242
|
-
class ConnectionLostEvent(
|
|
243
|
+
class ConnectionLostEvent(BaseModel):
|
|
243
244
|
"""
|
|
244
245
|
Event dispatched when TCP connection is lost.
|
|
245
246
|
|
|
@@ -250,12 +251,13 @@ class ConnectionLostEvent(BaseEvent):
|
|
|
250
251
|
reason: str = Field(description="Disconnection reason")
|
|
251
252
|
|
|
252
253
|
|
|
253
|
-
class TelegramEvent(
|
|
254
|
+
class TelegramEvent(BaseModel):
|
|
254
255
|
"""
|
|
255
256
|
Event for telegram operations.
|
|
256
257
|
|
|
257
258
|
Attributes:
|
|
258
|
-
|
|
259
|
+
model_config: Pydantic model configuration.
|
|
260
|
+
protocol: ConbusEventProtocol instance.
|
|
259
261
|
frame: Frame <S0123450001F02D12FK>.
|
|
260
262
|
telegram: Telegram S0123450001F02D12FK.
|
|
261
263
|
payload: Payload S0123450001F02D12.
|
|
@@ -265,9 +267,9 @@ class TelegramEvent(BaseEvent):
|
|
|
265
267
|
checksum_valid: Checksum valid true or false.
|
|
266
268
|
"""
|
|
267
269
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
)
|
|
270
|
+
model_config = {"arbitrary_types_allowed": True}
|
|
271
|
+
|
|
272
|
+
protocol: ConbusEventProtocol = Field(description="ConbusEventProtocol instance")
|
|
271
273
|
frame: str = Field(description="Frame <S0123450001F02D12FK>")
|
|
272
274
|
telegram: str = Field(description="Telegram: S0123450001F02D12FK")
|
|
273
275
|
payload: str = Field(description="Payload: S0123450001F02D12")
|
|
@@ -279,7 +281,7 @@ class TelegramEvent(BaseEvent):
|
|
|
279
281
|
)
|
|
280
282
|
|
|
281
283
|
|
|
282
|
-
class ModuleStateChangedEvent(
|
|
284
|
+
class ModuleStateChangedEvent(BaseModel):
|
|
283
285
|
"""
|
|
284
286
|
Event dispatched when a module's state changes (from event telegram).
|
|
285
287
|
|
|
@@ -314,16 +316,19 @@ class TelegramReceivedEvent(TelegramEvent):
|
|
|
314
316
|
pass
|
|
315
317
|
|
|
316
318
|
|
|
317
|
-
class InvalidTelegramReceivedEvent(
|
|
319
|
+
class InvalidTelegramReceivedEvent(BaseModel):
|
|
318
320
|
"""
|
|
319
321
|
Event dispatched when an invalid telegram frame is received.
|
|
320
322
|
|
|
321
323
|
Attributes:
|
|
322
|
-
|
|
324
|
+
model_config: Pydantic model configuration.
|
|
325
|
+
protocol: ConbusEventProtocol instance.
|
|
323
326
|
frame: Frame <S0123450001F02D12FK>.
|
|
324
327
|
error: Error with the received telegram.
|
|
325
328
|
"""
|
|
326
329
|
|
|
327
|
-
|
|
330
|
+
model_config = {"arbitrary_types_allowed": True}
|
|
331
|
+
|
|
332
|
+
protocol: ConbusEventProtocol = Field(description="ConbusEventProtocol instance")
|
|
328
333
|
frame: str = Field(description="Frame <S0123450001F02D12FK>")
|
|
329
334
|
error: str = Field(description="Error with the received telegram")
|
|
@@ -13,7 +13,7 @@ class AccessoryState:
|
|
|
13
13
|
Attributes:
|
|
14
14
|
room_name: Room containing the accessory (e.g., "Salon").
|
|
15
15
|
accessory_name: Accessory display name (e.g., "Variateur salon").
|
|
16
|
-
action: Action key (a-
|
|
16
|
+
action: Action key (a-z0-9) for toggle control.
|
|
17
17
|
output_state: Output state ("ON", "OFF", "?").
|
|
18
18
|
dimming_state: Dimming percentage for dimmable modules, "-" if OFF, empty otherwise.
|
|
19
19
|
module_name: Module identifier (e.g., "A12").
|
xp/services/protocol/__init__.py
CHANGED
|
@@ -8,11 +8,10 @@ from xp.models.protocol.conbus_protocol import (
|
|
|
8
8
|
TelegramReceivedEvent,
|
|
9
9
|
)
|
|
10
10
|
from xp.services.protocol.conbus_event_protocol import ConbusEventProtocol
|
|
11
|
-
from xp.services.protocol.telegram_protocol import TelegramProtocol
|
|
12
11
|
|
|
13
|
-
__all__ = ["
|
|
12
|
+
__all__ = ["ConbusEventProtocol"]
|
|
14
13
|
|
|
15
|
-
# Rebuild models after
|
|
14
|
+
# Rebuild models after ConbusEventProtocol is imported to resolve forward references
|
|
16
15
|
ConnectionMadeEvent.model_rebuild()
|
|
17
16
|
InvalidTelegramReceivedEvent.model_rebuild()
|
|
18
17
|
ModuleDiscoveredEvent.model_rebuild()
|
|
@@ -169,7 +169,7 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
|
|
|
169
169
|
payload = telegram[:-2] # S0123450001F02D12
|
|
170
170
|
checksum = telegram[-2:].decode() # FK
|
|
171
171
|
serial_number = (
|
|
172
|
-
telegram[1:11] if telegram_type in ("S", "R") else
|
|
172
|
+
telegram[1:11].decode("latin-1") if telegram_type in ("S", "R") else ""
|
|
173
173
|
) # 0123450001
|
|
174
174
|
calculated_checksum = calculate_checksum(payload.decode(encoding="latin-1"))
|
|
175
175
|
|
|
@@ -391,12 +391,12 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
|
|
|
391
391
|
self.logger.debug(f"buildProtocol: {addr}")
|
|
392
392
|
return self
|
|
393
393
|
|
|
394
|
-
def clientConnectionFailed(self,
|
|
394
|
+
def clientConnectionFailed(self, _connector: IConnector, reason: Failure) -> None:
|
|
395
395
|
"""
|
|
396
396
|
Handle client connection failure.
|
|
397
397
|
|
|
398
398
|
Args:
|
|
399
|
-
|
|
399
|
+
_connector: Connection connector instance (unused, required by Twisted).
|
|
400
400
|
reason: Failure reason details.
|
|
401
401
|
"""
|
|
402
402
|
self.logger.debug(f"clientConnectionFailed: {reason}")
|
|
@@ -404,12 +404,12 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
|
|
|
404
404
|
self.connection_failed(reason)
|
|
405
405
|
self._cancel_timeout()
|
|
406
406
|
|
|
407
|
-
def clientConnectionLost(self,
|
|
407
|
+
def clientConnectionLost(self, _connector: IConnector, reason: Failure) -> None:
|
|
408
408
|
"""
|
|
409
409
|
Handle client connection lost event.
|
|
410
410
|
|
|
411
411
|
Args:
|
|
412
|
-
|
|
412
|
+
_connector: Connection connector instance (unused, required by Twisted).
|
|
413
413
|
reason: Reason for connection loss.
|
|
414
414
|
"""
|
|
415
415
|
self.logger.debug(f"clientConnectionLost: {reason}")
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"""HomeKit Accessory Driver for pyhap integration."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import logging
|
|
5
|
+
from typing import Callable, Dict, Optional
|
|
6
|
+
|
|
7
|
+
from pyhap.accessory import Accessory, Bridge
|
|
8
|
+
from pyhap.accessory_driver import AccessoryDriver
|
|
9
|
+
from pyhap.const import CATEGORY_LIGHTBULB, CATEGORY_OUTLET
|
|
10
|
+
|
|
11
|
+
from xp.models.homekit.homekit_config import HomekitConfig
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class XPAccessory(Accessory):
|
|
15
|
+
"""Single accessory wrapping a Conbus output."""
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
driver: "HomekitAccessoryDriver",
|
|
20
|
+
name: str,
|
|
21
|
+
display_name: str,
|
|
22
|
+
service_type: str,
|
|
23
|
+
aid: int,
|
|
24
|
+
) -> None:
|
|
25
|
+
"""
|
|
26
|
+
Initialize the XP accessory.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
driver: HomekitAccessoryDriver instance.
|
|
30
|
+
name: Accessory name (unique identifier for internal tracking).
|
|
31
|
+
display_name: Display name shown in HomeKit (from config description).
|
|
32
|
+
service_type: Service type ('light', 'outlet', 'dimminglight').
|
|
33
|
+
aid: Accessory ID for HomeKit.
|
|
34
|
+
"""
|
|
35
|
+
super().__init__(driver._driver, display_name, aid=aid)
|
|
36
|
+
self._hk_driver = driver
|
|
37
|
+
self._accessory_id = name
|
|
38
|
+
self.logger = logging.getLogger(__name__)
|
|
39
|
+
|
|
40
|
+
if service_type == "dimminglight":
|
|
41
|
+
self.category = CATEGORY_LIGHTBULB
|
|
42
|
+
serv = self.add_preload_service("Lightbulb", chars=["On", "Brightness"])
|
|
43
|
+
# Note: Brightness setter_callback deferred to future update
|
|
44
|
+
elif service_type == "outlet":
|
|
45
|
+
self.category = CATEGORY_OUTLET
|
|
46
|
+
serv = self.add_preload_service("Outlet")
|
|
47
|
+
else:
|
|
48
|
+
self.category = CATEGORY_LIGHTBULB
|
|
49
|
+
serv = self.add_preload_service("Lightbulb")
|
|
50
|
+
|
|
51
|
+
self._char_on = serv.configure_char("On", setter_callback=self._set_on)
|
|
52
|
+
|
|
53
|
+
def _set_on(self, value: bool) -> None:
|
|
54
|
+
"""
|
|
55
|
+
Handle HomeKit set on/off request.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
value: True for on, False for off.
|
|
59
|
+
"""
|
|
60
|
+
if self._hk_driver._on_set:
|
|
61
|
+
self._hk_driver._on_set(self._accessory_id, value)
|
|
62
|
+
|
|
63
|
+
def update_state(self, is_on: bool) -> None:
|
|
64
|
+
"""
|
|
65
|
+
Update accessory state from Conbus event.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
is_on: True if accessory is on, False otherwise.
|
|
69
|
+
"""
|
|
70
|
+
self._char_on.set_value(is_on)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class HomekitAccessoryDriver:
|
|
74
|
+
"""Wrapper around pyhap AccessoryDriver."""
|
|
75
|
+
|
|
76
|
+
def __init__(self, homekit_config: HomekitConfig) -> None:
|
|
77
|
+
"""
|
|
78
|
+
Initialize the HomeKit accessory driver.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
homekit_config: HomekitConfig with network and accessory settings.
|
|
82
|
+
"""
|
|
83
|
+
self.logger = logging.getLogger(__name__)
|
|
84
|
+
self._homekit_config = homekit_config
|
|
85
|
+
self._driver: Optional[AccessoryDriver] = None
|
|
86
|
+
self._accessories: Dict[str, XPAccessory] = {}
|
|
87
|
+
self._on_set: Optional[Callable[[str, bool], None]] = None
|
|
88
|
+
|
|
89
|
+
def set_callback(self, on_set: Callable[[str, bool], None]) -> None:
|
|
90
|
+
"""
|
|
91
|
+
Set callback for HomeKit set events.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
on_set: Callback(accessory_name, is_on) called when HomeKit app toggles.
|
|
95
|
+
"""
|
|
96
|
+
self._on_set = on_set
|
|
97
|
+
|
|
98
|
+
def _setup_bridge(self, config: HomekitConfig) -> None:
|
|
99
|
+
"""
|
|
100
|
+
Set up HomeKit bridge with accessories.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
config: HomekitConfig with accessory definitions.
|
|
104
|
+
"""
|
|
105
|
+
assert self._driver is not None
|
|
106
|
+
bridge = Bridge(self._driver, config.bridge.name)
|
|
107
|
+
aid = 2 # Bridge is 1
|
|
108
|
+
|
|
109
|
+
for acc_config in config.accessories:
|
|
110
|
+
accessory = XPAccessory(
|
|
111
|
+
driver=self,
|
|
112
|
+
name=acc_config.name,
|
|
113
|
+
display_name=acc_config.description,
|
|
114
|
+
service_type=acc_config.service,
|
|
115
|
+
aid=aid,
|
|
116
|
+
)
|
|
117
|
+
bridge.add_accessory(accessory)
|
|
118
|
+
self._accessories[acc_config.name] = accessory
|
|
119
|
+
aid += 1
|
|
120
|
+
|
|
121
|
+
self._driver.add_accessory(bridge)
|
|
122
|
+
|
|
123
|
+
async def start(self) -> None:
|
|
124
|
+
"""Start the AccessoryDriver (non-blocking)."""
|
|
125
|
+
try:
|
|
126
|
+
# Enable pyhap debug logging
|
|
127
|
+
pyhap_logger = logging.getLogger("pyhap")
|
|
128
|
+
pyhap_logger.setLevel(logging.DEBUG)
|
|
129
|
+
|
|
130
|
+
# Create driver with the running event loop
|
|
131
|
+
loop = asyncio.get_running_loop()
|
|
132
|
+
config = self._homekit_config
|
|
133
|
+
pincode = config.homekit.pincode.encode()
|
|
134
|
+
self.logger.info(
|
|
135
|
+
f"Starting HAP driver on {config.homekit.ip}:{config.homekit.port} with pincode {config.homekit.pincode}"
|
|
136
|
+
)
|
|
137
|
+
self._driver = AccessoryDriver(
|
|
138
|
+
loop=loop,
|
|
139
|
+
address=str(config.homekit.ip),
|
|
140
|
+
port=config.homekit.port,
|
|
141
|
+
pincode=pincode,
|
|
142
|
+
persist_file=config.homekit.accessory_state_file,
|
|
143
|
+
)
|
|
144
|
+
self._setup_bridge(config)
|
|
145
|
+
await self._driver.async_start()
|
|
146
|
+
self.logger.info("AccessoryDriver started successfully")
|
|
147
|
+
except Exception as e:
|
|
148
|
+
self.logger.error(f"Error starting AccessoryDriver: {e}", exc_info=True)
|
|
149
|
+
|
|
150
|
+
async def stop(self) -> None:
|
|
151
|
+
"""Stop the AccessoryDriver."""
|
|
152
|
+
if not self._driver:
|
|
153
|
+
return
|
|
154
|
+
try:
|
|
155
|
+
await self._driver.async_stop()
|
|
156
|
+
self.logger.info("AccessoryDriver stopped successfully")
|
|
157
|
+
except Exception as e:
|
|
158
|
+
self.logger.error(f"Error stopping AccessoryDriver: {e}", exc_info=True)
|
|
159
|
+
|
|
160
|
+
def update_state(self, accessory_name: str, is_on: bool) -> None:
|
|
161
|
+
"""
|
|
162
|
+
Update accessory state from Conbus event.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
accessory_name: Accessory name to update.
|
|
166
|
+
is_on: True if accessory is on, False otherwise.
|
|
167
|
+
"""
|
|
168
|
+
if acc := self._accessories.get(accessory_name):
|
|
169
|
+
acc.update_state(is_on)
|
|
170
|
+
else:
|
|
171
|
+
self.logger.warning(f"Unknown accessory name: {accessory_name}")
|