Commit Graph

163 Commits

Author SHA1 Message Date
Smittix
32b373bf2c Fix stalled audio pipeline cleanup and scanner stop race condition
- Kill audio pipeline when startup produces no data instead of leaving
  zombie processes running
- Skip unnecessary 1s USB release delay when no processes were active
- Remove racy fresh=1 pipeline restart from stream endpoint
- Await stopScanner() before starting direct listen to prevent race

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 15:39:51 +00:00
Smittix
70e9611f02 Remove orphaned receiver count section from WebSDR sidebar
The Receiver Count section had no <h3> so it didn't get collapsible
panel styling, rendering as a small out-of-place rectangle. The count
is already shown in the main receiver list panel so this was redundant.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 14:38:07 +00:00
Smittix
d05144bdb3 Fix WebSDR map black space with dynamic minZoom and background color
Static minZoom: 2 wasn't enough for tall containers. Now calculate
minZoom from actual container height so tiles always cover the visible
area. Also set map background to match CartoDB dark tile ocean color
so any remaining edge at extreme latitudes blends seamlessly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 14:32:16 +00:00
Smittix
bfd92e3883 Constrain WebSDR map to prevent vertical black space
Add maxBounds to limit vertical panning to ±85° latitude and set
minZoom to 2 so tiles always cover the visible area. Prevents the
large black bands above and below the map tiles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 14:30:23 +00:00
Smittix
3b191dccd6 Remove raw output display and filter DSD startup banner lines
The dmrRawOutput div was rendering garbled box-drawing characters from
the dsd-fme ASCII art banner below the signal activity canvas. Remove
the div and filter banner lines (box-drawing chars, version info) in
the parser so they never become events.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:52:59 +00:00
Smittix
c0eda84644 Fix signal activity panel dying after DSD startup banner
The stream thread used a blocking readline() with no timeout, so once
DSD finished outputting its startup banner there were no more events
until actual signal activity. The frontend decayed to zero and appeared
dead. If DSD crashed, the synthesizer state never transitioned to
'stopped' so there was no visual or textual indication of failure.

- Use select() with 1s timeout on DSD stderr to avoid indefinite block
- Send heartbeat events every 3s while decoder is alive but idle
- Detect DSD crashes: capture exit code and remaining stderr, send as
  'crashed' status with details and show notification to user
- Frontend properly transitions synthesizer to 'stopped' on process
  death (was only happening on user-initiated stop)
- Increase idle breathing amplitude so LISTENING state is clearly
  visible (0.12 +/- 0.06 vs old 0.05 +/- 0.035)
- Release device reservation on crash, not just user stop

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:49:35 +00:00
Smittix
19f382a31a Add device reservation to DMR mode and improve USB busy error message
DMR was missing checkDeviceAvailability/reserveDevice/releaseDevice
calls that other modes (SSTV, listening post) use, so the device
dropdown showed device 0 as available even when another process held
it. Also detect USB claim errors from rtl_fm and surface a clear
message telling the user to pick a different device.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:44:47 +00:00
Smittix
3b205db329 Fix DMR decoder signal activity and parsing for dsd-fme compatibility
The DSD stderr parser had regex ordering bugs that swallowed voice and
call events as bare slot events, and only matched classic dsd output
format (not dsd-fme). Unmatched lines were silently dropped, leaving
the signal activity panel with nothing to display.

- Reorder regex checks: TG/Src before voice before slot
- Support dsd-fme comma-separated format (TG: x, Src: y)
- Make bare slot regex strict (only standalone "Slot N" lines)
- Forward unmatched DSD lines as raw events for diagnostics
- Add LISTENING state to signal activity panel for raw output
- Show raw decoder output text below synthesizer canvas
- Fix test mocks for find_dsd() tuple return value

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:41:15 +00:00
Smittix
b9c8b1c730 Register SSTV mode with SDR device registry for device state panel
SSTV was not claiming/releasing SDR devices through the centralized
registry, so the device state panel always showed the device as idle
during SSTV use. Added claim_sdr_device/release_sdr_device on the
backend and reserveDevice/releaseDevice on the frontend, matching the
pattern used by all other modes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:28:37 +00:00
Smittix
684f17f507 Add delete and download functionality to SSTV image gallery
Users can now manage decoded SSTV images with download and delete actions
accessible from hover overlays on gallery cards, the full-size image modal
toolbar, and a "Clear All" button in the gallery header. Both ISS and
General SSTV modes are supported.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:12:26 +00:00
Smittix
a0f64f6fa6 Stream partial decoded images during SSTV decode progress
The decode canvas was always black because nothing drew on it. Now the
backend encodes partial JPEG snapshots every 5% progress and the frontend
uses an <img> tag with in-place DOM updates instead of recreating innerHTML
on every SSE event.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 11:58:00 +00:00
Smittix
06c218c736 Add VIS detector state to signal monitor for decode diagnostics
Shows the current VIS detection state machine position (Idle, Leader,
Break, Start bit, Data bits, etc.) in the signal monitor. This helps
diagnose why decoding may not be starting - e.g. if the VIS detector
is stuck in Idle despite a leader tone being present, the signal may
not contain a valid VIS header.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 11:44:35 +00:00
Smittix
1e249a0eec Fix Doppler detecting events clobbering decode progress UI
The Doppler tracking thread emits detecting events every 5s from a
separate thread, unaware of decode state. The previous to_dict() change
included signal_level for ALL detecting events, causing the frontend to
replace the decode progress canvas with the signal monitor mid-decode.

Fix: use None as default for signal_level so only signal-metrics events
(which explicitly set the value) include the field. Also add a frontend
guard to ignore detecting events while the UI is in decoding state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 11:37:14 +00:00
Smittix
82957ab162 Add real-time signal level monitor to SSTV decoder UI
Shows RMS audio level bar and SSTV tone classification (leader/sync/noise)
via SSE during detecting mode, replacing the static "Listening..." state
with actionable signal feedback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 11:25:01 +00:00
Smittix
ef7d8cca9f Replace broken slowrx dependency with pure Python SSTV decoder
slowrx is a GTK GUI app that doesn't support CLI usage, so the SSTV
decoder was silently failing. This replaces it with a pure Python
implementation using numpy and Pillow that supports Robot36/72,
Martin1/2, Scottie1/2, and PD120/180 modes via VIS header auto-detection.

Key implementation details:
- Generalized Goertzel (DTFT) for exact-frequency tone detection
- Vectorized batch Goertzel for real-time pixel decoding performance
- Overlapping analysis windows for short-window frequency estimation
- VIS header detection state machine with parity validation
- Per-line sync re-synchronization for drift tolerance

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 19:47:02 +00:00
Smittix
6783a1cbc4 Fix DMR synthesizer canvas sizing to use element's own rendered rect
getBoundingClientRect on the canvas itself (sized via CSS width:100%)
instead of parentElement with arbitrary offset, preventing zero-width
canvas when flex layout timing varies.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 17:06:22 +00:00
Smittix
7fd7861b4b Add canvas-based visual synthesizer to DMR dashboard
Event-driven spring-physics bar visualization reacting to SSE events
(sync/call/voice) with HSL color coding and center-outward ripple effects.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 17:03:58 +00:00
Smittix
4e3f0ad800 Add DMR digital voice, WebSDR, and listening post enhancements
- DMR/P25 digital voice decoder mode with DSD-FME integration
- WebSDR mode with KiwiSDR audio proxy and websocket-client support
- Listening post waterfall/spectrogram visualization and audio streaming
- Dockerfile updates for mbelib and DSD-FME build dependencies
- New tests for DMR, WebSDR, KiwiSDR, waterfall, and signal guess API
- Chart.js date adapter for time-scale axes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 15:38:08 +00:00
Smittix
4c67307951 Add terrestrial HF SSTV mode with predefined frequencies and modulation support
Adds a general-purpose SSTV decoder alongside the existing ISS SSTV mode,
supporting USB/LSB/FM modulation on common amateur radio HF/VHF/UHF
frequencies (14.230 MHz USB, 3.845 MHz LSB, etc.) with auto-detection
of modulation from preset frequency table.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 15:36:41 +00:00
Smittix
88f71c9b5e Fix updater settings panel error when updater.js is blocked
Add defensive typeof checks before referencing the Updater global in
loadUpdateStatus() and checkForUpdatesManual() so the settings panel
shows a helpful message instead of crashing. Also swap script load
order so updater.js loads before settings-manager.js.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 20:57:10 +00:00
Smittix
5d4b19aef2 Fix TSCM sweep scan resilience and add per-device error isolation
The sweep loop's WiFi/BT/RF scan processing had unprotected
timeline_manager.add_observation() calls that could crash an entire
scan iteration, silently preventing all device events from reaching
the frontend. Additionally, scan interval timestamps were only updated
at the end of processing, causing tight retry loops on persistent errors.

- Wrap timeline observation calls in try/except for all three protocols
- Move last_*_scan timestamp updates immediately after scan completes
- Add per-device try/except so one bad device doesn't block others
- Emit sweep_progress after WiFi scan for real-time status visibility
- Log warning when WiFi scan returns 0 networks for easier diagnosis
- Add known_device and score_modifier fields to correlation engine
- Add TSCM scheduling, cases, known devices, and advanced WiFi indicators

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 16:07:34 +00:00
Smittix
8ba47f3935 Fix radar blip flicker by deferring renders during hover
The innerHTML rebuild on every SSE event was destroying and recreating
DOM elements under the cursor, causing rapid mouseenter/mouseleave
cycling. Now defers DOM rebuilds while hovering and debounces rapid
update calls with a 200ms window.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 23:43:19 +00:00
Smittix
9dd8849b21 Fix proximity radar tooltip flicker on hover
Separate SVG translate positioning from CSS hover scale by nesting
device elements in two groups, preventing the CSS transform from
overriding the position and causing rapid mouseenter/mouseleave cycling.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 23:40:14 +00:00
Smittix
953e94da44 Add SNR column to signal hits table
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 23:01:20 +00:00
Smittix
805fc69281 Set cyan-tinted map tiles as default 2026-02-04 22:31:02 +00:00
Smittix
24332a4e23 Release v2.13.1 - Help modal and navigation improvements
- Add help modal system with keyboard shortcuts reference
- Add Main Dashboard button in navigation bar
- Make settings modal accessible from all dashboards
- Dashboard CSS improvements and consistency fixes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 20:05:07 +00:00
Smittix
340b300aa4 Release v2.13.0 - WiFi client display in AP detail drawer
Features:
- Display connected clients for access points in detail drawer
- Real-time client updates via SSE streaming
- Client cards show MAC, vendor, RSSI, probed SSIDs, and last seen
- Count badge in Connected Clients header

Other changes:
- Updated aircraft database
- CSS and template refinements

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 17:44:23 +00:00
Smittix
1b04b52509 Sync scanner range from backend updates 2026-02-04 13:25:14 +00:00
Smittix
fca334f472 Sync scanner range with backend config 2026-02-04 13:14:42 +00:00
Smittix
d81d644319 Prefer progress data for scanner sweep 2026-02-04 13:11:02 +00:00
Smittix
400cf1114f Use frequency-based sweep display 2026-02-04 12:48:40 +00:00
Smittix
fec38adc78 Stabilize scanner progress tracking 2026-02-04 12:42:30 +00:00
Smittix
993a7d2626 Stabilize sweep display and lower SNR default 2026-02-04 12:30:13 +00:00
Smittix
dbe09411ac Stabilize sweep progress updates 2026-02-04 12:20:38 +00:00
Smittix
0afc47fcdd Ignore out-of-order scan updates 2026-02-04 12:17:36 +00:00
Smittix
c0fa59d10e Add SNR threshold control for power scan 2026-02-04 11:54:56 +00:00
Smittix
812f85b9a9 Log only interesting listening signals 2026-02-04 11:37:15 +00:00
Smittix
77888b7d88 Align scanner audio stream start 2026-02-04 11:27:10 +00:00
Smittix
4a38d7512d Align listening action button styles 2026-02-04 11:23:32 +00:00
Smittix
5d0df18dac Silence listen slow-start log 2026-02-04 11:19:44 +00:00
Smittix
d18e38800e Retry listen playback without fallback 2026-02-04 11:12:46 +00:00
Smittix
76e595aaec Prompt user to enable audio playback 2026-02-04 11:10:34 +00:00
Smittix
dfb9897fa1 Trigger user-initiated audio play on listen 2026-02-04 11:09:04 +00:00
Smittix
82ad784fcb Restart audio pipeline for fresh stream header 2026-02-04 11:04:43 +00:00
Smittix
3f6b9cc5ef Force squelch open for listen audio 2026-02-04 11:00:20 +00:00
Smittix
d75f7c794f Retry listening audio stream fetch 2026-02-04 10:01:58 +00:00
Smittix
503b91ea87 Add fetch stream fallback for listening audio 2026-02-04 09:49:14 +00:00
Smittix
43db7c309d Add WebSocket audio fallback for listening 2026-02-04 09:46:34 +00:00
Smittix
6e57927409 Force audio stream load on listen 2026-02-04 09:39:47 +00:00
Smittix
a404f5ded9 Send SDR settings for listening audio 2026-02-04 09:31:07 +00:00