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.
Files changed (39) hide show
  1. {conson_xp-1.51.1.dist-info → conson_xp-2.0.0.dist-info}/METADATA +1 -11
  2. {conson_xp-1.51.1.dist-info → conson_xp-2.0.0.dist-info}/RECORD +20 -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/homekit/homekit_config.py +4 -0
  8. xp/models/protocol/conbus_protocol.py +30 -25
  9. xp/models/term/accessory_state.py +1 -1
  10. xp/services/protocol/__init__.py +2 -3
  11. xp/services/protocol/conbus_event_protocol.py +5 -5
  12. xp/services/term/homekit_accessory_driver.py +171 -0
  13. xp/services/term/homekit_service.py +187 -10
  14. xp/term/homekit.py +146 -14
  15. xp/term/homekit.tcss +4 -4
  16. xp/term/widgets/room_list.py +61 -3
  17. xp/utils/dependencies.py +34 -154
  18. xp/cli/commands/homekit/__init__.py +0 -3
  19. xp/cli/commands/homekit/homekit.py +0 -120
  20. xp/cli/commands/homekit/homekit_start_commands.py +0 -44
  21. xp/services/homekit/__init__.py +0 -1
  22. xp/services/homekit/homekit_cache_service.py +0 -313
  23. xp/services/homekit/homekit_conbus_service.py +0 -99
  24. xp/services/homekit/homekit_config_validator.py +0 -327
  25. xp/services/homekit/homekit_conson_validator.py +0 -130
  26. xp/services/homekit/homekit_dimminglight.py +0 -189
  27. xp/services/homekit/homekit_dimminglight_service.py +0 -155
  28. xp/services/homekit/homekit_hap_service.py +0 -351
  29. xp/services/homekit/homekit_lightbulb.py +0 -125
  30. xp/services/homekit/homekit_lightbulb_service.py +0 -91
  31. xp/services/homekit/homekit_module_service.py +0 -60
  32. xp/services/homekit/homekit_outlet.py +0 -175
  33. xp/services/homekit/homekit_outlet_service.py +0 -127
  34. xp/services/homekit/homekit_service.py +0 -371
  35. xp/services/protocol/protocol_factory.py +0 -84
  36. xp/services/protocol/telegram_protocol.py +0 -270
  37. {conson_xp-1.51.1.dist-info → conson_xp-2.0.0.dist-info}/WHEEL +0 -0
  38. {conson_xp-1.51.1.dist-info → conson_xp-2.0.0.dist-info}/entry_points.txt +0 -0
  39. {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: 1.51.1
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.51.1.dist-info/METADATA,sha256=15wTMgVInRD7kUjYvZe3AtZPgmPGG_XcXsaGRB3Vjds,11448
2
- conson_xp-1.51.1.dist-info/WHEEL,sha256=tsUv_t7BDeJeRHaSrczbGeuK-TtDpGsWi_JfpzD255I,90
3
- conson_xp-1.51.1.dist-info/entry_points.txt,sha256=1OcdIcDM1hz3ljCXgybaPUh1IOFEwkaTgLIW9u9zGeg,50
4
- conson_xp-1.51.1.dist-info/licenses/LICENSE,sha256=rxj6woMM-r3YCyGq_UHFtbh7kHTAJgrccH6O-33IDE4,1419
5
- xp/__init__.py,sha256=PTmuTUb4TXiPuSSkKX3UT63IhH_fx4EpMP33cMsA6Nc,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
@@ -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=EqoiZ1E6l9bBjxKqK1nxVGRfFY5ZtRHH-jZhYtRH2gU,3048
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,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/homekit_service.py,sha256=3g6Twhg6wcRT2E01Daa2J41lzdyX6gVjfz5wgutOvgQ,19307
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=IYJEVhQUFUcmC_TubYxcvlU5IKF-2sL_giBNKO35fjU,3642
193
- 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
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=3q3otusnQn4qFRbTY0-QbpMP3vPmywM0izYRA_KjXn0,7871
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=XHOAq5nIbXD8oq4FBp3wWvinDa4Ti7cUktJtUB0z51A,25339
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-1.51.1.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.51.1"
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)
@@ -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, 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}")
@@ -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}")