-
Notifications
You must be signed in to change notification settings - Fork 0
Signal Strength
Device Sentinel watches how strong each device's radio link is, and how long it spends struggling. As of 0.4.3 this records and reports; it does not notify yet. The numbers land in the nightly report and the diagnostics, for you to read and act on.
Signal numbers have no shared scale. Link quality (LQI) is defined by each manufacturer, so a device deep in the mesh may idle happily at a value that would mean death for one sitting beside the coordinator. A single global cutoff cannot tell those two apart. A per-device baseline can.
So Device Sentinel learns each device's floor: the worst link quality that device has repeatedly shown while still working. It is built from a rolling window of daily lows, with the worst readings trimmed off, so one bad hour does not move it but a real decline does.
The floor is not just a baseline to sit under. It is the line itself. Dwell counts the time a device spends at or below its own trimmed floor.
This is deliberate, and it is the change that makes the whole feature testable. A line set below the floor could only ever catch catastrophe: on a healthy day nothing would reach it, the reading would be zero, and you would have no evidence the detector works at all. A line set at the floor is brushed by a healthy device on its bad moments, which gives a small nonzero reading that proves the detector has teeth, and it is clearly exceeded by a device that lives at its lows, which is the anomaly you want to catch.
One rule covers both radio scales. For LQI a lower number is worse; for RSSI, measured in dBm, a more negative number is worse. Below the floor is below the floor either way, so there is no separate formula and no asterisk on RSSI.
The floor is the lowest reading a device has shown, after trimming off a few of the very lowest as spurious. How many it trims grows with how much history it has:
- Under a week: trim nothing. The floor is the plain lowest reading, so the line is live from the very first day.
- At a week: trim the single lowest.
- At two weeks: trim the two lowest.
The floor settles from "worst ever seen" toward "typical worst" as the history earns trust. Note this trims the lowest values, the opposite of how the freeze rhythm trims its highest gaps. For signal, a spuriously bad reading is the anomaly to set aside; for rhythm, a spuriously long gap is. Both trim the outlier; the outlier just sits at a different end.
Rail values never feed the floor. A link quality pinned at 255 (or an RSSI at -128) is the empty value of a field the device stopped filling in, not a reading, so it is filtered out before the floor is computed. A device whose entire history is rail has no floor at all, rather than a false one.
The Signal Strength config screen has one sensitivity control for the whole fleet. It shifts the floor up or down by trimming more or fewer of the low readings.
- Left is less sensitive. The floor sits at the rawest low and is rarely crossed. Fewer, only-severe flags.
- Right is more sensitive. The floor sits higher and is brushed more often. Weak moments register sooner.
The goal to aim for: some of your devices should show small readings in the 0-5 percent range. That is the proof the line sits where normal variation just reaches it, so that a real problem stands out as big and obvious. If nothing ever touches the line, the line is telling you nothing.
The control is not retroactive. Changing it recomputes the floor for readings that arrive afterward; the dwell already counted today stays counted. A full clean day is needed to see a change's true effect. That is why it lives on the config screen, which sets the expectation of "this configures behavior going forward," rather than as a live entity that would imply an immediacy it cannot deliver.
A signal is noisy. It dips and recovers constantly, and a device that brushed its floor for one second at 3 AM is not a problem. So Device Sentinel does not report crossings. It reports dwell: the share of each day a device spent at or below its floor.
A brief dip that recovers counts only for the seconds it lasted. A link genuinely in trouble sits at or below the floor and the percentage climbs. If a device goes silent while below the floor, that silence counts as time below, because a link that died while struggling was struggling the whole time.
The nightly telemetry report gives each device a SIGNAL LOWS column and a DWELL% column. SIGNAL LOWS shows the daily minimums the floor is chosen from, newest first, with three marks: the floor (the line dwell measures against) is bold on its earliest recorded appearance, readings strictly below the floor are struck through (the trimmed lows set aside so a spurious bad reading does not define the line), and rail fill values are shown in italic. A value equal to the floor is never struck, so the same number is never both the line and an outlier. The way to use it:
Most of your devices should sit in low single digits. That is the design working: a healthy device brushing its own floor a few percent of the day is proof the line has teeth, and you ignore it.
The outliers are the whole point. A device reading 20 or 40 percent spent much of its day at or below its normal-worst, and that is worth looking at. If several outliers are in the same room, that room is where your mesh is thin: it needs a router or a repeater. The percentage turns a vague "my Zigbee feels flaky" into a specific place to put hardware.
The marks let you check the line against the readings behind it at a glance: the bold value is the line, and you can see the struck lows it set aside and the italic rails it ignored. If a device's line looks wrong, its lows show you why.
Sometimes a device stops reporting its signal at all and leaves the last value frozen. In Zigbee2MQTT this shows as a link quality pinned at 255, which looks like perfect signal and is the opposite: it is the empty value of a field the device stopped filling in. Across a whole fleet, real link quality never reaches 255, so a flat 255 is always a stale reading, not a strong one.
Device Sentinel calls a signal frozen when two things are true: the device is lively by its own learned rhythm (still reporting on schedule), and its signal value has read identical across its last five reports. Counting reports rather than time is what lets one rule fit a device that reports every few seconds and one that reports every few hours, because a live radio link wobbles a point or two on every reading, so five identical readings in a row is stuck whatever the gap between them. This is judged live, so the Signals Frozen entity updates as reports arrive and the nightly report is a snapshot of the same judgment. A freeze at the rail value 255 or -128 is marked FROZEN (rail), a near-certain fault. A frozen signal is not a weak link; it is a lying one, and it is worth fixing because it hides whatever the real signal is doing.
To clear a frozen signal, in order of effort:
- Trigger the device to force a fresh report: press its button, open and close the contact, cycle the plug.
- Power cycle it, or pull and reseat the battery.
- Re-interview or re-bind it in Zigbee2MQTT, which makes it re-establish what it reports.
On the development system this detection found sensors frozen at 255 that every dashboard showed as healthy. Most were recovered within minutes by the steps above. One, a mains plug, resisted every step and stayed frozen, which is why a frozen device is never dropped from tracking automatically. It stays on the report until you either recover it or exclude it by hand.
A device that resists every recovery, like that stuck mains plug, will report noise forever. The Signal Strength config screen has a signal-only exclude list to silence it, in the same broad-to-narrow shape as Low Battery: by integration, by label, or by individual device.
Exclusion suppresses judgment, not observation. An excluded device keeps recording its floor and dwell in storage; it simply stops being reported and never appears in the frozen list. Because the history keeps accumulating silently, re-including the device later brings its data back instantly, with no relearning. In the report, an excluded device shows its daily lows as normal but reads "excl" in the dwell and frozen columns.
Press Enable Signals on the device page. Some integrations ship signal entities turned off, and this turns them on so Device Sentinel can learn from them. Entities you disabled yourself are left alone. There are matching Enable Last Seen and Enable Battery buttons beside it for those diagnostics.
Open the Signal Strength config screen to set the sensitivity and, if you have a device that will not recover, to exclude it from reporting.
Notifications for signal problems, once the dwell soak matures enough to rule where the alerting thresholds sit. Until then, signal detection records and reports for you to read; it does not alert on its own.
Device Sentinel is brought to you by James Lander at The Thinking Home. Read the story behind it: Reliable Home Assistant Dead Sensor Detection.
Repository · Report an Issue · Releases · Blueprints
Licensed under GPL-3.0-or-later. Copyright © 2026 James Lander.
Start Here
Configuration
- The Device Page
- Notifications and Daily Brief
- Exclusions and Muting
- Low Battery
- Signal Strength
- Freeze Detection
- Advanced
The Reports
Automations
Understanding
- How Device Sentinel Learns
- Maintenance Mode
- The Bridge and Broker Sensors
- What Is Recorded About Your House
- Built to Be Efficient
Coordinator Stacks
Help