docs(zigbee2mqtt): the WS90 merge does not make the glitch detectable #561

Merged
k.renner merged 1 commits from fix-ws90-merge-overclaim into master 2026-08-24 17:07:35 +00:00
Member

Comment-only follow-up to #560, which is already merged. No behaviour change — the debounce value and device stanza are untouched.

The wrong claim

#560's comment says a merged episode "surfaces as a single all-zero frame". That decides whether a downstream filter is possible at all, and it is not true.

The zeros propagate attribute by attribute through the burst, so the merged frame carries whatever subset had zeroed when that burst ended. Three episodes captured at nanosecond resolution all happened to complete the propagation, which is where the generalisation came from — but nothing guarantees it. A burst ending mid-propagation publishes temperature at zero while humidity and pressure still read normally. That frame is physically self-consistent (Z2M recomputes dew_point from the false temperature) and cannot be told apart from a genuine winter reading.

It is also not separable by timing

The zeros begin inside an otherwise normal transmit cycle. Measured gap between the last valid reading and the first zero, same burst:

episode last good first zero delta
2026-08-22 04.671277 04.698965 27.7 ms
2026-08-13 34.985417 35.005194 19.8 ms
2026-08-12 16.655758 16.677800 22.0 ms

They occupy a regular reporting slot. No window can exclude them without also excluding a normal cycle.

What debounce actually buys

Because the merge is last-wins and the zeros arrive at the tail of the burst, it resolves that burst to the zeros and discards the valid reading that led it.

bad samples per episode good sample at burst head
before ~6 kept
after 1 lost

A worthwhile reduction — ~6 episodes/month — but a bound on the corruption, not a filter. The comment now states that limitation instead of implying the opposite.

Consequence

Neither a timing rule nor a content rule is sound, so this cannot be filtered anywhere downstream of the device. It is a firmware defect (currently 251015/v1.1.6@62, the newest published on the Shelly branch) and only Shelly/Ecowitt can fix it. Koenkk/zigbee2mqtt#31048 tracks it upstream but is a converter project and cannot.

🤖 Generated with Claude Code

Comment-only follow-up to #560, which is already merged. No behaviour change — the debounce value and device stanza are untouched. ## The wrong claim #560's comment says a merged episode *"surfaces as a single all-zero frame"*. That decides whether a downstream filter is possible at all, and it is not true. The zeros propagate **attribute by attribute** through the burst, so the merged frame carries whatever subset had zeroed when that burst ended. Three episodes captured at nanosecond resolution all happened to complete the propagation, which is where the generalisation came from — but nothing guarantees it. A burst ending mid-propagation publishes temperature at zero while humidity and pressure still read normally. That frame is physically self-consistent (Z2M recomputes `dew_point` from the false temperature) and cannot be told apart from a genuine winter reading. ## It is also not separable by timing The zeros begin **inside an otherwise normal transmit cycle**. Measured gap between the last valid reading and the first zero, same burst: | episode | last good | first zero | delta | |---|---|---|---| | 2026-08-22 | 04.671277 | 04.698965 | 27.7 ms | | 2026-08-13 | 34.985417 | 35.005194 | 19.8 ms | | 2026-08-12 | 16.655758 | 16.677800 | 22.0 ms | They occupy a regular reporting slot. No window can exclude them without also excluding a normal cycle. ## What debounce actually buys Because the merge is last-wins and the zeros arrive at the *tail* of the burst, it resolves that burst **to the zeros** and discards the valid reading that led it. | | bad samples per episode | good sample at burst head | |---|---|---| | before | ~6 | kept | | after | 1 | lost | A worthwhile reduction — ~6 episodes/month — but a bound on the corruption, not a filter. The comment now states that limitation instead of implying the opposite. ## Consequence Neither a timing rule nor a content rule is sound, so this cannot be filtered anywhere downstream of the device. It is a firmware defect (currently `251015/v1.1.6@62`, the newest published on the Shelly branch) and only Shelly/Ecowitt can fix it. Koenkk/zigbee2mqtt#31048 tracks it upstream but is a converter project and cannot. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
claude-bot added 1 commit 2026-08-24 04:41:36 +00:00
docs(zigbee2mqtt): the WS90 merge does not make the glitch detectable
ci/woodpecker/pr/ci-manifests-test Pipeline was successful
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
ci/woodpecker/pr/pr-review Pipeline was successful
06ffc3c910
#560 claimed a merged episode "surfaces as a single all-zero frame". It
does not, and the difference decides whether a downstream filter is even
possible.

