SolarOS

SolarOS 4.13.4 manual · shell

SolarOS Shell Commands

This document covers built-in shell commands. Foreground applications are documented separately in apps.md. Command availability depends on the compiled firmware flavor and board capabilities; commands shows the commands in the running image.

Shell Conventions

Paths are resolved relative to the current shell directory. The default storage volume is presented as /. On SD-backed boards, the primary SD card volume also has the internal mount path /sdcard, and the internal flash volume is mounted at /flash. On boards without SD support, internal flash is mounted as /.

Wildcard patterns are supported by selected filesystem commands, for example *.txt.

Tab completion covers commands, subcommands, filesystem paths, job names, port names, and stream IDs where the command exposes enough structure. Completed paths that contain spaces are inserted as quoted shell tokens. For ssh and scp, it also reads host aliases from /.ssh/hosts. An explicit user@ prefix is preserved; a unique SCP host match appends : for the remote path.

Ctrl+V pastes the shared SolarOS clipboard at the command-line cursor. Line breaks and tabs become spaces, and a paste stops at the shell input limit; it never executes a command by itself.

Invalid input is reported as a specific problem followed by only the relevant usage line. Close, unambiguous command and subcommand typos include a did you mean hint; SolarOS never runs the suggested command automatically. Missing, unexpected, and invalid arguments identify the affected argument and its expected form. Passwords, tokens, and other credential values are redacted.

Quotes and backslash escapes are checked before a command runs. Unterminated quotes, a trailing backslash, too many arguments, and unsupported shell operators such as |, >, &&, and ; reject the complete line. URLs and ordinary argument text containing punctuation remain valid.

Shell scripts use the .sh extension. Run one with sh <file> or invoke its path directly; for example, ./somescript.sh is equivalent to sh ./somescript.sh. SolarOS storage does not require an executable permission bit for this shorthand. Use echo for script progress messages and wait to insert a whole-second delay between commands. wait does not put the device into light sleep. A foreground application launch ends the current script; the script does not resume after the application closes.

History is kept in memory and cached at /.shell/history when storage is available. The optional user alias file follows the default storage volume:

/.shell/alias

Playground separately maintains /.shell/playground. Do not edit that file; installing, updating, or uninstalling community applications regenerates it.

The startup script source is selected with setterm startup [auto|flash|sd] and is stored in NVS. auto is the default, including after nvs clear: it uses a mounted board-owned SD card when available and otherwise falls back to internal flash. flash and sd are explicit selections without fallback. On an SD-capable board, the paths are /flash/.shell/startup and /sdcard/.shell/startup; on a board without SD, internal flash is mounted at /, so its path is /.shell/startup. The script runs once per boot on the first startup-enabled shell. Shell sessions created by that script do not run it again.

The device user and hostname are stored in NVS and configured with identity. The user is also the default remote username used by ssh and scp when user@host is not supplied. On the first boot after upgrading, existing /.solar/user and /.solar/hostname values are imported when the corresponding NVS value is not already set.

The display-shell app exit chord is CTRL+ALT+DEL. Port shells use Ctrl+].

Shell Control

CommandUsageDescription
commandscommandsList built-in shell commands.
helphelp [TOPIC]; help command.status; help status; help update; help resetBrowse the package-aware manual or manage its signed exact-version SD copy. command.status escapes the maintenance keyword.
manman TOPIC; man -k QUERY...; man --listRead or search the package-aware SolarOS manual.
clearclearClear the active shell terminal.
echoecho [text...]Print the arguments separated by spaces, followed by a newline. Quotes preserve spaces and are not printed.
waitwait <seconds>Pause the calling shell or shell script for 0 through 86400 seconds.
watchwatch [-n seconds] <command> [args...]Repeat another shell command until Esc, q, or the app-exit key is pressed.
shsh <file>Run a simple SolarOS shell script from storage.
exitexitClose the current UART, USB CDC, or telnet shell when another interactive shell remains.
rebootrebootRestart the board.
nvsnvs statusShow the default NVS partition size, entry usage, and namespace count.
nvsnvs list [namespace]List non-empty namespaces and their entry usage, or list one namespace's keys, types, sizes, and storage cost. Values are never displayed.
nvsnvs erase <namespace> [key]Erase one key or all data in one namespace, then reboot.
nvsnvs backup [file]Back up the complete NVS partition to disk. The default is /.solar/nvs.bin.
nvsnvs restore [file]Validate and restore a complete NVS backup, then reboot. The default is /.solar/nvs.bin.
nvsnvs clearErase all NVS-backed settings and reboot immediately.
sessionssessionsList display app sessions, display shell sessions, and port shell sessions.
fgfg [session-id]Resume a display session or a port-owned app on its owning terminal. Without an ID, restore the calling port shell's most recently suspended app.
closeclose <session-id>Close a display app, display shell, or retained port app, or stop a port shell session. The final interactive shell cannot be closed.
inboxinboxOpen the universal incoming-message browser.
inboxinbox statusShow universal incoming-message counts and storage status.
inbox`inbox list [all\unread]`List newest messages first.
inboxinbox read <id>Print one message and mark it read.
inboxinbox delete <id>Delete one message by its decimal ID.
inboxinbox clearRemove every message.
inboxinbox post <source> <message>Post a message from a shell script or for testing.
inbox`inbox notify [on\off\test]`Show, persist, disable, or test the Inbox notification sound. It defaults to on and is unavailable on boards without audio output.
contactscontactsOpen the searchable provider-neutral contact browser.
contactscontacts statusShow contact, endpoint, persistence, PSRAM, and opaque-credential counts.
contacts`contacts list [all\discovered\trusted\blocked]`List contacts, optionally filtered by endpoint trust.
contactscontacts show <contact-id>Show a contact and its bounded provider endpoints.
contactscontacts rename <contact-id> <name>Change the local contact display name.
contactscontacts trust <contact-id> [endpoint-id]Trust one endpoint or every endpoint on a contact.
contactscontacts block <contact-id> [endpoint-id]Block one endpoint or every endpoint on a contact.
contactscontacts remove <contact-id>Remove a contact and all its endpoints.
contactscontacts link <target-contact-id> <source-contact-id>Move the source endpoints into the target and remove the source contact.
messagesmessages statusShow bounded-store, persistence, drop, and live provider state.
messagesmessages conversationsList provider-neutral conversations and unread/security state.
messagesmessages list <conversation-id>List retained messages and their stable hexadecimal IDs.
messagesmessages send <conversation-id> <text> [--allow-untrusted]Queue an outbound message; discovered direct endpoints require the explicit flag.
messagesmessages read <conversation-id>Mark a conversation and its linked Inbox entries read.
messagesmessages delete <message-id>Delete one retained message and its linked Inbox projection by hexadecimal ID.
messages`messages clear <gateway\meshcore\link\all>`Clear retained history and owned Inbox projections for one provider or every messaging provider. Unrelated Inbox sources remain.
messagesmessages outboxList pending outbound requests in queue order.
messagesmessages cancel <message-id>Cancel a queued outbound message by the hexadecimal ID printed by list or send.
outboxoutbox [list]List pending outbound messages. Sent and failed messages remain in conversation history, not Outbox.
outboxoutbox cancel <message-id>Cancel one pending message by hexadecimal ID.
gatewaygateway statusShow gateway configuration, connection state, and traffic counters.
gatewaygateway configure <url> [token]Save gateway connection settings. The gateway uses the global SolarOS user identity.
gatewaygateway connect [url] [token]Enable gateway synchronization, optionally updating settings.
gatewaygateway disconnectDisable gateway synchronization.
gatewaygateway roomsList known and joined gateway rooms.
gateway`gateway join\leave\delete <room>`Queue a gateway-specific room operation.
emailemailOpen the receive-only email app.
emailemail statusShow saved account, local message counts, and last sync error.
emailemail configure <imaps://host[:port]> <user> <password> [mailbox]Save an IMAPS account; the default mailbox is INBOX.
emailemail syncStart a one-shot mailbox synchronization.
emailemail forgetRemove the saved account and local email list.
pocsagpocsag statusShow POCSAG receiver configuration, counters, correction statistics, and RSSI.
pocsag`pocsag send <radio> <frequency-hz> <baud> <ric> <message> [alpha\numeric] [normal\inverted] [function]`Encode and transmit one POCSAG page.

