Browse Source

Document zone-aware RGB commands

Paul Klumpp 2 weeks ago
parent
commit
1c34a2fda1
3 changed files with 226 additions and 67 deletions
  1. 48 25
      AGENTS.md
  2. 90 27
      PLAN.md
  3. 88 15
      README.md

+ 48 - 25
AGENTS.md

@@ -16,35 +16,58 @@ keyboards.json          # VID/PID database + keyboard metadata
 ## CLI Interface
 
 ```
-wobkey keyboard info              # Discover connected VIA-compatible keyboards
-wobkey rgb effect <name>          # Set RGB effect (e.g. "solid", "breathing", "wave")
-wobkey rgb brightness <val>       # Set brightness (0-255)
-wobkey rgb speed <val>            # Set effect speed (0-255)
-wobkey rgb color <hex>            # Set solid color (e.g. "ff0000")
-wobkey rgb mode <index>           # Set mode by index
-wobkey rgb enable                 # Enable RGB lighting
-wobkey rgb disable                # Disable RGB lighting
-wobkey rgb info                   # Show current RGB state
+wobkey keyboard info
+wobkey rgb effect breathing
+wobkey rgb effect rainbow_moving_chevron
+wobkey rgb effect rainbow_moving_chevron --zone backlight
+wobkey rgb brightness <val>       # 0-255
+wobkey rgb speed <val>            # 0-255
+wobkey rgb color <hex>            # Six hexadecimal digits
+wobkey rgb mode <index>           # Raw zone-specific effect ID
+wobkey rgb enable
+wobkey rgb disable
+wobkey rgb info
 ```
 
-### Set the Keyboard to Solid Red
-
-Treat a request such as "set the keyboard to red" as two ordered CLI operations, not one. From the repository root, run:
-
-```sh
-go run ./cmd/wobkey rgb effect solid && \
-  go run ./cmd/wobkey rgb color ff0000
+`rgb` has a persistent `--zone` flag accepting `logo`, `backlight`, or `side`.
+Without `--zone`, commands target Logo, Backlight, and Side in that order.
+With `--zone`, commands target exactly one zone. Unsupported default targets
+are skipped with a stderr warning; unsupported explicit-zone effects and
+unknown names fail before the device is opened.
+
+### Impact 80 Effect Families
+
+Logo and Side use IDs 0–6: `none`, `wave`, `fixed_wave`, `spectrum`,
+`breathing`, `light`, and `shutdown`.
+
+Backlight uses the complete ID 0–45 family:
+
+```text
+none, solid_color, alphas_mods, gradient_up_down, gradient_left_right,
+breathing, band_sat, band_val, band_pinwheel_sat, band_pinwheel_val,
+band_spiral_sat, band_spiral_val, cycle_all, cycle_left_right,
+cycle_up_down, cycle_out_in, cycle_out_in_dual, rainbow_moving_chevron,
+cycle_pinwheel, cycle_spiral, dual_beacon, rainbow_beacon,
+rainbow_pinwheels, flower_blooming, raindrops, jellybean_raindrops,
+hue_breathing, hue_pendulum, hue_wave, pixel_flow, digital_rain,
+solid_reactive, solid_reactive_wide, solid_reactive_multiwide,
+solid_reactive_cross, solid_reactive_multicross, solid_reactive_nexus,
+solid_reactive_multinexus, splash, multisplash, solid_splash,
+solid_multisplash, starlight, starlight_dual_hue, starlight_dual_sat,
+riverflow
 ```
 
-Agent rules:
-
-- Always set `effect solid` before setting the color.
-- Pass colors as exactly six hexadecimal digits without `#`; red is `ff0000`.
-- Run the color command only after the effect command succeeds, as ensured by `&&`.
-- Do not add `rgb enable`; the Impact 80 uses no separate enable handshake.
-- For another fixed color, keep the same order and replace `ff0000` with the desired RGB value.
+ID 39 is `multisplash`; ID 41 is `solid_multisplash`. Supported aliases are
+`off` → `none`, `breathe` → `breathing`, `rainbow` (zone-dependent),
+`rainbow_wave` (Logo/Side), `solid` (zone-dependent), and legacy `static`.
+Do not assume a numeric effect ID is valid on every zone; use the zone-aware
+name resolver or deliberately use `rgb mode` as a raw escape hatch.
 
-These commands apply the color to the Impact 80's backlight, logo, and side-light channels.
+`rgb info` emits a `zones` array containing each selected zone's channel,
+enabled state, effect name and ID, brightness, speed, and color. The
+top-level summary comes from the first selected zone. A failed zone includes
+an `error` field while other zone results remain available; the command
+prints JSON before returning non-zero.
 
 ## VIA Protocol Essentials
 
