fix: prevent NodeInfo from overwriting high-precision positions (#3513)#3516
Conversation
…lower-precision ones (#3513) Meshtastic firmware applies the channel's positionPrecision setting to positions embedded in NodeInfo broadcasts, grid-snapping coordinates to reduced precision. MeshMonitor was unconditionally overwriting the stored lat/lon from every NodeInfo arrival, causing accurate stored positions to degrade silently over time. Add a precision downgrade guard in the NodeInfo handler: lat/lon is only updated when both sides carry explicit non-zero precisionBits AND the incoming is clearly lower, we skip the position update. The telemetry history row is still written so the position history log remains complete. Also fix the estimated_positions PostgreSQL schema to use DOUBLE PRECISION (64-bit) instead of REAL (32-bit / ~7 significant digits), which caused visible coordinate rounding for estimated-position nodes. Migration 091 alters the three numeric columns; SQLite and MySQL are no-ops. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jNq9fvemyLZVB1fqv3YGb
|
Claude finished @Yeraze's task —— View job PR Review
Overall: This is a well-targeted fix with clear logic and good comments. The change is minimal, focused, and correctly handles the precision downgrade guard. A few issues worth addressing before merge. Potential Bug: Altitude silently dropped on downgrade
When if (shouldUpdateLatLon) {
nodeData.latitude = coords.latitude;
nodeData.longitude = coords.longitude;
nodeData.altitude = nodeInfo.position.altitude; // altitude silently dropped if skipping
}Consider updating altitude separately when it's present, or renaming the flag to Potential Behavior Issue:
|
- Move positionPrecisionBits write inside shouldUpdateLatLon block to prevent the one-shot guard defect (stored precision would decrease even when lat/lon was blocked, letting the next packet bypass the guard) - Add independent altitude update in the else-branch — altitude is not grid-snapped by firmware positionPrecision, so it should update even when lat/lon is blocked - Replace fragile try/catch string-match in migration 091 with an information_schema.columns pre-check for idempotent ALTER - Add 11 behavioral tests for the precision guard logic covering all guard conditions and the one-shot/altitude regression cases Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jNq9fvemyLZVB1fqv3YGb
|
Claude finished @Yeraze's task —— View job PR Review
Overall: This is a well-targeted, minimal fix that correctly addresses the NodeInfo precision downgrade bug (#3513) and the PostgreSQL What's Fixed vs. the Earlier Review CommentsThe previous review raised four issues. All four have been addressed in the current code:
Remaining ObservationsTest structure: guard logic duplicated between test and production code
The This is a minor concern, not a blocker.
|
?? already falls through to undefined; the trailing ?? undefined was cosmetically redundant (noted in automated review). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jNq9fvemyLZVB1fqv3YGb
|
Claude finished @Yeraze's task —— View job PR Review
Overall: This is a clean, well-targeted fix. All issues from prior reviews have been addressed. The code is correct and ready to merge. Core Guard Logic (
|
Release candidate for 4.11.0. Bumps the version across all five tracked locations (package.json, package-lock.json, helm Chart.yaml version+appVersion, desktop/package.json, desktop/src-tauri/tauri.conf.json). 4.11.0 carries the multi-source route-extraction refactors, the telemetry ingestion unification (#3506/#3507/#3515), the auto-ping ack/race fix (#3522), NodeInfo position-precision guard (#3516), backup-route hardening (#3524), and the Node Details telemetry range selector (#3530). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
When a
NODEINFO_APPpacket arrives over a direct TCP connection, MeshMonitor was unconditionally overwriting the storedlatitude/longitudewith whatever position was embedded — even when that position had lower precision than what was already stored. Meshtastic firmware applies the channel'spositionPrecisionsetting to positions embedded in NodeInfo broadcasts, grid-snapping coordinates before broadcast. Every periodic NodeInfo from a node with reduced positionPrecision silently degraded the stored coordinates. The MQTT position monitor referenced in the issue only captures standalonePOSITION_APPpackets (not embedded NodeInfo positions), which is why it showed accurate coordinates while MeshMonitor showed rounded ones.A secondary issue: the
estimated_positionstable in PostgreSQL usedREALcolumns (32-bit, ~7 significant digits) instead ofDOUBLE PRECISION(64-bit), causing visible coordinate rounding for estimated-position nodes — inconsistent with thenodestable which already usesDOUBLE PRECISION.Changes
src/server/meshtasticManager.ts: Add a precision downgrade guard in the NodeInfo position handler. Before writinglatitude/longitude, compare incomingprecisionBitsagainst the storedpositionPrecisionBits. Skip the lat/lon update only when both sides carry explicit non-zero precision info AND the incoming is clearly lower. Position telemetry history rows are still written unconditionally (full historical record preserved).src/db/schema/estimatedPositions.ts: Change PostgreSQLlatitude,longitude, anduncertaintyKmcolumns frompgRealtopgDoublePrecision.src/server/migrations/091_estimated_positions_double_precision.ts: Migration 091 — ALTERs the three columns on PostgreSQL deployments; no-op for SQLite (REAL is already 64-bit) and MySQL (already DOUBLE).src/db/migrations.ts/src/db/migrations.test.ts: Register migration 091, update count/name assertions.Issues Resolved
Fixes #3513
Documentation Updates
No documentation changes needed — this is an internal bug fix with no user-facing behavior changes beyond correcting the displayed positions.
Testing
npx tsc --noEmit)positionPrecisionto a low value (e.g. 14 bits) on a Meshtastic device and confirm MeshMonitor no longer replaces the stored accurate coordinates after the next NodeInfo broadcast🤖 Generated with Claude Code
Generated by Claude Code