nvs status distinguishes raw free entries from entries currently available for new data; use the available count when diagnosing a failed NVS write. nvs list does not display values, so credentials and other secrets are not printed. Namespace entry totals include the namespace record itself. Clearing a namespace removes all of its keys, but ESP-IDF retains its one-entry namespace record. nvs erase reboots after a successful change because running services can cache NVS-backed settings. Use nvs backup before erasing unfamiliar namespaces or keys. nvs backup writes a versioned, CRC-protected image of the complete default NVS partition. The file contains unencrypted credentials and settings, so protect it like a password. nvs restore accepts only a complete backup for the current NVS partition address and size, verifies its CRC before changing flash, verifies the written partition again, and reboots. nvs clear erases the complete default NVS partition, including identity, Wi-Fi and BLE state, credentials, service settings, and radio profiles, then reboots. Files on SD or the internal FAT filesystem are not affected.

Sessions are foreground application state plus shell instances attached to a display target or byte-stream port. Background services such as log followers, SLIP, DAQ, and HTTP serving are jobs and are controlled with job.

Scripts are intentionally simple. sh skips blank lines and lines whose first non-space character is #, then executes each remaining line as a normal shell command. Diagnostics produced through the common command parser include the script path and line number. A failed or malformed command does not execute, and the script continues with its next line; exit stops the script and closes its port shell. There are no variables, pipes, redirects, or conditionals yet.

man TOPIC opens one manual entry in the less pager when that app is installed. Use q, Esc, or the app-exit key to return to the shell. man -k searches page names, aliases, summaries, keywords, and API contracts; man --list shows every entry compiled into the current flavor. Optional topics are omitted when their package is absent. The same generated registry supplies the agent's solaros_reference tool, so local help and generated-code guidance do not drift apart.

Bare help opens a foldable topic tree. Graphic display shells read the selected topic in reader; text shells use less, both through the same man:TOPIC source. On builds with Wi-Fi, PSRAM, and SD, help update shows terminal-width-aware progress while downloading one manual.zip published for the exact running firmware version. The catalog signature authenticates the archive hash; after extraction every Markdown page is checked by size and SHA-256 before activation. help reset returns immediately to the embedded manual.

User aliases are stored in /.shell/alias, one per line:

name command-or-app fixed-args...

Arguments typed after the alias are appended. SolarOS reads the user file before the managed /.shell/playground aliases, so a user alias with the same name takes precedence. Native commands and firmware applications always take precedence over both alias files. Tab completion expands the complete fixed alias target. For example, run playground run completes installed application IDs after run .

The inbox is a persistent, producer-neutral message sink. Radio decoders, background chat or mail jobs, and shell scripts publish messages with a source, optional topic/sender/title, priority, timestamp, and body. New messages are unread by default. The status bar shows an envelope and unread count; reading or clearing messages durably updates that count. The newest 64 messages are kept in PSRAM when available and mirrored by a fixed-size ring at /.inbox/messages.bin; its compiled maximum is below 32 KB, so systems using the 64 KB internal flash volume cannot grow the inbox without bound. Replayed mail and chat notifications retain their existing read state. The browser shows newest messages first; opening a message marks the shared entry read.

Email configuration is saved in NVS and deliberately has no compiled remote server or account default. Only imaps:// endpoints are accepted, with TLS certificate validation enabled. Use a provider-specific app password where available. The password is supplied as a shell argument and stored with the device configuration, so treat shell history and physical access to the device as sensitive. email sync performs one synchronization; use the email-sync job for periodic polling.

System And Diagnostics

