diff --git a/meshview/mqtt_store.py b/meshview/mqtt_store.py index 949ec8c..4271f2d 100644 --- a/meshview/mqtt_store.py +++ b/meshview/mqtt_store.py @@ -82,12 +82,9 @@ async def process_envelope(topic, env): async with mqtt_database.async_session() as session: # --- Packet insert with ON CONFLICT DO NOTHING result = await session.execute(select(Packet).where(Packet.id == env.packet.id)) - # FIXME: Not Used - # new_packet = False packet = result.scalar_one_or_none() if not packet: - # FIXME: Not Used - # new_packet = True + now = datetime.datetime.now(datetime.UTC) now_us = int(now.timestamp() * 1_000_000) stmt = ( @@ -238,6 +235,3 @@ async def process_envelope(topic, env): await session.commit() - # if new_packet: - # await packet.awaitable_attrs.to_node - # await packet.awaitable_attrs.from_node diff --git a/meshview/templates/node.html b/meshview/templates/node.html index 0483059..f91604e 100644 --- a/meshview/templates/node.html +++ b/meshview/templates/node.html @@ -777,21 +777,6 @@ async function loadPackets(filters = {}) { for (const pkt of packets.reverse()) { - // ================================ - // 🔵 NEIGHBOR PACKETS → MAP OVERLAY - // ================================ - if (pkt.portnum === 71 && pkt.payload && map) { - const nids = []; - const re = /neighbors\s*\{\s*node_id:\s*(\d+)/g; - let m; - while ((m = re.exec(pkt.payload)) !== null) { - nids.push(parseInt(m[1], 10)); - } - if (nids.length) { - await drawNeighbors(pkt.from_node_id, nids); - } - } - // ================================ // TABLE ROW // ================================ @@ -1009,6 +994,32 @@ async function loadTelemetryCharts(){ }); } + +async function loadLatestNeighborIds() { + const url = new URL("/api/packets", window.location.origin); + url.searchParams.set("from_node_id", fromNodeId); + url.searchParams.set("portnum", 71); + url.searchParams.set("limit", 1); // ✅ ONLY the latest packet + + const res = await fetch(url); + if (!res.ok) return []; + + const data = await res.json(); + const pkt = data.packets?.[0]; + if (!pkt || !pkt.payload) return []; + + const ids = []; + const re = /neighbors\s*\{([^}]+)\}/g; + let m; + + while ((m = re.exec(pkt.payload)) !== null) { + const id = m[1].match(/node_id:\s*(\d+)/); + if (id) ids.push(parseInt(id[1], 10)); + } + + return ids; +} + /* ====================================================== NEIGHBOR CHART (portnum=71) ====================================================== */ @@ -1315,17 +1326,29 @@ document.addEventListener("click", e => { ====================================================== */ document.addEventListener("DOMContentLoaded", async () => { - await loadTranslationsNode(); // translations first + await loadTranslationsNode(); requestAnimationFrame(async () => { - await loadNodeInfo(); // single-node fetch - if (!map) initMap(); // init map early so neighbors can draw + await loadNodeInfo(); + + // ✅ MAP MUST EXIST FIRST + if (!map) initMap(); + + // ✅ DRAW LATEST NEIGHBORS ONCE + const neighborIds = await loadLatestNeighborIds(); + if (neighborIds.length) { + await drawNeighbors(fromNodeId, neighborIds); + } + + // ⚠️ Track may add to map, but must not hide it await loadTrack(); + await loadPackets(); initPacketPortFilter(); await loadTelemetryCharts(); await loadNeighborTimeSeries(); await loadPacketHistogram(); + ensureMapVisible(); setTimeout(ensureMapVisible, 1000); window.addEventListener("resize", ensureMapVisible); @@ -1334,6 +1357,7 @@ document.addEventListener("DOMContentLoaded", async () => { }); + function packetSizeBytes(pkt) { if (!pkt) return 0;