.scadable/ Folder Spec
The .scadable/ folder lives at the root of your firmware repo. SCADABLE reads it on every build to decide what to compile and how your device behaves in the field. Two files:
| File | Purpose |
|---|---|
.scadable/config.yaml | Build target + ESP-IDF version + runtime observability (heartbeat, metrics, logs). |
.scadable/tests.yml | Declarative diagnostic test manifest, surfaced in the dashboard. |
Both are optional — a repo with no .scadable/ folder still builds (it falls back to an esp32 classic target with all opt-in features off). You add only the keys you need; your repo is the source of truth.
config.yaml
config.yamlA complete example with every section:
# .scadable/config.yaml
# --- Build ---
device_type: esp32-s3 # which chip to compile for (default: esp32 classic)
idf_version: v5.2.7 # pin the ESP-IDF toolchain (default: build server's)
# --- Heartbeat ---
heartbeat:
interval_seconds: 30 # how often the device reports in (default: 30)
# --- Metrics (opt-in; always-on fields ship regardless) ---
metrics:
collect:
- cpu_percent
- mem_kb
- wifi_rssi
- mqtt_reconnect_count
# --- On-device logs (opt-in) ---
logs:
enabled: true
upload_interval_seconds: 60
buffer_kb: 16
min_level: I # one of V, D, I, W, EEverything outside device_type and idf_version is translated into CONFIG_SCD_* Kconfig flags and compiled in — there's zero overhead when a feature is left out.
device_type
device_typePicks the ESP-IDF build target. Hyphen, lowercase. Unknown or missing → esp32 classic.
device_type | Chip |
|---|---|
esp32-classic (or esp32) | ESP32 (original / "classic") |
esp32-s2 | ESP32-S2 |
esp32-s3 | ESP32-S3 |
esp32-c2 | ESP32-C2 |
esp32-c3 | ESP32-C3 |
esp32-c6 | ESP32-C6 |
esp32-h2 | ESP32-H2 |
idf_version
idf_versionPins the ESP-IDF toolchain the build uses. Accepts v5.2.7 or 5.2.5 (normalised to the v-prefixed tag). Omit it to use the build server's default image.
heartbeat
heartbeat| Key | Default | Notes |
|---|---|---|
interval_seconds | 30 | How often the device publishes a heartbeat. |
metrics
metricsFive fleet-health fields ship in every heartbeat automatically and don't need to be requested: boot, reset_reason, client_ts_ms, fw, uptime_s.
Beyond those, list the extra metrics you want under metrics.collect. Each one you opt into is compiled in; unknown names are ignored with a build-log warning.
| Metric | Meaning |
|---|---|
bytes_out | Bytes transmitted |
bytes_in | Bytes received |
cpu_percent | CPU utilisation |
mem_percent | Free heap as a percentage |
mem_kb | Free heap in KB |
storage_kb | Free storage in KB |
server_latency_ms | Round-trip latency to the broker |
wifi_rssi | Wi-Fi signal strength |
mqtt_reconnect_count | MQTT reconnect count |
ota_rollback_count | OTA rollback count |
current_partition | Active OTA partition |
logs
logsOn-device log capture: the library hooks ESP_LOG*, batches lines into a ring buffer, and uploads them to the dashboard. Off by default.
| Key | Default | Notes |
|---|---|---|
enabled | false | Master switch for log capture + upload. |
upload_interval_seconds | 60 | Flush cadence. |
buffer_kb | 16 | Ring buffer size (2–64 KB). |
min_level | I | Minimum level to upload: V, D, I, W, E. |
tests.yml
tests.ymlA declarative manifest of diagnostic tests SCADABLE surfaces in the dashboard. Captured at build time and attached to the deployment.
# .scadable/tests.yml
- id: wifi_connect
type: connectivity
description: Verify the device joins Wi-Fi within 30s of boot
- id: sensor_read
type: hardware
description: Confirm the primary sensor returns a plausible readingSync semantics
- The build reads
.scadable/from your latest pushed commit. - A change inside
.scadable/takes effect on the next build (push to your repo's default branch, or trigger a build from the dashboard). - These files are build-time configuration — they're baked into the firmware image. They are not live-editable from the dashboard. Your repo is the source of truth.
- For settings you do want to change live from the dashboard without rebuilding, see Config Variables — the
config:block ofconfig.yamldeclares typed variables you set per org / namespace / device at runtime.
Common mistakes
- YAML, not TOML. It's
.scadable/config.yaml, not.scadable/config.toml. Older examples used TOML; that format is gone. config.yamlvstests.yml. The build config isconfig.yaml; the test manifest istests.yml(note the.ymlspelling). Mixing them up means your tests won't be captured.- Hyphen, not underscore.
esp32-classic, notesp32_classic. Hyphen, lowercase. - Unknown metric names are silently dropped (with a build-log warning). Check the build log if a metric you expected isn't showing up.
