casambi-bt-revamped 0.3.6.dev1__tar.gz → 0.3.6.dev2__tar.gz

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 (24) hide show
  1. {casambi_bt_revamped-0.3.6.dev1/src/casambi_bt_revamped.egg-info → casambi_bt_revamped-0.3.6.dev2}/PKG-INFO +1 -1
  2. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/setup.cfg +1 -1
  3. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_client.py +52 -47
  4. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2/src/casambi_bt_revamped.egg-info}/PKG-INFO +1 -1
  5. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/LICENSE +0 -0
  6. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/README.md +0 -0
  7. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/pyproject.toml +0 -0
  8. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/__init__.py +0 -0
  9. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_cache.py +0 -0
  10. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_casambi.py +0 -0
  11. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_client_android_parser.py +0 -0
  12. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_constants.py +0 -0
  13. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_discover.py +0 -0
  14. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_encryption.py +0 -0
  15. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_keystore.py +0 -0
  16. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_network.py +0 -0
  17. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_operation.py +0 -0
  18. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_unit.py +0 -0
  19. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/errors.py +0 -0
  20. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/py.typed +0 -0
  21. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/casambi_bt_revamped.egg-info/SOURCES.txt +0 -0
  22. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/casambi_bt_revamped.egg-info/dependency_links.txt +0 -0
  23. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/casambi_bt_revamped.egg-info/requires.txt +0 -0
  24. {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/casambi_bt_revamped.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: casambi-bt-revamped
3
- Version: 0.3.6.dev1
3
+ Version: 0.3.6.dev2
4
4
  Summary: Enhanced Casambi Bluetooth client library with switch event support
5
5
  Home-page: https://github.com/rankjie/casambi-bt
6
6
  Author: rankjie
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = casambi-bt-revamped
3
- version = 0.3.6.dev1
3
+ version = 0.3.6.dev2
4
4
  author = rankjie
5
5
  author_email = rankjie@gmail.com
6
6
  description = Enhanced Casambi Bluetooth client library with switch event support
@@ -421,23 +421,47 @@ class CasambiClient:
421
421
  # TODO: Check incoming counter and direction flag
422
422
  self._inPacketCount += 1
423
423
 
424
- # Store raw encrypted packet for reference
425
- raw_packet = data[:]
424
+ # Store raw encrypted packet for Android parser analysis
425
+ raw_encrypted_packet = data[:]
426
+
427
+ # Try Android parser on the raw packet BEFORE decryption
428
+ android_switch_event = None
429
+ if AndroidPacketParser:
430
+ try:
431
+ # The Android parser expects unencrypted packets, but let's try anyway
432
+ # to see the structure
433
+ self._logger.debug(f"Attempting Android parser on raw packet: {b2a(raw_encrypted_packet)}")
434
+ android_result = AndroidPacketParser.parse_complete_packet(raw_encrypted_packet)
435
+ self._logger.debug(f"Android parser raw result: {android_result}")
436
+ except Exception as e:
437
+ self._logger.debug(f"Android parser on raw packet failed (expected): {e}")
426
438
 
427
439
  try:
428
- data = self._encryptor.decryptAndVerify(data, data[:4] + self._nonce[4:])
440
+ decrypted_data = self._encryptor.decryptAndVerify(data, data[:4] + self._nonce[4:])
429
441
  except InvalidSignature:
430
442
  # We only drop packets with invalid signature here instead of going into an error state
431
443
  self._logger.error(f"Invalid signature for packet {b2a(data)}!")
432
444
  return
445
+
446
+ # Now try Android parser on decrypted data
447
+ if AndroidPacketParser:
448
+ try:
449
+ self._logger.debug(f"Attempting Android parser on decrypted packet: {b2a(decrypted_data)}")
450
+ android_result = AndroidPacketParser.parse_complete_packet(decrypted_data)
451
+ if android_result.get('switch_event'):
452
+ android_switch_event = android_result['switch_event']
453
+ self._logger.info(f"Android parser found switch event: {android_switch_event['android_log']}")
454
+ self._logger.debug(f"Android parser decrypted result: {android_result}")
455
+ except Exception as e:
456
+ self._logger.debug(f"Android parser on decrypted packet failed: {e}")
433
457
 
434
- packetType = data[0]
435
- self._logger.debug(f"Incoming data of type {packetType}: {b2a(data)}")
458
+ packetType = decrypted_data[0]
459
+ self._logger.debug(f"Incoming data of type {packetType}: {b2a(decrypted_data)}")
436
460
 
437
461
  if packetType == IncommingPacketType.UnitState:
438
- self._parseUnitStates(data[1:])
462
+ self._parseUnitStates(decrypted_data[1:])
439
463
  elif packetType == IncommingPacketType.SwitchEvent:
440
- self._parseSwitchEvent(data[1:], self._inPacketCount, raw_packet)
464
+ self._parseSwitchEvent(decrypted_data[1:], self._inPacketCount, raw_encrypted_packet, android_switch_event)
441
465
  elif packetType == IncommingPacketType.NetworkConfig:
442
466
  # We don't care about the config the network thinks it has.
443
467
  # We assume that cloud config and local config match.
@@ -491,23 +515,13 @@ class CasambiClient:
491
515
  f"Ran out of data while parsing unit state! Remaining data {b2a(data[oldPos:])} in {b2a(data)}."
492
516
  )
493
517
 
494
- def _parseSwitchEvent(self, data: bytes, packet_seq: int = None, raw_packet: bytes = None) -> None:
518
+ def _parseSwitchEvent(self, data: bytes, packet_seq: int = None, raw_packet: bytes = None, android_switch_event: dict = None) -> None:
495
519
  """Parse switch event packet which contains multiple message types"""
496
520
  self._logger.info(f"Parsing incoming switch event packet... Data: {b2a(data)}")
497
521
 
498
- # Try Android parser for comparison if available
499
- if AndroidPacketParser and raw_packet:
500
- try:
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}")
522
+ # Log Android parser result if available
523
+ if android_switch_event:
524
+ self._logger.info(f"Android parser comparison: {android_switch_event['android_log']}")
511
525
 
512
526
  pos = 0
513
527
  oldPos = 0
@@ -536,7 +550,7 @@ class CasambiClient:
536
550
 
537
551
  # Process based on message type
538
552
  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)
553
+ self._processSwitchMessage(message_type, flags, parameter, payload, data, oldPos, packet_seq, raw_packet, android_switch_event)
540
554
  else:
541
555
  # Log other message types for now
542
556
  self._logger.debug(
@@ -552,7 +566,7 @@ class CasambiClient:
552
566
  f"Remaining data {b2a(data[oldPos:])} in {b2a(data)}."
553
567
  )
554
568
 
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:
569
+ 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
570
  """Process a switch/button message (types 0x08 or 0x10)"""
557
571
  if not payload:
558
572
  self._logger.error("Switch message has empty payload")
@@ -602,31 +616,22 @@ class CasambiClient:
602
616
  f"action={action_display} ({event_string}), flags=0x{flags:02x}"
603
617
  )
604
618
 
605
- # Also try to parse with Android method if this is the full packet
619
+ # Include Android parser comparison if available
606
620
  android_comparison = None
607
- if AndroidPacketParser and message_type == 0x07 and len(payload) >= 9:
608
- try:
609
- # Try to parse as Android packet structure
610
- android_parsed = AndroidPacketParser.parse_complete_packet(payload)
611
- if android_parsed.get('switch_event'):
612
- android_evt = android_parsed['switch_event']
613
- android_comparison = {
614
- 'unit_id': android_evt['unit_id'],
615
- 'button': android_evt['button'],
616
- 'state': android_evt['state'],
617
- 'param_p': android_evt['param_p'],
618
- 'param_s': android_evt['param_s'],
619
- 'android_log': android_evt['android_log']
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}")
621
+ if android_switch_event:
622
+ android_comparison = {
623
+ 'unit_id': android_switch_event['unit_id'],
624
+ 'button': android_switch_event['button'],
625
+ 'state': android_switch_event['state'],
626
+ 'param_p': android_switch_event['param_p'],
627
+ 'param_s': android_switch_event['param_s'],
628
+ 'android_log': android_switch_event['android_log']
629
+ }
630
+ # Log differences
631
+ if android_switch_event['unit_id'] != unit_id:
632
+ self._logger.warning(f"Unit ID mismatch: current={unit_id}, android={android_switch_event['unit_id']}")
633
+ if android_switch_event['button'] != button:
634
+ self._logger.warning(f"Button mismatch: current={button}, android={android_switch_event['button']}")
630
635
 
631
636
  self._dataCallback(
632
637
  IncommingPacketType.SwitchEvent,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: casambi-bt-revamped
3
- Version: 0.3.6.dev1
3
+ Version: 0.3.6.dev2
4
4
  Summary: Enhanced Casambi Bluetooth client library with switch event support
5
5
  Home-page: https://github.com/rankjie/casambi-bt
6
6
  Author: rankjie