Skip to content

Don't retry or warn on failed Poll Control check-in responses - #1905

Draft
zigpy-review-bot wants to merge 1 commit into
devfrom
zigpy-bot/checkin-response-failures
Draft

zigpy-review-bot wants to merge 1 commit into
devfrom
zigpy-bot/checkin-response-failures

Conversation

@zigpy-review-bot

@zigpy-review-bot zigpy-review-bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

Proposed change

When the Check-in Response to a Poll Control check-in fails to send, it is no longer retried, and the failure is logged at debug level instead of escaping the callback.

Before this change, a failed response was sent 3 times (the 2 default retries forced route discovery), all at CRITICAL priority, which bypasses the device and application request queues. Each check-in from a device that has stopped listening (e.g. one with a nearly dead battery) then ended with a WARNING and a full traceback from the callback wrapper in ControllerApplication.

The retries don't help here. Per ZCL 3.16.4.4, a Poll Control server that gets no Check-in Response within 7.68 s may return to long polling. A sleepy end device's parent holds an indirect frame for about that long before the send fails, so a retry arrives after the device has gone back to sleep. A dropped response is expected for such a device; it simply checks in again at its next interval. The OTA command handlers already log a failed reply at debug level.

The two checkin_response branches are folded into one call; the fast-poll decision and its arguments are unchanged.

Additional information

Closes #1804

Not addressed here:

  • Concurrent check-ins from one device still send their responses in parallel, since CRITICAL skips the queues. With the retries gone, each check-in now makes one send attempt from zigpy instead of three; radio libraries' own recovery (e.g. zigpy-znp retrying once after route discovery on NWK_NO_ROUTE) still applies.
  • If a check-in arrives without "disable default response" set, zigpy also sends a ZCL Default Response with the same TSN, which ZCL 2.5.12.2 says shouldn't happen when a specific response is sent.

Tests

  • The existing check-in test now also expects retries=0.
  • New: a DeliveryError or TimeoutError from checkin_response is logged at debug level and not raised.
  • New: a check-in received through packet_received, whose response fails with APS_NO_ACK, results in exactly one send and no "callback failed" warning. Without the fix this test sees 3 sends and the warning.

Related: #1913

A Poll Control server may go back to long polling 7.68s after checking in,
so a check-in response that fails to send is not retried and the failure is
logged at debug level instead of surfacing as a callback warning with a
traceback.
@codecov

codecov Bot commented Oct 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.51%. Comparing base (b4543ff) to head (634128f).

Additional details and impacted files
@@           Coverage Diff           @@
##              dev    #1905   +/-   ##
=======================================
  Coverage   99.51%   99.51%           
=======================================
  Files          61       61           
  Lines       12773    12775    +2     
=======================================
+ Hits        12711    12713    +2     
  Misses         62       62           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The focused implementation preserves fast-poll behavior and is covered by appropriate regression tests.

0 open findings

What changed in this PR

Prevents redundant Poll Control check-in response retries and suppresses expected delivery failures.

Changes:

  • Sends check-in responses once with retries=0.
  • Logs delivery failures and timeouts at debug level.
  • Adds unit and packet-level regression coverage.
File Description
zigpy/​device.py Consolidates response handling and suppresses expected failures.
tests/​test_device.py Verifies retry count, logging, and callback behavior.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix This PR fixes a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

poll_control_checkin_callback logs WARNING with full traceback on APS_NO_ACK, causing HA to become unresponsive

2 participants