Adding readme updates

This commit is contained in:
lwoodard
2026-04-16 15:38:46 -06:00
parent 5e85dda038
commit 44dc22d8ee

View File

@@ -14,14 +14,14 @@ No Elgato software required — communicates directly with the device over USB H
- PNG, JPEG, and SVG icons, automatically scaled to key size - PNG, JPEG, and SVG icons, automatically scaled to key size
- Animated GIF support — frames pre-encoded at startup, cycled at the GIF's native rate - Animated GIF support — frames pre-encoded at startup, cycled at the GIF's native rate
- Runs any shell command on key press - Runs any shell command on key press
- **Status/toggle keys** — poll any shell command on an interval, swap icons based on output; icon updates on press - **Status/toggle keys** — poll any shell command on an interval, swap icons based on output; icon updates on press. Either icon can be an animated GIF (e.g. a flashing record indicator when recording is active).
- **Live config reload** — save your config and the deck updates instantly, no restart needed - **Live config reload** — save your config and the deck updates instantly, no restart needed
- **Privileged commands** — run whitelisted root/admin commands; Linux uses a root helper daemon, macOS uses the native admin auth dialog - **Privileged commands** — run whitelisted root/admin commands; Linux uses a root helper daemon, macOS uses the native admin auth dialog
- Automatic reconnect — survives USB unplug, KVM switches, and suspend/resume - Automatic reconnect — survives USB unplug, KVM switches, and suspend/resume
- Runs as a systemd user service (Linux) or launchd agent (macOS), starts automatically at login - Runs as a systemd user service (Linux) or launchd agent (macOS), starts automatically at login
- No Stream Deck app, no Node.js, no Electron - No Stream Deck app, no Node.js, no Electron
- **Modules** — define reusable, parameterised commands in `modules.yaml` with Go templates; secrets stay in env vars, config stays in dotfiles. First built-in example: Slack (status, presence, snooze). See [Modules](#modules). - **Modules** — define reusable, parameterised commands in `modules.yaml` with Go templates; secrets stay in env vars, config stays in dotfiles. Built-in examples: Slack (status, presence, snooze) and OBS Studio (recording, streaming, scene switching, media control). See [Modules](#modules).
- **Interactive config builder** — TUI tool (`streamdeck-init`) that walks you through key setup: pick a slot, pick a module/function, customize params, choose an icon. No YAML editing required. See [Config builder](#config-builder). - **Interactive config builder** — TUI tool (`streamdeck-init`) that walks you through key setup: pick a slot, pick a module/function, customize params, choose an icon. No YAML editing required. See [Config builder](#config-builder).
**Planned:** text/label overlays on keys, multi-page layouts, AUR package — see [Roadmap](#roadmap) **Planned:** text/label overlays on keys, multi-page layouts, AUR package — see [Roadmap](#roadmap)
@@ -669,6 +669,67 @@ modules:
A full example is included at [`modules.example.yaml`](modules.example.yaml) in the repo root. A full example is included at [`modules.example.yaml`](modules.example.yaml) in the repo root.
#### OBS Studio module
The example `modules.yaml` also includes an `obs` module that drives OBS over WebSocket using [`obs-cmd`](https://github.com/grigio/obs-cmd).
**Setup:**
1. Install `obs-cmd`:
- macOS: `brew install grigio/obs-cmd/obs-cmd`
- Linux: `cargo install obs-cmd` or download a release binary
2. Requires **OBS 30.2 or newer** — earlier versions fail `obs-cmd`'s version check.
3. In OBS, enable **Tools → WebSocket Server Settings** and note the port + password.
4. Export env vars (see [Secrets and tokens](#secrets-and-tokens) for launchd/systemd setup):
```bash
export OBS_WEBSOCKET_PASSWORD="your-password"
export OBS_HOST="localhost" # or remote IP, e.g. 192.168.1.28
export OBS_PORT="4455"
```
**Functions:**
| Function | Purpose | Params |
|---|---|---|
| `play` / `pause` / `stop` / `restart` | Media input controls | `source` (default `"Media Source"`) |
| `toggle_record` | Start/stop recording | — |
| `toggle_record_pause` | Pause/resume recording | — |
| `toggle_stream` | Start/stop streaming | — |
| `scene_switch` | Switch active scene | `scene` (default `"Scene 1"`) |
| `toggle_mute` | Toggle input mute | `source` (default `"Mic/Aux"`) |
| `is_recording` | Status check for poll blocks | — |
| `is_recording_paused` | Status check for poll blocks | — |
| `is_streaming` | Status check for poll blocks | — |
**Example — record button with flashing GIF when active:**
```yaml
keys:
7:
icon_true: recording.gif # animated — flashes while recording
icon_false: camera.png # static — shown when stopped
module: obs
function: toggle_record
poll:
module: obs
function: is_recording
match: "Active: true" # obs-cmd output contains this when recording
interval: 2s
15:
icon_true: pause.svg
icon_false: play.svg
module: obs
function: toggle_record_pause
poll:
module: obs
function: is_recording_paused
match: "Paused: true"
interval: 2s
```
**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.
#### Using modules in config.yaml #### Using modules in config.yaml
Reference a module function instead of writing inline commands: Reference a module function instead of writing inline commands:
@@ -741,6 +802,36 @@ keys:
match: "snooze_enabled.*true" match: "snooze_enabled.*true"
``` ```
#### Adding your own modules
Modules are purely YAML — no Go code changes required.
1. Open `~/.config/streamdeck-go/modules.yaml`.
2. Add a new top-level key under `modules:` (e.g. `home_assistant`, `spotify`).
3. Define functions, each with an `exec` template and optional default `params`. Use `{{env "VAR"}}` for secrets and `{{.paramName}}` for parameters.
4. Save — the daemon reloads automatically.
5. Reference the new module from `config.yaml` with `module:` / `function:` / `params:`.
**Skeleton:**
```yaml
modules:
my_api:
do_thing:
params:
target: "default-value"
exec: |
curl -s -X POST https://example.com/api/thing \
-H "Authorization: Bearer {{env "MY_API_TOKEN"}}" \
-d '{"target":"{{.target}}"}'
```
**Tips:**
- If the template calls an external binary (like `curl`, `obs-cmd`, `osascript`), use the absolute path — service `PATH` is minimal.
- Chain multiple API calls with `&&` inside a single `exec` (see `go_offline` in the example).
- Status functions for poll blocks should output text matching a substring you set in the key's `poll.match`.
#### Template helpers #### Template helpers
Two helpers are available in `exec` templates: Two helpers are available in `exec` templates: