Commit Graph

1498 Commits

Author SHA1 Message Date
James Smith f873e200c1 style: group --accent-cyan-glow with other cyan tokens 2026-04-13 18:17:42 +01:00
James Smith fe6a220384 style: deepen background tokens and add scanline/glow variables 2026-04-13 18:16:03 +01:00
James Smith 2723fa3cf1 docs: add Sub-Project 1 implementation plan (design system uplift)
6-task plan covering token deepening, nav active state glow, panel pulse
animation, scanline texture, and localStorage nav group persistence.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 16:50:22 +01:00
James Smith 04e6d24bd9 docs: add UI/UX improvements design spec
Mission Control aesthetic, maps overhaul, mode polish sprint for 12 modes,
and 5 new features (Spectrum Overview, Alerts Engine, Signal Recording,
Signal ID, Mobile PWA) — decomposed into 4 sequential sub-projects.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 16:47:30 +01:00
James Smith f7d6503e07 chore: add pre-commit hook to catch lint errors before push
Adds ruff pre-commit hook that auto-fixes and formats on every commit,
preventing lint CI failures from reaching GitHub.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 13:40:22 +01:00
Smittix b462d3c6c6 fix(adsb): disable bias-T on stop and warn when toggled while running (#207)
* fix(adsb): disable bias-T on stop and warn when toggled while running

The RTL-SDR bias-T hardware register persists after the device is closed,
so toggling bias-T off in the UI and stopping the SDR had no effect on the
actual hardware — verified with a multimeter in issue #205.

- Add disable_bias_t_via_rtl_biast() to rtlsdr.py (mirrors enable, uses -b 0)
- Track adsb_bias_t_active in adsb.py; call disable on stop_adsb() so the
  hardware register is cleared when ADS-B is stopped
- Show an inline warning in the UI when the bias-T checkbox is toggled while
  any SDR mode is active, since the setting only takes effect at start time

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): remove unused imports in tscm sweep.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 13:18:50 +01:00
Smittix d9666c10a5 Merge pull request #206 from smittix/fix/sensor-removeChild-freeze
fix(sensor): replace static NodeList loops causing page freeze and removeChild TypeError
2026-04-12 21:29:41 +01:00
James Smith 2360e6a303 fix(sensor): replace static NodeList while-loops causing page freeze and removeChild TypeError
Four list-trimming loops used querySelectorAll (static NodeList) inside a
while condition, so .length never decreased — causing infinite loops that
froze the page, or repeated removeChild calls on already-removed nodes
(TypeError: parameter 1 is not of type 'Node').

Also replaces blocking alert() with showInfo() for start errors and adds
a .catch() handler to the start_sensor fetch so network failures surface
cleanly instead of leaving the UI in a broken state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 21:28:50 +01:00
James Smith a1af859cd1 feat(export): AIS UDP NMEA forward and JSON export endpoints for AIS/ADS-B
AIS:
- New optional NMEA UDP forwarding via AIS-catcher's -u flag, configurable
  from the AIS sidebar (host + port). Lets OpenCPN and other NMEA tools
  receive live vessel data directly. All SDR builders updated.
- New GET /ais/vessels endpoint — clean JSON snapshot of tracked vessels
  for REST integration

ADS-B:
- New GET /adsb/aircraft endpoint — JSON snapshot of all tracked aircraft,
  with optional ?icao= and ?military=true filters. Response includes a
  reminder that port 30003 (SBS) is already available for tools like
  Virtual Radar Server and OpenCPN's AIS/target plugin.

Closes #90
2026-04-05 16:20:10 +01:00
James Smith 50de9a9932 feat(gain): normalize gain controls across modes
- Pager and sensor gain inputs changed from unvalidated text fields to
  number inputs with min/max/step constraints
- ADS-B dashboard now exposes a gain input in the tracking strip;
  previously gain was hardcoded to 40 dB with no user control
- validate_gain() ceiling raised from 50 to 102 dB to support HackRF
  (LNA 40 + VGA 62 = 102 dB combined) and LimeSDR (73 dB)
- sdrCapabilities gain_max values corrected: HackRF 62→102, Airspy 21→45
- onSDRTypeChanged() now propagates gain_max to all mode gain inputs so
  HTML constraints match the selected SDR's actual range

Closes #162
2026-04-05 16:02:03 +01:00
James Smith 3ed4313854 feat(tscm): add custom frequency range option to RF sweep
Adds a "Custom Range" sweep type that lets users specify start/end MHz
instead of using a fixed preset. Useful in dense RF environments where
a full or standard sweep returns too many signals and causes slowdown.

UI shows start/end MHz inputs when "Custom Range" is selected. Range is
validated (0 < start < end ≤ 6000 MHz) before the sweep starts.
Backend threads the ranges through to _scan_rf_signals(), which already
supports arbitrary frequency bands.

Closes #172
2026-04-05 15:46:01 +01:00
James Smith 3ed1c8bd37 feat(api): add sdr_claims to /health and surface /devices/status
/health now includes sdr_claims: a dict mapping 'sdr_type:device_index'
to the mode currently using that device (e.g. {"rtlsdr:0": "pager"}).
Empty when no devices are in use.

