Skip to content

Devices

A device is a single physical ESP32 unit in the field.

Identity

A device is identified by (project, device_id). The device_id is opaque to SimpleOTA; pick whatever is stable on your hardware:

  • MAC address (AA:BB:CC:DD:EE:FF): common for Wi-Fi-only fleets.
  • Serial number / chip ID: useful if you provision IDs at the factory.
  • A UUID burned into NVS during first-boot: flexible, vendor-agnostic.

Warning

device_id participates in cohort hashing. Changing it on a unit moves it to a different bucket and can flip its exposure to an in-flight rollout.

Compatibility metadata

Devices declare their hardware so SimpleOTA can refuse to install incompatible firmware. Reported by the device on every /check/ call:

Field Example Notes
framework arduino, esp-idf Required.
chip_family esp32, esp32s3 Required.
board_id esp32dev Free-form, must match artifact.
hardware_revision rev-a Optional.
partition_profile default_4mb Required for Arduino, must match.
nvs_schema_version 1 Bumped when NVS layout changes.
security_mode basic, secure_boot_v2 Optional.

A device only receives an artifact whose manifest matches all required dimensions. See Compatibility.

Lifecycle

stateDiagram-v2
    [*] --> active: auto-register
    active --> inactive: plan downgrade<br/>or admin action
    inactive --> active: upgrade plan<br/>or re-activate
    active --> [*]: delete
    inactive --> [*]: delete

active = false devices keep their history but receive no updates. This is how plan downgrades work without losing audit trail.

Auto-registration

Most fleets never manually create a device. The first call to /api/v1/ota/check/ with a project token will create the device row, provided:

  • The plan's device limit hasn't been reached.
  • The token belongs to the same project.

If the cap is hit, the response is 200 with {"update_available": false, "status": "over_limit"} so the device doesn't hammer-retry.