casambi-bt-revamped 0.3.6.dev1__py3-none-any.whl → 0.3.6.dev3__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 +38 -47
- {casambi_bt_revamped-0.3.6.dev1.dist-info → casambi_bt_revamped-0.3.6.dev3.dist-info}/METADATA +1 -1
- {casambi_bt_revamped-0.3.6.dev1.dist-info → casambi_bt_revamped-0.3.6.dev3.dist-info}/RECORD +6 -6
- {casambi_bt_revamped-0.3.6.dev1.dist-info → casambi_bt_revamped-0.3.6.dev3.dist-info}/WHEEL +0 -0
- {casambi_bt_revamped-0.3.6.dev1.dist-info → casambi_bt_revamped-0.3.6.dev3.dist-info}/licenses/LICENSE +0 -0
- {casambi_bt_revamped-0.3.6.dev1.dist-info → casambi_bt_revamped-0.3.6.dev3.dist-info}/top_level.txt +0 -0
CasambiBt/_client.py
CHANGED
|
@@ -421,23 +421,33 @@ class CasambiClient:
|
|
|
421
421
|
# TODO: Check incoming counter and direction flag
|
|
422
422
|
self._inPacketCount += 1
|
|
423
423
|
|
|
424
|
-
# Store raw encrypted packet for
|
|
425
|
-
|
|
424
|
+
# Store raw encrypted packet for Android parser analysis
|
|
425
|
+
raw_encrypted_packet = data[:]
|
|
426
|
+
|
|
427
|
+
# Android parser comparison - disabled as protocols are incompatible
|
|
428
|
+
android_switch_event = None
|
|
429
|
+
# The Android parser expects a completely different packet format than what
|
|
430
|
+
# this implementation uses. Logging disabled to reduce noise.
|
|
426
431
|
|
|
427
432
|
try:
|
|
428
|
-
|
|
433
|
+
decrypted_data = self._encryptor.decryptAndVerify(data, data[:4] + self._nonce[4:])
|
|
429
434
|
except InvalidSignature:
|
|
430
435
|
# We only drop packets with invalid signature here instead of going into an error state
|
|
431
436
|
self._logger.error(f"Invalid signature for packet {b2a(data)}!")
|
|
432
437
|
return
|
|
438
|
+
|
|
439
|
+
# Protocol analysis: Current implementation vs Android
|
|
440
|
+
# Current: Encrypted packets decrypt to [packet_type][payload] format
|
|
441
|
+
# Android: Uses different structure with header/command/origin/target
|
|
442
|
+
# These are incompatible protocol formats
|
|
433
443
|
|
|
434
|
-
packetType =
|
|
435
|
-
self._logger.debug(f"Incoming data of type {packetType}: {b2a(
|
|
444
|
+
packetType = decrypted_data[0]
|
|
445
|
+
self._logger.debug(f"Incoming data of type {packetType}: {b2a(decrypted_data)}")
|
|
436
446
|
|
|
437
447
|
if packetType == IncommingPacketType.UnitState:
|
|
438
|
-
self._parseUnitStates(
|
|
448
|
+
self._parseUnitStates(decrypted_data[1:])
|
|
439
449
|
elif packetType == IncommingPacketType.SwitchEvent:
|
|
440
|
-
self._parseSwitchEvent(
|
|
450
|
+
self._parseSwitchEvent(decrypted_data[1:], self._inPacketCount, raw_encrypted_packet, android_switch_event)
|
|
441
451
|
elif packetType == IncommingPacketType.NetworkConfig:
|
|
442
452
|
# We don't care about the config the network thinks it has.
|
|
443
453
|
# We assume that cloud config and local config match.
|
|
@@ -491,23 +501,13 @@ class CasambiClient:
|
|
|
491
501
|
f"Ran out of data while parsing unit state! Remaining data {b2a(data[oldPos:])} in {b2a(data)}."
|
|
492
502
|
)
|
|
493
503
|
|
|
494
|
-
def _parseSwitchEvent(self, data: bytes, packet_seq: int = None, raw_packet: bytes = None) -> None:
|
|
504
|
+
def _parseSwitchEvent(self, data: bytes, packet_seq: int = None, raw_packet: bytes = None, android_switch_event: dict = None) -> None:
|
|
495
505
|
"""Parse switch event packet which contains multiple message types"""
|
|
496
506
|
self._logger.info(f"Parsing incoming switch event packet... Data: {b2a(data)}")
|
|
497
507
|
|
|
498
|
-
#
|
|
499
|
-
if
|
|
500
|
-
|
|
501
|
-
# The raw_packet includes encryption, we need the decrypted version
|
|
502
|
-
# which starts after the type byte (data includes content after type byte)
|
|
503
|
-
# Reconstruct the full decrypted packet for Android parser
|
|
504
|
-
full_packet = bytes([IncommingPacketType.SwitchEvent]) + data
|
|
505
|
-
android_result = AndroidPacketParser.parse_complete_packet(full_packet)
|
|
506
|
-
if android_result.get('switch_event'):
|
|
507
|
-
self._logger.info(f"Android parser result: {android_result['switch_event']['android_log']}")
|
|
508
|
-
self._logger.debug(f"Android parser details: {android_result}")
|
|
509
|
-
except Exception as e:
|
|
510
|
-
self._logger.debug(f"Android parser comparison failed: {e}")
|
|
508
|
+
# Log Android parser result if available
|
|
509
|
+
if android_switch_event:
|
|
510
|
+
self._logger.info(f"Android parser comparison: {android_switch_event['android_log']}")
|
|
511
511
|
|
|
512
512
|
pos = 0
|
|
513
513
|
oldPos = 0
|
|
@@ -536,7 +536,7 @@ class CasambiClient:
|
|
|
536
536
|
|
|
537
537
|
# Process based on message type
|
|
538
538
|
if message_type == 0x08 or message_type == 0x10: # Switch/button events
|
|
539
|
-
self._processSwitchMessage(message_type, flags, parameter, payload, data, oldPos, packet_seq, raw_packet)
|
|
539
|
+
self._processSwitchMessage(message_type, flags, parameter, payload, data, oldPos, packet_seq, raw_packet, android_switch_event)
|
|
540
540
|
else:
|
|
541
541
|
# Log other message types for now
|
|
542
542
|
self._logger.debug(
|
|
@@ -552,7 +552,7 @@ class CasambiClient:
|
|
|
552
552
|
f"Remaining data {b2a(data[oldPos:])} in {b2a(data)}."
|
|
553
553
|
)
|
|
554
554
|
|
|
555
|
-
def _processSwitchMessage(self, message_type: int, flags: int, button: int, payload: bytes, full_data: bytes, start_pos: int, packet_seq: int = None, raw_packet: bytes = None) -> None:
|
|
555
|
+
def _processSwitchMessage(self, message_type: int, flags: int, button: int, payload: bytes, full_data: bytes, start_pos: int, packet_seq: int = None, raw_packet: bytes = None, android_switch_event: dict = None) -> None:
|
|
556
556
|
"""Process a switch/button message (types 0x08 or 0x10)"""
|
|
557
557
|
if not payload:
|
|
558
558
|
self._logger.error("Switch message has empty payload")
|
|
@@ -602,31 +602,22 @@ class CasambiClient:
|
|
|
602
602
|
f"action={action_display} ({event_string}), flags=0x{flags:02x}"
|
|
603
603
|
)
|
|
604
604
|
|
|
605
|
-
#
|
|
605
|
+
# Include Android parser comparison if available
|
|
606
606
|
android_comparison = None
|
|
607
|
-
if
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
self._logger.info(f"Android parser comparison: {android_evt['android_log']}")
|
|
622
|
-
|
|
623
|
-
# Log differences
|
|
624
|
-
if android_evt['unit_id'] != unit_id:
|
|
625
|
-
self._logger.warning(f"Unit ID mismatch: current={unit_id}, android={android_evt['unit_id']}")
|
|
626
|
-
if android_evt['button'] != button:
|
|
627
|
-
self._logger.warning(f"Button mismatch: current={button}, android={android_evt['button']}")
|
|
628
|
-
except Exception as e:
|
|
629
|
-
self._logger.debug(f"Android parser comparison failed: {e}")
|
|
607
|
+
if android_switch_event:
|
|
608
|
+
android_comparison = {
|
|
609
|
+
'unit_id': android_switch_event['unit_id'],
|
|
610
|
+
'button': android_switch_event['button'],
|
|
611
|
+
'state': android_switch_event['state'],
|
|
612
|
+
'param_p': android_switch_event['param_p'],
|
|
613
|
+
'param_s': android_switch_event['param_s'],
|
|
614
|
+
'android_log': android_switch_event['android_log']
|
|
615
|
+
}
|
|
616
|
+
# Log differences
|
|
617
|
+
if android_switch_event['unit_id'] != unit_id:
|
|
618
|
+
self._logger.warning(f"Unit ID mismatch: current={unit_id}, android={android_switch_event['unit_id']}")
|
|
619
|
+
if android_switch_event['button'] != button:
|
|
620
|
+
self._logger.warning(f"Button mismatch: current={button}, android={android_switch_event['button']}")
|
|
630
621
|
|
|
631
622
|
self._dataCallback(
|
|
632
623
|
IncommingPacketType.SwitchEvent,
|
{casambi_bt_revamped-0.3.6.dev1.dist-info → casambi_bt_revamped-0.3.6.dev3.dist-info}/RECORD
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
CasambiBt/__init__.py,sha256=TW445xSu5PV3TyMjJfwaA1JoWvQQ8LXhZgGdDTfWf3s,302
|
|
2
2
|
CasambiBt/_cache.py,sha256=KZ2xbiHAHXUPa8Gw_75Nw9NL4QSY_sTWHbyYXYUDaB0,3865
|
|
3
3
|
CasambiBt/_casambi.py,sha256=gLLkhEcObgapqTx5Mk7WRClyG29UyfZYZCCIhhOg4H4,23101
|
|
4
|
-
CasambiBt/_client.py,sha256=
|
|
4
|
+
CasambiBt/_client.py,sha256=iGeJ1isvX-B7VqYr0s52djE9UR1uiM5TREzaYO9k5vw,25894
|
|
5
5
|
CasambiBt/_client_android_parser.py,sha256=1lVkVYMO0Nhh9_nkNwgb68hlCS_uD8WxYQDir5hOdHs,7744
|
|
6
6
|
CasambiBt/_constants.py,sha256=_AxkG7Btxl4VeS6mO7GJW5Kc9dFs3s9sDmtJ83ZEKNw,359
|
|
7
7
|
CasambiBt/_discover.py,sha256=H7HpiFYIy9ELvmPXXd_ck-5O5invJf15dDIRk-vO5IE,1696
|
|
@@ -12,8 +12,8 @@ CasambiBt/_operation.py,sha256=-BuC1Bvtg-G-zSN_b_0JMvXdHZaR6LbTw0S425jg96c,842
|
|
|
12
12
|
CasambiBt/_unit.py,sha256=YiQWoHmMDWHHo4XAjtW8rHsBqIqpmp9MVdv1Mbu2xw4,17043
|
|
13
13
|
CasambiBt/errors.py,sha256=0JgDjaKlAKDes0poWzA8nrTUYQ8qdNfBb8dfaqqzCRA,1664
|
|
14
14
|
CasambiBt/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
casambi_bt_revamped-0.3.6.
|
|
16
|
-
casambi_bt_revamped-0.3.6.
|
|
17
|
-
casambi_bt_revamped-0.3.6.
|
|
18
|
-
casambi_bt_revamped-0.3.6.
|
|
19
|
-
casambi_bt_revamped-0.3.6.
|
|
15
|
+
casambi_bt_revamped-0.3.6.dev3.dist-info/licenses/LICENSE,sha256=TAIIitFxpxEDi6Iju7foW4TDQmWvC-IhLVLhl67jKmQ,11341
|
|
16
|
+
casambi_bt_revamped-0.3.6.dev3.dist-info/METADATA,sha256=sVnGlUxEcV6DpklIygo-2IXVZz0-EM85_I_-XqtBh2Y,3049
|
|
17
|
+
casambi_bt_revamped-0.3.6.dev3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
18
|
+
casambi_bt_revamped-0.3.6.dev3.dist-info/top_level.txt,sha256=uNbqLjtecFosoFzpGAC89-5icikWODKI8rOjbi8v_sA,10
|
|
19
|
+
casambi_bt_revamped-0.3.6.dev3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
{casambi_bt_revamped-0.3.6.dev1.dist-info → casambi_bt_revamped-0.3.6.dev3.dist-info}/top_level.txt
RENAMED
|
File without changes
|