# Argonaut 3 — Cockpit DIY Widgets ## Requirements - **Cockpit native desktop app v1.18.2** (or compatible 1.18.x) - The BlueOS browser extension ("Lite") does NOT support DIY widgets — the native desktop app is mandatory. - Cockpit must connect directly to the RPi4/BlueOS IP over plain HTTP (not through an HTTPS reverse proxy). - BlueOS Pirate Mode must be enabled each session (Settings → General). ## Network standard Use direct IP addresses everywhere. Do NOT use `blueos.local` — mDNS/Avahi resolution is unreliable across subnets and over Tailscale. | Host | IP | |---|---| | RPi4 (BlueOS gateway) | `192.168.1.100` | | RPi5 (autonomy brain) | `192.168.1.101` | ## How to install a widget 1. Open the Cockpit native desktop app. 2. Connect to the vehicle at `192.168.1.100` (RPi4/BlueOS) over HTTP. 3. Enter edit mode (pencil icon, top right). 4. Click **Add Widget** at the bottom of the screen. 5. Scroll right to find the `` DIY widget — drag it onto the view. 6. Click the **gear icon** on the widget to open the editor. 7. Click **Import** and select the `.json` file for the widget. 8. The widget loads immediately. > Widget files are `.json` (not `.html`). Cockpit expects a JSON file with `html`, `css`, and `js` string fields. ## Data lake API (Cockpit v1.18.2 DIY widget scope) - Read a single live value: `window.cockpit.getDataLakeVariableData(variableId)` — returns the live value. **This is the getter to use.** - `getAllDataLakeVariablesInfo()` returns metadata only (id/name/type/description), not values. - `getDataLakeValue()` does NOT exist — do not use. - `listenToDatalakeVariable()` does NOT exist in DIY widget scope (it is the postMessage iframe External API only). ## Live data lake variables (published by cockpit_bridge) External WebSocket variables carry the `external/` prefix. | Variable | Source topic | Notes | |---|---|---| | `external/rov-failsafe` | /rov/failsafe | Failsafe state: 0=GREEN 1=AMBER 2=RED | | `external/rov-ms` | /rov/mission/status | Mission state: 0=IDLE 1=RUNNING 2=PAUSED 3=COMPLETE 4=ABORTED | | `external/rov-mp` | /rov/mission/status | Mission progress 0.0–1.0 | | `external/rov-depth` | /rov/depth | Depth (m) | | `external/rov-heading` | /mavros compass_hdg | Heading (deg) | | `external/rov-voltage` | /mavros/battery | Battery voltage | ## Widget index | File | Widget | Status | Reads | |---|---|---|---| | w0_data_lake_inspector.json | Data Lake Inspector | Diagnostic. Flashing/scroll issue OUTSTANDING. | All data lake variables | | w1_system_health_indicator.json | System Health Indicator | CONFIRMED working | `external/rov-failsafe` | | w2_mission_status.json | Mission Status | CONFIRMED working | `external/rov-ms`, `external/rov-mp` | | w3_abort_button.json | Abort Button | UI CONFIRMED. Backend pending. | POST → FastAPI `/abort` | | w4_mission_setup_button.json | Mission Setup Button | UI CONFIRMED. Backend pending. | `external/rov-ms`; opens `/setup` | | w5_battery_return_budget.json | Return Budget | UI CONFIRMED. Live budget pending. | `SYS_STATUS/battery_remaining` + `external/rov-return-budget` | Diagnostic widget (not production): | File | Widget | Purpose | |---|---|---| | diagnostics/w_probe_api.json | API Probe | Enumerates `window.cockpit.*` methods and live-reads one variable. Used to confirm the data lake getter. Keep for future debugging. | ## Backend dependencies (not yet built) - **FastAPI service on RPi5:8081** — required by W3 (`POST /abort`) and W4 (`GET /setup`). Until built, W3's abort returns a network error (handled cleanly) and W4's setup page is blank. - **`external/rov-return-budget`** — not yet published by cockpit_bridge. Until then W5 shows the budget as pending and battery as "not reported" under SITL (SITL reports -1). ## Config values W3 and W4 target the RPi5 backend directly: - W3 `W3_FASTAPI_HOST` = `http://192.168.1.101:8081` - W4 `W4_SETUP_URL` = `http://192.168.1.101:8081/setup` ## Widget conventions (for new widgets) - All element IDs and CSS classes are prefixed per-widget (e.g. `w1-`, `w2-`) to avoid collisions in the shared Cockpit renderer. - All `document.getElementById` calls must be INSIDE functions, not at script load time (DOM timing). - Avoid: `body {}` / `:root {}` globals, `@keyframes`, `position: fixed`, Unicode in JS strings, `async/await`. Use `var`, not `let`/`const`. - A footer status line (debug) is present on data-reading widgets during validation; strip before final production.