mirror of
https://github.com/ajvpot/meshexplorer.git
synced 2026-07-29 04:42:23 +02:00
7528eac3a24e534e95bf199e851fb420a7797c9c
* Derive more neighbor edges: hash-size-aware paths, anchors, confidence tiers Rework the meshcore_all_neighbor_edges materialized view (migration 008) so the map's "show all neighbors" layer surfaces many more, and higher-quality, edges: - Parse routing paths at the packet's real hash_size (1/2/3 bytes per hop) instead of assuming 1-byte hops, so extended-hash packets are no longer mis-sliced, and wide (2-/3-byte) prefixes resolve uniquely. - Add anchored edges: resolve a hop against a fully-known endpoint (the advert originator or the uploading gateway) when exactly one in-region repeater of the right prefix sits within a plausible LoRa-hop distance. - Tag every edge with a derivation `method` and a `confidence` score, and aggregate undirected edges across observations. Frontend: expose method/confidence on the all-neighbors API and color edges by method / fade by confidence. The old "only MQTT neighbors" checkbox becomes the top notch of a single confidence selector (MQTT-direct only -> high -> standard -> all). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Tighten neighbor edges: 100km anchor cap + region-unique anchor binds Two precision fixes after reviewing cross-metro over-linking: - Cap anchored edges at 100 km (was 206 km). Anchors bind a hop to the single nearby repeater of a prefix, so a wrong bind is indistinguishable from a real hop -> a loose cap admitted ~200 km false links. path-uniq and direct edges (observed consecutive hops / zero-hop adverts) keep the 206 km backstop. - Require a region-unique prefix for anchor binds. Without it, a 1-byte hop whose true (unlocated) forwarder is out of set mis-binds to a coincidental same-prefix repeater that merely happens to be the lone nearby candidate (~22% of 1-byte anchors). Region-uniqueness removes the proximity guess; the 100 km check becomes a sanity confirm. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Demote anchored edges to substandard confidence Anchored edges are geographically inferred (resolve a hop to the region-unique repeater near a known endpoint), not observed consecutive hops, so they are less trustworthy than any path-uniq edge. Re-rank confidence to: direct 1.0 > path-uniq-3b 0.8 > path-uniq-2b 0.6 > anchor 0.45 > path-uniq-1b 0.4. Anchors now fall below the 0.5 "Standard" default (hidden by default, just above the noisy 1-byte tier). Add an "Include anchored (lower confidence)" UI tier at 0.45 so they can be opted into without the 1-byte noise. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Unify neighbor inference: global confidence setting, hover + node page - Move the neighbor-confidence preference from per-map-layer settings to global Settings (ConfigContext); the map all-neighbors layer, map hover, and node page all read it. Default "Standard" (0.5). - Map hover and the node detail page now derive neighbors from the unified graph (meshcore_all_neighbor_edges) via a new getMeshcoreNodeAllEdges + a mode=all option on the node neighbors route/hook, so they match "show all neighbors". - Node page shows direct and inferred neighbors in one list; inferred cards carry an "Inferred · <method>" + confidence indicator instead of direction arrows. - Color map hover lines by derivation method (purple/blue/teal), fade by confidence. - Remove the "Manage Channel Keys" button from the Settings popover (still reachable via the + on the messages page). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Keep neighbor lines when either endpoint is in view Both the server bbox filter (getAllNodeNeighbors) and the client filter (AllNeighborLines) required BOTH endpoints inside the viewport, so any line with one end off-screen vanished when zooming in. Switch both to "either endpoint in view": the server returns an edge if source OR target falls in the bbox, and the client keeps it if either endpoint is a visible node. Each edge carries both endpoints' coordinates, so the off-screen end still draws. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Alex Vanderpot <alex@Alexs-MacBook-Pro-2.local> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
MeshExplorer
A real-time map, chat client, and packet-analysis tool for MeshCore mesh
networks. This repository ships the whole stack so it can be brought up with a
single docker compose up:
| Component | Path | Description |
|---|---|---|
| Web app | meshexplorer/ |
Next.js UI + API (map, chat, stats, packet analysis) |
| Ingest + DB | ingest/ |
Go MeshCore MQTT→ClickHouse ingest, ClickHouse image, and SQL migrations |
| Discord relay | meshexplorer/ (Dockerfile.bot) |
Optional bot that relays MeshCore channel messages to Discord |
| Grafana | grafana/ |
Dashboards with a pre-provisioned ClickHouse datasource (read-only user), on 127.0.0.1:3000 |
Architecture
MQTT brokers (you configure)
│
▼
┌──────────────┐ ┌──────────────┐
│ meshcoreingest│──▶│ ClickHouse │◀── migrate (one-shot, applies schema)
└──────────────┘ └──────┬───────┘
│ (readonly user)
┌──────────┴──────────┐
▼ ▼ ▼
meshexplorer discord-bot grafana
(web UI :3001) (--profile bot) (:3000)
Quick start
Requirements: Docker + Docker Compose.
cp .env.example .env
# Edit .env — at minimum set:
# CLICKHOUSE_PASSWORD (read/write user, used by ingest + migrations)
# MQTT_BROKERS (JSON array of meshcore MQTT brokers to ingest from)
# Optional, for the Discord relay: DISCORD_WEBHOOK_URL (+ run with --profile bot)
docker compose up --build
Then open http://localhost:3001.
Startup order is handled automatically: ClickHouse becomes healthy → migrate
applies the schema and exits → meshcoreingest and meshexplorer start.
To also run the Discord relay:
docker compose --profile bot up --build
Configuration
All configuration is via environment variables in .env (see
.env.example for the full list and defaults). Highlights:
- ClickHouse — two accounts. The read/write
defaultuser (CLICKHOUSE_PASSWORD) is used by the ingest daemon and the migration runner; thereadonlyuser (CLICKHOUSE_READONLY_PASSWORD) is used by the web app and the Discord bot. ClickHouse is only published to127.0.0.1for debugging and is otherwise reachable only on the internalmeshnetnetwork. - MQTT_BROKERS — a JSON array; each entry is
{ "url", "username", "password", "topics" }(topicsdefaults to["meshcore/#"]). The ingest daemon exits with a clear error if this is unset, so configure at least one broker.
Development
Each component can be run on its own:
- Web app: see
meshexplorer/README.md(npm install && npm run dev). - Ingest: see
ingest/README.md(go build ./...).
Security notes
.envis gitignored — keep real credentials out of version control.- If you previously used the bundled defaults, rotate any secrets before going to production.
Description
Languages
TypeScript
83.6%
Go
10.1%
JavaScript
3.7%
CSS
1.6%
Dockerfile
0.8%
Other
0.2%