casambi-bt-revamped 0.3.7.dev8__tar.gz → 0.3.7.dev10__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 (23) hide show
  1. {casambi_bt_revamped-0.3.7.dev8/src/casambi_bt_revamped.egg-info → casambi_bt_revamped-0.3.7.dev10}/PKG-INFO +1 -1
  2. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/setup.cfg +1 -1
  3. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/src/CasambiBt/_casambi.py +10 -0
  4. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/src/CasambiBt/_client.py +18 -71
  5. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/src/CasambiBt/_network.py +7 -0
  6. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10/src/casambi_bt_revamped.egg-info}/PKG-INFO +1 -1
  7. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/LICENSE +0 -0
  8. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/README.md +0 -0
  9. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/pyproject.toml +0 -0
  10. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/src/CasambiBt/__init__.py +0 -0
  11. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/src/CasambiBt/_cache.py +0 -0
  12. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/src/CasambiBt/_constants.py +0 -0
  13. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/src/CasambiBt/_discover.py +0 -0
  14. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/src/CasambiBt/_encryption.py +0 -0
  15. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/src/CasambiBt/_keystore.py +0 -0
  16. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/src/CasambiBt/_operation.py +0 -0
  17. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/src/CasambiBt/_unit.py +0 -0
  18. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/src/CasambiBt/errors.py +0 -0
  19. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/src/CasambiBt/py.typed +0 -0
  20. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/src/casambi_bt_revamped.egg-info/SOURCES.txt +0 -0
  21. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/src/casambi_bt_revamped.egg-info/dependency_links.txt +0 -0
  22. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/src/casambi_bt_revamped.egg-info/requires.txt +0 -0
  23. {casambi_bt_revamped-0.3.7.dev8 → casambi_bt_revamped-0.3.7.dev10}/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.7.dev8
3
+ Version: 0.3.7.dev10
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.7.dev8
3
+ version = 0.3.7.dev10
4
4
  author = rankjie
5
5
  author_email = rankjie@gmail.com
6
6
  description = Enhanced Casambi Bluetooth client library with switch event support
@@ -98,6 +98,16 @@ class Casambi:
98
98
  and self._casaClient._connectionState == ConnectionState.AUTHENTICATED
99
99
  )
100
100
 
