Device silently stops reporting: lost coordinator binding and cached reporting config diverging from the device, both invisible to Z2M
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 15.7k
- Forks
- 2k
- Avg merge
- 18h 55m
- Merged PRs (30d)
- 35
Description
What happened
A SmartThings GP-WOU019BBDWG plug silently stopped reporting state and power.
Zigbee2MQTT continued to show the device as healthy throughout: availability
online, last_seen current, LQI 94. Toggling the plug's physical button changed
nothing in Zigbee2MQTT.
Investigating turned up two separate problems.
1. The device loses its binding to the coordinator
With the device in the failed state:
- A ZCL read of
genOnOff/onOffreturned the correct value (ON) immediately,
and the plug had been physically switched on hours earlier. The device was
reachable, responsive, and tracking its own state correctly. - On/off commands worked normally.
- Clicking Bind on the existing Coordinator entry — and nothing else, no
reconfigure, no change to reporting config — immediately restoredonOff
reporting. Verified by pressing the physical button off and on; both were
reported within a second.
This failure mode is invisible to every health signal Zigbee2MQTT exposes.
Commands, reads and availability pings are all unaffected because they don't
depend on the binding table, so last_seen stays fresh while the device reports
nothing.
2. Zigbee2MQTT's cached reporting config diverges from the device
The Reporting tab listed six entries for endpoint 1 — genOnOff/onOff,
haElectricalMeasurement/activePower and seMetering/currentSummDelivered each
appearing twice.
Running Sync reporting per attribute in the Dev console reduced this to four.
Three entries were pruned as not present on the device.
Sync also revealed the surviving entries didn't match. For genOnOff/onOff,
Zigbee2MQTT had cached min 0 / max 65000; the device actually held min 1 / max 65534.
After the re-bind, power still did not report. A read returned a correct 32 W
(acPowerMultiplier / acPowerDivisor both sane), and switching the load off
produced a 32 W → 0 W change — six times the configured 5 W reportable change,
with a 10 s minimum interval — and still no report. So the cached activePower
entry did not exist on the device either.
Applying the activePower and currentSummDelivered rows restored both. Power
and energy now track the physical button in real time.
Why this matters beyond the one device
Because meta.configured was set, configure.ts would never re-run on startup.
The frontend showed a fully populated, healthy-looking reporting table. Nothing
in Zigbee2MQTT surfaces the divergence between the cached configuredReportings
and what the device actually holds, and Sync reporting is only reachable as a
manual, per-attribute button in the Dev console.
What I am not claiming
- I did not issue a ZDO
Mgmt_Bind_req, so binding loss is inferred from the
re-bind fixing reporting, not directly observed. The Bind tab is cached and so
can't confirm it either. - Sample size is one device so far.
- I don't know what triggers either failure, or how the two relate. The device is
mains-powered and never sendsdeviceAnnounce, so
reconfigureReportingsOnDeviceAnnounce()would not fire here — which rules out
the usual remedy used for Legrand and IKEA devices. The closest existing
precedent islumiOutageCountRestoreBindReporting(), which restores bindings
and reporting using a device-specific signal; this plug offers no equivalent.
Possibly related
- #18315, #19750, #23258 — all this model or similar, all closed as stale. All
assumed reporting configuration was at fault; none considered binding loss or
cache divergence.
Device
| Model | SmartThings GP-WOU019BBDWG (ZB-ONOFFPlug-D0005) |
| Manufacturer OUI | Silicon Laboratories |
| Firmware ID | 2.3 (20190716-165) |
| Type | Router, mains |
Debug info
| Zigbee2MQTT | 2.13.0 (fcbb7ff) |
| Frontend | 2.14.0 |
| zigbee-herdsman-converters | 26.90.0 |
| zigbee-herdsman | 10.8.0 |
| Coordinator | ZStack3x0, revision 20250321 |
| Node | v24.18.1 |
| Network size | 34 devices |
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with configure.ts and the reconfigureReportingsOnDeviceAnnounce() path, then compare them with the lumiOutageCountRestoreBindReporting() precedent. Use the Dev console's Sync reporting and Bind actions to reproduce the cached-reporting and coordinator-binding symptoms. Done should include an agreed, reproducible way to detect or recover from the divergence for this device class.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100