fix(telemetry): unify serial ingest onto shared digit-aware normalizer (#3506)#3514
Conversation
#3506) The serial telemetry path (processTelemetryMessageProtobuf) read each device/environment/airQuality/power metric by a hand-maintained camelCase property name, with per-field `?? particles_NNum` / `?? rainfall_Nh` fallbacks bolted on to survive the protobuf.js underscore-before-digit quirk (#3483). Any new underscore-before-digit field added upstream would silently drop again until someone remembered to add another fallback. Replace the four static metric lists with buildCanonicalMetrics(group, decoded), which iterates the fields the decoder actually produced and resolves each leaf through the shared canonicalTelemetryType/canonicalTelemetryUnit map (the same digit-aware snakeToCamel the MQTT path uses). New `_<digit>` fields are now picked up automatically once their unit lands in CANONICAL_TELEMETRY_UNITS — no per-field fallback to maintain. Verified against the real decoder shape: Object.entries yields only wire-present own fields (unset scalars are null and excluded), genuine 0 readings are own properties and preserved, and protobuf.js repeated fields (own `[]`) plus untracked leaves are skipped via the typeof-number + known-unit guards. Behavior-preserving for the current protobuf; adds coverage for the env leaf renames, device/power channels, genuine-0, and the repeated/unknown-field skips. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @Yeraze's task —— View job PR Review: fix(telemetry): unify serial ingest onto shared digit-aware normalizerTasks:
Overall AssessmentThis is a well-executed, focused refactor. The motivation is clear — protobuf.js's underscore-before-digit quirk silently dropped fields, and the fix eliminates the category of bug rather than patching individual fields. The code is clean, the reduction of 117 lines is meaningful, and the existing test suite protects against regressions. Code Quality
Consistency gap — Type mismatch — minor:
Potential Issues
Missing validation of Test CoverageThe new
Gaps worth considering:
Minor Nits
SummaryApprove with minor notes. The core change is correct and well-tested. The inconsistency between the four converted metric groups and the three hand-maintained |
- Add a test pinning the Number.isFinite guard (NaN/Infinity excluded, finite values still stored). - Comment the deviceMetrics nodeData copies vs telemetry-history rows so the apparent duplication reads clearly. Follow-up for the unconverted localStats/host/trafficManagement branches tracked in #3515. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @Yeraze's task —— View job PR Review: fix(telemetry): unify serial ingest onto shared digit-aware normalizerTasks:
Overall AssessmentThis is a well-targeted refactor that eliminates a whole class of silent data-loss bugs. The What was addressed since the initial reviewNaN/Infinity test added ✅ — Dual-path comment added ✅ — Remaining observations
Type signature asymmetry (minor):
Test coverage assessmentThe two test files together give strong coverage:
One remaining gap: No test covers SummaryApprove. All blocking concerns from the initial review have been addressed. The remaining items (three unconverted branches, MQTT migration list drift, |
Summary
Closes #3506. Durable fix for the protobuf.js underscore-before-digit recurrence class (#3483).
The serial telemetry path (
processTelemetryMessageProtobuf) read each device/environment/airQuality/power metric by a hand-maintained camelCase property name, carrying per-field?? particles_NNum/?? rainfall_Nhfallbacks to survive the protobuf.js quirk whereparticles_03um/rainfall_1hstay snake_case on the decoded message. Any new underscore-before-digit field upstream would silently drop again until someone added another fallback.What changed
buildCanonicalMetrics(group, decoded)helper iterates the fields the decoder actually produced and resolves each leaf through the sharedcanonicalTelemetryType/canonicalTelemetryUnitmap — the same digit-awaresnakeToCamelthe MQTT path already uses._<digit>fields are picked up automatically once their unit lands inCANONICAL_TELEMETRY_UNITS(this is what Coverage: wire up newer AirQualityMetrics fields (particles_40um and adjacent) #3507 will extend), with no per-field fallback to maintain.nodeData+localChannelUtilizationside-effects; only its telemetry inserts route through the helper.Verification
Confirmed empirically against the real decoder shape (
Telemetry.decode, a protobuf.js message instance):Object.entriesyields only wire-present own fields — unset scalars read asnulland are excluded (no spurious 0s).0readings are own properties → preserved.oneWireTemperature→ own[]) and untracked leaves are skipped viatypeof === 'number'+ known-unit guards.Behavior-preserving for the current protobuf. Existing #3483 regression test (
meshtasticManager.airQualityParticles.test.ts) still passes; newmeshtasticManager.telemetryCanonical.test.tscovers env leaf renames, device/power channels, genuine-0, and the repeated/unknown-field skips.Full suite: 6569 passed, 0 failed.
🤖 Generated with Claude Code