Difference between revisions of "API reference"
Jump to navigation
Jump to search
(Fix hostname: bcmeter-XXXX.local (last 4 hex chars of MAC)) |
(Update API reference to match current bcmeter-dev codebase: add incidents section to /api/logs, add identify/debug_mobile actions, add /api/maintenance-logs and /api/debug_mobile/status, add wifi/scan/refresh POST, update response schemas, add static routes, remove endpoints not in current codebase (cleanempty/export/factory_reset), add CORS note) |
||
| Line 1: | Line 1: | ||
== API Reference == | == API Reference == | ||
The bcMeter exposes a REST API on port 80. All endpoints are accessible without authentication when connected to the device network. | The bcMeter exposes a REST API on port 80. All endpoints are accessible without authentication when connected to the device network. CORS is enabled for all GET requests (<code>allow_origins=["*"]</code>). | ||
The software is open source: [https://github.com/dahljo/bcmeter github.com/dahljo/bcmeter] | The software is open source: [https://github.com/dahljo/bcmeter github.com/dahljo/bcmeter] | ||
| Line 10: | Line 10: | ||
! Method !! Endpoint !! Description | ! Method !! Endpoint !! Description | ||
|- | |- | ||
| GET || <code>/api/status</code> || Current measurement state, last sensor readings, error codes, sample count, WiFi mode, firmware version | | GET || <code>/api/status</code> || Current measurement state, last sensor readings, error codes, sample count, WiFi mode, firmware version, OTA info. Returns <code>"env": "pi"</code> to distinguish from ESP32 (<code>"env": "esp32"</code>). | ||
|- | |- | ||
| GET || <code>/api/system</code> || Hardware info: MAC address, memory, | | GET || <code>/api/system</code> || Hardware info: IP, MAC address, disk usage, memory, modem status, GPS detail, barometric altitude, geolocation, current time | ||
|- | |- | ||
| GET || <code>/api/logs</code> || Structured health report with sections: hardware, measurement, system, network | | GET || <code>/api/logs</code> || Structured health report as JSON with sections: <code>hardware</code>, <code>measurement</code>, <code>system</code>, <code>network</code>, <code>incidents</code>. Each entry has <code>{k, v, s}</code> (key, value, status: ok/warn/error/info). | ||
|- | |||
| GET || <code>/api/maintenance-logs</code> || Downloads a zip bundle containing: rotating bcmeter.log files, syslog, 10 newest CSV sessions, dmesg, journalctl for bcmeter and pigpiod services, config JSON, incident log. | |||
|- | |||
| GET || <code>/api/debug_mobile/status</code> || Returns modem debug send progress (from email handler). | |||
|} | |} | ||
=== Measurement Control === | === Measurement Control === | ||
All control is dispatched through a single endpoint with an <code>action</code> query parameter: | |||
{| class="wikitable" | {| class="wikitable" | ||
! Method !! Endpoint !! Description | ! Method !! Endpoint !! Description | ||
|- | |- | ||
| GET || <code>/api/control?action=start</code> || Begin measurement session | | GET || <code>/api/control?action=start</code> || Begin measurement session. Returns 409 if time not synced, 423 if never calibrated, 424 if calibration stale (>28 days). Add <code>&force=1</code> to override preflight checks. | ||
|- | |||
| GET || <code>/api/control?action=stop</code> || Stop measurement and save session file. | |||
|- | |||
| GET || <code>/api/control?action=calibrate</code> || Start calibration routine (returns 202 immediately — poll <code>/api/calibration</code> for progress). Requires sampling to be stopped. | |||
|- | |- | ||
| GET || <code>/api/ | | GET || <code>/api/calibration</code> || Calibration status: <code>{running, done, ok, elapsed_ms, log}</code>. | ||
|- | |- | ||
| GET || <code>/api/control?action= | | GET || <code>/api/control?action=clear_error</code> || Reset error state to ERR_NONE. | ||
|- | |- | ||
| GET || <code>/api/ | | GET || <code>/api/control?action=identify</code> || Triggers LED identify blink pattern (Morse code spelling "bcmeter" for 30 seconds). Useful for locating a specific device when multiple units are deployed. | ||
|- | |- | ||
| GET || <code>/api/control?action= | | GET || <code>/api/control?action=debug_mobile</code> || Triggers modem debug email via Lambda. Requires modem present. | ||
|} | |} | ||
| Line 40: | Line 50: | ||
| GET || <code>/api/config</code> || All settings as JSON. Each parameter includes type, value, label, tab, and description. | | GET || <code>/api/config</code> || All settings as JSON. Each parameter includes type, value, label, tab, and description. | ||
|- | |- | ||
| POST || <code>/api/config</code> || Update settings. JSON body with key-value pairs. Only changed values need to be sent. | | POST || <code>/api/config</code> || Update settings. JSON body with key-value pairs. Accepts <code>{key: value}</code> or <code>{key: {value: ...}}</code> format. Only changed values need to be sent. Triggers deferred modem onboarding if <code>mail_logs_to</code> is set. | ||
|- | |- | ||
| POST || <code>/api/device/rename</code> || Set device name. Body: <code>{"name": "bcmeter01"}</code> | | POST || <code>/api/device/rename</code> || Set device name and hostname. Body: <code>{"name": "bcmeter01"}</code> (1–32 chars). Runs <code>hostnamectl set-hostname</code>. | ||
|- | |- | ||
| GET || <code>/api/control?action=synctime&ts=EPOCH&tz=IANA</code> || Sync device clock. <code>ts</code> = Unix timestamp, <code>tz</code> = IANA timezone string. | | GET || <code>/api/control?action=synctime&ts=EPOCH&tz=IANA</code> || Sync device clock. <code>ts</code> = Unix timestamp, <code>tz</code> = IANA timezone string (e.g. <code>Europe/Berlin</code>). Applies timezone via <code>timedatectl</code>. | ||
|} | |} | ||
| Line 52: | Line 62: | ||
! Method !! Endpoint !! Description | ! Method !! Endpoint !! Description | ||
|- | |- | ||
| GET || <code>/api/wifi/scan</code> || List nearby networks. Add <code>?refresh=1</code> to trigger a new scan. | | GET || <code>/api/wifi/scan</code> || List nearby networks: <code>{scanning: bool, networks: [{ssid, rssi, secure}]}</code>. Add <code>?refresh=1</code> to trigger a new background scan. | ||
|- | |||
| POST || <code>/api/wifi/scan/refresh</code> || Explicitly trigger a new WiFi scan (returns 202, or 409 if already scanning). | |||
|- | |- | ||
| GET || <code>/api/wifi/status</code> || Current connection: mode ( | | GET || <code>/api/wifi/status</code> || Current connection: <code>{mode, status, ssid, ip, rssi, quality (0-4), internet, timeSynced}</code>. | ||
|- | |- | ||
| POST || <code>/api/wifi | | POST || <code>/api/wifi</code> || Save WiFi credentials. Body: <code>{"ssid": "...", "pass": "..."}</code> (password min 8 chars). | ||
|- | |- | ||
| | | POST || <code>/api/wifi/connect</code> || Save credentials and initiate background connection attempt (returns 202). Password must be 8–63 chars. Body: <code>{"ssid": "...", "pass": "..."}</code> | ||
|- | |- | ||
| | | GET || <code>/api/wifi/connect/status</code> || Connection progress: <code>{state: 0-3, elapsed, log, mode, ip, ssid, device_name, hostname}</code>. States: 0=idle, 1=connecting, 2=success, 3=failed. Poll after POST to <code>/api/wifi/connect</code>. | ||
|- | |- | ||
| | | POST || <code>/api/wifi/delete</code> || Delete credentials and switch to AP mode (deferred 2s background switch). | ||
|- | |- | ||
| POST || <code>/api/ap-security</code> || Update hotspot password. Body: <code>{"secured": true, "password": "..."}</code> | | GET || <code>/api/ap-security</code> || Hotspot security settings: <code>{secured: bool, password: str}</code>. | ||
|- | |||
| POST || <code>/api/ap-security</code> || Update hotspot password. Body: <code>{"secured": true, "password": "..."}</code> (min 8 chars). | |||
|} | |} | ||
| Line 72: | Line 86: | ||
! Method !! Endpoint !! Description | ! Method !! Endpoint !! Description | ||
|- | |- | ||
| GET || <code>/api/csv</code> || Current session CSV data. Add <code>?file=FILENAME</code> for archived files. | | GET || <code>/api/csv</code> || Current session CSV data. Returns header-only if no active session. Add <code>?file=FILENAME</code> for archived files. | ||
|- | |- | ||
| GET || <code>/api/files</code> || List stored CSV logs | | GET || <code>/api/files</code> || List stored CSV logs: <code>[{name, size, lines, date}]</code> sorted newest first. | ||
|- | |- | ||
| GET || <code>/api/control?action=cleardata</code> || Delete all stored log files | | GET || <code>/api/control?action=cleardata</code> || Delete all stored log files. | ||
|} | |} | ||
| Line 88: | Line 98: | ||
! Method !! Endpoint !! Description | ! Method !! Endpoint !! Description | ||
|- | |- | ||
| GET || <code>/api/ota/status</code> || Check if update available: version, | | GET || <code>/api/ota/status</code> || Check if update available: <code>{available, version, url, sha256, notes, skipped}</code>. | ||
|- | |- | ||
| POST || <code>/api/ota/check</code> || Force check for new firmware | | POST || <code>/api/ota/check</code> || Force check for new firmware against GitHub Releases. | ||
|- | |- | ||
| POST || <code>/api/ota/skip</code> || Skip current available update | | POST || <code>/api/ota/skip</code> || Skip current available update for this boot. | ||
|- | |- | ||
| POST || <code>/api/ota/apply</code> || Download and | | POST || <code>/api/ota/apply</code> || Download and apply firmware update. Returns 409 if none pending. | ||
|- | |- | ||
| POST || <code>/api/update</code> || Direct firmware upload ( | | POST || <code>/api/update</code> || Direct firmware upload (.tar.gz or .zip archive). Extracts over the code directory and restarts <code>bcMeter.service</code> via <code>systemctl</code>. Stops active session first. | ||
|} | |} | ||
| Line 104: | Line 114: | ||
! Method !! Endpoint !! Description | ! Method !! Endpoint !! Description | ||
|- | |- | ||
| GET || <code>/api/control?action=reboot</code> || | | GET || <code>/api/control?action=reboot</code> || End session and reboot the device (fire-and-forget thread via <code>sudo reboot</code>). | ||
|- | |- | ||
| GET || <code>/api/control?action= | | GET || <code>/api/control?action=shutdown</code> || Safely shut down via <code>sudo shutdown -h now</code>. | ||
|- | |- | ||
| POST || <code>/api/email/validate</code> || Validate email API key. Body: <code>{"api_key": "..."}</code> | | POST || <code>/api/email/validate</code> || Validate email API key against the Lambda endpoint. Body: <code>{"api_key": "..."}</code>. Returns <code>{valid: bool, error: str}</code>. | ||
|} | |} | ||
=== Captive Portal === | === Captive Portal === | ||
These endpoints handle captive portal detection on mobile devices: | These endpoints handle captive portal detection on mobile devices and redirect to the main interface in AP mode: | ||
{| class="wikitable" | {| class="wikitable" | ||
| Line 124: | Line 132: | ||
| <code>/hotspot-detect.html</code> || Apple captive portal check | | <code>/hotspot-detect.html</code> || Apple captive portal check | ||
|- | |- | ||
| <code>/success.txt</code> || Generic connectivity probe | | <code>/canonical.html</code> || Firefox captive portal check | ||
|- | |||
| <code>/ncsi.txt</code> || Windows captive portal check | |||
|- | |||
| <code>/success.txt</code> || Generic connectivity probe (returns <code>"success"</code>) | |||
|} | |||
=== Static Routes === | |||
{| class="wikitable" | |||
! Path !! Description | |||
|- | |||
| <code>/</code> || Serves the SPA frontend (<code>interface/index.html</code>) | |||
|- | |||
| <code>/discover</code> || Standalone device discovery page (also hostable on bcmeter.org) | |||
|- | |||
| <code>/manual/*</code> || Static files from <code>interface/manual/</code> | |||
|- | |||
| <code>/current_log.csv</code> || Legacy redirect to <code>/api/csv</code> | |||
|} | |} | ||
Latest revision as of 19:41, 31 March 2026
API Reference
The bcMeter exposes a REST API on port 80. All endpoints are accessible without authentication when connected to the device network. CORS is enabled for all GET requests (allow_origins=["*"]).
The software is open source: github.com/dahljo/bcmeter
Status & Diagnostics
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/status |
Current measurement state, last sensor readings, error codes, sample count, WiFi mode, firmware version, OTA info. Returns "env": "pi" to distinguish from ESP32 ("env": "esp32").
|
| GET | /api/system |
Hardware info: IP, MAC address, disk usage, memory, modem status, GPS detail, barometric altitude, geolocation, current time |
| GET | /api/logs |
Structured health report as JSON with sections: hardware, measurement, system, network, incidents. Each entry has {k, v, s} (key, value, status: ok/warn/error/info).
|
| GET | /api/maintenance-logs |
Downloads a zip bundle containing: rotating bcmeter.log files, syslog, 10 newest CSV sessions, dmesg, journalctl for bcmeter and pigpiod services, config JSON, incident log. |
| GET | /api/debug_mobile/status |
Returns modem debug send progress (from email handler). |
Measurement Control
All control is dispatched through a single endpoint with an action query parameter:
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/control?action=start |
Begin measurement session. Returns 409 if time not synced, 423 if never calibrated, 424 if calibration stale (>28 days). Add &force=1 to override preflight checks.
|
| GET | /api/control?action=stop |
Stop measurement and save session file. |
| GET | /api/control?action=calibrate |
Start calibration routine (returns 202 immediately — poll /api/calibration for progress). Requires sampling to be stopped.
|
| GET | /api/calibration |
Calibration status: {running, done, ok, elapsed_ms, log}.
|
| GET | /api/control?action=clear_error |
Reset error state to ERR_NONE. |
| GET | /api/control?action=identify |
Triggers LED identify blink pattern (Morse code spelling "bcmeter" for 30 seconds). Useful for locating a specific device when multiple units are deployed. |
| GET | /api/control?action=debug_mobile |
Triggers modem debug email via Lambda. Requires modem present. |
Configuration
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/config |
All settings as JSON. Each parameter includes type, value, label, tab, and description. |
| POST | /api/config |
Update settings. JSON body with key-value pairs. Accepts {key: value} or {key: {value: ...}} format. Only changed values need to be sent. Triggers deferred modem onboarding if mail_logs_to is set.
|
| POST | /api/device/rename |
Set device name and hostname. Body: {"name": "bcmeter01"} (1–32 chars). Runs hostnamectl set-hostname.
|
| GET | /api/control?action=synctime&ts=EPOCH&tz=IANA |
Sync device clock. ts = Unix timestamp, tz = IANA timezone string (e.g. Europe/Berlin). Applies timezone via timedatectl.
|
WiFi Management
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/wifi/scan |
List nearby networks: {scanning: bool, networks: [{ssid, rssi, secure}]}. Add ?refresh=1 to trigger a new background scan.
|
| POST | /api/wifi/scan/refresh |
Explicitly trigger a new WiFi scan (returns 202, or 409 if already scanning). |
| GET | /api/wifi/status |
Current connection: {mode, status, ssid, ip, rssi, quality (0-4), internet, timeSynced}.
|
| POST | /api/wifi |
Save WiFi credentials. Body: {"ssid": "...", "pass": "..."} (password min 8 chars).
|
| POST | /api/wifi/connect |
Save credentials and initiate background connection attempt (returns 202). Password must be 8–63 chars. Body: {"ssid": "...", "pass": "..."}
|
| GET | /api/wifi/connect/status |
Connection progress: {state: 0-3, elapsed, log, mode, ip, ssid, device_name, hostname}. States: 0=idle, 1=connecting, 2=success, 3=failed. Poll after POST to /api/wifi/connect.
|
| POST | /api/wifi/delete |
Delete credentials and switch to AP mode (deferred 2s background switch). |
| GET | /api/ap-security |
Hotspot security settings: {secured: bool, password: str}.
|
| POST | /api/ap-security |
Update hotspot password. Body: {"secured": true, "password": "..."} (min 8 chars).
|
Data Management
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/csv |
Current session CSV data. Returns header-only if no active session. Add ?file=FILENAME for archived files.
|
| GET | /api/files |
List stored CSV logs: [{name, size, lines, date}] sorted newest first.
|
| GET | /api/control?action=cleardata |
Delete all stored log files. |
Firmware Updates
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/ota/status |
Check if update available: {available, version, url, sha256, notes, skipped}.
|
| POST | /api/ota/check |
Force check for new firmware against GitHub Releases. |
| POST | /api/ota/skip |
Skip current available update for this boot. |
| POST | /api/ota/apply |
Download and apply firmware update. Returns 409 if none pending. |
| POST | /api/update |
Direct firmware upload (.tar.gz or .zip archive). Extracts over the code directory and restarts bcMeter.service via systemctl. Stops active session first.
|
System Operations
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/control?action=reboot |
End session and reboot the device (fire-and-forget thread via sudo reboot).
|
| GET | /api/control?action=shutdown |
Safely shut down via sudo shutdown -h now.
|
| POST | /api/email/validate |
Validate email API key against the Lambda endpoint. Body: {"api_key": "..."}. Returns {valid: bool, error: str}.
|
Captive Portal
These endpoints handle captive portal detection on mobile devices and redirect to the main interface in AP mode:
| Endpoint | Purpose |
|---|---|
/generate_204 |
Android captive portal check |
/hotspot-detect.html |
Apple captive portal check |
/canonical.html |
Firefox captive portal check |
/ncsi.txt |
Windows captive portal check |
/success.txt |
Generic connectivity probe (returns "success")
|
Static Routes
| Path | Description |
|---|---|
/ |
Serves the SPA frontend (interface/index.html)
|
/discover |
Standalone device discovery page (also hostable on bcmeter.org) |
/manual/* |
Static files from interface/manual/
|
/current_log.csv |
Legacy redirect to /api/csv
|
Example: Start a Measurement
# Sync time first curl "http://bcmeter-XXXX.local/api/control?action=synctime&ts=$(date +%s)&tz=Europe/Berlin" # Start measurement curl "http://bcmeter-XXXX.local/api/control?action=start" # Poll status curl "http://bcmeter-XXXX.local/api/status" # Download current data curl "http://bcmeter-XXXX.local/api/csv" -o measurement.csv