Commit Graph

352 Commits

Author SHA1 Message Date
Smittix bb263ce1b0 morse: remove select()-based pipe polling for capture/output 2026-02-26 17:29:41 +00:00
Smittix 23d592af1d morse: align rtl_fm streaming path with pager backend 2026-02-26 17:25:33 +00:00
Smittix ababa63856 morse: switch live decode to rtl_fm + multimon backend 2026-02-26 17:20:20 +00:00
Smittix fdffb8e88e Add FIFO transport fallback for Morse SDR sample stream 2026-02-26 16:25:37 +00:00
Smittix 98642e43c7 Use fd-backed stdout paths for Morse rtl_sdr/rtl_fm 2026-02-26 16:16:46 +00:00
Smittix 8cb7edf41e Use non-blocking pipe reads and raw-stream telemetry for Morse 2026-02-26 16:02:10 +00:00
Smittix 64f0e687a0 Fix Morse stderr thread race and broaden startup fallbacks 2026-02-26 15:37:17 +00:00
Smittix 6a54bc8cf3 Use stable RTL IQ sample rate for Morse IQ fallback 2026-02-26 15:08:03 +00:00
Smittix b32d30b789 Force fresh Morse JS and robust IQ stdout capture 2026-02-26 14:08:22 +00:00
Smittix d3b737c19b Switch Morse startup to IQ-first and harden timeout handling 2026-02-26 13:44:04 +00:00
Smittix 146bca4b37 Speed up Morse startup failure cleanup to avoid request timeouts 2026-02-26 13:30:09 +00:00
Smittix e3cf9daaed Add IQ-capture Morse fallback when rtl_fm has no PCM 2026-02-26 13:06:38 +00:00
Smittix 81e5f5479f Add merged-stream rtl_fm fallback for Morse startup 2026-02-26 12:58:29 +00:00
Smittix a5eefc712a Add rtl_fm resample and dc/agc Morse startup fallbacks 2026-02-26 12:46:22 +00:00
Smittix a50d200af4 Prevent Morse start timeout aborts on slow startup 2026-02-26 12:39:31 +00:00
Smittix 99db7f1faf Prefer no-squelch rtl_fm startup profile for Morse 2026-02-26 12:28:53 +00:00
Smittix 4560ec1800 Harden Morse startup PCM detection and retry fallback 2026-02-26 12:25:23 +00:00
Smittix c1dd615e11 Force explicit rtl_fm squelch-off and log first PCM chunk 2026-02-26 11:59:07 +00:00
Smittix 8eb4ff41e2 Improve Morse stream startup compatibility and diagnostics 2026-02-26 11:15:45 +00:00
Smittix 286ab53d26 Fix Morse mode lifecycle stop hangs and rebuild CW decoder 2026-02-26 11:03:00 +00:00
Smittix 5d90c308a9 Fix Morse decoder not receiving PCM audio from rtl_fm
Add bufsize=0 to Popen for raw FileIO instead of BufferedReader, and
start decoder/stderr threads immediately before sleep+poll so stdout
is read without delay — matching the working pager pattern.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 10:21:14 +00:00
Smittix bfae73cabf Forward rtl_fm stderr to Morse frontend diagnostic log
rtl_fm prints device info, tuning, and errors to stderr but the morse
route only logged these server-side. Now stderr lines are forwarded to
the morse queue as info events, displayed in a compact diagnostic log
below the scope canvas. After 10s with no audio data, the scope text
escalates to prompt the user to check the SDR log.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 09:43:28 +00:00
Smittix 0bf8341b6c Fix Morse mode HF reception, stop button, and UX guidance
Enable direct sampling (-D 2) for RTL-SDR at HF frequencies below 24 MHz
so rtl_fm can actually receive CW signals. Add startup health check to
detect immediate rtl_fm failures. Push stopped status event from decoder
thread on EOF so the frontend auto-resets. Add frequency placeholder and
help text. Fix stop button silently swallowing errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 08:43:51 +00:00
Smittix 2ec458aa14 Fix Morse mode rejecting valid HF frequencies
validate_frequency() defaults to 24-1766 MHz (VHF/UHF range), but Morse/CW
operates on HF bands (0.5-30 MHz). Pass explicit min/max to allow HF frequencies.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 08:09:25 +00:00
Smittix 935b7a4d9d Fix weather satellite mode returning false success on SatDump startup failure
Add synchronous startup verification after Popen() — sleep 0.5s and poll
the process before returning to the caller. If SatDump exits immediately
(missing device, bad args), raise RuntimeError with the actual error
message instead of returning status: 'started'. Keep a shorter (2s) async
backup check for slower failures.

Also fix --source_id handling: omit the flag entirely when no serial number
is found instead of passing "0" which SatDump may reject. Change start()
and start_from_file() to return (bool, str|None) tuples so error messages
propagate through to the HTTP response.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 21:49:16 +00:00
Smittix ecdc060d81 Add HackRF support to TSCM RF scan and misc improvements
TSCM RF scan now auto-detects HackRF via SDRFactory and uses
hackrf_sweep as an alternative to rtl_power. Also includes
improvements to listening post, rtlamr, weather satellite,
SubGHz, Meshtastic, SSTV, WeFax, and process monitor modules.