101
+ @property
102
+ def rawNetworkData(self) -> dict | None:
103
+ """Get the raw network configuration data if available.
104
+
105
+ :return: The raw network JSON data or None if not connected.
106
+ """
107
+ if self._casaNetwork:
108
+ return self._casaNetwork.rawNetworkData
109
+ return None
110
+
101
111
  async def connect(
102
112
  self,
103
113
  addr_or_device: str | BLEDevice,
@@ -1,7 +1,7 @@
1
1
  import asyncio
2
2
  import logging
3
3
  import struct
4
- from binascii import b2a_hex as b2a, hexlify
4
+ from binascii import b2a_hex as b2a
5
5
  from collections.abc import Callable
6
6
  from enum import IntEnum, unique
7
7
  from hashlib import sha256
@@ -417,9 +417,6 @@ class CasambiClient:
417
417
 
418
418
  # Store raw encrypted packet for reference
419
419
  raw_encrypted_packet = data[:]
420
-
421
- # Log raw encrypted packet with special marker for easy filtering
422
- self._logger.info(f"[CASAMBI_RAW_PACKET] Encrypted #{self._inPacketCount}: {b2a(raw_encrypted_packet)}")
423
420
 
424
421
  try:
425
422
  decrypted_data = self._encryptor.decryptAndVerify(
@@ -432,9 +429,6 @@ class CasambiClient:
432
429
 
433
430
  packetType = decrypted_data[0]
434
431
  self._logger.debug(f"Incoming data of type {packetType}: {b2a(decrypted_data)}")
435
-
436
- # Log decrypted packet with special marker
437
- self._logger.info(f"[CASAMBI_DECRYPTED] Type={packetType} #{self._inPacketCount}: {b2a(decrypted_data)}")
438
432
 
439
433
  if packetType == IncommingPacketType.UnitState:
440
434
  self._parseUnitStates(decrypted_data[1:])
@@ -502,9 +496,6 @@ class CasambiClient:
502
496
  self._logger.info(
503
497
  f"Parsing incoming switch event packet #{packet_seq}... Data: {b2a(data)}"
504
498
  )
505
-
506
- # Log complete packet structure with marker
507
- self._logger.info(f"[CASAMBI_SWITCH_PACKET] Full data #{packet_seq}: hex={b2a(data)} len={len(data)}")
508
499
 
509
500
  # Special handling for message type 0x29 - not a switch event
510
501
  if len(data) >= 1 and data[0] == 0x29:
@@ -516,7 +507,6 @@ class CasambiClient:
516
507
  pos = 0
517
508
  oldPos = 0
518
509
  switch_events_found = 0
519
- all_messages_found = []
520
510
 
521
511
  try:
522
512
  while pos <= len(data) - 3:
@@ -528,12 +518,6 @@ class CasambiClient:
528
518
  length = ((data[pos + 2] >> 4) & 15) + 1
529
519
  parameter = data[pos + 2] # Full byte, not just lower 4 bits
530
520
  pos += 3
531
-
532
- # Log every message found with detailed structure
533
- self._logger.info(
534
- f"[CASAMBI_MSG_FOUND] At pos={oldPos}: type=0x{message_type:02x} flags=0x{flags:02x} "
535
- f"len={length} param=0x{parameter:02x}"
536
- )
537
521
 
538
522
  # Sanity check: message type should be reasonable
539
523
  if message_type > 0x80:
@@ -555,51 +539,25 @@ class CasambiClient:
555
539
  # Extract the payload
556
540
  payload = data[pos : pos + length]
557
541
  pos += length
558
-
559
- # Log the payload
560
- self._logger.info(
561
- f"[CASAMBI_MSG_PAYLOAD] Type 0x{message_type:02x} payload: {b2a(payload)} "
562
- f"(bytes {oldPos+3} to {oldPos+3+length-1})"
563
- )
564
-
565
- # Track all messages
566
- all_messages_found.append({
567
- 'type': message_type,
568
- 'pos': oldPos,
569
- 'flags': flags,
570
- 'param': parameter,
571
- 'payload': b2a(payload)
572
- })
573
542
 
574
543
  # Process based on message type
575
544
  if message_type == 0x08 or message_type == 0x10: # Switch/button events
576
545
  switch_events_found += 1
577
-
578
- # Button extraction differs between type 0x08 and type 0x10
579
- if message_type == 0x08:
580
- # For type 0x08, the lower nibble is a code that maps to physical button id
581
- # Using formula: ((code + 2) % 4) + 1 based on reverse engineering findings
582
- code_nibble = parameter & 0x0F
583
- button = ((code_nibble + 2) % 4) + 1
546
+ # Extract button ID - try both upper and lower nibbles
547
+ button_lower = parameter & 0x0F
548
+ button_upper = (parameter >> 4) & 0x0F
549
+
550
+ # Use upper 4 bits if lower 4 bits are 0, otherwise use lower 4 bits
551
+ if button_lower == 0 and button_upper != 0:
552
+ button = button_upper
584
553
  self._logger.debug(
585
- f"Type 0x08 button extraction: parameter=0x{parameter:02x}, code={code_nibble}, button={button}"
554
+ f"EVO button extraction: parameter=0x{parameter:02x}, using upper nibble, button={button}"
586
555
  )
587
556
  else:
588
- # For type 0x10, use existing logic
589
- button_lower = parameter & 0x0F
590
- button_upper = (parameter >> 4) & 0x0F
591
-
592
- # Use upper 4 bits if lower 4 bits are 0, otherwise use lower 4 bits
593
- if button_lower == 0 and button_upper != 0:
594
- button = button_upper
595
- self._logger.debug(
596
- f"Type 0x10 button extraction: parameter=0x{parameter:02x}, using upper nibble, button={button}"
597
- )
598
- else:
599
- button = button_lower
600
- self._logger.debug(
601
- f"Type 0x10 button extraction: parameter=0x{parameter:02x}, using lower nibble, button={button}"
602
- )
557
+ button = button_lower
558
+ self._logger.debug(
559
+ f"EVO button extraction: parameter=0x{parameter:02x}, using lower nibble, button={button}"
560
+ )
603
561
 
604
562
  # For type 0x10 messages, we need to pass additional data beyond the declared payload
605
563
  if message_type == 0x10:
@@ -642,17 +600,6 @@ class CasambiClient:
642
600
  f"Remaining data {b2a(data[oldPos:])} in {b2a(data)}."
643
601
  )
644
602
 
645
- # Log summary of all messages found
646
- self._logger.info(
647
- f"[CASAMBI_PARSE_SUMMARY] Packet #{packet_seq}: Found {len(all_messages_found)} messages, "
648
- f"{switch_events_found} switch events"
649
- )
650
- for i, msg in enumerate(all_messages_found):
651
- self._logger.info(
652
- f"[CASAMBI_MSG_{i+1}] Type=0x{msg['type']:02x} Pos={msg['pos']} "
653
- f"Flags=0x{msg['flags']:02x} Param=0x{msg['param']:02x} Payload={msg['payload']}"
654
- )
655
-
656
603
  if switch_events_found == 0:
657
604
  self._logger.debug(f"No switch events found in packet: {b2a(data)}")
658
605
 
@@ -747,13 +694,13 @@ class CasambiClient:
747
694
  f"action={action_display} ({event_string}), flags=0x{flags:02x}"
748
695
  )
