split rgb to library
This commit is contained in:
parent
d43c712301
commit
63060b6f10
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,7 +14,6 @@ dist/
|
|||||||
downloads/
|
downloads/
|
||||||
eggs/
|
eggs/
|
||||||
.eggs/
|
.eggs/
|
||||||
lib/
|
|
||||||
lib64/
|
lib64/
|
||||||
parts/
|
parts/
|
||||||
sdist/
|
sdist/
|
||||||
|
|||||||
@ -6,6 +6,8 @@ from math import e, exp, pi, sin
|
|||||||
from kmk.extensions import Extension
|
from kmk.extensions import Extension
|
||||||
from kmk.handlers.stock import passthrough as handler_passthrough
|
from kmk.handlers.stock import passthrough as handler_passthrough
|
||||||
from kmk.keys import make_key
|
from kmk.keys import make_key
|
||||||
|
from kmk.kmktime import ticks_ms
|
||||||
|
from kmk.lib import rgb_helper
|
||||||
|
|
||||||
rgb_config = {}
|
rgb_config = {}
|
||||||
|
|
||||||
@ -169,404 +171,29 @@ class RGB(Extension):
|
|||||||
def on_powersave_disable(self, sandbox):
|
def on_powersave_disable(self, sandbox):
|
||||||
self._do_update()
|
self._do_update()
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def time_ms():
|
|
||||||
return int(time.monotonic() * 1000)
|
|
||||||
|
|
||||||
def hsv_to_rgb(self, hue, sat, val):
|
|
||||||
'''
|
|
||||||
Converts HSV values, and returns a tuple of RGB values
|
|
||||||
:param hue:
|
|
||||||
:param sat:
|
|
||||||
:param val:
|
|
||||||
:return: (r, g, b)
|
|
||||||
'''
|
|
||||||
r = 0
|
|
||||||
g = 0
|
|
||||||
b = 0
|
|
||||||
|
|
||||||
if val > self.val_limit:
|
|
||||||
val = self.val_limit
|
|
||||||
|
|
||||||
if sat == 0:
|
|
||||||
r = val
|
|
||||||
g = val
|
|
||||||
b = val
|
|
||||||
|
|
||||||
else:
|
|
||||||
base = ((100 - sat) * val) / 100
|
|
||||||
color = (val - base) * ((hue % 60) / 60)
|
|
||||||
|
|
||||||
x = int(hue / 60)
|
|
||||||
if x == 0:
|
|
||||||
r = val
|
|
||||||
g = base + color
|
|
||||||
b = base
|
|
||||||
elif x == 1:
|
|
||||||
r = val - color
|
|
||||||
g = val
|
|
||||||
b = base
|
|
||||||
elif x == 2:
|
|
||||||
r = base
|
|
||||||
g = val
|
|
||||||
b = base + color
|
|
||||||
elif x == 3:
|
|
||||||
r = base
|
|
||||||
g = val - color
|
|
||||||
b = val
|
|
||||||
elif x == 4:
|
|
||||||
r = base + color
|
|
||||||
g = base
|
|
||||||
b = val
|
|
||||||
elif x == 5:
|
|
||||||
r = val
|
|
||||||
g = base
|
|
||||||
b = val - color
|
|
||||||
|
|
||||||
return int(r), int(g), int(b)
|
|
||||||
|
|
||||||
def hsv_to_rgbw(self, hue, sat, val):
|
|
||||||
'''
|
|
||||||
Converts HSV values, and returns a tuple of RGBW values
|
|
||||||
:param hue:
|
|
||||||
:param sat:
|
|
||||||
:param val:
|
|
||||||
:return: (r, g, b, w)
|
|
||||||
'''
|
|
||||||
rgb = self.hsv_to_rgb(hue, sat, val)
|
|
||||||
return rgb[0], rgb[1], rgb[2], min(rgb)
|
|
||||||
|
|
||||||
def set_hsv(self, hue, sat, val, index):
|
|
||||||
'''
|
|
||||||
Takes HSV values and displays it on a single LED/Neopixel
|
|
||||||
:param hue:
|
|
||||||
:param sat:
|
|
||||||
:param val:
|
|
||||||
:param index: Index of LED/Pixel
|
|
||||||
'''
|
|
||||||
if self.neopixel:
|
|
||||||
if self.rgbw:
|
|
||||||
self.set_rgb(self.hsv_to_rgbw(hue, sat, val), index)
|
|
||||||
else:
|
|
||||||
self.set_rgb(self.hsv_to_rgb(hue, sat, val), index)
|
|
||||||
|
|
||||||
def set_hsv_fill(self, hue, sat, val):
|
|
||||||
'''
|
|
||||||
Takes HSV values and displays it on all LEDs/Neopixels
|
|
||||||
:param hue:
|
|
||||||
:param sat:
|
|
||||||
:param val:
|
|
||||||
'''
|
|
||||||
if self.neopixel:
|
|
||||||
if self.rgbw:
|
|
||||||
self.set_rgb_fill(self.hsv_to_rgbw(hue, sat, val))
|
|
||||||
else:
|
|
||||||
self.set_rgb_fill(self.hsv_to_rgb(hue, sat, val))
|
|
||||||
|
|
||||||
def set_rgb(self, rgb, index):
|
|
||||||
'''
|
|
||||||
Takes an RGB or RGBW and displays it on a single LED/Neopixel
|
|
||||||
:param rgb: RGB or RGBW
|
|
||||||
:param index: Index of LED/Pixel
|
|
||||||
'''
|
|
||||||
if self.neopixel and 0 <= index <= self.num_pixels - 1:
|
|
||||||
self.neopixel[index] = rgb
|
|
||||||
if not self.disable_auto_write:
|
|
||||||
self.neopixel.show()
|
|
||||||
|
|
||||||
def set_rgb_fill(self, rgb):
|
|
||||||
'''
|
|
||||||
Takes an RGB or RGBW and displays it on all LEDs/Neopixels
|
|
||||||
:param rgb: RGB or RGBW
|
|
||||||
'''
|
|
||||||
if self.neopixel:
|
|
||||||
self.neopixel.fill(rgb)
|
|
||||||
if not self.disable_auto_write:
|
|
||||||
self.neopixel.show()
|
|
||||||
|
|
||||||
def increase_hue(self, step=None):
|
|
||||||
'''
|
|
||||||
Increases hue by step amount rolling at 360 and returning to 0
|
|
||||||
:param step:
|
|
||||||
'''
|
|
||||||
if not step:
|
|
||||||
step = self.hue_step
|
|
||||||
|
|
||||||
self.hue = (self.hue + step) % 360
|
|
||||||
|
|
||||||
if self._check_update():
|
|
||||||
self._do_update()
|
|
||||||
|
|
||||||
def decrease_hue(self, step=None):
|
|
||||||
'''
|
|
||||||
Decreases hue by step amount rolling at 0 and returning to 360
|
|
||||||
:param step:
|
|
||||||
'''
|
|
||||||
if not step:
|
|
||||||
step = self.hue_step
|
|
||||||
|
|
||||||
if (self.hue - step) <= 0:
|
|
||||||
self.hue = (self.hue + 360 - step) % 360
|
|
||||||
else:
|
|
||||||
self.hue = (self.hue - step) % 360
|
|
||||||
|
|
||||||
if self._check_update():
|
|
||||||
self._do_update()
|
|
||||||
|
|
||||||
def increase_sat(self, step=None):
|
|
||||||
'''
|
|
||||||
Increases saturation by step amount stopping at 100
|
|
||||||
:param step:
|
|
||||||
'''
|
|
||||||
if not step:
|
|
||||||
step = self.sat_step
|
|
||||||
|
|
||||||
if self.sat + step >= 100:
|
|
||||||
self.sat = 100
|
|
||||||
else:
|
|
||||||
self.sat += step
|
|
||||||
|
|
||||||
if self._check_update():
|
|
||||||
self._do_update()
|
|
||||||
|
|
||||||
def decrease_sat(self, step=None):
|
|
||||||
'''
|
|
||||||
Decreases saturation by step amount stopping at 0
|
|
||||||
:param step:
|
|
||||||
'''
|
|
||||||
if not step:
|
|
||||||
step = self.sat_step
|
|
||||||
|
|
||||||
if (self.sat - step) <= 0:
|
|
||||||
self.sat = 0
|
|
||||||
else:
|
|
||||||
self.sat -= step
|
|
||||||
|
|
||||||
if self._check_update():
|
|
||||||
self._do_update()
|
|
||||||
|
|
||||||
def increase_val(self, step=None):
|
|
||||||
'''
|
|
||||||
Increases value by step amount stopping at 100
|
|
||||||
:param step:
|
|
||||||
'''
|
|
||||||
if not step:
|
|
||||||
step = self.val_step
|
|
||||||
if (self.val + step) >= 100:
|
|
||||||
self.val = 100
|
|
||||||
else:
|
|
||||||
self.val += step
|
|
||||||
|
|
||||||
if self._check_update():
|
|
||||||
self._do_update()
|
|
||||||
|
|
||||||
def decrease_val(self, step=None):
|
|
||||||
'''
|
|
||||||
Decreases value by step amount stopping at 0
|
|
||||||
:param step:
|
|
||||||
'''
|
|
||||||
if not step:
|
|
||||||
step = self.val_step
|
|
||||||
if (self.val - step) <= 0:
|
|
||||||
self.val = 0
|
|
||||||
else:
|
|
||||||
self.val -= step
|
|
||||||
|
|
||||||
if self._check_update():
|
|
||||||
self._do_update()
|
|
||||||
|
|
||||||
def increase_ani(self):
|
|
||||||
'''
|
|
||||||
Increases animation speed by 1 amount stopping at 10
|
|
||||||
:param step:
|
|
||||||
'''
|
|
||||||
if (self.animation_speed + 1) > 10:
|
|
||||||
self.animation_speed = 10
|
|
||||||
else:
|
|
||||||
self.animation_speed += 1
|
|
||||||
if self._check_update():
|
|
||||||
self._do_update()
|
|
||||||
|
|
||||||
def decrease_ani(self):
|
|
||||||
'''
|
|
||||||
Decreases animation speed by 1 amount stopping at 0
|
|
||||||
:param step:
|
|
||||||
'''
|
|
||||||
if (self.animation_speed - 1) <= 0:
|
|
||||||
self.animation_speed = 0
|
|
||||||
else:
|
|
||||||
self.animation_speed -= 1
|
|
||||||
if self._check_update():
|
|
||||||
self._do_update()
|
|
||||||
|
|
||||||
def off(self):
|
|
||||||
'''
|
|
||||||
Turns off all LEDs/Neopixels without changing stored values
|
|
||||||
'''
|
|
||||||
if self.neopixel:
|
|
||||||
self.set_hsv_fill(0, 0, 0)
|
|
||||||
|
|
||||||
def show(self):
|
|
||||||
'''
|
|
||||||
Turns on all LEDs/Neopixels without changing stored values
|
|
||||||
'''
|
|
||||||
if self.neopixel:
|
|
||||||
self.neopixel.show()
|
|
||||||
|
|
||||||
def animate(self):
|
|
||||||
'''
|
|
||||||
Activates a "step" in the animation based on the active mode
|
|
||||||
:return: Returns the new state in animation
|
|
||||||
'''
|
|
||||||
if self.effect_init:
|
|
||||||
self._init_effect()
|
|
||||||
|
|
||||||
if self.animation_mode is not AnimationModes.STATIC_STANDBY:
|
|
||||||
self.loopcounter += 1
|
|
||||||
if self.loopcounter >= 7 and self.enable:
|
|
||||||
self.loopcounter = 0
|
|
||||||
if self.animation_mode == AnimationModes.BREATHING:
|
|
||||||
self.effect_breathing()
|
|
||||||
elif self.animation_mode == AnimationModes.RAINBOW:
|
|
||||||
self.effect_rainbow()
|
|
||||||
elif self.animation_mode == AnimationModes.BREATHING_RAINBOW:
|
|
||||||
self.effect_breathing_rainbow()
|
|
||||||
elif self.animation_mode == AnimationModes.STATIC:
|
|
||||||
self.effect_static()
|
|
||||||
elif self.animation_mode == AnimationModes.KNIGHT:
|
|
||||||
self.effect_knight()
|
|
||||||
elif self.animation_mode == AnimationModes.SWIRL:
|
|
||||||
self.effect_swirl()
|
|
||||||
elif self.animation_mode == AnimationModes.USER:
|
|
||||||
self.user_animation(self)
|
|
||||||
elif self.animation_mode == AnimationModes.STATIC_STANDBY:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.off()
|
|
||||||
if self.loopcounter >= 7:
|
|
||||||
self.loopcounter = 0
|
|
||||||
|
|
||||||
def _animation_step(self):
|
|
||||||
interval = self.time_ms() - self.time
|
|
||||||
if interval >= max(self.intervals):
|
|
||||||
self.time = self.time_ms()
|
|
||||||
return max(self.intervals)
|
|
||||||
if interval in self.intervals:
|
|
||||||
return interval
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _init_effect(self):
|
|
||||||
if (
|
|
||||||
self.animation_mode == AnimationModes.BREATHING
|
|
||||||
or self.animation_mode == AnimationModes.BREATHING_RAINBOW
|
|
||||||
):
|
|
||||||
self.intervals = (30, 20, 10, 5)
|
|
||||||
elif self.animation_mode == AnimationModes.SWIRL:
|
|
||||||
self.intervals = (50, 50)
|
|
||||||
|
|
||||||
self.pos = 0
|
|
||||||
self.reverse_animation = False
|
|
||||||
self.effect_init = False
|
|
||||||
|
|
||||||
def _check_update(self):
|
|
||||||
return bool(self.animation_mode == AnimationModes.STATIC_STANDBY)
|
|
||||||
|
|
||||||
def _do_update(self):
|
|
||||||
if self.animation_mode == AnimationModes.STATIC_STANDBY:
|
|
||||||
self.animation_mode = AnimationModes.STATIC
|
|
||||||
|
|
||||||
def effect_static(self):
|
|
||||||
self.set_hsv_fill(self.hue, self.sat, self.val)
|
|
||||||
self.animation_mode = AnimationModes.STATIC_STANDBY
|
|
||||||
|
|
||||||
def effect_breathing(self):
|
|
||||||
# http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/
|
|
||||||
# https://github.com/qmk/qmk_firmware/blob/9f1d781fcb7129a07e671a46461e501e3f1ae59d/quantum/rgblight.c#L806
|
|
||||||
sined = sin((self.pos / 255.0) * pi)
|
|
||||||
multip_1 = exp(sined) - self.breathe_center / e
|
|
||||||
multip_2 = self.val_limit / (e - 1 / e)
|
|
||||||
|
|
||||||
self.val = int(multip_1 * multip_2)
|
|
||||||
self.pos = (self.pos + self.animation_speed) % 256
|
|
||||||
self.set_hsv_fill(self.hue, self.sat, self.val)
|
|
||||||
|
|
||||||
def effect_breathing_rainbow(self):
|
|
||||||
self.increase_hue(self.animation_speed)
|
|
||||||
self.effect_breathing()
|
|
||||||
|
|
||||||
def effect_rainbow(self):
|
|
||||||
self.increase_hue(self.animation_speed)
|
|
||||||
self.set_hsv_fill(self.hue, self.sat, self.val)
|
|
||||||
|
|
||||||
def effect_swirl(self):
|
|
||||||
self.increase_hue(self.animation_speed)
|
|
||||||
self.disable_auto_write = True # Turn off instantly showing
|
|
||||||
for i in range(0, self.num_pixels):
|
|
||||||
self.set_hsv(
|
|
||||||
(self.hue - (i * self.num_pixels)) % 360, self.sat, self.val, i
|
|
||||||
)
|
|
||||||
|
|
||||||
# Show final results
|
|
||||||
self.disable_auto_write = False # Resume showing changes
|
|
||||||
self.show()
|
|
||||||
|
|
||||||
def effect_knight(self):
|
|
||||||
# Determine which LEDs should be lit up
|
|
||||||
self.disable_auto_write = True # Turn off instantly showing
|
|
||||||
self.off() # Fill all off
|
|
||||||
pos = int(self.pos)
|
|
||||||
|
|
||||||
# Set all pixels on in range of animation length offset by position
|
|
||||||
for i in range(pos, (pos + self.knight_effect_length)):
|
|
||||||
self.set_hsv(self.hue, self.sat, self.val, i)
|
|
||||||
|
|
||||||
# Reverse animation when a boundary is hit
|
|
||||||
if pos >= self.num_pixels or pos - 1 < (self.knight_effect_length * -1):
|
|
||||||
self.reverse_animation = not self.reverse_animation
|
|
||||||
|
|
||||||
if self.reverse_animation:
|
|
||||||
self.pos -= self.animation_speed / 2
|
|
||||||
else:
|
|
||||||
self.pos += self.animation_speed / 2
|
|
||||||
|
|
||||||
# Show final results
|
|
||||||
self.disable_auto_write = False # Resume showing changes
|
|
||||||
self.show()
|
|
||||||
|
|
||||||
def _rgb_tog(self, *args, **kwargs):
|
|
||||||
if self.animation_mode == AnimationModes.STATIC:
|
|
||||||
self.animation_mode = AnimationModes.STATIC_STANDBY
|
|
||||||
self._do_update()
|
|
||||||
if self.animation_mode == AnimationModes.STATIC_STANDBY:
|
|
||||||
self.animation_mode = AnimationModes.STATIC
|
|
||||||
self._do_update()
|
|
||||||
if self.enable:
|
|
||||||
self.off()
|
|
||||||
self.enable = not self.enable
|
|
||||||
|
|
||||||
def _rgb_hui(self, *args, **kwargs):
|
def _rgb_hui(self, *args, **kwargs):
|
||||||
self.increase_hue()
|
rgb_helper.increase_hue(self)
|
||||||
|
|
||||||
def _rgb_hud(self, *args, **kwargs):
|
def _rgb_hud(self, *args, **kwargs):
|
||||||
self.decrease_hue()
|
rgb_helper.decrease_hue(self)
|
||||||
|
|
||||||
def _rgb_sai(self, *args, **kwargs):
|
def _rgb_sai(self, *args, **kwargs):
|
||||||
self.increase_sat()
|
rgb_helper.increase_sat(self)
|
||||||
|
|
||||||
def _rgb_sad(self, *args, **kwargs):
|
def _rgb_sad(self, *args, **kwargs):
|
||||||
self.decrease_sat()
|
rgb_helper.decrease_sat(self)
|
||||||
|
|
||||||
def _rgb_vai(self, *args, **kwargs):
|
def _rgb_vai(self, *args, **kwargs):
|
||||||
self.increase_val()
|
rgb_helper.increase_val(self)
|
||||||
|
|
||||||
def _rgb_vad(self, *args, **kwargs):
|
def _rgb_vad(self, *args, **kwargs):
|
||||||
self.decrease_val()
|
rgb_helper.decrease_val(self)
|
||||||
|
|
||||||
def _rgb_ani(self, *args, **kwargs):
|
def _rgb_ani(self, *args, **kwargs):
|
||||||
self.increase_ani()
|
rgb_helper.increase_ani(self)
|
||||||
|
|
||||||
def _rgb_and(self, *args, **kwargs):
|
def _rgb_and(self, *args, **kwargs):
|
||||||
self.decrease_ani()
|
rgb_helper.decrease_ani(self)
|
||||||
|
|
||||||
def _rgb_mode_static(self, *args, **kwargs):
|
def _rgb_mode_static(self, *args, **kwargs):
|
||||||
self.effect_init = True
|
self.effect_init = True
|
||||||
@ -599,3 +226,134 @@ class RGB(Extension):
|
|||||||
if self.animation_mode == AnimationModes.STATIC_STANDBY:
|
if self.animation_mode == AnimationModes.STATIC_STANDBY:
|
||||||
self.animation_mode = AnimationModes.STATIC
|
self.animation_mode = AnimationModes.STATIC
|
||||||
self._do_update()
|
self._do_update()
|
||||||
|
|
||||||
|
def animate(self):
|
||||||
|
'''
|
||||||
|
Activates a "step" in the animation based on the active mode
|
||||||
|
:return: Returns the new state in animation
|
||||||
|
'''
|
||||||
|
if self.effect_init:
|
||||||
|
self._init_effect()
|
||||||
|
|
||||||
|
if self.animation_mode is not AnimationModes.STATIC_STANDBY:
|
||||||
|
self.loopcounter += 1
|
||||||
|
if self.loopcounter >= 7 and self.enable:
|
||||||
|
self.loopcounter = 0
|
||||||
|
if self.animation_mode == AnimationModes.BREATHING:
|
||||||
|
self.effect_breathing()
|
||||||
|
elif self.animation_mode == AnimationModes.RAINBOW:
|
||||||
|
self.effect_rainbow()
|
||||||
|
elif self.animation_mode == AnimationModes.BREATHING_RAINBOW:
|
||||||
|
self.effect_breathing_rainbow()
|
||||||
|
elif self.animation_mode == AnimationModes.STATIC:
|
||||||
|
self.effect_static()
|
||||||
|
elif self.animation_mode == AnimationModes.KNIGHT:
|
||||||
|
self.effect_knight()
|
||||||
|
elif self.animation_mode == AnimationModes.SWIRL:
|
||||||
|
self.effect_swirl()
|
||||||
|
elif self.animation_mode == AnimationModes.USER:
|
||||||
|
self.user_animation(self)
|
||||||
|
elif self.animation_mode == AnimationModes.STATIC_STANDBY:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
rgb_helper.off(self)
|
||||||
|
if self.loopcounter >= 7:
|
||||||
|
self.loopcounter = 0
|
||||||
|
|
||||||
|
def _animation_step(self):
|
||||||
|
interval = ticks_ms() - self.time
|
||||||
|
if interval >= max(self.intervals):
|
||||||
|
self.time = ticks_ms()
|
||||||
|
return max(self.intervals)
|
||||||
|
if interval in self.intervals:
|
||||||
|
return interval
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _init_effect(self):
|
||||||
|
if (
|
||||||
|
self.animation_mode == AnimationModes.BREATHING
|
||||||
|
or self.animation_mode == AnimationModes.BREATHING_RAINBOW
|
||||||
|
):
|
||||||
|
self.intervals = (30, 20, 10, 5)
|
||||||
|
elif self.animation_mode == AnimationModes.SWIRL:
|
||||||
|
self.intervals = (50, 50)
|
||||||
|
|
||||||
|
self.pos = 0
|
||||||
|
self.reverse_animation = False
|
||||||
|
self.effect_init = False
|
||||||
|
|
||||||
|
def _check_update(self):
|
||||||
|
return bool(self.animation_mode == AnimationModes.STATIC_STANDBY)
|
||||||
|
|
||||||
|
def _do_update(self):
|
||||||
|
if self.animation_mode == AnimationModes.STATIC_STANDBY:
|
||||||
|
self.animation_mode = AnimationModes.STATIC
|
||||||
|
|
||||||
|
def effect_static(self):
|
||||||
|
rgb_helper.set_hsv_fill(self, self.hue, self.sat, self.val)
|
||||||
|
self.animation_mode = AnimationModes.STATIC_STANDBY
|
||||||
|
|
||||||
|
def effect_breathing(self):
|
||||||
|
# http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/
|
||||||
|
# https://github.com/qmk/qmk_firmware/blob/9f1d781fcb7129a07e671a46461e501e3f1ae59d/quantum/rgblight.c#L806
|
||||||
|
sined = sin((self.pos / 255.0) * pi)
|
||||||
|
multip_1 = exp(sined) - self.breathe_center / e
|
||||||
|
multip_2 = self.val_limit / (e - 1 / e)
|
||||||
|
|
||||||
|
self.val = int(multip_1 * multip_2)
|
||||||
|
self.pos = (self.pos + self.animation_speed) % 256
|
||||||
|
rgb_helper.set_hsv_fill(self, self.hue, self.sat, self.val)
|
||||||
|
|
||||||
|
def effect_breathing_rainbow(self):
|
||||||
|
rgb_helper.increase_hue(self, self.animation_speed)
|
||||||
|
self.effect_breathing()
|
||||||
|
|
||||||
|
def effect_rainbow(self):
|
||||||
|
rgb_helper.increase_hue(self, self.animation_speed)
|
||||||
|
rgb_helper.set_hsv_fill(self, self.hue, self.sat, self.val)
|
||||||
|
|
||||||
|
def effect_swirl(self):
|
||||||
|
rgb_helper.increase_hue(self, self.animation_speed)
|
||||||
|
self.disable_auto_write = True # Turn off instantly showing
|
||||||
|
for i in range(0, self.num_pixels):
|
||||||
|
rgb_helper.set_hsv(
|
||||||
|
self, (self.hue - (i * self.num_pixels)) % 360, self.sat, self.val, i
|
||||||
|
)
|
||||||
|
|
||||||
|
# Show final results
|
||||||
|
self.disable_auto_write = False # Resume showing changes
|
||||||
|
rgb_helper.show(self)
|
||||||
|
|
||||||
|
def effect_knight(self):
|
||||||
|
# Determine which LEDs should be lit up
|
||||||
|
self.disable_auto_write = True # Turn off instantly showing
|
||||||
|
rgb_helper.off(self) # Fill all off
|
||||||
|
pos = int(self.pos)
|
||||||
|
|
||||||
|
# Set all pixels on in range of animation length offset by position
|
||||||
|
for i in range(pos, (pos + self.knight_effect_length)):
|
||||||
|
rgb_helper.set_hsv(self, self.hue, self.sat, self.val, i)
|
||||||
|
|
||||||
|
# Reverse animation when a boundary is hit
|
||||||
|
if pos >= self.num_pixels or pos - 1 < (self.knight_effect_length * -1):
|
||||||
|
self.reverse_animation = not self.reverse_animation
|
||||||
|
|
||||||
|
if self.reverse_animation:
|
||||||
|
self.pos -= self.animation_speed / 2
|
||||||
|
else:
|
||||||
|
self.pos += self.animation_speed / 2
|
||||||
|
|
||||||
|
# Show final results
|
||||||
|
self.disable_auto_write = False # Resume showing changes
|
||||||
|
rgb_helper.show(self)
|
||||||
|
|
||||||
|
def _rgb_tog(self, *args, **kwargs):
|
||||||
|
if self.animation_mode == AnimationModes.STATIC:
|
||||||
|
self.animation_mode = AnimationModes.STATIC_STANDBY
|
||||||
|
self._do_update()
|
||||||
|
if self.animation_mode == AnimationModes.STATIC_STANDBY:
|
||||||
|
self.animation_mode = AnimationModes.STATIC
|
||||||
|
self._do_update()
|
||||||
|
if self.enable:
|
||||||
|
rgb_helper.off(self)
|
||||||
|
self.enable = not self.enable
|
||||||
|
|||||||
254
kmk/lib/rgb_helper.py
Normal file
254
kmk/lib/rgb_helper.py
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
def hsv_to_rgb(rgb_obj, hue, sat, val):
|
||||||
|
'''
|
||||||
|
Converts HSV values, and returns a tuple of RGB values
|
||||||
|
:param hue:
|
||||||
|
:param sat:
|
||||||
|
:param val:
|
||||||
|
:return: (r, g, b)
|
||||||
|
'''
|
||||||
|
r = 0
|
||||||
|
g = 0
|
||||||
|
b = 0
|
||||||
|
|
||||||
|
if val > rgb_obj.val_limit:
|
||||||
|
val = rgb_obj.val_limit
|
||||||
|
|
||||||
|
if sat == 0:
|
||||||
|
r = val
|
||||||
|
g = val
|
||||||
|
b = val
|
||||||
|
|
||||||
|
else:
|
||||||
|
base = ((100 - sat) * val) / 100
|
||||||
|
color = (val - base) * ((hue % 60) / 60)
|
||||||
|
|
||||||
|
x = int(hue / 60)
|
||||||
|
if x == 0:
|
||||||
|
r = val
|
||||||
|
g = base + color
|
||||||
|
b = base
|
||||||
|
elif x == 1:
|
||||||
|
r = val - color
|
||||||
|
g = val
|
||||||
|
b = base
|
||||||
|
elif x == 2:
|
||||||
|
r = base
|
||||||
|
g = val
|
||||||
|
b = base + color
|
||||||
|
elif x == 3:
|
||||||
|
r = base
|
||||||
|
g = val - color
|
||||||
|
b = val
|
||||||
|
elif x == 4:
|
||||||
|
r = base + color
|
||||||
|
g = base
|
||||||
|
b = val
|
||||||
|
elif x == 5:
|
||||||
|
r = val
|
||||||
|
g = base
|
||||||
|
b = val - color
|
||||||
|
|
||||||
|
return int(r), int(g), int(b)
|
||||||
|
|
||||||
|
|
||||||
|
def hsv_to_rgbw(rgb_obj, hue, sat, val):
|
||||||
|
'''
|
||||||
|
Converts HSV values, and returns a tuple of RGBW values
|
||||||
|
:param hue:
|
||||||
|
:param sat:
|
||||||
|
:param val:
|
||||||
|
:return: (r, g, b, w)
|
||||||
|
'''
|
||||||
|
rgb = rgb_obj.hsv_to_rgb(hue, sat, val)
|
||||||
|
return rgb[0], rgb[1], rgb[2], min(rgb)
|
||||||
|
|
||||||
|
|
||||||
|
def set_hsv(rgb_obj, hue, sat, val, index):
|
||||||
|
'''
|
||||||
|
Takes HSV values and displays it on a single LED/Neopixel
|
||||||
|
:param hue:
|
||||||
|
:param sat:
|
||||||
|
:param val:
|
||||||
|
:param index: Index of LED/Pixel
|
||||||
|
'''
|
||||||
|
if rgb_obj.neopixel:
|
||||||
|
if rgb_obj.rgbw:
|
||||||
|
rgb_obj.set_rgb(rgb_obj.hsv_to_rgbw(hue, sat, val), index)
|
||||||
|
else:
|
||||||
|
rgb_obj.set_rgb(rgb_obj.hsv_to_rgb(hue, sat, val), index)
|
||||||
|
|
||||||
|
|
||||||
|
def set_hsv_fill(rgb_obj, hue, sat, val):
|
||||||
|
'''
|
||||||
|
Takes HSV values and displays it on all LEDs/Neopixels
|
||||||
|
:param hue:
|
||||||
|
:param sat:
|
||||||
|
:param val:
|
||||||
|
'''
|
||||||
|
if rgb_obj.neopixel:
|
||||||
|
if rgb_obj.rgbw:
|
||||||
|
rgb_obj.set_rgb_fill(rgb_obj.hsv_to_rgbw(hue, sat, val))
|
||||||
|
else:
|
||||||
|
rgb_obj.set_rgb_fill(rgb_obj.hsv_to_rgb(hue, sat, val))
|
||||||
|
|
||||||
|
|
||||||
|
def set_rgb(rgb_obj, rgb, index):
|
||||||
|
'''
|
||||||
|
Takes an RGB or RGBW and displays it on a single LED/Neopixel
|
||||||
|
:param rgb: RGB or RGBW
|
||||||
|
:param index: Index of LED/Pixel
|
||||||
|
'''
|
||||||
|
if rgb_obj.neopixel and 0 <= index <= rgb_obj.num_pixels - 1:
|
||||||
|
rgb_obj.neopixel[index] = rgb
|
||||||
|
if not rgb_obj.disable_auto_write:
|
||||||
|
rgb_obj.neopixel.show()
|
||||||
|
|
||||||
|
|
||||||
|
def set_rgb_fill(rgb_obj, rgb):
|
||||||
|
'''
|
||||||
|
Takes an RGB or RGBW and displays it on all LEDs/Neopixels
|
||||||
|
:param rgb: RGB or RGBW
|
||||||
|
'''
|
||||||
|
if rgb_obj.neopixel:
|
||||||
|
rgb_obj.neopixel.fill(rgb)
|
||||||
|
if not rgb_obj.disable_auto_write:
|
||||||
|
rgb_obj.neopixel.show()
|
||||||
|
|
||||||
|
|
||||||
|
def increase_hue(rgb_obj, step=None):
|
||||||
|
'''
|
||||||
|
Increases hue by step amount rolling at 360 and returning to 0
|
||||||
|
:param step:
|
||||||
|
'''
|
||||||
|
if not step:
|
||||||
|
step = rgb_obj.hue_step
|
||||||
|
|
||||||
|
rgb_obj.hue = (rgb_obj.hue + step) % 360
|
||||||
|
|
||||||
|
if rgb_obj._check_update():
|
||||||
|
rgb_obj._do_update()
|
||||||
|
|
||||||
|
|
||||||
|
def decrease_hue(rgb_obj, step=None):
|
||||||
|
'''
|
||||||
|
Decreases hue by step amount rolling at 0 and returning to 360
|
||||||
|
:param step:
|
||||||
|
'''
|
||||||
|
if not step:
|
||||||
|
step = rgb_obj.hue_step
|
||||||
|
|
||||||
|
if (rgb_obj.hue - step) <= 0:
|
||||||
|
rgb_obj.hue = (rgb_obj.hue + 360 - step) % 360
|
||||||
|
else:
|
||||||
|
rgb_obj.hue = (rgb_obj.hue - step) % 360
|
||||||
|
|
||||||
|
if rgb_obj._check_update():
|
||||||
|
rgb_obj._do_update()
|
||||||
|
|
||||||
|
|
||||||
|
def increase_sat(rgb_obj, step=None):
|
||||||
|
'''
|
||||||
|
Increases saturation by step amount stopping at 100
|
||||||
|
:param step:
|
||||||
|
'''
|
||||||
|
if not step:
|
||||||
|
step = rgb_obj.sat_step
|
||||||
|
|
||||||
|
if rgb_obj.sat + step >= 100:
|
||||||
|
rgb_obj.sat = 100
|
||||||
|
else:
|
||||||
|
rgb_obj.sat += step
|
||||||
|
|
||||||
|
if rgb_obj._check_update():
|
||||||
|
rgb_obj._do_update()
|
||||||
|
|
||||||
|
|
||||||
|
def decrease_sat(rgb_obj, step=None):
|
||||||
|
'''
|
||||||
|
Decreases saturation by step amount stopping at 0
|
||||||
|
:param step:
|
||||||
|
'''
|
||||||
|
if not step:
|
||||||
|
step = rgb_obj.sat_step
|
||||||
|
|
||||||
|
if (rgb_obj.sat - step) <= 0:
|
||||||
|
rgb_obj.sat = 0
|
||||||
|
else:
|
||||||
|
rgb_obj.sat -= step
|
||||||
|
|
||||||
|
if rgb_obj._check_update():
|
||||||
|
rgb_obj._do_update()
|
||||||
|
|
||||||
|
|
||||||
|
def increase_val(rgb_obj, step=None):
|
||||||
|
'''
|
||||||
|
Increases value by step amount stopping at 100
|
||||||
|
:param step:
|
||||||
|
'''
|
||||||
|
if not step:
|
||||||
|
step = rgb_obj.val_step
|
||||||
|
if (rgb_obj.val + step) >= 100:
|
||||||
|
rgb_obj.val = 100
|
||||||
|
else:
|
||||||
|
rgb_obj.val += step
|
||||||
|
|
||||||
|
if rgb_obj._check_update():
|
||||||
|
rgb_obj._do_update()
|
||||||
|
|
||||||
|
|
||||||
|
def decrease_val(rgb_obj, step=None):
|
||||||
|
'''
|
||||||
|
Decreases value by step amount stopping at 0
|
||||||
|
:param step:
|
||||||
|
'''
|
||||||
|
if not step:
|
||||||
|
step = rgb_obj.val_step
|
||||||
|
if (rgb_obj.val - step) <= 0:
|
||||||
|
rgb_obj.val = 0
|
||||||
|
else:
|
||||||
|
rgb_obj.val -= step
|
||||||
|
|
||||||
|
if rgb_obj._check_update():
|
||||||
|
rgb_obj._do_update()
|
||||||
|
|
||||||
|
|
||||||
|
def increase_ani(rgb_obj):
|
||||||
|
'''
|
||||||
|
Increases animation speed by 1 amount stopping at 10
|
||||||
|
:param step:
|
||||||
|
'''
|
||||||
|
if (rgb_obj.animation_speed + 1) > 10:
|
||||||
|
rgb_obj.animation_speed = 10
|
||||||
|
else:
|
||||||
|
rgb_obj.animation_speed += 1
|
||||||
|
if rgb_obj._check_update():
|
||||||
|
rgb_obj._do_update()
|
||||||
|
|
||||||
|
|
||||||
|
def decrease_ani(rgb_obj):
|
||||||
|
'''
|
||||||
|
Decreases animation speed by 1 amount stopping at 0
|
||||||
|
:param step:
|
||||||
|
'''
|
||||||
|
if (rgb_obj.animation_speed - 1) <= 0:
|
||||||
|
rgb_obj.animation_speed = 0
|
||||||
|
else:
|
||||||
|
rgb_obj.animation_speed -= 1
|
||||||
|
if rgb_obj._check_update():
|
||||||
|
rgb_obj._do_update()
|
||||||
|
|
||||||
|
|
||||||
|
def off(rgb_obj):
|
||||||
|
'''
|
||||||
|
Turns off all LEDs/Neopixels without changing stored values
|
||||||
|
'''
|
||||||
|
if rgb_obj.neopixel:
|
||||||
|
rgb_obj.set_hsv_fill(0, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def show(rgb_obj):
|
||||||
|
'''
|
||||||
|
Turns on all LEDs/Neopixels without changing stored values
|
||||||
|
'''
|
||||||
|
if rgb_obj.neopixel:
|
||||||
|
rgb_obj.neopixel.show()
|
||||||
Loading…
x
Reference in New Issue
Block a user