Fixes #154

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 20:58:57 +00:00
Smittix ee9356c358 Add CW/Morse code decoder mode
New signal mode for decoding Morse code (CW) transmissions via SDR.
Includes route blueprint, utility decoder, frontend UI, and tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 20:58:48 +00:00
Smittix dbf76a4e84 Improve waterfall error handling and SDR tool path resolution
- Add pre-flight check for I/Q capture binary before spawning process
- Capture stderr from I/Q process for better error diagnostics
- Sync effective span value back to UI when backend adjusts it
- Use get_tool_path('rx_sdr') in Airspy, HackRF, LimeSDR, and SDRPlay
  command builders to support custom install locations

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 18:32:14 +00:00
Smittix 3f7430d114 Fix APRS stop/start not repopulating stations
- Make stopAprs() async and await backend stop completion before
  re-enabling the Start button, preventing race where a late stop
  request kills newly started processes
- Add cache-buster param to EventSource URL to prevent browser
  SSE connection reuse between stop/start cycles
- Capture aprs_active_device locally in stream_aprs_output so the
  old thread's finally block doesn't release a device claimed by
  a new session

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 18:31:10 +00:00
Smittix f3158cbb69 Add multi-SDR support to WeFax decoder (HackRF, LimeSDR, Airspy, SDRPlay)
Replace hardcoded rtl_fm with SDRFactory abstraction layer so WeFax works
with any supported SDR hardware, matching the pattern used by APRS and
other modes. RTL-SDR direct sampling flag preserved for HF reception.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 16:45:07 +00:00
Smittix 2d92243341 Harden APRS station plotting across payload variants 2026-02-25 10:19:22 +00:00
Smittix 2c76039f2c Fix ADS-B and VDL2 stop button handling 2026-02-25 10:05:16 +00:00
Smittix c4bde6c707 Fix APRS map ingestion and parser compatibility 2026-02-24 23:39:54 +00:00
Smittix 6384e39576 Fix GPS globe startup and satellite polling errors 2026-02-24 23:32:08 +00:00
Smittix 5edfe1797c wefax: auto-align carrier frequencies for usb tuning 2026-02-24 23:20:09 +00:00
Smittix 4bf452d462 Fix APRS parser for direwolf bracket-prefixed frames 2026-02-24 22:52:34 +00:00
Smittix f6b0edaf5a Harden GPS mode updates with callback reattach and status polling fallback 2026-02-24 22:50:17 +00:00
Smittix 6c20b3d23f Apply pending weather-sat and wefax updates 2026-02-24 21:46:58 +00:00
Smittix 53f54af871 Fix Python 3.9 startup crash in waterfall websocket 2026-02-24 21:02:03 +00:00
Smittix 0afa25e57c Fix weather sat 0dB SNR: increase sample rate to 2.4 MHz for Meteor LRPT
The default 1 MHz sample rate was too low for SatDump's meteor_m2-x_lrpt
pipeline, causing NOSYNC and 0.000dB SNR. Bumped to 2.4 MHz (SatDump
recommendation) and wired up the WEATHER_SAT_SAMPLE_RATE config value
so it actually gets passed to decoder.start() from both the auto-scheduler
and manual start route.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:27:08 +00:00
Smittix 085a6177f9 Add WeFax start button feedback and auto-capture scheduler
Fix silent failure when starting without station/frequency selected by
flashing amber on status text and dropdowns. Add auto-capture scheduler
that uses fixed UTC broadcast schedules from station data to
automatically start/stop WeFax decoding at broadcast times.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 13:28:53 +00:00
Smittix 01abcac8f2 Add WeFax (Weather Fax) decoder mode
Implement HF radiofax decoding with custom Python DSP pipeline
(rtl_fm USB → Goertzel/Hilbert demodulation), 33-station database
with broadcast schedules, audio waveform scope, live image preview,
and decoded image gallery. Amber/gold UI theme for HF distinction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 12:30:31 +00:00
Smittix 55c38522a4 Bind monitor audio stream to start request token 2026-02-24 09:15:24 +00:00
Smittix d9b528f3d3 Retry monitor audio starts after stale token responses 2026-02-24 09:04:51 +00:00
Smittix 9cd7f1c0c8 Snapshot audio tune config when spawning demod process 2026-02-24 08:55:32 +00:00
Smittix 975a95e1b0 Prevent stale monitor start requests from retuning audio 2026-02-23 23:56:21 +00:00
Smittix e81a409234 Stabilize monitor retune across waterfall click restarts 2026-02-23 23:39:50 +00:00
Smittix 739b0b136e Fix shared waterfall monitor tuning across in-span clicks 2026-02-23 23:14:37 +00:00
Smittix a5452fa1b1 fix: flush shared audio queue on VFO frequency change
The shared audio queue (maxsize reduced from 80 to 20) was not flushed
when the monitor frequency changed — only when the monitor was disabled.
This caused up to 4 seconds of stale old-frequency audio to play after
clicking to tune, making click-to-tune appear non-functional.

Now flushes the queue whenever the VFO frequency changes, so audio at
the new frequency begins within ~50ms (one FFT frame).
2026-02-23 22:42:41 +00:00
Smittix 0a4a0689a0 fix: zombie IQ process holds USB and stale WS handler clobbers shared state
Two root causes for the waterfall/monitor lockup when scrolling past the
2.4 MHz RTL-SDR span:

1. safe_terminate() sent SIGKILL but never called wait(), leaving a
   zombie process that kept the USB device handle open. The subsequent
   capture restart failed the USB probe and the monitor could not use
   the shared IQ path, falling back to a process-based monitor that
   stole the SDR from the waterfall.

2. When the frontend created a new WebSocket after a failure, the old
   handler's finally block called _set_shared_capture_state(running=False)
   which could race with the new handler's running=True, making the
   shared monitor path unavailable. Added a generation counter so only
   the owning handler can clear the shared state.
2026-02-23 21:59:03 +00:00