/board-status — read the H15's vital signs
Give the user one snapshot: thermals, power, CPU, memory, NN core utilization, running app PID. All canonical Hailo commands — nothing invented.
Authoritative reference: Hailo OS User Guide v1.12.0 — docs/guides/hailo_os_guide_1.12.0.pdf. Relevant sections: §3.3 ("Temperature Monitoring"), §6.1 ("Hailo-15 Profiler"), §6.2 ("NoC Profiler"), §6.3 ("CMA Heap info").
hailortcli cheat sheet (relevant subcommands)
The HailoRT CLI is preinstalled on the board image as /usr/bin/hailortcli. The subcommands this skill uses:
hailortcli fw-control identify — returns firmware version, serial, board name. A health check that the SCU/FW side is alive.
hailortcli monitor — prints three tables once per second:
- Devices —
Device Id, total Utilization (%) (scheduler-runtime share spent on the NN core), Architecture.
- Models — per-loaded model:
FPS, Utilization (%), PID of the owning process.
- Frames state — per stream of each model: queue depths and pending counts.
Sample interval defaults to 1 s — override with HAILO_MONITOR_TIME_INTERVAL=<ms>. Preconditions for non-empty output: see Gotchas.
hailortcli measure-power — instantaneous wattage from the device side. Skip on every poll; perturbs the device briefly. Useful for spot-checks under a known workload.
Preconditions
/connect succeeded — ssh -o BatchMode=yes root@<board> works (default 10.0.0.1).
Procedure
The board identifies its own SBC revision via /etc/build-info's MACHINE field. The procedure reads it inline and picks the right INA set automatically — no need to ask the user.
MACHINE |
Board label |
INA addresses for SOC power |
Rails measured |
hailo15-sbc |
SBC-Mercury-Rev2 |
1-42, 1-43, 1-40 |
DDR_VDDQX, INA_0V8, INA_1V8 |
hailo15-sbc-rev3-1 |
SBC-Mercury-Rev3.1 |
1-46, 1-47, 1-43, 1-48 |
INA_0V6, VDDQ_SOC, INA_0V8, INA_1V8 |
hailo15l-sbc |
SBC-Pluto |
1-40, 1-41, 1-44, 1-46, 1-47 |
INA_1V8, INA_0V8, INA_3V3, VDDQX_SOC, VDDQ_SOC |
Batch the read in a single SSH call. The script auto-selects INAS from MACHINE:
ssh root@<board> '
M=$(awk -F" = " "/^MACHINE/{print \$2}" /etc/build-info)
case "$M" in
hailo15-sbc) L="SBC-Mercury-Rev2"; INAS="1-42 1-43 1-40" ;;
hailo15-sbc-rev3-1) L="SBC-Mercury-Rev3.1"; INAS="1-46 1-47 1-43 1-48" ;;
hailo15l-sbc) L="SBC-Pluto"; INAS="1-40 1-41 1-44 1-46 1-47" ;;
*) L="unknown($M)"; INAS="" ;;
esac
echo "=== identity ==="
uname -a; grep ^VERSION= /etc/os-release
echo "Board: $L (MACHINE=$M)"
echo "=== sensors (raw rails — thermals + per-INA power) ==="
sensors
echo "=== SOC power (sum of $INAS) ==="
sensors 2>/dev/null | awk -v addrs="$INAS" "
BEGIN { n = split(addrs, a, \" \"); for (i = 1; i <= n; i++) want[a[i]] = 1; total = 0 }
/^ina231_precise-i2c-/ {
split(\$0, p, \"i2c-\"); curr = p[2]
keep = (curr in want) ? 1 : 0
}
/Power:/ && keep {
val = \$3 + 0; unit = \$4
if (unit == \"uW\") val /= 1000000
else if (unit == \"mW\") val /= 1000
total += val
}
END { printf \"SOC power: %.2f W\n\", total }
"
echo "=== cpu / mem ==="
cat /proc/loadavg
top -bn1 -w 200 | sed -n "1,5p"
free -h | head -2
echo "=== cma / dma-buf (OS Guide §6.3) ==="
/usr/bin/hailo-dma-usage.sh -v 2>/dev/null
echo "=== nn core (HailoRT CLI) ==="
hailortcli scan 2>&1 | head -5
hailortcli fw-control identify 2>&1 | grep -E "Firmware|Serial|Board" | head -5
echo "=== dsp ==="
(stdbuf -oL dsp-utilization 2>/dev/null & p=$!; sleep 2; kill $p 2>/dev/null) \
| awk "/[0-9]+(\.[0-9]+)?[[:space:]]*%/{last=\$0} END{if(last)print last; else print \"N/A\"}"
echo "=== running apps ==="
pgrep -af "_case_study|hailort_server|hailoencodebin|hailofrontend|camera-viewer-server"
'
The aggregator parses each ina231_precise-i2c-X-XX chip's Power: line, normalizes the unit (µW / mW / W), and prints exactly SOC power: N.NN W. The full per-rail sensors output stays above it for debugging. If MACHINE is unrecognized, INAS is empty and SOC power will print 0.00 W — flag that to the user instead of trusting the number.
Capture one frame of hailortcli monitor for live NN core utilization. The interactive form (hailortcli monitor) refreshes in place using ANSI screen-clear codes, so a plain piped/timeout'd ssh returns empty. Use this incantation instead — it forces line buffering, kills after 2 s, strips the ANSI escapes, and keeps just the first refresh:
ssh root@<board> 'stdbuf -oL hailortcli monitor & p=$!; sleep 2; kill $p 2>/dev/null' \
| sed -E "s/\x1b\[[?]?[0-9;]*[a-zA-Z]//g; s/\x1b[()][AB012]//g" \
| awk "/Device ID/{found=1} found{print}" | head -20
Empty output ⇒ the running app didn't export HAILO_MONITOR=1, or isn't using a VDevice (see Gotchas) — report that fact, don't make up a "0 %" reading.
Summarize — extract numbers, don't dump raw output. Use the SOC power: <N> W line from step 1 as the headline power figure (not per-rail). Highlight any line that's trending hot or unusually loaded first. The (high = +X°C) numbers inside the raw sensors block are sensor-chip trip points, not the SoC die's thermal envelope (which is SCU-managed — see thermal gotcha below).
Output format
H15<H|L> rev<…> · SW <ver> · uptime <…>
Thermals: H15 temp1 <X>°C temp2 <Y>°C near-SoC <Z>°C
SOC power: <N.NN> W
CPU (4c): load <1m> / <5m> / <15m> id <X>% sy <Y>%
Memory: <avail> MiB available of <total> MiB
NN core: <N> device(s), FW <ver>
DSP: <X>% utilization
Running: <app cmd line>
If anything looks off — load > 3 on 4 cores, MemAvailable < 200 MiB, no NN device found, app crash-looping, or die temps trending into the 80–90s — call it out as the first line of the report.
When to delegate / dig deeper
Gotchas
hailortcli monitor is silent unless the running app exported HAILO_MONITOR=1 and uses a VDevice. With either missing, you get empty output.
(high = +X°C) in sensors output is the per-sensor trip, not the SoC die envelope. The die is SCU-managed: graduated throttling (states S0…S4) below 120°C, hard shutdown at 120°C — OS Guide §3.3.
- CMA pressure looks like a pipeline failure, not a memory failure. When video stages drop frames while
free -h is healthy, check hailo-dma-usage.sh -v Use%. The hailo_media_buf,cma row is the contiguous-memory pool 4K / media-library pipelines allocate from — the first to fill up under heavy video load.
- One-shot
top -bn1 reports CPU since boot on its first sample. For a current spike, sample twice: top -bn2 -d1 | tail -20 and use the second snapshot.
1---2name: board-status3description: Snapshot the H15 SBC's runtime health — chip temperature, power consumption, CPU load, DRAM use, NN core utilization, DSP utilization, and the running app's PID. Use when the user asks "is the board OK", "is it overheating", "how loaded is the chip", "why is FPS low", or before/after a long demo to check how hot it's running and how much it's drawing. Read-only over SSH; no app restart.4---56# /board-status — read the H15's vital signs78Give the user one snapshot: thermals, power, CPU, memory, NN core utilization, running app PID. All canonical Hailo commands — nothing invented.910Authoritative reference: **Hailo OS User Guide v1.12.0** — `docs/guides/hailo_os_guide_1.12.0.pdf`. Relevant sections: §3.3 ("Temperature Monitoring"), §6.1 ("Hailo-15 Profiler"), §6.2 ("NoC Profiler"), §6.3 ("CMA Heap info").1112### `hailortcli` cheat sheet (relevant subcommands)1314The HailoRT CLI is preinstalled on the board image as `/usr/bin/hailortcli`. The subcommands this skill uses:1516- **`hailortcli fw-control identify`** — returns firmware version, serial, board name. A health check that the SCU/FW side is alive.17- **`hailortcli monitor`** — prints three tables once per second:18 1. **Devices** — `Device Id`, total `Utilization (%)` (scheduler-runtime share spent on the NN core), `Architecture`.19 2. **Models** — per-loaded model: `FPS`, `Utilization (%)`, `PID` of the owning process.20 3. **Frames state** — per stream of each model: queue depths and pending counts.2122 Sample interval defaults to 1 s — override with `HAILO_MONITOR_TIME_INTERVAL=<ms>`. Preconditions for non-empty output: see Gotchas.2324- **`hailortcli measure-power`** — instantaneous wattage from the device side. Skip on every poll; perturbs the device briefly. Useful for spot-checks under a known workload.2526## Preconditions2728`/connect` succeeded — `ssh -o BatchMode=yes root@<board>` works (default `10.0.0.1`).2930## Procedure3132The board identifies its own SBC revision via `/etc/build-info`'s `MACHINE` field. The procedure reads it inline and picks the right INA set automatically — no need to ask the user.3334| `MACHINE` | Board label | INA addresses for SOC power | Rails measured |35|------------------------|---------------------|---------------------------------------------------|-------------------------------------------------|36| `hailo15-sbc` | SBC-Mercury-Rev2 | `1-42`, `1-43`, `1-40` | DDR_VDDQX, INA_0V8, INA_1V8 |37| `hailo15-sbc-rev3-1` | SBC-Mercury-Rev3.1 | `1-46`, `1-47`, `1-43`, `1-48` | INA_0V6, VDDQ_SOC, INA_0V8, INA_1V8 |38| `hailo15l-sbc` | SBC-Pluto | `1-40`, `1-41`, `1-44`, `1-46`, `1-47` | INA_1V8, INA_0V8, INA_3V3, VDDQX_SOC, VDDQ_SOC |39401. **Batch the read in a single SSH call.** The script auto-selects `INAS` from `MACHINE`:4142 ```bash43 ssh root@<board> '44 M=$(awk -F" = " "/^MACHINE/{print \$2}" /etc/build-info)45 case "$M" in46 hailo15-sbc) L="SBC-Mercury-Rev2"; INAS="1-42 1-43 1-40" ;;47 hailo15-sbc-rev3-1) L="SBC-Mercury-Rev3.1"; INAS="1-46 1-47 1-43 1-48" ;;48 hailo15l-sbc) L="SBC-Pluto"; INAS="1-40 1-41 1-44 1-46 1-47" ;;49 *) L="unknown($M)"; INAS="" ;;50 esac5152 echo "=== identity ==="53 uname -a; grep ^VERSION= /etc/os-release54 echo "Board: $L (MACHINE=$M)"5556 echo "=== sensors (raw rails — thermals + per-INA power) ==="57 sensors5859 echo "=== SOC power (sum of $INAS) ==="60 sensors 2>/dev/null | awk -v addrs="$INAS" "61 BEGIN { n = split(addrs, a, \" \"); for (i = 1; i <= n; i++) want[a[i]] = 1; total = 0 }62 /^ina231_precise-i2c-/ {63 split(\$0, p, \"i2c-\"); curr = p[2]64 keep = (curr in want) ? 1 : 065 }66 /Power:/ && keep {67 val = \$3 + 0; unit = \$468 if (unit == \"uW\") val /= 100000069 else if (unit == \"mW\") val /= 100070 total += val71 }72 END { printf \"SOC power: %.2f W\n\", total }73 "7475 echo "=== cpu / mem ==="76 cat /proc/loadavg77 top -bn1 -w 200 | sed -n "1,5p"78 free -h | head -27980 echo "=== cma / dma-buf (OS Guide §6.3) ==="81 /usr/bin/hailo-dma-usage.sh -v 2>/dev/null8283 echo "=== nn core (HailoRT CLI) ==="84 hailortcli scan 2>&1 | head -585 hailortcli fw-control identify 2>&1 | grep -E "Firmware|Serial|Board" | head -58687 echo "=== dsp ==="88 (stdbuf -oL dsp-utilization 2>/dev/null & p=$!; sleep 2; kill $p 2>/dev/null) \89 | awk "/[0-9]+(\.[0-9]+)?[[:space:]]*%/{last=\$0} END{if(last)print last; else print \"N/A\"}"9091 echo "=== running apps ==="92 pgrep -af "_case_study|hailort_server|hailoencodebin|hailofrontend|camera-viewer-server"93 '94 ```9596 The aggregator parses each `ina231_precise-i2c-X-XX` chip's `Power:` line, normalizes the unit (µW / mW / W), and prints exactly `SOC power: N.NN W`. The full per-rail `sensors` output stays above it for debugging. If `MACHINE` is unrecognized, `INAS` is empty and SOC power will print `0.00 W` — flag that to the user instead of trusting the number.97982. **Capture one frame of `hailortcli monitor`** for live NN core utilization. The interactive form (`hailortcli monitor`) refreshes in place using ANSI screen-clear codes, so a plain piped/timeout'd ssh returns empty. Use this incantation instead — it forces line buffering, kills after 2 s, strips the ANSI escapes, and keeps just the first refresh:99 ```bash100 ssh root@<board> 'stdbuf -oL hailortcli monitor & p=$!; sleep 2; kill $p 2>/dev/null' \101 | sed -E "s/\x1b\[[?]?[0-9;]*[a-zA-Z]//g; s/\x1b[()][AB012]//g" \102 | awk "/Device ID/{found=1} found{print}" | head -20103 ```104 Empty output ⇒ the running app didn't export `HAILO_MONITOR=1`, or isn't using a `VDevice` (see Gotchas) — report that fact, don't make up a "0 %" reading.1051063. **Summarize — extract numbers, don't dump raw output.** Use the **`SOC power: <N> W`** line from step 1 as the headline power figure (not per-rail). Highlight any line that's trending hot or unusually loaded *first*. The `(high = +X°C)` numbers inside the raw `sensors` block are sensor-chip trip points, **not** the SoC die's thermal envelope (which is SCU-managed — see thermal gotcha below).107108## Output format109110```111H15<H|L> rev<…> · SW <ver> · uptime <…>112Thermals: H15 temp1 <X>°C temp2 <Y>°C near-SoC <Z>°C113SOC power: <N.NN> W114CPU (4c): load <1m> / <5m> / <15m> id <X>% sy <Y>%115Memory: <avail> MiB available of <total> MiB116NN core: <N> device(s), FW <ver>117DSP: <X>% utilization118Running: <app cmd line>119```120121If anything looks off — load > 3 on 4 cores, MemAvailable < 200 MiB, no NN device found, app crash-looping, or die temps trending into the 80–90s — call it out as the **first** line of the report.122123## When to delegate / dig deeper124125- **`hailo-soc-profiler` (OS Guide §6.1)** for Perfetto traces — DDR bandwidth, media-library events, queue levels, Linux scheduler. Heavyweight; not for routine status:126 ```bash127 hailo-soc-profiler applications noc-bandwidth-vpu -t 10s -o /tmp/soc.trace128 scp root@<board>:/tmp/soc.trace . # then open in ui.perfetto.dev129 ```130- **`htop`** when the user wants the live interactive CPU view rather than a one-shot snapshot.131- **`hailo-dma-usage.sh -u M`** to force MiB units explicitly, or **`-h`** for the full flag list. The snapshot already calls this with `-v`; usually you don't need anything else.132- **doc-explorer** for OS Guide §3.3 (thermal throttling internals, Hailo Thermal Engine) or §6.2 (NoC Profiler for memory bandwidth) — both inside the only doc the user is expected to have.133- **`hailortcli --help`** (or `hailortcli <subcommand> --help`) on the board itself for any sub-flag the cheat sheet doesn't cover.134135## Gotchas136137- **`hailortcli monitor` is silent unless the running app exported `HAILO_MONITOR=1` *and* uses a `VDevice`**. With either missing, you get empty output.138- **`(high = +X°C)` in `sensors` output is the per-sensor trip, not the SoC die envelope.** The die is SCU-managed: graduated throttling (states `S0`…`S4`) below 120°C, hard shutdown at 120°C — OS Guide §3.3.139- **CMA pressure looks like a pipeline failure, not a memory failure.** When video stages drop frames while `free -h` is healthy, check `hailo-dma-usage.sh -v` Use%. The `hailo_media_buf,cma` row is the contiguous-memory pool 4K / media-library pipelines allocate from — the first to fill up under heavy video load.140- **One-shot `top -bn1` reports CPU since boot** on its first sample. For a current spike, sample twice: `top -bn2 -d1 | tail -20` and use the second snapshot.