Skip to content

Add vrgb cycle command for software rainbow cycling - #8

Open
MHS-20 wants to merge 1 commit into
vrgb-dev:mainfrom
MHS-20:add-cycle-command
Open

Add vrgb cycle command for software rainbow cycling#8
MHS-20 wants to merge 1 commit into
vrgb-dev:mainfrom
MHS-20:add-cycle-command

Conversation

@MHS-20

@MHS-20 MHS-20 commented Sep 6, 2026

Copy link
Copy Markdown

Summary

  • Adds a vrgb cycle [percent] [period_seconds] [fps] command that smoothly sweeps the full color spectrum via the existing HID color path (set_color/set_firmware_mode), with adjustable brightness, cycle duration, and frame rate.
  • Unlike rainbow, this works on every currently supported device — it doesn't depend on OEM firmware rainbow support (rainbow_supported: False devices, e.g. the 0x5570 mapping, are unaffected) — and doesn't require sudo, since it stays entirely on the HID color path set/brightness already use.
  • The loop recovers from OSError if the hidraw node briefly disappears or re-enumerates (observed around suspend/resume), instead of crashing and leaving the keyboard stuck on whatever color it was mid-cycle.
  • Related to Hardware Compatibility Reports #1 — posted a hardware confirmation comment there.

Why

I wanted a smooth, speed-adjustable rainbow effect and ran a standalone script driving the hidraw device directly to prototype it. That worked, but died the first time the laptop suspended (unhandled OSError when the hidraw node vanished/re-enumerated around the suspend transition — confirmed via journalctl, the process had run cleanly for over an hour before dying exactly when omarchy-sleep-lock.service fired). Folding the fixed version into vrgb itself as cycle, reusing the project's own find_device/set_color/set_firmware_mode, seemed more useful than keeping it as an out-of-tree script, and it directly follows from the rainbow/auto commands already in the file.

Implementation notes

  • No new dependencies — only stdlib (time, colorsys) added to the existing imports.
  • Follows the file's existing conventions: manual sys.argv parsing (no argparse) with optional trailing positional args, same pattern as cmd_set(cfg, devinfo, color, percent=None); die() for user-facing errors; debug() tracing hooks throughout.
  • Deliberately does not write to the persistent config (save_config) while cycling, since the color is constantly changing and there's no single "current color" worth persisting — this mirrors how off/restore treat state, but a continuously-running effect doesn't fit that model.
  • Runs in the foreground until Ctrl+C (KeyboardInterrupt caught, prints "Stopped cycling." and exits 0); for continuous background operation the README's new section for this command points at a process supervisor (e.g. a systemd --user service — see the separate PR for a related vrgb-restore.service example).
  • README updated: Features list, new Command List entry with a worked example, and a short note on the recovery behavior and how it differs from rainbow.

System tested on

  • Laptop: ASUS Vivobook S14 (S5406SA)
  • HID device: ITE5570:00 0B05:19B6, HID_ID=0018:00000B05:000019B6 (the primary mapping in SUPPORTED_DEVICES)
  • Kernel: Linux 7.2.3-arch1-2 (x86_64, #1 SMP PREEMPT_DYNAMIC)
  • Distro: Omarchy (Arch-based), version 4.0.0.r2015.g4930677
  • Desktop: Hyprland (Wayland), via Omarchy's systemd --user session management (uwsm)
  • Python: 3.14.7 (via mise-managed interpreter, not the system Python — confirms no reliance on system-Python-only stdlib behavior)
  • asus-nb-wmi kernel module loaded (required for this device per the existing required_modules mapping)

Testing performed

All tests run directly against the modified vrgb.py (invoked as python3 vrgb.py ... from a working copy, group-permissioned via the existing vrgb udev rule/group from a prior install):

  • python3 -m py_compile vrgb.py — clean compile, no syntax errors.
  • Default invocationvrgb cycle with no arguments: uses cfg["percent"], 6s period, 20 fps defaults; observed smooth color sweep on the physical keyboard.
  • Explicit argumentsvrgb cycle 100 2 (fast 2s period) and vrgb cycle 50 3 10 (custom brightness/period/fps): correct clamping and frame timing confirmed via --debug output (hid_set_feature calls showing the expected RGB progression, e.g. 255,7,0255,33,0 → … around the hue wheel).
  • --debug modepython3 vrgb.py --debug cycle 50 3 10: confirmed device selection log (exact HID_ID match), report IDs (firmware=0x0B color=0x05), and per-frame hid_set_feature/set_color traces.
  • Graceful stop (Ctrl+C / SIGINT) — verified via timeout --signal=INT --preserve-status: process exits 0 and prints Stopped cycling.; also verified interactively with a backgrounded process and kill -INT.
  • Input validation:
    • vrgb cycle 100 0Error: period must be greater than 0 (exit 1)
    • vrgb cycle 100 abcError: period and fps must be numbers (exit 1)
    • vrgb cycle 150 → percent silently clamped to 100 via existing clamp() helper, no crash
  • Live suspend/resume recovery — started vrgb cycle in the background (--debug, logging to file), confirmed continuous hid_set_feature writes, then physically suspended and resumed the laptop (systemctl suspend equivalent via lid/power). Process (checked via pgrep) survived and kept writing colors afterward — this is the scenario that crashed the earlier unpatched prototype, and it did not crash here.
  • Manual end-user validation — ran the equivalent standalone logic (later folded into this PR) as my actual daily keyboard lighting for several days, including one full suspend/resume cycle confirmed live during this session, and a subsequent unrelated systemd-service hiccup (service manually stopped for testing, not a cycle/recovery bug) that was diagnosed and resolved separately.

Not tested: the 0018:00000B05:00005570 (0x5570) device mapping — I don't have that hardware. The cycle command doesn't touch any device-specific behavior beyond the existing firmware_report_id/color_report_id fields already used by set/brightness/auto, which are exercised identically regardless of mapping, so I'd expect it to work there too, but can't confirm firsthand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant