Commit Graph

1367 Commits

Author SHA1 Message Date
Smittix
c3dcf1401a Fix GSM Spy logger never configured - all log output was silenced
gsm_spy.py used logging.getLogger() directly which returns a bare
logger with no handler. The parent 'intercept' logger has
propagate=False, so all GSM Spy logs were silently dropped.

Now uses utils.logging.get_logger() which adds a stderr handler
and sets the log level, matching all other route modules.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 15:53:57 +00:00
Smittix
6f9873d47f Parse grgsm_scanner stderr output (GNU Radio outputs data to stderr)
grgsm_scanner (like many GNU Radio tools) writes scan results to
stderr, not stdout. The stderr reader was only logging at debug
level and discarding lines. Now feeds stderr into the parse queue.

Also added info-level logging for all scanner output lines to aid
debugging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 15:51:16 +00:00
Smittix
28185727e3 Fix grgsm_scanner output parser to match real output format
Parser expected pipe-delimited table rows but grgsm_scanner outputs
comma-separated key-value pairs like:
  ARFCN: 975, Freq: 925.2M, CID: 13522, LAC: 38722, MCC: 262, MNC: 1, Pwr: -58

This was the root cause of no data appearing in GSM Spy.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 15:48:57 +00:00
Smittix
48795f6ec3 Fix SDR device not released on GSM Spy stop
stop_scanner() cleared gsm_spy_active_device without calling
release_sdr_device(), so the device stayed claimed in the registry.
The scanner thread's finally block then saw None and skipped release.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 15:43:06 +00:00
Smittix
f5021a0fdf Fix GSM band name mismatch between UI and backend
UI was sending GSM900 but backend REGIONAL_BANDS expects EGSM900
for Europe and Asia regions, causing validation rejection.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 15:39:28 +00:00
Smittix
7312f330ed Add gr-gsm and tshark as auto-installed dependencies
GSM Spy was failing with FileNotFoundError because grgsm_scanner
wasn't installed. These tools are now installed automatically by
setup.sh (both Debian and macOS) and included in the Dockerfile,
matching how other tools like multimon-ng and ffmpeg are handled.

- setup.sh: Remove ask_yes_no prompts for gr-gsm and tshark, install
  unconditionally; add check_recommended tier for final summary
- Dockerfile: Add tshark to apt layer, add gr-gsm RUN layer with
  apt-then-source-build fallback, preseed debconf for tshark
- gsm_spy.py: Add shutil.which pre-check in start_scanner route,
  catch FileNotFoundError in scanner_thread to stop retry loop

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 15:35:15 +00:00
Smittix
2115bc551d Merge branch 'pr-124'
# Conflicts:
#	app.py
#	routes/__init__.py
#	utils/database.py
2026-02-08 15:04:17 +00:00
Smittix
f6c19af33a Fix PR #124 remaining issues: XSS, state management, DB regression
- kill_all() now resets gsm_spy_scanner_running and related state so
  the scanner thread stops after killall
- scanner_thread sets flag to False instead of None on exit
- Restore alert_rules, alert_events, recording_sessions tables and
  wifi_clients column removed by PR in database.py
- Escape all server-sourced values in analysis modals with escapeHtml()
- Reset gsm_towers_found/gsm_devices_tracked on stop to prevent
  counter drift across sessions
