Files
rf-mapper/docs/API.md
User 7cc7c47805 feat: add Home Assistant integration and improve CLI/UI
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>
2026-02-01 03:31:02 +01:00

12 KiB

RF Mapper API Reference

REST API documentation for RF Mapper web interface.

Base URL: http://localhost:5000


Scanning

Trigger Scan

Performs WiFi and/or Bluetooth scan.

POST /api/scan

Request Body:

Field Type Default Description
location string "web_scan" Location label for the scan
lat number config value GPS latitude
lon number config value GPS longitude
scan_wifi boolean true Include WiFi networks
scan_bluetooth boolean true Include Bluetooth devices

Example:

curl -X POST http://localhost:5000/api/scan \
  -H "Content-Type: application/json" \
  -d '{"location": "kitchen", "scan_wifi": true, "scan_bluetooth": true}'

Response:

{
  "timestamp": "2026-02-01T14:30:00.123456",
  "location": "kitchen",
  "gps": {"lat": 50.8585, "lon": 4.3978},
  "wifi_networks": [
    {
      "ssid": "HomeNetwork",
      "bssid": "AA:BB:CC:DD:EE:FF",
      "rssi": -45,
      "channel": 6,
      "frequency": 2437,
      "encryption": "WPA2",
      "manufacturer": "Cisco",
      "estimated_distance_m": 3.5,
      "signal_quality": "Excellent",
      "floor": null,
      "height_m": null
    }
  ],
  "bluetooth_devices": [
    {
      "address": "11:22:33:44:55:66",
      "name": "iPhone",
      "rssi": -60,
      "device_class": "Phone",
      "device_type": "Smartphone",
      "manufacturer": "Apple",
      "estimated_distance_m": 5.2,
      "signal_quality": "Good",
      "floor": null,
      "height_m": null
    }
  ]
}

Quick Bluetooth Scan

Fast BLE-only scan for real-time tracking (uses bleak library).

POST /api/scan/bt

Response: Same as /api/scan but only bluetooth_devices populated.


Get Latest Scan

Retrieve the most recent scan results.

GET /api/latest

Response: Same format as /api/scan response.


List Scans

List saved scan files (most recent 50).

GET /api/scans

Response:

[
  {
    "filename": "scan_20260201_143000_kitchen.json",
    "timestamp": "2026-02-01T14:30:00",
    "location": "kitchen",
    "wifi_count": 12,
    "bt_count": 5
  }
]

Get Specific Scan

Retrieve a specific scan by filename.

GET /api/scans/<filename>

Example:

curl http://localhost:5000/api/scans/scan_20260201_143000_kitchen.json

Position & Configuration

GPS Position

Get or set current GPS position.

GET /api/position
POST /api/position

POST Body:

{"lat": 50.8585, "lon": 4.3978}

Response:

{"lat": 50.8585, "lon": 4.3978}

Configuration

Get or update application configuration.

GET /api/config
POST /api/config

POST Body:

Field Type Description
gps.latitude number GPS latitude
gps.longitude number GPS longitude
scanner.path_loss_exponent number Distance calculation parameter
save boolean Persist changes to config file

Example:

curl -X POST http://localhost:5000/api/config \
  -H "Content-Type: application/json" \
  -d '{"gps": {"latitude": 50.85, "longitude": 4.39}, "save": true}'

Response:

{
  "gps": {"latitude": 50.85, "longitude": 4.39},
  "web": {"host": "0.0.0.0", "port": 5000},
  "scanner": {
    "wifi_interface": "wlan0",
    "bt_scan_timeout": 10,
    "path_loss_exponent": 2.5
  },
  "config_file": "/home/user/git/rf-mapper/config.yaml"
}

Building Configuration

Get or update building configuration for 3D visualization.

GET /api/building
POST /api/building

POST Body:

Field Type Description
enabled boolean Enable 3D building view
name string Building name
floors integer Number of floors
floor_height_m number Height per floor (meters)
ground_floor_number integer Ground floor number (0 or 1)
current_floor integer Scanner's current floor
save boolean Persist changes

Response:

{
  "enabled": true,
  "name": "Home",
  "floors": 3,
  "floor_height_m": 3.0,
  "ground_floor_number": 0,
  "current_floor": 1
}

Device Management

Set Device Floor

Assign a floor to a device (persists in database).

POST /api/device/<device_id>/floor

Parameters:

  • device_id: BSSID (WiFi) or address (Bluetooth)

Request Body:

{"floor": 2, "height_m": 6.0}

Response:

{
  "status": "updated",
  "device_id": "AA:BB:CC:DD:EE:FF",
  "device_type": "wifi",
  "floor": 2,
  "height_m": 6.0
}

Set Device Distance

Override estimated distance for a device.

POST /api/device/<device_id>/distance

Request Body:

{"distance": 5.5}

Get All Floor Assignments

Retrieve all saved floor assignments.

GET /api/device/floors

Response:

{
  "AA:BB:CC:DD:EE:FF": 2,
  "11:22:33:44:55:66": 1
}

Bluetooth Identification

Identify Single Device

Get detailed info about a Bluetooth device.

GET /api/bluetooth/identify/<address>

Example:

curl http://localhost:5000/api/bluetooth/identify/11:22:33:44:55:66

Batch Identify

Identify multiple devices (max 10).

POST /api/bluetooth/identify

Request Body:

{"addresses": ["11:22:33:44:55:66", "AA:BB:CC:DD:EE:FF"]}

Auto-Scan

Get Status

GET /api/autoscan

Response:

