Direct Mode

In v0.1.0 there's one flashing flow: Direct mode. The dashboard's WebSerial flasher writes your firmware plus the SCADABLE provisioning bundle in one USB session.

The flasher does NOT write Wi-Fi credentials. v0.1.0 is network-agnostic — your firmware in scadable_user_main decides how to bring up the network (hardcoded Wi-Fi STA, SoftAP-based provisioning you build yourself, Ethernet, cellular, whatever). Captive-portal-driven onboarding is a v0.2.0+ feature, not in this release.

What the flasher writes

In one WebSerial pass:

SlotContentSource
ota_0 (offset 0x10000)Your firmware binaryThe build artifact SCADABLE produced from your repo
nvs (offset 0x9000)SCADABLE credential bundle: cert, key, CA chain, identity (device_id, common_name), broker defaults (mqtt_host, mqtt_port)Minted at provision time by the dashboard

NVS namespace for the bundle: scadable_cfg. See Device cert lifecycle for the per-key detail.

Total flash time: 30–60 seconds depending on firmware size.

Step-by-step

  1. Open the dashboard → namespace → DevicesProvision device.
  2. The dashboard mints a per-device cert and prepares the NVS bundle.
  3. Connect your ESP32 over USB. Click Flash in the wizard.
  4. WebSerial writes firmware to ota_0 and the NVS bundle to 0x9000.
  5. Unplug the USB cable, power the chip from its normal supply.
  6. Within ~30 seconds the device appears as online on the dashboard.

The provisioning record is automatically promoted to "operational" on the first /v1/route hit from the device (see backend/edge.go:recordEdgeHit).

What your firmware needs to do

The library handles the SCADABLE side; your firmware only needs to bring up the network:

#include "scadable.h"

void scadable_user_main(void) {
    my_wifi_connect();   // or Ethernet init, or PPP init, etc.
    // ... your application logic ...
}

If your firmware doesn't define scadable_user_main, the library boots into headless mode (logs a warning and idles). Useful for the very first flash where you haven't written customer firmware yet — flash the cert + a stub firmware, see the device appear, then iterate.

When the flasher offers a placeholder firmware

If you haven't yet pushed firmware to your bound repo (no SCADABLE build artifact exists), the dashboard offers a tiny placeholder image you can flash. It's a minimal firmware that:

  • Defines an empty scadable_user_main (boots headless).
  • Does NOT bring up Wi-Fi (the device stays unable to reach the broker).
  • Lets you confirm the NVS bundle was written correctly via idf.py monitor.

Use this for first-flash sanity, then OTA your real firmware once the build pipeline produces it.

Partition table

The flasher assumes the standard ESP-IDF partitions_two_ota.csv layout:

# Name,   Type, SubType, Offset,   Size,      Flags
nvs,      data, nvs,     0x9000,   0x4000,
otadata,  data, ota,     0xd000,   0x2000,
phy_init, data, phy,     0xf000,   0x1000,
ota_0,    app,  ota_0,   0x10000,  0x180000,
ota_1,    app,  ota_1,   0x190000, 0x180000,

If you've customized your partitions, make sure nvs is at 0x9000 and has ≥ 16 KB.

Re-flashing

Re-flashing through the dashboard with a new provisioning bundle gives the device a new cert + identity. The old cert becomes invalid; if it was already on the broker, it gets disconnected on next reconnect.

Re-flashing with the same bundle (re-flash the same device) preserves the cert and identity — just refreshes firmware and any other NVS values.

Browser requirements

The WebSerial flasher requires a Chromium-based browser (Chrome, Edge, Brave, Opera). Safari and Firefox don't support WebSerial. If WebSerial is blocked by your OS (Linux often requires udev rules for /dev/ttyUSB*), grant the browser permission.