- Replace raw terminate/kill with safe_terminate() in scanner_thread

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 15:02:14 +00:00
Smittix
ebd9eb81f2 Add WATERFALL title label to function bar
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 14:30:39 +00:00
Smittix
c87c01cdfe Load function-strip.css so waterfall bar renders horizontally
The function-strip CSS was never linked in index.html, causing all
strip items to render as unstyled stacked elements instead of a
horizontal flex bar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 14:29:09 +00:00
Smittix
19a94d4a84 Move waterfall controls to function bar and fix SDR claim race on tune
Move waterfall controls from the sidebar into a function-strip bar inside
#listeningPostVisuals so they sit directly above the waterfall canvas.
Also fix the "SDR device in use" error when clicking a waterfall frequency
to listen — the WebSocket waterfall's device claim wasn't being released
before the audio start request because the backend cleanup hadn't finished.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 14:25:36 +00:00
Smittix
cca04918a9 Fix waterfall crash on zoom by reusing WebSocket and adding USB release retry
Zooming caused "I/Q capture process exited immediately" because the client
closed the WebSocket and opened a new one, racing with the old rtl_sdr
process releasing the USB device. Now zoom/retune sends a start command on
the existing WebSocket, and the server adds a USB release delay plus retry
loop when restarting capture within the same connection.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 14:00:40 +00:00
Smittix
777b83f6e0 Fix waterfall showing solid yellow by auto-scaling FFT quantization
The FFT pipeline produces power values in the ~0-60 dB range for
normalized IQ data, but quantize_to_uint8 used a hardcoded range
of -90 to -20 dB. Every bin saturated to 255, producing a uniform
yellow waterfall with no signal differentiation.

Now auto-scales to the actual min/max of each frame so the full
colour palette is always used.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 13:45:07 +00:00
Smittix
455bc05c69 Shut down WebSocket socket to prevent Werkzeug HTTP response leak
After a WebSocket handler exits, flask-sock returns a Response to
Werkzeug which writes "HTTP/1.1 200 OK..." on the still-open socket.
Browsers see these HTTP bytes as a malformed WebSocket frame, causing
"Invalid frame header".

Now the handler explicitly closes the raw TCP socket after the
WebSocket close handshake, so Werkzeug's write harmlessly fails.
Applied to both waterfall and audio WebSocket handlers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 13:40:17 +00:00
Smittix
37842dc1ef Fix WebSocket handler exiting immediately on receive timeout
simple-websocket 1.1.0's receive(timeout=N) returns None on timeout
instead of raising TimeoutError. The handler treated None as
"connection closed" and broke out of the loop, causing Werkzeug to
write its HTTP 200 response on the still-open WebSocket socket.
The browser saw those HTTP bytes as an invalid WebSocket frame.

Now checks ws.connected to distinguish timeout (None + connected)
from actual close (None + not connected).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 13:21:25 +00:00
Smittix
01f3cc845b Add missing /sensor/status and /tscm/status endpoints
agents.js syncLocalModeStates() expects these endpoints to check
whether each mode is running locally. Both were missing, causing
404 errors on mode switch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 13:14:27 +00:00
Marc
bdba56bef1 PR #124 fixed major and minor issues 2026-02-08 07:04:10 -06:00
Smittix
a5ea632cc2 Fix WebSocket waterfall blocked by login redirect
The before_request require_login hook was returning a 302 redirect
for WebSocket upgrade requests, which browsers report as "Invalid
frame header". WebSocket requests don't always carry session cookies
reliably. Allow /ws/ paths through the login check since the page
that initiates these connections already requires authentication.

