Add slow-scan television decoder for receiving images from ISS.
Includes new Space dropdown in navigation grouping Satellite and SSTV modes.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Check for new releases from GitHub API with 6-hour cache
- Show toast notification when updates are available
- Add Updates tab in settings for manual checks and preferences
- Support git-based updates with stash handling for local changes
- Persist dismissed versions to avoid repeated notifications
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add QR code generation for sharing Meshtastic channel configurations.
Add qrcode[pil] dependency for QR code generation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The bias-T checkbox on the main dashboard was not being passed to the
ADS-B and AIS tracking start requests. Added getBiasTEnabled() helper
to each dashboard that reads from shared localStorage, and updated all
start request bodies to include bias_t parameter.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add inline script in <head> that checks localStorage before page renders
- If disclaimer not accepted, hide welcome page via injected CSS
- Show disclaimer modal on DOMContentLoaded
- After accepting, remove gate CSS and reveal welcome page
- User must accept disclaimer before they can access the application
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Reverts the utility bar feature and disclaimer timing changes that
caused the disclaimer to flash on screen for users who had already
accepted it.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Show disclaimer BEFORE welcome page on first visit (was showing after)
- Add shared utility-bar.html partial with theme, animations, settings, help
- Include utility bar on Aircraft, Satellite, and Vessels dashboards
- Support ?settings=open and ?help=open URL params from dashboards
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The CSS filter (invert + hue-rotate) was previously used to make light
OSM tiles appear dark. Now that we use actual dark CARTO tiles, this
filter was inverting them back to light. Removed from all dashboards.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Settings.registerMap() to register maps for tile updates
- Add Settings.createTileLayer() to create tile layers from settings
- Update _updateMapTiles() to use registered maps
- Expose all maps to window object for settings manager access
- All dashboards now use Settings manager when available
- Tile provider changes in settings now apply immediately to all maps
- Use Fastly CDN for CARTO tiles (more reliable)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The {r} retina parameter was causing CARTO to return light/gray tiles
instead of dark tiles. Removed {r} from all tile layer URLs.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix traceroute button in Meshtastic popups using event delegation
instead of inline onclick handlers (more reliable with Leaflet)
- Update all maps to use dark CARTO tiles for consistency:
- ADS-B dashboard radar map
- AIS dashboard vessel map
- Satellite dashboard ground map
- APRS map
- Satellite ground track map in main UI
- Change settings manager default tile provider to cartodb_dark
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Makes it much clearer which vehicle is being tracked on the map by adding
two animated concentric rings that pulse outward from the selected marker.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Increased viewport height offset from 95px to 115px to account for the
actual combined height of header and stats strip elements.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The audio visualizer was returning early if audioSpectrumCanvas didn't
exist, preventing the signal level from being fed to the synthesizer.
Now it continues to update currentSignalLevel even without the canvas.
Also added detailed logging to diagnose audio context issues.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds console logging and on-canvas display of signal level values to
help diagnose why synthesizer isn't responding to signals.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The audio visualizer (Web Audio API analyzer) was not being initialized
when direct listening or scanner signal detection started, so the
synthesizer never received audio level data.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The synthesizer was showing a decorative animation unrelated to actual
signals. Now it responds to real RMS levels from scanner SSE events and
Web Audio API data during direct listening.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add full telemetry display in node popups including device metrics
(voltage, channel utilization, air TX) and environment sensors
(temperature, humidity, barometric pressure).
Add traceroute functionality with interactive visualization showing
hop paths and SNR values. Includes API endpoints for sending traceroutes
and retrieving results, plus a modal UI for displaying route information.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Automatically connects to gpsd on page load if available. Updates
observer location in real-time with GPS indicator in top bar.
Includes auto-reconnect on visibility change.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The map was showing correct node count from API while the top bar
showed 0 because uniqueNodes Set was only populated from messages.
Now loadNodes() adds nodes to uniqueNodes and updates stats.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When multiple serial ports are detected (e.g., /dev/ttyACM0 and /dev/ttyUSB0),
the Meshtastic SDK's auto-detect fails. This adds a /meshtastic/ports endpoint
to list available ports and populates the device dropdown, auto-selecting the
first port when multiple exist.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Transform flat scrolling meter list into grouped view showing one card
per unique meter with:
- Consumption history tracking and delta from previous reading
- Trend sparkline visualization (color-coded for normal/elevated/spike)
- Consumption rate calculation (units/hour over 30-min window)
- Cards update in place instead of creating duplicates
- Alert sound only plays for new meters
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add getMeterTypeInfo() with ERT endpoint type lookups for utility type
(Electric/Gas/Water) and manufacturer (Itron, Landis+Gyr, Neptune, etc.)
- Hook addRtlamrReading into trackDevice() for Device Intelligence panel
- Add meter protocol handling to generateDeviceId()
- Display manufacturer and utility type on meter cards
- Show utility type as badge, manufacturer in meta row and details panel
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Make logo clickable, opens GitHub Pages in new tab
- Match What's New box height to Select Mode box
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When clicking an aircraft in the sidebar, its map marker now shows
an enhanced white glow (10px) to distinguish it from other markers.
This matches the existing behavior in AIS mode.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Merged the two gear icons in the header bar into one unified Settings modal.
Added a "Tools" tab to display dependency status, removing the separate
dependencies modal and button.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The JavaScript checks for 'statusJetbrains' but the HTML had
'statusJetBrains' causing the status check to fail.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New Features:
- Meshtastic LoRa mesh network integration
- Real-time message streaming via SSE
- Channel configuration with encryption
- Node information with RSSI/SNR metrics
- Ubertooth One BLE scanner backend
- Passive capture across all 40 BLE channels
- Raw advertising payload access
- Offline mode with bundled assets
- Local Leaflet, Chart.js, and fonts
- Multiple map tile providers
- Settings modal for configuration
Technical Changes:
- New routes: meshtastic.py, offline.py
- New utils: ubertooth_scanner.py, meshtastic.py
- New CSS/JS for meshtastic and settings
- Updated dashboard templates with conditional asset loading
- Added context processor for offline settings
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add animated SVG globe with rotating meridians as a subtle background
element on the welcome overlay and login pages.
Also removes unused signal-cards-mockup.html.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add browser history back button alongside existing dashboard links on
vessels, aircraft, network monitor, and remote agents pages.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update dashboard screenshot to v2.10.0
- Add Remote Agents screenshot to docs gallery
- Add Remote Agents feature card to GitHub Pages
- Add navigation links to DISTRIBUTED_AGENTS.md
- Add Remote Agents section to FEATURES.md and USAGE.md
- Link distributed agents docs from main README
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix header logo and title alignment using flexbox
- Move Refresh All button next to Register Agent button
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add support for connecting to Meshtastic LoRa mesh devices via USB/Serial.
Includes routes for device connection, channel configuration with encryption,
and SSE streaming of received messages.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change .section overflow from hidden to visible so form elements
and buttons display fully within sidebar boxes.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add fallback direct DOM manipulation in agents.js selectAgent()
- Fix setListeningPostRunning to check agent mode before re-enabling button
- Add debug logging for button state changes
Agent scanner fixes:
- Use non-blocking I/O with select/fcntl to prevent blocking reads
- Pass dwell_time parameter through to scanner function
- Add freqs_scanned counter to status and data endpoints
- Improve SDR test process cleanup with kill() fallback
Frontend listening post fixes:
- Add setListeningPostRunning for UI sync when switching to agent
- Fix button ID (radioScanBtn not scannerStartBtn)
- Handle nested data structure from controller proxy
- Update freqs_scanned and signal_count from polling data
- Disable listen button for agent mode (audio can't stream over HTTP)
Add listening_post to agents.js uiSetters map for mode sync.
Live testing completed:
- Sensor mode: works via agent
- WiFi quick scan: works via agent
- Listening post: works via agent (AM airband, WFM broadcast tested)
- Signal detection: confirmed working via agent
Testing ongoing - modes not yet tested via agent:
- Pager, ADS-B, AIS, ACARS, APRS, DSC, RTL-AMR, TSCM, Bluetooth
- Location dropdown in header to select observer position source
- Options: Local (browser GPS) or any registered agent with GPS
- Fetches agent GPS position via /controller/agents/{id}/status
- Satellite pass predictions calculated from agent's location
- Observer marker on map shows agent name in popup
- Status dot indicates GPS availability
Agent fixes:
- Accept 'success' status for quick scans (not just 'started')
- WiFi quick scans return 'success' with results, not 'started'
Controller fixes:
- Pass through actual error messages from agent responses
- Previously showed generic "Agent returned error: 400"
- Now shows actual message like "Root privileges required for deep scan"
- Agent: Add _detect_acarsdec_fork() for f00b4r0/DragonOS support
- Agent: Use --output json:file, --rtlsdr, -m 256 for f00b4r0 fork
- UI: Add setAcarsRunning() to sync button state with agent
- UI: Add 'acars' to syncModeUI uiSetters map
ACARS (f00b4r0/DragonOS compatibility):
- Use --output json:file (not json:file:-) for stdout
- Use --rtlsdr instead of -r for device selection
- Use -m 256 for 3.2 MS/s sample rate (wider bandwidth for NA freqs)
- Properly detects fork by checking for --output in help
The f00b4r0 fork (used by DragonOS) has different CLI syntax than
TLeconte's original. Key differences:
- TLeconte: -j -r <device>
- f00b4r0: --output json:file -m 256 --rtlsdr <device>
ADS-B stop fix:
- Add Content-Type header to stop fetch request
- Flask's request.json requires application/json content type
- Without this header, stop returns HTTP 415 and dump1090 keeps running
- Fix device dropdown to use sdr_devices (same as agents.js fix)
- Keep dropdown/start button enabled in "All Agents" mode for control
- Disable airband controls for remote agents (audio not supported)
Agent fixes:
- Fix stop not killing secondary processes (pager_rtl, aprs_rtl, rtlamr_tcp)
- Modes using piped processes now properly terminate all child processes
UI state sync fixes:
- Add syncLocalModeStates() to check local status when switching to local
- Fix switchMode() to re-sync with agent/local when changing mode tabs
- Only stop local modes when actually in local mode
- UI now correctly reflects running state when switching agents or modes