Skip to content

Only await TX confirm if APS ACKs are requested#275

Closed
MalteGruber wants to merge 2 commits intozigpy:devfrom
MalteGruber:dev
Closed

Only await TX confirm if APS ACKs are requested#275
MalteGruber wants to merge 2 commits intozigpy:devfrom
MalteGruber:dev

Conversation

@MalteGruber
Copy link
Copy Markdown

I have had issues in my system where send_packet waits for the full SEND_CONFIRM_TIMEOUT regardless if zigpy.types.TransmitOptions.ACK is present in the packet. This causes delays when many devices are offline.

With this change, TX confirm is only awaited when APS ACKs are requested.

Note: handle_tx_confirm will still fire without a future in the _pending_requests, this is inherent in how the Network operates, so the warning that was raised has been changed to a debug message to reflect this.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.14%. Comparing base (d7d73ba) to head (4a84c37).

Additional details and impacted files
@@           Coverage Diff           @@
##              dev     #275   +/-   ##
=======================================
  Coverage   99.14%   99.14%           
=======================================
  Files           7        7           
  Lines         931      932    +1     
=======================================
+ Hits          923      924    +1     
  Misses          8        8           

☔ View full report in Codecov by Sentry.
📢 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.

@puddly
Copy link
Copy Markdown
Contributor

puddly commented Apr 16, 2026

Thanks for the PR!

What Conbee device are you using?

@MalteGruber
Copy link
Copy Markdown
Author

Hey,
I am using the ConBee II with a custom program (i.e., not HA) that then uses zigpy/zigpy-deconz.

@puddly
Copy link
Copy Markdown
Contributor

puddly commented Apr 18, 2026

Could you describe the device you're communicating with and include some debug logs or a traffic capture?

The deconz docs say:

A data response with a status of SUCCESS signals that the request is enqueued and will be
processed by the device. Note that the response does not reflect the actual completion of the
request, which should be further monitored with an APSDE-DATA.confirm command as soon as
the relevant flag is set in the device status fields. The APS Request ID shall be used to match a
specific request to its confirmation.

Is the device you're communicating with battery powered?

In zigpy, send_packet is expected to block until the device actually sends the packet, not just enqueues it. APS ACKs further block until the receiving device sends back an ACK. Without it, we usually wait for the next-hop device to accept the packet. If the next hop is a child or a neighbor, it is expected for the request to take a while, since we aren't handing off the packet to another device to forward.

@MalteGruber
Copy link
Copy Markdown
Author

The problem occurs for me with devices that are offline (say, ceiling lights that are unpowered). The handle_tx_confirm will not fire if the device is offline, which causes the confirmation future to be awaited for 60 seconds; it is this wait I want to skip if the ACK is not specified in the TransmitOptions. Even if I specify not to set zigpy.types.TransmitOptions.ACK in packet.tx_options, send_packet will block until it hits the 60-second SEND_CONFIRM_TIMEOUT if the device is offline, and there is no option to change this timeout in the config.

I believe await self._api.aps_data_request( still handles the actual request and waits for the UART response from the Conbee, see here in api.py. This part is unchanged:

LOGGER.debug("Sending %s%s (seq=%s)", cmd, kwargs, seq)
                self._uart.send(command.replace(seq=seq).serialize())

                async with asyncio_timeout(COMMAND_TIMEOUT):
                    return await fut

Even with the change in this MR, I believe the Conbee UART reception confirmation is still awaited, regardless if waiting for an ACK is specified, so the contract with the Conbee is still respected. It's just the ACK from the actual lamp or whatever that is now not awaited if the ACK option is not passed, which is what I would expect zigpy.types.TransmitOptions.ACK to do, similar to broadcasting, etc.

@puddly
Copy link
Copy Markdown
Contributor

puddly commented Apr 22, 2026

Within ZHA, we just use async with asyncio.timeout on requests to ensure they take the right amount of time. You should be able to do the same in your program to ensure requests don't take 60s when talking to offline devices.

What firmware version is your Conbee II running?

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