Also keeps the prior fix: serialize WebSocket sends through a queue
to avoid concurrent read/write on the non-thread-safe simple-websocket.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 13:03:34 +00:00
Smittix
a3b81bead8 Fix WebSocket waterfall "Invalid frame header" by serializing sends
The fft_reader thread was calling ws.send() concurrently with
ws.receive() in the main loop. simple-websocket is not thread-safe
for simultaneous read/write, corrupting frame headers. Now the reader
thread enqueues frames and only the main loop touches the WebSocket.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 12:52:42 +00:00
Smittix
026337a350 Add real-time WebSocket waterfall with I/Q capture and server-side FFT
Replace the batch rtl_power SSE pipeline with continuous I/Q streaming
via WebSocket for smooth ~25fps waterfall display. The server captures
raw I/Q samples (rtl_sdr/rx_sdr), computes Hann-windowed FFT, and
sends compact binary frames (1035 bytes vs ~15KB JSON, 93% reduction).
Client falls back to existing SSE path if WebSocket is unavailable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 12:37:50 +00:00
Marc
44b1a74838 Fixes regarding for PR #124, also added vector images for towers and phones 2026-02-08 03:23:23 -06:00
Smittix
7aae2944d4 Add waterfall modulation auto-select and fix kill-all message
Waterfall clicks now auto-select the correct modulation for the frequency
band (e.g., WFM for FM broadcast, AM for airband) instead of using whatever
modulation was last selected. Adds a hover tooltip showing frequency and
suggested modulation. Fixes the kill-all notification to show a clean
"All processes stopped" message instead of listing "bluetooth_scanner".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 00:41:18 +00:00
Smittix
766a51753d Add real-time signal scope to both SSTV modes
Adds a phosphor-persistence waveform scope showing audio RMS/peak
levels during ISS SSTV and General SSTV decoding, matching the
existing pager scope pattern with a purple color scheme.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 00:28:33 +00:00
Smittix
92e5e7c6da Add real-time signal scope to 433MHz sensor mode
Enable -M level on rtl_433 to include RSSI/SNR in decoded JSON, extract
signal levels and push scope events to the SSE stream. Renders a green-
themed canvas oscilloscope showing signal strength pulses on packet decode
with amber SNR indicator and decay between packets.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 00:00:01 +00:00
Smittix
154dc898ff Add real-time signal scope to pager mode
Tap the rtl_fm → multimon-ng audio pipeline via a relay thread to extract
RMS/peak amplitude levels and render a 60fps canvas oscilloscope during
pager decoding, giving visual feedback of RF activity before messages are
fully decoded.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 23:50:41 +00:00
Smittix
beb38b6b98 Remove waterfall from all modes except listening post
Reverts IQ pipeline and removes syncWaterfallToFrequency calls from
pager, sensor, rtlamr, DMR, SSTV, and SSTV general modes. Waterfall
is now exclusive to listening post mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 23:29:56 +00:00
Smittix
f04ba7f143 Add live waterfall during pager and sensor decoding via IQ pipeline
Replace rtl_fm/rtl_433 with rtl_sdr for raw IQ capture when available,
enabling a Python IQ processor to compute FFT for the waterfall while
simultaneously feeding decoded data to multimon-ng (pager) or rtl_433
(sensor). Falls back to the legacy pipeline when rtl_sdr is unavailable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 23:18:43 +00:00
Mitch Ross
fd0953bfb5 up 2026-02-07 17:56:45 -05:00
Smittix
b312eb20aa Resume waterfall after listen and sync to mode frequency 2026-02-07 22:40:00 +00:00
Smittix
8eb8a2fe97 Fix waterfall resume and add zoom controls 2026-02-07 22:13:50 +00:00
Mitch Ross
13be4302c3 Update index.html 2026-02-07 16:07:12 -05:00
Mitch Ross
5fd45d3e94 Merge remote-tracking branch 'upstream/main' 2026-02-07 16:03:32 -05:00
Smittix
e88b815dc9 Add shared waterfall UI across SDR modes 2026-02-07 16:01:01 -05:00
Mitch Ross
556a4ffcc2 tweaks
1. utils/weather_sat.py — Added delete_all_images() method that globs for *.png, *.jpg, *.jpeg in the output dir, unlinks each, clears _images list, and returns the
  count.
  2. routes/weather_sat.py — Added DELETE /weather-sat/images route that calls decoder.delete_all_images() and returns {'status': 'ok', 'deleted': count}.
  3. static/js/modes/weather-satellite.js:
    - Added currentModalFilename state variable
    - renderGallery() now sorts images by timestamp descending, groups by date using toLocaleDateString(), renders date headers spanning the grid, and adds a delete
  overlay button on each card
    - showImage() accepts a filename param, stores it in currentModalFilename, and creates a modal toolbar with a delete button
    - Added deleteImage(filename) — confirm dialog → DELETE /weather-sat/images/{filename} → filter from array → re-render + close modal
    - Added deleteAllImages() — confirm dialog → DELETE /weather-sat/images → clear array → re-render
    - Exposed deleteImage, deleteAllImages, and _getModalFilename in public API
  4. static/css/modes/weather-satellite.css:
    - Added position: relative to .wxsat-image-card
    - .wxsat-image-actions — absolute top-right overlay, hidden by default, appears on card hover
    - .wxsat-image-actions button — dark background, turns red on hover
    - .wxsat-date-header — full-grid-width date separator with dimmed uppercase text
    - .wxsat-modal-toolbar — absolute top-left in modal for the delete button
    - .wxsat-modal-btn.delete — turns red on hover
    - .wxsat-gallery-clear-btn — subtle icon button, pushed right via margin-left: auto, turns red on hover
    - Updated .wxsat-gallery-header from justify-content: space-between to gap: 8px for proper 3-child layout
  5. templates/index.html — Added clear-all trash button with SVG icon in the gallery header, wired to WeatherSat.deleteAllImages().
