From e2adb73feaa871eee6a8bcc71dcc4e1355b7becf Mon Sep 17 00:00:00 2001 From: pablorevilla-meshtastic Date: Thu, 25 Jun 2026 17:19:35 -0700 Subject: [PATCH] map changes and other fixes --- meshview/mqtt_store.py | 30 +++++-- meshview/templates/firehose.html | 15 ++-- meshview/templates/map.html | 148 ++++++++++++++++++++++++++++--- meshview/templates/node.html | 15 +++- meshview/web.py | 6 ++ meshview/web_api/api.py | 4 + 6 files changed, 190 insertions(+), 28 deletions(-) diff --git a/meshview/mqtt_store.py b/meshview/mqtt_store.py index 6bd9bab..68acd8e 100644 --- a/meshview/mqtt_store.py +++ b/meshview/mqtt_store.py @@ -19,6 +19,7 @@ logger = logging.getLogger(__name__) MQTT_GATEWAY_CACHE: set[int] = set() UNKNOWN_NODE_NAME = "unknown name" NODE_NAME_CONTROL_CHARS = re.compile(r"[\x00-\x1f\x7f]") +MQTT_DIRECT_NODE_ID = 1 def normalize_node_name(name: str) -> str: @@ -28,6 +29,24 @@ def normalize_node_name(name: str) -> str: return name +def storage_packet_id(packet) -> int | None: + if packet.id: + return packet.id + + if packet.decoded.portnum != PortNum.MAP_REPORT_APP: + return None + + from_node_id = getattr(packet, "from", 0) or 0 + now_us = int(time.time() * 1_000_000) + return -(now_us * 2048 + (from_node_id & 0x7FF)) + + +def storage_to_node_id(packet) -> int: + if packet.decoded.portnum == PortNum.MAP_REPORT_APP: + return MQTT_DIRECT_NODE_ID + return packet.to + + async def capture_daily_snapshot() -> None: today = datetime.now(UTC).date() @@ -147,20 +166,21 @@ async def process_envelope(topic, env): await session.commit() - if not env.packet.id: + packet_id = storage_packet_id(env.packet) + if packet_id is None: return 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)) + result = await session.execute(select(Packet).where(Packet.id == packet_id)) packet = result.scalar_one_or_none() if not packet: now_us = int(time.time() * 1_000_000) packet_values = { - "id": env.packet.id, + "id": packet_id, "portnum": env.packet.decoded.portnum, "from_node_id": getattr(env.packet, "from"), - "to_node_id": env.packet.to, + "to_node_id": storage_to_node_id(env.packet), "payload": env.packet.SerializeToString(), "import_time_us": now_us, "channel": env.channel_id, @@ -208,7 +228,7 @@ async def process_envelope(topic, env): now_us = int(time.time() * 1_000_000) seen_values = { - "packet_id": env.packet.id, + "packet_id": packet_id, "node_id": int(env.gateway_id[1:], 16), "channel": env.channel_id, "rx_time": env.packet.rx_time, diff --git a/meshview/templates/firehose.html b/meshview/templates/firehose.html index bc5266a..cc42be0 100644 --- a/meshview/templates/firehose.html +++ b/meshview/templates/firehose.html @@ -241,7 +241,7 @@ function logPacketTimes(packet) { const times = formatTimes(packet.import_time_us); console.log( "[firehose] packet time", - "id=" + packet.id, + "id=" + (packet.packet_id ?? packet.id), "epoch_us=" + times.epoch, "local=" + times.local, "utc=" + times.utc @@ -372,6 +372,14 @@ async function fetchUpdates() { const safePayload = (pkt.payload || "") .replace(//g, ">"); + const packetIdCell = pkt.packet_id + ? ` + ${pkt.packet_id} + ` + : pkt.portnum === 73 + ? `Not at Packet` + : ``; const html = ` @@ -382,10 +390,7 @@ async function fetchUpdates() { - - ${pkt.id} - + ${packetIdCell} ${from} diff --git a/meshview/templates/map.html b/meshview/templates/map.html index 7602aa6..babe229 100644 --- a/meshview/templates/map.html +++ b/meshview/templates/map.html @@ -148,6 +148,7 @@ +