Standardize API UART parity and update docs
This commit is contained in:
+305
@@ -233,3 +233,308 @@ text 0.3.x
|
||||
Future firmware versions may add fields while maintaining backward compatibility.
|
||||
|
||||
Consumers should ignore unknown fields.
|
||||
|
||||
---
|
||||
|
||||
## Embedded Dashboard
|
||||
|
||||
The ESP32 is planned to serve a lightweight mobile dashboard at:
|
||||
|
||||
GET /
|
||||
|
||||
When connected directly to the ESP32 AP:
|
||||
|
||||
http://192.168.4.1/
|
||||
|
||||
The page should:
|
||||
|
||||
- Poll /status
|
||||
- Display battery state
|
||||
- Display temperature sensors
|
||||
- Display relay states
|
||||
- Show alarms
|
||||
- Allow basic relay control
|
||||
|
||||
Design limits:
|
||||
|
||||
- Small inline HTML/CSS/JS
|
||||
- No external libraries
|
||||
- No large assets
|
||||
- No heavy JavaScript framework
|
||||
|
||||
The embedded dashboard is intended as a convenient phone view, not a replacement for the physical Pico dashboard.
|
||||
|
||||
---
|
||||
|
||||
## Future WiFi API
|
||||
|
||||
Future configuration may include WiFi management endpoints.
|
||||
|
||||
Possible future endpoints:
|
||||
|
||||
GET /config/wifi
|
||||
POST /config/wifi
|
||||
POST /config/wifi/add
|
||||
POST /config/wifi/remove
|
||||
POST /config/wifi/reorder
|
||||
|
||||
Potential config model:
|
||||
|
||||
ap_enabled
|
||||
sta_enabled
|
||||
hostname
|
||||
saved_networks
|
||||
|
||||
Saved networks should support priority order.
|
||||
|
||||
Example:
|
||||
|
||||
Starlink
|
||||
Home WiFi
|
||||
Shop WiFi
|
||||
|
||||
The AP should remain enabled even when connected to STA WiFi.
|
||||
|
||||
---
|
||||
|
||||
# HTTP / UART Parity Endpoints
|
||||
|
||||
These endpoints mirror UART setup/control messages.
|
||||
|
||||
## Save Config
|
||||
|
||||
POST /config/save
|
||||
|
||||
Equivalent UART message:
|
||||
|
||||
{"type":"save_config"}
|
||||
|
||||
## BMS Setup Mode
|
||||
|
||||
Enter BMS setup mode:
|
||||
|
||||
POST /bms/setup/enter
|
||||
|
||||
Equivalent UART message:
|
||||
|
||||
{"type":"enter_bms_setup"}
|
||||
|
||||
Exit BMS setup mode:
|
||||
|
||||
POST /bms/setup/exit
|
||||
|
||||
Equivalent UART message:
|
||||
|
||||
{"type":"exit_bms_setup"}
|
||||
|
||||
## BLE Scan
|
||||
|
||||
Scan for BLE devices:
|
||||
|
||||
POST /bms/scan
|
||||
|
||||
Equivalent UART message:
|
||||
|
||||
{"type":"scan_ble"}
|
||||
|
||||
Response:
|
||||
|
||||
{
|
||||
"type": "ble_scan_response",
|
||||
"devices": [
|
||||
{
|
||||
"index": 1,
|
||||
"name": "House Battery",
|
||||
"address": "aa:bb:cc:dd:ee:ff",
|
||||
"rssi": -65
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
## Select BMS
|
||||
|
||||
Select a BMS from the most recent scan:
|
||||
|
||||
POST /bms/select
|
||||
|
||||
Request body:
|
||||
|
||||
{
|
||||
"index": 1
|
||||
}
|
||||
|
||||
Equivalent UART message:
|
||||
|
||||
{"type":"select_bms","index":1}
|
||||
|
||||
---
|
||||
|
||||
# Preferred Relay Command Endpoint
|
||||
|
||||
The preferred relay control endpoint is:
|
||||
|
||||
POST /relay/set
|
||||
|
||||
Request body:
|
||||
|
||||
{
|
||||
"id": "relay_1",
|
||||
"state": true
|
||||
}
|
||||
|
||||
Example:
|
||||
|
||||
curl -X POST http://192.168.88.108/relay/set \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"id":"relay_1","state":true}'
|
||||
|
||||
Equivalent UART message:
|
||||
|
||||
{"type":"set_relay","relay":"relay_1","enabled":true}
|
||||
|
||||
Legacy GET relay routes may remain for compatibility:
|
||||
|
||||
GET /relay/relay_1/on
|
||||
GET /relay/relay_1/off
|
||||
GET /relay/relay_2/on
|
||||
GET /relay/relay_2/off
|
||||
|
||||
---
|
||||
|
||||
# WiFi Configuration API
|
||||
|
||||
## Get WiFi Config
|
||||
|
||||
GET /config/wifi
|
||||
|
||||
## Set WiFi Config
|
||||
|
||||
POST /config/wifi
|
||||
|
||||
Request body:
|
||||
|
||||
{
|
||||
"ssid": "Starlink",
|
||||
"password": "password_here"
|
||||
}
|
||||
|
||||
## Connect STA WiFi
|
||||
|
||||
POST /wifi/connect
|
||||
|
||||
## Clear WiFi Config
|
||||
|
||||
POST /wifi/clear
|
||||
|
||||
The ESP32 AP remains available even when STA WiFi is configured.
|
||||
|
||||
Equivalent UART messages:
|
||||
|
||||
{"type":"wifi_request"}
|
||||
|
||||
{"type":"config_wifi","ssid":"Starlink","password":"password_here"}
|
||||
|
||||
{"type":"wifi_connect"}
|
||||
|
||||
{"type":"wifi_clear"}
|
||||
|
||||
---
|
||||
|
||||
# WiFi Priority and Runtime Failover
|
||||
|
||||
Saved WiFi networks support priority.
|
||||
|
||||
Lower priority numbers are attempted first.
|
||||
|
||||
Example:
|
||||
|
||||
{
|
||||
"networks": [
|
||||
{
|
||||
"ssid": "Starlink",
|
||||
"password": "starlink_password",
|
||||
"priority": 1
|
||||
},
|
||||
{
|
||||
"ssid": "Home WiFi",
|
||||
"password": "home_password",
|
||||
"priority": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
The ESP32 behavior is:
|
||||
|
||||
AP always stays enabled
|
||||
STA tries saved networks by priority
|
||||
If disconnected at runtime, STA retries saved networks every 30 seconds
|
||||
If all STA networks fail, AP remains available at 192.168.4.1
|
||||
|
||||
|
||||
---
|
||||
|
||||
# API Parity Notes
|
||||
|
||||
The HTTP API is intended to mirror the UART JSON protocol where practical.
|
||||
|
||||
## Preferred Relay Control
|
||||
|
||||
Preferred endpoint:
|
||||
|
||||
POST /relay/set
|
||||
|
||||
Request:
|
||||
|
||||
{
|
||||
"id": "relay_1",
|
||||
"state": true
|
||||
}
|
||||
|
||||
Response:
|
||||
|
||||
{
|
||||
"type": "relay_response",
|
||||
"ok": true,
|
||||
"id": "relay_1",
|
||||
"state": true
|
||||
}
|
||||
|
||||
Legacy relay routes may remain available for compatibility:
|
||||
|
||||
GET /relay/relay_1/on
|
||||
GET /relay/relay_1/off
|
||||
GET /relay/relay_2/on
|
||||
GET /relay/relay_2/off
|
||||
|
||||
## WiFi Parity
|
||||
|
||||
WiFi configuration supports multiple saved STA networks.
|
||||
|
||||
Request:
|
||||
|
||||
POST /config/wifi
|
||||
|
||||
Body:
|
||||
|
||||
{
|
||||
"networks": [
|
||||
{
|
||||
"ssid": "Starlink",
|
||||
"password": "starlink_password",
|
||||
"priority": 1
|
||||
},
|
||||
{
|
||||
"ssid": "Home WiFi",
|
||||
"password": "home_password",
|
||||
"priority": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Lower priority numbers are attempted first.
|
||||
|
||||
Runtime behavior:
|
||||
|
||||
AP always remains enabled.
|
||||
STA tries saved networks by priority.
|
||||
If STA disconnects, saved networks are retried every 30 seconds.
|
||||
|
||||
@@ -233,3 +233,99 @@ Possible future integrations:
|
||||
- OTA updates
|
||||
|
||||
All future integrations should consume the same generic status/config model.
|
||||
|
||||
---
|
||||
|
||||
## Networking Architecture
|
||||
|
||||
### Current Network Mode
|
||||
|
||||
The ESP32 currently runs in Access Point mode.
|
||||
|
||||
Default access:
|
||||
|
||||
http://192.168.4.1
|
||||
|
||||
The AP is the recovery/setup network.
|
||||
|
||||
### Planned Network Mode
|
||||
|
||||
The planned long-term network mode is AP + STA.
|
||||
|
||||
AP mode:
|
||||
|
||||
Always available
|
||||
Used for recovery and direct setup
|
||||
|
||||
STA mode:
|
||||
|
||||
Connects to a configured WiFi network
|
||||
Used for camp/home access from phone or laptop
|
||||
|
||||
Example networks:
|
||||
|
||||
Starlink
|
||||
Home WiFi
|
||||
Shop WiFi
|
||||
|
||||
### Multiple WiFi Profiles
|
||||
|
||||
The ESP32 should eventually store multiple WiFi profiles and try them in priority order.
|
||||
|
||||
Example:
|
||||
|
||||
1. Starlink
|
||||
2. Home WiFi
|
||||
3. Shop WiFi
|
||||
|
||||
Expected behavior:
|
||||
|
||||
Start AP first
|
||||
Try configured STA networks
|
||||
Connect to the first available network
|
||||
Keep AP available even after STA connects
|
||||
|
||||
Reason:
|
||||
|
||||
- Starlink may be off
|
||||
- Home WiFi may only be available in the driveway
|
||||
- AP must remain available for recovery
|
||||
- User should not lose access because of a bad WiFi password
|
||||
|
||||
### Phone Dashboard Access
|
||||
|
||||
When connected to the ESP32 AP:
|
||||
|
||||
http://192.168.4.1
|
||||
|
||||
When connected through Starlink/home WiFi:
|
||||
|
||||
http://controller-ip
|
||||
|
||||
Future mDNS target:
|
||||
|
||||
http://overland-controller.local
|
||||
|
||||
### Dashboard Roles
|
||||
|
||||
ESP32:
|
||||
|
||||
Source of truth
|
||||
Lightweight phone dashboard
|
||||
HTTP API
|
||||
Recovery AP
|
||||
|
||||
Pico 2 W:
|
||||
|
||||
Instant physical dashboard
|
||||
UART client
|
||||
Touchscreen UI
|
||||
|
||||
Optional future Pi Zero:
|
||||
|
||||
Advanced web dashboard
|
||||
Logging
|
||||
Charts
|
||||
Integrations
|
||||
|
||||
The Pi Zero should be optional, not required for core operation.
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
# Command Parity Matrix
|
||||
|
||||
This document tracks feature parity across the three control surfaces.
|
||||
|
||||
Control surfaces:
|
||||
|
||||
- USB serial console
|
||||
- UART JSON protocol
|
||||
- HTTP API
|
||||
|
||||
## Current Parity
|
||||
|
||||
| Feature | USB Serial | UART JSON | HTTP API | Notes |
|
||||
|---|---:|---:|---:|---|
|
||||
| Status | Yes | Yes | Yes | `/status` equals `status_request` |
|
||||
| Config view | Yes | Yes | Yes | `/config` equals `config_request` |
|
||||
| Relay control | Yes | Yes | Yes | Preferred HTTP endpoint is `POST /relay/set` |
|
||||
| Device name config | Yes | Yes | Yes | `devicename`, `config_device`, `/config/device` |
|
||||
| Relay config | Yes | Yes | Yes | `relayname`, `config_relay`, `/config/relay` |
|
||||
| Temperature config | Yes | Yes | Yes | `tempname`, `config_temp`, `/config/temp` |
|
||||
| BMS config | Yes | Yes | Yes | `bmsname`/`bmsaddr`, `config_bms`, `/config/bms` |
|
||||
| Save config | Yes | Yes | Yes | `save`, `save_config`, `/config/save` |
|
||||
| Factory reset | Yes | Yes | Yes | AP remains recovery path |
|
||||
| BMS setup enter | Yes | Yes | Yes | Setup pauses normal BMS reconnect behavior |
|
||||
| BMS setup exit | Yes | Yes | Yes | Returns to normal mode |
|
||||
| BLE scan | Yes | Yes | Yes | Some BMS devices require repeated scans |
|
||||
| Select BMS | Yes | Yes | Yes | Uses most recent scan result index |
|
||||
| WiFi config | Yes | Yes | Yes | Supports multiple saved STA networks |
|
||||
| WiFi priority | Yes | Yes | Yes | Lower priority number is tried first |
|
||||
| WiFi connect | Yes | Yes | Yes | AP remains available |
|
||||
| WiFi clear | Yes | Yes | Yes | Clears saved STA networks |
|
||||
|
||||
## Preferred Command Model
|
||||
|
||||
Use generic IDs everywhere.
|
||||
|
||||
Relays:
|
||||
|
||||
relay_1
|
||||
relay_2
|
||||
|
||||
Temperature sensors:
|
||||
|
||||
temp_1 through temp_8
|
||||
|
||||
Preferred relay command shape:
|
||||
|
||||
{
|
||||
"type": "set_relay",
|
||||
"id": "relay_1",
|
||||
"state": true
|
||||
}
|
||||
|
||||
Legacy UART relay fields may still be accepted:
|
||||
|
||||
relay
|
||||
enabled
|
||||
|
||||
Preferred HTTP relay endpoint:
|
||||
|
||||
POST /relay/set
|
||||
|
||||
Legacy HTTP relay routes may remain for compatibility:
|
||||
|
||||
GET /relay/relay_1/on
|
||||
GET /relay/relay_1/off
|
||||
GET /relay/relay_2/on
|
||||
GET /relay/relay_2/off
|
||||
|
||||
## Response Shape Standard
|
||||
|
||||
Success responses should include:
|
||||
|
||||
ok: true
|
||||
|
||||
Error responses should include:
|
||||
|
||||
ok: false
|
||||
error: "error_code"
|
||||
|
||||
Status/config responses should preserve the generic data model used by `/status`.
|
||||
@@ -27,3 +27,8 @@ This folder contains project documentation for Overland Controller.
|
||||
Older or duplicate documents have been moved to `archive/`.
|
||||
|
||||
Archived documents are kept for history, but the primary documents above should be treated as the current source of truth.
|
||||
|
||||
|
||||
## Parity
|
||||
|
||||
- `PARITY_MATRIX.md` - Command parity across USB serial, UART JSON, and HTTP API
|
||||
|
||||
@@ -364,3 +364,53 @@ Returns complete runtime status including:
|
||||
- Alarms
|
||||
- Network state
|
||||
- System information
|
||||
|
||||
|
||||
---
|
||||
|
||||
# WiFi Serial Commands
|
||||
|
||||
## wifi status
|
||||
|
||||
Print current WiFi status.
|
||||
|
||||
## wifi list
|
||||
|
||||
Print saved WiFi networks, priorities, and whether passwords are set.
|
||||
|
||||
## wifi clear
|
||||
|
||||
Clear saved STA WiFi networks.
|
||||
|
||||
## wifi ssid <ssid>
|
||||
|
||||
Set primary WiFi SSID.
|
||||
|
||||
## wifi pass <password>
|
||||
|
||||
Set primary WiFi password.
|
||||
|
||||
## wifi add <ssid>|<password>|<priority>
|
||||
|
||||
Add a saved WiFi network.
|
||||
|
||||
Example:
|
||||
|
||||
wifi add Starlink|starlink_password|1
|
||||
wifi add WardAP|Ward5213|2
|
||||
wifi save
|
||||
wifi connect
|
||||
|
||||
Lower priority numbers are tried first.
|
||||
|
||||
## wifi save
|
||||
|
||||
Save WiFi configuration.
|
||||
|
||||
## wifi connect
|
||||
|
||||
Attempt STA WiFi connection using saved networks by priority.
|
||||
|
||||
AP remains available at:
|
||||
|
||||
192.168.4.1
|
||||
|
||||
@@ -205,3 +205,30 @@ Runtime behavior:
|
||||
|
||||
If STA disconnects, the ESP32 retries saved networks by priority every 30 seconds.
|
||||
AP mode remains available as a recovery path.
|
||||
|
||||
|
||||
---
|
||||
|
||||
# UART Parity Notes
|
||||
|
||||
UART should use the same generic command model as HTTP.
|
||||
|
||||
## Preferred Relay Command
|
||||
|
||||
Preferred:
|
||||
|
||||
{"type":"set_relay","id":"relay_1","state":true}
|
||||
|
||||
Legacy accepted shape:
|
||||
|
||||
{"type":"set_relay","relay":"relay_1","enabled":true}
|
||||
|
||||
Preferred response:
|
||||
|
||||
{"type":"relay_response","ok":true,"id":"relay_1","state":true}
|
||||
|
||||
## WiFi Priority Config
|
||||
|
||||
{"type":"config_wifi","networks":[{"ssid":"Starlink","password":"password","priority":1},{"ssid":"Home WiFi","password":"password","priority":2}]}
|
||||
|
||||
Lower priority numbers are tried first.
|
||||
|
||||
@@ -591,8 +591,8 @@ bool setRelayById(const String& relayId, bool enabled) {
|
||||
void sendRelayResponse(Stream& output, const String& relayId, bool enabled) {
|
||||
DynamicJsonDocument doc(256);
|
||||
doc["type"] = MSG_RELAY_RESPONSE;
|
||||
doc["relay"] = relayId;
|
||||
doc["enabled"] = enabled;
|
||||
doc["id"] = relayId;
|
||||
doc["state"] = enabled;
|
||||
doc["ok"] = true;
|
||||
serializeJson(doc, output);
|
||||
output.println();
|
||||
@@ -712,8 +712,15 @@ void handleUartMessage(const String& line) {
|
||||
}
|
||||
|
||||
if (strcmp(type, MSG_SET_RELAY) == 0 || strcmp(type, "set_relay") == 0) {
|
||||
String relayId = doc["relay"] | "";
|
||||
bool enabled = doc["enabled"] | false;
|
||||
String relayId = doc["id"] | "";
|
||||
if (relayId.length() == 0) {
|
||||
relayId = doc["relay"] | "";
|
||||
}
|
||||
|
||||
bool enabled = doc["state"] | false;
|
||||
if (doc["enabled"].is<bool>()) {
|
||||
enabled = doc["enabled"].as<bool>();
|
||||
}
|
||||
|
||||
if (!setRelayById(relayId, enabled)) {
|
||||
sendError(DashboardSerial, "unknown_relay");
|
||||
@@ -1631,9 +1638,8 @@ void handleSetRelayPost() {
|
||||
DynamicJsonDocument response(512);
|
||||
response["type"] = "relay_response";
|
||||
response["ok"] = true;
|
||||
response["relay"] = relayId;
|
||||
response["id"] = relayId;
|
||||
response["state"] = state;
|
||||
response["enabled"] = state;
|
||||
|
||||
String output;
|
||||
serializeJson(response, output);
|
||||
|
||||
Reference in New Issue
Block a user