749
696
 
750
- # Log detailed info about type 0x08 messages (now processed, not filtered)
697
+ # Filter out all type 0x08 messages
751
698
  if message_type == 0x08:
752
- self._logger.info(
753
- f"[CASAMBI_TYPE08_PROCESSED] Type 0x08 event processed: button={button}, unit_id={unit_id}, "
754
- f"action={action_display}, event={event_string}, flags=0x{flags:02x}, "
755
- f"payload={hexlify(payload).decode()}, extra_data={hexlify(extra_data).decode() if extra_data else 'none'}"
699
+ self._logger.debug(
700
+ f"Filtering out type 0x08 event: button={button}, unit_id={unit_id}, "
701
+ f"action={action_display}, flags=0x{flags:02x}"
756
702
  )
703
+ return
757
704
 
758
705
  self._dataCallback(
759
706
  IncommingPacketType.SwitchEvent,
@@ -44,6 +44,7 @@ class Network:
44
44
  self._networkName: str | None = None
45
45
  self._networkRevision: int | None = None
46
46
  self._protocolVersion: int = -1
47
+ self._rawNetworkData: dict | None = None
47
48
 
48
49
  self._unitTypes: dict[int, tuple[UnitType | None, datetime]] = {}
49
50
  self.units: list[Unit] = []
@@ -153,6 +154,10 @@ class Network:
153
154
  def protocolVersion(self) -> int:
154
155
  return self._protocolVersion
155
156
 
157
+ @property
158
+ def rawNetworkData(self) -> dict | None:
159
+ return self._rawNetworkData
160
+
156
161
  async def logIn(self, password: str, forceOffline: bool = False) -> None:
157
162
  await self.getNetworkId(forceOffline)
158
163
 
@@ -191,6 +196,7 @@ class Network:
191
196
  cachedNetworkPah = cachePath / f"{self._id}.json"
192
197
  if await cachedNetworkPah.exists():
193
198
  network = json.loads(await cachedNetworkPah.read_bytes())
199
+ self._rawNetworkData = network
194
200
  self._networkRevision = network["network"]["revision"]
195
201
  self._logger.info(
196
202
  f"Loaded cached network. Revision: {self._networkRevision}"
@@ -233,6 +239,7 @@ class Network:
233
239
  updateResult = res.json()
234
240
  if updateResult["status"] != "UPTODATE":
235
241
  self._networkRevision = updateResult["network"]["revision"]
242
+ self._rawNetworkData = updateResult
236
243
  async with self._cache as cachePath:
237
244
  cachedNetworkPah = cachePath / f"{self._id}.json"
238
245
  await cachedNetworkPah.write_bytes(res.content)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: casambi-bt-revamped
3
- Version: 0.3.7.dev8
3
+ Version: 0.3.7.dev10
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