Skip to content

Answer getter failures per characteristic and add the busy_lock example - #561

Open
ikalchev wants to merge 1 commit into
refactor/hap-status-errorfrom
refactor/getter-error-isolation
Open

ikalchev wants to merge 1 commit into
refactor/hap-status-errorfrom
refactor/getter-error-isolation

Conversation

@ikalchev

@ikalchev ikalchev commented Nov 13, 2026 •

Copy link
Copy Markdown
Owner

Stacked on #560 (APIs: #562). Two parts:

1. Getters answer with a status, isolated per characteristic

  • A getter that raises HapStatusError answers a read of its characteristic with that status instead of -70402 — the read-side twin of Add HapStatusError and answer setter failures with its status #560.
  • A failing getter no longer fails the whole /accessories response: its characteristic is listed without its value, and the rest of the accessory database is served as usual. Until now a raising getter failed the entire request, so one broken accessory could break pairing for every accessory behind the bridge.

2. Example accessory: accessories/busy_lock.py

Demonstrates the error protocol end to end, as a bridge:

  • BusyLock — a lock whose bolt takes five seconds to move. While it moves, commands to the target state are refused with RESOURCE_BUSY, and the refused target is put back so the accessory keeps a consistent state. The Home app shows the command as failed instead of pretending it worked.
  • OfflineSensor — a temperature sensor that cannot be reached: its reads answer with SERVICE_COMMUNICATION_FAILURE instead of a value that would be a lie.

Listed in intro/examples.rst; verified with a smoke test against the real driver (set_characteristics / get_characteristics / get_accessories).

Tests

New tests cover: sync and async setter refusals (standalone and bridged), service and accessory level refusals, getter status answers, and /accessories isolation of a failing getter. Stack tip: 1729 tests pass, ruff clean, ty at the pre-existing baseline categories, docs build -W clean.

@codecov

codecov Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.06%. Comparing base (df8cde0) to head (e64d6e5).

Additional details and impacted files
@@                    Coverage Diff                     @@
##           refactor/hap-status-error     #561   +/-   ##
==========================================================
  Coverage                      92.05%   92.06%           
==========================================================
  Files                             54       54           
  Lines                          10914    10920    +6     
  Branches                        1407     1407           
==========================================================
+ Hits                           10047    10053    +6     
  Misses                           579      579           
  Partials                         288      288           
Files with missing lines Coverage Δ
pyhap/accessory_driver.py 94.26% <100.00%> (+0.02%) ⬆️
pyhap/characteristic.py 98.00% <100.00%> (+0.02%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

A getter that raises HapStatusError answers a read of its
characteristic with that status instead of -70402, like a setter does.

A failing getter no longer fails the whole /accessories response: its
characteristic is listed without its value, and the rest of the
accessory database is served as usual. Until now a raising getter
failed the entire request, so one broken accessory could break pairing
for every accessory behind the bridge.

Add accessories/busy_lock.py as an example of the error protocol: a
lock that refuses commands with RESOURCE_BUSY while its bolt is moving,
and an offline sensor whose reads answer with a status instead of a
value.
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