2026-09-25-impact80-effects-design.md 6.8 KB

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:

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:

{
  "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.