Skip to content
Back to skills

Verifying Firmware Ui

ASecurity

Checks firmware UI and Clawd behaviour changes visually - the simulator grid (every panel at once, scripted, deterministic), single-sim screenshots (SIM_SHOTS, SIM_CMDS, SIM_TAPS), director walkthroughs, then `clawd <beat>` + `screenshot` on a connected board, with the C6 no-screenshot limit. Use after any change to the meters, Clawd, the face, layouts or LVGL drawing, when asked to screenshot the device or simulator, or before opening a firmware UI PR.

  • 2,260 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 16, 2026
ai-agentspythonbashtesting

Security analysis

A100/100

Scanned October 16, 2026

npx -y skills add HermannBjorgvin/Clawdmeter --skill verifying-firmware-ui --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Verifying Firmware Ui?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Verifying Firmware Ui
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/hermannbjorgvin-verifying-firmware-ui/badge)](https://www.skillsdirectory.com/skills/hermannbjorgvin-verifying-firmware-ui)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: verifying-firmware-ui
description: Checks firmware UI and Clawd behaviour changes visually - the simulator grid (every panel at once, scripted, deterministic), single-sim screenshots (SIM_SHOTS, SIM_CMDS, SIM_TAPS), director walkthroughs, then `clawd <beat>` + `screenshot` on a connected board, with the C6 no-screenshot limit. Use after any change to the meters, Clawd, the face, layouts or LVGL drawing, when asked to screenshot the device or simulator, or before opening a firmware UI PR.
---

# Verifying firmware UI

Check your own UI changes; don't ask the user to look first. Read every
capture you take. The simulator is the first pass, real hardware the last.

## Simulator grid (start here)

`tools/simgrid/` runs the sim for every supported panel at once on one
virtual clock (guide: [docs/sim-grid.md](../../../docs/sim-grid.md)). Write a
script of actions to your scratch dir and run it headless; it rebuilds stale
sims, prints the files it saved, and gives the same pixels every run:

```bash
SCRATCH=/your/scratch/dir
cat > "$SCRATCH/check.txt" <<EOS
step 6000
shot $SCRATCH/meters.png
beat attention
record $SCRATCH/attention.gif fps=12 scale=0.4
step 8000
record_stop
link false
step 500
shot $SCRATCH/pairing.png
EOS
python3 tools/simgrid/simgrid.py run "$SCRATCH/check.txt"
```

Read every PNG, and
pull a few frames out of a GIF to check motion. `--boards 154,round` limits
the cells; `simgrid.py actions` lists everything a script can do (payload
fields, presets, alerts, events, beats, taps and button presses on one
board, the BLE link, battery, scenarios). For a before/after comparison,
run the same script on both versions.

## Single simulator

The sim runs the full firmware loop unmodified in an SDL2 window (director,
meters, idle fade, pair gesture, payload/signals, rate math, chime logic);
only `ble.cpp`/`chime.cpp` are stubs. It needs SDL2 dev files
(`libsdl2-dev` / `brew install sdl2`); if they're missing, ask the user to
install them. Build from the repo root, run from `firmware/`:

```bash
pio run -d firmware -e sim
cd firmware
SDL_VIDEODRIVER=dummy SIM_FAST=1 SIM_SCENARIO=sim/director.jsonl \
  SIM_SHOTS="19500:/tmp/shot-a.bmp,57000:/tmp/shot-b.bmp" .pio/build/sim/program
```

Write captures outside the repo (a scratch dir), convert BMP → PNG if needed
(`convert in.bmp out.png`), and Read them.

| Variable | Use |
| --- | --- |
| `SIM_FAST=1` | Director minutes → seconds (`clawd_tuning_fast()`) |
| `SIM_SCENARIO=sim/<file>.jsonl` | Payload script; `director.jsonl` hits every beat, `director-resume.jsonl` interruptions |
| `SIM_SHOTS="ms:path,…"` | Screenshots at ascending times; exits after the last |
| `SIM_CMDS="ms:cmd;…"` | Serial commands, e.g. `clawd show`, `clawd peek <x>`, `liveliness 1`; `pwr`, `prompt`, `stop`, `alert` press the button/keys |
| `SIM_TAPS="ms@x,y;…"` | Touches; `ms@x,y+hold_ms` for a touch hold |
| `SIM_TRACE=1` | Director transitions with timestamps (find when a beat actually happens) |
| `SIM_NO_PWR=1` / `SIM_NO_TOUCH=1` / `SIM_MINIMAL=1` | A board without a PWR button / without a touchscreen / `BoardCaps.minimal_ui` |
| `SIM_CIRCLE=1` | A round panel (`BoardCaps.round_panel`); the corners are drawn as a bezel |
| `SIM_AUTOSHOT_MS`, `SIM_AUTOSHOT_PATH` | One headless shot (what CI captures) |

Full key map, scenario format and the rest of the variables:
[docs/simulator.md](../../../docs/simulator.md).

**Other panel sizes** are compile-time defines, so each size needs its own
build dir (never the scratchpad root):

```bash
PLATFORMIO_BUILD_DIR=/tmp/clawdmeter-sim-240 \
PLATFORMIO_BUILD_FLAGS="-DSIM_LCD_W=240 -DSIM_LCD_H=240" pio run -d firmware -e sim
(cd firmware && /tmp/clawdmeter-sim-240/sim/program)
```

Check every size your change can affect: 480×480 and 410×502 (large
design), 368×448 (compact), 240×240 (small), and for layout changes the port
sizes in `firmware/test/test_layout` (466×466 with `SIM_CIRCLE=1`, 450×600,
320×240, 240×320, 170×320, 135×240, 200×200, …).

**Layout changes** (`layout.cpp`, `ui_text.h`, anything that moves or resizes
meters text): run `pio test -d firmware -e native -f test_layout` first. It
checks every supported panel shape with the real fonts and names what leaves
the glass, overlaps or doesn't fit. Then diff before/after sim captures at
the four sizes on main: they should be pixel-identical unless the change is
meant to show there. Attention captures vary run to run (sprite and scroll
timing), so compare those against several base runs.

**Walkthroughs** (from `firmware/`):

```bash
SIM_FAST=1 SIM_SCENARIO=sim/director.jsonl .pio/build/sim/program
#   notice ~3 s, show ~14 s, screensaver ~53 s, wake ~90 s, attention ~97–110 s, reset joy ~115 s
SIM_FAST=1 SIM_SCENARIO=sim/director-resume.jsonl \
  SIM_CMDS="2500:clawd lurk;5200:prompt;34000:alert;67500:pwr;80000:prompt" .pio/build/sim/program
```

Scene choice shifts later timings; use `SIM_TRACE=1` rather than guessing.
Reference captures live in `screenshots/director/`; expected behaviour is in
[docs/clawd-director.md](../../../docs/clawd-director.md).

## On hardware

The sim renders with desktop LVGL and fake data. **Always do a final check on
real hardware before merging panel-related changes**: column offsets,
rotation and flush rounding live in the board code, not shared code.

With a board attached and flashed (`flashing-and-probing-boards` skill), on
each UI iteration:

1. Force the state: `clawd <show|screensaver|attention|joy|lurk|home>` or
   `clawd peek <x>` over serial.
2. Capture it with the `capturing-device-screenshots` skill.
3. Read the PNG.

There's no need to edit the boot screen in `main.cpp` to reach a state.

**C6 boards can't be captured** (no PSRAM for the snapshot). Verify C6
changes in the sim at 480×480 / 368×448 and say in the PR that the C6 panel
needs eyeballing on hardware.

## Reporting

In the PR, label simulator captures as simulator output; they don't count as
hardware testing. Name the exact boards tested on hardware, or write
"not tested on hardware".

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.