# API.md # HTTP API Reference The ESP32 controller exposes a local HTTP API used by dashboards, management interfaces, and future integrations. Default access point address: text http://192.168.4.1 All responses are JSON. --- # GET /status Returns complete controller status. Includes: - Battery telemetry - Temperature sensor status - Relay status - Vehicle status - Network status - Alarm status - System information - Current configuration Example: json { "type": "status_response", "battery": {}, "temps": [], "relays": [], "vehicle": {}, "network": {}, "alarms": {}, "system": {}, "config": {} } --- # Temperature Sensors Temperature sensors are returned as an array. Example: json { "id": "temp_1", "name": "Cabin", "enabled": true, "online": true, "temperature_f": 72.4 } Fields: | Field | Description | |---------|---------| | id | Internal sensor identifier | | name | User configured name | | enabled | Sensor enabled | | online | Sensor currently detected | | temperature_f | Current temperature | Valid IDs: text temp_1 temp_2 temp_3 temp_4 temp_5 temp_6 temp_7 temp_8 --- # Relays Relay states are returned as an array. Example: json { "id": "relay_1", "name": "Aux Power", "pin": 16, "enabled": true, "state": false } Fields: | Field | Description | |---------|---------| | id | Internal relay identifier | | name | User configured name | | pin | GPIO pin | | enabled | Relay enabled | | state | Current output state | Valid IDs: text relay_1 relay_2 Future firmware versions may support additional relay outputs. --- # Battery Object Example: json { "source": "jbd_bms", "connected": true, "soc": 70, "voltage": 13.34, "current": 0.0, "remaining_ah": 104.8, "capacity_ah": 150.0, "temperature_f": 76.5, "cycle_count": 3 } Additional fields may include: text cell_count cell_voltages cell_min_voltage cell_max_voltage cell_delta_mv runtime_hours ntc_count cells_valid `runtime_hours` is discharge runtime from the ESP32 status payload. The WebUI derives charging time-to-full from `capacity_ah`, `remaining_ah`, and positive incoming `current` without changing the API shape. --- # GET /config Returns the current saved configuration. Example: json { "device_name": "Overland Controller", "relays": [], "temperature_sensors": [], "bms": {} } --- # Relay Control ## Turn Relay On text GET /relay/relay_1/on Example response: json { "ok": true, "id": "relay_1", "state": true } --- ## Turn Relay Off text GET /relay/relay_1/off Example response: json { "ok": true, "id": "relay_1", "state": false } --- # Device Configuration ## POST /config/device Updates the controller device name. Example request: json { "device_name": "Overland Controller" } Example response: json { "ok": true } --- # Relay Configuration ## POST /config/relay Updates relay settings. Example request: json { "id": "relay_1", "name": "Aux Power", "enabled": true } Fields: | Field | Required | |---------|---------| | id | Yes | | name | No | | enabled | No | --- # Temperature Sensor Configuration ## POST /config/temp Updates temperature sensor settings. Example request: json { "id": "temp_1", "name": "Cabin", "enabled": true, "address": "" } Fields: | Field | Required | |---------|---------| | id | Yes | | name | No | | enabled | No | | address | No | --- # BMS Configuration ## POST /config/bms Updates BMS settings. Example request: json { "enabled": true, "name": "House Battery", "address": "AA:BB:CC:DD:EE:FF", "address_type": "public" } Address types: text public random --- # Factory Reset ## POST /config/factory-reset Clears stored configuration and restores firmware defaults. Example response: json { "ok": true } --- # Error Responses Example: json { "ok": false, "error": "invalid relay id" } Typical errors: text invalid relay id invalid sensor id invalid request missing parameter configuration save failed --- # Versioning Current firmware: 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. --- # Temperature Probe Setup API ## Scan Temperature Sensors POST /temps/scan Response: { "type": "temp_scan_response", "ok": true, "devices": [ { "index": 1, "address": "28:AA:BB:CC:DD:EE:FF:00" } ] } ## Assign Temperature Sensor POST /temps/assign Request: { "id": "temp_1", "index": 1 } Alternative request: { "slot": 1, "index": 1 } ## Clear Temperature Sensor POST /temps/clear Request: { "id": "temp_1" } Alternative request: { "slot": 1 } --- ## Version 0.4.0 Notes The WebUI Config tab now exposes the preferred setup workflow. Important endpoints used by the WebUI: GET /status GET /config POST /config/device POST /config/relay POST /config/temp POST /config/bms POST /config/save POST /config/factory-reset POST /relay/set POST /temps/scan POST /temps/assign POST /temps/clear POST /config/wifi POST /wifi/connect POST /wifi/clear POST /bms/reconnect POST /system/restart The preferred relay command endpoint remains: POST /relay/set Request: { "id": "relay_1", "state": true }\n\n### Weather temperature sensor flag Temperature sensor config entries now include `weather: true`. When a configured temp sensor has `weather: true`, the WebUI may show it as the outside/weather temperature badge. The `/status` temp objects also include this flag so HTTP, UART, USB serial, and future Pico clients can identify the selected outside-air sensor without guessing from the sensor name.\n