Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement esp_zb_stop() call so we can stop the Zigbee radio in code. (TZ-1530) #561

Open
IgnacioHR opened this issue Feb 7, 2025 · 5 comments

Comments

@IgnacioHR
Copy link

Is your feature request related to a problem?

As stated on issue #558 SDK v1.6.2 contains no mechanism to stop the zigbee radio.

This is line with the Global objetives of saving energy.

Describe the solution you'd like.

I would like to have a core function to stop the zigbee device as it is for other devices such as WIFI, Bluetooth, etc.

Describe alternatives you've considered.

The alternative is to send the device to deep sleep and prepare it to come back from deep sleep saving the device state so it can be recovered at the same point.

Additional context.

In the context of End Devices that implement the seMetering cluster and are battery powered, the designer has to made decisions about how to save as much energy as possible.

As you can see in the screen capture:

Image

The ESP32C6 device consumes 22.2mA while running with the Zigbee radio turned OFF
The ESP32C6 device consumes 8.5uA while in Deep Sleep mode.
The ESP32C6 device consumes 78.5mA while the Zigbee Radio is turned ON

It is desired to have the capacity to turn the Zigbee radio OFF so we can save some power when the device is running but the Zigbee link is not providing any added value.

This is line with the Global objetives of saving energy.

@github-actions github-actions bot changed the title Implement esp_zb_stop() call so we can stop the Zigbee radio in code. Implement esp_zb_stop() call so we can stop the Zigbee radio in code. (TZ-1530) Feb 7, 2025
@chshu
Copy link
Collaborator

chshu commented Feb 8, 2025

I think the Zigbee sleepy end device could meet your requirement, during the idle phase, the raido is stopped and the SoC is under light sleep mode, this is handled by the Zigbee SDK, so don't need to call stop() API in application.

Please refer to the light_example example.

@IgnacioHR
Copy link
Author

In the short term, for sure that will help. IMHO, in the long term, having esp_zb-stop() is more elegant solution.

@IgnacioHR
Copy link
Author

I'v taken some time to better document the use case

Background

I am developing a Zigbee-based gas consumption meter that reports usage through the seMetering cluster. According to the Zigbee specification, the device can report its consumption data whenever the internal counter increases by a predefined value (e.g., every 10 units).

The Issue

The device remains in deep sleep most of the time to save battery. However, when the counter increases by 10 units, the Zigbee radio must be turned on for at least 30 seconds to transmit the data and receive any acknowledgments or configuration updates.

The problem arises because the mechanical gas meter’s counting wheel rotates approximately once every 10 seconds, meaning the device wakes up frequently but only requires active radio communication every tenth increment. The process follows this sequence:
1. The device detects a pulse from the gas meter.
2. It increments the internal counter.
3. After 10 increments, the Zigbee radio is enabled to report the consumption.
4. The radio must remain active for at least 30 seconds.
5. Due to the reason the radio is active, the new value is reported immediately and so remains on for another 30s
6. Currently, there is no way to stop the Zigbee radio once it is enabled, except by entering deep sleep.
Since my use case does not allow entering deep sleep immediately after the 30-second window, the Zigbee radio remains active indefinitely, draining the battery unnecessarily.

Proposed Solution

To address this, I propose implementing an esp_zb_stop() function that allows stopping the Zigbee stack when it is no longer needed. This function should properly shut down the Zigbee radio and stack so we can implement more flexible power management strategies.

This feature would significantly benefit low-power battery-operated devices that do not need continuous Zigbee connectivity but must wake up periodically to report data.

Conclusion

Implementing esp_zb_stop() would improve power efficiency for devices that rely on Zigbee for periodic reporting but cannot afford to keep the radio on indefinitely. I hope this feature request can be considered for a future release.

@chshu
Copy link
Collaborator

chshu commented Feb 17, 2025

@IgnacioHR Could you please check if the deep_sleep example could meet your requirement? The application can call esp_deep_sleep_start() whenever it wants to stop the zigbee connection, and put the device to deep sleep mode, then a RTC timer can be used to wake up the device and do the reporting periodically.

Please note that the device needs to go through a rejoin process after the deep sleep, while the light_sleep doesn't.

esp_zb_stop() will be supported in our future release. But for your current requirement, please check the light_sleep or deep_sleep examples.

@IgnacioHR
Copy link
Author

Hi @chshu

Yes sir, this is the workaround we are using, the source code is published here:

https://github.com/IgnacioHR/ZigbeeGasMeter

  1. We explicitly send report values using a call to esp_zb_zcl_report_attr_cmd_req(...) we also take care of the reporting schedule not to break the Zigbee Specification.
  2. If the zigbee radio is ON we set a timeout of 30 seconds before entering deep sleep in order for the values to be received and acknowledge by the coordinator. If the Zigbee radio is OFF the timeout is only 500 milliseconds.
  3. Deep sleep works very well, but due to the reason the mechanical gas meter’s counting wheel rotates approximately once every 10 seconds, it sends a new value under the 30s to enter deep sleep and this maintains the device powered on.

We can force the device to operate in a manner that the counter value will be transmitted every 10 rotations so it gives 300 seconds and the device can enter deep sleep and remain active 10% of the time but all this are just workarounds until we have the opportunity to better control the Zigbee radio.

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

No branches or pull requests

2 participants