Documents the non-default ZCL reporting configuration now on the Wetterstation, and how to restore it. No behaviour change from this PR — the device was reconfigured at runtime; this records it.
Adds zigbee2mqtt-ws90-reporting.md plus a pointer from the device stanza in zigbee2mqtt-config.yaml.
Why it needs a document rather than a manifest
Zigbee2MQTT has no settings-schema field for reporting configuration. It is applied over MQTT (bridge/request/device/configure_reporting) and stored on the device and in database.db. Flux cannot reconcile it, and a fresh PVC will not have it.
What changed on the device
attribute
cluster
min
change
was
temperature
1026
5
10 → 0.1 °C
10 / 100 (1 °C)
humidity
1029
5
50 → 0.5 %
10 / 100 (1 %)
pressure
1027
5
1 → 1 hPa
10 / 50 (50 hPa)
illuminance
1024
5
5
10 / 5
wind ×3
0xfc01
5
1
10 / 1
UV
0xfc02
5
1
10 / 1
rain ×2
0xfc03
5
1
10 / 1
Battery (cluster 1) left at its hourly default.
The interval
min is a hold-off, and it was 10 s against an 8.8 s transmit interval — so every change-triggered report was held past a cycle and landed on the next. Attributes reported at best every 17.6 s and drifted out of phase with each other; the published stream showed no 8.8 s periodicity at all, just a smear across 2–8 s.
At min: 5 each attribute reports on its own transmit:
Mean gap 8.69 s — the transmit cycle, visible in MQTT for the first time. Publish volume fell, ~631/h → ~445/h, because each publish is now a whole cycle rather than a fragment of one.
The deadbands
These come from the shared modernExtend helpers, which the WS90 definition in shelly.ts composes without overrides — anti-chatter values sized for battery-powered indoor sensors, where report volume costs coin-cell life and mesh airtime.
temperature was 1.00 °C: a staircase moving ~twice an hour. Now 0.1 °C, matching the resolution the device reports.
pressure was change: 50 with scale: 10 — a 5 kPa (50 hPa) deadband, which real barometric pressure never traverses. Pressure only ever updated on the hourly max heartbeat, and pressure_trend / weather_condition derive from it. Worth noting the same library configures the identical ZCL attribute with change: 5 (5 hPa) in its older reporting.ts helper — the two code paths disagree by 10×, and the modernExtend value is the outlier.
Durability
Anything that makes Z2M re-run configure reverts all of it: re-pairing, an explicit bridge/request/device/configure, or a converter update that changes the definition. The document says so and carries the restore commands.
Those commands are written out literally, one per attribute, rather than generated by a shell helper — the nested quoting through kubectl exec -- sh -c is exactly where this goes wrong. Each was executed and verified in the form given, including the POD extraction and the read-back, and re-applying is a genuine no-op.
The lasting fix is upstream: the WS90 definition should pass explicit reporting overrides instead of inheriting indoor-sensor defaults. Noted at the end of the document.
Documents the non-default ZCL reporting configuration now on the Wetterstation, and how to restore it. **No behaviour change from this PR** — the device was reconfigured at runtime; this records it.
Adds `zigbee2mqtt-ws90-reporting.md` plus a pointer from the device stanza in `zigbee2mqtt-config.yaml`.
## Why it needs a document rather than a manifest
Zigbee2MQTT has no settings-schema field for reporting configuration. It is applied over MQTT (`bridge/request/device/configure_reporting`) and stored on the device and in `database.db`. Flux cannot reconcile it, and a fresh PVC will not have it.
## What changed on the device
| attribute | cluster | min | change | was |
|---|---|---|---|---|
| temperature | 1026 | 5 | 10 → 0.1 °C | 10 / 100 (1 °C) |
| humidity | 1029 | 5 | 50 → 0.5 % | 10 / 100 (1 %) |
| pressure | 1027 | 5 | 1 → 1 hPa | 10 / 50 (50 hPa) |
| illuminance | 1024 | 5 | 5 | 10 / 5 |
| wind ×3 | 0xfc01 | 5 | 1 | 10 / 1 |
| UV | 0xfc02 | 5 | 1 | 10 / 1 |
| rain ×2 | 0xfc03 | 5 | 1 | 10 / 1 |
Battery (cluster 1) left at its hourly default.
## The interval
`min` is a hold-off, and it was 10 s against an 8.8 s transmit interval — so every change-triggered report was held past a cycle and landed on the next. Attributes reported at best every 17.6 s and drifted out of phase with each other; the published stream showed **no 8.8 s periodicity at all**, just a smear across 2–8 s.
At `min: 5` each attribute reports on its own transmit:
```
17:06:07 17:06:15 17:06:24 17:06:33 17:06:42 17:06:50 17:06:59 17:07:08 ...
8s 9s 9s 9s 8s 9s 9s
```
Mean gap **8.69 s** — the transmit cycle, visible in MQTT for the first time. Publish volume *fell*, ~631/h → ~445/h, because each publish is now a whole cycle rather than a fragment of one.
## The deadbands
These come from the shared `modernExtend` helpers, which the WS90 definition in `shelly.ts` composes without overrides — anti-chatter values sized for battery-powered indoor sensors, where report volume costs coin-cell life and mesh airtime.
- **temperature** was 1.00 °C: a staircase moving ~twice an hour. Now 0.1 °C, matching the resolution the device reports.
- **pressure** was `change: 50` with `scale: 10` — a **5 kPa (50 hPa)** deadband, which real barometric pressure never traverses. Pressure only ever updated on the hourly `max` heartbeat, and `pressure_trend` / `weather_condition` derive from it. Worth noting the same library configures the *identical* ZCL attribute with `change: 5` (5 hPa) in its older `reporting.ts` helper — the two code paths disagree by 10×, and the modernExtend value is the outlier.
## Durability
Anything that makes Z2M re-run `configure` reverts all of it: re-pairing, an explicit `bridge/request/device/configure`, or a converter update that changes the definition. The document says so and carries the restore commands.
Those commands are written out literally, one per attribute, rather than generated by a shell helper — the nested quoting through `kubectl exec -- sh -c` is exactly where this goes wrong. Each was executed and verified in the form given, including the `POD` extraction and the read-back, and re-applying is a genuine no-op.
The lasting fix is upstream: the WS90 definition should pass explicit `reporting` overrides instead of inheriting indoor-sensor defaults. Noted at the end of the document.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The Wetterstation now carries a non-default reporting configuration: min
interval 5s on all ten reportable attributes, and tighter reportable-change
deadbands on temperature, humidity and pressure. None of it is expressible
in configuration.yaml - Zigbee2MQTT has no settings-schema field for
reporting configuration - so it lives only on the device and in Z2M's
database.db. This documents it and how to restore it.
min was 10s against an 8.8s transmit interval. Since min is a hold-off, every
change-triggered report was held past a transmit cycle and landed on the
next, so attributes reported at best every 17.6s and drifted out of phase.
The published stream showed no 8.8s periodicity at all. At min 5 each
attribute reports on its own transmit and the stream carries one publish per
cycle, measured at a mean gap of 8.69s. Publish volume fell from ~631/h to
~445/h because each publish is now a whole cycle rather than a fragment.
The deadbands come from the shared modernExtend helpers, which the WS90
definition composes without overrides. They are anti-chatter values sized for
battery-powered indoor sensors. Temperature was 1.00 C, giving a staircase
that moved about twice an hour; it is now 0.1 C, matching the resolution the
device actually reports. Pressure was 5 kPa - 50 hPa, which real barometric
pressure never traverses, so it only ever updated on the hourly heartbeat
that pressure_trend and weather_condition derive from. Note the same library
configures the identical ZCL attribute with a 5 hPa deadband in its older
reporting.ts helper, so the two code paths disagree by 10x.
Anything that makes Z2M re-run configure on the device reverts all of it, and
a fresh PVC will not have it. The restore commands are written out literally
rather than generated by a shell helper, because the nested quoting through
`kubectl exec -- sh -c` is where this goes wrong; each was executed and
verified as written, including the read-back, and re-applying is a no-op.
No behaviour change from this commit itself - the device was reconfigured at
runtime, this only records it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
🤖Automated review — model claude-haiku-4-5-20251001 (complexity: trivial), commit c0791e2747d17f3f2285becd0b9e4e88ada62a00.
Advisory review by the review-bot pipeline. It never approves; a human merges. Push new commits to get a fresh review.
Summary
This PR documents the ZCL reporting configuration applied to the Ecowitt WS90 weather station, which lives on the device and in Z2M's database.db rather than in version control. It adds a comprehensive guide with restore commands, verification steps, and context on why the configuration differs from library defaults. The changes are documentation only; no behavioral changes to the system.
🟡 Suggestions
Documentation clarity on $BASE_TOPIC variable (line 122): The restore commands reference $BASE_TOPIC in the mosquitto_pub -t flag, but there's no explicit setup shown. While the author states these commands were executed and verified, adding one line like BASE_TOPIC=zigbee2mqtt or noting that it's set by the sidecar would make the commands copy-paste ready for future operators unfamiliar with the discovery-guard environment.
Verification command database format (line 156): The verification command pipes grep output through jq, which assumes database.db is JSON-formatted. A brief note that Z2M's database.db is JSONL or similar would help future readers understand the format and troubleshoot if the format changes.
🟢 Nits
Minor: Comment style consistency (zigbee2mqtt-config.yaml, lines 182–187): The added comment uses — (em-dash) while surrounding comments don't consistently use it. This is very minor; the style matches the rest of the codebase's doc comments fine.
Tests
This is documentation. The author has verified the restore commands by executing them against the device and confirmed idempotency. The verification section provides a concrete way to validate restored state. No automated tests needed for documentation.
Recommendation
Looks reasonable — no blocking issues; suggestions above are optional polish to reduce friction for future operators restoring this configuration.
🤖 **Automated review** — model `claude-haiku-4-5-20251001` (complexity: trivial), commit `c0791e2747d17f3f2285becd0b9e4e88ada62a00`.
> Advisory review by the `review-bot` pipeline. It never approves; a human merges. Push new commits to get a fresh review.
---
## Summary
This PR documents the ZCL reporting configuration applied to the Ecowitt WS90 weather station, which lives on the device and in Z2M's database.db rather than in version control. It adds a comprehensive guide with restore commands, verification steps, and context on why the configuration differs from library defaults. The changes are documentation only; no behavioral changes to the system.
## 🟡 Suggestions
**Documentation clarity on `$BASE_TOPIC` variable** (line 122): The restore commands reference `$BASE_TOPIC` in the mosquitto_pub `-t` flag, but there's no explicit setup shown. While the author states these commands were executed and verified, adding one line like `BASE_TOPIC=zigbee2mqtt` or noting that it's set by the sidecar would make the commands copy-paste ready for future operators unfamiliar with the `discovery-guard` environment.
**Verification command database format** (line 156): The verification command pipes `grep` output through `jq`, which assumes `database.db` is JSON-formatted. A brief note that Z2M's database.db is JSONL or similar would help future readers understand the format and troubleshoot if the format changes.
## 🟢 Nits
**Minor: Comment style consistency** (zigbee2mqtt-config.yaml, lines 182–187): The added comment uses `—` (em-dash) while surrounding comments don't consistently use it. This is very minor; the style matches the rest of the codebase's doc comments fine.
## Tests
This is documentation. The author has verified the restore commands by executing them against the device and confirmed idempotency. The verification section provides a concrete way to validate restored state. No automated tests needed for documentation.
## Recommendation
Looks reasonable — no blocking issues; suggestions above are optional polish to reduce friction for future operators restoring this configuration.
<!-- pr-review:sha=c0791e2747d17f3f2285becd0b9e4e88ada62a00 -->
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Documents the non-default ZCL reporting configuration now on the Wetterstation, and how to restore it. No behaviour change from this PR — the device was reconfigured at runtime; this records it.
Adds
zigbee2mqtt-ws90-reporting.mdplus a pointer from the device stanza inzigbee2mqtt-config.yaml.Why it needs a document rather than a manifest
Zigbee2MQTT has no settings-schema field for reporting configuration. It is applied over MQTT (
bridge/request/device/configure_reporting) and stored on the device and indatabase.db. Flux cannot reconcile it, and a fresh PVC will not have it.What changed on the device
Battery (cluster 1) left at its hourly default.
The interval
minis a hold-off, and it was 10 s against an 8.8 s transmit interval — so every change-triggered report was held past a cycle and landed on the next. Attributes reported at best every 17.6 s and drifted out of phase with each other; the published stream showed no 8.8 s periodicity at all, just a smear across 2–8 s.At
min: 5each attribute reports on its own transmit:Mean gap 8.69 s — the transmit cycle, visible in MQTT for the first time. Publish volume fell, ~631/h → ~445/h, because each publish is now a whole cycle rather than a fragment of one.
The deadbands
These come from the shared
modernExtendhelpers, which the WS90 definition inshelly.tscomposes without overrides — anti-chatter values sized for battery-powered indoor sensors, where report volume costs coin-cell life and mesh airtime.change: 50withscale: 10— a 5 kPa (50 hPa) deadband, which real barometric pressure never traverses. Pressure only ever updated on the hourlymaxheartbeat, andpressure_trend/weather_conditionderive from it. Worth noting the same library configures the identical ZCL attribute withchange: 5(5 hPa) in its olderreporting.tshelper — the two code paths disagree by 10×, and the modernExtend value is the outlier.Durability
Anything that makes Z2M re-run
configurereverts all of it: re-pairing, an explicitbridge/request/device/configure, or a converter update that changes the definition. The document says so and carries the restore commands.Those commands are written out literally, one per attribute, rather than generated by a shell helper — the nested quoting through
kubectl exec -- sh -cis exactly where this goes wrong. Each was executed and verified in the form given, including thePODextraction and the read-back, and re-applying is a genuine no-op.The lasting fix is upstream: the WS90 definition should pass explicit
reportingoverrides instead of inheriting indoor-sensor defaults. Noted at the end of the document.🤖 Generated with Claude Code
🤖 Automated review — model
claude-haiku-4-5-20251001(complexity: trivial), commitc0791e2747d17f3f2285becd0b9e4e88ada62a00.Summary
This PR documents the ZCL reporting configuration applied to the Ecowitt WS90 weather station, which lives on the device and in Z2M's database.db rather than in version control. It adds a comprehensive guide with restore commands, verification steps, and context on why the configuration differs from library defaults. The changes are documentation only; no behavioral changes to the system.
🟡 Suggestions
Documentation clarity on
$BASE_TOPICvariable (line 122): The restore commands reference$BASE_TOPICin the mosquitto_pub-tflag, but there's no explicit setup shown. While the author states these commands were executed and verified, adding one line likeBASE_TOPIC=zigbee2mqttor noting that it's set by the sidecar would make the commands copy-paste ready for future operators unfamiliar with thediscovery-guardenvironment.Verification command database format (line 156): The verification command pipes
grepoutput throughjq, which assumesdatabase.dbis JSON-formatted. A brief note that Z2M's database.db is JSONL or similar would help future readers understand the format and troubleshoot if the format changes.🟢 Nits
Minor: Comment style consistency (zigbee2mqtt-config.yaml, lines 182–187): The added comment uses
—(em-dash) while surrounding comments don't consistently use it. This is very minor; the style matches the rest of the codebase's doc comments fine.Tests
This is documentation. The author has verified the restore commands by executing them against the device and confirmed idempotency. The verification section provides a concrete way to validate restored state. No automated tests needed for documentation.
Recommendation
Looks reasonable — no blocking issues; suggestions above are optional polish to reduce friction for future operators restoring this configuration.