@@ -61,7 +84,7 @@ These commands apply the color to the Impact 80's backlight, logo, and side-ligh
 | Keyboard         | VID    | PID    |
 |------------------|--------|--------|
 | Wobkey Rainy 75  | 0x6666 | 0x0001 |
-| Wobkey Impact 80 | TBD    | TBD    |
+| Wobkey Impact 80 | 0x36B0 | 0x309F |
 
 `keyboards.json` maps VID+PID → VIA protocol config + RGB layout metadata.
 

+ 90 - 27
PLAN.md

@@ -3,45 +3,108 @@
 ## Status
 
 - ✅ Go module initialized (`github.com/wobkey/rgb`)
-- ✅ `git init` + AGENTS.md + README.md
-- ✅ Directory structure: `cmd/wobkey/`, `internal/device/`, `internal/hid/`, `internal/rgb/`, `internal/via/`
-- ✅ Pure-Go HID layer: reads `/dev/hidraw*`, `/sys/class/hidraw/*/report_descriptor`, and HID metadata (no cgo, no libudev)
-- ✅ Keyboard discovery: detects Impact 80 (VID `0x36B0`, PID `0x309F`) and Rainy 75
-- ✅ All 8 RGB subcommands implemented (effect, brightness, speed, color, mode, enable, disable, info)
-- ✅ `go build` ✅ `go vet` ✅ `go test ./...` ✅ `gofmt` clean
-- ✅ QMK v12 Raw HID protocol: custom set/get values with 32-byte reports and response validation
-- ✅ Impact 80 three-zone lighting control (logo, backlight, side)
-- ✅ `keyboards.json` with decimal VID/PID
+- ✅ HID discovery and QMK v12 Raw HID transport implemented
+- ✅ Impact 80 three-zone lighting control (Logo, Backlight, Side) implemented
+- ✅ Zone selection with default-all and explicit `--zone` behavior implemented
+- ✅ Zone-aware effect names, aliases, and target resolution implemented
+- ✅ Per-zone `rgb info` JSON implemented
+- ✅ All RGB subcommands implemented (effect, brightness, speed, color, mode, enable, disable, info)
+- ✅ Automated tests, vet, formatting, and build verification
+- ⚠️ Hardware smoke discovery succeeds, but the connected Impact 80 is blocked by root-only `/dev/hidraw7` permissions
 
-## Open Issues
+## Zone-Aware Lighting Semantics
 
-### 1. Impact 80 Effect Mapping
+The `rgb` command has a persistent `--zone` flag with the values `logo`,
+`backlight`, and `side`. Without the flag, commands target Logo, Backlight,
+and Side in that order. With the flag, commands target exactly one zone.
 
-The keyboard's official VIA definition uses model-specific effect IDs for its three lighting zones. The generic QMK effect list in `internal/rgb/effects.go` does not yet map names such as `rainbow` to those IDs.
+An unknown effect name fails before the device is opened. An effect that is
+unsupported by an explicitly selected zone also fails before the device is
+opened. For a default all-zone request, supported zones receive the command
+and unsupported zones are skipped with a warning on stderr.
 
-### 2. Cross-Platform HID Backends
+The exact effect examples are:
 
-The current transport is Linux-specific (`/dev/hidraw*` and Linux syscalls). macOS and Windows builds need platform-specific HID backends or a shared library.
+```bash
+wobkey rgb effect breathing
+wobkey rgb effect rainbow_moving_chevron
+wobkey rgb effect rainbow_moving_chevron --zone backlight
+wobkey rgb brightness 160
+wobkey rgb speed 2
+wobkey rgb color 00ff00
+```
 
-### 3. Documentation and Release Artifacts
+## Effect Families
 
-Keep protocol documentation, keyboard metadata, and generated graph outputs synchronized with the implementation.
+Logo and Side share the complete seven-name family:
 
-## Quick Commands for Next Session
+```text
+none, wave, fixed_wave, spectrum, breathing, light, shutdown
+```
 
