The Zigbee Mesh Audit Checklist

Thanks for subscribing. Check your inbox for the confirmation link so the newsletter actually reaches you. In the meantime, this is the checklist I wish I’d had before I found out my own Zigbee network was half dead. Print it, or keep it open next to Home Assistant.

Find the dead and weak devices before they find you. About 20 to 30 minutes.

When I audited my own network, 7 of my 14 battery sensors were offline. That included two leak sensors, one on the water heater and one on the washing machine. I hadn’t noticed. Not one of them.

My setup is a SONOFF ZBDongle-P on a Raspberry Pi 5 running Home Assistant OS with ZHA, and zero routers. This checklist takes that audit and adds what Home Assistant’s and Zigbee2MQTT’s own docs recommend. It’s written for ZHA, with notes on where things live in Zigbee2MQTT.

1. Take inventory

You can’t judge a mesh until you know what’s in it. Three roles matter: the coordinator, routers (mains-powered devices that relay traffic), and end devices (usually battery-powered, and they don’t route).

  • ☐ Count your coordinator. There should be exactly one.
  • ☐ Count your routers. These are always-powered devices like plugs, many bulbs, and some fans.
  • ☐ Count your end devices. These are your battery sensors, remotes, and buttons.
  • ☐ In ZHA, open a device’s page from Settings, Devices & services, ZHA. The Zigbee info block on that page shows Device Type (coordinator, router, or end device), Power source, LQI, RSSI, and Last seen. In Zigbee2MQTT, the device page in the frontend shows the type, and it’s also logged at startup.
  • ☐ Write the three numbers down. If routers is zero and end devices is a big number, that was me.

To be clear, a router has to stay powered. A bulb on a switch that gets flipped off every night is a bad router, because every device that was talking through it loses its path. Home Assistant’s docs say the same thing: don’t run a setup where your router devices are often powered off.

2. Find the dead ones

This is the part that stings. Do it before you read anything else.

  • ☐ List every Zigbee entity that shows unavailable. Filter your entity list by that state, or sort by the integration.
  • ☐ Open each sensor and check when it last reported (ZHA shows Last seen on the device page). A sensor that says it’s fine but hasn’t changed in weeks isn’t fine.
  • ☐ Check battery readings. A battery percentage frozen at the same number for a long time is a stale reading, not a healthy battery.
  • ☐ Trigger each sensor by hand and watch the entity update.
  • ☐ Zigbee2MQTT note: its availability feature is off by default, so turn it on in the configuration first. Once it’s on, mains devices are marked offline after 10 minutes of silence, but battery devices get 25 hours before they’re marked offline. So a dead battery sensor can look fine for a full day.

My result was 7 of 14 offline. Motion 1 of 4 online, temperature and humidity 2 of 3, leak 1 of 3, door and window 2 of 3. Only the presence sensor was fully online. Count yours by type too. Patterns show up fast.

3. Read the signal

Two numbers come up: LQI (link quality, a positive number on a 0 to 255 scale) and RSSI (raw signal strength in negative dBm). Home Assistant’s docs describe LQI as hard to interpret, because the Zigbee spec doesn’t standardize how vendors measure it. For RSSI, they say values of -60 and above are strong and values of -80 and below suggest a noisy environment.

  • ☐ Find LQI and RSSI for each device. In ZHA, they’re on the device page, and the network visualization (next section) shows them per link. In Zigbee2MQTT, look at the device’s link quality and the map.
  • ☐ Note the lowest ones. Mine ranged from 24 to 114 out of 255 on the devices that were online. Use the numbers to rank your devices, not to grade them.
  • ☐ Treat a low number on a device that works as a warning, not a verdict. Treat a low number on a device that’s offline as a clue.

Home Assistant’s docs also say not to judge RSSI or LQI on their own, and that the numbers describe the first hop from the device, not the whole path back to the coordinator. One reading isn’t gospel. It’s a place to start looking, if that makes sense?

4. Check the mesh

  • ☐ Open the ZHA network visualization. The docs say Settings, Connectivity, Zigbee, then Show map. On older Home Assistant versions it’s under Settings, Devices & services, ZHA, Configure. Zigbee2MQTT has a Map page in its frontend.
  • ☐ Look at which devices connect through which. Battery devices connect to a parent. They don’t relay for anyone else. Don’t panic over a missing link on a sleepy battery sensor, though. The docs say that’s common and not a fault if the device is still reporting.
  • ☐ Find your routers on the map. If the coordinator is the only parent, every sensor has to reach it directly.
  • ☐ Mark the dead and weak devices on a rough floor plan. Look for the far corners.
  • ☐ Check your routers for known problems. Zigbee2MQTT’s docs warn that some routers are of mediocre quality, and they name some versions of one SONOFF plug as limited. Search your router model before you trust it.

