mirror of
https://github.com/zvx-echo6/meshai.git
synced 2026-05-21 23:24:44 +02:00
fix: Dedup packets across sources, translate numeric port numbers to names
Packet dedup: track seen packet IDs across all sources. Same packet from Meshview + MeshMonitor counted once, not twice. Fixes inflated counts. Portnum: numeric values (3, 4, 71) mapped to names (Position, NodeInfo, Neighbors). LLM prompt: guidance on normal vs abnormal packet rates per type.
This commit is contained in:
parent
1d97854319
commit
a80ed6cc7c
3 changed files with 39 additions and 2 deletions
|
|
@ -458,12 +458,20 @@ class MeshDataStore:
|
||||||
- Deliverability (source overlap)
|
- Deliverability (source overlap)
|
||||||
Does NOT rebuild the full node model.
|
Does NOT rebuild the full node model.
|
||||||
"""
|
"""
|
||||||
# Recount packets per node from all sources
|
# Recount packets per node from all sources (deduped by packet ID)
|
||||||
packet_counts: dict[int, int] = {}
|
packet_counts: dict[int, int] = {}
|
||||||
packets_by_type: dict[int, dict[str, int]] = {}
|
packets_by_type: dict[int, dict[str, int]] = {}
|
||||||
|
seen_packet_ids: set = set()
|
||||||
|
|
||||||
for name, source in self._sources.items():
|
for name, source in self._sources.items():
|
||||||
for pkt in (source.packets if hasattr(source, 'packets') else []):
|
for pkt in (source.packets if hasattr(source, 'packets') else []):
|
||||||
|
# Dedup: skip packets already seen from another source
|
||||||
|
pkt_id = pkt.get("packet_id") or pkt.get("id")
|
||||||
|
if pkt_id is not None:
|
||||||
|
if pkt_id in seen_packet_ids:
|
||||||
|
continue
|
||||||
|
seen_packet_ids.add(pkt_id)
|
||||||
|
|
||||||
from_node = pkt.get("from_node") or pkt.get("from_node_id") or pkt.get("from")
|
from_node = pkt.get("from_node") or pkt.get("from_node_id") or pkt.get("from")
|
||||||
if from_node is None:
|
if from_node is None:
|
||||||
continue
|
continue
|
||||||
|
|
@ -478,7 +486,7 @@ class MeshDataStore:
|
||||||
|
|
||||||
packet_counts[from_node] = packet_counts.get(from_node, 0) + 1
|
packet_counts[from_node] = packet_counts.get(from_node, 0) + 1
|
||||||
|
|
||||||
portnum = pkt.get("portnum") or pkt.get("portnum_name") or pkt.get("type") or "UNKNOWN"
|
portnum = str(pkt.get("portnum") or pkt.get("portnum_name") or pkt.get("type") or "UNKNOWN")
|
||||||
if from_node not in packets_by_type:
|
if from_node not in packets_by_type:
|
||||||
packets_by_type[from_node] = {}
|
packets_by_type[from_node] = {}
|
||||||
packets_by_type[from_node][portnum] = packets_by_type[from_node].get(portnum, 0) + 1
|
packets_by_type[from_node][portnum] = packets_by_type[from_node].get(portnum, 0) + 1
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# Portnum display names (from Meshtastic protobufs)
|
# Portnum display names (from Meshtastic protobufs)
|
||||||
PORTNUM_DISPLAY = {
|
PORTNUM_DISPLAY = {
|
||||||
|
# String names (from some APIs)
|
||||||
"TEXT_MESSAGE_APP": "Text",
|
"TEXT_MESSAGE_APP": "Text",
|
||||||
"POSITION_APP": "Position",
|
"POSITION_APP": "Position",
|
||||||
"NODEINFO_APP": "NodeInfo",
|
"NODEINFO_APP": "NodeInfo",
|
||||||
|
|
@ -35,6 +36,29 @@ PORTNUM_DISPLAY = {
|
||||||
"REMOTE_HARDWARE_APP": "RemoteHW",
|
"REMOTE_HARDWARE_APP": "RemoteHW",
|
||||||
"ATAK_PLUGIN": "ATAK",
|
"ATAK_PLUGIN": "ATAK",
|
||||||
"ATAK_FORWARDER": "ATAK",
|
"ATAK_FORWARDER": "ATAK",
|
||||||
|
# Numeric port numbers (from other APIs)
|
||||||
|
"0": "Unknown",
|
||||||
|
"1": "Text",
|
||||||
|
"3": "Position",
|
||||||
|
"4": "NodeInfo",
|
||||||
|
"5": "Routing",
|
||||||
|
"6": "Admin",
|
||||||
|
"7": "Waypoint",
|
||||||
|
"8": "Audio",
|
||||||
|
"33": "Reply",
|
||||||
|
"34": "IP Tunnel",
|
||||||
|
"64": "Serial",
|
||||||
|
"65": "Store&Fwd",
|
||||||
|
"66": "RangeTest",
|
||||||
|
"67": "Telemetry",
|
||||||
|
"68": "Sensor",
|
||||||
|
"69": "PaxCounter",
|
||||||
|
"70": "Traceroute",
|
||||||
|
"71": "Neighbors",
|
||||||
|
"72": "ATAK",
|
||||||
|
"73": "MapReport",
|
||||||
|
"256": "Private",
|
||||||
|
"257": "ATAK Fwd",
|
||||||
}
|
}
|
||||||
|
|
||||||
def _clean_portnum(portnum) -> str:
|
def _clean_portnum(portnum) -> str:
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,11 @@ RESPONSE STYLE:
|
||||||
- ABSOLUTELY NO markdown. No asterisks, no bold, no bullet points with * or -, no numbered lists with 1. 2. 3. Just plain text sentences.
|
- ABSOLUTELY NO markdown. No asterisks, no bold, no bullet points with * or -, no numbered lists with 1. 2. 3. Just plain text sentences.
|
||||||
- NEVER say "Want me to keep going?" — the message system adds this automatically when needed. If you say it yourself, users see it twice.
|
- NEVER say "Want me to keep going?" — the message system adds this automatically when needed. If you say it yourself, users see it twice.
|
||||||
- When explaining "X/Y gateways" (like 7/7), explain that it means the node is visible to X out of Y data sources (Meshview and MeshMonitor instances that monitor the mesh). It does NOT mean infrastructure routers or regional gateways.
|
- When explaining "X/Y gateways" (like 7/7), explain that it means the node is visible to X out of Y data sources (Meshview and MeshMonitor instances that monitor the mesh). It does NOT mean infrastructure routers or regional gateways.
|
||||||
|
- When reporting packet types, ALWAYS use the name (Position, NodeInfo, Telemetry) not the number.
|
||||||
|
- Normal position interval: 15-30 minutes (48-96 packets/day). 400+ Position packets in 24h means aggressive position interval, wasting airtime. Tell the user.
|
||||||
|
- Normal NodeInfo: every 2-3 hours (8-12/day). 50+ is excessive.
|
||||||
|
- Normal NeighborInfo: every 6 hours (4/day). 20+ is aggressive.
|
||||||
|
- If a node has high packet volume, explain WHAT the packets are and WHETHER the rate is abnormal compared to normal intervals.
|
||||||
|
|
||||||
QUESTION TYPES:
|
QUESTION TYPES:
|
||||||
- "How's the mesh?" -> Lead with composite score. Highlight 1-2 biggest issues by name. Summarize each region briefly.
|
- "How's the mesh?" -> Lead with composite score. Highlight 1-2 biggest issues by name. Summarize each region briefly.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue