View LQI & RSSI in ZHA

Is there any possibility to view ALL the LQI & RSSI figures for the devices paired in ZHA ? Now one has to click each individual device to see the numbers. Unfortunately in the “Visualization” screen many of the devices show no linkages (even though they send data and have LQI numbers) . I would like the possibility to see these numbers on the "Devices " screen or any other screen . Appreciate your inputs.

You could try the network card

I have submitted a feature request for this but it has not gained any traction.

https://community.home-assistant.io/t/zha-show-last-seen-lqi-and-rssi-as-entity-attributes/275760

The tool referenced by @Luitertje is a start, but I still unclear which LQI value it displays for a device. There is one LQI value termed ‘coordinator to device last path’ or something like that. But I do not see this value exposed by ZHA, it might calculated. You can get all the RSSI values for each device and each of their peer LQI values from ZHA via web socket call. This gives you a little insight into what devices have connections between what devices and the link quality of these peer connections. I wrote a couple of basic routines to continuously capture these and collect them into a SQLITE db. They also dump the most recent data to the screen. It is a work in progress and pretty rough, but might give you some ideas:
ws02.py dumps the raw JSON of current state from ZHA
zha_ws.py is the current version of the ‘over time’ collector and ‘nicer’ display

Your work on this is excellent and useful but what I am really looking for is LQI, RSSI and last_seen as device or entity attributes so that I can use these values in automation triggers.
For example, in my case the last_seen date for each of my approx 40 zha devices is almost always updated within the hour. In rare cases my Aqara temp sensors stop reporting and I could setup an automation to let me know when this happens. This sensor eventually shows as unavailable but not for many hours later and in some cases, this is a real problem for me.
cheers

Well, it’s bit of coding, however I think what you want to get it possible. I agree, doing so it reinventing the wheel, as this data should be easily exposed by ZHA in the entity. I understand Zigbee2MQTT does this.

If you start with the example I wrote and turned it into a reactive app daemon application you could create a entity or entities that would expose LQI, RSSI and last seen.

Perhaps you would like to get in touch with the maintainers from zha.

Also, I know there’s a repo that’s refactoring the visualization card in to an addon. But that’s still a lot of work in progress as far as I know.

Yes, zigbee2mqtt exposes these values and I was using them but now I have switched to ZHA and they are missing.
Also, a ‘reactive app daemon application’ is waaayyyyy beyond my skills. :slight_smile:

I have submitted a feature request for this but not sure if that is enough?

It’s one way. But I’m not sure if the devs of zha look into the forums for feature requests.

I’m not sure either but then what is the feature request forum for?

1 Like

If you need LQI and RSSI as entities in Zigbee, you are doing zigbee wrong

  • A wise Zigbee developer

That said, I’m doing zigbee wrong. I wrote out some Node-RED flows that consumes the ZHA WS API and then creates MQTT auto discovery sensors with the LQI, RSSI, parent information, etc. Needs a little work to re-do now what zha-map is deprecated though.

var devices     = [];

msg.zha_devices.forEach(item => {
    var map = msg.zha_map_devices.devices.find(o => {
        return o.ieee === item.ieee
    });

    // Find Parent
    var parent_router = {};
    if(map.neighbours.length === 0) {
        msg.zha_map_devices.devices.forEach(parent => {
            parent.neighbours.forEach( neighbour => {
                if (neighbour.relation == "Child" && neighbour.ieee == item.ieee) {
                     parent_router = parent;
                }
            });
        });
    }

    var dev = {
        name : (item.user_given_name !== null ? item.user_given_name : item.name),
        ieee: item.ieee,
        lqi : map.lqi,
        zha_lqi: item.lqi,
        zha_rssi : item.rssi,
        available : item.available && !map.offline,
        manufacturer: item.manufacturer,
        model: item.model,
        power_source: item.power_source,
        is_router: (map.neighbours.length > 0)
    };
    
    if(!dev.is_router) {

        dev.parent_ieee         = (parent_router.ieee !== null ? parent_router.ieee : "None");
        dev.parent_manufacturer = (parent_router.manufacturer !== null ? parent_router.manufacturer : "None");
        dev.parent_model        = (parent_router.model !== null ? parent_router.model : "None");
        dev.parent_nwk          = (parent_router.nwk !== null ? parent_router.nwk : "None");
    } else {
     
        var neighbours_lqi      = 0;
        var neighbours_best_lqi = 0;
        var child_count         = 0;
        var neighbours_best     = {};
        var coordinator_direct  = false; 
        
        map.neighbours.forEach(neighbour => {
            neighbours_lqi = neighbours_lqi + neighbour.lqi;
            if(neighbour.lqi > neighbours_best_lqi ) {
                neighbours_best_lqi = neighbour.lqi;
                neighbours_best = neighbour;
            }
            
            if(neighbour.device_type == "Coordinator") {
                coordinator_direct = true;
            }
            if (neighbour.relation == "Child") {
                child_count = child_count + 1;
            }
            
        });
        
        dev.child_count         = child_count;
        dev.neighbour_count     = (map.neighbours.length > 0 ? map.neighbours.length : null);
        dev.neighbour_avg_lqi   = Math.floor(neighbours_lqi / map.neighbours.length) ;
        dev.neighbour_best_lqi  = neighbours_best_lqi;
        dev.neighbour_best      = neighbours_best;
        dev.coordinator_direct  = coordinator_direct;
    }
    
    devices.push(dev);
});

msg.payload = devices;

return msg;

and

var sensor_name      = msg.payload.name;
var ieee             = msg.payload.ieee;
var unique_id        = msg.payload.ieee.replace(/:/g, '-').toLowerCase();
var state_topic      = "zha_devices/" + unique_id + "/state";
var attributes_topic = "zha_devices/" + unique_id + "/attributes";

if (msg.payload.available) {
    state_payload = 'ON';
} else {
    state_payload = 'OFF';
}

var sensor_config = {
    payload: {
        name: "ZHA Devices - " + sensor_name,
        unique_id: unique_id,
        state_topic: state_topic,
        json_attributes_topic: attributes_topic
    },

    topic: "homeassistant/binary_sensor/" + unique_id + "/config"
};

var state = {
    payload: state_payload,
    topic: state_topic
};

var attributes = {
    payload: msg.payload,
    topic: attributes_topic
};
return [sensor_config, state, attributes];

Is there any chance that your code can run as a script within HA?
Also, I am mostly interested in Last Seen as some of my key sensors drop off the mesh occasionally. Is this possible.
thanks for you work.

No easy way to perform the fully entity iteration within a HA script outside of going to AppDaemon.

Oh well, thanks for the reply.
fyi, I have created a feature request for this but it has not gained any traction.