diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index f12b077..9f72748 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -477,6 +477,19 @@ storage: Packets are stored in a local SQLite database. Old packets are pruned automatically based on `max_packets_retained`. +### Stray frames (Unknown RF) + +When a LoRa frame fails **both** Meshtastic and MeshCore decode, Meshpoint can log RF metadata only (no relay, no re-encode). View results in the dashboard **Unknown RF** tab or export via `GET /api/stray_frames?format=csv`. + +```yaml +stray_frames: + enabled: true + max_retained: 10000 # hard cap on SQLite rows + retention_hours: 168 # drop rows older than this (7 days) +``` + +Pruning runs in the background during the normal storage cleanup loop and does not block the receive path. + --- ## Dashboard @@ -490,6 +503,10 @@ dashboard: Access at `http://:8080`. Bind to `127.0.0.1` to restrict to local access only. +### Unknown RF tab + +Open **Unknown RF** in the sidebar to browse undecodable frames logged by `stray_frames` (see Storage). Filter by time window and minimum RSSI; use **Export CSV** to download the current filter via `/api/stray_frames?format=csv`. Disable logging with `stray_frames.enabled: false` in `local.yaml`. + --- ## Device Identity @@ -744,6 +761,11 @@ storage: # local SQLite packet store max_packets_retained: 100000 cleanup_interval_seconds: 3600 +stray_frames: # undecodable RF metadata (Unknown RF tab) + enabled: true + max_retained: 10000 + retention_hours: 168 + dashboard: # local web UI host: "0.0.0.0" port: 8080 diff --git a/frontend/css/unknown_rf.css b/frontend/css/unknown_rf.css new file mode 100644 index 0000000..49d94ed --- /dev/null +++ b/frontend/css/unknown_rf.css @@ -0,0 +1,113 @@ +.section[data-section="unknown-rf"] { + overflow-y: auto; +} + +.unknown-rf-panel { + padding: 1.25rem; + max-width: 1100px; + margin: 0 auto; +} + +.unknown-rf-panel__header { + display: flex; + flex-wrap: wrap; + align-items: flex-start; + justify-content: space-between; + gap: 1rem; + margin-bottom: 1rem; +} + +.unknown-rf-panel__title { + margin: 0; + font-size: 1.1rem; + color: var(--text-primary, #f1f5f9); +} + +.unknown-rf-panel__desc { + margin: 0.35rem 0 0; + font-size: 0.78rem; + color: var(--text-secondary, #94a3b8); + max-width: 40rem; +} + +.unknown-rf-controls { + display: flex; + flex-wrap: wrap; + align-items: flex-end; + gap: 0.75rem; + margin-bottom: 1rem; +} + +.unknown-rf-field label { + display: block; + font-size: 0.68rem; + color: var(--text-muted, #64748b); + margin-bottom: 0.2rem; +} + +.unknown-rf-field input, +.unknown-rf-field select { + background: rgba(15, 23, 42, 0.8); + border: 1px solid rgba(51, 65, 85, 0.8); + border-radius: 6px; + color: var(--text-primary, #e2e8f0); + padding: 0.35rem 0.5rem; + font-size: 0.78rem; +} + +.unknown-rf-btn { + background: rgba(6, 182, 212, 0.15); + border: 1px solid rgba(6, 182, 212, 0.45); + color: #67e8f9; + border-radius: 6px; + padding: 0.4rem 0.75rem; + font-size: 0.75rem; + cursor: pointer; +} + +.unknown-rf-btn:hover { + background: rgba(6, 182, 212, 0.25); +} + +.unknown-rf-meta { + font-size: 0.72rem; + color: var(--text-secondary, #94a3b8); + margin-bottom: 0.75rem; +} + +.unknown-rf-table-wrap { + overflow-x: auto; + border: 1px solid rgba(51, 65, 85, 0.6); + border-radius: 8px; +} + +.unknown-rf-table { + width: 100%; + border-collapse: collapse; + font-size: 0.75rem; +} + +.unknown-rf-table th, +.unknown-rf-table td { + padding: 0.45rem 0.6rem; + text-align: left; + border-bottom: 1px solid rgba(51, 65, 85, 0.35); +} + +.unknown-rf-table th { + color: var(--text-muted, #64748b); + font-weight: 600; + background: rgba(15, 23, 42, 0.6); +} + +.unknown-rf-table td { + color: var(--text-primary, #e2e8f0); + font-variant-numeric: tabular-nums; +} + +.unknown-rf-empty { + padding: 2rem; + text-align: center; + color: var(--text-secondary, #94a3b8); + font-size: 0.8rem; +} diff --git a/frontend/index.html b/frontend/index.html index 239398c..a367685 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -33,6 +33,7 @@ + @@ -102,6 +103,24 @@ Stats +