Integration + API

Frontend + Tooling Contract

OpenHaldex Integration and API Contract

This consolidated reference is the integration contract for OpenHaldex UI clients, mobile tools, support tooling, and automated validation scripts. It focuses on route behavior, payload constraints, read-after-write reconciliation, and operational reliability under real vehicle/network conditions.

Endpoint Matrix (Consolidated)

Domain Read endpoints Write endpoints Integration purpose
Status + mode GET /api/status POST /api/mode, POST /api/settings Canonical runtime state plus primary mutators.
Active map GET /api/map POST /api/map Read/write in-memory 2D lock map.
Stored map files GET /api/maps POST /api/maps/load, /api/maps/save, /api/maps/delete Persist, load, and delete named map profiles.
Speed curve GET /api/curve/speed POST /api/curve/speed Speed-axis lock shaping.
Throttle curve GET /api/curve/throttle POST /api/curve/throttle Pedal-axis lock shaping.
RPM curve GET /api/curve/rpm POST /api/curve/rpm Engine-speed lock shaping.
CAN diagnostics GET /api/canview, GET /api/canview/dump, GET /api/canview/capture POST /api/canview/capture Live decoded/raw telemetry and capture-safe diagnostics mode.
Logs GET /api/logs, GET /api/logs/read POST /api/logs/delete, POST /api/logs/clear Forensic runtime log list/read/delete/clear operations.
Network GET /api/wifi, GET /api/network POST /api/wifi STA/AP credential and connectivity control.
OTA GET /api/update POST /api/update/check, POST /api/update/install Manifest check + staged firmware/filesystem install progress.

Payload Schemas and Validation Constraints

POST /api/mode
{ "mode": "MAP" }

POST /api/settings
{
  "disableController": false,
  "broadcastOpenHaldexOverCAN": true,
  "haldexGeneration": 4,
  "disableThrottle": 0,
  "disableSpeed": 180,
  "lockReleaseRatePctPerSec": 18,
  "disengageUnderSpeed": { "map": 20, "speed": 20, "throttle": 20, "rpm": 20 },
  "inputMappings": {
    "speed": "chassis|123|vehicle_speed|km/h",
    "throttle": "chassis|456|pedal|%",
    "rpm": "chassis|789|engine_speed|rpm"
  }
}
  • disableThrottle range: 0..100
  • disableSpeed range: 0..300
  • lockReleaseRatePctPerSec range: 0..1000
  • haldexGeneration valid: 1, 2, 4

GET /api/map -> { speedBins[], throttleBins[], lockTable[][] }

POST /api/map
{
  "speedBins": [...],
  "throttleBins": [...],
  "lockTable": [[...], ...]
}

POST /api/maps/load   { "path": "maps/aggressive.txt" }
POST /api/maps/save   { "name": "aggressive" }
POST /api/maps/delete { "path": "maps/aggressive.txt" }
  • Matrix dimensions must match firmware constants exactly.
  • Lock table values are clamped to 0..100.
  • Missing path or name returns 400.

POST /api/curve/speed
{ "points": [ { "x": 0, "lock": 0 }, { "x": 80, "lock": 45 } ] }

POST /api/curve/throttle
{ "points": [ { "x": 0, "lock": 0 }, { "x": 35, "lock": 55 } ] }

POST /api/curve/rpm
{ "points": [ { "x": 1200, "lock": 5 }, { "x": 4200, "lock": 70 } ] }
  • All curve payloads require points array with strict ascending x.
  • Speed curve x: 0..300
  • Throttle curve x: 0..100
  • RPM curve x: 0..10000
  • All lock values: 0..100

GET /api/canview?decoded=200&raw=20&bus=all
GET /api/canview/dump?seconds=30&bus=chassis
POST /api/canview/capture { "active": true }

GET /api/logs
GET /api/logs/read?path=/logs/all.txt&max=32768
POST /api/logs/delete { "path": "/logs/all.txt" }
POST /api/logs/clear { "scope": "all" }

POST /api/wifi { "ssid": "...", "password": "...", "staEnabled": true, "apPassword": "..." }
POST /api/update/check
POST /api/update/install
  • CAN dump seconds is bounded to 1..120.
  • Log read max is bounded to 1..262144 bytes.
  • AP password must be empty or length 8..63.

Integration Rules

  • Always re-read /api/status after writes.
  • Treat firmware JSON as canonical state model.
  • Never infer accepted writes without response validation.
  • Handle 409 capture-mode lockouts explicitly.
  • Do not duplicate lock math in the browser.

Primary Source Files

  • src/functions/api/api.cpp
  • src/functions/net/update.cpp
  • src/functions/storage/filelog.cpp
  • firmware/assets/js/openhaldex-firmware-ui.js

Reference Integration Patterns

const status = await fetch('/api/status').then(r => r.json());
renderState(status);

if (status.inputsMapped === false) {
  showSetupPrompt();
}

await fetch('/api/settings', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload)
});

const status = await fetch('/api/status').then(r => r.json());
renderState(status);

// Poll lightly for dashboard refresh
setInterval(async () => {
  const net = await fetch('/api/network').then(r => r.json());
  updateNetworkBadge(net);
}, 1500);

// Poll CAN view only when diagnostics page is active
const can = await fetch('/api/canview?decoded=120&raw=30&bus=all').then(r => r.json());

Error Model and Retry Strategy

  • 400: malformed JSON, missing required field, range violation, or invalid path/name.
  • 404: log read path missing/unreadable.
  • 409: conflict state (commonly capture mode lockout).
  • 503: transient busy state (for example mapping update contention).

Client strategy

  • Show endpoint-specific error text directly to users.
  • Retry only idempotent reads automatically.
  • Retry writes only after state re-check and user confirmation.
  • After any error, refresh /api/status before next mutation.

Network + OTA Behavior Contract

OTA backend publishes stage and progress fields via GET /api/update while install is active.

{
  "current": "openhaldex-s3-v0.9.0-beta",
  "latest": "openhaldex-s3-v0.9.1-beta",
  "available": true,
  "installing": true,
  "stage": "firmware",
  "bytesDone": 123456,
  "bytesTotal": 1440656,
  "speedBps": 28743.2,
  "installError": ""
}
  • POST /api/update/check updates latest/version availability state.
  • POST /api/update/install starts staged firmware then filesystem update.
  • On full success, firmware restarts after install sequence completes.
  • If filesystem URL exists and FS stage fails, install reports failure and does not complete.

Integration Acceptance Checklist

  1. All write actions perform status readback reconciliation.
  2. Mode/settings/map/curve payloads validated client-side before POST.
  3. CAN diagnostics pages use bounded polling and on-demand dump capture.
  4. Log read/delete/clear flows handle missing-path and scope errors cleanly.
  5. Network + OTA pages handle offline/connectivity transitions without stale UI state.
  6. No UI-side shadow logic for lock request math or generation byte conversion.
© Bored Systems
Theme Settings
Color Scheme
Light
Dark
Layout Mode
Fluid
Boxed
Topbar Color
Light
Dark
Menu Color
Light
Dark
Layout Position