/devices/status already existed and returns the full device list with
in_use/used_by per device — documented in the issue response.

Closes #158
2026-04-05 14:40:42 +01:00
James Smith 15e25a66a3 feat(adsb): expand aircraft icon types and add type to hover tooltip
Adds three new icon shapes (widebody, bizjet, turboprop) to the existing
set (jet, prop, helicopter, military, glider), giving 8 distinct silhouettes.
Classification covers common ICAO type codes: widebodies (744, 777, A380 etc.),
business jets (Citation, Gulfstream, Learjet etc.), turboprops (ATR, DH8 etc.),
and light GA piston aircraft.

Hover tooltip now shows aircraft type description (e.g. "Airbus A320-200")
when available from the aircraft DB, in addition to callsign and altitude.

Closes #201
2026-04-05 14:29:50 +01:00
James Smith 9345419bc6 fix(weather-sat): lower default gain to 30 dB to prevent ADC saturation
Strong passes at 40 dB (the previous default) cause RTL-SDR ADC clipping,
producing a distorted IQ stream that SatDump cannot lock onto. 30 dB is
a safer starting point that still captures weak passes cleanly.

Also adds a UI hint below the gain control explaining the saturation issue.

Closes #185
2026-04-05 14:20:06 +01:00
James Smith 03f0f8fd4c fix(bluetooth): fix locate button not switching to bt_locate mode
Remove the split fast-path in doLocateHandoff that called BtLocate.handoff()
directly when the module was already loaded. That path relied on handoff()
internally calling switchMode, causing a double switchMode in the lazy-load
path and no guaranteed mode switch in the fast path.

Now doLocateHandoff always calls switchMode('bt_locate') first (lazy-loading
script/styles as needed), then calls BtLocate.handoff() in .then(). Removed
the redundant switchMode call from BtLocate.handoff() since the caller owns
the mode transition.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 13:54:16 +01:00
James Smith 90398b11cb chore: add AGENTS.md and superpowers plan docs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 12:59:51 +01:00
James Smith 524b329ac5 fix(bluetooth): add transform-box to radar sweep for Firefox, remove dead radar-sweep rule 2026-03-29 21:34:35 +01:00
James Smith bb0743001c feat(bluetooth): WiFi-style 2-line device rows
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 16:07:51 +01:00
James Smith f8f98ca832 feat(bluetooth): scan indicator JS, sort controls, renderAllDevices
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 15:31:02 +01:00
James Smith 0533ca0190 fix(bluetooth): update filter container ID to btFilterGroup, document sticky offset 2026-03-29 15:29:07 +01:00
James Smith 1f5e125d97 feat(bluetooth): scan indicator and sort+filter controls row in device list header
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 15:25:15 +01:00
James Smith 4b9b436423 feat(bluetooth): CSS animated radar sweep with trailing glow arc
Replaces the requestAnimationFrame loop in proximity-radar.js with a
CSS @keyframes rotation on .bt-radar-sweep, mirroring the WiFi radar
pattern. Adds two trailing arc paths for a glow effect and updates
setPaused() to toggle animationPlayState instead of the rAF flag.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 14:35:45 +01:00
James Smith 4efe09c8aa Add Bluetooth UI polish implementation plan 2026-03-27 16:48:08 +00:00
James Smith aa8cf41486 Add Bluetooth UI polish design spec 2026-03-27 16:19:16 +00:00
James Smith 762c771d0e fix(wifi): remove dead chart pendingRender flag, dead radar highlight call, CSS.escape client mac
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 22:58:58 +00:00
James Smith 895250b190 feat(wifi): network detail panel replaces slide-up drawer
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 22:48:23 +00:00
James Smith 5c357f3b09 fix(wifi): render heatmap and security ring even when filter yields no networks 2026-03-26 22:40:08 +00:00
James Smith 1a4c6ee612 feat(wifi): channel heatmap and security ring chart
Replace static channel bar chart and security dots with a scrolling
2.4 GHz channel heatmap (up to 10 scan snapshots) and an SVG donut
security ring showing WPA2/WPA3/WEP/Open network distribution.
2026-03-26 22:38:31 +00:00
James Smith 7291043273 fix(wifi): correct zone count colors (close=red, far=green) 2026-03-26 22:32:34 +00:00
James Smith 702f696475 fix(wifi): radar bssidToAngle divisor, Firefox SVG transform-origin, zone label clarity
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 22:31:21 +00:00
James Smith aa49f6a41c fix(wifi): remove duplicate zone count update from updateStats 2026-03-26 22:28:44 +00:00
James Smith 0648e80a74 feat(wifi): animated SVG proximity radar with sweep rotation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 22:26:47 +00:00
James Smith 642d243556 fix(wifi): XSS fix for onclick handler, unknown security badge, null rssi handling
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 22:23:40 +00:00
James Smith e9959050e6 feat(wifi): replace table with styled div network rows
Replaces the 7-column <table> network list with flex div rows featuring
two-line layout (SSID + security badges on top, signal bar + meta on
bottom), coloured left-border threat indicators, and new sort controls.
Renames selectedNetwork → selectedBssid and updateNetworkTable → renderNetworks throughout wifi.js.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 22:18:51 +00:00
James Smith dfa47e27c4 feat(wifi): enhanced status bar with open count and scan indicator
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 22:11:48 +00:00
James Smith 702743f826 Finalise WiFi scanner redesign spec (reviewer approved) 2026-03-26 21:54:13 +00:00
James Smith 446a4a3019 Add WiFi scanner redesign spec 2026-03-26 21:40:27 +00:00
James Smith 67d322403b Bump VERSION to 2.26.13 and add changelog entry
config.VERSION was not updated when the v2.26.13 tag was created,
causing the update checker to always report an update available on
fresh installs and git pulls.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 17:15:32 +00:00
James Smith d53f31b59e Persist aircraft DB under data/adsb/ for Docker volume compatibility
Move aircraft_db.json and aircraft_db_meta.json from the project root
to data/adsb/ so they survive container restarts and rebuilds. Add
matching volume mount to both Docker Compose profiles.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 16:56:34 +00:00
James Smith 34b9199bb2 Fix Docker volume mount shadowing data Python modules
Mounting ./data:/app/data caused the host directory to shadow the
entire /app/data Python package, making modules like data.oui
unavailable and crashing gunicorn on startup. Mount only the three
runtime output subdirectories instead.

Fixes #200

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 16:28:11 +00:00
James Smith 2c19e3e43f Fix TSCM sweep module variable scoping and remove stale progress bar call
- Access module-level _sweep_running, _current_sweep_id, and tscm_queue
  via explicit package import to avoid UnboundLocalError from closure
  variable shadowing in route handlers
- Remove orphaned tscmProgressBar.style.width assignment in index.html

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 21:52:29 +00:00
James Smith 253b7e05f8 Fix 5GHz WiFi scanning failures in deep scan and band detection
- Fix deep scan with 'All bands' never scanning 5GHz: band='all' now
  correctly passes --band abg to airodump-ng (previously no flag was
  added, causing airodump-ng to default to 2.4GHz-only)
- Fix APs first seen without channel info permanently stuck at
  band='unknown': _update_access_point now backfills channel, frequency,
  and band when a subsequent observation resolves the channel
- Fix legacy /wifi/scan/start combining mutually exclusive --band and -c
  flags: --band is now only added when no explicit channel list is given,
  and the interface is always placed as the last argument

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 21:50:47 +00:00
James Smith f3b88cfc60 Fix ADS-B remote mode incorrectly stopping other SDR services
When using a remote SBS feed, no local SDR is needed. The pre-flight
device conflict check was running regardless and stopping whichever
mode had the selected SDR device claimed — even though ADS-B remote
mode never touches a local SDR. Skip the conflict check when remoteConfig is set.
2026-03-20 14:04:04 +00:00
James Smith 28bc3b37ad Fix radiosonde false 'missing' report at end of setup
check_tools() was using cmd_exists on 'auto_rx.py' which fails because
it's never in PATH — installed to /opt/radiosonde_auto_rx/. Now uses
the same file-based check as tool_is_installed(), consistent with
health check and status view.
2026-03-20 13:53:50 +00:00
James Smith 1fa9667c80 Fix ruff lint errors to unblock CI (import sorting, unused imports, style) 2026-03-20 13:51:30 +00:00
James Smith c2f70d6ea5 Add multi-arch support (amd64 + arm64) to Docker CI workflow 2026-03-20 13:47:27 +00:00
Smittix dfff6f424c Merge pull request #199 from jangrewe/main
Add Github Action to build Docker image
2026-03-20 13:38:32 +00:00
Jan Grewe c43e2edec9 Add Github Action to build Docker image 2026-03-20 13:58:02 +01:00
James Smith dff3545e1a Balance column heights to eliminate sky view gap
Precise calculation showed mission-drawer (~1100px) was 213px taller
than command-rail content (~887px), leaving 213px of empty background
at the bottom of the right column.

Three targeted reductions to mission-drawer height (~234px total):
- drawer-actions: stacked 1-column → 3-column row (-76px)
- drawer-list: max-height 240px → 180px (-40px)
- drawer-info-grid: 1-column → 2-column for Quick Info (-118px)

Mission-drawer drops to ~866px, command-rail (~887px) now drives the
primary-layout row height — gap closes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 00:08:07 +00:00
James Smith fd8d565908 Fix sky view gap: don't stretch polar panel beyond its content
The command-rail's 1fr last row caused the sky view panel to fill all
remaining column height (driven by the tall mission-drawer), showing a
large empty bordered space below the pass data strip.

Switch to all-auto rows with align-content: start so each panel is
exactly as tall as its content — the open background below the column
looks intentional rather than a panel with dead space inside it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 00:00:47 +00:00