2026-02-07 15:52:52 -05:00
Mitch Ross
03c5d33eb7 Fix race condition: set _running before starting reader thread
The reader thread loop checks self._running but it was being set to
True after _start_satdump() returned, which is after the thread
already started. The thread would see _running=False and exit
immediately without reading any SatDump output.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 15:28:07 -05:00
Mitch Ross
f9786aa75a Use PTY for SatDump output capture instead of pipe
SatDump writes to stderr via fwrite() with its custom logger. When
stderr is redirected to a pipe, C runtime fully buffers it. Neither
stdbuf nor bufsize settings help since SatDump doesn't use stdio for
output.

PTY (pseudo-terminal) makes SatDump think it's writing to a real
terminal, which disables buffering. Also strips ANSI escape codes
from the output and properly handles \r progress lines.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 15:17:03 -05:00
Mitch Ross
b87623cf66 Update weather_sat.py 2026-02-07 15:06:58 -05:00
Mitch Ross
4d24e648ab Update weather_sat.py 2026-02-07 15:04:53 -05:00
Mitch Ross
99f42f66b2 Merge upstream main: add DMR, WebSDR, HF SSTV, alerts, recordings, waterfall
Merges upstream changes into fork while preserving weather satellite
(NOAA APT/Meteor LRPT via SatDump), rtlamr, multi-arch build, and
decoder console features from our branch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 14:29:09 -05:00
Smittix
3240b0788b Add shared waterfall UI across SDR modes 2026-02-07 19:18:57 +00:00
Smittix
3ab1501a90 Clamp waterfall interval to server minimum 2026-02-07 19:08:28 +00:00
Smittix
7e42e00449 Fix waterfall stop before direct listen 2026-02-07 19:06:06 +00:00
Smittix
51ea558e19 Allow listening with waterfall and speed up updates 2026-02-07 18:49:48 +00:00
Smittix
75bd3228e5 Improve waterfall rendering and add click-to-tune 2026-02-07 18:36:14 +00:00
Smittix
86e4ba7e29 Add alerts/recording, WiFi/TSCM updates, optimize waterfall 2026-02-07 18:29:58 +00:00
Smittix
4bbc00b765 Improve TSCM detection and include WiFi clients 2026-02-07 17:31:17 +00:00
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
cdfc10c854 Make Postgres data path configurable for ADS-B history
Allow users to override the pgdata volume mount via PGDATA_PATH env var,
enabling external storage (e.g. USB) for ADS-B history. Defaults to
./pgdata for backwards compatibility.

Based on PR #88 by JamesIOmete, rebased cleanly onto main.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 15:35:32 +00:00
Smittix
adb472956e Merge pull request #126 from suidroot/add_airspy_docker
Add Soapy Airspy package and airspy pages to Dockerfile
2026-02-07 15:31:08 +00:00
Smittix
60d3cff5e7 Fix SDR device lock-up from unreleased device registry on process crash
Stream threads for sensor, pager, acars, rtlamr, dmr, and dsc modes
never called release_sdr_device() when their SDR process crashed,
leaving devices permanently locked in the registry. Also fixes orphaned
companion processes (rtl_fm, rtl_tcp) not being killed on crash, start
path failures leaking processes, DMR stop handler missing lock, and
listening post/audio websocket pkill nuking all system-wide rtl_fm
processes. Wires up register_process()/unregister_process() so the
atexit/signal cleanup safety net actually works, and adds rtl_tcp,
rtl_power, rtlamr, ffmpeg to the killall endpoint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 15:18:15 +00:00