conson-xp 1.52.0__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.
Files changed (38) hide show
  1. {conson_xp-1.52.0.dist-info → conson_xp-2.0.0.dist-info}/METADATA +1 -11
  2. {conson_xp-1.52.0.dist-info → conson_xp-2.0.0.dist-info}/RECORD +19 -38
  3. xp/__init__.py +1 -1
  4. xp/cli/commands/__init__.py +0 -4
  5. xp/cli/commands/term/term_commands.py +1 -1
  6. xp/cli/main.py +0 -3
  7. xp/models/protocol/conbus_protocol.py +30 -25
  8. xp/models/term/accessory_state.py +1 -1
  9. xp/services/protocol/__init__.py +2 -3
  10. xp/services/protocol/conbus_event_protocol.py +5 -5
  11. xp/services/term/homekit_accessory_driver.py +5 -2
  12. xp/services/term/homekit_service.py +118 -11
  13. xp/term/homekit.py +140 -8
  14. xp/term/homekit.tcss +4 -4
  15. xp/term/widgets/room_list.py +61 -3
  16. xp/utils/dependencies.py +24 -154
  17. xp/cli/commands/homekit/__init__.py +0 -3
  18. xp/cli/commands/homekit/homekit.py +0 -120
  19. xp/cli/commands/homekit/homekit_start_commands.py +0 -44
  20. xp/services/homekit/__init__.py +0 -1
  21. xp/services/homekit/homekit_cache_service.py +0 -313
  22. xp/services/homekit/homekit_conbus_service.py +0 -99
  23. xp/services/homekit/homekit_config_validator.py +0 -327
  24. xp/services/homekit/homekit_conson_validator.py +0 -130
  25. xp/services/homekit/homekit_dimminglight.py +0 -189
  26. xp/services/homekit/homekit_dimminglight_service.py +0 -155
  27. xp/services/homekit/homekit_hap_service.py +0 -351
  28. xp/services/homekit/homekit_lightbulb.py +0 -125
  29. xp/services/homekit/homekit_lightbulb_service.py +0 -91
  30. xp/services/homekit/homekit_module_service.py +0 -60
  31. xp/services/homekit/homekit_outlet.py +0 -175
  32. xp/services/homekit/homekit_outlet_service.py +0 -127
  33. xp/services/homekit/homekit_service.py +0 -371
  34. xp/services/protocol/protocol_factory.py +0 -84
  35. xp/services/protocol/telegram_protocol.py +0 -270
  36. {conson_xp-1.52.0.dist-info → conson_xp-2.0.0.dist-info}/WHEEL +0 -0
  37. {conson_xp-1.52.0.dist-info → conson_xp-2.0.0.dist-info}/entry_points.txt +0 -0
  38. {conson_xp-1.52.0.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: 1.52.0
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-1.52.0.dist-info/METADATA,sha256=eOYsythIuuDYadskAlya_jpbvYD2Wu-6MymZA0encfg,11448
2
- conson_xp-1.52.0.dist-info/WHEEL,sha256=tsUv_t7BDeJeRHaSrczbGeuK-TtDpGsWi_JfpzD255I,90
3
- conson_xp-1.52.0.dist-info/entry_points.txt,sha256=1OcdIcDM1hz3ljCXgybaPUh1IOFEwkaTgLIW9u9zGeg,50
4
- conson_xp-1.52.0.dist-info/licenses/LICENSE,sha256=rxj6woMM-r3YCyGq_UHFtbh7kHTAJgrccH6O-33IDE4,1419
5
- xp/__init__.py,sha256=wi3ok8DMPwweHsqxB5KwuT1FJynHp6v2d2Vt06prmpw,182
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=G7A1KFRSV0CEeDTqr_khu-K9_sc01CTI2KSfkFcaBRM,4949
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=Z3pq_xzP0j5YfYFOwASaZUxXDkikSV_E4cFjMb69LUU,1796
47
- xp/cli/main.py,sha256=Wbtji5ddW3IEoAfecHrEPk8W_w1bGD20B-NqAWfI_F4,1968
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
@@ -87,7 +84,7 @@ xp/models/homekit/homekit_accessory.py,sha256=ANjDWlFxeNTstl7lKdmf6vMOC0wc005vpi
87
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=hF78N5xvBzMiyWoKd8i_avA8kJ1As_9Pplkw1GMqKzk,9145
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=GcMtCxOeHpc3IPDO1F9j2I6rdhaNV75iQ2md--XY6jo,1650
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=4zC__3e-Hma_IrmFCvsL44wJRd5LLHLSI_tahqdaTF8,741
163
- xp/services/protocol/conbus_event_protocol.py,sha256=7AMn_5jr8lWPbf3C2s0P-r-w4PgdsmsBVcK0UMmrdaw,19572
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,13 +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/homekit_accessory_driver.py,sha256=vCkeXHwIBwUIuUGoTdflbIOm8EQhT33pX8j4Smhr1co,5759
189
- xp/services/term/homekit_service.py,sha256=QZnAzgOVIZ8vlfa1ehIp4Q1zZyIAj2f0SB1W8wdmemo,21895
169
+ xp/services/term/homekit_accessory_driver.py,sha256=jHhHHOOvzdDjuYys1cUZHcH2uwZy_Y6o5aGAQqXGAVg,5935
170
+ xp/services/term/homekit_service.py,sha256=h1wAguhUG9f8cdolFKsp-V-iZV5x52Wm0L7syKoK6Qs,25183
190
171
  xp/services/term/protocol_monitor_service.py,sha256=5YBI0Nu7B7gMhaTbUhL6k9LSRfnCIj6CwrCYHiMHavA,10067
191
172
  xp/services/term/state_monitor_service.py,sha256=EK9tNBfamAIV0z0EMsXDYWC-rXv6l6k_bHsC8xyEFSo,17116
192
173
  xp/term/__init__.py,sha256=Xg2DhBeI3xQJLfc7_BPWI1por-rUXemyer5OtOt9Cus,51
193
- xp/term/homekit.py,sha256=xN2BiMHHF3tPR96ixg_qO5y6fDNTkjEzau3YDTNuk1U,3711
194
- xp/term/homekit.tcss,sha256=qeR_OV8D_9Mxb-aPNz-MH0ZJOsdCk-fJ-zv6CQV5ihw,1382
174
+ xp/term/homekit.py,sha256=A9l9zK6KSBx_Cc8I_AZhAWdQjZYnTGLxkln6CzFn3-Q,8935
175
+ xp/term/homekit.tcss,sha256=A1f5-V3mvxAMZK_ERq8lLjNcOWH0U5tblIBbeL3OYYM,1382
195
176
  xp/term/protocol.py,sha256=6MX3mduLei-AgLGaIe8lfOSu4Hi0y3KGePFFM2ssstc,3475
196
177
  xp/term/protocol.tcss,sha256=r_KfxrbpycGHLVXqZc6INBBcUJME0hLrAZkF1oqnab4,2126
197
178
  xp/term/state.py,sha256=FBpYV_bWYJh9o17qcMx6sHgUARQS-uNOtUt6G7Vs1n8,3274
@@ -200,14 +181,14 @@ xp/term/widgets/__init__.py,sha256=ftWmN_fmjxy2E8Qfm-YSRmzKfgL0KTBCTpgvYWCPbUY,2
200
181
  xp/term/widgets/help_menu.py,sha256=KLkdIXfhARLFNEs2lv1u0sYBz9LzOCcDLxbMGzc7e5Y,1812
201
182
  xp/term/widgets/modules_list.py,sha256=qAG-n0nK0YdNE9v4C3-sHgxLvF1i1FR7v_GArdaoUQw,7831
202
183
  xp/term/widgets/protocol_log.py,sha256=E68QmSMpOFrvrPTo_gOQVfyiDqY5c_y8fkNKnQw6Vwo,2650
203
- xp/term/widgets/room_list.py,sha256=3q3otusnQn4qFRbTY0-QbpMP3vPmywM0izYRA_KjXn0,7871
184
+ xp/term/widgets/room_list.py,sha256=ecdpK-QOP1Zmi0ntYxpWhik9EQc8wBNNjPirMWhJ7gs,9807
204
185
  xp/term/widgets/status_footer.py,sha256=biV3EzfVSgm1T7Ofi88LXsTFCkD5mI_6Cpe-RpuOSxA,3429
205
186
  xp/utils/__init__.py,sha256=_avMF_UOkfR3tNeDIPqQ5odmbq5raKkaq1rZ9Cn1CJs,332
206
187
  xp/utils/checksum.py,sha256=Px1S3dFGA-_plavBxrq3IqmprNlgtNDunE3whg6Otwg,1722
207
- xp/utils/dependencies.py,sha256=McCgnBrg0Jw98_bFQv3uPG0bYkGKHC-mFJPmILlvv5k,25754
188
+ xp/utils/dependencies.py,sha256=DBkzKKsRAw_dzLRlpQxaKKxtnytQA9G_a6YWglQDVlE,20664
208
189
  xp/utils/event_helper.py,sha256=zD0K3TPfGEThU9vUNlDtglTai3Cmm30727iwjDZy6Dk,1007
209
190
  xp/utils/logging.py,sha256=wJ1d-yg97NiZUrt2F8iDMcmnHVwC-PErcI-7dpyiRDc,3777
210
191
  xp/utils/serialization.py,sha256=TS1OwpTOemSvXsCGw3js4JkYYFEqkzrPe8V9QYQefdw,4684
211
192
  xp/utils/state_machine.py,sha256=W9AY4ntRZnFeHAa5d43hm37j53uJPlqkRvWTPiBhJ_0,2464
212
193
  xp/utils/time_utils.py,sha256=K17godWpL18VEypbTlvNOEDG6R3huYnf29yjkcnwRpU,3796
213
- conson_xp-1.52.0.dist-info/RECORD,,
194
+ conson_xp-2.0.0.dist-info/RECORD,,
xp/__init__.py CHANGED
@@ -4,7 +4,7 @@ XP CLI tool for remote console bus operations.
4
4
  conson-xp package.
5
5
  """
6
6
 
7
- __version__ = "1.52.0"
7
+ __version__ = "2.0.0"
8
8
  __manufacturer__ = "salchichon"
9
9
  __model__ = "xp.cli"
10
10
  __serial__ = "2025.09.23.000"
@@ -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-z) to
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)
@@ -2,10 +2,9 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import TYPE_CHECKING, Union
5
+ from typing import TYPE_CHECKING
6
6
 
7
- from bubus import BaseEvent
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(BaseEvent):
17
+ class ConnectionMadeEvent(BaseModel):
20
18
  """
21
19
  Event dispatched when TCP connection is established.
22
20
 
23
21
  Attributes:
24
- protocol: Reference to the TelegramProtocol instance.
22
+ model_config: Pydantic model configuration.
23
+ protocol: Reference to the ConbusEventProtocol instance.
25
24
  """
26
25
 
27
- protocol: TelegramProtocol = Field(
28
- description="Reference to the TelegramProtocol instance"
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(BaseEvent):
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(BaseEvent):
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(BaseEvent):
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(BaseEvent):
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(BaseEvent):
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, BaseEvent[bool]):
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, BaseEvent[bool]):
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(BaseEvent):
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(BaseEvent):
254
+ class TelegramEvent(BaseModel):
254
255
  """
255
256
  Event for telegram operations.
256
257
 
257
258
  Attributes:
258
- protocol: TelegramProtocol instance.
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
- protocol: Union[TelegramProtocol, ConbusEventProtocol] = Field(
269
- description="TelegramProtocol instance"
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(BaseEvent):
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(BaseEvent):
319
+ class InvalidTelegramReceivedEvent(BaseModel):
318
320
  """
319
321
  Event dispatched when an invalid telegram frame is received.
320
322
 
321
323
  Attributes:
322
- protocol: TelegramProtocol instance.
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
- protocol: TelegramProtocol = Field(description="TelegramProtocol instance")
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-z) for toggle control.
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").
@@ -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__ = ["TelegramProtocol", "ConbusEventProtocol"]
12
+ __all__ = ["ConbusEventProtocol"]
14
13
 
15
- # Rebuild models after TelegramProtocol and ConbusEventProtocol are imported to resolve forward references
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 b""
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, connector: IConnector, reason: Failure) -> None:
394
+ def clientConnectionFailed(self, _connector: IConnector, reason: Failure) -> None:
395
395
  """
396
396
  Handle client connection failure.
397
397
 
398
398
  Args:
399
- connector: Connection connector instance.
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, connector: IConnector, reason: Failure) -> None:
407
+ def clientConnectionLost(self, _connector: IConnector, reason: Failure) -> None:
408
408
  """
409
409
  Handle client connection lost event.
410
410
 
411
411
  Args:
412
- connector: Connection connector instance.
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}")
@@ -18,6 +18,7 @@ class XPAccessory(Accessory):
18
18
  self,
19
19
  driver: "HomekitAccessoryDriver",
20
20
  name: str,
21
+ display_name: str,
21
22
  service_type: str,
22
23
  aid: int,
23
24
  ) -> None:
@@ -26,11 +27,12 @@ class XPAccessory(Accessory):
26
27
 
27
28
  Args:
28
29
  driver: HomekitAccessoryDriver instance.
29
- name: Accessory name (unique identifier and display name).
30
+ name: Accessory name (unique identifier for internal tracking).
31
+ display_name: Display name shown in HomeKit (from config description).
30
32
  service_type: Service type ('light', 'outlet', 'dimminglight').
31
33
  aid: Accessory ID for HomeKit.
32
34
  """
33
- super().__init__(driver._driver, name, aid=aid)
35
+ super().__init__(driver._driver, display_name, aid=aid)
34
36
  self._hk_driver = driver
35
37
  self._accessory_id = name
36
38
  self.logger = logging.getLogger(__name__)
@@ -108,6 +110,7 @@ class HomekitAccessoryDriver:
108
110
  accessory = XPAccessory(
109
111
  driver=self,
110
112
  name=acc_config.name,
113
+ display_name=acc_config.description,
111
114
  service_type=acc_config.service,
112
115
  aid=aid,
113
116
  )
@@ -89,7 +89,7 @@ class HomekitService:
89
89
 
90
90
  def _initialize_accessory_states(self) -> None:
91
91
  """Initialize accessory states from HomekitConfig and ConsonModuleListConfig."""
92
- action_keys = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
92
+ action_keys = "abcdefghijklmnopqrstuvwxyz0123456789"
93
93
  action_index = 0
94
94
  sort_order = 0
95
95
 
@@ -180,6 +180,23 @@ class HomekitService:
180
180
  return accessory
181
181
  return None
182
182
 
183
+ def _find_accessory_config_by_id(
184
+ self, accessory_id: str
185
+ ) -> Optional[HomekitAccessoryConfig]:
186
+ """
187
+ Find accessory config by accessory ID.
188
+
189
+ Args:
190
+ accessory_id: Accessory ID (e.g., "A12_1").
191
+
192
+ Returns:
193
+ HomekitAccessoryConfig if found, None otherwise.
194
+ """
195
+ state = self._accessory_states.get(accessory_id)
196
+ if not state:
197
+ return None
198
+ return self._find_accessory_config_by_output(state.serial_number, state.output)
199
+
183
200
  def _connect_signals(self) -> None:
184
201
  """Connect to protocol signals."""
185
202
  self._conbus_protocol.on_connection_made.connect(self._on_connection_made)
@@ -291,13 +308,23 @@ class HomekitService:
291
308
  config = self._find_accessory_config(accessory_name)
292
309
  if config:
293
310
  action = config.on_action if is_on else config.off_action
294
- self._conbus_protocol.send_raw_telegram(action)
311
+ self.send_action(action)
295
312
  self.on_status_message.emit(
296
313
  f"HomeKit: {accessory_name} {'ON' if is_on else 'OFF'}"
297
314
  )
298
315
  else:
299
316
  self.logger.warning(f"No config found for accessory: {accessory_name}")
300
317
 
318
+ def send_action(self, action: str) -> None:
319
+ """
320
+ Send an action telegram to the conbus protocol.
321
+
322
+ Args:
323
+ action: The action string to send (e.g., "E00L00I00").
324
+ """
325
+ self._conbus_protocol.send_raw_telegram(f"{action}M")
326
+ self._conbus_protocol.send_raw_telegram(f"{action}B")
327
+
301
328
  def toggle_connection(self) -> None:
302
329
  """
303
330
  Toggle connection state between connected and disconnected.
@@ -313,31 +340,111 @@ class HomekitService:
313
340
  else:
314
341
  self.connect()
315
342
 
316
- def toggle_accessory(self, action_key: str) -> bool:
343
+ def select_accessory(self, action_key: str) -> Optional[str]:
344
+ """
345
+ Get accessory ID for action key.
346
+
347
+ Args:
348
+ action_key: Action key (a-z0-9).
349
+
350
+ Returns:
351
+ Accessory ID if found, None otherwise.
317
352
  """
318
- Toggle accessory by action key.
353
+ return self._action_map.get(action_key)
319
354
 
320
- Sends the toggle_action telegram for the accessory mapped to the given key.
355
+ def toggle_selected(self, accessory_id: str) -> bool:
356
+ """
357
+ Toggle accessory by ID.
321
358
 
322
359
  Args:
323
- action_key: Action key (a-z).
360
+ accessory_id: Accessory ID (e.g., "A12_1").
324
361
 
325
362
  Returns:
326
363
  True if toggle was sent, False otherwise.
327
364
  """
328
- accessory_id = self._action_map.get(action_key)
329
- if not accessory_id:
330
- return False
331
-
332
365
  state = self._accessory_states.get(accessory_id)
333
366
  if not state or not state.toggle_action:
334
367
  self.logger.warning(f"No toggle_action for accessory {accessory_id}")
335
368
  return False
336
369
 
337
- self._conbus_protocol.send_raw_telegram(state.toggle_action)
370
+ self.send_action(state.toggle_action)
338
371
  self.on_status_message.emit(f"Toggling {state.accessory_name}")
339
372
  return True
340
373
 
374
+ def turn_on_selected(self, accessory_id: str) -> bool:
375
+ """
376
+ Turn on accessory by ID.
377
+
378
+ Args:
379
+ accessory_id: Accessory ID (e.g., "A12_1").
380
+
381
+ Returns:
382
+ True if on command was sent, False otherwise.
383
+ """
384
+ config = self._find_accessory_config_by_id(accessory_id)
385
+ state = self._accessory_states.get(accessory_id)
386
+ if not config or not state:
387
+ self.logger.warning(f"No config for accessory {accessory_id}")
388
+ return False
389
+
390
+ self.send_action(config.on_action)
391
+ self.on_status_message.emit(f"Turning ON {state.accessory_name}")
392
+ return True
393
+
394
+ def turn_off_selected(self, accessory_id: str) -> bool:
395
+ """
396
+ Turn off accessory by ID.
397
+
398
+ Args:
399
+ accessory_id: Accessory ID (e.g., "A12_1").
400
+
401
+ Returns:
402
+ True if off command was sent, False otherwise.
403
+ """
404
+ config = self._find_accessory_config_by_id(accessory_id)
405
+ state = self._accessory_states.get(accessory_id)
406
+ if not config or not state:
407
+ self.logger.warning(f"No config for accessory {accessory_id}")
408
+ return False
409
+
410
+ self.send_action(config.off_action)
411
+ self.on_status_message.emit(f"Turning OFF {state.accessory_name}")
412
+ return True
413
+
414
+ def increase_dimmer(self, accessory_id: str) -> bool:
415
+ """
416
+ Increase dimmer level for accessory.
417
+
418
+ Args:
419
+ accessory_id: Accessory ID (e.g., "A12_1").
420
+
421
+ Returns:
422
+ True if command was sent, False otherwise.
423
+ """
424
+ state = self._accessory_states.get(accessory_id)
425
+ if not state:
426
+ return False
427
+ # TODO: Implement dimmer control
428
+ self.on_status_message.emit(f"Dimmer+ {state.accessory_name} (not implemented)")
429
+ return False
430
+
431
+ def decrease_dimmer(self, accessory_id: str) -> bool:
432
+ """
433
+ Decrease dimmer level for accessory.
434
+
435
+ Args:
436
+ accessory_id: Accessory ID (e.g., "A12_1").
437
+
438
+ Returns:
439
+ True if command was sent, False otherwise.
440
+ """
441
+ state = self._accessory_states.get(accessory_id)
442
+ if not state:
443
+ return False
444
+ # TODO: Implement dimmer control
445
+ self.on_status_message.emit(f"Dimmer- {state.accessory_name} (not implemented)")
446
+ return False
447
+
341
448
  def refresh_all(self) -> None:
342
449
  """
343
450
  Refresh all module states.