Skip to main content

Tools reference

The SDK ships five Python tools under tools/. None of them are needed to build firmware — they exist for manufacturing, OTA management, and development shortcuts.

ToolUse it to
factory_nvs_genTurn credentials you already have into a factory NVS image
factory_autoregCreate, register, and provision a batch of nodes in one command
ota_helperSet up OTA infrastructure and drive AWS IoT jobs from the CLI
local_ctrl_cliTalk to a node's local-control or challenge-response service
esp_network_prov_nvsSkip provisioning by writing Wi-Fi credentials straight to NVS

Environment setup

There are two paths, and which you need depends on whether you also want to run the integration tests.

Path A — tools only

Enough for every tool on this page — none of them needs a backend checkout or RMNG_BACKEND_DIR:

python3 -m venv .venv && source .venv/bin/activate
pip install -r tools/requirements.txt

Path B — backend checkout required

Needed for the integration tests under test/ and for tools/common/util/factory_config.py, which import backend test helpers. Install the backend's requirements first so versions resolve predictably:

export RMNG_BACKEND_DIR=/path/to/rmng-backend
python3 -m venv .venv && source .venv/bin/activate
pip install -r "${RMNG_BACKEND_DIR}/requirements.txt"
pip install -r test/requirements.txt

test/requirements.txt pulls in tools/requirements.txt and the POSIX build requirements, so this one install also covers every tool on this page.

Provide network credentials in a .env file at the repository root; see .env.example for the fields.

System prerequisite

tools/requirements.txt pins a package that builds a native extension against an old cffi with no prebuilt wheel for recent Python versions, so you need libffi headers:

sudo apt-get install -y libffi-dev # Debian/Ubuntu
brew install libffi # macOS

Without them the install fails with fatal error: ffi.h: No such file or directory. Alternatively, run pip install -U cffi in the environment afterwards.

AWS and stack credentials for the tools that need them go in tools/common/credentials_store/ — see its README for the layout.


factory_nvs_gen

Generates a factory NVS partition from credentials you supply.

python factory_nvs_gen.py <factory_partition_label> <factory_namespace> <json_input_file>

Emits out/<json_basename>/esp-idf/*.bin and out/<json_basename>/posix/nvs_persistent/*.bin.

It does not register the node with the cloud. Use factory_autoreg or the dashboard for that.

Full guide: Factory NVS.


factory_autoreg

Creates node identities, registers them with the admin API, and writes factory artifacts — the manufacturing path.

python3 factory_autoreg.py [-n N] [--config CONFIG] \
[--part-label LABEL] [--namespace NS] [--capabilities CAP ...] username password

Ships alongside factory_attach.py, which merges generated factory partitions into full ESP-IDF flash images.

Full guide: CLI batch flow.


ota_helper

CLI for the AWS IoT side of OTA: one-time infrastructure setup, then job creation, starting, tracking, cancelling, and cleanup.

CommandDoes
--setupOne-time: ACM certificates, Code Signer profile, S3 bucket, IAM role
--create-ota-jobStandard FreeRTOS OTA job (create-ota-update). Needs --files plus --thing-name or --thing-group-name.
--create-custom-jobCustom OTA job (create-job). Optional --job-config.
--create-rmng-ota-jobRainMaker Neo OTA job. Needs --files and --job-config.
--start-jobStart a job and monitor it. Needs --job-id.
--track-job-executionPoll a job execution for one thing. Needs --job-id and --thing-name.
--cancel-custom-job / --cancel-ota-jobCancel. Needs --job-id; optional --force.
--delete-jobDelete a job and its S3 files.
--destroyTear down the OTA infrastructure — cancels running jobs, removes S3, certs, IAM, streams.
python ota_helper.py --setup
python ota_helper.py --create-rmng-ota-job --files templates/ota_file_template.json \
--job-config templates/job_config_template.json --thing-name node_switch
python ota_helper.py --start-job --job-id ota-update-12345
python ota_helper.py --track-job-execution --job-id ota-update-12345 --thing-name node_switch

Options: --cert-type {RSA,ECDSA} (default ECDSA) and --platform-id for setup. Configuration comes from your deployment's stack outputs at tools/common/credentials_store/general/rmng-outputs.json — the tool fails at import without it.

danger
--destroy is not reversible

It cancels running jobs and deletes the S3 bucket, certificates, IAM role, and streams for OTA. Do not point it at a production deployment.

For the dashboard equivalent, see OTA firmware updates.


local_ctrl_cli

Interactive client for a node's local-control and challenge-response services. Discovers the node over mDNS by node ID, connects, and drops into a REPL.

python3 tools/local_ctrl_cli/local_ctrl_cli.py [--pop <pop>] [--auto-reconnect] [--verbose] <node_id>
ArgumentNotes
node_idRequired. The node ID / thing name — get it from get-node-id on the serial console.
--popProof of possession. Prompted for if the device needs one and you didn't pass it.
--auto-reconnectRetry once after reconnecting when a command fails.
--verboseVerbose LocalController logging.

It connects to the node's local endpoints service (_esp_rmaker_ctrl._tcp), which carries local control and/or challenge-response depending on the node's cap TXT record; commands for a capability the node does not advertise are rejected with a clear message. On connect it prints the node state and the cached local-control endpoint (ip:port), then shows a lc> prompt.

For SEC2 (SRP6a) the username is fixed to wifiprov to match the device — it is neither prompted for nor configurable.

Run it from the repository root so it can import the shared utilities under tools/common.

Full guide: Local control.


esp_network_prov_nvs

Writes Wi-Fi credentials directly into an NVS partition on a connected chip, so you can skip provisioning entirely on the bench.

python esp_network_prov_nvs.py --port /dev/cu.usbserial-0001 --offset 0x9000 --size 0x6000
ArgumentExample
--port/dev/cu.usbserial-0001
--offset0x9000 — the NVS partition offset from your partitions.csv
--size0x6000 — the NVS partition size

Credentials come from .env via tools/common/util/esp_helpers.py: ESP_WIFI_SSID and ESP_WIFI_PASSWORD.

Override per invocation:

python esp_network_prov_nvs.py --port /dev/cu.usbserial-0001 --offset 0x9000 --size 0x6000 \
--network-type wifi --wifi-ssid "MySSID" --wifi-password "MyPassword"

This is a development convenience, not a production flow — real devices get credentials from an end user through network provisioning.


Integration tests

test/ holds a PyTest suite that drives real firmware — ESP boards over UART and POSIX processes on the host — against a live backend. It needs Path B. Run it from the test/ directory so builds and coverage reports land under test/build/:

pytest -n auto -v

By default it uses both ESP and POSIX instances. --no-esp skips boards; --no-posix skips host processes. With ESP enabled, tests are unique per board target type.

The simulators the suite drives are useful on their own: test/sims/device-sim/ is a serial-driven device with an arbitrary shape, and test/sims/ota-sim/ exercises the OTA state machine. device-sim needs CONFIG_RMNG_HOST_CTRL=y — see Configure and build.