zigpy / zigpy-xbee

A library which communicates with XBee radios for zigpy
GNU General Public License v3.0
22 stars 18 forks source link

LQI and RSSI sensors for some devices #153

Closed Shulyaka closed 11 months ago

Shulyaka commented 1 year ago

This PR adds LQI and RSSI sensors to certain devices.

Problem: The XBee API does not provide an API to directly measure LQI of a zigbee packet. There is DB (Last Packet RSSI) AT command that measures the RSSI of a last received packet, but 0x91 Explicit Receive Indicator API frame is missing the address of the last hop node, so it is not clear to which device the RSSI is related. It also lacks the LQI or RSSI info. There is ND (Network Discovery) AT command which can provide the RSSI of a node, but this only works for other XBee devices and not any Zigbee device. There is also AS (Active Scan) AT command which provides both LQI and RSSI information, but the active scan ignores the network topology and thus useless, it does not also work on end devices because they are sleeping nodes an don't respond to the scan.

But not all hope is lost.

Solution: Instead o relying on the API, we will use ZDO. In fact, we already do all the needed ZDO requests for the topology scan. All e need is to listen and interpret the results. The sensor values will be updated as often as the topology scan is run (every hours by default and min 20 minutes).

LQI: As part of topology scanning we do a neighbors scan from all routers by sending Mgmt_Lqi_req. The response is a table of neighbors, including their relationship and LQI. If a neighbor is a parent, then we save the LQI for the device that responded, and if a neighbor is a child, then we save the LQI for the child. Siblings and other devices are ignored. Limitation: Because the XBee devices don't handle well self-addressed ZDO requests, this does not work for end devices that are immediate children of the coordinator.

RSSI: For the topology scan we also request the route information from the routers, by sending Mgmt_Rtg_req ZDO request. The response is a list of routes from the node. If that response contains a direct route to the coordinator, we realize it is the last hop, so we immediately execute the DB AT command and save the RSSI value. Limitation: This technique only works for routers that are direct children of the coordinator.

codecov[bot] commented 1 year ago

Codecov Report

All modified lines are covered by tests :white_check_mark:

Comparison is base (39ef2f1) 100.00% compared to head (576f148) 100.00%.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## dev #153 +/- ## ========================================= Coverage 100.00% 100.00% ========================================= Files 6 6 Lines 758 779 +21 ========================================= + Hits 758 779 +21 ``` | [Files](https://app.codecov.io/gh/zigpy/zigpy-xbee/pull/153?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zigpy) | Coverage Δ | | |---|---|---| | [zigpy\_xbee/zigbee/application.py](https://app.codecov.io/gh/zigpy/zigpy-xbee/pull/153?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zigpy#diff-emlncHlfeGJlZS96aWdiZWUvYXBwbGljYXRpb24ucHk=) | `100.00% <100.00%> (ø)` | |

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

Shulyaka commented 1 year ago

Rebased and added tests