feat: weekly config backup + unified telemetry schema + fleet dashboard

- scripts/backup-config.sh: weekly router config backup to hub (SRM + OpenWrt)
  Runs via cron, exports platform-specific config, POSTs to /api/backup
  Keeps last 10 backups per device on hub

- hub/ingest.sh: fleet hub telemetry normalizer + backup receiver
  Normalises GL (openwrt) and Synology telemetry into single schema
  Adds platform field to GL telemetry for unified dashboard

- hub/dashboard.html: single-pane fleet console
  Shows all routers (GL + Synology) with scores, WAN state, GPS, uptime
  Auto-refreshes every 10s from /api/status endpoint

- 62-point checklist updated with weekly backup section 9b

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-22 00:18:27 +00:00
parent f15ac69925
commit 1005269239
5 changed files with 391 additions and 3 deletions
@@ -96,7 +96,7 @@ telemetry_collect() {
esc_id=$(_json_str "$device_id")
esc_ver=$(_json_str "$version")
esc_sel=$(_json_str "$sel_primary")
printf '{"device_id":"%s","timestamp":%d,"uptime":%d,"version":"%s","sel_primary":"%s","gps":{"lat":%s,"lon":%s,"fix":%s},"wan":{"modem_0001":{"score":%s,"latency_ms":%s,"dl_mbps":%s,"ul_mbps":%s,"jitter_ms":%s,"loss_pct":%s,"rsrp_dbm":%s},"wan":{"score":%s,"latency_ms":%s,"dl_mbps":%s,"ul_mbps":%s,"jitter_ms":%s,"loss_pct":%s}},"sim_slot":%s,"starlink":{"latency_ms":%s,"dl_bps":%s,"obstructed":%s,"outage":%s}}\n' \
printf '{"device_id":"%s","timestamp":%d,"uptime":%d,"version":"%s","platform":"openwrt","sel_primary":"%s","gps":{"lat":%s,"lon":%s,"fix":%s},"wan":{"modem_0001":{"score":%s,"latency_ms":%s,"dl_mbps":%s,"ul_mbps":%s,"jitter_ms":%s,"loss_pct":%s,"rsrp_dbm":%s},"wan":{"score":%s,"latency_ms":%s,"dl_mbps":%s,"ul_mbps":%s,"jitter_ms":%s,"loss_pct":%s}},"sim_slot":%s,"starlink":{"latency_ms":%s,"dl_bps":%s,"obstructed":%s,"outage":%s}}\n' \
"${esc_id}" "${now:-0}" "${uptime_s:-0}" "${esc_ver}" "${esc_sel}" \
"${gps_lat:-null}" "${gps_lon:-null}" "${gps_fix:-null}" \
"${cell_score:-0}" "${cell_lat:-null}" "${cell_dl:-null}" "${cell_ul:-null}" "${cell_jitter:-null}" "${cell_loss:-null}" "${cell_rsrp:-null}" \