python-jebao 0.1.1__tar.gz → 0.1.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-jebao
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Python library for controlling Jebao aquarium pumps
5
5
  Home-page: https://github.com/jrigling/python-jebao
6
6
  Author: Justin Rigling
@@ -16,7 +16,7 @@ from .const import (
16
16
  MODEL_MD44,
17
17
  )
18
18
 
19
- __version__ = "0.1.1"
19
+ __version__ = "0.1.2"
20
20
 
21
21
  __all__ = [
22
22
  "JebaoDevice",
@@ -363,6 +363,10 @@ class JebaoProtocol:
363
363
  if not self.is_connected:
364
364
  raise JebaoConnectionError("Not connected")
365
365
 
366
+ # Drain any unexpected leftover bytes as safety net (very short timeout)
367
+ # Normally padding is read explicitly, but this catches edge cases
368
+ await self._drain_garbage_bytes(timeout=0.01)
369
+
366
370
  # Send simple status request (0x90)
367
371
  # Format: 00 00 00 03 04 00 00 90 02
368
372
  # The last byte (02) requests values, and response will be message type 91 or 0x00
@@ -415,9 +419,9 @@ class JebaoProtocol:
415
419
  if not self.is_connected:
416
420
  raise JebaoConnectionError("Not connected")
417
421
 
418
- # Drain any garbage bytes left from previous operations
419
- # This prevents garbage from corrupting the ACK read
420
- await self._drain_garbage_bytes(timeout=0.05)
422
+ # Drain any unexpected leftover bytes as safety net (very short timeout)
423
+ # Normally padding is read explicitly, but this catches edge cases
424
+ await self._drain_garbage_bytes(timeout=0.01)
421
425
 
422
426
  command = self._build_control_command(opcode1, opcode2, param1, param2)
423
427
  _LOGGER.debug(
@@ -445,8 +449,6 @@ class JebaoProtocol:
445
449
  "Pump sent unsolicited status update after control command: type=0x%02x",
446
450
  status_type,
447
451
  )
448
- # Drain any remaining garbage after the status update
449
- await self._drain_garbage_bytes()
450
452
  except asyncio.TimeoutError:
451
453
  # No status update sent, that's OK
452
454
  _LOGGER.debug("No unsolicited status update after control command")
@@ -606,10 +608,17 @@ class JebaoProtocol:
606
608
  for attempt in range(max_resync_attempts):
607
609
  if header[0:4] == b"\x00\x00\x00\x03":
608
610
  # Valid header found
611
+ if attempt > 0:
612
+ # Log when we had to re-sync (shouldn't happen often now)
613
+ _LOGGER.warning(
614
+ "Had to re-sync message stream after %d attempt(s) - "
615
+ "garbage bytes not properly drained",
616
+ attempt
617
+ )
609
618
  break
610
619
 
611
620
  # Invalid header - try to re-sync by reading one more byte
612
- _LOGGER.warning(
621
+ _LOGGER.debug(
613
622
  "Invalid header %s, attempting re-sync (attempt %d/%d)",
614
623
  header[0:4].hex(),
615
624
  attempt + 1,
@@ -632,6 +641,43 @@ class JebaoProtocol:
632
641
 
633
642
  result = header + remaining
634
643
  msg_type = result[7] if len(result) > 7 else 0
644
+
645
+ # Only message type 0x00 (extended status responses) has 129-byte padding
646
+ # All other message types have no padding
647
+ if msg_type == MSG_EXTENDED_DATA:
648
+ # Read fixed padding (129 bytes) that pump sends for extended responses
649
+ # The pump uses fixed-frame protocol with padding (0xee or 0x00)
650
+ padding = await self._reader.readexactly(129)
651
+
652
+ # Validate padding - should be mostly 0xee or 0x00 patterns
653
+ # Check first 4 bytes and last byte
654
+ padding_start = padding[0:4]
655
+ padding_end = padding[-1]
656
+
657
+ # Valid patterns: eeeeeeee or 00000000 at start, 00 at end
658
+ is_valid_padding = (
659
+ (padding_start == b'\xee\xee\xee\xee' or padding_start == b'\x00\x00\x00\x00')
660
+ and padding_end == 0x00
661
+ )
662
+
663
+ if not is_valid_padding:
664
+ _LOGGER.error(
665
+ "Invalid padding detected! Start: %s, End: 0x%02x - possible protocol corruption",
666
+ padding_start.hex(),
667
+ padding_end
668
+ )
669
+ # Drain any additional garbage as fallback
670
+ await self._drain_garbage_bytes(timeout=0.05)
671
+ raise JebaoConnectionError(
672
+ f"Protocol error: invalid padding (start={padding_start.hex()}, end=0x{padding_end:02x})"
673
+ )
674
+
675
+ _LOGGER.debug(
676
+ "Read 129-byte padding frame for msg type 0x00 (start: %s, end: 0x%02x)",
677
+ padding_start.hex(),
678
+ padding_end
679
+ )
680
+
635
681
  _LOGGER.debug(
636
682
  f"Message complete: {len(result)} bytes, type=0x{msg_type:02x}"
637
683
  )
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "python-jebao"
7
- version = "0.1.1"
7
+ version = "0.1.2"
8
8
  description = "Python library for controlling Jebao aquarium pumps"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-jebao
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Python library for controlling Jebao aquarium pumps
5
5
  Home-page: https://github.com/jrigling/python-jebao
6
6
  Author: Justin Rigling
File without changes
File without changes
File without changes
File without changes