ESP RainMaker Provisioning
This document describes how OpenSprinkler firmware handles ESP RainMaker provisioning, covering both BLE Claiming and On-Network methods.
Overview
ESP RainMaker requires two things before a device can be controlled from the cloud:
- Claiming — The device obtains TLS certificates from Espressif's claiming server. These certificates authenticate the device for MQTT communication with the RainMaker cloud.
- User-Node Mapping — The device is linked to a user's RainMaker account so they can control it from the phone app.
Provisioning Methods
BLE Claiming (First-Time Setup)
Used when the device has no TLS certificates (first boot, or after factory reset).
Flow:
- Firmware detects no TLS client cert in factory NVS (
esp_rmaker_factory_get("client_cert")) - RainMaker core is started (
RMaker.start()) - BLE provisioning begins via
WiFiProv.beginProvision(NETWORK_PROV_SCHEME_BLE, ...) - Device advertises as a BLE device (service name:
PROV_XXXXXX) - User opens ESP RainMaker phone app → "Add Device" → scans BLE
- Phone app connects via BLE and:
- Proxies the CSR (Certificate Signing Request) to Espressif's claiming server
- Returns the signed TLS certificate to the device
- Optionally provides WiFi credentials
- Device stores TLS certs in factory NVS
RMAKER_EVENT_CLAIM_SUCCESSFULfires- Device connects to MQTT via WiFi or Ethernet
Priority: During BLE claiming, the BLE radio is exclusively used for provisioning. Sensor BLE scanning (sensor_radio_early_init()) is deferred until claiming completes. After the CLAIM_SUCCESSFUL event, BLE resources are released and sensor scanning resumes.
On-Network Provisioning (User-Node Mapping)
Used when TLS certificates exist but the device needs to be linked to a user account.
Flow:
- Firmware detects valid TLS client cert → normal mode
- RainMaker core starts and connects MQTT
- Local control service starts (
esp_local_ctrl) on a TCP port - mDNS advertises
_esp_local_ctrl._tcpfor phone app discovery - User opens ESP RainMaker app → "Add Device" → "On Network"
- Phone finds device via mDNS on the local network
- User enters the PoP (Proof of Possession) PIN
- User-node mapping request is sent to RainMaker cloud
Requirement: Phone and device must be on the same network (WiFi or Ethernet).
Ethernet Support
Both provisioning methods work with Ethernet:
-
Ethernet + BLE Claiming: The device has network via Ethernet. BLE is used only for the claiming handshake (phone proxies CSR). The web UI remains accessible on Ethernet during BLE claiming. After claiming, MQTT connects via Ethernet.
-
Ethernet + On-Network: Local control and mDNS are advertised on both the WiFi STA and Ethernet interfaces. Phone app discovers the device on the local network via either interface.
Sensor Priority
During BLE claiming, sensors that use BLE (e.g., BLE temperature sensors) are deferred:
sensor_radio_early_init()is skipped whenOSRainMaker::sensors_deferred()returns truesensor_api_connect()is delayed until claiming completes- After
CLAIM_SUCCESSFUL, a 3-second grace period allows BLE cleanup (HANDLER_FREE_BLE) - Then
sensor_radio_early_init()runs automatically, followed bysensor_api_connect()
This is a one-time delay during the initial device setup. On subsequent boots (certs exist), sensors initialize immediately.
API Endpoint
GET /rk?pw=<hash> returns provisioning state:
| Field | Type | Description |
|---|---|---|
provisioning |
0/1 | Any provisioning active (BLE or On-Network) |
ble_claiming |
0/1 | BLE assisted claiming in progress |
sensors_deferred |
0/1 | Sensor BLE init waiting for provisioning |
local_ctrl_active |
0/1 | On-Network discovery available |
pop |
string | Proof of Possession PIN (from eFuse) |
prov_service |
string | BLE service name for phone app |
PoP (Proof of Possession)
The PoP is derived from the device's eFuse MAC address and is unique per device. It is always displayed:
- In the serial log at boot
- On the LCD during BLE provisioning
- In the web UI (RainMaker popup → PoP PIN)
- Via the
/rkAPI endpoint
Timeout and Fallback
- BLE provisioning has a 5-minute timeout in the WiFi state machine
- If the phone app doesn't connect within 5 minutes, the device falls back to STA+AP mode
- The web UI becomes accessible via the AP (192.168.4.1) or via Ethernet
- A reboot retries BLE claiming if certs still don't exist
Debug Logging
All provisioning events are logged with the RMAKER tag at INFO level using RM_LOGI / RM_LOGW / RM_LOGE macros. Key log messages:
I (xxx) RMAKER: === RainMaker BLE CLAIMING mode ===
I (xxx) RMAKER: BLE provisioning has PRIORITY over sensor BLE — sensors deferred
I (xxx) RMAKER: Starting BLE provisioning: service=PROV_XXXXXX pop=XXXXXXXX
I (xxx) RMAKER: Event: CLAIM_STARTED — contacting claiming server...
I (xxx) RMAKER: Event: CLAIM_SUCCESSFUL — TLS certs provisioned!
I (xxx) RMAKER: === Claiming successful — TLS certs received ===
I (xxx) RMAKER: Sensor BLE init will resume after BLE cleanup (~3s)
Source Files
opensprinkler_rainmaker.h/.cpp— RainMaker integration, provisioning logicmain.cpp— WiFi state machine, sensor init deferralopensprinkler_server.cpp—/rkAPI endpointsensors.cpp—sensor_radio_early_init(),is_radio_early_init_done()