Bleak requires D-Bus which isn't available on Android. Detect Termux
environment and skip both Classic BT and BLE scanning gracefully.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use bleak's BleakScanner for BLE device discovery instead of
hcitool lescan subprocess. Provides real RSSI values from
advertisement packets instead of hardcoded -70dB estimate.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add bt_mac field to scanner config for identifying scanner BT adapters
- Store bt_mac in peers table for peer scanners
- Filter out devices matching scanner BT MACs from all views
- Prevents scanners from appearing as devices in device lists/maps
Config: scanner.bt_mac = "XX:XX:XX:XX:XX:XX"
API: /api/peers/register accepts bt_mac field
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use viewing scanner name (peer or local) for center marker
- Filter out the peer being viewed from peer markers list
- Fixes duplicate grokbox markers when viewing grokbox from master
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Cache successful GET responses from peers (5 min TTL)
- Return cached data when peer is unreachable
- Add _cached, _cached_at, _cache_age_seconds flags
- Add /api/node/<id>/health proxy endpoint
Enables master dashboard to show peer data even when
peers are temporarily unreachable (e.g., mobile devices,
VPN disconnections).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Architecture overview with diagram
- Enabling master mode (is_master config)
- Node selector UI indicators
- Switching between local and peer views
- Live tracking on remote nodes
- Proxy API endpoints for peer data
- Peer registration examples
- WebSocket peer connection details
- Troubleshooting section for common issues
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Show each scanner as a single marker with WiFi/Bluetooth capabilities
listed in the popup, instead of separate entries per capability.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Show the scanner's configured name (or hostname if not set) in map
markers and popups instead of the generic "Your Position" label.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Enable a designated "master" node to view device data from any peer node
within the same dashboard, without page redirects.
- Add is_master config option to ScannerConfig
- Add proxy endpoints /api/node/<id>/* for peer data
- Add node selector dropdown UI (shown only on master)
- Add peer WebSocket connection support for real-time updates
- Live tracking uses node-specific scan endpoint
- Map centers on selected peer's position
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Document Android/Termux requirements (Termux:API, permissions)
- Add ADB command to disable phantom process killer
- Document check-termux command for prerequisite verification
- Add Termux boot script example for auto-start
- Add troubleshooting section for common Termux issues
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Detects when running in Termux on Android and checks for required
prerequisites before starting the server:
- Termux:API package installed
- Location services enabled and accessible
- Wake lock available
Exits with informative error message if prerequisites not met.
Adds `rf-mapper check-termux` command for manual verification.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Set overflow: visible on MapLibre popup to prevent clipping
of floor select dropdown when it expands.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Coverage rings now render as CSS pseudo-elements on scanner markers,
following the same floor offset positioning. Toggle .heatmap-enabled
class on map container to show/hide coverage visualization.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace heatmap layer with concentric circle layers around scanner
positions. This avoids the z-index issue where heatmap appeared at
floor 0 below all markers.
Shows three coverage rings:
- Green inner (good signal ~5m)
- Yellow middle (fair signal ~10m)
- Red outer (weak signal ~15m)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add database methods for multi-scanner RSSI queries
- Add weighted trilateration function supporting 2+ scanners
- Add /api/positions/trilaterated endpoint
- Add /api/heatmap/signal endpoint for heat map data
- Update frontend to show trilaterated positions with gold markers
- Add heat map toggle button for signal coverage visualization
Trilateration uses RSSI from multiple scanners to calculate device
positions with confidence scores. Devices seen by 2+ scanners within
60 seconds get trilaterated positions shown with gold border markers.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add WebSocket state variables (wsEnabled, wsConnected)
- Add initWebSocket() function with connection and event handling
- Add handleWebSocketScanUpdate() for processing WS scan events
- Modify startLiveTracking() to use WS mode with HTTP fallback
- Update index.html to load socket.io and websocket.js scripts
- Show [WS] indicator in status when using WebSocket mode
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Initialize SocketIO with threading mode
- Add WebSocket event handlers (connect, disconnect, subscribe_floor)
- Add broadcast_scan_update() function for pushing scan results
- Integrate broadcast with BT scan endpoint
- Update run_server() to use socketio.run()
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Load peer scanner positions from /api/peers
- Use peer's CURRENT position instead of stored position
- Ensures device positions update when peer scanner moves
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Added peer scanner markers to MapLibre 3D view
- Peer scanners shown with cyan icon and absolute position
- Styled with distinct color and shadow
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When devices are synced from a peer, they now retain their original
source scanner reference. This ensures:
- Device positions are calculated relative to the scanner that
detected them, not the local scanner
- Moving the local scanner won't affect synced devices' positions
- Popup shows "Source: <scanner_id>" for remotely-synced devices
Database changes:
- Added source_scanner_id, source_scanner_lat, source_scanner_lon
columns to devices table
- get_devices_since() includes source scanner info in sync data
- bulk_update_devices() accepts and stores source scanner position
- Added get_all_device_sources() method
API changes:
- /api/sync/devices GET includes scanner_lat and scanner_lon
- /api/sync/devices POST accepts source_scanner_lat/lon
- /api/device/floors includes sources dict
Frontend changes:
- loadDevicePositions() loads source scanner info
- getDevicePosition() uses source scanner position for synced devices
- Popup shows source scanner info for remotely-synced devices
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- bulk_update_devices now creates devices if they don't exist locally
but have useful metadata (floor, label, or favorite status)
- Sync trigger endpoint now reports both pulled and pushed device counts
- Enables full bidirectional sync of device metadata between peers
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Scanner positions shown as magenta stars (this scanner)
- Peer scanners shown as cyan stars
- Clear visual distinction from WiFi (orange circles) and BT (blue circles)
- Radar view also shows scanner as star shape
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
WiFi devices now shown in orange (#f59f00), Bluetooth in blue (#4dabf7).
Makes it easier to distinguish device types on map and in device list.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Position offsets (custom_lat_offset, custom_lon_offset) are relative
to each scanner's location, so syncing them between scanners would
place devices incorrectly. Only sync: floor, label, favorite, notes.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The /api/scan, /api/scans/<filename>, and /api/latest endpoints
now look up saved floor assignments from the database and include
them in responses. Previously only /api/scan/bt did this.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The updated_at timestamp should only change when user metadata
changes (floor, label, position, notes), not on every scan
observation. This was breaking peer sync because observation
timestamps were overwriting metadata timestamps.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Home Assistant Integration:
- New homeassistant.py module with webhook support
- Webhooks for scan results, new devices, and device departures
- Absence detection with configurable timeout
- Documentation in docs/HOME_ASSISTANT.md
CLI Improvements:
- Replace 'web' command with start/stop/restart/status
- Background daemon mode with PID file management
- Foreground mode for debugging (--foreground)
Web UI Enhancements:
- Improved device list styling and layout
- Better floor assignment UI
- Enhanced map visualization
Documentation:
- Add CHANGELOG.md
- Add docs/API.md with full endpoint reference
- Add docs/CHEATSHEET.md for quick reference
- Update project documentation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The scan_wifi() calls were using the default "wlan0" instead of
the configured interface from config.yaml. This broke WiFi scanning
on systems with non-standard interface names like wlo1.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Popups now stay open during live BT tracking updates
- Track open popup device ID and restore after marker refresh
- Update TASKS.md, TODO.md, PROJECT.md, ROADMAP.md
- Mark position smoothing, floor persistence as complete
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Store floor assignments in SQLite database for persistence
- Floor now saves correctly for live-tracked BT devices
- Add statistical movement detection (5-sample average + stddev)
- Require 1.5m + 2σ deviation to mark device as moving
- Reduces false positives from RSSI noise/fluctuations
- Add /api/device/floors endpoint for bulk floor retrieval
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
WiFi & Bluetooth signal mapping tool for Raspberry Pi with:
- WiFi scanning via iw command
- Bluetooth Classic/BLE device discovery
- RSSI-based distance estimation
- OUI manufacturer lookup
- Web dashboard with multiple views:
- Radar view (polar plot)
- 2D Map (Leaflet/OpenStreetMap)
- 3D Map (MapLibre GL JS with building extrusion)
- Floor-based device positioning
- Live BT tracking mode (auto-starts on page load)
- SQLite database for historical device tracking:
- RSSI time-series history
- Device statistics (avg/min/max)
- Movement detection and velocity estimation
- Activity patterns (hourly/daily)
- New device alerts
- Automatic data retention/cleanup
- REST API for all functionality
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>