# 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://` (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://192.168.5.4:8000/api/v1", "cfg_polling_timeout": 30, "ble": { "enabled": true, "batch_interval_ms": 2500, "upload_endpoint": "" }, "wifi": { "monitor_enabled": true, "client_enabled": false, "ssid": "MyNetwork", "psk": "", "batch_interval_ms": 10000, "upload_endpoint": "" }, "ssh_tunnel": { "enabled": false, "server": "", "port": 22, "user": "", "key_path": "", "remote_port": 0, "keepalive_interval": 30, "reconnect_delay": 5 }, "dashboard_tunnel": { "enabled": false, "server": "", "port": 22, "user": "", "remote_port": 0, "keepalive_interval": 30, "reconnect_delay": 5 }, "network": { "ntp_servers": ["pool.ntp.org", "time.google.com"], "eth0": { "static": false, "address": "", "gateway": "", "dns": "" } }, "ap_fallback": { "password": "mybeacon" }, "dashboard": { "enabled": true }, "zmq_addr_ble": "tcp://127.0.0.1:5555", "zmq_addr_wifi": "tcp://127.0.0.1:5556", "spool_dir": "/var/spool/mybeacon", "wifi_iface": "wlan0", "debug": false } ``` **Note:** Sensitive fields (`wifi.psk`, `ssh_tunnel.key_path`) are returned as empty strings. Device ID and token are omitted. --- ### 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": "lan", "wifi_client_enabled": true, "wifi_ssid": "MyNetwork", "wifi_psk": "password123", "wifi_monitor_enabled": true, "wifi_monitor_endpoint": "http://192.168.1.100:8080/wifi", "wifi_monitor_batch_interval_ms": 10000, "ble_enabled": true, "ble_batch_interval_ms": 2500, "ble_endpoint": "http://192.168.1.100:8080/ble", "eth0_mode": "dhcp", "ntp_servers": "pool.ntp.org,time.google.com" } } ``` **Settings Fields:** **Mode:** - `mode` (string): `"cloud"` or `"lan"`. In Cloud mode, server config has priority. In LAN mode, local settings have priority. **BLE Scanner (LAN mode only):** - `ble_enabled` (bool): Enable BLE scanner - `ble_batch_interval_ms` (int): BLE batch upload interval in milliseconds - `ble_endpoint` (string, optional): Custom BLE upload endpoint URL (full URL, e.g., "http://192.168.1.100:8080/ble") **WiFi Scanner (LAN mode only):** - `wifi_monitor_enabled` (bool): Enable WiFi monitor/scanner mode - `wifi_monitor_batch_interval_ms` (int): WiFi batch upload interval in milliseconds - `wifi_monitor_endpoint` (string, optional): Custom WiFi upload endpoint URL (full URL, e.g., "http://192.168.1.100:8080/wifi") **WiFi Client (both modes):** - `wifi_client_enabled` (bool): Enable WiFi client mode (connect to AP) - `wifi_ssid` (string): WiFi network SSID - `wifi_psk` (string): WiFi password (WPA/WPA2 pre-shared key) **Ethernet (always local):** - `eth0_mode` (string): `"dhcp"` or `"static"` - `eth0_ip` (string): Static IP address with CIDR (e.g., "192.168.1.100/24") when `eth0_mode="static"` - `eth0_gateway` (string): Gateway IP when `eth0_mode="static"` - `eth0_dns` (string): DNS server IP when `eth0_mode="static"` **NTP:** - `ntp_servers` (string): Comma-separated list of NTP server addresses (e.g., "pool.ntp.org,time.google.com") **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. Device polls this endpoint at interval specified by `cfg_polling_timeout` (default: 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, "cfg_polling_timeout": 30, "ble": { "enabled": true, "batch_interval_ms": 2500, "uuid_filter_hex": "f7826da64fa24e988024bc5b71e0893e", "upload_endpoint": "http://custom.example.com:8080/ble" }, "wifi": { "monitor_enabled": true, "client_enabled": true, "ssid": "MyNetwork", "psk": "mypassword123", "batch_interval_ms": 10000, "upload_endpoint": "http://custom.example.com:8080/wifi" }, "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 **Configuration Fields:** **Top-Level:** - `force_cloud` (bool): Override local mode setting to force Cloud mode. Used for remote support/management. When true, device switches from LAN to Cloud mode even if locally configured otherwise. - `cfg_polling_timeout` (int): Configuration polling interval in seconds (default: 30). Device fetches configuration from server at this interval. Minimum: 5 seconds, recommended: 30-300 seconds. - `debug` (bool): Enable debug logging **BLE Settings (`ble`):** - `enabled` (bool): Enable/disable BLE scanner - `batch_interval_ms` (int): Batch upload interval in milliseconds (default: 2500) - `uuid_filter_hex` (string, optional): Filter beacons by specific UUID. Only beacons matching this UUID will be reported. Format: 32 hex characters without dashes (e.g., "f7826da64fa24e988024bc5b71e0893e") - `upload_endpoint` (string, optional): Custom upload endpoint URL. If set, BLE events will be sent to this URL instead of `{api_base}/ble`. Must be full URL (e.g., "http://custom.example.com:8080/ble") **WiFi Settings (`wifi`):** - `monitor_enabled` (bool): Enable WiFi scanner (AP detection/monitor mode) - `client_enabled` (bool): Enable WiFi client mode (connect to AP) - `ssid` (string): WiFi network SSID to connect to (when client_enabled=true) - `psk` (string): WiFi password (WPA/WPA2 pre-shared key) - `batch_interval_ms` (int): Batch upload interval in milliseconds (default: 10000) - `upload_endpoint` (string, optional): Custom upload endpoint URL. If set, WiFi events will be sent to this URL instead of `{api_base}/wifi`. Must be full URL (e.g., "http://custom.example.com:8080/wifi") **SSH Tunnel (`ssh_tunnel`):** - `enabled` (bool): Enable SSH reverse tunnel for remote terminal access - `server` (string): SSH server hostname/IP - `port` (int): SSH server port (default: 22) - `user` (string): SSH username - `remote_port` (int): Remote port assigned for this device's tunnel - `keepalive_interval` (int): SSH keepalive interval in seconds (default: 30) **Dashboard Tunnel (`dashboard_tunnel`):** - `enabled` (bool): Enable SSH reverse tunnel for remote dashboard access - `server` (string): SSH server hostname/IP - `port` (int): SSH server port (default: 22) - `user` (string): SSH username - `remote_port` (int): Remote port assigned for dashboard tunnel - `keepalive_interval` (int): SSH keepalive interval in seconds (default: 30) **Dashboard (`dashboard`):** - `enabled` (bool): Enable/disable HTTP dashboard on port 80 **Network (`net`):** - `ntp.servers` ([]string): NTP server addresses (e.g., ["pool.ntp.org", "time.google.com"]) **Custom Upload Endpoints:** When `upload_endpoint` is set for BLE or WiFi, the device will send event batches to the specified URL instead of the default API base URL. This allows: - Directing data to different collection servers per device - Using separate data pipelines for BLE and WiFi - Custom data processing without modifying the main API - Multi-tenant setups where each client has their own endpoint The custom endpoint receives the same gzip-compressed JSON payload format as described in `/api/v1/ble` and `/api/v1/wifi` endpoints below. **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 ``` **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 ``` **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 ` **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@` (password: `1`) - Review daemon status: `/etc/init.d/S98mybeacon status`