-```bash
-# Rebuild with latest code
-go build -o /tmp/wobkey ./cmd/wobkey/
+Backlight uses these complete 46 names, with IDs 0–45:
 
-# Discover the QMK Raw HID interface
-/tmp/wobkey keyboard info
+```text
+none, solid_color, alphas_mods, gradient_up_down, gradient_left_right,
+breathing, band_sat, band_val, band_pinwheel_sat, band_pinwheel_val,
+band_spiral_sat, band_spiral_val, cycle_all, cycle_left_right,
+cycle_up_down, cycle_out_in, cycle_out_in_dual, rainbow_moving_chevron,
+cycle_pinwheel, cycle_spiral, dual_beacon, rainbow_beacon,
+rainbow_pinwheels, flower_blooming, raindrops, jellybean_raindrops,
+hue_breathing, hue_pendulum, hue_wave, pixel_flow, digital_rain,
+solid_reactive, solid_reactive_wide, solid_reactive_multiwide,
+solid_reactive_cross, solid_reactive_multicross, solid_reactive_nexus,
+solid_reactive_multinexus, splash, multisplash, solid_splash,
+solid_multisplash, starlight, starlight_dual_hue, starlight_dual_sat,
+riverflow
+```
 
-# Test RGB state
-/tmp/wobkey rgb disable
-/tmp/wobkey rgb info
+Backlight ID 39 is `multisplash`; ID 41 is the distinct
+`solid_multisplash` name. Compatibility aliases are `off`, `breathe`,
+`rainbow`, `rainbow_wave`, `solid`, and the legacy `static` alias; aliases
+resolve independently for each zone.
+
+## Verification
 
-# Run all checks
+Run the complete automated check set from the repository root:
+
+```bash
 gofmt -w .
+go test -count=1 ./...
 go vet ./...
-go test ./...
+go build -o /tmp/wobkey ./cmd/wobkey/
+git diff --check
 ```
+
+Run the hardware smoke sequence when the Impact 80 is available:
+
+```bash
+/tmp/wobkey keyboard info
+/tmp/wobkey rgb effect breathing
+/tmp/wobkey rgb effect rainbow_moving_chevron
+/tmp/wobkey rgb effect rainbow_moving_chevron --zone backlight
+/tmp/wobkey rgb info
+/tmp/wobkey rgb color 00ff00
+/tmp/wobkey rgb disable
+/tmp/wobkey rgb enable
+```
+
+The expected result is three selected zones, warnings only for unsupported
+default targets, a working explicit Backlight command, per-zone JSON from
+`rgb info`, and a final enabled state. Record device or permission failures
+without changing unrelated code.
+
+## Open Issues
+
+### Cross-Platform HID Backends
+
+The current transport is Linux-specific (`/dev/hidraw*` and Linux syscalls).
+macOS and Windows require platform-specific HID backends or a shared library.
+
+### Hardware Environment
+
+Hardware smoke tests require the Impact 80 to be connected and the user to
+have permission to access its hidraw device. In the acceptance environment,
+`/dev/hidraw7` is `root:root` with mode `600`, so discovery succeeds but all
+HID opens fail with `permission denied`. No persistent profile storage or
+EEPROM save command is included.

+ 88 - 15
README.md

@@ -22,23 +22,95 @@ go install ./cmd/wobkey/
 # Discover connected keyboards
 ./wobkey keyboard info
 
-# RGB commands
+# RGB commands target Logo, Backlight, and Side by default
+./wobkey rgb effect breathing
+./wobkey rgb effect rainbow_moving_chevron
+./wobkey rgb effect rainbow_moving_chevron --zone backlight
+./wobkey rgb brightness 160
+./wobkey rgb speed 2
+./wobkey rgb color 00ff00
+./wobkey rgb mode 17
 ./wobkey rgb enable
 ./wobkey rgb disable
 ./wobkey rgb info
-./wobkey rgb effect rainbow
-./wobkey rgb effect breathing
-./wobkey rgb brightness 128
-./wobkey rgb speed 100
-./wobkey rgb color ff0000
-./wobkey rgb mode 7
+
+# Select exactly one zone
+./wobkey rgb brightness 160 --zone side
 
 # Specify a target device (when multiple are connected)
 ./wobkey rgb --device /dev/hidraw0 enable
 ```
 
+`--zone` is persistent on `rgb` and accepts `logo`, `backlight`, or `side`.
+Without `--zone`, commands target Logo, Backlight, and Side in that order.
+With `--zone`, commands target exactly the selected zone. An unsupported
+name for an explicit zone fails before the device is opened; a default
+command skips unsupported zones and prints a warning on stderr.
+
 All output is machine-parseable JSON when applicable.
 
