浏览代码

Document zone-aware Impact 80 effects design

Paul Klumpp 2 周之前
父节点
当前提交
d64a93c803
共有 1 个文件被更改,包括 170 次插入 和 0 次删除
  1. 170 0
      docs/superpowers/specs/2026-09-25-impact80-effects-design.md

+ 170 - 0
docs/superpowers/specs/2026-09-25-impact80-effects-design.md

@@ -0,0 +1,170 @@
+# Impact 80 Zone-Aware Lighting Effects Design
+
+## Status
+
+Approved design for implementing the complete Impact 80 VIA lighting catalog in the CLI.
+
+## Goals
+
+- Expose every effect documented by the Impact 80 VIA definition.
+- Apply RGB commands to Logo, Backlight, and Side lighting by default.
+- Allow `--zone logo`, `--zone backlight`, or `--zone side` to target one zone.
+- Keep effect IDs channel-specific and prevent generic QMK IDs from being sent to the wrong zone.
+- Preserve machine-readable output and existing top-level `rgb info` fields.
+
+## Non-goals
+
+- No EEPROM save command or persistent profile storage.
+- No macOS or Windows HID backend.
+- No completion of an independent Rainy 75 effect catalog.
+- No changes to the QMK v12 Raw HID transport.
+
+## Zone model
+
+The Impact 80 has three VIA lighting channels:
+
+| Zone | CLI name | VIA channel | Effect catalog |
+|---|---|---:|---|
+| Logo | `logo` | 2 | 7 effects |
+| Backlight | `backlight` | 3 | 46 effects including `none` |
+| Side | `side` | 4 | 7 effects |
+
+The `--zone` flag is persistent on the `rgb` command. If omitted, commands target all three zones in this order: Logo, Backlight, Side.
+
+## Effect catalog
+
+The canonical effect table is zone-aware. Logo and Side use:
+
+| ID | Name |
+|---:|---|
+| 0 | `none` |
+| 1 | `wave` |
+| 2 | `fixed_wave` |
+| 3 | `spectrum` |
+| 4 | `breathing` |
+| 5 | `light` |
+| 6 | `shutdown` |
+
+Backlight uses the complete official 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` |
+
+The Backlight catalog follows the QMK RGB Matrix effect names. ID 41 is exposed as `solid_multisplash`, distinct from `multisplash` at ID 39.
+
+## Name resolution
+
+`rgb effect <name>` resolves a canonical name or alias independently for each target zone.
+
+Supported compatibility aliases:
+
+- `off` → `none`
+- `breathe` → `breathing`
+- `rainbow_wave` → `wave` for Logo/Side
+- `rainbow` → `spectrum` for Logo/Side and `rainbow_moving_chevron` for Backlight
+- `solid` → `light` for Logo/Side and `solid_color` for Backlight
+
+If no `--zone` is supplied and an effect is unsupported by one or more zones, the supported zones receive the command and a warning names every skipped zone. If `--zone` is supplied and the effect is unsupported there, the command fails without sending a report.
+
+Unknown effect names fail before opening the device.
+
+## CLI behavior
+
+All zone-aware commands use the same target resolver:
+
+```text
+wobkey rgb effect breathing
+wobkey rgb effect rainbow_moving_chevron
+wobkey rgb effect rainbow_moving_chevron --zone backlight
+wobkey rgb brightness 160
+wobkey rgb brightness 160 --zone logo
+wobkey rgb color 00ff00
+wobkey rgb speed 2 --zone side
+wobkey rgb disable
+wobkey rgb enable
+```
+
+- `effect`: sends the zone-specific Effect value (`0x02`).
+- `brightness`: sends Brightness (`0x01`) to selected zones.
+- `speed`: sends Effect Speed (`0x03`) to selected zones.
+- `color`: sends Color (`0x04`) to selected zones.
+- `disable`: sends Effect `0` and Brightness `0` to selected zones.
+- `enable`: enables each selected zone with its default breathing effect: Logo `4`, Backlight `5`, Side `4`, then Brightness `160`.
+- `mode <index>` remains a raw numeric escape hatch and applies the supplied ID to selected zones; names are preferred because IDs differ by zone.
+
+## Info output
+
+`rgb info` queries all selected zones and emits a `zones` array. Each entry contains:
+
+```json
+{
+  "zone": "logo",
+  "channel": 2,
+  "enabled": true,
+  "effect": "breathing",
+  "effectId": 4,
+  "brightness": 160,
+  "speed": 2,
+  "color": {"hue": 0, "saturation": 255}
+}
+```
+
+The existing top-level `enabled`, `mode`, `brightness`, and `speed` fields remain as a compatibility summary of the first selected zone (Logo when no zone is specified). If a zone cannot be queried, its entry contains an `error` string and the process exits non-zero after preserving the other zone results in JSON.
+
+## Component boundaries
+
+- `internal/rgb`: zone names, canonical effect definitions, aliases, and zone-specific value lookup.
+- `internal/via`: Raw HID transport and channel/value writes; no CLI policy or effect names.
+- `cmd/wobkey/rgb`: Cobra flag parsing, target-zone selection, warnings, JSON presentation, and exit status.
+- `keyboards.json`: remains device identity/configuration metadata; effect definitions are code-owned because they are protocol semantics, not user preferences.
+
+## Error handling
+
+- Invalid `--zone`, unknown effect names, and unsupported explicit-zone effects return errors before any HID write.
+- Read timeouts remain bounded by the existing 500 ms hidraw timeout.
+- Set acknowledgements are validated for command, channel, and value ID.
+- Default-target warnings go to stderr; machine-readable stdout remains valid JSON for `info`.
+
+## Testing strategy
+
+Implementation follows TDD:
+
+1. Table-driven tests for every canonical Backlight effect and the Logo/Side catalog.
+2. Alias resolution tests for all supported aliases and zone-specific aliases.
+3. Target resolver tests for default-all, explicit-zone, invalid-zone, and unsupported-effect behavior.
+4. Fake-transport tests asserting one 32-byte report per selected zone and the correct channel/value.
+5. CLI tests for inherited `--zone` and warning/error behavior.
+6. Full `go test ./...`, `go vet ./...`, `gofmt`, and `go build` verification.
+7. Hardware smoke tests on the connected Impact 80: discovery, `effect`, `info`, `color`, `disable`, and `enable`.
+
+## Acceptance criteria
+
+- Every official Impact 80 effect name can be selected.
+- A command without `--zone` reaches all compatible zones.
+- A command with `--zone` reaches exactly one zone.
+- Unsupported effects never produce a wrong-zone report.
+- `rgb info` reports all selected zones and retains the compatibility summary.
+- Existing hardware smoke tests continue to pass.