Moves the Selected Device panel to be the first element in the
WiFi visualizations grid so it's visible without scrolling.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add new panel to display aircraft photos when selected
- Fetch photos from planespotters API via /adsb/aircraft-photo endpoint
- Cache photos to avoid repeated API calls
- Show loading, no photo, and placeholder states appropriately
- Reduced map panel to span 2 to accommodate new image panel
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Selected Device panel showing detailed info for networks/clients
- Make network cards clickable to view details
- Make probe analysis client entries clickable
- Fix signal strength to show "N/A" when airodump returns -1
- Add visual signal meter and action buttons to selected device panel
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Hide waterfall and output panels in aircraft mode (use dedicated visualization)
- Add aircraft list panel with clickable aircraft selection
- Add selected aircraft info panel showing altitude, speed, heading, squawk
- Add "Open Full Dashboard" button linking to dedicated aircraft radar
- Add debugging console logs and alert messages to WiFi scan function
- Better error feedback when WiFi interface not selected or scan fails
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Added "Select Device" label to WiFi adapter dropdown
- Better error handling with user notifications when interfaces fail to load
- Shows loading state while detecting interfaces
- Clearer notification messages for found/missing interfaces
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Auto-enable monitor mode when clicking Start Scanning (no manual step needed)
- Improved WiFi interface detection using airmon-ng for chipset info
- Added lsusb fallback for USB adapter identification
- Fixed interface display format in enableMonitorMode callback
- Better error handling and status notifications during scan startup
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- WiFi interfaces now show driver, chipset, and MAC address for easier identification
- Remove signal history feature from WiFi and Bluetooth sections (HTML, JS, CSS, API)
- Fix Listen button in Listening Post signal hits to properly tune to frequency
- Make stopAudio() async and improve tuneToFrequency() with proper awaits
- Fix Device Intelligence panel auto-expand and manufacturer display
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- New panel shows full device details when clicked
- Displays name, type, RSSI with signal bars, MAC, manufacturer
- Shows tracker/FindMy badges for detected trackers
- Buttons to enumerate services and copy MAC address
- Reorganized BT visualization layout
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Added clickable device list panel sorted by signal strength
- Added dedicated tracker detection panel for AirTags/Tiles
- Clicking a device selects it for signal tracking and targeting
- Devices show name, MAC, RSSI with color-coded signal strength
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Backend route to proxy photo requests from Planespotters API
- Frontend displays photo in Selected Target panel when available
- Photos are cached to avoid repeated API calls
- Clicking photo links to full image on Planespotters.net
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add ability to filter out unwanted pager messages from display:
- Hide "Tone Only" messages by default (toggle in UI)
- Custom keyword filter (comma-separated list)
- Filtered messages are still logged and counted, just hidden from view
- Filter settings persist in localStorage
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove direct serial GPS dongle support in favor of gpsd daemon connectivity.
The UI now auto-connects to gpsd on page load and shows a GPS indicator when connected.
Simplify ADS-B dashboard controls bar for a cleaner, more compact layout.
Add setup-dev.sh for streamlined development environment setup.
- Remove GPSReader class and NMEA parsing (utils/gps.py)
- Consolidate to GPSDClient only with auto-connect endpoint
- Add GPS indicator with pulsing dot animation
- Compact controls bar with smaller fonts and tighter spacing
- Add aircraft database download banner/functionality
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added duplicate detection to addSignalHit():
- Tracks recent signals by frequency in a Map
- Ignores same frequency within 5 seconds
- Auto-cleans entries older than 30 seconds
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The periodic /status check was throwing uncaught promise errors
when the server was unavailable or restarting.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed /spectrum/audio/* to /listening/audio/* to match the
actual listening_post blueprint URL prefix.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The warning was triggered when ffmpeg was missing, but the message
incorrectly said "No RTL-SDR devices found". Now properly shows
"ffmpeg not found" with installation instructions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Listening Post actually uses ffmpeg for audio encoding, not sox.
Updated all documentation, setup scripts, and code to reflect this:
- Removed unused find_sox() function from listening_post.py
- Simplified tools endpoint to only check for ffmpeg
- Updated CHANGELOG, README, HARDWARE.md, Dockerfile
- Fixed setup.sh to check for ffmpeg
- Updated frontend warnings to mention ffmpeg
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Enhanced /adsb/tools endpoint to detect SoapySDR hardware and check for readsb
- Added UI warning in aircraft dashboard when HackRF/LimeSDR is detected but readsb is missing
- Warning includes expandable installation instructions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Listening Post mode with frequency scanner and audio monitoring
- Add dependency warning for aircraft dashboard listen feature
- Auto-restart audio when switching frequencies
- Fix toolbar overflow on aircraft dashboard custom frequency
- Update setup script with full macOS/Debian support
- Clean up README and documentation for clarity
- Add sox and dump1090 to Dockerfile
- Add comprehensive tool reference to HARDWARE.md
- Add correlation, settings, and database utilities
- Add new test files for routes, validation, correlation, database
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Airspy support:
- Add AIRSPY to SDRType enum and driver mappings
- Create AirspyCommandBuilder using SoapySDR tools (rx_fm, readsb, rtl_433)
- Register in SDRFactory and add to hardware type dropdown
- Supports Airspy R2/Mini (24MHz-1.8GHz) and HF+ devices
GPS coordinate persistence:
- Save observer location to localStorage when manually entered or via geolocation
- Restore saved coordinates on page load in both index.html and adsb_dashboard.html
- Coordinates are shared between both pages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Features:
- Add rtl_tcp support for pager and sensor decoding
- Connect to remote RTL-SDR via rtl_tcp server
- New UI toggle and host:port inputs in sidebar
- Supports rtl_fm and rtl_433 with remote devices
- Add remote dump1090 support for ADS-B tracking
- Connect to dump1090 SBS output on remote machine
- New "Remote" checkbox with host:port in ADS-B dashboard
Backend changes:
- Add rtl_tcp_host/port fields to SDRDevice dataclass
- Add is_network property for detecting remote devices
- Update RTLSDRCommandBuilder to use rtl_tcp:host:port format
- Add create_network_device() to SDRFactory
- Add validate_rtl_tcp_host/port validation functions
- Update pager, sensor, and adsb routes to accept remote params
Note: dump1090 doesn't support rtl_tcp directly - use remote
dump1090's SBS output (port 30003) for remote ADS-B tracking.
- Fix escaped newline in CSV export causing literal \n in output
- Clear allMessages array when clearing messages so CSV/JSON exports
reflect current data after clearing
Moved CSS files for ADS-B and satellite dashboards, as well as the main index page. Updated screenshot image paths in the README and moved screenshot files to a dedicated images/screenshots directory. Adjusted HTML templates to use the new path for the CSS files.
- Add GPS dongle support with NMEA parsing (utils/gps.py, routes/gps.py)
- Add GPS device selector to ADS-B and Satellite observer location sections
- Add GPS dongle option to ADS-B dashboard
- Fix Python 3.7/3.8 compatibility by adding 'from __future__ import annotations'
to all SDR module files (fixes TypeError: 'type' object is not subscriptable)
- Add pyserial to requirements.txt
- Update README with GPS dongle documentation and troubleshooting
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added toggleAircraftRadar() function and onchange handler to the
checkbox. Also updated switchMode() to respect the checkbox state
when switching to aircraft mode.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Satellite dashboard: Add header stat badges, bottom controls bar,
streamlined sidebar with countdown/telemetry/pass list panels
- Main dashboard: Add UTC clock, mode-specific header stats with
real-time syncing, active mode indicator with pulse animation
- Controls bar: Reorganize into logical groups (Mode, Export),
gradient background, styled status indicator
- Panel styling: Gradient backgrounds, indicator dots on headers,
Orbitron font for titles, rounded corners throughout
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Aircraft Trails: altitude-based color gradient with fading opacity
- Virtual Radar Scope (PPI): canvas-based with sweep animation, range rings, compass rose
- UI Overhaul: controls bar at bottom, compact stats in header, MAP/RADAR view toggle
- Range selector syncs with both map rings and radar scope
- Click-to-select aircraft works in both map and radar views
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
GPS geolocation only works on HTTPS or localhost. Added manual lat/lon
input fields so users can enter their coordinates directly when
accessing the app over HTTP on a local network.
- Added latitude/longitude input fields to both ADS-B tab and dashboard
- GPS button now checks for secure context before attempting geolocation
- Shows helpful error message directing users to use manual input
- Input fields update observer location and redraw range rings on change
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New features for both ADS-B tab and dashboard:
1. Range Rings - Concentric circles at 25, 50, 100, 150, 200nm showing
distance from observer location with dashed styling and labels
2. Statistics Panel - Tracks:
- Max range achieved (with aircraft that achieved it)
- Total unique aircraft seen this session
- Messages per second rate
- Busiest hour of tracking
3. Geolocation Button - Gets user's actual GPS location to:
- Center the map on their position
- Calculate accurate distances for range statistics
- Position range rings correctly
4. Reception Statistics - Real-time msg/sec counter to monitor
receiver performance
All features work on both the ADS-B tab and full-screen dashboard.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The UK range 0x400000-0x43FFFF was the entire UK allocation, not just
military - this incorrectly flagged civilian airlines like EasyJet
(EZY callsign) as military aircraft.
Fixed ranges:
- Removed broad UK range, kept only RAF sub-range 0x43C000-0x43CFFF
- Narrowed France range to actual military 0x3F4000-0x3F7FFF
- Fixed Germany to correct Luftwaffe range 0x3D0000-0x3DFFFF
- Fixed typo in US range (0xADFFFFF -> 0xADFFFF)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Renamed ADS-B audio context to avoid conflict with existing audio
system. The duplicate 'let audioContext' declaration was causing
a JavaScript syntax error that prevented the rest of the script
from loading, including the acceptDisclaimer function.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Features:
- Audio alert plays when military aircraft or emergency squawk code
(7500/7600/7700) is first detected
- Different tones: two-tone urgent alert for emergencies, single tone
for military aircraft
- Visual banner notification appears at top of screen for 5 seconds
- Toggle checkbox to enable/disable audio alerts
- Alerts only trigger once per aircraft to avoid spam
- Implemented on both ADS-B tab and full-screen dashboard
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The previous logic split the track whenever longitude jumped by more
than 180°, which could happen in cases other than actual antimeridian
crossings, causing gaps in the middle of the orbit track.
New logic only splits when one longitude is > 90° and the other is
< -90°, which specifically identifies crossings of the ±180° line.
Also changed segment minimum from 2 to 1 point to preserve all data.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Keep trackLine (visible pass trajectory) when drawing orbit track
- Make visible pass line solid (weight 4, full opacity) vs orbit track
(dashed, weight 2, 60% opacity) for clear visual distinction
- Only fit bounds on initial pass selection, not periodic updates
- Prevents map from re-zooming every 5 seconds
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The orbit track was being added correctly but wasn't visible because
the map was zoomed to the pass ground track (a small arc). Now the map
fits bounds to include the full orbit track plus observer location
after adding the orbit layer.
Also removed debug console.log statements.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Temporary logging to diagnose why dashboard isn't showing satellite
position and orbit track like the tab does.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove duplicate updateRealTimePositions() call from onSatelliteChange()
since calculatePasses() already calls selectPass() which triggers it
- Clear passes and selectedPass when changing satellites to prevent
using stale data
- Clear map layers when changing satellites
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When removing map layers, set references to null so new markers get
created properly on position updates. Also clear orbit track lines
when changing passes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Same fix as dashboard: LayerGroup doesn't have getBounds(), so collect
all coordinates and create bounds manually using L.latLngBounds().
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The polar plot now redraws the pass trajectory before overlaying the
current position indicator, matching the dashboard behavior.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Bug: Both files were fetching orbit data for the dropdown-selected
satellite instead of the satellite from the selected pass.
Fixes:
- satellite_dashboard.html: updateRealTimePositions() now uses
passes[selectedPass].satellite instead of selectedSatellite
- index.html: updateRealTimePosition() now ensures the selected
pass's satellite is included in the position request, and added
includeTrack: true to get orbit data
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added updateRealTimePositions() call to selectPass() so the full orbit
track is fetched immediately when a pass is selected, not just on the
5-second interval.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
LayerGroup doesn't have getBounds() like polyline does. Collect all
coordinates and create bounds manually using L.latLngBounds().
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>