+## Impact 80 Zones and Effects
+
+| Zone | CLI name | VIA channel | Effect IDs |
+|---|---|---:|---|
+| Logo | `logo` | 2 | 0–6 |
+| Backlight | `backlight` | 3 | 0–45 |
+| Side | `side` | 4 | 0–6 |
+
+Logo and Side share this complete effect family:
+
+| ID | Name |
+|---:|---|
+| 0 | `none` |
+| 1 | `wave` |
+| 2 | `fixed_wave` |
+| 3 | `spectrum` |
+| 4 | `breathing` |
+| 5 | `light` |
+| 6 | `shutdown` |
+
+Backlight uses the complete Impact 80 catalog:
+
+| ID | Name | ID | Name |
+|---:|---|---:|---|
+| 0 | `none` | 23 | `flower_blooming` |
+| 1 | `solid_color` | 24 | `raindrops` |
+| 2 | `alphas_mods` | 25 | `jellybean_raindrops` |
+| 3 | `gradient_up_down` | 26 | `hue_breathing` |
+| 4 | `gradient_left_right` | 27 | `hue_pendulum` |
+| 5 | `breathing` | 28 | `hue_wave` |
+| 6 | `band_sat` | 29 | `pixel_flow` |
+| 7 | `band_val` | 30 | `digital_rain` |
+| 8 | `band_pinwheel_sat` | 31 | `solid_reactive` |
+| 9 | `band_pinwheel_val` | 32 | `solid_reactive_wide` |
+| 10 | `band_spiral_sat` | 33 | `solid_reactive_multiwide` |
+| 11 | `band_spiral_val` | 34 | `solid_reactive_cross` |
+| 12 | `cycle_all` | 35 | `solid_reactive_multicross` |
+| 13 | `cycle_left_right` | 36 | `solid_reactive_nexus` |
+| 14 | `cycle_up_down` | 37 | `solid_reactive_multinexus` |
+| 15 | `cycle_out_in` | 38 | `splash` |
+| 16 | `cycle_out_in_dual` | 39 | `multisplash` |
+| 17 | `rainbow_moving_chevron` | 40 | `solid_splash` |
+| 18 | `cycle_pinwheel` | 41 | `solid_multisplash` |
+| 19 | `cycle_spiral` | 42 | `starlight` |
+| 20 | `dual_beacon` | 43 | `starlight_dual_hue` |
+| 21 | `rainbow_beacon` | 44 | `starlight_dual_sat` |
+| 22 | `rainbow_pinwheels` | 45 | `riverflow` |
+
+ID 39 is `multisplash`; ID 41 is the distinct `solid_multisplash` name.
+Effect names are resolved independently for each target zone. Compatibility
+aliases are `off` → `none`, `breathe` → `breathing`, `rainbow` → `spectrum`
+for Logo/Side and `rainbow_moving_chevron` for Backlight, `rainbow_wave` →
+`wave` for Logo/Side, and `solid` → `light` for Logo/Side and `solid_color`
+for Backlight. The legacy `static` alias remains accepted as a compatibility
+alias for `solid`.
+
+`rgb info` reports a `zones` array with each zone's channel, enabled state,
+effect name and ID, brightness, speed, and color. The top-level `enabled`,
+`mode`, `brightness`, and `speed` fields summarize the first selected zone.
+If one zone cannot be queried, its record contains an `error`, other records
+are retained, and the process exits non-zero after printing the JSON.
+
 ## Linux HID Device Permissions
 
 The tool accesses keyboards via `/dev/hidraw*` which requires root permissions by default. To run without `sudo`, choose one of the methods below.
@@ -85,14 +157,15 @@ New keyboards can be added to `keyboards.json`.
 | Command                         | Description                              |
 |---------------------------------|------------------------------------------|
 | `wobkey keyboard info`          | Discover connected VIA-compatible keyboards |
-| `wobkey rgb enable`             | Enable RGB lighting                      |
-| `wobkey rgb disable`            | Disable RGB lighting                     |
-| `wobkey rgb info`               | Show current RGB state (JSON)            |
-| `wobkey rgb effect <name>`      | Set effect (static, breathing, rainbow…) |
-| `wobkey rgb brightness <val>`   | Set brightness (0–255)                   |
-| `wobkey rgb speed <val>`        | Set effect speed (0–255)                 |
-| `wobkey rgb color <hex>`        | Set solid color (e.g. `ff0000`)          |
-| `wobkey rgb mode <index>`       | Set mode by numeric index                |
+| `wobkey rgb enable`             | Enable selected lighting zones           |
+| `wobkey rgb disable`            | Disable selected lighting zones          |
+| `wobkey rgb info`               | Show per-zone RGB state (JSON)            |
+| `wobkey rgb effect <name>`      | Set a zone-aware effect by name           |
+| `wobkey rgb brightness <val>`   | Set brightness (0–255) on selected zones |
+| `wobkey rgb speed <val>`        | Set effect speed (0–255) on selected zones |
+| `wobkey rgb color <hex>`        | Set color (e.g. `ff0000`) on selected zones |
+| `wobkey rgb mode <index>`       | Set a raw zone-specific effect ID        |
+| `wobkey rgb --zone <zone> ...`  | Target `logo`, `backlight`, or `side`     |
 
 ## Architecture