|
@@ -0,0 +1,975 @@
|
|
|
|
|
+# MyBeacon API Documentation
|
|
|
|
|
+
|
|
|
|
|
+## Overview
|
|
|
|
|
+
|
|
|
|
|
+MyBeacon device provides two types of APIs:
|
|
|
|
|
+1. **Device API** - HTTP API running on the device (port 80)
|
|
|
|
|
+2. **Server API** - Backend endpoints that device communicates with
|
|
|
|
|
+
|
|
|
|
|
+**Device Identification:**
|
|
|
|
|
+- `device_id`: eth0 MAC address (e.g., `38:54:39:4b:1b:ad`)
|
|
|
|
|
+- `device_token`: Authentication token (received during registration)
|
|
|
|
|
+- `device_password`: 8-digit PIN for dashboard access
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Table of Contents
|
|
|
|
|
+
|
|
|
|
|
+- [Device API](#device-api) - Running on device
|
|
|
|
|
+ - [GET /api/status](#get-apistatus)
|
|
|
|
|
+ - [GET /api/metrics](#get-apimetrics)
|
|
|
|
|
+ - [GET /api/config](#get-apiconfig)
|
|
|
|
|
+ - [GET /api/ble/recent](#get-apiblerecent)
|
|
|
|
|
+ - [GET /api/wifi/recent](#get-apiwifirecent)
|
|
|
|
|
+ - [GET /api/logs](#get-apilogs)
|
|
|
|
|
+ - [GET /api/kernel-logs](#get-apikernel-logs)
|
|
|
|
|
+ - [POST /api/unlock](#post-apiunlock)
|
|
|
|
|
+ - [POST /api/settings](#post-apisettings)
|
|
|
|
|
+ - [WebSocket /api/ws](#websocket-apiws)
|
|
|
|
|
+- [Server API](#server-api) - Backend endpoints
|
|
|
|
|
+ - [POST /api/v1/registration](#post-apiv1registration)
|
|
|
|
|
+ - [GET /api/v1/config](#get-apiv1config)
|
|
|
|
|
+ - [POST /api/v1/ble](#post-apiv1ble)
|
|
|
|
|
+ - [POST /api/v1/wifi](#post-apiv1wifi)
|
|
|
|
|
+ - [POST /api/v1/wifi-credentials](#post-apiv1wifi-credentials)
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Device API
|
|
|
|
|
+
|
|
|
|
|
+Base URL: `http://<device-ip>` (default port 80)
|
|
|
|
|
+
|
|
|
|
|
+All responses include CORS headers:
|
|
|
|
|
+```
|
|
|
|
|
+Access-Control-Allow-Origin: *
|
|
|
|
|
+Access-Control-Allow-Methods: GET, POST, OPTIONS
|
|
|
|
|
+Access-Control-Allow-Headers: Content-Type, Authorization
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### GET /api/status
|
|
|
|
|
+
|
|
|
|
|
+Returns current device status including network state, scanners status, and counters.
|
|
|
|
|
+
|
|
|
|
|
+**Request:**
|
|
|
|
|
+```http
|
|
|
|
|
+GET /api/status HTTP/1.1
|
|
|
|
|
+Host: 192.168.5.244
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Response:** `200 OK`
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "device_id": "38:54:39:4b:1b:ad",
|
|
|
|
|
+ "registered": true,
|
|
|
|
|
+ "mode": "cloud",
|
|
|
|
|
+ "uptime_sec": 45652,
|
|
|
|
|
+ "network": {
|
|
|
|
|
+ "eth0_ip": "192.168.5.244/24",
|
|
|
|
|
+ "eth0_mac": "38:54:39:4b:1b:ad",
|
|
|
|
|
+ "eth0_rx": 29226155,
|
|
|
|
|
+ "eth0_tx": 53569343,
|
|
|
|
|
+ "wlan0_ip": "192.168.5.100/24",
|
|
|
|
|
+ "wlan0_mac": "38:54:39:4b:1b:ac",
|
|
|
|
|
+ "wlan0_ssid": "MyNetwork",
|
|
|
|
|
+ "wlan0_signal": -45,
|
|
|
|
|
+ "wlan0_channel": 6,
|
|
|
|
|
+ "wlan0_gateway": "192.168.5.1",
|
|
|
|
|
+ "wlan0_dns": "192.168.5.1",
|
|
|
|
|
+ "wlan0_rx": 1234567,
|
|
|
|
|
+ "wlan0_tx": 7654321,
|
|
|
|
|
+ "gateway": "192.168.5.1",
|
|
|
|
|
+ "dns": "192.168.5.1",
|
|
|
|
|
+ "ntp": "pool.ntp.org",
|
|
|
|
|
+ "ap_active": false
|
|
|
|
|
+ },
|
|
|
|
|
+ "scanners": {
|
|
|
|
|
+ "ble_running": true,
|
|
|
|
|
+ "wifi_running": false
|
|
|
|
|
+ },
|
|
|
|
|
+ "counters": {
|
|
|
|
|
+ "ble_events": 12345,
|
|
|
|
|
+ "wifi_events": 6789,
|
|
|
|
|
+ "uploads": 42,
|
|
|
|
|
+ "errors": 0
|
|
|
|
|
+ },
|
|
|
|
|
+ "server_ok": true
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Fields:**
|
|
|
|
|
+- `device_id`: Device MAC address (eth0)
|
|
|
|
|
+- `registered`: Whether device is registered on server
|
|
|
|
|
+- `mode`: Operating mode (`cloud` or `lan`)
|
|
|
|
|
+- `uptime_sec`: System uptime in seconds
|
|
|
|
|
+- `network.eth0_*`: Ethernet interface stats
|
|
|
|
|
+- `network.wlan0_*`: WiFi interface stats (only when connected)
|
|
|
|
|
+- `network.ap_active`: Whether AP fallback is active
|
|
|
|
|
+- `scanners.*_running`: Scanner status
|
|
|
|
|
+- `counters`: Event and upload counters
|
|
|
|
|
+- `server_ok`: Server connection status
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### GET /api/metrics
|
|
|
|
|
+
|
|
|
|
|
+Returns system metrics (CPU, memory, temperature, load).
|
|
|
|
|
+
|
|
|
|
|
+**Request:**
|
|
|
|
|
+```http
|
|
|
|
|
+GET /api/metrics HTTP/1.1
|
|
|
|
|
+Host: 192.168.5.244
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Response:** `200 OK`
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "cpu_percent": 15.5,
|
|
|
|
|
+ "mem_used_mb": 42.3,
|
|
|
|
|
+ "mem_total_mb": 245.0,
|
|
|
|
|
+ "temperature": 45.2,
|
|
|
|
|
+ "load_avg": 0.42,
|
|
|
|
|
+ "load_1m": 0.42,
|
|
|
|
|
+ "load_5m": 0.35,
|
|
|
|
|
+ "load_15m": 0.28
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Fields:**
|
|
|
|
|
+- `cpu_percent`: CPU usage percentage
|
|
|
|
|
+- `mem_used_mb`: Used memory in MB
|
|
|
|
|
+- `mem_total_mb`: Total memory in MB
|
|
|
|
|
+- `temperature`: SoC temperature in °C
|
|
|
|
|
+- `load_avg`: 1-minute load average
|
|
|
|
|
+- `load_1m/5m/15m`: Load averages
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### GET /api/config
|
|
|
|
|
+
|
|
|
|
|
+Returns current device configuration (without secrets).
|
|
|
|
|
+
|
|
|
|
|
+**Request:**
|
|
|
|
|
+```http
|
|
|
|
|
+GET /api/config HTTP/1.1
|
|
|
|
|
+Host: 192.168.5.244
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Response:** `200 OK`
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "mode": "cloud",
|
|
|
|
|
+ "api_base": "http://server:8000/api/v1",
|
|
|
|
|
+ "ble": {
|
|
|
|
|
+ "enabled": true,
|
|
|
|
|
+ "batch_interval_ms": 2500
|
|
|
|
|
+ },
|
|
|
|
|
+ "wifi": {
|
|
|
|
|
+ "monitor_enabled": true,
|
|
|
|
|
+ "client_enabled": false,
|
|
|
|
|
+ "ssid": "",
|
|
|
|
|
+ "batch_interval_ms": 10000
|
|
|
|
|
+ },
|
|
|
|
|
+ "network": {
|
|
|
|
|
+ "ntp_servers": ["pool.ntp.org"],
|
|
|
|
|
+ "eth0": {
|
|
|
|
|
+ "static": false,
|
|
|
|
|
+ "address": "",
|
|
|
|
|
+ "gateway": "",
|
|
|
|
|
+ "dns": ""
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ "dashboard": {
|
|
|
|
|
+ "enabled": true
|
|
|
|
|
+ },
|
|
|
|
|
+ "ssh_tunnel": {
|
|
|
|
|
+ "enabled": false,
|
|
|
|
|
+ "server": "",
|
|
|
|
|
+ "port": 22,
|
|
|
|
|
+ "user": "tunnel",
|
|
|
|
|
+ "remote_port": 0
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Note:** Sensitive fields (passwords, keys) are omitted from response.
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### GET /api/ble/recent
|
|
|
|
|
+
|
|
|
|
|
+Returns recent BLE events (last 100, kept for 15 seconds).
|
|
|
|
|
+
|
|
|
|
|
+**Request:**
|
|
|
|
|
+```http
|
|
|
|
|
+GET /api/ble/recent HTTP/1.1
|
|
|
|
|
+Host: 192.168.5.244
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Response:** `200 OK`
|
|
|
|
|
+```json
|
|
|
|
|
+[
|
|
|
|
|
+ {
|
|
|
|
|
+ "type": "ibeacon",
|
|
|
|
|
+ "mac": "AA:BB:CC:DD:EE:FF",
|
|
|
|
|
+ "rssi": -65,
|
|
|
|
|
+ "ts_ms": 1703001234567,
|
|
|
|
|
+ "uuid": "f7826da64fa24e988024bc5b71e0893e",
|
|
|
|
|
+ "major": 100,
|
|
|
|
|
+ "minor": 1,
|
|
|
|
|
+ "tx_power": -59
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "type": "my-beacon_acc",
|
|
|
|
|
+ "mac": "11:22:33:44:55:66",
|
|
|
|
|
+ "rssi": -72,
|
|
|
|
|
+ "ts_ms": 1703001234568,
|
|
|
|
|
+ "x": 123,
|
|
|
|
|
+ "y": -45,
|
|
|
|
|
+ "z": 678,
|
|
|
|
|
+ "bat": 95,
|
|
|
|
|
+ "temp": 25.5
|
|
|
|
|
+ }
|
|
|
|
|
+]
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**BLE Event Types:**
|
|
|
|
|
+- `ibeacon`: Apple iBeacon format
|
|
|
|
|
+- `my-beacon_acc`: Custom accelerometer beacon
|
|
|
|
|
+- `rt_mybeacon`: Relay beacon
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### GET /api/wifi/recent
|
|
|
|
|
+
|
|
|
|
|
+Returns recent WiFi probe requests (last 100).
|
|
|
|
|
+
|
|
|
|
|
+**Request:**
|
|
|
|
|
+```http
|
|
|
|
|
+GET /api/wifi/recent HTTP/1.1
|
|
|
|
|
+Host: 192.168.5.244
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Response:** `200 OK`
|
|
|
|
|
+```json
|
|
|
|
|
+[
|
|
|
|
|
+ {
|
|
|
|
|
+ "mac": "AA:BB:CC:DD:EE:FF",
|
|
|
|
|
+ "rssi": -55,
|
|
|
|
|
+ "ts_ms": 1703001234567,
|
|
|
|
|
+ "ssid": "MyNetwork",
|
|
|
|
|
+ "freq": 2437,
|
|
|
|
|
+ "channel": 6
|
|
|
|
|
+ }
|
|
|
|
|
+]
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### GET /api/logs
|
|
|
|
|
+
|
|
|
|
|
+Returns recent daemon log lines (last 500).
|
|
|
|
|
+
|
|
|
|
|
+**Request:**
|
|
|
|
|
+```http
|
|
|
|
|
+GET /api/logs HTTP/1.1
|
|
|
|
|
+Host: 192.168.5.244
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Response:** `200 OK`
|
|
|
|
|
+```json
|
|
|
|
|
+[
|
|
|
|
|
+ "12:36:28 [ble] Uploaded 2 events to server",
|
|
|
|
|
+ "12:36:31 [ble] Uploaded 1 events to server",
|
|
|
|
|
+ "12:36:33 [scanner] BLE scanner started (pid=1234)"
|
|
|
|
|
+]
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### GET /api/kernel-logs
|
|
|
|
|
+
|
|
|
|
|
+Returns kernel log messages from `dmesg` (last 500 lines).
|
|
|
|
|
+
|
|
|
|
|
+**Request:**
|
|
|
|
|
+```http
|
|
|
|
|
+GET /api/kernel-logs HTTP/1.1
|
|
|
|
|
+Host: 192.168.5.244
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Response:** `200 OK`
|
|
|
|
|
+```json
|
|
|
|
|
+[
|
|
|
|
|
+ "[45666.294334] aicwf_sdio mmc1:7a8a:1 wlan0: CLOSE",
|
|
|
|
|
+ "[45666.295543] ieee80211 phy0: HT supp 1, VHT supp 1, HE supp 1"
|
|
|
|
|
+]
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Note:** BusyBox dmesg doesn't support `-T` flag, timestamps are in `[seconds.microseconds]` format since boot.
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### POST /api/unlock
|
|
|
|
|
+
|
|
|
|
|
+Validates device password and creates a session.
|
|
|
|
|
+
|
|
|
|
|
+**Request:**
|
|
|
|
|
+```http
|
|
|
|
|
+POST /api/unlock HTTP/1.1
|
|
|
|
|
+Host: 192.168.5.244
|
|
|
|
|
+Content-Type: application/json
|
|
|
|
|
+
|
|
|
|
|
+{
|
|
|
|
|
+ "password": "82680499"
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Response:** `200 OK`
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "token": "abc123def456..."
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Error Response:** `401 Unauthorized`
|
|
|
|
|
+```
|
|
|
|
|
+Invalid password
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### POST /api/settings
|
|
|
|
|
+
|
|
|
|
|
+Updates device settings (requires valid password).
|
|
|
|
|
+
|
|
|
|
|
+**Request:**
|
|
|
|
|
+```http
|
|
|
|
|
+POST /api/settings HTTP/1.1
|
|
|
|
|
+Host: 192.168.5.244
|
|
|
|
|
+Content-Type: application/json
|
|
|
|
|
+
|
|
|
|
|
+{
|
|
|
|
|
+ "password": "82680499",
|
|
|
|
|
+ "settings": {
|
|
|
|
|
+ "mode": "cloud",
|
|
|
|
|
+ "wifi_client_enabled": true,
|
|
|
|
|
+ "wifi_ssid": "MyNetwork",
|
|
|
|
|
+ "wifi_psk": "password123",
|
|
|
|
|
+ "wifi_monitor_enabled": false,
|
|
|
|
|
+ "eth0_mode": "dhcp",
|
|
|
|
|
+ "ntp_servers": "pool.ntp.org,time.google.com"
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Settings Fields:**
|
|
|
|
|
+- `mode`: `"cloud"` or `"lan"`
|
|
|
|
|
+- `wifi_client_enabled`: Enable WiFi client
|
|
|
|
|
+- `wifi_ssid`: WiFi network name
|
|
|
|
|
+- `wifi_psk`: WiFi password
|
|
|
|
|
+- `wifi_monitor_enabled`: Enable WiFi scanner (LAN mode only)
|
|
|
|
|
+- `eth0_mode`: `"dhcp"` or `"static"`
|
|
|
|
|
+- `eth0_ip`: Static IP (when `eth0_mode="static"`)
|
|
|
|
|
+- `eth0_gateway`: Gateway (static mode)
|
|
|
|
|
+- `eth0_dns`: DNS server (static mode)
|
|
|
|
|
+- `ntp_servers`: Comma-separated NTP servers
|
|
|
|
|
+- `ble_enabled`: Enable BLE scanner (LAN mode only)
|
|
|
|
|
+- `ble_batch_interval_ms`: BLE batch interval
|
|
|
|
|
+- `wifi_monitor_batch_interval_ms`: WiFi batch interval
|
|
|
|
|
+
|
|
|
|
|
+**Response:** `200 OK`
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "success": true
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Error Response:** `401 Unauthorized`
|
|
|
|
|
+```
|
|
|
|
|
+Invalid password
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Note:**
|
|
|
|
|
+- In Cloud mode, scanner settings come from server
|
|
|
|
|
+- In LAN mode, scanner settings are local
|
|
|
|
|
+- WiFi client settings work in both modes
|
|
|
|
|
+- Changes to WiFi credentials in Cloud mode are also sent to server
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### WebSocket /api/ws
|
|
|
|
|
+
|
|
|
|
|
+Real-time event stream for dashboard updates.
|
|
|
|
|
+
|
|
|
|
|
+**Connection:**
|
|
|
|
|
+```javascript
|
|
|
|
|
+const ws = new WebSocket('ws://192.168.5.244/api/ws');
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Message Format:**
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "type": "ble",
|
|
|
|
|
+ "event": {
|
|
|
|
|
+ "mac": "AA:BB:CC:DD:EE:FF",
|
|
|
|
|
+ "rssi": -65,
|
|
|
|
|
+ "ts_ms": 1703001234567
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Message Types:**
|
|
|
|
|
+- `type: "ble"`: BLE event
|
|
|
|
|
+- `type: "wifi"`: WiFi event
|
|
|
|
|
+- `type: "log"`: Log message
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Server API
|
|
|
|
|
+
|
|
|
|
|
+Base URL: Configured in device settings (default: `http://server:8000/api/v1`)
|
|
|
|
|
+
|
|
|
|
|
+Authentication: Bearer token in `Authorization` header (except registration).
|
|
|
|
|
+
|
|
|
|
|
+### POST /api/v1/registration
|
|
|
|
|
+
|
|
|
|
|
+Registers a new device with the server. Called once on first boot.
|
|
|
|
|
+
|
|
|
|
|
+**Request:**
|
|
|
|
|
+```http
|
|
|
|
|
+POST /api/v1/registration HTTP/1.1
|
|
|
|
|
+Host: server:8000
|
|
|
|
|
+Content-Type: application/json
|
|
|
|
|
+
|
|
|
|
|
+{
|
|
|
|
|
+ "device_id": "38:54:39:4b:1b:ad",
|
|
|
|
|
+ "eth_ip": "192.168.5.244",
|
|
|
|
|
+ "wlan_ip": "192.168.5.100",
|
|
|
|
|
+ "ssh_public_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA..."
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Fields:**
|
|
|
|
|
+- `device_id`: Device MAC address (eth0)
|
|
|
|
|
+- `eth_ip`: Ethernet IP address (optional)
|
|
|
|
|
+- `wlan_ip`: WiFi IP address (optional)
|
|
|
|
|
+- `ssh_public_key`: SSH public key for tunnel (optional)
|
|
|
|
|
+
|
|
|
|
|
+**Response:** `201 Created`
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "device_token": "gRMRUKnqO9KXikBzoKhs0aE3uDYUvTxHYuU4/uatyrc=",
|
|
|
|
|
+ "device_password": "82680499",
|
|
|
|
|
+ "ssh_tunnel": {
|
|
|
|
|
+ "enabled": true,
|
|
|
|
|
+ "remote_port": 50123,
|
|
|
|
|
+ "server": "tunnel.example.com"
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Response Fields:**
|
|
|
|
|
+- `device_token`: Authentication token for API calls (save to `/opt/mybeacon/etc/device.json`)
|
|
|
|
|
+- `device_password`: 8-digit PIN for dashboard (save to device.json)
|
|
|
|
|
+- `ssh_tunnel`: SSH tunnel configuration (optional)
|
|
|
|
|
+
|
|
|
|
|
+**Error Response:** `400 Bad Request`
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "error": "device_id is required"
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### GET /api/v1/config
|
|
|
|
|
+
|
|
|
|
|
+Fetches device configuration from server (Cloud mode only, polled every 30 seconds).
|
|
|
|
|
+
|
|
|
|
|
+**Request:**
|
|
|
|
|
+```http
|
|
|
|
|
+GET /api/v1/config?device_id=38:54:39:4b:1b:ad HTTP/1.1
|
|
|
|
|
+Host: server:8000
|
|
|
|
|
+Authorization: Bearer gRMRUKnqO9KXikBzoKhs0aE3uDYUvTxHYuU4/uatyrc=
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Response:** `200 OK`
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "force_cloud": false,
|
|
|
|
|
+ "ble": {
|
|
|
|
|
+ "enabled": true,
|
|
|
|
|
+ "batch_interval_ms": 2500,
|
|
|
|
|
+ "uuid_filter_hex": ""
|
|
|
|
|
+ },
|
|
|
|
|
+ "wifi": {
|
|
|
|
|
+ "client_enabled": false,
|
|
|
|
|
+ "ssid": "",
|
|
|
|
|
+ "psk": "",
|
|
|
|
|
+ "monitor_enabled": true,
|
|
|
|
|
+ "batch_interval_ms": 10000
|
|
|
|
|
+ },
|
|
|
|
|
+ "ssh_tunnel": {
|
|
|
|
|
+ "enabled": true,
|
|
|
|
|
+ "server": "tunnel.example.com",
|
|
|
|
|
+ "port": 22,
|
|
|
|
|
+ "user": "tunnel",
|
|
|
|
|
+ "remote_port": 50123,
|
|
|
|
|
+ "keepalive_interval": 30
|
|
|
|
|
+ },
|
|
|
|
|
+ "dashboard_tunnel": {
|
|
|
|
|
+ "enabled": true,
|
|
|
|
|
+ "server": "tunnel.example.com",
|
|
|
|
|
+ "port": 22,
|
|
|
|
|
+ "user": "tunnel",
|
|
|
|
|
+ "remote_port": 60123,
|
|
|
|
|
+ "keepalive_interval": 30
|
|
|
|
|
+ },
|
|
|
|
|
+ "dashboard": {
|
|
|
|
|
+ "enabled": true
|
|
|
|
|
+ },
|
|
|
|
|
+ "net": {
|
|
|
|
|
+ "ntp": {
|
|
|
|
|
+ "servers": ["pool.ntp.org", "time.google.com"]
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ "debug": false
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Configuration Priority:**
|
|
|
|
|
+- **Cloud mode:** Server settings override local for BLE, WiFi, NTP
|
|
|
|
|
+- **LAN mode:** Local settings have priority
|
|
|
|
|
+- **Always from server:** SSH tunnel, Dashboard tunnel, Dashboard enable/disable
|
|
|
|
|
+- **Always local:** eth0 network settings
|
|
|
|
|
+
|
|
|
|
|
+**Error Response:** `401 Unauthorized`
|
|
|
|
|
+```
|
|
|
|
|
+Invalid or missing token
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### POST /api/v1/ble
|
|
|
|
|
+
|
|
|
|
|
+Uploads batch of BLE events (gzip compressed).
|
|
|
|
|
+
|
|
|
|
|
+**Request:**
|
|
|
|
|
+```http
|
|
|
|
|
+POST /api/v1/ble HTTP/1.1
|
|
|
|
|
+Host: server:8000
|
|
|
|
|
+Authorization: Bearer gRMRUKnqO9KXikBzoKhs0aE3uDYUvTxHYuU4/uatyrc=
|
|
|
|
|
+Content-Type: application/json
|
|
|
|
|
+Content-Encoding: gzip
|
|
|
|
|
+
|
|
|
|
|
+<gzipped JSON payload>
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Uncompressed Payload:**
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "device_id": "38:54:39:4b:1b:ad",
|
|
|
|
|
+ "events": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "type": "ibeacon",
|
|
|
|
|
+ "mac": "AA:BB:CC:DD:EE:FF",
|
|
|
|
|
+ "rssi": -65,
|
|
|
|
|
+ "ts_ms": 1703001234567,
|
|
|
|
|
+ "uuid": "f7826da64fa24e988024bc5b71e0893e",
|
|
|
|
|
+ "major": 100,
|
|
|
|
|
+ "minor": 1,
|
|
|
|
|
+ "tx_power": -59
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "type": "my-beacon_acc",
|
|
|
|
|
+ "mac": "11:22:33:44:55:66",
|
|
|
|
|
+ "rssi": -72,
|
|
|
|
|
+ "ts_ms": 1703001234568,
|
|
|
|
|
+ "x": 123,
|
|
|
|
|
+ "y": -45,
|
|
|
|
|
+ "z": 678,
|
|
|
|
|
+ "bat": 95,
|
|
|
|
|
+ "temp": 25.5,
|
|
|
|
|
+ "ff": false
|
|
|
|
|
+ }
|
|
|
|
|
+ ]
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Event Types and Fields:**
|
|
|
|
|
+
|
|
|
|
|
+**iBeacon:**
|
|
|
|
|
+- `type`: `"ibeacon"`
|
|
|
|
|
+- `mac`: Device MAC address
|
|
|
|
|
+- `rssi`: Signal strength (dBm)
|
|
|
|
|
+- `ts_ms`: Timestamp (milliseconds since epoch)
|
|
|
|
|
+- `uuid`: iBeacon UUID (32 hex chars, no dashes)
|
|
|
|
|
+- `major`: Major value (0-65535)
|
|
|
|
|
+- `minor`: Minor value (0-65535)
|
|
|
|
|
+- `tx_power`: Calibrated TX power
|
|
|
|
|
+
|
|
|
|
|
+**my-beacon_acc:**
|
|
|
|
|
+- `type`: `"my-beacon_acc"`
|
|
|
|
|
+- `mac`: Device MAC address
|
|
|
|
|
+- `rssi`: Signal strength (dBm)
|
|
|
|
|
+- `ts_ms`: Timestamp
|
|
|
|
|
+- `x`, `y`, `z`: Accelerometer values
|
|
|
|
|
+- `bat`: Battery level (0-100)
|
|
|
|
|
+- `temp`: Temperature (°C)
|
|
|
|
|
+- `ff`: Free fall detected (boolean)
|
|
|
|
|
+
|
|
|
|
|
+**rt_mybeacon (Relay):**
|
|
|
|
|
+- `type`: `"rt_mybeacon"`
|
|
|
|
|
+- `mac`: Relay device MAC
|
|
|
|
|
+- `rssi`: Signal strength at relay
|
|
|
|
|
+- `ts_ms`: Timestamp
|
|
|
|
|
+- `relay_mac`: Original beacon MAC
|
|
|
|
|
+- `relay_rssi`: Original RSSI
|
|
|
|
|
+
|
|
|
|
|
+**Response:** `200 OK`
|
|
|
|
|
+
|
|
|
|
|
+**Error Response:** `401 Unauthorized` / `500 Internal Server Error`
|
|
|
|
|
+
|
|
|
|
|
+**Notes:**
|
|
|
|
|
+- Device retries up to 3 times on failure
|
|
|
|
|
+- Failed batches are spooled to `/var/spool/mybeacon/ble/` (max 100MB)
|
|
|
|
|
+- Batching interval: 2.5 seconds (default)
|
|
|
|
|
+- Average batch size: 5-12 events
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### POST /api/v1/wifi
|
|
|
|
|
+
|
|
|
|
|
+Uploads batch of WiFi probe requests (gzip compressed).
|
|
|
|
|
+
|
|
|
|
|
+**Request:**
|
|
|
|
|
+```http
|
|
|
|
|
+POST /api/v1/wifi HTTP/1.1
|
|
|
|
|
+Host: server:8000
|
|
|
|
|
+Authorization: Bearer gRMRUKnqO9KXikBzoKhs0aE3uDYUvTxHYuU4/uatyrc=
|
|
|
|
|
+Content-Type: application/json
|
|
|
|
|
+Content-Encoding: gzip
|
|
|
|
|
+
|
|
|
|
|
+<gzipped JSON payload>
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Uncompressed Payload:**
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "device_id": "38:54:39:4b:1b:ad",
|
|
|
|
|
+ "events": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "mac": "AA:BB:CC:DD:EE:FF",
|
|
|
|
|
+ "rssi": -55,
|
|
|
|
|
+ "ts_ms": 1703001234567,
|
|
|
|
|
+ "ssid": "MyNetwork",
|
|
|
|
|
+ "freq": 2437,
|
|
|
|
|
+ "channel": 6
|
|
|
|
|
+ }
|
|
|
|
|
+ ]
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Event Fields:**
|
|
|
|
|
+- `mac`: Device MAC address
|
|
|
|
|
+- `rssi`: Signal strength (dBm)
|
|
|
|
|
+- `ts_ms`: Timestamp (milliseconds since epoch)
|
|
|
|
|
+- `ssid`: Network SSID (may be empty for probe requests)
|
|
|
|
|
+- `freq`: Frequency (MHz)
|
|
|
|
|
+- `channel`: WiFi channel
|
|
|
|
|
+
|
|
|
|
|
+**Response:** `200 OK`
|
|
|
|
|
+
|
|
|
|
|
+**Notes:**
|
|
|
|
|
+- Batching interval: 10 seconds (default)
|
|
|
|
|
+- Average batch size: 10-200 events
|
|
|
|
|
+- Spool directory: `/var/spool/mybeacon/wifi/`
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### POST /api/v1/wifi-credentials
|
|
|
|
|
+
|
|
|
|
|
+Updates WiFi client credentials (Cloud mode only).
|
|
|
|
|
+
|
|
|
|
|
+**Request:**
|
|
|
|
|
+```http
|
|
|
|
|
+POST /api/v1/wifi-credentials HTTP/1.1
|
|
|
|
|
+Host: server:8000
|
|
|
|
|
+Authorization: Bearer gRMRUKnqO9KXikBzoKhs0aE3uDYUvTxHYuU4/uatyrc=
|
|
|
|
|
+Content-Type: application/json
|
|
|
|
|
+
|
|
|
|
|
+{
|
|
|
|
|
+ "ssid": "NewNetwork",
|
|
|
|
|
+ "psk": "password123"
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Response:** `200 OK`
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "success": true
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Purpose:**
|
|
|
|
|
+When user changes WiFi credentials via dashboard in Cloud mode, device:
|
|
|
|
|
+1. Saves credentials locally
|
|
|
|
|
+2. Connects to new network
|
|
|
|
|
+3. Sends credentials to server for centralized management
|
|
|
|
|
+
|
|
|
|
|
+Server can use this for:
|
|
|
|
|
+- Displaying current WiFi config in user dashboard
|
|
|
|
|
+- Remote WiFi management via config endpoint
|
|
|
|
|
+- Syncing settings across devices
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Error Codes
|
|
|
|
|
+
|
|
|
|
|
+**Device API:**
|
|
|
|
|
+- `200 OK`: Success
|
|
|
|
|
+- `401 Unauthorized`: Invalid password
|
|
|
|
|
+- `405 Method Not Allowed`: Wrong HTTP method
|
|
|
|
|
+- `500 Internal Server Error`: Server error
|
|
|
|
|
+
|
|
|
|
|
+**Server API:**
|
|
|
|
|
+- `200 OK`: Success
|
|
|
|
|
+- `201 Created`: Resource created
|
|
|
|
|
+- `400 Bad Request`: Invalid request
|
|
|
|
|
+- `401 Unauthorized`: Invalid/missing token
|
|
|
|
|
+- `500 Internal Server Error`: Server error
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Data Flow
|
|
|
|
|
+
|
|
|
|
|
+### Device Startup
|
|
|
|
|
+1. Device boots, reads `/opt/mybeacon/etc/device.json`
|
|
|
|
|
+2. If `device_token` missing → POST `/api/v1/registration`
|
|
|
|
|
+3. Save token and password to `device.json`
|
|
|
|
|
+4. Start polling GET `/api/v1/config` every 30s (Cloud mode)
|
|
|
|
|
+
|
|
|
|
|
+### Event Upload
|
|
|
|
|
+1. BLE/WiFi scanner publishes to ZMQ
|
|
|
|
|
+2. Daemon batches events (2.5s for BLE, 10s for WiFi)
|
|
|
|
|
+3. Gzip compress → POST `/api/v1/ble` or `/api/v1/wifi`
|
|
|
|
|
+4. On failure → spool to disk, retry later
|
|
|
|
|
+
|
|
|
|
|
+### Configuration Management
|
|
|
|
|
+1. **Cloud mode:** Server config overrides local (via `/api/v1/config`)
|
|
|
|
|
+2. **LAN mode:** Local config used, no polling
|
|
|
|
|
+3. User changes via dashboard → POST `/api/settings` → apply locally
|
|
|
|
|
+4. In Cloud mode, WiFi credentials also sent to server
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Authentication
|
|
|
|
|
+
|
|
|
|
|
+**Server API:**
|
|
|
|
|
+- Uses Bearer token authentication
|
|
|
|
|
+- Token received during registration
|
|
|
|
|
+- Include in header: `Authorization: Bearer <token>`
|
|
|
|
|
+
|
|
|
|
|
+**Device API:**
|
|
|
|
|
+- Most endpoints are open (read-only)
|
|
|
|
|
+- Write endpoints require `device_password`
|
|
|
|
|
+- Password is 8-digit number generated during registration
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Network Modes
|
|
|
|
|
+
|
|
|
|
|
+### Cloud Mode (Default)
|
|
|
|
|
+- Config polled from server every 30s
|
|
|
|
|
+- BLE/WiFi scanner settings from server
|
|
|
|
|
+- Local changes to scanners ignored
|
|
|
|
|
+- WiFi client credentials sync with server
|
|
|
|
|
+- SSH/Dashboard tunnels controlled by server
|
|
|
|
|
+
|
|
|
|
|
+### LAN Mode
|
|
|
|
|
+- No config polling
|
|
|
|
|
+- All settings local
|
|
|
|
|
+- Manual configuration via dashboard
|
|
|
|
|
+- No server dependency (except registration)
|
|
|
|
|
+
|
|
|
|
|
+**Switching Modes:**
|
|
|
|
|
+Via dashboard → Settings → Mode → Apply
|
|
|
|
|
+
|
|
|
|
|
+**Force Cloud:**
|
|
|
|
|
+Server can set `force_cloud: true` in config to prevent mode switching (for support).
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Files
|
|
|
|
|
+
|
|
|
|
|
+**Configuration:**
|
|
|
|
|
+- `/opt/mybeacon/etc/config.json` - Local config
|
|
|
|
|
+- `/opt/mybeacon/etc/device.json` - Device state (token, password)
|
|
|
|
|
+- `/opt/mybeacon/etc/tunnel_key` - SSH private key
|
|
|
|
|
+
|
|
|
|
|
+**Logs:**
|
|
|
|
|
+- `/var/log/mybeacon.log` - Daemon logs (tmpfs)
|
|
|
|
|
+- Kernel logs via `dmesg`
|
|
|
|
|
+
|
|
|
|
|
+**Spool:**
|
|
|
|
|
+- `/var/spool/mybeacon/ble/` - Failed BLE batches
|
|
|
|
|
+- `/var/spool/mybeacon/wifi/` - Failed WiFi batches
|
|
|
|
|
+- Max total: 100MB
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Examples
|
|
|
|
|
+
|
|
|
|
|
+### Registering a New Device
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+curl -X POST http://server:8000/api/v1/registration \
|
|
|
|
|
+ -H "Content-Type: application/json" \
|
|
|
|
|
+ -d '{
|
|
|
|
|
+ "device_id": "38:54:39:4b:1b:ad",
|
|
|
|
|
+ "eth_ip": "192.168.5.244"
|
|
|
|
|
+ }'
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### Fetching Device Status
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+curl http://192.168.5.244/api/status | jq
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### Changing WiFi Settings
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+curl -X POST http://192.168.5.244/api/settings \
|
|
|
|
|
+ -H "Content-Type: application/json" \
|
|
|
|
|
+ -d '{
|
|
|
|
|
+ "password": "82680499",
|
|
|
|
|
+ "settings": {
|
|
|
|
|
+ "wifi_client_enabled": true,
|
|
|
|
|
+ "wifi_ssid": "MyNetwork",
|
|
|
|
|
+ "wifi_psk": "password123"
|
|
|
|
|
+ }
|
|
|
|
|
+ }'
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### Uploading BLE Events (with gzip)
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+# Prepare JSON
|
|
|
|
|
+echo '{
|
|
|
|
|
+ "device_id": "38:54:39:4b:1b:ad",
|
|
|
|
|
+ "events": [{"type":"ibeacon","mac":"AA:BB:CC:DD:EE:FF","rssi":-65,"ts_ms":1703001234567}]
|
|
|
|
|
+}' | gzip > /tmp/events.json.gz
|
|
|
|
|
+
|
|
|
|
|
+# Upload
|
|
|
|
|
+curl -X POST http://server:8000/api/v1/ble \
|
|
|
|
|
+ -H "Authorization: Bearer YOUR_TOKEN" \
|
|
|
|
|
+ -H "Content-Type: application/json" \
|
|
|
|
|
+ -H "Content-Encoding: gzip" \
|
|
|
|
|
+ --data-binary @/tmp/events.json.gz
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### WebSocket Example (JavaScript)
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+const ws = new WebSocket('ws://192.168.5.244/api/ws');
|
|
|
|
|
+
|
|
|
|
|
+ws.onmessage = (event) => {
|
|
|
|
|
+ const msg = JSON.parse(event.data);
|
|
|
|
|
+
|
|
|
|
|
+ if (msg.type === 'ble') {
|
|
|
|
|
+ console.log('BLE event:', msg.event);
|
|
|
|
|
+ } else if (msg.type === 'wifi') {
|
|
|
|
|
+ console.log('WiFi event:', msg.event);
|
|
|
|
|
+ } else if (msg.type === 'log') {
|
|
|
|
|
+ console.log('Log:', msg.message);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+ws.onopen = () => console.log('Connected');
|
|
|
|
|
+ws.onerror = (err) => console.error('Error:', err);
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Security Notes
|
|
|
|
|
+
|
|
|
|
|
+1. **Device Password:** 8-digit numeric PIN, generated during registration
|
|
|
|
|
+2. **Device Token:** Base64-encoded random token, store securely
|
|
|
|
|
+3. **HTTPS:** Not implemented on device (use VPN/tunnel for remote access)
|
|
|
|
|
+4. **SSH Tunnel:** Ed25519 key-based authentication
|
|
|
|
|
+5. **CORS:** Enabled on device API (allow all origins)
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Troubleshooting
|
|
|
|
|
+
|
|
|
|
|
+### Device not uploading events
|
|
|
|
|
+1. Check `GET /api/status` → `server_ok: true`
|
|
|
|
|
+2. Check logs: `GET /api/logs`
|
|
|
|
|
+3. Verify network: `GET /api/status` → `network`
|
|
|
|
|
+4. Check spool directory: `ls -lh /var/spool/mybeacon/`
|
|
|
|
|
+
|
|
|
|
|
+### WiFi scanner not working
|
|
|
|
|
+1. Check if WiFi client active: `GET /api/status` → `network.wlan0_ip`
|
|
|
|
|
+2. WiFi client and scanner can't run simultaneously
|
|
|
|
|
+3. Disable client or use AP mode
|
|
|
|
|
+4. Check AIC8800 chip conflicts in logs
|
|
|
|
|
+
|
|
|
|
|
+### Configuration not applying
|
|
|
|
|
+1. Cloud mode: Wait for next poll (30s) or restart daemon
|
|
|
|
|
+2. LAN mode: Check password and permissions
|
|
|
|
|
+3. Verify mode: `GET /api/config` → `mode`
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Appendix: BLE Event Formats
|
|
|
|
|
+
|
|
|
|
|
+### iBeacon Format
|
|
|
|
|
+```
|
|
|
|
|
+Company ID: 0x004C (Apple)
|
|
|
|
|
+Type: 0x02 0x15
|
|
|
|
|
+UUID: 16 bytes
|
|
|
|
|
+Major: 2 bytes (big-endian)
|
|
|
|
|
+Minor: 2 bytes (big-endian)
|
|
|
|
|
+TX Power: 1 byte (signed)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### my-beacon_acc Format
|
|
|
|
|
+```
|
|
|
|
|
+Company ID: 0x0059 (Nordic)
|
|
|
|
|
+Prefix: "acc" (3 bytes)
|
|
|
|
|
+X: 2 bytes (signed)
|
|
|
|
|
+Y: 2 bytes (signed)
|
|
|
|
|
+Z: 2 bytes (signed)
|
|
|
|
|
+Battery: 1 byte (0-100)
|
|
|
|
|
+Temp: 1 byte (signed, °C)
|
|
|
|
|
+Free Fall: 1 bit
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### rt_mybeacon Format
|
|
|
|
|
+```
|
|
|
|
|
+Company ID: 0xFFFF (Custom)
|
|
|
|
|
+Prefix: "rt" (2 bytes)
|
|
|
|
|
+Original MAC: 6 bytes
|
|
|
|
|
+Original RSSI: 1 byte (signed)
|
|
|
|
|
+Original payload: variable
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Version
|
|
|
|
|
+
|
|
|
|
|
+**API Version:** 1.0
|
|
|
|
|
+**Last Updated:** 2025-12-28
|
|
|
|
|
+**Device Firmware:** Alpine Linux + MyBeacon Native
|
|
|
|
|
+**Compatible with:** Backend API v1
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Support
|
|
|
|
|
+
|
|
|
|
|
+For issues or questions:
|
|
|
|
|
+- Check device logs: `GET /api/logs`
|
|
|
|
|
+- Check kernel logs: `GET /api/kernel-logs`
|
|
|
|
|
+- SSH to device: `ssh root@<device-ip>` (password: `1`)
|
|
|
|
|
+- Review daemon status: `/etc/init.d/S98mybeacon status`
|