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

751 lines
12 KiB
Markdown

# 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:**
```bash
curl -X POST http://localhost:5000/api/scan \
-H "Content-Type: application/json" \
-d '{"location": "kitchen", "scan_wifi": true, "scan_bluetooth": true}'
```
**Response:**
```json
{
"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:**
```json
[
{
"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:**
```bash
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:**
```json
{"lat": 50.8585, "lon": 4.3978}
```
**Response:**
```json
{"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:**
```bash
curl -X POST http://localhost:5000/api/config \
-H "Content-Type: application/json" \
-d '{"gps": {"latitude": 50.85, "longitude": 4.39}, "save": true}'
```
**Response:**
```json
{
"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:**
```json
{
"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:**
```json
{"floor": 2, "height_m": 6.0}
```
**Response:**
```json
{
"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:**
```json
{"distance": 5.5}
```
---
### Get All Floor Assignments
Retrieve all saved floor assignments.
```
GET /api/device/floors
```
**Response:**
```json
{
"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:**
```bash
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:**
```json
{"addresses": ["11:22:33:44:55:66", "AA:BB:CC:DD:EE:FF"]}
```
---
## Auto-Scan
### Get Status
```
GET /api/autoscan
```
**Response:**
```json
{
"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:**
```json
{"save": true}
```
---
### Update Settings
```
POST /api/autoscan/settings
```
**Request Body:**
```json
{"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{"label": "Living Room TV"}
```
---
### Toggle Favorite
```
POST /api/history/devices/<device_id>/favorite
```
**Request Body:**
```json
{"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{
"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:**
```json
{"retention_days": 30}
```
**Response:**
```json
{
"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:
```json
{"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 |