CommandUsageDescription
versionversionPrint the SolarOS version and firmware flavor.
pkgpkgPrint compiled package groups and build units.
boardboardPrint board ID, name, and capabilities.
identityidentity [status]Show the configured user and hostname.
identityidentity user <name>Save the SolarOS user and default SSH/SCP username in NVS.
identityidentity hostname <name>Save the device hostname in NVS; reboot to update Wi-Fi.
engine`engine [statusreset]`Print or reset generic engine utilization counters for CPU/SIMD-style backends and vector bulk operations.
displaydisplay [list]; display test <target>; display mode <target> [mode]List drawable display targets, draw a test pattern, or change driver-specific display settings.
input`input [statuskeyboardtouchmousejoystickdpadbuttonsgesture]`List all input sources or filter them by semantic class.
inputinput test <source>Show event counters and the last key, pointer, axis, or gesture event accepted from one source.
input`input calibrate <source> [set <min-x> <max-x> <min-y> <max-y> <width> <height>\reset]`Show, save, or reset coordinate calibration for an absolute-pointer source.
input`input emit <key\chord>`Emit a local key tap, such as RIGHT, ALT+RIGHT, ENTER, or one literal character, through the normal input-focus path.
gesturegesture [status]List gesture-capable input sources, readiness, and the gesture kinds each source advertises.
gesture`gesture bind source=<name\*> gesture=<name> [direction=<name\*>] [cooldown=<ms>] -- <command> [args...]`Configure a volatile gesture-to-command rule for the gesture-listener job.
gesturegesture bindingsShow listener state and list volatile gesture bindings, trigger counts, queue drops, cooldowns, and commands.
gesture`gesture unbind <id\all>`Remove one volatile gesture binding or all of them.
statusstatusPrint a compact system summary, including the last foreground-app exit code.
uptimeuptimePrint elapsed time since boot.
memmem [policy]Print heap status; policy also shows allocation-class counters, guarded fallback limits, and the last tagged failure.
toptopPrint FreeRTOS task resource information when available.
sleepsleepEnter explicit light sleep.
suspendsuspendTurn off the primary display and temporarily use the lowpower profile while services and jobs continue. Press KEY to resume.
powerpower [status]Show the selected and effective profiles, suspend state, sleep policy, and wake statistics.
power`power profile [performance\balanced\battery\lowpower]`Show or save the power profile.
power`power idle [off\seconds]`Show or configure the display-shell idle light-sleep timeout.
power`power key [off\sleep\suspend]`Show or configure the dedicated KEY short-press action.
powerpower sleepEnter explicit light sleep from the display shell. Press KEY to wake.
powerpower suspendTurn off the primary display while services and jobs continue. Press KEY to resume.
rtcrtc [status]Show the RTC provider, capabilities, interrupt wiring, and alarm/timer owners. Reports unavailable when no RTC is present.
rtcrtc alarm set HH:MM[:SS] [day=N] [weekday=N]Program the RTC hardware alarm, optionally matching a day or weekday.
rtcrtc alarm clearClear the RTC hardware alarm owned by this command.
rtcrtc timer set <duration> [repeat]Program the RTC countdown timer. Durations use an s, m, h, or d suffix.
rtcrtc timer clearClear the RTC countdown timer owned by this command.
rtcrtc pendingShow pending RTC alarm and timer interrupts.
rtc`rtc ack <alarm\timer\all>`Acknowledge pending RTC interrupts.
scheduleschedule; schedule listList persistent alarms and scheduled shell scripts. Entries show their enabled state, trigger, and action.
scheduleschedule show <name>Show one entry, including its run and skip counters.
schedule`schedule add <name> in <duration> <alarm\run script>`Add a one-shot monotonic schedule. Durations use an s, m, h, or d suffix.
schedule`schedule add <name> every <duration> <alarm\run script>`Add a recurring monotonic interval schedule.
schedule`schedule add <name> at YYYY-MM-DD HH:MM[:SS] <alarm\run script>`Add a one-shot schedule in configured local time. It waits for valid wall-clock time.
schedule`schedule add <name> daily HH:MM[:SS] <alarm\run script>`Add a daily schedule in configured local time.
schedule`schedule add <name> weekly <sun,mon,...> HH:MM[:SS] <alarm\run script>`Add a schedule for the selected local weekdays.
scheduleschedule enable <name>; schedule disable <name>Enable or disable an entry without removing it.
scheduleschedule remove <name>Remove an entry.
scheduleschedule run <name>Run an entry immediately. Only one scheduled shell script can run at a time.
scheduleschedule stop [name]Stop the active ringing alarm, optionally only when its name matches.
settermsettermOpen the terminal settings TUI from the display shell.
setterm`setterm --display <target> [orientation\font\textsize\palette\statusbar] [value]`Show or change the volatile terminal profile of a named display target.
setterm`setterm orientation [0\90\180\270]`Show or set primary-display orientation.
setterm`setterm font [mono\compact]; setterm textsize [10\12\14\16\18\20]`Show or set the terminal font and text size.
setterm`setterm palette [normal\inverted]`Show or set the logical terminal and shared-graphics palette.
settermsetterm foreground [#RRGGBB]; setterm background [#RRGGBB]Show or set the persistent RGB terminal theme colors.
setterm`setterm statusbar [show\hide]`Show or hide the graphical shell status bar.
settermsetterm brightness [0..100]; setterm backlight [0..100]Show or set display brightness or backlight level.
setterm`setterm profile [vt100\ansi\dumb]; setterm charset [utf8\ascii]`Configure escape sequences and TUI glyph output for the current port shell.
setterm`setterm keyboard [us\de]; setterm powerkey [sleep\suspend]`Show or set the keyboard layout and dedicated KEY action.
setterm`setterm keyrate [off\1..60 [delay-ms]]`Show or set the shared keyboard and button repeat policy.
setterm`setterm ble [default\on\off]`Show or set the BLE preference for the next boot.
setterm`setterm timezone [UTC\UTC+/-offset\Europe/Berlin\POSIX-TZ]`Show or set the timezone used for local time.
setterm`setterm startup [auto\flash\sd]`Show or select the volume containing .shell/startup for the next boot.
settermsetterm otaurl [url]Show or set the OTA metadata URL.

Input completion lists every current source after input test, only absolute pointer sources after input calibrate, common named keys after input emit, status after an input class, and set or reset after a calibration source. Gesture completion lists gesture-capable sources after source=, limits gesture= values to the selected source's advertised gestures, and offers all after gesture unbind.

power usage:

power status
power profile [performance|balanced|battery|lowpower]
power idle [off|seconds]
power key [off|sleep|suspend]
power sleep
power suspend

Profiles:

ProfileBehavior
performanceCPU fixed at 240 MHz, no automatic light sleep. This is the default.
balancedCPU fixed at 160 MHz, no automatic light sleep.
batteryCPU fixed at 160 MHz with ESP-IDF automatic light sleep.
lowpowerCPU fixed at 80 MHz with automatic light sleep and display-shell idle sleep after 60 seconds.

Suspend is different from explicit light sleep. It keeps the runtime, radios, background jobs, Inbox notifications, and audio active while the primary display is off. It temporarily uses the lowpower profile and prevents the idle policy from entering explicit light sleep. Another short press of KEY resumes the display and restores the selected profile. power status shows the selected profile, effective profile, and suspend state.

power key retains off for compatibility. sleep uses the existing light sleep path, and suspend toggles the runtime suspend state. The default for a new or cleared NVS configuration is suspend; an existing saved value remains unchanged.

rtc is the low-level hardware interface. rtc status remains useful on boards without RTC hardware and reports unavailable there.

rtc status
rtc alarm set HH:MM[:SS] [day=N] [weekday=N]
rtc alarm clear
rtc timer set <duration> [repeat]
rtc timer clear
rtc pending
rtc ack <alarm|timer|all>

Direct alarm and timer controls are leased. If the scheduler or a script owns the requested hardware slot, the command reports the owner instead of replacing its wake-up configuration.

schedule stores named alarms and script jobs in the internal flash filesystem at .solar/schedule.bin. Updates replace the file atomically. Durations accept s, m, h, or d; dates and times use configured local time.

schedule list
schedule show <name>
schedule add <name> in <duration> <alarm|run script>
schedule add <name> every <duration> <alarm|run script>
schedule add <name> at YYYY-MM-DD HH:MM[:SS] <alarm|run script>
schedule add <name> daily HH:MM[:SS] <alarm|run script>
schedule add <name> weekly <sun,mon,...> HH:MM[:SS] <alarm|run script>
schedule enable <name>
schedule disable <name>
schedule remove <name>
schedule run <name>
schedule stop [name]

Only one scheduled shell script runs at a time. A due script is skipped and its skip counter increases if another scheduled script is still running. Scheduled scripts run without a terminal, and attempts to launch foreground applications are rejected. Calendar schedules wait for valid wall-clock time. Interval schedules continue to work from monotonic uptime without an RTC.

During explicit light sleep, the nearest schedule is armed as an internal timer. When a wired interrupt-capable RTC is available, the scheduler also programs its calendar alarm when wall-clock time is valid and, for a monotonic schedule, its countdown timer. The RTC GPIO is added to the wake sources. This lets countdowns use the RTC even while wall-clock time is invalid. An RTC interrupt can wake light sleep; it cannot turn on a board whose hardware power has been switched off.

setterm usage:

setterm
setterm --display <target> [orientation|font|textsize|palette|statusbar] [value]
setterm orientation [0|90|180|270]
setterm font [mono|compact]
setterm textsize [10|12|14|16|18|20]
setterm palette [normal|inverted]
setterm foreground [#RRGGBB]
setterm background [#RRGGBB]
setterm statusbar [show|hide]
setterm brightness [0..100]
setterm backlight [0..100]
setterm profile [vt100|ansi|dumb]
setterm charset [utf8|ascii]
setterm keyboard [us|de]
setterm powerkey [sleep|suspend]
setterm keyrate [off|1..60 [delay-ms]]
setterm ble [default|on|off]
setterm timezone [UTC|UTC+/-offset|Europe/Berlin|POSIX-TZ]
setterm startup [auto|flash|sd]
setterm otaurl [url]

setterm keyrate configures the shared repeat policy for BLE, PS/2, CardKB, and the CL-32 keyboard, fixed board buttons, gpio-keys, and ADC D-pads. Analog joysticks publish axes and do not generate key events. The value is stored in NVS and is available on builds without BLE.

setterm ble selects the next-boot BLE preference. default clears the saved override and follows the active board profile; on and off remain in effect across firmware updates until changed. The current boot is unchanged.

setterm timezone accepts fixed offsets with the conventional UTC sign: UTC-8 is eight hours behind UTC and UTC+5:30 is five hours and 30 minutes ahead. Fixed offsets do not apply daylight-saving transitions. Other accepted timezone expressions use POSIX TZ syntax and its POSIX sign convention. SolarOS does not include the IANA timezone database; Europe/Berlin is a built-in daylight-saving alias.

setterm powerkey selects the dedicated KEY short-press action. sleep enters explicit light sleep; suspend turns off the display while jobs and services continue. setterm key is accepted as a shorter alias.

setterm startup selects the volume used for .shell/startup on the next boot. The default auto setting prefers a mounted board-owned SD card and falls back to flash when SD is unavailable. flash always selects internal flash, even when an SD card is mounted. sd always selects SD and is rejected on boards without SD support. Use setterm startup without a value to show the selected source and currently resolved path.

setterm profile and setterm charset are runtime-only and apply to the current port shell. From the display shell they print guidance to configure them from a port shell. profile controls terminal escape sequences; charset controls TUI glyph output. The default utf8 mode uses Unicode box drawing. Select ascii for DOS and other legacy serial terminals; TUI borders, blocks, arrows, and punctuation are replaced with readable ASCII characters. Display layout settings (orientation, font, textsize, palette, and statusbar) apply to the current display and its app sessions. Settings on the primary display are persistent; settings on secondary or virtual displays such as web0 are runtime-only. When no saved values exist, the font defaults to compact and the text size defaults to 16. palette exchanges logical black and white in terminal content and in the shared graphics palette; dithered shades are reversed as well. It remains independent of hardware inversion modes exposed by display mode, and does not rewrite an existing framebuffer. On a headless board, a port shell can set or query the persistent palette before an expansion-display session exists; subsequently created terminal and graphic sessions inherit it.

setterm --display <target> reads or changes the volatile terminal profile of a named runtime display target, even when a TUI application rather than a shell owns that display. The target profile is initialized from the single global NVS parameter set when the display registers. Orientation is relative to the target's native panel rotation, so 0 keeps every display in its normal mounting even when their drivers use different U8g2 rotations. Display-targeted absolute pointer coordinates follow this logical orientation. A targeted change applies to current and future sessions on that display until reboot or until the display target is unregistered; it does not create or update per-display NVS keys. Without a setting, the command prints the target's complete volatile profile. For example:

setterm --display oled0 statusbar hide
setterm --display oled0 textsize 10
setterm --display oled0 palette inverted

foreground and background select the persistent RGB theme colors for the built-in color display. They color terminal scanout and semantic GUI elements, including text, backgrounds, borders, and intermediate shades. Explicit RGB image, canvas, and script colors remain literal. Use six hexadecimal digits, for example setterm foreground '#d8e8ff' and setterm background '#102030'; the leading # can be omitted. The defaults are #000000 and #ffffff. These settings do not add a color framebuffer or affect monochrome-display rendering. palette inverted continues to exchange the foreground and background roles.

setterm statusbar hide removes the top status bar from graphical shell sessions and gives its space to the terminal. show restores it. The default is show when no value is stored in NVS.

On BLE-capable builds, the status bar has a separate Bluetooth symbol: plain means enabled for the current boot, slashed means disabled, and a small search marker means scanning. The keyboard symbol shows only availability: plain when at least one keyboard is available, slashed otherwise, regardless of transport. Compact displays omit icons that do not fit before the clock and unread count.

Apps And Jobs

CommandUsageDescription
appsappsList registered foreground apps compiled into the firmware.
agentagent; agent new; agent ask PROMPT...Open a new native LLM agent TUI or make one unsaved foreground request.
agentagent list; agent resume SLOT; agent delete SLOTList, restore, or delete durable local conversation slots.
agentagent status; agent toolsInspect provider state, request statistics, typed tools, risk, and policy.
agent`agent config endpointmodelkeyreasoningtoolsmax-tools VALUE`Configure the provider and tool policy.
agent`agent script python\lua (-c SOURCE \FILE) [ARGS...]`Run a bounded script through the agent execution path.
agentagent forgetErase the saved agent configuration.
jobsjobsList registered jobs and their state.
jobjob status [name]Show one job or all jobs.
jobjob start <name> [args...]Start or restart a job.
jobjob stop <name>Stop a job.
sessionsession listList display sessions, port shells, and retained port-owned application sessions with their owner.
session`session create shell <port> [--term autovt100ansidumb] [--charset utf8ascii] [--size COLSxROWS]`Start a shell session on a byte-stream port.
sessionsession create shell <display-target>Attach a shell session to a ready display target such as lcd0.
sessionsession create <app> <display-target> [args...]Start a foreground application as the active session on a named display.
sessionsession focus [display-target]Show or assign the display that receives BLE keyboard and local board-control input.
sessionsession fg [id] or session switch [id]Resume a display session or a port-owned app on its owning terminal. Without an ID, restore the calling port's last suspended app.
sessionsession close <id>Close a display app, display shell, port-owned app, or port shell session.
sessionsession send <id> <command> [args...]Run a command on an active display-shell session. The target must be at an empty prompt.
sessionsession backgroundExplain the foreground/background controls.

Port shells default to --term auto. Auto mode sends a terminal Device Attributes probe; a recognizable response enables VT100-style cursor controls and a size probe, while no response falls back to a dumb line-oriented shell. The dumb profile can run line-oriented shell commands, but cursor-addressable TUI applications cannot run on it and report <app>: can't run on a dumb terminal. Use --term vt100 or --term ansi to force escape-sequence output, --term dumb for plain text, and --size COLSxROWS to set the terminal dimensions without probing. Character encoding is independent of that profile: port shells default to --charset utf8; use --charset ascii when a legacy terminal displays Unicode TUI glyphs as unrelated code-page characters.

jobs prints a compact table that fits the built-in display terminal:

NAME         STATE    STACK KIND        EVT  TICKS RES
batmon       running      - background  tick    17   1
log          stopped   6144 background  tick     0   0

Columns:

ColumnMeaning
NAMEJob registry name.
STATEstopped, waiting, running, or failed. A waiting launch retries automatically.
STACKDeclared worker-stack admission requirement in bytes; - means no dedicated stack is declared. Dynamic allocations are not included.
KINDJob kind. Current registry jobs are background workers.
EVTtick if the job receives periodic tick events, otherwise -.
TICKSNumber of dispatched tick events while running.
RESNumber of resources currently recorded for the job.

Use job status <name> for the job summary, owner string, last error, effective worker-stack placement, tick interval/deadline, last and maximum handler time, deadline-miss count, and resource details. Running rows are bold. A waiting job has retained its launch request until the stack can be admitted while preserving the internal-memory reserve; a failed job completed a start attempt with an error. sessions prints the same timing telemetry for display and port sessions as one row per session in ID TITLE APP STATE TIME order. In the TIME column, the first pair is interval/deadline in milliseconds, the second is last/max in microseconds, n is the dispatch count, and ! is the deadline miss count. Job timing detail uses the same values with explicit labels. Job-owned resources use owner strings such as job:log; port conflicts are reported as readable messages such as job log owns cdc0.

Common job examples:

session create shell cdc0
session create shell uart0 --term ansi --charset ascii --size 80x25
session create shell lcd0
session create files display0
session focus display0
job start log cdc0
job start log file /.shell/log info
job start bridge cdc0 uart0
job start bridge uart0 link0 broadcast
link stream create link0 vser0 0x12345678
job start bridge cdc0 vser0
job start gpio-keys gpio17:UP gpio2:ENTER
job start gpio-keys --config /flash/gpio-keys.conf
job start graffiti
job start gesture-listener
job start httpd /www
job start displayd [display-target]   # display0 by default, web0 when headless
job start ntp-sync once
job start batmon 60
job start slip uart0 115200
job start pppd uart0 baud=115200
job stop log

Only one instance of each built-in job name is active at a time. Starting the same job again stops the previous instance and starts it with the new arguments.

Filesystems And Storage

CommandUsageDescription
diskdisk [status]Show persistent-storage status.
diskdisk lsblkList internal flash and detected removable block devices and partitions.
disk`disk mount [flash\sd0pN] [mount]`Mount the default volume or an explicit persistent volume.
disk`disk umount [flash\sd0pN\mount]`Unmount the default volume or an explicit volume/mount point.
disk`disk format <flash\sd0\sd0pN> --force`Create a FAT filesystem, permanently erasing the unmounted target.
ramfsramfs [status]List PSRAM-backed volatile filesystem mounts.
ramfsramfs mount /path sizeMount a volatile filesystem that reserves PSRAM, such as ramfs mount / 1m.
ramfsramfs unmount /pathUnmount a ramfs mount.
dfdfShow free space on mounted storage volumes.
cdcd [path]Change current shell directory.
ls`ls [-a] [-h] [pathpattern]`List files. Hidden files are shown only with -a; sizes are human-readable with -h.
cat`cat <pathpattern>`Print a small text file.
mkdirmkdir <path> [path...]Create directories.
rm`rm [-f-rf] <pathpattern> [pathpattern...]`Remove files. -f allows directories; -rf removes directories recursively.
mv`mv <sourcepattern> <dest>`Rename or move a file or matched set.
cp`cp <sourcepattern> <dest>`Copy a file or matched set.
zip`zip [-0] <archive.zip> <pathpattern> [pathpattern...]`Create a ZIP archive. -0 stores without compression.
unzipunzip [-l] <archive.zip> [dest]List or extract a ZIP archive.

Examples:

ls -ah /.ssh
cp *.txt /backup
rm -rf /tmp/old
disk mount sd0p2 /mnt
ramfs mount /tmp 1m
ramfs mount / 4m
ramfs unmount /tmp
zip /books/archive.zip /books/*.txt
unzip -l /books/archive.zip

Streams, Logs, Ports, And Transfers

CommandUsageDescription
streamstream or stream listList dynamic typed stream endpoints.
streamstream status <id>Show type, direction, provider, format, owner, and counters for one stream.
daqdaq helpPrint DAQ usage.
daqdaq statusShow DAQ job status.
daqdaq streamsList stream IDs.
daq`daq start <file.csv> <stream...> [--rate seconds\--rate-ms ms]; daq start <stream...> <file.csv> [--rate seconds\--rate-ms ms]`Start periodic CSV capture from one or more streams.
daq`daq start <file.csv> <stream> --changes [--append\--replace]`Capture a scalar or event stream only when its value changes.
daqdaq start <file.bin> <byte-or-audio-stream> --raw [--rate-ms ms]Capture one byte or PCM audio stream without CSV framing.
daqdaq stopStop the active data-acquisition job.
loglog statusShow runtime log ring status.
loglog show [count]Print recent SolarOS log entries.
log`log follow [errorwarninfodebug]`Follow logs in the current shell.
loglog clearClear the runtime log ring.
log`log level [errorwarninfodebug]`Show or change runtime log level.
log`log sink cdc [onoff]`Enable or disable CDC mirroring of SolarOS logs.
portport listList byte-stream ports.
portport status <name>Show port capabilities and owner.
xferxfer protocolsList supported and reserved transfer protocols.
xferxfer send <port> <file> --raw [-d ms]Send a file as raw bytes, optionally delaying between chunks.
xfer`xfer recv <port> <file> --raw [--append\--replace] [--idle-ms ms]`Receive raw bytes until the idle timeout and append or replace the destination.
xferxfer send <port> <file> --zmodemSend a file with ZMODEM.
xfer`xfer recv <port> <file> --zmodem [--append\--replace]`Receive a file with ZMODEM and append or replace the destination.

DAQ usage:

daq start <file.csv> <stream...> [--rate seconds|--rate-ms ms]
daq start <stream...> <file.csv> [--rate seconds|--rate-ms ms]
daq start <file.csv> <stream> --changes [--append|--replace]
daq start <file.bin> <byte-or-audio-stream> --raw [--rate-ms ms]
daq stop

DAQ examples:

daq start /logs/env.csv temperature humidity battery --rate 60
daq start /logs/key.csv gpio17 --changes
daq start /logs/uart0.bin uart0 --raw --rate-ms 25
daq start /logs/microphones.pcm audio0.capture --raw

daq CSV rows include uptime_ms, and include UTC time_ms when wall-clock time is trusted. Raw mode accepts one byte or audio source and writes its data directly without CSV framing. Audio uses the native PCM format reported by stream status; arecord writes the same input as a WAV file. recorder adds interactive stream and WAV-format selection, no-file live input monitoring, hardware input gain when the selected device supports it, visualization, pause, and playback.

Streams are runtime-registered endpoints, similar to services and displays. Providers can add or remove scalar sensor, event, byte, and PCM audio streams. Direction is source, sink, or duplex; sharing and current ownership are reported by stream status. Board audio devices currently publish audio0.capture and/or audio0.playback. Microphone level compatibility streams remain available as mic0 and mic1 where the board has two input channels.

Transfer usage:

xfer protocols
xfer send <port> <file> --raw [-d ms]
xfer recv <port> <file> --raw [--append|--replace] [--idle-ms ms]
xfer send <port> <file> --zmodem
xfer recv <port> <file> --zmodem [--append|--replace]

raw and zmodem are supported. kermit is reserved but not implemented.

Networking

CommandUsageDescription
networknetworkOpen the two-tab network TUI. Status shows interfaces and routes; Settings changes persistent interface priority and client routing.
networknetwork statusShow network interfaces, route selection, VPN routes, and router state as text.
networknetwork interfacesList route-capable interfaces, addresses, priorities, and the local downstream interface.
networknetwork routesShow the default route, automatic base path, and active WireGuard routes.
network router`network router [status\on\off]`Route Wi-Fi AP clients through the SolarOS route table using IPv4 forwarding and NAT.
wifiwifiOpen the Wi-Fi display TUI when launched from the display shell.
wifiwifi statusShow station/AP/NAT state and the current/next boot setting.
wifiwifi enableSave Wi-Fi enabled for the next boot. The current boot is unchanged.
wifiwifi disableSave Wi-Fi disabled for the next boot. The current boot is unchanged.
wifiwifi onStart Wi-Fi station mode and connect to remembered networks.
wifiwifi offStop station/AP networking; an active ESP-NOW lease retains the radio.
wifiwifi scanScan access points.
wifiwifi connect [ssid [password]]Connect and save/update a station profile.
wifiwifi disconnectDisconnect station mode.
wifiwifi knownList remembered station profiles.
wifi`wifi forget [ssidall]`Remove one or all remembered station profiles.
wifi repeaterwifi repeaterShow L2 IPv4 repeater state, upstream, downstream, learned clients, and forwarding counters.
wifi repeaterwifi repeater onRepeat the current or preferred saved network with the same SSID and password on the same IPv4 subnet.
wifi repeaterwifi repeater offStop L2 forwarding and the downstream AP while retaining the upstream station.
wifi apwifi ap [status]Show SoftAP status.
wifi ap`wifi ap on [ssid [password [openwpawpa2wpa/wpa2]]]`Start and save SoftAP settings.
wifi apwifi ap offStop SoftAP.
wifi nat`wifi nat [statusonoff]`Advanced control for IPv4 NAT on the SoftAP interface. Prefer network router.
wireguardwireguard [status]Show profile, tunnel, selected underlay, route, peer, DNS, and kill-switch state without printing key material.
wireguardwireguard import <file>Validate one standard WireGuard client profile and save it in NVS. The source file is not removed.
wireguardwireguard forgetLogically remove the saved profile from NVS. Bring the tunnel down first.
wireguard`wireguard up [fail-open\fail-closed]`Request the tunnel and reconnect it when the preferred network underlay changes. The default is fail-closed for a full tunnel and fail-open for a split tunnel.
wireguardwireguard downStop the tunnel, remove its routes, restore DNS, and disable its kill switch.
bleble [status]Show BLE keyboard state and the current/next boot setting.
bleble enableSave BLE enabled for the next boot. The current boot is unchanged.
bleble disableSave BLE disabled for the next boot. The current boot is unchanged.
bleble defaultClear the saved override and use the board default on the next boot.
ble`ble keepalive [on\off]`Show or save the best-effort BLE keyboard keepalive setting.
bleble scanScan nearby BLE devices.
bleble pairStart keyboard pairing.
bleble forgetErase the remembered keyboard, its BLE bond, and its cached GATT service database.
ble gattble gatt statusShow the generic GATT connection state and discovered-service count.
ble gatt`ble gatt connect <aa:bb:cc:dd:ee:ff> <public\random\rpa_public\rpa_random>`Connect to a BLE peripheral by address and address type.
ble gattble gatt disconnectRequest disconnect of the shell's GATT session and cancel its pending operation.
ble gattble gatt servicesList discovered services and their indexes and handle ranges.
ble gattble gatt chars <service-index>List the characteristics discovered for one service.
ble gattble gatt read <handle>Read a characteristic or descriptor by handle.
ble gattble gatt write <handle> <hex...>Write hexadecimal bytes and request a response.
ble gattble gatt write-nr <handle> <hex...>Write hexadecimal bytes without requesting a response.
mqttmqtt statusShow broker, authentication, connection, traffic, queue, and error status without revealing the password.
mqttmqtt connect [mqtt[s]://host[:port] [username [password]]]Connect to a broker and save supplied connection settings; omit them to reuse saved settings.
mqttmqtt disconnectDisconnect and stop the MQTT client.
mqttmqtt publish <topic> <payload> [qos] [retain]Publish a message with optional QoS 0–2 and retain flag.
mqttmqtt subscribe <topic> [qos]Subscribe and print received messages until app-exit or q.
pingping <host> [count]Send ICMP echo requests. Without count, ping runs until Esc, Ctrl+C, or app-exit.
netscan`netscan <hostrange> [ports]`Scan TCP ports on one host or a capped IPv4 range.
ntpntp [server]Sync the wall clock from NTP.

Wi-Fi is enabled by default when no saved setting exists, including after nvs clear. wifi on and wifi off control the radio in the current boot. The wifi enable and wifi disable settings take effect only after a reboot. Disabling Wi-Fi does not erase saved station, access-point, or NAT settings.

WireGuard accepts one IPv4 interface address, one peer, one optional numeric IPv4 DNS server, and at most eight IPv4 AllowedIPs prefixes. IPv6 addresses, multiple peers, interface hooks, and configuration keys outside the documented client subset are rejected. Use wireguard down before importing a replacement profile or using wireguard forget. See WireGuard VPN client for routing, secret, and disconnect behavior.

When no saved preference exists, including after nvs clear, BLE follows the board default. Most boards enable it; TTGO VGA32 v1.4 disables it to preserve internal heap. setterm ble on|off|default stores or clears the preference for the next boot. ble enable, ble disable, and ble default are equivalent compatibility commands. Disabling BLE does not forget the remembered keyboard or erase its BLE bond. On a BLE-disabled boot, SolarOS returns the unused Bluetooth controller and host memory to the internal heap before normal service initialization.

When a keyboard exposes the standard Battery Service, SolarOS subscribes to its Battery Level notifications and reads the initial level when supported. ble status, the general status command, and the Python/Lua BLE status strings include the latest percentage while that keyboard remains connected.

ble keepalive on sends the standard HID Exit Suspend command every 30 seconds when the connected keyboard exposes a writable HID Control Point. It falls back to reading the HID Information characteristic when Exit Suspend is unavailable. The setting persists and is off by default. ble keepalive reports the selected method, the last local operation result, and the attempt count. These operations do not count as SolarOS user activity. They can prevent sleep when a keyboard bases its inactivity timer on host HID or GATT traffic, but the keyboard remains in control of its own power policy, so the result is device-specific. ble keepalive off stops the operations.

BLE GATT usage:

ble gatt status
ble gatt connect <aa:bb:cc:dd:ee:ff> <public|random|rpa_public|rpa_random>
ble gatt disconnect
ble gatt services
ble gatt chars <service-index>
ble gatt read <handle>
ble gatt write <handle> <hex...>
ble gatt write-nr <handle> <hex...>

The shell GATT session owns one peer and shares the configured connection budget with app BLE sessions, which may own multiple peers. It cannot read or disconnect an app-owned connection. Disconnect and operation timeout retire the connection asynchronously; reconnect can report busy until cleanup finishes. A write without response waits for local stack completion, not a remote acknowledgement. Generic scans are unavailable while any generic peer is active or retiring.

MQTT usage:

mqtt status
mqtt connect [url [username [password]]]
mqtt disconnect
mqtt publish <topic> <payload> [qos] [retain]
mqtt subscribe <topic> [qos]

mqtt connect mqtt://host[:port] [username [password]] and mqtt connect mqtts://host[:port] [username [password]] save broker settings in NVS. Later mqtt connect reuses the saved settings.

netscan accepts a host, same-subnet range, or compact range form. Examples:

netscan 192.168.1.10 22,80,443
netscan 192.168.1.1-50 22
netscan wintermute 22

OTA And Keys

CommandUsageDescription
otaota statusShow running and configured OTA state.
otaota checkCheck signed board/flavor release metadata.
otaota upgradeDownload firmware into the inactive OTA partition and reboot into it.
otaota url [url]Show or set the OTA base URL.
otaota flavor [flavor]Show or set target OTA flavor.
ota`ota boot 01`Select an OTA slot and reboot.
sshkeysshkey [status]Show default SSH key status.
sshkey`sshkey gen [-f] [204830724096]`Generate /.ssh/id_rsa and /.ssh/id_rsa.pub.
sshkeysshkey pubPrint the default public key.
sshkeysshkey rmRemove the default key pair.

OTA resolves the artifact for the compiled board and target flavor from the configured release index, verifies the signed index, verifies firmware SHA-256, and writes the inactive ESP-IDF OTA partition. A signed ota check also caches the flavors present for the compiled board in RAM. ota flavor completion uses that verified list. Before a check, completion asks you to run ota check; changing the OTA URL or rebooting clears the list. If the selected flavor is not present in the checked release, ota check lists the flavors that are available for the compiled board.

Hardware And Time

CommandUsageDescription
batterybattery [status]Show voltage, state of charge, power source, config, and monitor trend.
batterybattery configShow battery capacity and voltage thresholds.
batterybattery capacity [mAh]Show or set capacity estimate.
battery`battery min_voltage [VmV]`Show or set low-voltage threshold.
battery`battery max_voltage [VmV]`Show or set full/external-power shortcut threshold.
audioaudio statusShow audio state, global speaker level, tone queue, and active synth telemetry.
audioaudio devicesList registered audio devices and their capture/playback streams.
audioaudio device <id>Show one audio device and its native PCM format.
audio`audio default [auto\<id>]`Show or select the preferred playback device. auto restores first-compatible-device selection.
audioaudio tone [hz] [ms] [volume]Play a diagnostic tone.
audioaudio tone-async [hz] [ms] [volume]Queue a tone and return its request ID immediately.
audioaudio queueShow asynchronous tone queue state and counters.
audioaudio cancel <request-id>Cancel a queued or playing asynchronous tone request.
audioaudio level [volume]Show or set global speaker level.
audioaudio mic [ms]Sample microphone level.
audioaudio loopback [ms] [volume]Run microphone-to-speaker loopback.
audioaudio offStop audio output.
led`led [statusonofftoggle]`Inspect or control the built-in status LED when available.
expansionexpansionOpen the expansion device manager. Browse attached devices and driver categories, inspect details, attach supported drivers, save runtime attachments to the selected startup script, and detach runtime devices. Bus lifecycle remains in the io app.
expansionexpansion statusShow expansion capabilities, named buses and leases, connector resources, active devices, and resource claims.
expansionexpansion layout [connector]Draw the board's physical connector map with live free, releasable, claimed, fixed, power, ground, and NC markers.
expansionexpansion scanList expansion resources and probe-capable drivers.
expansionexpansion driversList compiled expansion drivers.
expansionexpansion devicesList fixed board and runtime-attached expansion devices with origin, readiness, startup mode, policy, and bindings.
expansion`expansion bus create i2c <name> port=<i2c0\i2c1> sda=<gpio> scl=<gpio> [speed=<hz>]`Define a runtime I2C bus on an unused controller and approved expansion pins.
expansionexpansion bus create onewire <name> pin=<gpio>Define a runtime named 1-Wire bus on an approved expansion pin.
expansionexpansion bus create ps2 <name> clock=<gpio> data=<gpio>Define an exclusive PS/2 bus on two approved expansion pins.
expansionexpansion bus create midi <name> tx=<gpio> rx=<gpio> [baud=<rate>]Define an exclusive MIDI bus; SolarOS selects the UART backend and defaults to 31250 baud.
expansion`expansion bus create spi <name> host=<spi2\spi3> sclk=<gpio> mosi=<gpio> [miso=<gpio\none>] cs=<gpio> [cs=<gpio> ...] [max=<bytes>]`Define a runtime-routed SPI bus on a board-approved host and expansion pins.
expansion`expansion bus create uart <name> port=<uart1\uart2> tx=<gpio> rx=<gpio> [baud=<rate>]`Define a lazy runtime UART on an unused controller and approved expansion pins.
expansionexpansion bus attach <name>Attach a named detachable bus and reserve its endpoint and signal pins.
expansionexpansion bus detach <name>Detach an idle named bus, preserving its descriptor while releasing its endpoint and signal pins.
expansionexpansion bus remove <name>Remove an idle runtime bus and release its signal pins.
expansionexpansion attach <driver> <name> <resource...>Attach a compiled expansion driver or manual resource profile.
expansionexpansion detach <name>Detach an active expansion device and release its resource claims.
expansionexpansion export <path>Atomically export runtime buses and catalog-backed device attachments as a portable expansion manifest for custom-board generation.
neopixel`neopixel [status\list] [name]`List attached WS2812/NeoPixel strips.
neopixelneopixel set <name> <index> <red> <green> <blue>Set one zero-based pixel and immediately refresh the strip.
neopixelneopixel fill <name> <red> <green> <blue>Fill and immediately refresh the strip. Color components are 0..255.
neopixel`neopixel clear\show <name>`Clear a strip immediately, or transmit its buffered colors.
midimidi statusShow MIDI worker, traffic, parser, and queue status.
midimidi monitorPrint incoming CC and key messages until the app-exit key, Esc, or q is pressed.
midi`midi note-on\note-off <channel> <note> [velocity]`Queue a MIDI note message for transmission.
midimidi cc <channel> <controller> <value>Queue a MIDI control-change message.
midimidi program <channel> <program>Queue a MIDI program-change message.
midimidi send <status> [data1] [data2]Queue one validated raw MIDI message.
midimidi stream listList configured incoming MIDI CC scalar streams and their latest values.
midi`midi stream add\remove <channel> <controller>`Register or remove midi.cc.<channel>.<controller> as a scalar stream.
midimidi stream clearRemove all configured MIDI CC scalar streams.
control`control list\parameters\bindings`Inspect normalized controls, native app parameters, or target bindings.
controlcontrol create <name> <stream> <min> <max> [smooth=ms] [deadband=value] [invert]Normalize a scalar stream as a named continuous control; use manual for script-supplied values.
control`control bind <name> parameter <path> [pickup=on\off]`Bind a control to a typed native-app parameter with optional soft takeover.
controlcontrol bind <name> midi <channel> <cc>Bind a control to a MIDI Control Change target.
control`control get\set <name> [value]`Read or set a normalized 0..65535 control value.
control`control parameter get\set <path> [value]`Read or set an available native parameter in its declared unit.
controlcontrol unbind <name>Remove all target bindings owned by one named control.
controlcontrol delete <name> or control clearRemove one control and its bindings, or remove all controls and bindings.
oscosc bindingsInspect named outbound OSC bindings and their live source, value, send, and error state.
osc`osc bind <name> stream <stream> <address> [rate=hz] [delta=value] [send=change\always]`Publish one scalar stream as OSC float32 values in its native unit.
osc`osc bind <name> stream <event-stream> <address> edge=rising\falling\both [rate=hz]`Publish sampled boolean transitions as OSC int32 0 or 1.
osc`osc bind <name> control <control> <address> [rate=hz] [send=change\always]`Publish one normalized named control as an OSC float32 value from 0.0..1.0.
oscosc unbind <name> or osc clearRemove one outbound binding or all outbound bindings.
radioradioOpen the packet-radio TUI with live status and editable common config.
radio`radio statuslist`List packet radios registered by expansion drivers.
radioradio status <name>Show one packet radio, its capabilities, state, and current config.
radioradio config <name> [field value]Show or update common packet-radio configuration.
radioradio profile listList immutable built-in and persistent user radio profiles.
radioradio profile show <profile>Show every setting captured by one profile.
radioradio profile apply <radio> <profile>Apply one complete profile to a radio, restoring the prior config if application fails.
radioradio profile save <radio> <profile>Save or replace a user profile from the radio's complete current config.
radioradio profile remove <profile>Remove a user profile. Built-in profiles are read-only.
meshcoremeshcore statusShow MeshCore identity, radio, packet, delivery, duplicate, memory, and stack state.
meshcore`meshcore identity show\generate\import\export`Inspect or explicitly manage the private MeshCore identity.
meshcoremeshcore name [name]Show or set the MeshCore-specific advertised name.
meshcore`meshcore advert zero\flood`Queue a local or explicitly network-wide advert.
meshcore`meshcore channel list\add\remove\public`Join public hashtag channels or manage bounded shared-key groups while the job is stopped.
meshcoremeshcore stream list or meshcore stream status [port]Inspect trusted peer-bound virtual serial ports carried by encrypted MeshCore direct packets.
meshcoremeshcore stream create <port> <trusted-endpoint-id>Register a reliable MeshCore virtual serial port for one exact trusted endpoint. Configure both peers.
meshcoremeshcore stream remove <port>Remove an unclaimed MeshCore virtual serial port.
radio`radio state <name> [sleepstandbyrxtx]`Show or change radio operating state.
radio`radio send <name> <textbyte...>`Send one packet.
radioradio recv <name> [timeout-ms]Receive one packet and print metadata plus payload.
gnssgnss [list]List registered GNSS receivers and their concrete drivers.
gnssgnss status [name]Show power, fix, fix type, and satellite state for one logical receiver.
gnss`gnss power <on\off> [name]`Enable or disable one logical receiver using its driver-specific power control.
gnssgnss fix [name] [timeout-ms]Poll one receiver for a position, UTC time, fix type, satellite count, and accuracy. A timeout can be supplied without a receiver name.
modemmodemOpen the modem status and settings TUI.
modemmodem listList registered cellular modems, concrete drivers, transports, and power, reset, and baud capabilities.
modemmodem status [name]Read SIM readiness, LTE registration, signal, packet-context, and IP-interface state.
modem`modem power <on\off> [name]`Switch a modem's optional hardware power line.
modemmodem reset [name]Reset a supported modem using its reset line or driver-defined power cycle.
modem`modem baud [name] [auto\rate]`Show or persist an optional serial modem transport rate. auto selects the driver's preferred rate.
modem`modem profile set [name] --apn <apn> [--dns <ipv4\auto>] [--ip ipv4\ipv6\ipv4v6] [--auth none\pap\chap\auto] [--user <user> --password <password>]`Validate, apply, and persist a modem-independent cellular profile.
modem`modem profile show\clear [name]`Inspect a saved profile with its password redacted, or remove it.
modem`modem connect\disconnect [name]`Bring the saved cellular network connection and PPP interface up or down.
modemmodem sim unlock <pin> [name]Enter a required SIM PIN without persisting it.
modemmodem at <quoted-command> [name] [timeout-ms]Send one validated AT command and print the complete response.
haptichaptic [list]List registered haptic devices, their concrete drivers, and supported effect range.
haptichaptic play <effect> [name]Play one numbered effect on a haptic device.
haptichaptic stop [name]Stop the active haptic effect.
chargercharger [list]List registered battery chargers, concrete drivers, and valid configuration ranges.
chargercharger status [name]Show charger state, input status, configured limits, and the raw fault byte.
charger`charger enable <on\off> [name]`Enable or disable charging.
chargercharger input-limit <mA> [name]Set the input current limit to an advertised, exact step value.
chargercharger current <mA> [name]Set fast-charge current to an advertised, exact step value.
chargercharger voltage <mV> [name]Set charge voltage to an advertised, exact step value.
imuimu [list]List registered motion sensors, their concrete drivers, and available measurements.
imuimu sample [name] [timeout-ms]Read acceleration, angular velocity, and optional orientation from one motion sensor.
nfcnfc [list]List registered NFC readers and their concrete drivers.
nfc`nfc power <on\off> [name]`Enable or disable a reader that has a driver-managed power rail.
nfcnfc scan [name] [timeout-ms]Discover one collision-free NFC-A tag and print its UID, ATQA, and SAK.
espnowespnow [status]Show ESP-NOW owner, channel, PHY, peers, traffic, drops, conflicts, and last error.
espnow`espnow peers\list`List persistent configured and volatile learned Link-ID-to-MAC mappings.
espnowespnow peer add <link-id> <mac>Save a persistent unicast peer mapping.
espnowespnow peer remove <link-id>Remove a configured or learned peer mapping.
link`link status\list`List active SolarOS Link instances and their queue/protocol counters.
linklink status <link>Show local ID, transport MTU, queues, acknowledgements, duplicates, CRC errors, and drops.
link`link send <link> <broadcast\destination-id> <text>`Queue a text message. Unicast requests an acknowledgement.
link`link send-binary <link> <broadcast\destination-id> <byte...>`Queue a binary message.
linklink receive <link> [timeout-ms]Remove and print one received message.
linklink stream listList Link-backed virtual serial ports.
linklink stream status [port]Show virtual-port peer, connection, queue, traffic, retry, reconnect, and error state.
linklink stream create <link> <port> <peer-id>Register a reliable peer-bound Link stream as a normal SolarOS byte-stream port.
linklink stream remove <port>Remove an unclaimed Link stream port.
pocsagpocsag statusShow detailed status for the POCSAG background receiver.
pocsag`pocsag send <radio> <frequency-hz> <baud> <ric> <message> [alpha\numeric] [normal\inverted] [function]`Encode and transmit one POCSAG page.
uartuart [status [bus]]Show the default uart0 or a selected named UART bus.
uartuart baud [bus] [rate]Show or set a named UART bus baud rate.
uart`uart mode [bus] [raw\line]`Show or set a named UART bus service mode.
uartuart write [bus] <text>Write text through the default or selected named UART bus.
uartuart read [bus] [ms]Read bytes from the default or selected named UART bus.
gpiogpio status or gpio listList board GPIOs with free, releasable, or fixed pin policy.
gpio`gpio mode <pin> <inout> [noneupdown]`Configure a runtime GPIO.
gpiogpio read <pin>Read a runtime GPIO.
gpio`gpio write <pin> <01>`Write a runtime GPIO configured as output.
gpiogpio release <pin>Reset a direct GPIO and release its resource claim for a bus or another service.
onewireonewire [status [bus]]Show every registered named 1-Wire bus, or one selected bus.
onewire`onewire reset <bus\pin>`Reset a named bus or direct runtime GPIO and report presence.
onewire`onewire scan <bus\pin>`Discover and list 1-Wire ROM addresses.
onewire`onewire xfer <bus\pin> <read-len> [byte...]`Reset, write bytes, then read bytes on a 1-Wire target.
adcadc statusShow ADC service status.
adcadc read <pin>Read an ADC-capable runtime pin.
dpaddpad [status]Show ADC D-pad pins, raw values, zones, and calibration thresholds.
dpaddpad calibrate [idle]Calibrate the current D-pad idle value.
dpaddpad calibrate resetRestore the compiled D-pad calibration.
pwmpwm statusShow PWM state.
pwmpwm set <pin> <freq-hz> <duty-percent>Start LEDC PWM on a runtime pin.
pwmpwm off <pin>Stop PWM on a pin.
i2ci2c [status [bus]]Show every named I2C bus, or one selected bus.
i2ci2c speed [bus] [hz]Show or change a named bus clock; defaults to i2c0 and accepts 1 through 1000000 Hz.
i2ci2c scan [bus]Scan a named bus; defaults to i2c0.
i2ci2c probe [bus] <addr>Probe one address; defaults to i2c0.
i2ci2c read [bus] <addr> <reg> [len]Read register bytes; defaults to i2c0.
i2ci2c write [bus] <addr> <reg> <byte...>Write register bytes; defaults to i2c0.
spispi [status [bus]]Show every named SPI bus, or one selected bus.
spispi xfer <bus> <cs> <mode> <hz> <byte...>Full-duplex transfer over a named SPI bus.
spispi read <bus> <cs> <mode> <hz> <len> [fill]Read bytes over a named SPI bus.
spispi write <bus> <cs> <mode> <hz> <byte...>Write bytes over a named SPI bus.
datedate [YYYY-MM-DD]Show or set the local date.
timetime [HH:MM[:SS]]Show or set the local time.
temperature`temperature [list\sensor]`List temperature providers or read the default or named sensor.
humidity`humidity [list\sensor]`List humidity providers or read the default or named sensor.

Board-specific connector resources, runtime GPIO policy, named buses, leases, and attachment examples are documented in Expansion Ports. Use expansion status and gpio list for the authoritative view on a running device.

The onewire command accepts a registered bus name or any runtime-accessible GPIO. onewire status discovers named buses, while the numeric form preserves the direct-pin workflow. Every xfer starts with a 1-Wire reset, writes the supplied bytes, and then reads read-len bytes. For example, onewire xfer 1 9 0xcc 0xbe issues Skip ROM and Read Scratchpad, then reads a nine-byte scratchpad. The equivalent named form starts with onewire xfer onewire0. ROM address bytes supplied to xfer use least-significant-byte-first wire order. The service enables the ESP32 internal pull-up, but a 4.7 kohm external pull-up from the data line to 3.3 V is strongly recommended. The internal pull-up is not a parasite-power supply.

Physical displays are listed by display list. A built-in board panel registers as a board display target such as display0; an expansion display driver stays in expansion drivers as attachable hardware and registers a display target after it is attached. The built-in board panel is not an expansion driver. display list includes the current owner when a target is claimed. display test <target> claims the target while it draws a visible frame/test pattern, then releases it. display mode <target> lists driver-specific display settings for supported display drivers; display mode <target> <mode> applies one setting. With power=auto, the built-in ST7305 path uses the normal power profile before writing changed frame content and switches to the paired lpm profile after the frame has been idle for the configured driver debounce, or immediately when a present pass finds no changed pixels. The default ST7305 idle debounce is 1000 ms. The advanced display mode <target> idle-lpm-ms=<ms> driver option updates it at runtime and persists it in the ST7305 NVS namespace. ST7305 tuning options also live on this driver-specific mode surface: power=<auto|hpm|lpm> selects automatic idle switching or a forced power mode, inverted=<on|off> selects panel inversion, lpm-hz=<0.25|0.5|1|2|4|8> changes the controller's LPM frame-rate field, and hpm-hz=<16|25.5|32|51> changes the controller's HPM frame-rate field. These driver values are stored in NVS when changed. The ST7305 inverted= setting controls panel polarity and remains independent of the terminal palette selected with setterm palette. On SSD1683 board and expansion targets, refresh=auto uses a full waveform for the first changed frame and after every 19 non-full updates, while unchanged frames are skipped. Waveshare V2 expansion targets use the changed framebuffer rectangle and the controller's partial-window waveform for those intermediate updates. refresh=fast forces a fast full-frame waveform and refresh=full forces the full cleanup waveform on every changed frame.

Packet radio devices are datagram endpoints registered by expansion drivers, not byte-stream ports. The common radio layer preserves packet metadata such as RSSI and optional source/destination IDs. Radio frequency values are Hz by default and also accept k, kHz, M, and MHz suffixes:

radio status radio0
radio config radio0 frequency 433MHz
radio config radio0 modulation gfsk
radio send radio0 hello
radio recv radio0 5000

Profiles avoid partially reconfiguring one end while copying a list of fields. lora-eu868, gfsk-eu868, and ook-eu868 are built in. Up to eight user profiles are stored as one versioned NVS record and consume no idle profile cache:

radio profile list
radio profile apply radio0 lora-eu868
radio config radio0 sf 9
radio profile save radio0 lora-sf9
radio profile show lora-sf9
radio profile remove lora-sf9

Like radio config, applying a profile leaves the radio in driver standby. If the driver rejects a setting, SolarOS attempts to restore the complete prior configuration and operating state. A profile does not bypass the driver's supported frequency, modulation, power, or packet-size checks. The operator remains responsible for regional frequency, transmit-power, and duty-cycle rules.

RFM95W radios support FSK, GFSK, MSK, GMSK, OOK, and LoRa. LoRa additionally uses bandwidth, sf, and coding-rate. For an RFM95W using the common 868 MHz profile:

radio config radio0 frequency 868MHz
radio config radio0 bandwidth 125000
radio config radio0 sf 7
radio config radio0 coding-rate 4/5

variable=on selects the normal explicit LoRa header. variable=off selects implicit-header mode and requires the configured length to match on both ends. SF6 requires implicit-header mode.

FSK-family and OOK modes use bitrate, deviation, and a single-side bandwidth. MSK and GMSK derive deviation as one quarter of bitrate; GFSK and GMSK use Gaussian BT=1.0 shaping. RFM95W FSK/OOK packets contain at most 64 payload bytes, while fixed length zero enables the unlimited FIFO-stream mode.

The POCSAG job configures an attached packet radio for one paging channel, filters addresses to one RIC, corrects up to two bad bits per BCH codeword, and publishes decoded pages to the universal inbox. Consecutive POCSAG batches are kept in one message. For the 448.425 MHz test channel:

job start pocsag radio 448425000 1200 1841525 alpha
pocsag status
inbox list unread

Use inverted as the final argument if the transmitter and receiver use opposite FSK mark/space polarity. Stopping the job restores the radio's previous configuration and state.

To transmit a page, stop the receiver when it uses the same half-duplex radio, then send the message. Alphanumeric pages default to function 3; numeric pages default to function 0. The optional final argument selects function 0 through 3. The previous radio configuration and state are restored after transmission.

job stop pocsag
pocsag send radio 448425000 1200 1841525 "SolarOS calling" alpha inverted

Quick Examples

help
version
pkg
board
wifi on
ping wintermute
sshkey gen 2048
ota check
ota upgrade
watch -n 1 battery
daq start /logs/env.csv temperature humidity battery --rate 60
session create shell cdc0 --term auto
session create shell lcd0
xfer send uart0 /logs/payload.bin --zmodem

Quick reference

Run commands to list commands compiled into the current firmware, man TOPIC for a focused guide, and help for the complete manual tree. Commands are package-aware, support shell completion where applicable, and use the current shell working directory for relative paths.

Join us on: