Skip to content

fix: add timeout and fallback for lock_info probe#306

Merged
bdraco merged 4 commits intomainfrom
fix-lock-info-probe-hang
Mar 2, 2026
Merged

fix: add timeout and fallback for lock_info probe#306
bdraco merged 4 commits intomainfrom
fix-lock-info-probe-hang

Conversation

@bdraco
Copy link
Member

@bdraco bdraco commented Mar 2, 2026

Summary

  • Add 5s timeout around the lock_info() GATT reads to prevent indefinite hangs
  • Handle individual BleakError per characteristic so partial reads return partial results
  • Read model characteristic first since it drives battery workaround and door sense logic
  • Fall back to default LockInfo in _update() when the entire probe fails, breaking the infinite reconnect-probe-disconnect loop
  • Use BLE address as fallback serial number to prevent Home Assistant from grouping unrelated devices together

Problem

lock_info() reads 4 Device Information Service characteristics (read_gatt_char) with no timeout. When the lock drops the BLE connection during these reads (e.g. ATT error 19), read_gatt_char hangs until the remote disconnects (~30s). Since _lock_info is required before any _update() can proceed, every update cycle reconnects and retries the probe, creating an infinite loop that makes the lock completely unresponsive.

Test plan

  • test_lock_info_success — all reads succeed
  • test_lock_info_partial_failure — one read fails, others succeed with partial results
  • test_lock_info_all_reads_fail — all reads fail, returns all defaults
  • test_lock_info_timeout — reads hang, 5s timeout fires
  • test_lock_info_reads_model_first — model is read before other characteristics
  • test_update_continues_when_lock_info_probe_failsTimeoutError fallback with MAC as serial
  • test_update_continues_when_lock_info_probe_bleak_errorBleakError fallback with MAC as serial
  • Verified on live system: lock falls back to defaults and continues operating

… retry loop

lock_info() reads GATT Device Information characteristics with no timeout,
causing hangs when the lock drops the connection during reads. Since
lock_info is required before any update can proceed, a failing probe
creates an infinite reconnect-probe-disconnect loop.

- Add 10s timeout around the entire lock_info() probe
- Handle individual BleakError per characteristic so partial reads succeed
- Read model first since it drives battery and door sense behavior
- Fall back to default LockInfo in _update() when probe fails entirely
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the BLE lock_info() probe and the PushLock._update() flow so update cycles can continue even when device-information GATT reads hang or fail, avoiding repeated reconnect/probe loops.

Changes:

  • Add a timeout + per-characteristic error handling in Lock.lock_info() and read the model characteristic first.
  • Add _probe_lock_info() in PushLock to fall back to a default LockInfo when probing fails, allowing _update() to proceed.
  • Add unit tests covering success, partial failure, total failure, timeout behavior, model-first ordering, and _update() fallback behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
src/yalexs_ble/lock.py Adds LOCK_INFO_TIMEOUT and updates lock_info() to read model first, apply a timeout, and tolerate per-read BleakErrors.
src/yalexs_ble/push.py Adds _probe_lock_info() and uses it from _update() to avoid update failures when probing lock info fails.
tests/test_lock.py Adds coverage for lock_info() success/partial failure/all-fail/timeout and verifies characteristic read order.
tests/test_push.py Adds coverage to ensure _update() continues when lock_info() raises TimeoutError or BleakError.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

bdraco added 3 commits March 1, 2026 19:52
- Skip missing characteristics instead of aborting entire probe
- Use empty model default so door_sense=False when model is unknown
- Fix docstring wording
- Add test for missing characteristic handling
@bdraco bdraco merged commit bcd6505 into main Mar 2, 2026
8 checks passed
@bdraco bdraco deleted the fix-lock-info-probe-hang branch March 2, 2026 06:07
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.

2 participants