- Replace rf-mapper with python -m rf_mapper throughout docs - Add note about activating venv first - Updated: CLAUDE.md, PROJECT.md, USAGE.md, CHEATSHEET.md, HOME_ASSISTANT.md Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
13 KiB
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+
sudoaccess (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:
# 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
# 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:
#!/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:
chmod +x ~/.termux/boot/start-rf-mapper.sh
Installation
# Create and activate virtual environment
python -m venv venv
source venv/bin/activate
# Install dependencies
pip install -e .
Quick Start
# 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:
source venv/bin/activate
Scanning
# 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)
# 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
# List saved scans
python -m rf_mapper list
Web Server
# 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
# 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
# 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):
./config.yaml~/.config/rf-mapper/config.yaml/etc/rf-mapper/config.yaml
Example config.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/<filename> |
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/<id>/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/<addr> |
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:
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
- Click the node selector dropdown
- Select a peer node (e.g., "📡 grokbox")
- Dashboard recenters on peer's GPS location
- Device lists show peer's scanned devices
- 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:
- Select a peer from node selector
- Enable "Live BT Track" toggle
- Scans run on the selected peer (not locally)
- Results stream back via WebSocket
- 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/<id>/latest |
Get latest scan from peer |
/api/node/<id>/scan/bt |
Trigger BT scan on peer |
/api/node/<id>/device/floors |
Get device floor assignments |
/api/node/<id>/positions/trilaterated |
Get trilaterated positions |
Example:
# 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:
# 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:
- Disconnects from local WebSocket
- Connects to peer's WebSocket at
peer_url/ws/scan - Receives real-time scan updates from peer
- 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_<location>.json
Troubleshooting
"WiFi scan error: Operation not permitted"
Run with sudo or ensure your user has permissions:
sudo rf-mapper scan
"No Bluetooth adapter found"
Ensure Bluetooth is enabled:
sudo systemctl start bluetooth
sudo hciconfig hci0 up
Web interface shows no devices
- Run a scan first: click "New Scan" or use CLI
- Check if data directory has scan files
- 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"
- Ensure Termux:API is from F-Droid (not Play Store)
- Grant all permissions to Termux:API in Android settings
- Restart Termux after installing Termux:API
Termux: Process killed in background
Android's phantom process killer terminates background processes. Fix:
adb shell "settings put global settings_enable_monitor_phantom_procs false"
Termux: Location services failing
- Enable GPS/Location in Android settings
- Grant location permission to Termux:API
- Test with:
termux-location -p passive - Ensure you're outdoors or near windows for GPS signal
Termux: Wake lock not working
- Disable battery optimization for Termux in Android settings
- Run
termux-wake-lockbefore starting RF Mapper - The app acquires wake lock automatically on start
Master Dashboard: Node selector not appearing
- Verify
is_master: truein config.yaml - Restart rf-mapper:
python -m rf_mapper restart - Check peers are registered:
curl http://localhost:5000/api/peers | jq '.peers | length' - At least one peer must be registered for selector to appear
Master Dashboard: Peer shows red status
- Check peer is running:
curl http://peer:5000/api/peers - Check network connectivity:
ping peer - Check firewall allows port 5000
- Re-register peer if needed (see Peer Registration above)
Master Dashboard: WebSocket to peer fails
- Check peer WebSocket endpoint:
curl http://peer:5000/socket.io/ - Browser console shows connection errors
- Falls back to HTTP polling automatically
- Ensure peer is running with WebSocket support enabled