# Adding a device to lightctl You are extending a peripheral-lighting framework. Do **not** add clap subcommands or QML branches for a new brand. ## Steps 1. Copy `src/devices/dummy.rs` to `src/devices/_.rs`. 2. Change `ID` (kebab-case, stable), `DeviceInfo` (name, kind, `udev` rules, `exclusive` if hidraw must not be shared). 3. Implement `detect` (USB vid/pid only — do not open hidraw here) and `open`. 4. In `status()`, list only the capabilities you implement. Use `0` for a real duty/brightness; omit or null for unknown. 5. In `apply()`, handle `Action` variants you support; `bail!("… does not support {}", action.summary())` for the rest. 6. Register `&YourDevice` in the `all()` slice in `src/devices/mod.rs`. 7. Put udev text on `DeviceInfo.udev` with `MODE="0660", GROUP="input", TAG+="uaccess"` (never `MODE="0666"`). Refresh `udev/70-lightctl.rules` via `lightctl udev` and commit it. The `70-` prefix is required so the uaccess tag is set before `73-seat-late.rules`. Do not add a `lightctl` `--install` path that runs this binary as root. ## Capabilities / actions | Capability | Action | UI the panel already shows | |---|---|---| | `color` | `SetColor` | presets, hex, per-device Color | | `brightness` / `lcd-brightness` | `SetBrightness` | slider 0–100 | | `effects` | `SetEffect` / `Off` / `Release` | buttons from `zones[0].effects` | | `lcd` `lcd-liquid` `lcd-image` `lcd-gif` | `SetLcd` | liquid, splash, file picker | | `lcd-rotate` | `SetLcdRotate` | 0/90/180/270 | | `cooling` | `SetDuty` | one slider per `channels[]` | | `battery` | (status only) | header caption | | `liquid_c` | (status only) | bar chip temperature | If you need a new verb, add it to `src/core/action.rs` **and** a capability the generic panel understands. Never `if device.id == ...` in QML. ## Verify ``` cargo test --offline --lib LIGHTCTL_DUMMY=1 lightctl status --json cargo build --release ``` Status must stay fast: no optional protocol probes on `status()`. Read `docs/adding-a-device.md` for the longer checklist.