# MightyWatt Linux CLI Help This document matches the current backend/CLI tree in this repository. ## Scope Current features: - serial communication with MightyWatt hardware - reusable C backend (`libmightywatt_core` style project layout) - CLI control and monitoring - CSV logging - JSON-driven sequence runner - loops in the sequence engine - mandatory `abort_sequence` for safe shutdown / cleanup Current sequence format: - **JSON only** - YAML is **not** supported in the current C implementation --- ## General usage ```bash mwcli -d /dev/ttyACM0 [global options] [command args] ``` Example: ```bash ./mwcli -d /dev/ttyACM0 caps ``` --- ## Global options These options go before the command. ### `-d, --device PATH` Serial device path. Example: ```bash ./mwcli -d /dev/ttyACM0 caps ``` ### `-s, --settle-ms N` Delay after opening the serial port, in milliseconds. Default: ```text 2200 ``` Use this because Arduino-class boards often reset when the port is opened. Example: ```bash ./mwcli -d /dev/ttyACM0 -s 2500 caps ``` ### `-i, --interval-ms N` Polling interval in milliseconds. Used by: - `monitor` - `hold` Default: ```text 500 ``` ### `-c, --count N` Number of samples. Used by: - `monitor` - `hold` If omitted, the stream continues until interrupted with `Ctrl+C`. ### `--sample-period-ms N` Override `sample_period_ms` from the JSON sequence file. Used by: - `run-sequence` ### `--csv PATH` Write measurement samples to a CSV file. Works with: - `report` - `monitor` - `hold` - `load-on` - `load-off` - `safe` - `remote` - `set-*` - `run-sequence` ### `-j, --json` Print JSON to stdout instead of plain text. Useful for: - scripts - wrappers - future GUI integration Current behaviour: - one-shot commands print one JSON object - `monitor` and `hold` print JSON lines - `run-sequence` prints one summary object at the end ### `-h, --help` Show built-in CLI help. --- # Commands ## `idn` Query the device identity string. ## `caps` Read device capabilities. Typical fields: - firmware version - board revision - max current DAC / ADC - max voltage DAC / ADC - max power - DVM input resistance - temperature threshold ## `report` Read one measurement report. Returns: - current - voltage - power - temperature - remote state - status ## `monitor` Continuously poll and print measurements. Examples: ```bash ./mwcli -d /dev/ttyACM0 monitor ./mwcli -d /dev/ttyACM0 -i 500 -c 20 monitor ./mwcli -d /dev/ttyACM0 -j monitor ``` ## `set-current ` Stage/set current target. ## `set-voltage ` Stage/set voltage target. ## `set-power ` Stage/set power target. ## `set-resistance ` Stage/set resistance target. ## `set-vinv ` Stage/set inverted-voltage target. This is a firmware-supported special mode. ## `hold ` Enable and keep a target alive by polling continuously. This is the right command for real bench work because the MightyWatt watchdog requires regular host traffic. Modes: - `current` - `voltage` - `power` - `resistance` - `vinv` Aliases accepted: - `CC` - `CV` - `CP` - `CR` Examples: ```bash ./mwcli -d /dev/ttyACM0 hold current 0.250 ./mwcli -d /dev/ttyACM0 -i 500 -c 10 hold power 1.000 ./mwcli -d /dev/ttyACM0 -j hold resistance 20.000 ``` ## `load-on ` Apply a target once and return one report. Important: - this is a one-shot command - the hardware may fall back after ~1–2 seconds if no more host traffic follows - for sustained load use `hold` ## `load-off` Turn the load off. Current implementation: - host-side load-off via zero-current target - the MightyWatt protocol has no dedicated hardware output-enable bit ## `safe` Go to safe state. Current implementation: - load off - remote sense off ## `remote on|off` Enable or disable remote sense. ## `get-series` Read configured series resistance. Output unit: - ohms ## `set-series ` Set series resistance. ## `run-sequence ` Run a JSON sequence file. Examples: ```bash ./mwcli -d /dev/ttyACM0 run-sequence profile.json ./mwcli -d /dev/ttyACM0 --csv run.csv run-sequence profile.json ./mwcli -d /dev/ttyACM0 --sample-period-ms 200 run-sequence profile.json ``` --- # CSV logging When `--csv ` is used, the logger writes: - `timestamp_utc` - `elapsed_s` - `context` - `step_index` - `current_a` - `voltage_v` - `power_w` - `temperature_c` - `remote` - `status_bits` - `status_text` Example: ```bash ./mwcli -d /dev/ttyACM0 --csv monitor.csv -c 20 monitor ``` --- # JSON sequence format ## Top-level structure A sequence file is a JSON object with these top-level keys: ```json { "name": "example_name", "sample_period_ms": 500, "safety": { "max_voltage": 30.0, "max_current": 2.0, "max_power": 20.0, "abort_on_disconnect": true }, "steps": [ ... ], "abort_sequence": [ { "action": "safe" } ] } ``` Important: - `steps` is required and must be non-empty - `abort_sequence` is required and must be non-empty - `abort_sequence` runs at the normal end of the main sequence and also after runtime abort/error paths whenever possible ## Top-level fields ### `name` Optional string. ### `sample_period_ms` Optional number. Default: ```text 500 ``` Purpose: - polling interval during `hold`, `hold_until`, loops, ramps, and CSV logging ### `safety` Optional object. Supported fields: - `max_voltage` in volts - `max_current` in amps - `max_power` in watts - `abort_on_disconnect` boolean Practical note: - the current engine attempts the `abort_sequence` on runtime failures in general - `abort_on_disconnect` is kept in the profile format for future separation of policies, but is not yet handled as a dedicated branch different from other runtime failures ### `steps` Required array. ### `abort_sequence` Required array. Typical safe form: ```json "abort_sequence": [ { "action": "safe" } ] ``` --- # Supported actions ## `set_mode` Stage the operating mode. ```json { "action": "set_mode", "mode": "CC" } ``` Accepted `mode` values: - `CC` / `current` - `CV` / `voltage` - `CP` / `power` - `CR` / `resistance` - `CVINV` / `vinv` / `voltage_inverted` ## `set_current` ```json { "action": "set_current", "value": 0.20 } ``` Unit: amps. ## `set_voltage` ```json { "action": "set_voltage", "value": 4.80 } ``` Unit: volts. ## `set_power` ```json { "action": "set_power", "value": 2.00 } ``` Unit: watts. ## `set_resistance` ```json { "action": "set_resistance", "value": 10.0 } ``` Unit: ohms. ## `set_vinv` ```json { "action": "set_vinv", "value": 4.50 } ``` Unit: volts. ## `output` Enable or disable the staged output. ```json { "action": "output", "enabled": true } ``` or ```json { "action": "output", "enabled": false } ``` ## `hold` Keep the current staged/active target alive for a duration. ```json { "action": "hold", "duration_s": 30 } ``` ## `hold_until` Keep polling until a condition becomes true or timeout is reached. ```json { "action": "hold_until", "timeout_s": 300, "condition": { "type": "voltage_below", "value": 3.00 } } ``` ## `ramp_current` ```json { "action": "ramp_current", "start": 0.20, "stop": 1.00, "step": 0.10, "dwell_s": 20 } ``` ## `ramp_voltage` ```json { "action": "ramp_voltage", "start": 4.0, "stop": 5.0, "step": 0.1, "dwell_s": 10 } ``` ## `ramp_power` ```json { "action": "ramp_power", "start": 0.5, "stop": 5.0, "step": 0.5, "dwell_s": 15 } ``` ## `ramp_resistance` ```json { "action": "ramp_resistance", "start": 100.0, "stop": 10.0, "step": 10.0, "dwell_s": 5 } ``` ## `ramp_vinv` ```json { "action": "ramp_vinv", "start": 4.8, "stop": 4.0, "step": 0.1, "dwell_s": 10 } ``` ## `repeat` Run a nested block a fixed number of times. ```json { "action": "repeat", "times": 5, "steps": [ { "action": "set_current", "value": 0.20 }, { "action": "output", "enabled": true }, { "action": "hold", "duration_s": 10 }, { "action": "output", "enabled": false }, { "action": "hold", "duration_s": 5 } ] } ``` ## `repeat_until` Run a nested block until a condition becomes true. ```json { "action": "repeat_until", "timeout_s": 1800, "condition": { "type": "voltage_below", "value": 3.20 }, "steps": [ ... ] } ``` Notes: - the block runs at least once - `timeout_s` is optional - if omitted or `0`, the loop is unlimited ## `repeat_while` Run a nested block while a condition remains true. ```json { "action": "repeat_while", "timeout_s": 7200, "condition": { "type": "temperature_above", "value": 20.0 }, "steps": [ ... ] } ``` Notes: - the condition is checked before each iteration - `timeout_s` is optional - if omitted or `0`, the loop is unlimited ## `safe` Immediate safe-state action. ```json { "action": "safe" } ``` ## `remote` Set remote sense on or off. ```json { "action": "remote", "enabled": true } ``` --- # Conditions Supported condition types: - `voltage_below` - `voltage_above` - `current_below` - `current_above` - `power_below` - `power_above` - `temperature_above` Units: - voltage conditions: volts - current conditions: amps - power conditions: watts - temperature condition: °C --- # `break_if` Any step can carry an optional `break_if` object. Format: ```json "break_if": { "type": "temperature_above", "value": 45.0 } ``` Behaviour: - `break_if` is checked whenever a report is read during that step - on block steps like `repeat`, `repeat_until`, or `repeat_while`, the `break_if` stays active for the whole nested block - if `break_if` becomes true, the main sequence stops and the mandatory `abort_sequence` starts Typical use: - thermal guard during long tests - abort if measured voltage/current/power crosses a forbidden threshold --- # Sequence execution model Recommended staging pattern: 1. `set_mode` 2. `set_current` / `set_voltage` / `set_power` / `set_resistance` / `set_vinv` 3. `output true` 4. `hold`, `hold_until`, `ramp_*`, or loop block 5. `output false` or rely on `abort_sequence` Important: - the MightyWatt watchdog requires regular host traffic - `hold`, `hold_until`, ramps, and loop checks all provide that traffic - a plain one-shot `output true` step with no later polling logic is not suitable for long unattended operation --- # Example sequence with loop and safe abort ```json { "name": "repeat_until_cutoff", "sample_period_ms": 1000, "safety": { "max_voltage": 5.0, "max_current": 0.6, "max_power": 3.0, "abort_on_disconnect": true }, "steps": [ { "action": "set_mode", "mode": "CC" }, { "action": "repeat_until", "timeout_s": 14400, "condition": { "type": "voltage_below", "value": 3.20 }, "break_if": { "type": "temperature_above", "value": 45.0 }, "steps": [ { "action": "set_current", "value": 0.30 }, { "action": "output", "enabled": true }, { "action": "hold", "duration_s": 60 }, { "action": "output", "enabled": false }, { "action": "hold", "duration_s": 10 } ] } ], "abort_sequence": [ { "action": "safe" } ] } ``` Run it with: ```bash ./mwcli -d /dev/ttyACM0 --csv run.csv run-sequence repeat_until_cutoff.json ``` --- # Practical notes - Use `hold` or `run-sequence` for anything longer than a quick manual check. - Use `--csv` whenever the data matters. - Keep `abort_sequence` simple and safe. - Start with conservative limits. - `set-vinv` / `ramp_vinv` are advanced functions. - Loop timing in practice is affected by serial round-trip time and sample period; do not expect hard real-time behaviour. ## CSV raw mode Use `--csv-raw` together with `--csv ` to write elapsed time in **ms** and electrical values in **mA / mV / mW**. This is useful for spreadsheet tools that handle decimal separators poorly.