Repository navigation
RaftCLI
The RaftCLI project installs an executable program on your machine called raft. It is partly a wrapper around the Espressif ESP IDF build tools and also provides a consistent developer experience for scaffolding, building, flashing, serial monitoring, remote logging and OTA update of Raft applications, and for managing the files and device type records on a running device over HTTP, WebSocket, USB serial or BLE.
RaftCLI handles the following tasks so you don't have to interact with ESP IDF directly:
-
SysType resolution — determines which SysType to build (from the
-sflag, a previously recorded choice, or the first SysType folder found) - Build method selection — automatically chooses Docker or native ESP IDF, with options to override
-
ESP IDF version matching — reads the required ESP IDF version from the project's
Dockerfileand locates a matching local installation for native builds -
Build invocation — calls
idf.py -B build/<SysType> buildwith the correct environment -
Flash — uses
esptoolfor flashing - Serial Monitor provides a built-in serial monitor with command history and auto-reconnect
- Remote Logging provides logging and command handling over an IP (WiFi, etc) link directly to the terminal
- OTA update — sends firmware to a device over WiFi/Ethernet
- Files on a device — lists, downloads, uploads and mirrors files (including the app's FSImage) on a running device, over HTTP, WebSocket, USB serial or BLE - see Devices
- Device type records — chooses the records compiled into the firmware and builds, pushes and checks the device type file on a running device
-
Local library checkouts — fetches Raft libraries into a project's
raftdevlibs/folder for in-place development
For a detailed description of each build stage that happens after RaftCLI invokes the build, see Raft Build Process.
RaftCLI is written in Rust and installed via:
cargo install raftcli
You will also need either Docker (for containerised builds) or a locally installed ESP IDF (for native builds). For flashing, install esptool:
python3 -m pip install esptool
| Command | Alias | Description |
|---|---|---|
raft new <folder> |
raft n |
Scaffold a new Raft app - see Creating an app |
raft detect |
The chip, flash size and PSRAM of a connected board (esptool) | |
raft build |
raft b |
Build the firmware |
raft run |
raft r |
Build, flash and monitor |
raft flash |
raft f |
Flash without rebuilding (or from a browser: the Raft Flasher, below) |
raft monitor |
raft m |
Serial monitor |
raft debug <args> |
raft d |
Debug over IP |
raft ota <ip> |
raft o |
Over-the-air firmware update |
raft fs <command> <device> |
Manage files on a running device: list (ls), df, get, put, cat, delete (rm), sync, format; raft fs <device> on its own mirrors the built FSImage - see Devices
|
|
raft ports |
raft p |
List serial ports |
raft ble scan |
List the Raft devices in BLE range (name, address, signal strength) | |
raft esptool <args> |
raft e |
Run esptool directly |
raft devtypes |
raft dt |
Manage device type records: the selection, checks, and device type files on a running device - see Selecting Device Types |
raft libs <command> |
raft l |
Local development libraries in raftdevlibs/: status (default), fetch, pull, link, unlink, remove
|
raft update-project |
Bring the CMakeLists.txt of an app made by an older raft new up to date; with --set <key=value>, change one of raft new's answers and update the files made from it |
Use --no-docker to build with a local ESP IDF instead of Docker. Use -s <SysType> to select a specific SysType.
raft new asks for the project name, then the hardware, in one of four ways:
- detected from a connected board (esptool reports the chip, flash size and PSRAM in the chip) - the board on
-p/--port, or the most likely serial port (under WSL through Windowsraft.exe, or with-na port attached to WSL); - a dev board from a list, which also gives the I2C connector's pins;
- an Espressif module by its ordering code (e.g. ESP32-S3-WROOM-1-N8R2: 8 MB flash, 2 MB PSRAM);
- the chip, with safe defaults if you don't know the rest.
Then:
- wireless connectivity: WiFi and BLE, WiFi, BLE or none;
- OTA updates: two app slots, or one larger one;
-
I2C and sensors: RaftCore's
commonorextendednamed sets, all, none built in, or no I2C; - decoding of sensors added later from a device type file;
- a user SysMod.
A summary shows the partition table and an estimate of the app's size before anything is written.
The answers are saved in the app as .raftnew.json:
-
raft new --answers <file>makes the same app; -
raft update-project --set flash_size=8(for example) changes an answer and updates the files that haven't been edited.
The questions, their --set keys and the size of each choice are in RaftCLI's README.
Without WiFi (connectivity ble or none), add_compile_definitions(RAFT_NO_NETWORKING) in the app's features.cmake leaves out:
- the networking SysMods (NetMan, CommandSocket, MQTTMan) and the network loggers;
- the WiFi driver, IP stack and mDNS.
That saves about 700 KB on an ESP32-S3 (RaftCore 1.64.0 and RaftSysMods 1.28.0 and later).
raft fs and raft devtypes reach a running device over any of its connections. The device is named as:
| Device | Connection |
|---|---|
192.168.86.52, MyDevice.local, http://host[:port]
|
HTTP: the device's REST API |
ws://host[:port][/path] |
The device's WebSocket (path default /ws), using RICREST
|
serial:<port>[@baud], e.g. serial:COM4
|
The device's USB serial console, using RICREST alongside the log output (SerialConsole). serial: on its own picks the port |
ble:<name, name prefix or address> |
The device's RICREST BLE service (BLEManager). ble: on its own uses the only Raft device in range |
The device is the first argument, or comes from -d/--device or the RAFT_DEVICE environment variable:
raft fs ls 192.168.86.52 -r # list every file
raft fs get serial:COM4 config.json # download
raft fs put ws://MyDevice.local settings.json # upload (checked with the device's CRC of the file)
raft fs sync ble:Axiom018 ./webui /web --hash # mirror a folder
raft fs MyDevice.local --dry-run # mirror the project's built FSImage
RAFT_DEVICE=serial:COM4 raft devtypes status- Uploads use the file upload protocol over WebSocket, serial and BLE, and an HTTP multipart POST over HTTP. Downloads use
filesectionrequests (FileManager) on every connection. -
--fs sdworks with a device's SD card (defaultlocal). - Over serial the port is shared with the log:
--show-logshows it, andraft monitorcan't have the port open at the same time. - In WSL, serial and BLE devices are handed to the Windows
raft.exe(WSL has no USB serial ports or Bluetooth);-nuses WSL's own ports. - Rough speeds with an ESP32-S3: HTTP and WebSocket 20-50 KB/s, USB serial 10-16 KB/s up and about 40 KB/s down, BLE 15-25 KB/s up and 5-8 KB/s down.
raft ble scan lists the Raft devices in range (those advertising a RICREST BLE service). BLE has been tested on Windows only so far. Connections are made with btleplug; RaftCLI:
- writes the response characteristic's CCCD as notify after subscribing (older firmware doesn't count an indicate-only subscription), and sizes its writes from the MTU;
- remembers each device's address on Windows, so later connections skip the scan;
- always sends
bledisconnectwhen it finishes, including on Ctrl-C, because Windows otherwise keeps the link up after a program exits. If RaftCLI is killed, Windows ends the link about 25 s later; devices with RaftSysMods 1.26 or later keep advertising meanwhile (BLEManager connections).
--ble-service, --ble-cmd and --ble-resp reach devices with other UUIDs, and --ble-mtu overrides the MTU.
The Raft Flasher (raftjs apps/flasher) flashes a build over USB from Chrome or Edge, with no tools installed. Pick the project's build/<SysType> folder (or its flasher_args.json and .bin files), or give the URL of an ESP Web Tools manifest. It writes what raft flash writes, where it writes it (from flasher_args.json), and:
- shows the app's name, version and build date, and the partition table, and checks each image fits its partition and the build is for the board's chip;
- flashes everything, the firmware only (keeping the file system, as
raft flash --no-fs), or the file system image only, optionally erasing the flash first; - checks each image after writing it (MD5), then restarts the board.
Writing the file system image replaces the device's files, among them its device type file and saved device settings.
raft libs (raft l) manages a project's raftdevlibs/ folder, where the Raft build system picks up library checkouts in place of the normal GitHub fetch. A library there is either a clone made for the project or a link (symlink, or a junction on Windows) to a repo kept elsewhere.
raft l # status of each library (clone or link, branch, ahead/behind, changes)
raft l fetch # clone the libraries in RAFT_COMPONENTS at main, or update existing clones
raft l fetch --branch v1.44.1 --libs RaftCore # pin a library to a tag
raft l fetch --account my-fork --libs RaftCore # fetch from a fork
raft l pull # fast-forward pull every clean library
raft l link ../../raft # link repos from a folder (relative to the app folder)
raft l unlink # remove links (the linked repos aren't changed)
raft l remove --libs RaftI2C # delete a clone (refused if it holds local work, unless --force)fetch stops before updating a clone with uncommitted changes unless --force is given, and never changes linked repos. After a library is added to or removed from raftdevlibs, the next raft build recreates the SysType's build folder.
See Local Raft Development Libraries and the Library Developer Guide for what raftdevlibs/ does at build time.
Several options are remembered between invocations — -p serial port, -b monitor baud, -f flash baud, -v vendor ID, and --no-fs/--fs — saved to build/raft.info after a successful run. Specify the option again to override the saved value.
Full documentation including all command options is available in the RaftCLI README.
Getting Started
- Quick Start
- Architecture at a Glance
- Writing Your First SysMod
- Adding a Comms Channel
- Adding an I2C Device Type
Scaffolding & Building
- Raft CLI
- Web Apps (Device Types, Flasher)
- SysTypes
- Top-Level SysType
- Build Process
- WebUI Build Pipeline
- File System
- Partitions & Flash
- Local Dev Libraries
- Library Developer Guide
Architecture
Built-in SysMods
- NetworkManager
- WiFi Troubleshooting
- BLEManager
- WebServer
- MQTTManager
- SerialConsole
- CommandSerial
- CommandSocket
- CommandFile
- FileManager
- LogManager
- ESPOTAUpdate
- StatePublisher
- Remote Logging
- Data Source Registration
Comms & Protocols
- Stack Overview
- Comms Channels
- ProtocolExchange
- RICREST Protocol
- Real-Time Streams
- Adding REST Endpoints
- Built-in REST Endpoints
- File Download (OKTO)
- OTA Update Flow
Devices & Buses
- DeviceManager
- Device Manager REST API
- Device Factory & Classes
- Device Type Records
- Adding an I2C Device Type
- Device Data Publishing
- Data Logger
- I2C Bus
- I2C Device Scanning
- I2C ID & Polling
- MotorControl Overview
- MotorControl Config
- MotorControl Commands
- Camera
ROS 2
Helpers
Reference