Skip to content

Fix BLE protocol and MQTT connection bugs#4

Merged
syscod3 merged 3 commits intomainfrom
fix/bug-fixes
Mar 19, 2026
Merged

Fix BLE protocol and MQTT connection bugs#4
syscod3 merged 3 commits intomainfrom
fix/bug-fixes

Conversation

@syscod3
Copy link
Contributor

@syscod3 syscod3 commented Feb 18, 2026

Summary

  • HIGH: Replace blocking time.sleep() with asyncio.sleep() in HADiscoveryPublisher.connect() — the old code stalled the event loop for up to 5 seconds during every MQTT connection attempt. Made connect() and connect_mqtt() async and consolidated into a single asyncio.run() in main().
  • HIGH: Fix silent data corruption in _decrypt() — invalid PKCS7 padding (padding_len == 0 or > 16) previously returned garbage bytes; now raises ValueError so callers can handle the error properly.
  • MEDIUM: Guard publish_state() and publish_availability() with _connected check — previously called _client.publish() when disconnected, silently losing data.
  • MEDIUM: Add is_connected guard in _trigger_update() before write_gatt_char() — prevents an AttributeError/BleakError if the device drops connection between the initial query and the trigger.
  • MEDIUM: Replace hard-coded asyncio.sleep(2) after _trigger_update() in read_sensors() with an event-based wait (_response_event.clear() then wait_for(..., timeout=5.0)) — avoids stale signals and gives a proper timeout/log on failure.
  • MEDIUM: Validate required sensor keys (mac_address, device_id, local_key) in load_config() — missing keys now cause an early, descriptive error at startup instead of a KeyError during live polling.

Test plan

  • Unit-test _decrypt() with padding_len > 16 — expect ValueError
  • Run --once against a real SGS01 and confirm MQTT messages appear in HA
  • Simulate MQTT disconnect mid-run and confirm publish_state logs error instead of crashing
  • Supply a config with a sensor missing local_key and confirm startup exits with a clear error
  • Verify ruff passes: python3 -m ruff check pi-fallback/

🤖 Generated with Claude Code

- Replace blocking time.sleep() with asyncio.sleep() in HADiscoveryPublisher.connect()
  to avoid stalling the event loop during MQTT handshake
- Make connect_mqtt() and HADiscoveryPublisher.connect() async; consolidate
  MQTT connection into the single asyncio.run() call in main()
- Raise ValueError on invalid PKCS7 padding in _decrypt() instead of
  silently returning corrupt data
- Guard publish_state() and publish_availability() with _connected check
  to surface failures instead of dropping data silently
- Add is_connected guard in _trigger_update() before write_gatt_char()
- Replace hard-coded asyncio.sleep(2) after trigger_update() with an
  event-based wait (clear then await with timeout) to avoid stale signals
- Validate required sensor keys (mac_address, device_id, local_key) at
  config load time so missing keys fail fast at startup

Nightshift-Task: bug-finder
Nightshift-Ref: https://github.com/marcus/nightshift
Clear _response_event after _trigger_update() returns and before the
follow-up wait, so a DP_WRITE ack that resolved the internal wait in
_trigger_update() does not cause the outer wait_for() to return
immediately with a stale signal instead of properly waiting for the
DP_REPORT notification.

Nightshift-Task: bug-finder
Nightshift-Ref: https://github.com/marcus/nightshift
Use rjust instead of ljust when zero-padding VALUE-type DPs to 4 bytes
before big-endian unpacking. ljust appends zeros to the right (LSB side),
corrupting temperature and moisture readings for payloads shorter than 4
bytes. rjust correctly left-pads (MSB side) to preserve the value.

Nightshift-Task: bug-finder
Nightshift-Ref: https://github.com/marcus/nightshift
@syscod3 syscod3 merged commit cc43c58 into main Mar 19, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant