tlaukkan / zigbee4java

Zigbee API for Java provides simple Java interface to ZigBee network.
Apache License 2.0
144 stars 68 forks source link

Timeouts on End Devices #43

Closed presslab-us closed 9 years ago

presslab-us commented 9 years ago

I often see timeouts on end devices, which are battery powered. These devices spend most of the time sleeping, and only occasionally wake up and poll their nearest router to see if any requests are waiting.

The poll time for most end devices I have here is 5 seconds. The HA spec is as follows: In their normal operating state, ZigBee end devices shall poll no more frequently than once every 7.5 seconds... Unfortunately the default timeout in zigbee4java is 5 seconds. So often any read operation will timeout to an end device.

What would be the best way to address this? In the short term I think raising the timeout to 10 seconds would work for my devices here. But according to the HA spec it could be much longer than 7.5 seconds. Maybe there should be a separate large timeout (30 seconds?) for end devices, and the usual timeout for routers. Or the timeout could be exposed in the API, but then it's left up to the host application which seems unnecessary.

cdealti commented 9 years ago

Note that in the ZigBee Pro stack profile the MAC of the router is buffering the indirect transmissions addressing sleeping end devices (aka rxOnWhenIdle=false) for exacly 7.5s. After this interval an indirect message is purged by the router. So if you send a message, say from the coordinator, to a sleeping end device, the device might not be able to extract the message from its router via a poll, unless it polls its router with a period <= 7.5s which the HA profiles spec does not allow and would waste too much energy on the device.

In my experience battery powered devices cannot normally poll their routers at these rates due to energy constraints, so you cannot talk to a device at any time.

Instead, these device can be configured to report (some of) their attributes to the coordinator with a long period, say once every 10 minutes. Usually, the device's stack will poll it's router shortly after sending the report. maybe to receive an application acknowledge from the coordinator.

This will be the time to try to talk to the device and you must do that readily. In the meantime, the messages to be delivered to a sleeping end device must be buffered by the sender because the device's router cannot buffer them for more than 7.5s.

On the reply timeout you should choose a value > 7.5s. Waiting much more time is not needed if the route to the device already exists.

Regards, Cristiano

presslab-us commented 9 years ago

Thanks for the info! So perhaps a value of 8 seconds makes sense; this will allow the end device to poll the router for a message (which it must do within 7.5 seconds), process it, and send a reply.

I know some end devices poll much faster when first powered up, or joined, so as to receive any configuration messages. But sending a request when the device sends it's attribute change is an interesting idea. Maybe sometime in the future there could be an API for this where zigbee4java queues the message until it sees something from the device and then immediately sends it.

Does anyone see a problem with increasing the default timeout to 8 seconds? Hopefully this will fix the communication problems with end devices that poll frequently, like mine which poll every 5 seconds.

Thanks again, Ryan

cdealti commented 9 years ago

The original zb4o had configuration properties for these timeouts. I haven't looked to zb4j yet but I expected these were not hardcoded.

presslab-us commented 9 years ago

Commit changing the default timeout: https://github.com/tlaukkan/zigbee4java/commit/7c45f053b710cd2cd38c638a6639c19d6c3c30ae

cdjackson commented 9 years ago

Hey Ryan. As a matter of interest, does this help with your devices or do you still get timeouts?

presslab-us commented 9 years ago

Yes it certainly seems to have helped. I have played around with my battery powered end devices in the console for about an hour and I did not see any timeouts, where previously I would get timeouts and no ack. I still get "BROKEN ZIGBEE UNDERSTANDING" but this seems unrelated.

All three of my battery end devices poll at 5 seconds. As mentioned above if a device polls at longer than 7.5 seconds those devices will need to be handled in a different way.

presslab-us commented 9 years ago

I did find a different timeout that was also 5 seconds: https://github.com/tlaukkan/zigbee4java/commit/6426a579b972baa7c1df7274d0615dbd6e9b8a86 This should probably use the DEFAULT_TIMEOUT but for now I just changed it to 8 seconds also.