casambi-bt-revamped 0.3.12.dev3__py3-none-any.whl → 0.3.12.dev4__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.
- CasambiBt/_client.py +58 -40
- {casambi_bt_revamped-0.3.12.dev3.dist-info → casambi_bt_revamped-0.3.12.dev4.dist-info}/METADATA +1 -1
- {casambi_bt_revamped-0.3.12.dev3.dist-info → casambi_bt_revamped-0.3.12.dev4.dist-info}/RECORD +6 -6
- {casambi_bt_revamped-0.3.12.dev3.dist-info → casambi_bt_revamped-0.3.12.dev4.dist-info}/WHEEL +0 -0
- {casambi_bt_revamped-0.3.12.dev3.dist-info → casambi_bt_revamped-0.3.12.dev4.dist-info}/licenses/LICENSE +0 -0
- {casambi_bt_revamped-0.3.12.dev3.dist-info → casambi_bt_revamped-0.3.12.dev4.dist-info}/top_level.txt +0 -0
CasambiBt/_client.py
CHANGED
|
@@ -207,19 +207,23 @@ class CasambiClient:
|
|
|
207
207
|
self._logger.info(f"Connected to {self.address}")
|
|
208
208
|
self._connectionState = ConnectionState.CONNECTED
|
|
209
209
|
|
|
210
|
-
# Detect protocol mode
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
210
|
+
# Detect protocol mode.
|
|
211
|
+
#
|
|
212
|
+
# Important: Home Assistant wraps BleakClient (HaBleakClientWrapper) which does not implement
|
|
213
|
+
# `get_services()`. Therefore we use "try-read" probing instead of enumerating GATT services.
|
|
214
|
+
#
|
|
215
|
+
# Order:
|
|
216
|
+
# 1) Classic "non-conformant": CA51 (hash) + CA52 (data channel)
|
|
217
|
+
# 2) EVO: auth char read starts with 0x01 (NodeInfo)
|
|
218
|
+
# 3) Classic "conformant": auth char read returns connection hash (first 8 bytes used)
|
|
219
|
+
|
|
220
|
+
classic_hash: bytes | None = None
|
|
221
|
+
try:
|
|
222
|
+
classic_hash = await self._gattClient.read_gatt_char(CASA_CLASSIC_HASH_CHAR_UUID)
|
|
223
|
+
except Exception:
|
|
224
|
+
classic_hash = None
|
|
225
|
+
|
|
226
|
+
if classic_hash and len(classic_hash) >= 8:
|
|
223
227
|
if os.getenv("CASAMBI_BT_DISABLE_CLASSIC", "").strip() in {"1", "true", "TRUE", "yes", "YES"}:
|
|
224
228
|
raise ProtocolError("Classic protocol detected but disabled via CASAMBI_BT_DISABLE_CLASSIC=1")
|
|
225
229
|
|
|
@@ -232,7 +236,7 @@ class CasambiClient:
|
|
|
232
236
|
self._dataCharUuid = CASA_CLASSIC_DATA_CHAR_UUID
|
|
233
237
|
|
|
234
238
|
# Read connection hash (first 8 bytes are used for CMAC signing).
|
|
235
|
-
raw_hash =
|
|
239
|
+
raw_hash = classic_hash
|
|
236
240
|
if raw_hash is None or len(raw_hash) < 8:
|
|
237
241
|
raise ClassicHandshakeError(
|
|
238
242
|
f"Classic connection hash read failed/too short (len={0 if raw_hash is None else len(raw_hash)})."
|
|
@@ -247,34 +251,48 @@ class CasambiClient:
|
|
|
247
251
|
notify_params = inspect.signature(self._gattClient.start_notify).parameters
|
|
248
252
|
if "bluez" in notify_params:
|
|
249
253
|
notify_kwargs["bluez"] = {"use_start_notify": True}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
# Classic has no EVO-style key exchange/auth; we can send immediately.
|
|
257
|
-
self._connectionState = ConnectionState.AUTHENTICATED
|
|
258
|
-
self._logger.info("Protocol mode selected: CLASSIC")
|
|
259
|
-
if self._logger.isEnabledFor(logging.DEBUG):
|
|
260
|
-
self._logger.debug(
|
|
261
|
-
"[CASAMBI_CLASSIC_CONN_HASH] len=%d hash=%s",
|
|
262
|
-
len(self._classicConnHash8),
|
|
263
|
-
b2a(self._classicConnHash8),
|
|
254
|
+
try:
|
|
255
|
+
await self._gattClient.start_notify(
|
|
256
|
+
CASA_CLASSIC_DATA_CHAR_UUID,
|
|
257
|
+
self._queueCallback,
|
|
258
|
+
**notify_kwargs,
|
|
264
259
|
)
|
|
265
|
-
|
|
260
|
+
except Exception as e:
|
|
261
|
+
# Some firmwares may expose Classic signing on the EVO UUID instead.
|
|
262
|
+
# Fall through to auth-char probing if CA52 isn't available.
|
|
263
|
+
self._logger.debug("Classic CA52 notify failed; trying auth UUID probing.", exc_info=True)
|
|
264
|
+
self._protocolMode = None
|
|
265
|
+
self._dataCharUuid = None
|
|
266
|
+
self._classicConnHash8 = None
|
|
267
|
+
# continue detection below
|
|
268
|
+
else:
|
|
269
|
+
# Classic has no EVO-style key exchange/auth; we can send immediately.
|
|
270
|
+
self._connectionState = ConnectionState.AUTHENTICATED
|
|
271
|
+
self._logger.info("Protocol mode selected: CLASSIC")
|
|
272
|
+
if self._logger.isEnabledFor(logging.DEBUG):
|
|
273
|
+
self._logger.debug(
|
|
274
|
+
"[CASAMBI_CLASSIC_CONN_HASH] len=%d hash=%s",
|
|
275
|
+
len(self._classicConnHash8),
|
|
276
|
+
b2a(self._classicConnHash8),
|
|
277
|
+
)
|
|
278
|
+
return
|
|
266
279
|
|
|
267
280
|
# Conformant devices can expose the Classic signed channel on the EVO-style UUID too.
|
|
268
|
-
|
|
281
|
+
first: bytes | None = None
|
|
282
|
+
try:
|
|
269
283
|
first = await self._gattClient.read_gatt_char(CASA_AUTH_CHAR_UUID)
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
284
|
+
except Exception:
|
|
285
|
+
first = None
|
|
286
|
+
|
|
287
|
+
if first and len(first) >= 2 and first[0] == 0x01:
|
|
288
|
+
# EVO NodeInfo packet starts with 0x01.
|
|
289
|
+
self._protocolMode = ProtocolMode.EVO
|
|
290
|
+
self._dataCharUuid = CASA_AUTH_CHAR_UUID
|
|
291
|
+
self._checkProtocolVersion(self._network.protocolVersion)
|
|
292
|
+
self._logger.info("Protocol mode selected: EVO")
|
|
293
|
+
return
|
|
277
294
|
|
|
295
|
+
if first is not None:
|
|
278
296
|
# Otherwise, treat as Classic conformant: read provides connection hash.
|
|
279
297
|
if os.getenv("CASAMBI_BT_DISABLE_CLASSIC", "").strip() in {"1", "true", "TRUE", "yes", "YES"}:
|
|
280
298
|
raise ProtocolError("Classic protocol detected but disabled via CASAMBI_BT_DISABLE_CLASSIC=1")
|
|
@@ -282,9 +300,9 @@ class CasambiClient:
|
|
|
282
300
|
raise ClassicKeysMissingError(
|
|
283
301
|
"Classic protocol detected but network has no visitorKey/managerKey."
|
|
284
302
|
)
|
|
285
|
-
if
|
|
303
|
+
if len(first) < 8:
|
|
286
304
|
raise ClassicHandshakeError(
|
|
287
|
-
f"Classic connection hash read failed/too short (len={
|
|
305
|
+
f"Classic connection hash read failed/too short (len={len(first)})."
|
|
288
306
|
)
|
|
289
307
|
|
|
290
308
|
self._protocolMode = ProtocolMode.CLASSIC
|
|
@@ -313,7 +331,7 @@ class CasambiClient:
|
|
|
313
331
|
return
|
|
314
332
|
|
|
315
333
|
raise ProtocolError(
|
|
316
|
-
"No supported Casambi characteristics found (Classic ca51/ca52 or EVO/Classic
|
|
334
|
+
"No supported Casambi characteristics found (Classic ca51/ca52 or EVO/Classic-conformant auth char)."
|
|
317
335
|
)
|
|
318
336
|
|
|
319
337
|
def _on_disconnect(self, client: BleakClient) -> None:
|
{casambi_bt_revamped-0.3.12.dev3.dist-info → casambi_bt_revamped-0.3.12.dev4.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: casambi-bt-revamped
|
|
3
|
-
Version: 0.3.12.
|
|
3
|
+
Version: 0.3.12.dev4
|
|
4
4
|
Summary: Forked Casambi Bluetooth client library with switch event support, use original if no special need. https://github.com/lkempf/casambi-bt
|
|
5
5
|
Home-page: https://github.com/rankjie/casambi-bt
|
|
6
6
|
Author: rankjie
|
{casambi_bt_revamped-0.3.12.dev3.dist-info → casambi_bt_revamped-0.3.12.dev4.dist-info}/RECORD
RENAMED
|
@@ -2,7 +2,7 @@ CasambiBt/__init__.py,sha256=TW445xSu5PV3TyMjJfwaA1JoWvQQ8LXhZgGdDTfWf3s,302
|
|
|
2
2
|
CasambiBt/_cache.py,sha256=3bQil8vhSy4f4sf9JusMfEdQC7d3cJuva9qHhyKro-0,3808
|
|
3
3
|
CasambiBt/_casambi.py,sha256=TN4ecgjm95nSJ4h9TsKayNn577Y82fdsGK4IGUZF23Q,40666
|
|
4
4
|
CasambiBt/_classic_crypto.py,sha256=6DcCOdjLQo7k2cOOutNdUKupykOG_E2TDDwg6fH-ODM,998
|
|
5
|
-
CasambiBt/_client.py,sha256=
|
|
5
|
+
CasambiBt/_client.py,sha256=yTSuAeJhBXp5Zs3jU-RvHFEpI-quRNwlB3HWGl7q_yY,50730
|
|
6
6
|
CasambiBt/_constants.py,sha256=sbElg5W8eeQvvL1rHn_E0jhP1wOrrabc7dFLLnlDMsU,810
|
|
7
7
|
CasambiBt/_discover.py,sha256=jLc6H69JddrCURgtANZEjws6_UbSzXJtvJkbKTaIUHY,1849
|
|
8
8
|
CasambiBt/_encryption.py,sha256=CLcoOOrggQqhJbnr_emBnEnkizpWDvb_0yFnitq4_FM,3831
|
|
@@ -14,8 +14,8 @@ CasambiBt/_switch_events.py,sha256=S8OD0dBcw5T4J2C7qfmOQMnTJ7omIXRUYv4PqDOB87E,1
|
|
|
14
14
|
CasambiBt/_unit.py,sha256=KIpvUT_Wm-O2Lmb1JVnNO625-j5j7GqufmZzfTR-jW0,18587
|
|
15
15
|
CasambiBt/errors.py,sha256=1L_Q8og_N_BRYEKizghAQXr6tihlHykFgtcCHUDcBas,1961
|
|
16
16
|
CasambiBt/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
-
casambi_bt_revamped-0.3.12.
|
|
18
|
-
casambi_bt_revamped-0.3.12.
|
|
19
|
-
casambi_bt_revamped-0.3.12.
|
|
20
|
-
casambi_bt_revamped-0.3.12.
|
|
21
|
-
casambi_bt_revamped-0.3.12.
|
|
17
|
+
casambi_bt_revamped-0.3.12.dev4.dist-info/licenses/LICENSE,sha256=TAIIitFxpxEDi6Iju7foW4TDQmWvC-IhLVLhl67jKmQ,11341
|
|
18
|
+
casambi_bt_revamped-0.3.12.dev4.dist-info/METADATA,sha256=DKE1xb6Jg8lORTpoWyiM8qaSBOXOb5V_l7phDqWHGBA,5877
|
|
19
|
+
casambi_bt_revamped-0.3.12.dev4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
20
|
+
casambi_bt_revamped-0.3.12.dev4.dist-info/top_level.txt,sha256=uNbqLjtecFosoFzpGAC89-5icikWODKI8rOjbi8v_sA,10
|
|
21
|
+
casambi_bt_revamped-0.3.12.dev4.dist-info/RECORD,,
|
{casambi_bt_revamped-0.3.12.dev3.dist-info → casambi_bt_revamped-0.3.12.dev4.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|