diff --git a/CHANGELOG.md b/CHANGELOG.md index 253ee03..0ed30ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,36 +1,77 @@ # Changelog -All notable changes to iNTERCEPT will be documented in this file. - -## [2.21.1] - 2026-02-20 - -### Fixed -- BT Locate map first-load rendering race that could cause blank/late map initialization -- BT Locate mode switch timing so Leaflet invalidation runs after panel visibility settles -- BT Locate trail restore startup latency by batching historical GPS point rendering - ---- - -## [2.21.0] - 2026-02-20 - -### Added -- Analytics panels for operational insights and temporal pattern analysis - -### Changed -- Global map theme refresh with improved contrast and cross-dashboard consistency -- Cross-app UX refinements for accessibility, mode consistency, and render performance -- BT Locate enhancements including improved continuity, smoothing, and confidence reporting - -### Fixed -- Weather satellite auto-scheduler and Mercator tracking reliability issues -- Bluetooth/WiFi runtime health issues affecting scanner continuity -- ADS-B SSE multi-client fanout stability and remote VDL2 streaming reliability - ---- - -## [2.15.0] - 2026-02-09 - -### Added +All notable changes to iNTERCEPT will be documented in this file. + +## [2.22.0] - 2026-02-23 + +### Added +- **Waterfall Receiver Overhaul** - WebSocket-based I/Q streaming with server-side FFT, click-to-tune, zoom controls, and auto-scaling +- **Voice Alerts** - Configurable text-to-speech event notifications across modes +- **Signal Fingerprinting** - RF device identification and pattern analysis mode +- **RF Heatmap** - Geographic signal density visualization with Leaflet heatmap overlay +- **SignalID** - Automatic signal classification via SigIDWiki API integration +- **PWA Support** - Installable web app with service worker caching and manifest +- **Real-time Signal Scope** - Live signal visualization for pager, sensor, and SSTV modes +- **ADS-B MSG2 Surface Parsing** - Ground vehicle movement tracking from MSG2 frames +- **Cheat Sheets** - Quick reference overlays for keyboard shortcuts and mode controls +- App icon (SVG) for PWA and browser tab + +### Changed +- **WebSDR overhaul** - Improved receiver management, audio streaming, and UI +- **Mode stop responsiveness** - Faster timeout handling and improved WiFi/Bluetooth scanner shutdown +- **Mode transitions** - Smoother navigation with performance instrumentation +- **BT Locate** - Refactored JS engine with improved trail management and signal smoothing +- **Listening Post** - Refactored with cross-module frequency routing +- **SSTV decoder** - State machine improvements and partial image streaming +- Analytics mode removed; per-mode analytics panels integrated into existing dashboards + +### Fixed +- ADS-B SSE multi-client fanout stability and update flush timing +- WiFi scanner robustness and monitor mode teardown reliability +- Agent client reliability improvements for remote sensor nodes +- SSTV VIS detector state reporting in signal monitor diagnostics + +### Documentation +- Complete documentation audit across README, FEATURES, USAGE, help modal, and GitHub Pages +- Fixed license badge (MIT → Apache 2.0) to match actual LICENSE file +- Fixed tool name `rtl_amr` → `rtlamr` throughout all docs +- Fixed incorrect entry point examples (`python app.py` → `sudo -E venv/bin/python intercept.py`) +- Removed duplicate AIS Vessel Tracking section from FEATURES.md +- Updated SSTV requirements: pure Python decoder, no external `slowrx` needed +- Added ACARS and VDL2 mode descriptions to in-app help modal +- GitHub Pages site: corrected Docker command, license, and tool name references + +--- + +## [2.21.1] - 2026-02-20 + +### Fixed +- BT Locate map first-load rendering race that could cause blank/late map initialization +- BT Locate mode switch timing so Leaflet invalidation runs after panel visibility settles +- BT Locate trail restore startup latency by batching historical GPS point rendering + +--- + +## [2.21.0] - 2026-02-20 + +### Added +- Analytics panels for operational insights and temporal pattern analysis + +### Changed +- Global map theme refresh with improved contrast and cross-dashboard consistency +- Cross-app UX refinements for accessibility, mode consistency, and render performance +- BT Locate enhancements including improved continuity, smoothing, and confidence reporting + +### Fixed +- Weather satellite auto-scheduler and Mercator tracking reliability issues +- Bluetooth/WiFi runtime health issues affecting scanner continuity +- ADS-B SSE multi-client fanout stability and remote VDL2 streaming reliability + +--- + +## [2.15.0] - 2026-02-09 + +### Added - **Real-time WebSocket Waterfall** - I/Q capture with server-side FFT - Click-to-tune, zoom controls, and auto-scaling quantization - Shared waterfall UI across SDR modes with function bar controls diff --git a/Dockerfile b/Dockerfile index fb48ca8..c6045db 100644 --- a/Dockerfile +++ b/Dockerfile @@ -57,7 +57,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ soapysdr-module-airspy \ airspy \ limesuite \ - hackrf \ # Utilities curl \ procps \ @@ -190,6 +189,17 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ fi \ && cd /tmp \ && rm -rf /tmp/SatDump \ + # Build hackrf CLI tools from source — avoids libhackrf0 version conflict + # between the 'hackrf' apt package and soapysdr-module-hackrf's newer libhackrf0 + && cd /tmp \ + && git clone --depth 1 https://github.com/greatscottgadgets/hackrf.git \ + && cd hackrf/host \ + && mkdir build && cd build \ + && cmake .. \ + && make \ + && make install \ + && ldconfig \ + && rm -rf /tmp/hackrf \ # Build rtlamr (utility meter decoder - requires Go) && cd /tmp \ && curl -fsSL "https://go.dev/dl/go1.22.5.linux-$(dpkg --print-architecture).tar.gz" | tar -C /usr/local -xz \ diff --git a/README.md b/README.md index ed677d9..b4d27b6 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

Python 3.9+ - MIT License + Apache 2.0 License Platform

@@ -40,7 +40,7 @@ Support the developer of this open-source project - **HF SSTV** - Terrestrial SSTV on shortwave frequencies (80m-10m, VHF, UHF) - **APRS** - Amateur packet radio position reports and telemetry via direwolf - **Satellite Tracking** - Pass prediction with polar plot and ground track map -- **Utility Meters** - Electric, gas, and water meter reading via rtl_amr +- **Utility Meters** - Electric, gas, and water meter reading via rtlamr - **ADS-B History** - Persistent aircraft history with reporting dashboard (Postgres optional) - **WiFi Scanning** - Monitor mode reconnaissance via aircrack-ng - **Bluetooth Scanning** - Device discovery and tracker detection (with Ubertooth support) @@ -57,8 +57,6 @@ Support the developer of this open-source project ## Installation / Debian / Ubuntu / MacOS -``` - **1. Clone and run:** ```bash git clone https://github.com/smittix/intercept.git @@ -150,7 +148,7 @@ Set these as environment variables for either local installs or Docker: ```bash INTERCEPT_ADSB_AUTO_START=true \ INTERCEPT_SHARED_OBSERVER_LOCATION=false \ -python app.py +sudo -E venv/bin/python intercept.py ``` **Docker example (.env)** @@ -172,7 +170,7 @@ Then open **/adsb/history** for the reporting dashboard. After starting, open **http://localhost:5050** in your browser. The username and password is admin:admin -The credentials can be change in the ADMIN_USERNAME & ADMIN_PASSWORD variables in config.py +The credentials can be changed in the ADMIN_USERNAME & ADMIN_PASSWORD variables in config.py --- @@ -245,7 +243,7 @@ Created by **smittix** - [GitHub](https://github.com/smittix) [AIS-catcher](https://github.com/jvde-github/AIS-catcher) | [acarsdec](https://github.com/TLeconte/acarsdec) | [direwolf](https://github.com/wb2osz/direwolf) | -[rtl_amr](https://github.com/bemasher/rtlamr) | +[rtlamr](https://github.com/bemasher/rtlamr) | [dumpvdl2](https://github.com/szpajder/dumpvdl2) | [aircrack-ng](https://www.aircrack-ng.org/) | [Leaflet.js](https://leafletjs.com/) | diff --git a/config.py b/config.py index 6b94432..b03efe5 100644 --- a/config.py +++ b/config.py @@ -6,35 +6,54 @@ import logging import os import sys -# Application version -VERSION = "2.21.1" - -# Changelog - latest release notes (shown on welcome screen) -CHANGELOG = [ - { - "version": "2.21.1", - "date": "February 2026", - "highlights": [ - "BT Locate map first-load fix with render stabilization retries during initial mode open", - "BT Locate trail restore optimization for faster startup when historical GPS points exist", - "BT Locate mode-switch map invalidation timing fix to prevent delayed/blank map render", - ] - }, - { - "version": "2.21.0", - "date": "February 2026", - "highlights": [ - "Global map theme refresh with improved contrast and cross-dashboard consistency", - "Cross-app UX updates for accessibility, mode consistency, and render performance", - "Weather satellite reliability fixes for auto-scheduler and Mercator pass tracking", - "Bluetooth/WiFi runtime health fixes with BT Locate continuity and confidence improvements", - "ADS-B/VDL2 streaming reliability upgrades for multi-client SSE fanout and remote decoding", - "Analytics enhancements with operational insights and temporal pattern panels", - ] - }, - { - "version": "2.20.0", - "date": "February 2026", +# Application version +VERSION = "2.22.0" + +# Changelog - latest release notes (shown on welcome screen) +CHANGELOG = [ + { + "version": "2.22.0", + "date": "February 2026", + "highlights": [ + "Waterfall receiver overhaul: WebSocket I/Q streaming with server-side FFT, click-to-tune, and zoom controls", + "Voice alerts for configurable event notifications across modes", + "Signal fingerprinting mode for RF device identification and pattern analysis", + "RF Heatmap for geographic signal density visualization", + "SignalID integration via SigIDWiki API for automatic signal classification", + "PWA support: installable web app with service worker and manifest", + "Mode stop responsiveness improvements with faster timeout handling", + "Navigation performance instrumentation and smoother mode transitions", + "Pager, sensor, and SSTV real-time signal scope visualization", + "ADS-B MSG2 surface movement parsing for ground vehicle tracking", + "WebSDR major overhaul with improved receiver management and audio streaming", + "Documentation audit: fixed license, tool names, entry points, and SSTV decoder references", + "Help modal updated with ACARS and VDL2 mode descriptions", + ] + }, + { + "version": "2.21.1", + "date": "February 2026", + "highlights": [ + "BT Locate map first-load fix with render stabilization retries during initial mode open", + "BT Locate trail restore optimization for faster startup when historical GPS points exist", + "BT Locate mode-switch map invalidation timing fix to prevent delayed/blank map render", + ] + }, + { + "version": "2.21.0", + "date": "February 2026", + "highlights": [ + "Global map theme refresh with improved contrast and cross-dashboard consistency", + "Cross-app UX updates for accessibility, mode consistency, and render performance", + "Weather satellite reliability fixes for auto-scheduler and Mercator pass tracking", + "Bluetooth/WiFi runtime health fixes with BT Locate continuity and confidence improvements", + "ADS-B/VDL2 streaming reliability upgrades for multi-client SSE fanout and remote decoding", + "Analytics enhancements with operational insights and temporal pattern panels", + ] + }, + { + "version": "2.20.0", + "date": "February 2026", "highlights": [ "Space Weather mode: real-time solar and geomagnetic monitoring from NOAA SWPC, NASA SDO, and HamQSL", "Kp index, solar wind, X-ray flux charts with Chart.js visualization", @@ -99,14 +118,14 @@ CHANGELOG = [ "Pure Python SSTV decoder replacing broken slowrx dependency", "Real-time signal scope for pager, sensor, and SSTV modes", "USB-level device probe to prevent cryptic rtl_fm crashes", - "SDR device lock-up fix from unreleased device registry on crash", + "SDR device lock-up fix from unreleased device registry on crash", ] }, { "version": "2.14.0", "date": "February 2026", "highlights": [ - "HF SSTV general mode with predefined shortwave frequencies", + "HF SSTV general mode with predefined shortwave frequencies", "WebSDR integration for remote HF/shortwave listening", "Listening Post signal scanner and audio pipeline improvements", "TSCM sweep resilience, WiFi detection, and correlation fixes", diff --git a/docs/FEATURES.md b/docs/FEATURES.md index 8d57ef9..73a2909 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -24,17 +24,6 @@ Complete feature list for all modules. - **Wideband spectrum analysis** with real-time visualization - **I/Q capture** - record raw samples for offline analysis -## AIS Vessel Tracking - -- **Real-time vessel tracking** via AIS-catcher on 161.975/162.025 MHz -- **Full-screen dashboard** - dedicated popout with interactive map -- **Interactive Leaflet map** with OpenStreetMap tiles (dark-themed) -- **Vessel details popup** - name, MMSI, callsign, destination, ETA -- **Navigation data** - speed, course, heading, rate of turn -- **Ship type classification** - cargo, tanker, passenger, fishing, etc. -- **Vessel dimensions** - length, width, draught -- **Multi-SDR support** - RTL-SDR, HackRF, LimeSDR, Airspy, SDRplay - ## Spy Stations (Number Stations) - **Comprehensive database** of active number stations and diplomatic networks diff --git a/docs/USAGE.md b/docs/USAGE.md index 8f15fd7..37774ad 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -172,7 +172,7 @@ Set the following environment variables (Docker recommended): ```bash INTERCEPT_ADSB_AUTO_START=true \ INTERCEPT_SHARED_OBSERVER_LOCATION=false \ -python app.py +sudo -E venv/bin/python intercept.py ``` **Docker example (.env)** diff --git a/docs/index.html b/docs/index.html index 7e0a7ac..a2bbc56 100644 --- a/docs/index.html +++ b/docs/index.html @@ -110,7 +110,7 @@

