Created
April 5, 2017 22:04
-
-
Save rigaspapas/6186144eec9c8f7c625a462ae2bfcead to your computer and use it in GitHub Desktop.
A color rain effect for Corsair RGB keyboards
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from cue_sdk import CUESDK, CAM, CLK, CorsairLedColor | |
import os | |
from random import choice | |
import time | |
# The directory where CUESDK is located | |
SDK_DIR = "D:\\Portable Apps\\CUEAudioVisualizer\\x86" | |
# The filename of the SDK dll file | |
SDK_DLL = "CUESDK_2015.dll" | |
# How much each animation will last (in 1/100 seconds) | |
DURATION = 150 | |
# How often a new key will be added (in 1/100 seconds) | |
ADD_KEY_INTERVAL = 20 | |
# Currently active keys - do not change | |
ACTIVE_KEYS = 0 | |
# Maximum active keys allowed | |
MAX_ACTIVE_KEYS = 20 | |
KEYS = [ | |
'A', 'ApostropheAndDoubleQuote', 'Application', 'B', 'Backslash', | |
'Backspace', 'BracketLeft', 'BracketRight', 'Brightness', 'C', | |
'CLH_LeftLogo', 'CLH_RightLogo', 'CLI_Invalid', 'CLM_1', 'CLM_2', 'CLM_3', | |
'CLM_4', 'CapsLock', 'CommaAndLessThan', 'D', 'Delete', 'DownArrow', 'E', | |
'End', 'Enter', 'EqualsAndPlus', 'Escape', 'F', 'F1', 'F10', 'F11', 'F12', | |
'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'Fn', 'G', 'G1', 'G10', | |
'G11', 'G12', 'G13', 'G14', 'G15', 'G16', 'G17', 'G18', 'G2', 'G3', 'G4', | |
'G5', 'G6', 'G7', 'G8', 'G9', 'GraveAccentAndTilde', 'H', 'Home', 'I', | |
'Insert', 'International1', 'International2', 'International3', | |
'International4', 'International5', 'J', 'K', 'Keypad0', 'Keypad1', | |
'Keypad2', 'Keypad3', 'Keypad4', 'Keypad5', 'Keypad6', 'Keypad7', | |
'Keypad8', 'Keypad9', 'KeypadAsterisk', 'KeypadComma', 'KeypadEnter', | |
'KeypadMinus', 'KeypadPeriodAndDelete', 'KeypadPlus', 'KeypadSlash', 'L', | |
'Lang1', 'Lang2', 'LedProgramming', 'LeftAlt', 'LeftArrow', 'LeftCtrl', | |
'LeftGui', 'LeftShift', 'Logo', 'M', 'M1', 'M2', 'M3', 'MR', | |
'MinusAndUnderscore', 'Mute', 'N', 'NonUsBackslash', 'NonUsTilde', | |
'NumLock', 'O', 'P', 'PageDown', 'PageUp', 'PauseBreak', | |
'PeriodAndBiggerThan', 'PlayPause', 'PrintScreen', 'Q', 'R', 'RightAlt', | |
'RightArrow', 'RightCtrl', 'RightGui', 'RightShift', 'S', 'ScanNextTrack', | |
'ScanPreviousTrack', 'ScrollLock', 'SemicolonAndColon', | |
'SlashAndQuestionMark', 'Space', 'Stop', 'T', 'Tab', 'U', 'UpArrow', 'V', | |
'VolumeDown', 'VolumeUp', 'W', 'WinLock', 'X', 'Y', 'Z', '_0', '_1', '_2', | |
'_3', '_4', '_5', '_6', '_7', '_8', '_9'] | |
# Comment out the colors you don't want or add new ones | |
COLORS = [ | |
# [255, 255, 255], # WHITE | |
[0, 172, 255], # BLUE | |
[255, 0, 65], # RED | |
[41, 255, 0], # GREEN | |
[255, 144, 0], # ORANGE | |
[0, 255, 137], # MINT | |
[220, 255, 0], # YELLOW | |
[174, 0, 255], # PURPLE | |
] | |
class ColorRain(object): | |
"""Let it rain with colors.""" | |
# The play queue | |
queue = [] | |
# The KEYS statuses | |
status = {} | |
Corsair = None | |
def play(self): | |
"""Play the next step of the animation.""" | |
frame = self.queue[0] | |
for effect in frame: | |
(key, red, green, blue) = (effect[0], effect[1], effect[2], | |
effect[3]) | |
self.Corsair.set_led_colors(CorsairLedColor(getattr(CLK, | |
KEYS[key]), | |
red, green, blue)) | |
self.status[KEYS[key]] += 1 | |
if self.status[KEYS[key]] >= 2 * DURATION: | |
self.status[KEYS[key]] = 0 | |
global ACTIVE_KEYS | |
ACTIVE_KEYS -= 1 | |
self.Corsair.set_led_colors(CorsairLedColor(getattr(CLK, | |
KEYS[key]), | |
0, 0, 0)) | |
self.queue = self.queue[1:] + [[]] | |
def add_effect(self): | |
"""Add an extra key animation to the effects queue.""" | |
global ACTIVE_KEYS, MAX_ACTIVE_KEYS | |
if ACTIVE_KEYS >= MAX_ACTIVE_KEYS: | |
return | |
ACTIVE_KEYS += 1 | |
# Choose a random key | |
key = choice(range(len(KEYS))) | |
while self.status[KEYS[key]] > 0: | |
key = choice(range(len(KEYS))) | |
color = choice(range(len(COLORS))) | |
color = COLORS[color] | |
for intensity in xrange(1, DURATION + 1): | |
r = int(intensity * color[0] / DURATION) | |
g = int(intensity * color[1] / DURATION) | |
b = int(intensity * color[2] / DURATION) | |
self.queue[intensity - 1].append([key, r, g, b]) | |
for intensity in xrange(DURATION, 0, -1): | |
r = int(intensity * color[0] / DURATION) | |
g = int(intensity * color[1] / DURATION) | |
b = int(intensity * color[2] / DURATION) | |
self.queue[2 * DURATION - intensity].append([key, r, g, b]) | |
def start(self): | |
os.chdir(SDK_DIR) | |
self.Corsair = CUESDK(SDK_DLL) | |
# Start the animation | |
if self.Corsair.RequestControl(CAM.ExclusiveLightingControl): | |
# Initialize it with empty actions | |
for step in xrange(DURATION * 2): | |
self.queue.append([]) | |
for key in KEYS: | |
self.status[key] = 0 | |
# Start playing | |
count = 0 | |
while True: | |
if count % ADD_KEY_INTERVAL == 0: | |
self.add_effect() | |
count = 1 | |
self.play() | |
time.sleep(.01) | |
count += 1 | |
if __name__ == '__main__': | |
effect = ColorRain() | |
effect.start() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment