diff --git a/BUGS.md b/BUGS.md index 087aa4f..49a50cd 100644 --- a/BUGS.md +++ b/BUGS.md @@ -40,6 +40,25 @@ When CLOSED, move the entire entry to Resolved — don't duplicate. --- +### BUG-11 — Dashboard GPS shows "Stale fix" while Status shows "Live fix" +- **Status**: `OPEN` +- **Severity**: Low +- **Area**: `static/js/yaris.js`, `static/js/status.js` +- **Phase**: Phase 26 +- **Symptom**: Dashboard shows "Stale fix", lat/lon blank. Status page shows "Live fix" + with valid coordinates. Both pages query the same `/api/gps/status` endpoint. +- **Root cause**: Dashboard `renderGpsStatus()` updates badge + age text but never + populates lat/lon fields — those only receive data from the live `socket.on('gps_location')` + event. Status page reads `gps.latitude`/`gps.longitude` directly from the API response. + Also, the staleness thresholds differ: Dashboard marks stale at >30s, Status page + ignores age entirely. +- **Fix scope**: `renderGpsStatus()` should populate lat/lon from the API response + (already present in `status.latitude`, `status.longitude`). +- **Acceptance**: Dashboard GPS card matches Status page — both show same fix status + and coordinates. + +--- + ## Resolved ### BUG-03 — DTC/MIL codes never persisted diff --git a/static/js/status.js b/static/js/status.js index 6aaa2e9..a3c63d5 100644 --- a/static/js/status.js +++ b/static/js/status.js @@ -215,7 +215,10 @@ function renderHealth(health) { function renderGpsAndCellular(gps, cellularHat) { const liveFix = gps.thread_alive && gps.has_fix; - if (liveFix) { + const staleFix = liveFix && gps.fix_age_seconds != null && gps.fix_age_seconds > 30; + if (staleFix) { + setBadge('gps-badge', 'Stale fix', 'text-bg-warning'); + } else if (liveFix) { setBadge('gps-badge', 'Live fix', 'text-bg-success'); } else if (gps.thread_alive) { setBadge('gps-badge', 'No fix', 'text-bg-warning'); diff --git a/static/js/yaris.js b/static/js/yaris.js index 3dfc6cd..8ef1a52 100644 --- a/static/js/yaris.js +++ b/static/js/yaris.js @@ -221,7 +221,8 @@ function formatGpsAge(seconds) { function renderGpsStatus(status) { const liveBadge = document.getElementById('gps-live-badge'); const fixDetail = document.getElementById('gps-fix-detail'); - if (!liveBadge || !fixDetail) return; + const locX = document.getElementById('gpsLocationX'); + const locY = document.getElementById('gpsLocationY'); let label = 'Unavailable'; let badgeClass = 'text-bg-secondary'; @@ -233,6 +234,9 @@ function renderGpsStatus(status) { label = stale ? 'Stale fix' : 'Live fix'; badgeClass = stale ? 'text-bg-warning' : 'text-bg-success'; detail = formatGpsAge(status.fix_age_seconds); + // Show lat/lon from API response (not just socket events) + if (locX) locX.textContent = status.latitude != null ? status.latitude.toFixed(6) : '—'; + if (locY) locY.textContent = status.longitude != null ? status.longitude.toFixed(6) : '—'; } else { label = 'No fix'; badgeClass = 'text-bg-warning';