Factory vs field firmware profiles
IOTMER devices are usually flashed twice with different configuration:
- Factory — production line: HTTPS provision, NVS write, optional OTA
- Field — deployed device: reads NVS, connects MQTT, no auth code in firmware
The SDK examples map to this split:
| Profile | Example | IOTMER_PROVISION_AUTH_CODE | MQTT |
|---|---|---|---|
| Factory | 01_provisioning | Set in menuconfig | No client loop |
| Field | 02_telemetry | Empty | Connect + telemetry |
create-app profiles
# Deployed device (NVS already provisioned)
iotmer create-app my-device --profile field
# Production line (first-time provision)
iotmer create-app my-device --profile factory
Each scaffold includes:
sdkconfig.defaults— active profilesdkconfig.defaults.field— archived field presetsdkconfig.defaults.factory— archived factory preset
Switch later:
cp sdkconfig.defaults.field sdkconfig.defaults
# or
cp sdkconfig.defaults.factory sdkconfig.defaults
idf.py fullclean build
Factory profile settings
| Kconfig | Factory | Notes |
|---|---|---|
IOTMER_PROVISION_AUTH_CODE | Required | Console API key; never ship in field images |
IOTMER_WORKSPACE_ID | Required | Sent in provision JSON |
IOTMER_OTA_APPLY_EVEN_IF_SAME_SHA | y (template default) | Re-flash when server returns same SHA |
IOTMER_WIFI_SSID / PASSWORD | Set per line or AP | Factory Wi‑Fi |
After successful provision, NVS holds device_id, device_key, workspace_slug, MQTT creds.
Field profile settings
| Kconfig | Field | Notes |
|---|---|---|
IOTMER_PROVISION_AUTH_CODE | Empty | HTTPS provision skipped when NVS session complete |
IOTMER_WORKSPACE_ID | Empty | Ignored |
IOTMER_OTA_APPLY_EVEN_IF_SAME_SHA | n | Skip redundant OTA when SHA unchanged |
iotmer_init() still runs Wi‑Fi and loads NVS; provision runs only when needed.
iotmer doctor profile hints
doctor guesses the profile from merged sdkconfig / sdkconfig.defaults:
- factory — auth code non-empty, or
IOTMER_OTA_APPLY_EVEN_IF_SAME_SHA=y - field — empty auth code
Warnings are emitted when factory/field settings disagree (e.g. auth code set in a field build).
Same codebase, two build targets (CI)
Many teams use one repo and two sdkconfig fragments:
idf.py -DSDKCONFIG_DEFAULTS="sdkconfig.defaults.factory" build # artifact: factory.bin
idf.py -DSDKCONFIG_DEFAULTS="sdkconfig.defaults.field" build # artifact: field.bin
(Exact idf.py flags depend on your ESP-IDF version; copying to sdkconfig.defaults before build is the portable approach.)
Security
- Do not commit production auth codes or Wi‑Fi passwords.
sdkconfigis gitignored in customer projects; usesdkconfig.defaultswith empty placeholders.- Rotate console credentials if a factory image leaks.