{
  "enabled": true,
  "running": true,
  "interval_minutes": 5,
  "location_label": "auto_scan",
  "scan_wifi": true,
  "scan_bluetooth": true,
  "last_scan_time": "2026-02-01T14:30:00",
  "last_scan_result": {"timestamp": "...", "wifi_count": 12, "bt_count": 5},
  "scan_count": 42
}

Start Auto-Scan

POST /api/autoscan/start

Request Body:

Field Type Default Description
interval_minutes integer 5 Scan interval
location_label string "auto_scan" Location label
scan_wifi boolean true Include WiFi
scan_bluetooth boolean true Include Bluetooth
save boolean false Persist to config

Stop Auto-Scan

POST /api/autoscan/stop

Request Body:

{"save": true}

Update Settings

POST /api/autoscan/settings

Request Body:

{"interval_minutes": 10, "location_label": "living_room", "save": true}

Historical Data API

All history endpoints require database to be enabled in config.

List Devices

Get all tracked devices with statistics.

GET /api/history/devices

Query Parameters:

Param Type Description
type string Filter by wifi or bluetooth
since string ISO timestamp filter
limit integer Max results (default: 100)

Response:

{
  "devices": [
    {
      "device_id": "AA:BB:CC:DD:EE:FF",
      "device_type": "wifi",
      "name": "HomeNetwork",
      "ssid": "HomeNetwork",
      "manufacturer": "Cisco",
      "first_seen": "2026-01-15T10:00:00",
      "last_seen": "2026-02-01T14:30:00",
      "total_observations": 500,
      "custom_label": "Main Router",
      "is_favorite": 1,
      "assigned_floor": 1
    }
  ],
  "count": 1
}

Get Device Details

GET /api/history/devices/<device_id>

Response:

{
  "device": { ... },
  "stats": {
    "avg_rssi": -55.3,
    "min_rssi": -75,
    "max_rssi": -40,
    "avg_distance_m": 4.2,
    "min_distance_m": 1.5,
    "max_distance_m": 12.0,
    "total_observations": 500
  }
}

Get RSSI History

Time series RSSI data for a device.

GET /api/history/devices/<device_id>/rssi

Query Parameters:

Param Type Description
since string ISO timestamp filter
limit integer Max results (default: 1000)

Response:

{
  "device_id": "AA:BB:CC:DD:EE:FF",
  "observations": [
    {"timestamp": "2026-02-01T14:30:00", "rssi": -55, "distance_m": 4.2, "floor": 1}
  ],
  "count": 100
}

Get Activity Pattern

Hourly/daily activity pattern for a device.

GET /api/history/devices/<device_id>/activity

Query Parameters:

Param Type Default Description
days integer 7 Analysis period

Response:

{
  "device_id": "AA:BB:CC:DD:EE:FF",
  "period_days": 7,
  "hourly_pattern": {
    "8": {"count": 50, "avg_rssi": -55.0},
    "9": {"count": 45, "avg_rssi": -52.3}
  },
  "daily_pattern": {
    "0": 120,
    "1": 115
  }
}

Set Device Label

POST /api/history/devices/<device_id>/label

Request Body:

{"label": "Living Room TV"}

Toggle Favorite

POST /api/history/devices/<device_id>/favorite

Request Body:

{"favorite": true}

Get Movement Events

GET /api/history/movement

Query Parameters:

Param Type Description
device_id string Filter by device
since string ISO timestamp filter
limit integer Max results (default: 100)

Response:

{
  "events": [
    {
      "id": 1,
      "device_id": "11:22:33:44:55:66",
      "timestamp": "2026-02-01T14:30:00",
      "rssi_delta": 10,
      "distance_delta_m": -2.5,
      "direction": "approaching",
      "velocity_m_s": 0.5
    }
  ],
  "count": 1
}

Get Alerts

GET /api/history/alerts

Query Parameters:

Param Type Description
acknowledged boolean Filter by acknowledged status
type string Filter by type: new_device, device_absent, rssi_threshold
limit integer Max results (default: 50)

Response:

{
  "alerts": [
    {
      "id": 1,
      "alert_type": "new_device",
      "device_id": "11:22:33:44:55:66",
      "timestamp": "2026-02-01T14:30:00",
      "message": "New Bluetooth device detected: iPhone (Apple)",
      "acknowledged": 0
    }
  ],
  "count": 1
}

Acknowledge Alert

POST /api/history/alerts/<alert_id>/acknowledge

Get Activity Summary

GET /api/history/activity

Query Parameters:

Param Type Default Description
hours integer 24 Period in hours

Response:

{
  "period_hours": 24,
  "since": "2026-01-31T14:30:00",
  "active_wifi_devices": 12,
  "active_bt_devices": 8,
  "total_observations": 2500,
  "movement_events": 15,
  "new_devices": 2,
  "scan_count": 288
}

Get Database Stats

GET /api/history/stats

Response:

{
  "total_devices": 45,
  "total_observations": 50000,
  "total_scans": 1200,
  "total_movement_events": 300,
  "unread_alerts": 5,
  "database_size_bytes": 5242880,
  "database_size_mb": 5.0
}

Manual Cleanup

Trigger data cleanup (removes old records).

POST /api/history/cleanup

Request Body:

{"retention_days": 30}

Response:

{
  "retention_days": 30,
  "cutoff": "2026-01-02T14:30:00",
  "cleaned_at": "2026-02-01T14:30:00"
}

Error Responses

All endpoints return errors in this format:

{"error": "Error message here"}

Common HTTP Status Codes:

Code Description
200 Success
400 Bad request (missing/invalid parameters)
404 Resource not found
500 Internal server error
503 Database not enabled