Utility Meters

-

Smart meter monitoring via rtl_amr. Receive electric, gas, and water meter broadcasts in real time.

+

Smart meter monitoring via rtlamr. Receive electric, gas, and water meter broadcasts in real time.

@@ -321,7 +321,7 @@ sudo -E venv/bin/python intercept.py
git clone https://github.com/smittix/intercept.git
 cd intercept
-docker compose up -d
+docker compose --profile basic up -d --build

Requires privileged mode for USB SDR access

@@ -422,7 +422,7 @@ docker compose up -d diff --git a/static/css/modes/bt_locate.css b/static/css/modes/bt_locate.css index d83a15b..236cca6 100644 --- a/static/css/modes/bt_locate.css +++ b/static/css/modes/bt_locate.css @@ -560,3 +560,69 @@ font-size: 9px; } } + +/* ── Crosshair sweep animation ───────────────────────────────────── */ +.btl-crosshair-overlay { + position: absolute; + inset: 0; + pointer-events: none; + overflow: hidden; + z-index: 1200; + --btl-crosshair-x-start: 100%; + --btl-crosshair-y-start: 100%; + --btl-crosshair-x-end: 50%; + --btl-crosshair-y-end: 50%; + --btl-crosshair-duration: 1500ms; +} + +.btl-crosshair-line { + position: absolute; + opacity: 0; + background: var(--accent-cyan); + will-change: transform, opacity; +} + +.btl-crosshair-vertical { + top: 0; + bottom: 0; + width: 1px; + left: 0; + transform: translateX(var(--btl-crosshair-x-start)); +} + +.btl-crosshair-horizontal { + left: 0; + right: 0; + height: 1px; + top: 0; + transform: translateY(var(--btl-crosshair-y-start)); +} + +.btl-crosshair-overlay.active .btl-crosshair-vertical { + animation: btlCrosshairSweepX var(--btl-crosshair-duration) cubic-bezier(0.2, 0.85, 0.28, 1) forwards; +} + +.btl-crosshair-overlay.active .btl-crosshair-horizontal { + animation: btlCrosshairSweepY var(--btl-crosshair-duration) cubic-bezier(0.2, 0.85, 0.28, 1) forwards; +} + +@keyframes btlCrosshairSweepX { + 0% { transform: translateX(var(--btl-crosshair-x-start)); opacity: 0; } + 12% { opacity: 1; } + 85% { opacity: 1; } + 100% { transform: translateX(var(--btl-crosshair-x-end)); opacity: 0; } +} + +@keyframes btlCrosshairSweepY { + 0% { transform: translateY(var(--btl-crosshair-y-start)); opacity: 0; } + 12% { opacity: 1; } + 85% { opacity: 1; } + 100% { transform: translateY(var(--btl-crosshair-y-end)); opacity: 0; } +} + +@media (prefers-reduced-motion: reduce) { + .btl-crosshair-overlay.active .btl-crosshair-vertical, + .btl-crosshair-overlay.active .btl-crosshair-horizontal { + animation-duration: 220ms; + } +} diff --git a/static/js/core/keyboard-shortcuts.js b/static/js/core/keyboard-shortcuts.js index 1028687..6bebdd2 100644 --- a/static/js/core/keyboard-shortcuts.js +++ b/static/js/core/keyboard-shortcuts.js @@ -8,17 +8,17 @@ const KeyboardShortcuts = (function () { function _handle(e) { if (e.target.matches(GUARD_SELECTOR)) return; - if (e.altKey) { - switch (e.key.toLowerCase()) { - case 'w': e.preventDefault(); window.switchMode && switchMode('waterfall'); break; - case 'm': e.preventDefault(); window.VoiceAlerts && VoiceAlerts.toggleMute(); break; - case 's': e.preventDefault(); _toggleSidebar(); break; - case 'k': e.preventDefault(); showHelp(); break; - case 'c': e.preventDefault(); window.CheatSheets && CheatSheets.showForCurrentMode(); break; + if (e.altKey) { + switch (e.code) { + case 'KeyW': e.preventDefault(); window.switchMode && switchMode('waterfall'); break; + case 'KeyM': e.preventDefault(); window.VoiceAlerts && VoiceAlerts.toggleMute(); break; + case 'KeyS': e.preventDefault(); _toggleSidebar(); break; + case 'KeyK': e.preventDefault(); showHelp(); break; + case 'KeyC': e.preventDefault(); window.CheatSheets && CheatSheets.showForCurrentMode(); break; default: - if (e.key >= '1' && e.key <= '9') { + if (e.code >= 'Digit1' && e.code <= 'Digit9') { e.preventDefault(); - _switchToNthMode(parseInt(e.key) - 1); + _switchToNthMode(parseInt(e.code.replace('Digit', '')) - 1); } } } else if (!e.ctrlKey && !e.metaKey) { diff --git a/static/js/modes/bt_locate.js b/static/js/modes/bt_locate.js index 59246be..7187c45 100644 --- a/static/js/modes/bt_locate.js +++ b/static/js/modes/bt_locate.js @@ -44,6 +44,7 @@ const BtLocate = (function() { let queuedDetectionTimer = null; let lastDetectionRenderAt = 0; let startRequestInFlight = false; + let crosshairResetTimer = null; const MAX_HEAT_POINTS = 1200; const MAX_TRAIL_POINTS = 1200; @@ -349,19 +350,18 @@ const BtLocate = (function() { } function stop() { + // Update UI immediately — don't wait for the backend response. + if (queuedDetectionTimer) { + clearTimeout(queuedDetectionTimer); + queuedDetectionTimer = null; + } + queuedDetection = null; + queuedDetectionOptions = null; + showIdleUI(); + disconnectSSE(); + stopAudio(); + // Notify backend asynchronously. fetch('/bt_locate/stop', { method: 'POST' }) - .then(r => r.json()) - .then(() => { - if (queuedDetectionTimer) { - clearTimeout(queuedDetectionTimer); - queuedDetectionTimer = null; - } - queuedDetection = null; - queuedDetectionOptions = null; - showIdleUI(); - disconnectSSE(); - stopAudio(); - }) .catch(err => console.error('[BtLocate] Stop error:', err)); } @@ -703,6 +703,32 @@ const BtLocate = (function() { if (gpsCountEl) gpsCountEl.textContent = gpsPoints || 0; } + function triggerCrosshairAnimation(lat, lon) { + if (!map) return; + const overlay = document.getElementById('btLocateCrosshairOverlay'); + if (!overlay) return; + const size = map.getSize(); + const point = map.latLngToContainerPoint([lat, lon]); + const targetX = Math.max(0, Math.min(size.x, point.x)); + const targetY = Math.max(0, Math.min(size.y, point.y)); + const startX = size.x + 8; + const startY = size.y + 8; + const duration = 1500; + overlay.style.setProperty('--btl-crosshair-x-start', `${startX}px`); + overlay.style.setProperty('--btl-crosshair-y-start', `${startY}px`); + overlay.style.setProperty('--btl-crosshair-x-end', `${targetX}px`); + overlay.style.setProperty('--btl-crosshair-y-end', `${targetY}px`); + overlay.style.setProperty('--btl-crosshair-duration', `${duration}ms`); + overlay.classList.remove('active'); + void overlay.offsetWidth; + overlay.classList.add('active'); + if (crosshairResetTimer) clearTimeout(crosshairResetTimer); + crosshairResetTimer = setTimeout(() => { + overlay.classList.remove('active'); + crosshairResetTimer = null; + }, duration + 100); + } + function addMapMarker(point, options = {}) { if (!map || point.lat == null || point.lon == null) return false; const lat = Number(point.lat); @@ -737,6 +763,7 @@ const BtLocate = (function() { 'Time: ' + formatPointTimestamp(trailPoint.timestamp) + '' ); + marker.on('click', () => triggerCrosshairAnimation(lat, lon)); trailPoints.push(trailPoint); mapMarkers.push(marker); diff --git a/templates/index.html b/templates/index.html index 8b27a9e..f3415b4 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1831,6 +1831,10 @@
+