Files
rf-mapper/USAGE.md
User 91536860ad docs: update CLI commands to use python -m rf_mapper
- 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>
2026-02-01 17:38:44 +01:00

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+
  • 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:

# 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):

  1. ./config.yaml
  2. ~/.config/rf-mapper/config.yaml
  3. /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

  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/<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:

  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_<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

  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:

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