From 0f565867a7b5cf12e4161a8dce1037d0e1914df7 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 6 Jul 2026 16:38:53 +0000 Subject: [PATCH] Extend mesh node staleness window from 10 min to 72 h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A mesh node's last_seen is its last advert timestamp, and MeshCore nodes typically advert only once every 24-48 h. The map layer flagged any node whose last advert was older than 10 minutes as STALE / OFFLINE, so nearly every node — including active repeaters like the primary that feeds the observer — rendered grey with a STALE / OFFLINE tooltip despite being live. Replace the hardcoded 10-minute threshold with a configurable window (MESH_NODE_STALE_MS, default 72 h, override via VITE_MESH_NODE_STALE_HOURS) so a node is only marked stale after missing roughly two advert cycles. Both the grey icon color and the tooltip label read the same picked object, so both update from this single source. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01DUSVEY4GGnyyt6PfXMKtR3 --- .env.example | 3 +++ frontend/src/config.ts | 8 ++++++++ frontend/src/layers/buildMeshNodeLayer.ts | 5 ++--- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.env.example b/.env.example index 1f411a0..36ce4c1 100644 --- a/.env.example +++ b/.env.example @@ -184,6 +184,9 @@ VITE_RADAR_FALLBACK_LAYER=radar VITE_RADAR_FALLBACK_MAX_ZOOM=6 # Trail history radius shown on the map (km) VITE_OBSERVATION_RANGE_KM=50 +# Hours since a mesh node's last advert before it is shown as STALE / OFFLINE on the map. +# MeshCore nodes advert only every 24–48 h, so keep this above one advert cycle. +VITE_MESH_NODE_STALE_HOURS=72 # Keep false for normal operation. True enables cleaner map snapshots but costs render performance. VITE_PRESERVE_DRAWING_BUFFER=false diff --git a/frontend/src/config.ts b/frontend/src/config.ts index 02d2617..b874ff3 100644 --- a/frontend/src/config.ts +++ b/frontend/src/config.ts @@ -55,3 +55,11 @@ export const RADAR_FALLBACK_LAYER = import.meta.env.VITE_RADAR_FALLBACK_LAYER || // Observation range ring — radius in km centered on DEFAULT_CENTER. // Set VITE_OBSERVATION_RANGE_KM=0 to hide the ring. export const OBSERVATION_RANGE_KM = Number(import.meta.env.VITE_OBSERVATION_RANGE_KM ?? 50) + +// Mesh node staleness window. A mesh node's last_seen is its last advert +// timestamp, and MeshCore nodes typically advert only once every 24–48 h, so a +// short window marks healthy-but-quiet nodes (including active repeaters) as +// stale. Default 72 h flags a node only after it has missed roughly two advert +// cycles. Override with VITE_MESH_NODE_STALE_HOURS. +export const MESH_NODE_STALE_MS = + Number(import.meta.env.VITE_MESH_NODE_STALE_HOURS ?? 72) * 60 * 60 * 1000 diff --git a/frontend/src/layers/buildMeshNodeLayer.ts b/frontend/src/layers/buildMeshNodeLayer.ts index 6ebd971..bd3f042 100644 --- a/frontend/src/layers/buildMeshNodeLayer.ts +++ b/frontend/src/layers/buildMeshNodeLayer.ts @@ -1,6 +1,7 @@ import { IconLayer } from '@deck.gl/layers' import type { Entity } from '../store' import { getAtlasIcons } from './atlasIcons' +import { MESH_NODE_STALE_MS } from '../config' export interface MeshNodePoint { entity_id: string @@ -11,8 +12,6 @@ export interface MeshNodePoint { status: string } -const STALE_MS = 10 * 60 * 1000 - // Atlas hue: --cat-mesh #FF8F00 const MESH_ACTIVE: [number, number, number, number] = [255, 143, 0, 240] const MESH_STALE: [number, number, number, number] = [136, 136, 136, 200] @@ -20,7 +19,7 @@ const MESH_STALE: [number, number, number, number] = [136, 136, 136, 200] function toMeshNodePoint(e: Entity, nowMs: number): MeshNodePoint | null { if (e.entity_type !== 'mesh_node' || e.lat == null || e.lon == null) return null const lastMs = e.last_seen ? Date.parse(e.last_seen) : 0 - const stale = !lastMs || (nowMs - lastMs > STALE_MS) + const stale = !lastMs || (nowMs - lastMs > MESH_NODE_STALE_MS) return { entity_id: e.entity_id, name: e.display_name ?? e.entity_id,