Scripting & Automation
pcu-cli is built to be scripted. Data goes to stdout; prompts, warnings, and errors go to stderr; and every command sets a meaningful exit code. This page covers the flags and output formats you need for unattended use. For the full command list, see the Command Reference.
Output discipline
Section titled “Output discipline”- stdout carries the data: the status table, timer values, channel states, and all JSON.
- stderr carries confirmation prompts, warnings, and error messages.
Because prompts and warnings never touch stdout, you can capture clean data with pcu-cli ... > out.txt while any prompt still appears on the terminal.
| Flag | Description |
|---|---|
--quiet | Bare values only, one per line. Also skips confirmation prompts. |
--json | JSON output. Supported on status, ign, dio, and version. |
--yes, -y | Skip write confirmation prompts. |
--version, -V | Print version info and exit. Runs without elevation. |
-h, --help, /? | Print command help and exit. |
Notes:
--quietimplies--yes: quiet writes never prompt.--jsonon its own still prompts before a write. Add--yesfor unattended writes.--jsonand--quiethave no effect ondriver; its output is always the text form.pcu-clireads no environment variables and no configuration files. Everything is passed on the command line.
JSON output
Section titled “JSON output”status, ign, dio, and version emit a single indented JSON object on stdout. Errors still go to stderr, and the exit code is unchanged, so a script can branch on either.
status --json on a CQ20:
{ "platform": "In-CarPC CQ20", "cpu": "Intel Atom x6425E", "mcu_identity": "CQ20 MCU", "hardware_rev": "DTB-IGN-MCU VER:10", "firmware": 12, "ignition": { "mode": 1, "ign_on_delay_s": 6, "sw_on_delay_s": 3, "sw_off_delay_s": 3, "pw_off_delay_s": 900 }, "timers_stored": true}ign --json is the timer summary on its own:
{ "mode": 1, "ign_on_delay_s": 6, "sw_on_delay_s": 3, "sw_off_delay_s": 3, "pw_off_delay_s": 900}A single ign get read is { timer, value }, with the value in seconds:
{ "timer": "sw-off-delay", "value": 3}A write reports the requested value, the value read back, whether they match, and whether the value was stored:
{ "timer": "sw-on-delay", "requested": 3, "actual": 3, "verified": true, "stored": true}stored is true when the value is stored. On a CQ20 it is false if the MCU did not confirm the store within 5 seconds, and on a CQ50S it is false if the MCU did not accept the save command. The exit code is then 1. The CQ40 series and CQ40N MCUs save by themselves, so stored is always true there.
status --json on a CQ50S has four timers, all in seconds, and no mode. The CQ50S reports no hardware revision, so hardware_rev is omitted, and firmware is a number (the status text shows a version string instead). ignition_line is the state of the ignition input, true for On:
{ "platform": "In-CarPC CQ50S series", "cpu": "Intel Core (CQ53S/CQ55S/CQ57S)", "mcu_identity": "CQ50S Ignition MCU", "firmware": 1280, "ignition": { "ign_on_delay_s": 3, "ign_off_delay_s": 3, "pw_off_delay_s": 900, "ups_off_delay_s": 60 }, "timers_stored": true, "ignition_line": true}ign set ign-off-delay 5 --yes --json on a CQ50S:
{ "timer": "ign-off-delay", "requested": 5, "actual": 5, "verified": true, "stored": true}Timer keys on a CQ40N and CQ40 series
Section titled “Timer keys on a CQ40N and CQ40 series”Every timer key carries the unit it is counted in as a suffix: _s for seconds, _m for minutes. On a CQ20 and a CQ50S every timer is always in seconds, so the keys are always _s and the shapes above never change. The CQ50S keys are ign_on_delay_s, ign_off_delay_s, pw_off_delay_s and ups_off_delay_s.
On a CQ40N or CQ40 series, four of the five timers follow the delay unit, so their key names change with it. The same machine reports ign_off_delay_m while the unit is minutes and ign_off_delay_s after pcu-cli ign unit seconds. Only ign_on_delay_s is fixed, because that timer is always in seconds.
ign --json on a CQ40N (or CQ40 series) with the unit on minutes:
{ "ign_on_delay_s": 7, "ign_off_delay_m": 1, "pw_off_delay_m": 15, "ups_off_delay_m": 5, "ups_pw_off_delay_m": 2}There is no mode key: only the CQ20 has an ignition mode setting, and fields that do not apply are omitted rather than set to null.
ign get and ign set gain a unit property on a timer counted in minutes. It is omitted entirely when the timer is in seconds, so it never appears on a CQ20:
{ "timer": "pw-off-delay", "value": 15, "unit": "m"}An ign set on a CQ40N or CQ40 series timer counted in minutes reports stored as well:
{ "timer": "ign-off-delay", "requested": 2, "actual": 2, "verified": true, "stored": true, "unit": "m"}Writing a timer on a CQ40N or CQ40 series can switch the MCU’s settings source from the BIOS to its own settings. When that happens the ign set JSON carries an extra notice string, and it is absent otherwise:
{ "timer": "ign-off-delay", "requested": 2, "actual": 2, "verified": true, "stored": true, "unit": "m", "notice": "The settings source was switched from BIOS to the MCU's own settings."}Reading and setting the delay unit
Section titled “Reading and setting the delay unit”ign unit --json reports the current setting:
{ "unit": "minutes"}Changing it reports requested, actual and verified like ign set, but has no stored field, and the key is setting rather than timer, because the delay unit applies to the whole device rather than to one timer:
{ "setting": "delay-unit", "requested": "seconds", "actual": "seconds", "verified": true}A write still prompts for confirmation unless you pass --yes.
dio --json on a CQ40 series reports each channel as a boolean (true = High for a channel, On for the ignition line):
{ "platform": "In-CarPC CQ40 series", "inputs": { "di1": true, "di2": false }, "outputs": { "do1": false, "do2": false }, "ignition": true}A dio set write reports the same three fields as booleans, and has no stored field:
{ "channel": "do1", "requested": true, "actual": true, "verified": true}version --json is the full inventory record: build stamp, driver and module versions, and the supported-platform catalogue. Use it for fleet inventory without touching the hardware bus.
{ "app": "pcu-cli", "version": "1.2.1", "git_commit": "ef9796e2daa7", "build_date": "2026-10-23 09:32:27 UTC", "build_config": "Release", "os": "Windows", "pawnio_version": "2.2.0", "pawnio_date": "2026-03-15", "smbus_module_date": "2025-05-05", "lpcio_version": "0.2.7", "lpcio_date": "2026-06-03", "platforms": [ { "model": "CQ20", "description": "In-CarPC CQ20", "cpu": "Intel Atom x6425E", "cpu_codename": "Elkhart Lake", "bus": "PCH SMBus", "features": "Ignition timers", "tested_os": [ "Windows 11 25H2 (x64)", "Ubuntu 24.04 LTS (x64)", "Windows 11 26H2 (x64)", "Ubuntu 26.04.1 LTS (x64)" ] }, { "model": "CQ40", "description": "In-CarPC CQ40 series", "cpu": "Intel (CQ41/CQ43/CQ47)", "cpu_codename": "Haswell", "bus": "SuperIO GPIO ports + PCH SMBus", "features": "Ignition timers, Digital I/O", "tested_os": [ "Windows 10 22H2 (x64)", "Ubuntu 24.04 LTS (x64)", "Ubuntu 26.04 LTS (x64)" ] }, { "model": "CQ40N", "description": "In-CarPC CQ40N series", "cpu": "Intel (CQ41N/CQ43N/CQ47N)", "cpu_codename": "Skylake", "bus": "PCH SMBus", "features": "Ignition timers", "tested_os": [ "Ubuntu 24.04 LTS (x64)", "Ubuntu 24.04.2 LTS (x64)", "Ubuntu 26.04 LTS (x64)" ] }, { "model": "CQ50S", "description": "In-CarPC CQ50S series", "cpu": "Intel Core (CQ53S/CQ55S/CQ57S)", "cpu_codename": "Tiger Lake", "bus": "PCH SMBus", "features": "Ignition timers", "tested_os": [ "Windows 11 26H2 (x64)", "Ubuntu 26.04.1 LTS (x64)" ] } ], "validated_configs": [ "Windows 11 25H2 (x64) - CQ20", "Ubuntu 24.04 LTS (x64) - CQ20", "Windows 11 26H2 (x64) - CQ20", "Ubuntu 26.04.1 LTS (x64) - CQ20", "Windows 10 22H2 (x64) - CQ40", "Ubuntu 24.04 LTS (x64) - CQ40", "Ubuntu 26.04 LTS (x64) - CQ40", "Ubuntu 24.04 LTS (x64) - CQ40N", "Ubuntu 24.04.2 LTS (x64) - CQ40N", "Ubuntu 26.04 LTS (x64) - CQ40N", "Windows 11 26H2 (x64) - CQ50S", "Ubuntu 26.04.1 LTS (x64) - CQ50S" ]}JSON field notes
Section titled “JSON field notes”- Fields that do not apply are omitted, not set to null. On a CQ20, CQ40N or CQ50S,
status --jsonhas noinputsoroutputs; on a CQ40N, CQ40 series or CQ50S there is nomode. On Linux,version --jsonomits thepawnio_*,smbus_module_date, andlpcio_*fields. - A platform that has not been validated on hardware yet carries no
tested_oslist and contributes nothing tovalidated_configs. Treat an absenttested_osas “not validated”, not as a parsing error. Every platform in this release has at least one entry, but a newly added model may not. The CQ40 series entry covers the ignition timers and digital I/O together, so one operating system can appear for it without both halves being validated. tested_oslists only the operating systems. Each one appears once, even when it was validated on more than one BIOS. The matching BIOS and date are not in the JSON; see Supported Platforms for those.featuresreports only the capabilities pcu exposes as features. The selectable delay unit of the CQ40N and CQ40 series is not one of them, so a CQ40Nfeaturesstring isIgnition timerseven thoughign unitworks there.ignition_lineappears instatus --jsonon a CQ40 series and a CQ50S, which have an ignition input. On a CQ40 series it followsoutputs; on a CQ50S it followstimers_stored. It is omitted on a CQ20 and a CQ40N.- The CQ50S
UPS ModeandUPS Voltagelines of thestatustext have nostatus --jsonfields. - Boolean channel values are
truefor High (inputs and outputs) andtruefor On (the ignition line). - On an
ign setwrite, the exit code is 0 only whenverifiedandstoredare both true. It is 1 when the readback differs or a CQ20 or CQ50S store was not confirmed. Adio setorign unitwrite has nostoredfield; its exit code mirrorsverified. A script can check the exit code or the fields. git_commit,build_date, andbuild_configinversion --jsonare stamped at build time and will differ from the example above.timers_storedappears instatus --jsononly when the ignition timers are reachable (CQ20, CQ40 series, CQ40N and CQ50S), straight after theignitionblock. It is a fixed fact about the platform, not a live check. It is omitted when theignitionblock is.- A CQ40 series can connect with only one of its two halves, the SMBus ignition timers or the port I/O digital I/O. When one half is missing,
status --jsonomits that half’s block and addsignition_unavailableordio_unavailablewith a sentence saying why. Both keys are absent when everything is reachable. On such a connectionpcu-cli ignorpcu-cli dioprints the same sentence on stderr and exits 1, because the hardware has the feature and the connection could not reach it. On a platform that never has the feature they exit 2.
Quiet mode
Section titled “Quiet mode”--quiet prints just the value, with no labels or headers, one per line. It is the simplest form to parse and it never prompts. Reads:
$ pcu-cli ign get sw-off-delay --quiet3$ pcu-cli dio get di1 --quiet0Writes print the value read back, and still set the exit code. The number is printed even when the exit code is 1, so always check the exit code:
$ pcu-cli dio set do1 1 --quiet1On ign set the exit code is also 1 when a CQ20 or CQ50S does not confirm the store. --quiet prints nothing about it, so the exit code is the only signal. The one exception is the settings-source notice on a CQ40 or CQ40N series, which --quiet writes to stderr, so stdout stays the bare value.
Examples
Section titled “Examples”Assert a digital output at boot. On Linux, run this from a systemd unit or an @reboot cron job:
pcu-cli dio set do1 1 --yesOn Windows, run the same command from a Task Scheduler task set to trigger “At startup”:
pcu-cli.exe dio set do1 1 --yesCollect a fleet inventory without touching the hardware bus:
pcu-cli version --json > inventory.jsonChange the shutdown delay across a fleet and fail loudly if the write did not verify or was not stored:
pcu-cli ign set sw-off-delay 120 --yes --quietif ($LASTEXITCODE -ne 0) { Write-Error "timer not verified or not stored" }Extract a single value with jq:
pcu-cli ign get sw-off-delay --json | jq '.value'Cancelling
Section titled “Cancelling”pcu-cli handles Ctrl+C gracefully: an in-flight bus transfer is allowed to finish and the transport is cleaned up before the tool exits, so a cancel never leaves a transfer half-done.
Thread and process safety
Section titled “Thread and process safety”pcu accesses the hardware bus directly. To avoid clashing with other low-level tools, every transfer is serialized on the standard system-wide bus mutexes also used by tools like HWiNFO (Access_SMBUS.HTP.Method for SMBus, Access_ISABUS.HTP.Method for SuperIO port I/O). Each access waits up to 5 seconds for the bus, then fails cleanly.
