Add camera module: drive UVC webcam controls via cameractrls
New `camera` module in modules.example.yaml (and the embedded copy) with four functions: `set` (any control=value list, incl. preset/colour buttons), `toggle` (flip between two values), `adjust` (step a numeric control by a delta, clamped to the min/max parsed from `cameractrls -l`, with optional `extra` controls applied first), and `is` (poll helper, exit 0 on match). Device comes from CAMERA_DEVICE in .env (default /dev/video0) or a per-key `device` param. cameractrls exits 0 for unknown controls, so polls must use `is`; stderr is discarded to drop Python deprecation warnings. README: Camera module section with setup, function table, a folder example, and the oksvg viewBox-offset centring gotcha for SVG icons. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017iodiNMYL9iuT7f6WCe5iv
This commit is contained in:
78
README.md
78
README.md
@@ -862,6 +862,84 @@ keys:
|
||||
|
||||
**Note — absolute paths in modules:** The example templates call `/usr/local/bin/obs-cmd` rather than just `obs-cmd`. This is because launchd (macOS) and systemd (Linux) give the service a minimal `PATH` that doesn't include `/usr/local/bin` or Homebrew. Use the absolute path returned by `which obs-cmd` in your own module templates, or set `PATH` in the launchd plist / systemd unit.
|
||||
|
||||
#### Camera module (Linux)
|
||||
|
||||
The example `modules.yaml` includes a `camera` module that drives any UVC webcam's V4L2 controls — zoom, pan/tilt, focus, exposure, white balance, brightness/contrast and so on — through [`cameractrls`](https://github.com/soyersoyer/cameractrls).
|
||||
|
||||
**Setup:**
|
||||
|
||||
1. Install `cameractrls` (Arch: `pacman -S cameractrls`; other distros: see the project README). The module calls `/usr/bin/cameractrls`.
|
||||
2. Point the module at your camera's stable device path (it defaults to `/dev/video0`, which renumbers across reboots):
|
||||
```bash
|
||||
ls -l /dev/v4l/by-id/ # pick the *-video-index0 entry for your camera
|
||||
echo 'CAMERA_DEVICE=/dev/v4l/by-id/usb-046d_Logitech_BRIO_XXXX-video-index0' >> ~/.config/streamdeck-go/.env
|
||||
```
|
||||
Any function also accepts a per-key `device` param for multi-camera setups.
|
||||
3. List the control names and ranges your camera exposes:
|
||||
```bash
|
||||
cameractrls -d /dev/video0 -l
|
||||
```
|
||||
|
||||
**Functions:**
|
||||
|
||||
| Function | Purpose | Params |
|
||||
|---|---|---|
|
||||
| `set` | Set one or more controls (comma-separated). Also fires button controls such as `preset=save_1` / `preset=load_1` or `color_preset=vivid` | `controls` |
|
||||
| `toggle` | Flip a control between two values — 0/1 switches or menu controls | `control`, `a`, `b` |
|
||||
| `adjust` | Step a numeric control by `delta` (negative to decrease), clamped to the min/max the camera reports. `extra` is applied first on the same call, e.g. `auto_exposure=manual_mode` so stepping exposure also leaves auto | `control`, `delta`, `extra` |
|
||||
| `is` | Poll helper: exits 0 when `control == value` | `control`, `value` |
|
||||
|
||||
**Example — a camera folder with FOV presets, a stepper pair and a status toggle:**
|
||||
|
||||
```yaml
|
||||
keys:
|
||||
18:
|
||||
icon: camera.svg
|
||||
text: "Camera"
|
||||
folder: camera
|
||||
|
||||
folders:
|
||||
camera:
|
||||
keys:
|
||||
1:
|
||||
icon: fov-wide.svg
|
||||
text: "Wide"
|
||||
module: camera
|
||||
function: set
|
||||
params: { controls: "logitech_brio_fov=90" }
|
||||
3:
|
||||
icon: zoom-out.svg
|
||||
text: "Zoom −"
|
||||
module: camera
|
||||
function: adjust
|
||||
params: { control: zoom_absolute, delta: "-25" }
|
||||
4:
|
||||
icon: zoom-in.svg
|
||||
text: "Zoom +"
|
||||
module: camera
|
||||
function: adjust
|
||||
params: { control: zoom_absolute, delta: "25" }
|
||||
14:
|
||||
icon_true: af-on.svg # green = autofocus on
|
||||
icon_false: af-off.svg # grey = manual focus
|
||||
text: "Autofocus"
|
||||
module: camera
|
||||
function: toggle
|
||||
params: { control: focus_automatic_continuous, a: "1", b: "0" }
|
||||
poll:
|
||||
module: camera
|
||||
function: is
|
||||
params: { control: focus_automatic_continuous, value: "1" }
|
||||
interval: 3s
|
||||
```
|
||||
|
||||
**Notes:**
|
||||
|
||||
- `cameractrls` exits 0 even for an unknown control name, so poll blocks must use the `is` function — never rely on a bare exit code.
|
||||
- Each call starts a Python process (~100 ms). A 3 s poll interval is comfortable; polls only run while the folder is open.
|
||||
- `cameractrls -l` prints Python deprecation warnings on stderr; the module templates discard stderr so the output stays clean.
|
||||
- SVG icons are rasterised by `oksvg`, which does **not** honour a viewBox x/y offset for centring (it applies the offset in pixels before scaling). To centre a glyph and leave room for a text label, keep `viewBox="0 0 S S"` and wrap the paths in `<g transform="translate(x y)">`.
|
||||
|
||||
#### Using modules in config.yaml
|
||||
|
||||
Reference a module function instead of writing inline commands:
|
||||
|
||||
Reference in New Issue
Block a user