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:

  1. Claiming — The device obtains TLS certificates from Espressif's claiming server. These certificates authenticate the device for MQTT communication with the RainMaker cloud.
  2. 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:

  1. Firmware detects no TLS client cert in factory NVS (esp_rmaker_factory_get("client_cert"))
  2. RainMaker core is started (RMaker.start())
  3. BLE provisioning begins via WiFiProv.beginProvision(NETWORK_PROV_SCHEME_BLE, ...)
  4. Device advertises as a BLE device (service name: PROV_XXXXXX)
  5. User opens ESP RainMaker phone app → "Add Device" → scans BLE
  6. Phone app connects via BLE and:
  7. Proxies the CSR (Certificate Signing Request) to Espressif's claiming server
  8. Returns the signed TLS certificate to the device
  9. Optionally provides WiFi credentials
  10. Device stores TLS certs in factory NVS
  11. RMAKER_EVENT_CLAIM_SUCCESSFUL fires
  12. 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:

  1. Firmware detects valid TLS client cert → normal mode
  2. RainMaker core starts and connects MQTT
  3. Local control service starts (esp_local_ctrl) on a TCP port
  4. mDNS advertises _esp_local_ctrl._tcp for phone app discovery
  5. User opens ESP RainMaker app → "Add Device" → "On Network"
  6. Phone finds device via mDNS on the local network
  7. User enters the PoP (Proof of Possession) PIN
  8. 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 when OSRainMaker::sensors_deferred() returns true
  • sensor_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 by sensor_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 /rk API 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 logic
  • main.cpp — WiFi state machine, sensor init deferral
  • opensprinkler_server.cpp/rk API endpoint
  • sensors.cppsensor_radio_early_init(), is_radio_early_init_done()