The zeros propagate attribute by attribute through the burst, so the
merged frame carries whatever subset had zeroed when that burst ended.
Across three episodes captured at nanosecond resolution the propagation
happened to complete, which is where the wrong generalisation came from.
Nothing guarantees it. A burst ending mid-propagation publishes a frame
with temperature at zero while humidity and pressure still read normally,
which is a physically consistent measurement - Z2M recomputes dew_point
from the false temperature - and is not separable from a genuine winter
reading.

The zeros also begin inside an otherwise normal transmit cycle, roughly
20ms after a valid reading in the same burst (measured: 27.7ms, 19.8ms,
22.0ms). They occupy a regular reporting slot, so no timing property
distinguishes them either.

Since the merge is last-wins and the zeros arrive at the tail of the
burst, it resolves that burst to the zeros and discards the valid reading
that led it. So debounce trades six bad samples per episode for one, at
the cost of one good sample. That is a bound on the corruption, not a
filter, and the comment now says so.

No behaviour change; the debounce value and device stanza are untouched.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
review-bot left a comment
Member

🤖 Automated review — model claude-haiku-4-5-20251001 (complexity: trivial), commit 06ffc3c910a14fa06141f4ea23f17e284be95895.

Advisory review by the review-bot pipeline. It never approves; a human merges. Push new commits to get a fresh review.


Summary

This PR corrects a factually inaccurate comment in the zigbee2mqtt config file about WS90 firmware behavior. The previous PR #560 claimed the glitch "surfaces as a single all-zero frame", but this PR provides a more accurate explanation: zeros propagate attribute-by-attribute, not atomically, and the resulting merged frame is indistinguishable from a valid reading. No code changes—purely documentation.

🟢 Nits

The documentation improvement is thorough and technically sound. The new comment accurately explains:

  • Why the old claim was wrong (attribute-by-attribute propagation with measured ~20ms gaps)
  • What debounce actually accomplishes (reduction from ~6 bad frames to 1, not filtering)
  • Why downstream filtering is impossible (indistinguishable from valid data)

Well-justified technical correction with clear motivation in the PR body.

Tests

Not applicable—this is documentation only.

Recommendation

Looks reasonable — no blocking issues; this is a solid technical correction.

🤖 **Automated review** — model `claude-haiku-4-5-20251001` (complexity: trivial), commit `06ffc3c910a14fa06141f4ea23f17e284be95895`. > Advisory review by the `review-bot` pipeline. It never approves; a human merges. Push new commits to get a fresh review. --- ## Summary This PR corrects a factually inaccurate comment in the zigbee2mqtt config file about WS90 firmware behavior. The previous PR #560 claimed the glitch "surfaces as a single all-zero frame", but this PR provides a more accurate explanation: zeros propagate attribute-by-attribute, not atomically, and the resulting merged frame is indistinguishable from a valid reading. No code changes—purely documentation. ## 🟢 Nits The documentation improvement is thorough and technically sound. The new comment accurately explains: - Why the old claim was wrong (attribute-by-attribute propagation with measured ~20ms gaps) - What debounce actually accomplishes (reduction from ~6 bad frames to 1, not filtering) - Why downstream filtering is impossible (indistinguishable from valid data) Well-justified technical correction with clear motivation in the PR body. ## Tests Not applicable—this is documentation only. ## Recommendation Looks reasonable — no blocking issues; this is a solid technical correction. <!-- pr-review:sha=06ffc3c910a14fa06141f4ea23f17e284be95895 -->
k.renner merged commit 2e00109f66 into master 2026-08-24 17:07:35 +00:00
Sign in to join this conversation.