# RF Mapper Usage Guide RF Mapper is a WiFi and Bluetooth signal mapper for Linux. It scans nearby devices, estimates distances, and visualizes results in multiple views including radar, 2.5D, world map, and 3D map with building support. ## Requirements - Linux with WiFi and Bluetooth hardware (or Android via Termux) - Python 3.10+ - `sudo` access (required for scanning on Linux) - System tools: `iw`, `hcitool`, `bluetoothctl` ### Android/Termux Requirements For running RF Mapper on Android via Termux: | Requirement | Description | |-------------|-------------| | **Termux** | From F-Droid (NOT Play Store) | | **Termux:API** | From F-Droid (same source as Termux) | | **Termux:Boot** | Optional, for auto-start on boot | | **termux-api package** | `pkg install termux-api` | | **Location permission** | Grant to Termux:API app | | **GPS enabled** | Enable Location in Android settings | **Important:** All Termux apps must be from the same source (F-Droid recommended). Mixing Play Store and F-Droid versions causes API communication failures. #### ADB Configuration for Android 12+ Android 12+ has a "phantom process killer" that terminates background processes. Disable it for stable Termux operation: ```bash # Connect via ADB and run: adb shell "settings put global settings_enable_monitor_phantom_procs false" ``` This setting persists across reboots but may reset after Android updates. #### Verify Termux Prerequisites ```bash # Check if all prerequisites are met rf-mapper check-termux ``` Output shows status of each requirement: ``` ================================================== TERMUX ENVIRONMENT DETECTED Checking prerequisites... ================================================== ✓ Termux:API package: OK ✓ Location services: OK (lat: 50.8585) ✓ Wake lock: OK (wake lock acquired) ✓ Termux:Boot: OK (boot directory exists) ================================================== All prerequisites met. Starting RF Mapper... ``` #### Termux Boot Script For auto-start on device boot, create `~/.termux/boot/start-rf-mapper.sh`: ```bash #!/data/data/com.termux/files/usr/bin/bash termux-wake-lock cd ~/git/rf-mapper source venv/bin/activate python -m rf_mapper start ``` Make it executable: ```bash chmod +x ~/.termux/boot/start-rf-mapper.sh ``` ## Installation ```bash # Create and activate virtual environment python -m venv venv source venv/bin/activate # Install dependencies pip install -e . ``` ## Quick Start ```bash # Activate venv source venv/bin/activate # Run interactive scan python -m rf_mapper # Start web server python -m rf_mapper start ``` ## CLI Commands All commands require activating the virtual environment first: ```bash source venv/bin/activate ``` ### Scanning ```bash # Basic scan (interactive mode) python -m rf_mapper # Scan with location label python -m rf_mapper scan -l kitchen # Scan WiFi only python -m rf_mapper scan --no-bt # Scan Bluetooth only python -m rf_mapper scan --no-wifi # Use specific WiFi interface python -m rf_mapper scan -i wlan1 ``` ### Visualization (CLI) ```bash # Visualize latest scan (ASCII radar + charts) python -m rf_mapper visualize # Visualize specific scan file python -m rf_mapper visualize -f data/scan_20240131_120000_kitchen.json # Analyze RF environment python -m rf_mapper analyze ``` ### Scan History ```bash # List saved scans python -m rf_mapper list ``` ### Web Server ```bash # Start web server (background daemon) python -m rf_mapper start # Start in foreground (for debugging) python -m rf_mapper start --foreground # Custom host/port python -m rf_mapper start -H 127.0.0.1 -p 8080 # With debug mode python -m rf_mapper start --foreground --debug # With request profiling python -m rf_mapper start --profile-requests # With request logging python -m rf_mapper start --log-requests # Stop the server python -m rf_mapper stop # Restart the server python -m rf_mapper restart # Check server status python -m rf_mapper status ``` ### Configuration ```bash # Show current configuration python -m rf_mapper config # Set GPS coordinates python -m rf_mapper config --set-gps 50.8585 4.3978 --save # Check Termux prerequisites (Android only) rf-mapper check-termux ``` ### Profiling ```bash # Profile CPU usage rf-mapper --profile scan # Profile memory usage rf-mapper --profile-memory scan # Save profile to file rf-mapper --profile --profile-output scan.prof scan ``` ## Web Interface Views The web dashboard offers 3 visualization modes: | View | Description | |------|-------------| | **Radar** | Classic radar display with distance rings | | **World Map** | Leaflet map with device markers on real geography | | **3D Map** | MapLibre GL 3D view with building extrusion | ### Features - Real-time scanning via "New Scan" button - Auto-scan mode with configurable interval - WiFi/Bluetooth filter toggles - Floor filtering for multi-story buildings - Click devices for detailed info popups - Device lists with signal strength indicators ## Configuration File Configuration is loaded from (in order): 1. `./config.yaml` 2. `~/.config/rf-mapper/config.yaml` 3. `/etc/rf-mapper/config.yaml` ### Example `config.yaml` ```yaml gps: latitude: 50.8585853 longitude: 4.3978724 web: host: "0.0.0.0" port: 5000 debug: false scanner: wifi_interface: "wlan0" bt_scan_timeout: 10 path_loss_exponent: 2.5 auto_identify_bluetooth: true data: directory: "data" max_scans: 100 building: enabled: false name: "My Building" floors: 3 floor_height_m: 3.0 ground_floor_number: 0 ``` ### Environment Variables | Variable | Description | |----------|-------------| | `RF_MAPPER_LAT` | Override GPS latitude | | `RF_MAPPER_LON` | Override GPS longitude | | `RF_MAPPER_HOST` | Override web server host | | `RF_MAPPER_PORT` | Override web server port | | `HA_TOKEN` | Home Assistant API token | | `HA_URL` | Home Assistant URL | ## API Endpoints The web server exposes a REST API: | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/health` | Health check for monitoring | | POST | `/api/scan` | Trigger new scan | | GET | `/api/latest` | Get most recent scan | | GET | `/api/scans` | List all scans | | GET | `/api/scans/` | Get specific scan | | GET/POST | `/api/position` | Get/set GPS position | | GET/POST | `/api/config` | Get/update configuration | | GET/POST | `/api/building` | Get/update building config | | POST | `/api/device//floor` | Assign floor to device | | GET | `/api/autoscan` | Get auto-scan status | | POST | `/api/autoscan/start` | Start auto-scanning | | POST | `/api/autoscan/stop` | Stop auto-scanning | | GET | `/api/bluetooth/identify/` | Identify BT device | ## Multi-Node Master Dashboard RF Mapper supports a multi-node architecture where one designated "master" node can view and control scanning on peer nodes without page redirects. ### Architecture Overview ``` ┌─────────────────────────────────────────────────────────┐ │ Master Node (rpios) │ │ ┌───────────────────────────────────────────────────┐ │ │ │ Node Selector: [📍 rpios ▼] │ │ │ │ ├─ 📍 rpios (local) │ │ │ │ ├─ 📡 grokbox │ │ │ │ └─ 📡 jellystar │ │ │ └───────────────────────────────────────────────────┘ │ │ │ │ │ │ │ [Radar] [3D Map] [Device Lists] │ └─────────────────────────────────────────────────────────┘ │ ┌────────────────┼────────────────┐ ▼ ▼ ▼ grokbox:5000 jellystar:5000 (local) ``` ### Enabling Master Mode Set `is_master: true` in `config.yaml` on the master node: ```yaml scanner: id: 'rpios' name: 'Master Scanner' is_master: true # Enable master dashboard features peers: [] # Peers auto-register via API accept_registrations: true ``` Peer nodes do NOT need this flag (defaults to `false`). ### Node Selector When `is_master: true` and peers are registered, a node selector dropdown appears in the header: | Indicator | Meaning | |-----------|---------| | 📍 | Local scanner (this node) | | 📡 | Peer scanner (remote node) | | ● (green) | Connected and responding | | ● (yellow) | Connecting/loading | | ○ (red) | Peer unreachable | ### Switching Between Nodes 1. Click the node selector dropdown 2. Select a peer node (e.g., "📡 grokbox") 3. Dashboard recenters on peer's GPS location 4. Device lists show peer's scanned devices 5. WebSocket connects to peer for real-time updates When viewing a peer: - Map centers on peer's coordinates - Radar shows devices relative to peer - "New Scan" triggers scan on peer node - Live tracking runs scans on peer ### Live Tracking on Remote Nodes Live tracking works across nodes: 1. Select a peer from node selector 2. Enable "Live BT Track" toggle 3. Scans run on the selected peer (not locally) 4. Results stream back via WebSocket 5. Map updates in real-time with peer's devices ### Proxy API Endpoints The master node provides proxy endpoints to access peer data: | Endpoint | Description | |----------|-------------| | `/api/node//latest` | Get latest scan from peer | | `/api/node//scan/bt` | Trigger BT scan on peer | | `/api/node//device/floors` | Get device floor assignments | | `/api/node//positions/trilaterated` | Get trilaterated positions | Example: ```bash # Get grokbox's latest scan via master curl http://rpios:5000/api/node/grokbox/latest | jq # Trigger BT scan on grokbox curl -X POST http://rpios:5000/api/node/grokbox/scan/bt ``` ### Peer Registration Peers register with the master automatically or manually: ```bash # Manual registration from peer curl -X POST http://rpios:5000/api/peers/register \ -H "Content-Type: application/json" \ -d '{ "id": "grokbox", "name": "Grokbox Scanner", "url": "http://grokbox:5000", "latitude": 50.858495, "longitude": 4.397614, "floor": 11 }' # List registered peers curl http://rpios:5000/api/peers | jq '.peers' ``` ### WebSocket Peer Connections When viewing a peer node, the dashboard: 1. Disconnects from local WebSocket 2. Connects to peer's WebSocket at `peer_url/ws/scan` 3. Receives real-time scan updates from peer 4. Falls back to HTTP polling if WebSocket fails ## Data Storage Scan results are saved as JSON in the data directory: - Default: `./data/` - Files: `scan_YYYYMMDD_HHMMSS_.json` ## Troubleshooting ### "WiFi scan error: Operation not permitted" Run with sudo or ensure your user has permissions: ```bash sudo rf-mapper scan ``` ### "No Bluetooth adapter found" Ensure Bluetooth is enabled: ```bash sudo systemctl start bluetooth sudo hciconfig hci0 up ``` ### Web interface shows no devices 1. Run a scan first: click "New Scan" or use CLI 2. Check if data directory has scan files 3. Verify filters aren't hiding devices ### 3D buildings not showing - Zoom in to level 15+ for buildings to appear - Not all areas have building data in OpenStreetMap - The map style must support vector tiles with building data ### Termux: "Termux:API app not responding" 1. Ensure Termux:API is from F-Droid (not Play Store) 2. Grant all permissions to Termux:API in Android settings 3. Restart Termux after installing Termux:API ### Termux: Process killed in background Android's phantom process killer terminates background processes. Fix: ```bash adb shell "settings put global settings_enable_monitor_phantom_procs false" ``` ### Termux: Location services failing 1. Enable GPS/Location in Android settings 2. Grant location permission to Termux:API 3. Test with: `termux-location -p passive` 4. Ensure you're outdoors or near windows for GPS signal ### Termux: Wake lock not working 1. Disable battery optimization for Termux in Android settings 2. Run `termux-wake-lock` before starting RF Mapper 3. The app acquires wake lock automatically on start ### Master Dashboard: Node selector not appearing 1. Verify `is_master: true` in config.yaml 2. Restart rf-mapper: `python -m rf_mapper restart` 3. Check peers are registered: `curl http://localhost:5000/api/peers | jq '.peers | length'` 4. At least one peer must be registered for selector to appear ### Master Dashboard: Peer shows red status 1. Check peer is running: `curl http://peer:5000/api/peers` 2. Check network connectivity: `ping peer` 3. Check firewall allows port 5000 4. Re-register peer if needed (see Peer Registration above) ### Master Dashboard: WebSocket to peer fails 1. Check peer WebSocket endpoint: `curl http://peer:5000/socket.io/` 2. Browser console shows connection errors 3. Falls back to HTTP polling automatically 4. Ensure peer is running with WebSocket support enabled