Mains-powered devices usually act as routers, including many plugs and light bulbs. Home Assistant’s docs also note some brands work better as routers than others, so a bulb isn’t automatically a good one.

5. Check the coordinator

Where the stick sits matters more than people expect. Home Assistant’s docs say to use a long USB extension cable and keep the coordinator away from interference and obstacles. They also say to avoid USB 3.0 ports, computers, and peripherals, and to use a USB 2.0 port or a powered USB 2.0 hub if that’s what you have.

  • ☐ Is the coordinator plugged straight into the host? Use a USB extension cable instead. Zigbee2MQTT’s docs say even 50 cm helps.
  • ☐ Is it next to a USB 3 port, an SSD, or the Wi-Fi radio? Move it.
  • ☐ Is it tucked in a corner or against a wall? Home Assistant’s docs say to place it near the middle of the house, away from walls, ceilings, and floors.
  • ☐ Consider a network coordinator on wired Ethernet, which lets you put the radio anywhere, away from the host entirely. Home Assistant’s docs warn against running a coordinator over Wi-Fi, WAN, or VPN.

If you’re choosing a stick, I wrote up the SONOFF ZBDongle-P, which is the one I run.

6. Check Wi-Fi overlap

Zigbee and Wi-Fi share the 2.4 GHz band, and their channels can overlap. Home Assistant’s docs say Wi-Fi frequency ranges can overlap with Zigbee.

  • ☐ Find your Wi-Fi channel on each 2.4 GHz access point. Write it down.
  • ☐ Try the Wi-Fi side first. Home Assistant’s docs say it’s usually better to first try setting a static Wi-Fi channel.
  • ☐ Keep the coordinator away from your access points.
  • ☐ Think hard before changing the Zigbee channel. The docs say the best practice is to leave it at the ZHA default. If you do change it, they suggest 15, 20, or 25, and it can take devices up to an hour to follow. Zigbee2MQTT warns that changing the channel might require re-pairing some devices.

7. Fix in the right order

If you replace batteries first, you’ve just wasted batteries on devices that can’t reach anything.

  • ☐ Add routers first. Put a mains-powered Zigbee plug between the coordinator and the weak area. Leave it plugged in permanently.
  • ☐ Fix the coordinator placement if that’s part of the problem.
  • ☐ Re-pair the devices that are still offline, as close to the new router as you can. Zigbee2MQTT’s docs suggest limiting pairing to that router.
  • ☐ Replace batteries last, and only on devices that still won’t report once the mesh reaches them.

That’s my own plan, and I’m partway through it. I’m adding Zigbee plugs as routers toward the laundry room and the workshop, moving the coordinator onto a USB extension cable away from USB 3 and Wi-Fi noise, and then re-pairing and replacing batteries.

8. Set an alert so it never happens silently again

This is the step I skipped, and it’s why I found out the hard way. A Home Assistant automation can tell you when a sensor goes unavailable.

  • ☐ Create an automation with a State trigger on your Zigbee sensors, to the state unavailable.
  • ☐ Add a for duration so a brief blip doesn’t ping you. Battery sensors can go quiet for a while, so pick a longer time for them.
  • ☐ Send a notification to your phone that names the sensor.
  • ☐ Test it, but be patient. ZHA waits a while before it marks a device unavailable: 2 hours of silence for mains devices and 6 hours for battery devices by default. You can see and change both timeouts under ZHA’s options (Settings, Connectivity, Zigbee, Options in current versions). Pull a battery and check back in the evening, not after five minutes.

Here’s a generic version. Swap in your own entities, and swap in your own phone’s notify action (search for “notify” under Developer tools, Actions to find its name). The for here stacks on top of ZHA’s own timeout, so with the defaults a dead battery sensor pings you about six and a half hours after it goes quiet.

alias: Zigbee sensor unavailable
triggers:
  - trigger: state
    entity_id:
      - binary_sensor.example_leak_sensor
      - binary_sensor.example_door_sensor
    to: unavailable
    for: "00:30:00"
actions:
  - action: notify.mobile_app_your_phone
    data:
      title: Zigbee sensor offline
      message: "{{ trigger.to_state.name }} has been unavailable for 30 minutes."

9. Check the critical sensors first

Not all sensors are equal. A dead motion sensor means a light doesn’t turn on. A dead leak sensor means you find out about the water when it’s on the floor.

  • ☐ Leak sensors first: water heater, washing machine, sinks, dishwasher.
  • ☐ Smoke sensors next, if they’re on Zigbee.
  • ☐ Door and window contacts next, especially exterior doors.
  • ☐ Motion, temperature, and everything else after that.
  • ☐ Put the critical ones on your alert list first, with a shorter delay.

I didn’t notice my two offline leak sensors. That’s the one to fix first.

Run it again

Run it once, write down what you find, and run it again after you make changes.

Reply to the newsletter email with what your audit found. How many offline, which devices, what fixed it. I’m all ears.

-Randall

Sources