Skip to content

Granular frame scheduling and error types - #1869

Draft
puddly wants to merge 4 commits into
zigpy:devfrom
puddly:puddly/send-packet-submission-api
Draft

puddly wants to merge 4 commits into
zigpy:devfrom
puddly:puddly/send-packet-submission-api

Conversation

@puddly

@puddly puddly commented Jul 30, 2026 •

Copy link
Copy Markdown
Collaborator

This is an experimental PR to port some of the Ziggurat frame scheduling improvements back to zigpy. bellows and zigpy-ziggurat are the current test targets but the other radio libraries will be migrated once the API stabilizes so the compatibility shim in this PR can be removed.

  • Radio libraries now implement _send_packet, not send_packet, and remove all concurrency and rate limiting. It's a simple interface to send a single packet. Nothing more.
  • Rate limiting is done dynamically based on radio backpressure indicators and takes into account both concurrency and total bytes used by each request.
  • There are now granular zigpy error codes for enqueuing errors (packet is too long, no space in buffers, firmware concurrency limit is exhausted, etc.) and delivery errors (CCA, broadcast storm, no ACK, no route, etc.).
  • Sends go through multiple stages: queued (we want to send and are waiting for a slot), parked (we are waiting for a sleepy end device to wake up), in-flight (we sent the packet and are waiting for a transmission confirmation), awaiting reply, and done. Before, we encoded this entire delivery mechanism within Python stack frame locals. Now, we know exactly what is being sent, queued, etc. Good for a future debug UI.
  • Requests to sleeping end devices can be parked and will wait until the device is awake. This benefits from the granular request state tracking because we can tell where a request timed out: we can still attach a 60s delivery timeout to a request that waits 1 hour for a device to wake up.
  • coalesce_key allows requests to supersede one another. This allows multiple queued up requests that control the same device state (i.e. bulb color or switch state) to replace one another, allowing them to effectively occupy the same send slot when waiting for the radio to free up. We can further improve this rate limit groupcasts better.

Radio library branches:

This PR + one of those is enough to test this PR out.

@codecov

codecov Bot commented Jul 30, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.73646% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 99.31%. Comparing base (8f3a91e) to head (5f6e917).
⚠️ Report is 10 commits behind head on dev.

Files with missing lines Patch % Lines
zigpy/scheduler.py 98.99% 5 Missing ⚠️
zigpy/application.py 93.75% 1 Missing ⚠️
zigpy/device.py 95.45% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #1869      +/-   ##
==========================================
- Coverage   99.48%   99.31%   -0.18%     
==========================================
  Files          59       60       +1     
  Lines       12280    12827     +547     
==========================================
+ Hits        12217    12739     +522     
- Misses         63       88      +25     

☔ 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.

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

Labels

new feature Adds new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants