Commit Graph

1493 Commits

Author SHA1 Message Date
Smittix
b01598753d 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
3fedff9d08 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
1fc80b05b1 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
0210791c69 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
592e97719b 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
ea80b5ebc3 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
fe64dd9c93 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
f0fb97512a 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
6ea34a4c60 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
6572119360 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
efb7d0ed20 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
5b9d81e3a8 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
71e5599300 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
6967a44620 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
ab4745c70a fix(bluetooth): update filter container ID to btFilterGroup, document sticky offset 2026-03-29 15:29:07 +01:00
James Smith
d2c00b4b2c 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
d45b8bc2fb 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
2511227c4e Add Bluetooth UI polish implementation plan 2026-03-27 16:48:08 +00:00
James Smith
5ee60c5259 Add Bluetooth UI polish design spec 2026-03-27 16:19:16 +00:00
James Smith
7a4dbb8260 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
73b227c49b 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
bfbf06f5c5 fix(wifi): render heatmap and security ring even when filter yields no networks 2026-03-26 22:40:08 +00:00
James Smith
e5a0635418 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
2fce80677a fix(wifi): correct zone count colors (close=red, far=green) 2026-03-26 22:32:34 +00:00
James Smith
56ebdd7670 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
4c37d39e07 fix(wifi): remove duplicate zone count update from updateStats 2026-03-26 22:28:44 +00:00
James Smith
d1d44195c1 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
0dbcb175c0 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
ea348b3360 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
36399cf4aa 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
837090d150 Finalise WiFi scanner redesign spec (reviewer approved) 2026-03-26 21:54:13 +00:00
James Smith
d01cb4b6f3 Add WiFi scanner redesign spec 2026-03-26 21:40:27 +00:00
James Smith
1dde2a008e 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
af2ab567ca 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
6928b8a622 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
205f396942 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>
v2.26.13
2026-03-20 21:52:29 +00:00
James Smith
89c7c2fb07 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
b20b9838d0 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
2d65c4efbf 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
34e1d25069 Fix ruff lint errors to unblock CI (import sorting, unused imports, style) 2026-03-20 13:51:30 +00:00
James Smith
90d39f12c1 Add multi-arch support (amd64 + arm64) to Docker CI workflow 2026-03-20 13:47:27 +00:00
Smittix
bca7888077 Merge pull request #199 from jangrewe/main
Add Github Action to build Docker image
2026-03-20 13:38:32 +00:00
Jan Grewe
cbc6275307 Add Github Action to build Docker image 2026-03-20 13:58:02 +01:00
James Smith
b26ce4f56f 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
44428c2517 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
James Smith
a670103325 Reduce map and primary-layout min-height 460px → 400px to close sky view gap
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 23:56:19 +00:00
James Smith
a2bd0e27f9 Fix weather sat handoff: remove defunct METEOR-M2, fire change event
- Remove 'METEOR-M2' (NORAD 40069) from WEATHER_SAT_KEYS — it has no
  entry in WEATHER_SATELLITES and no dropdown option, so the Capture
  button was silently scheduling against the wrong satellite
- Dispatch a 'change' event after setting satSelect.value in preSelect()
  and startPass() so any UI listeners (frequency display, mode info)
  update correctly when the satellite is set programmatically

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 23:52:14 +00:00
James Smith
7ca018fd7b Reduce map min-height 520px → 460px to close gap below sky view
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 23:45:41 +00:00
James Smith
607a2f28fa Cap polar container height to prevent oversized sky view on narrow screens
1fr in the grid row caused the panel to fill the entire remaining page
height on mobile (~1000px+), leaving large gaps around the centred content.
max-height: min(55vh, 520px) keeps it proportionate on any screen size.
Also switch to justify-content: flex-start so the canvas+strip pack at
the top rather than floating in the middle of a large void.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 23:43:04 +00:00
James Smith
a42ea35d8b Add AOS/TCA/LOS pass data strip below polar plot
Fills the empty space below the sky view circle with a compact
three-column AOS / TCA / LOS readout (time + azimuth/elevation)
and a duration + max elevation footer line.
Populated by drawPolarPlot() when a pass is selected; shows a
placeholder prompt otherwise.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 23:40:38 +00:00