Files
overland-controller/docs/cargo-api-contract.md

5.0 KiB

Cargo ESP API Contract

The Cargo ESP32 is the source of truth for power-system state.

The WebUI, ESP32-S3 dashboard, and future clients should consume this API rather than reading sensors or relay state directly.

Ownership

Cargo ESP32 owns:

  • Relay/output state
  • DS18B20 temperature readings
  • BMS telemetry
  • Alarm/fault state
  • Local configuration
  • WebUI/API service

Dashboard ESP32-S3 consumes:

  • Status
  • Battery/BMS telemetry
  • Temperature telemetry
  • Relay/output state
  • Alarm/fault state

The dashboard may request relay changes through the API, but the Cargo ESP remains authoritative.

Expected API Areas

System Status

Used by clients to determine whether the Cargo ESP is online and healthy.

Expected data:

  • Device name
  • Firmware version
  • Uptime
  • WiFi/AP status
  • API version
  • Alarm/fault summary

Battery / BMS

Used for house battery display.

Expected data:

  • Voltage
  • Current
  • State of charge
  • Charging/discharging state
  • Cell data when available
  • BMS online/offline status
  • Protection/fault state

Temperatures

DS18B20 support is already implemented in the Cargo ESP/WebUI/API path.

Expected data:

  • Sensor ID
  • Display name
  • Enabled state
  • Online/offline state
  • Temperature value
  • Temperature unit
  • Role/location, such as fridge, cargo, ambient, or spare

The ESP32-S3 dashboard should display this data from the Cargo ESP API. It should not directly own cargo/fridge DS18B20 sensor wiring for v1.

Relays / Outputs

Used for fridge, Starlink, lights, spare, and future switched outputs.

Expected data:

  • Output ID
  • Display name
  • Enabled state
  • Current state
  • Requested state
  • Fault/lockout state when available
  • Optional output type or role

Relay/output writes should go through the Cargo ESP API.

Configuration

Configuration should remain owned by the Cargo ESP.

Expected future areas:

  • Output names
  • Output enabled/disabled state
  • Temperature sensor names
  • Temperature sensor roles
  • Alarm thresholds
  • Network/AP settings
  • OTA settings

v1 Client Communication

Current v1 client path:

ESP32-S3 Dashboard
        <-> WiFi / HTTP REST
Cargo ESP32 AP

Not v1 API transport:

  • ESP-NOW
  • MQTT
  • UART dashboard link
  • CAN between controllers

Compatibility Rule

When possible, future changes should add fields rather than rename or remove existing fields.

Dashboard firmware should tolerate unknown fields.

Cargo ESP firmware should preserve stable field names once dashboard implementation begins.

Output Hardware Profiles

The Cargo ESP API should describe outputs generically instead of assuming a fixed relay board.

Current active hardware:

  • Generic ESP32 with 2-channel relay board
  • Used for ongoing development and testing

Ordered/future hardware:

  • LILYGO T-Relay-S3 6-way
  • Intended to trigger the 6 relays on the WUPP fuse/relay block
  • Not active firmware target until hardware arrives and is bench tested

API clients should not assume exactly 2 outputs or exactly 6 outputs.

Instead, clients should read the output list exposed by the Cargo ESP and render whatever outputs are available.

Expected output object fields:

  • id
  • name
  • role
  • enabled
  • state
  • requested_state
  • available
  • hardware_channel
  • hardware_profile

Example 2-channel profile:

{
  "hardware_profile": "generic_esp32_2ch_relay",
  "outputs": [
    {"id": 1, "name": "Fridge", "role": "fridge", "hardware_channel": 1},
    {"id": 2, "name": "Starlink", "role": "starlink", "hardware_channel": 2}
  ]
}

Example future 6-channel profile:

{
  "hardware_profile": "lilygo_t_relay_s3_6ch_wupp",
  "outputs": [
    {"id": 1, "name": "Fridge", "role": "fridge", "hardware_channel": 1},
    {"id": 2, "name": "Starlink", "role": "starlink", "hardware_channel": 2},
    {"id": 3, "name": "Lights", "role": "lights", "hardware_channel": 3},
    {"id": 4, "name": "Spare 1", "role": "spare", "hardware_channel": 4},
    {"id": 5, "name": "Spare 2", "role": "spare", "hardware_channel": 5},
    {"id": 6, "name": "Spare 3", "role": "spare", "hardware_channel": 6}
  ]
}

Compatibility rule:

  • The API should support the current 2-channel board while allowing a future 6-output profile without changing dashboard/client assumptions.
  • Clients should render outputs dynamically from the API response.
  • Clients should not hardcode relay count.

Implemented Output Compatibility Layer

The Cargo ESP firmware now exposes relay/output state as an output-count-agnostic list.

The current active hardware profile remains:

generic_esp32_2ch_relay

The API includes:

  • hardware_profile
  • output_count
  • relays[]
  • relays[].role
  • relays[].hardware_channel
  • relays[].hardware_profile
  • relays[].available
  • relays[].state

This keeps the current 2-channel relay board working while preparing the API shape for the future LilyGO T-Relay-S3 6-way profile.

When the LilyGO board arrives, the expected migration should be a hardware profile and relay driver change, not a dashboard/API redesign.