fix(node): chart local-node air-quality telemetry (orphaning + zero-suppression)#5793
Merged
Conversation
…uppression) Air-quality telemetry (PR #5701) showed in the in-app Debug log but never in the Air Quality chart. Two independent bugs: BUG A — persistence orphaning. A local-node telemetry packet received before MyNodeInfo resolves (myNodeNum still null) was stored in the `log` table under its raw from_num instead of NODE_NUM_LOCAL. Per-node chart queries (getTelemetryFrom -> effectiveLogId) key the local node on NODE_NUM_LOCAL, so those rows were invisible to charts while the unfiltered Debug log still showed them. Fix in MeshMessageProcessorImpl: gate early-packet processing on `isNodeDbReady && myNodeNum != null`; flush the early buffer once both hold (combine emits the value-pair through distinctUntilChanged so it re-fires across reconnect transitions); flushEarlyReceivedPackets null-guards myNodeNum before draining the buffer. BUG B — zero suppression. The chart hid present-and-zero readings (a PM sensor in clean air reports 0 ug/m3). Removed the `takeIf { it != 0 }` guards from AirQuality.getValue, the AirQualityMetricsCard, and the CSV export; a genuinely absent field stays null (Wire decodes an unset optional uint32 to null). Tests: AirQualityChartReproTest (jvmTest, replays the reporter's real packet bytes end-to-end through the insert path), AirQualityMetricsTest (locks the zero/absent semantics), and a strengthened MeshMessageProcessorImplTest (no insert before myNodeNum resolves + a reconnect-toggle regression). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jamesarich
added a commit
that referenced
this pull request
Jun 16, 2026
…uppression) (#5793) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jamesarich
added a commit
that referenced
this pull request
Jun 16, 2026
…uppression) (#5793) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jamesarich
added a commit
that referenced
this pull request
Jun 16, 2026
…uppression) (#5793) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Air-quality telemetry (#5701) shows in the in-app Debug log but never in the Air Quality chart, reported on a
release/2.8.0build with non-zero PM data from a locally-connected node. Two independent bugs.Bug A — persistence orphaning (why nothing charts)
A local-node telemetry packet received before
MyNodeInforesolves (myNodeNumstillnull, e.g. early in a (re)connect) was stored in thelogtable under its rawfrom_numinstead ofNODE_NUM_LOCAL. The per-node chart query (getTelemetryFrom→effectiveLogId) keys the local node onNODE_NUM_LOCALand filtersWHERE from_num = …, so those rows are invisible to the chart — while the Debug screen (getAllLogsUnbounded, nofrom_numfilter) still shows them. Not air-quality-specific; it orphans any local telemetry received in that window (environment survives because it's dense enough to keep charting from post-resolve rows).Fix (
MeshMessageProcessorImpl): gate early-packet processing onisNodeDbReady.value && myNodeNum != null; flush the early buffer once both hold (thecombineemits the value-pair throughdistinctUntilChangedso it re-fires across reconnect transitions);flushEarlyReceivedPacketsnull-guardsmyNodeNumbefore draining the buffer so a mid-flush regression can't drop packets.Bug B — zero suppression (clean-air 0 µg/m³)
The chart hid present-and-zero readings via
?.takeIf { it != 0 }. A PM sensor in clean air legitimately reports0. Removed the guards fromAirQuality.getValue, the card, and the CSV export; a genuinely absent field staysnull(Wire decodes an unset optionaluint32tonull).Tests
AirQualityChartReproTest(jvmTest) — replays the reporter's real packet bytes end-to-end throughMeshMessageProcessorImpland asserts buffer → resolve → charted underNODE_NUM_LOCAL. Fails on pre-fix code.AirQualityMetricsTest— locks the zero/absent semantics ofgetValue(present-zero plots; absent → null → not charted).MeshMessageProcessorImplTest— strengthened: no DBinsertbeforemyNodeNumresolves, plus a reconnect-toggle regression test.Verification
spotlessCheck·detekt·assembleDebug·test·allTests·kmpSmokeCompileall green (160 tests across the two touched modules; 742 in:feature:node).Notes
received_dateat async-flush time — a pre-existing trait offlushEarlyReceivedPackets(the prior code was already async).🤖 Generated with Claude Code