Switch coloUr to color in backend

This commit is contained in:
Shaun Eccles-Smith 2021-12-11 12:19:30 +11:00
parent 782111266d
commit 5928726fa0
15 changed files with 115 additions and 115 deletions

View File

@ -114,14 +114,14 @@ class EffectsEndpoint(RestEndpoint):
virtual.active_effect
and virtual.active_effect.type == effect_type
):
# substring search to match any key containing "color" or "colour"
# substring search to match any key of color
# this handles special cases where we want to update an effect and also trigger
# a transition by creating a new effect.
if next(
(
key
for key in effect_config.keys()
if "color" or "colour" in key
if "color" in key
),
None,
):

View File

@ -71,7 +71,7 @@ def parse_color(color: (str, list, tuple)) -> RGB:
# Failing that, try to parse it using ImageColor
return RGB(*ImageColor.getrgb(color))
except (ValueError, AssertionError):
msg = f"Invalid colour: {color}"
msg = f"Invalid color: {color}"
_LOGGER.error(msg)
raise ValueError(msg)

View File

@ -220,12 +220,12 @@ class Effect(BaseRegistry):
): vol.All(vol.Coerce(float), vol.Range(min=0.0, max=1.0)),
vol.Optional(
"background_color",
description="Apply a background colour",
description="Apply a background color",
default="#000000",
): validate_color,
vol.Optional(
"background_brightness",
description="Brightness of the background colour",
description="Brightness of the background color",
default=1.0,
): vol.All(vol.Coerce(float), vol.Range(min=0.0, max=1.0)),
}
@ -327,7 +327,7 @@ class Effect(BaseRegistry):
(pixels[-1 + len(pixels) % -2 :: -2], pixels[::2])
)
if self._config["background_color"]:
# TODO: colours in future should have an alpha value, which would work nicely to apply to dim the background colour
# TODO: colors in future should have an alpha value, which would work nicely to apply to dim the background color
# for now, just set it a bit less bright.
pass
# pixels += self._bg_color

View File

@ -56,11 +56,11 @@ class BarAudioEffect(AudioReactiveEffect, GradientEffect):
self.beat_now = data.bpm_beat_now()
self.beat_count = data.beat_counter
# Colour change and phase
# color change and phase
if self.beat_now:
self.phase = 1 - self.phase # flip flop 0->1, 1->0
if self.phase == 0:
# 8 colours, 4 beats to a bar
# 8 colors, 4 beats to a bar
self.color_idx += self._config["color_step"]
self.color_idx = self.color_idx % 1 # loop back to zero

View File

@ -49,7 +49,7 @@ class EnergyAudioEffect(AudioReactiveEffect):
): vol.All(vol.Coerce(float), vol.Range(min=0.3, max=0.99)),
vol.Optional(
"mixing_mode",
description="Mode of combining each frequencies' colours",
description="Mode of combining each frequencies' colors",
default="additive",
): vol.In(["additive", "overlap"]),
}
@ -72,13 +72,13 @@ class EnergyAudioEffect(AudioReactiveEffect):
self.color_cycler = 0
self.lows_colour = np.array(
self.lows_color = np.array(
parse_color(self._config["color_lows"]), dtype=float
)
self.mids_colour = np.array(
self.mids_color = np.array(
parse_color(self._config["color_mids"]), dtype=float
)
self.high_colour = np.array(
self.high_color = np.array(
parse_color(self._config["color_high"]), dtype=float
)
@ -103,23 +103,23 @@ class EnergyAudioEffect(AudioReactiveEffect):
color = np.random.choice(tuple(self._ledfx.colors.values()))
if self.color_cycler == 0:
self.lows_colour = color
self.lows_color = color
elif self.color_cycler == 1:
self.mids_colour = color
self.mids_color = color
elif self.color_cycler == 2:
self.high_colour = color
self.high_color = color
# Build the new energy profile based on the mids, highs and lows setting
# the colors as red, green, and blue channel respectively
self.p[:, :] = 0
if self._config["mixing_mode"] == "additive":
self.p[: self.lows_idx] = self.lows_colour
self.p[: self.mids_idx] += self.mids_colour
self.p[: self.highs_idx] += self.high_colour
self.p[: self.lows_idx] = self.lows_color
self.p[: self.mids_idx] += self.mids_color
self.p[: self.highs_idx] += self.high_color
elif self._config["mixing_mode"] == "overlap":
self.p[: self.lows_idx] = self.lows_colour
self.p[: self.mids_idx] = self.mids_colour
self.p[: self.highs_idx] = self.high_colour
self.p[: self.lows_idx] = self.lows_color
self.p[: self.mids_idx] = self.mids_color
self.p[: self.highs_idx] = self.high_color
# Filter and update the pixel values
self.pixels = self._p_filter.update(self.p)

View File

@ -7,7 +7,7 @@ from ledfx.effects.temporal import TemporalEffect
class FadeEffect(TemporalEffect, GradientEffect):
"""
Fades through the colours of a gradient
Fades through the colors of a gradient
"""
NAME = "Fade"

View File

@ -81,7 +81,7 @@ class GradientEffect(Effect):
gradient_colors = gradient.colors
# fill in start and end colours if not explicitly given
# fill in start and end colors if not explicitly given
if gradient_colors[0][1] != 0.0:
gradient_colors.insert(0, (gradient_colors[0][0], 0.0))

View File

@ -43,10 +43,10 @@ class MultiBarAudioEffect(AudioReactiveEffect, GradientEffect):
data.bpm_beat_now(),
)
# Colour change and phase
# color change and phase
if self.beat_now:
self.phase = 1 - self.phase # flip flop 0->1, 1->0
# 8 colours, 4 beats to a bar
# 8 colors, 4 beats to a bar
self.color_idx += self._config["color_step"]
self.color_idx = self.color_idx % 1 # loop back to zero

View File

@ -24,18 +24,18 @@ class RainAudioEffect(AudioReactiveEffect):
# which will provide a list of available drop names rather than just
# this static range
vol.Optional(
"lows_colour",
description="Colour for low sounds, ie beats",
"lows_color",
description="color for low sounds, ie beats",
default="white",
): validate_color,
vol.Optional(
"mids_colour",
description="Colour for mid sounds, ie vocals",
"mids_color",
description="color for mid sounds, ie vocals",
default="red",
): validate_color,
vol.Optional(
"high_colour",
description="Colour for high sounds, ie hi hat",
"high_color",
description="color for high sounds, ie hi hat",
default="blue",
): validate_color,
vol.Optional(
@ -63,7 +63,7 @@ class RainAudioEffect(AudioReactiveEffect):
def on_activate(self, pixel_count):
self.drop_frames = np.zeros(self.pixel_count, dtype=int)
self.drop_colours = np.zeros((3, self.pixel_count))
self.drop_colors = np.zeros((3, self.pixel_count))
def config_updated(self, config):
self.drop_animation = load_droplet(config["raindrop_animation"])
@ -77,41 +77,41 @@ class RainAudioEffect(AudioReactiveEffect):
)
self.filtered_intensities = np.zeros(3)
def new_drop(self, location, colour):
def new_drop(self, location, color):
"""
Add a new drop animation
TODO (?) this method overwrites a running drop animation in the same location
would need a significant restructure to fix
"""
self.drop_frames[location] = 1
self.drop_colours[:, location] = colour
self.drop_colors[:, location] = color
def update_drop_frames(self):
# Set any drops at final frame back to 0 and remove colour data
# Set any drops at final frame back to 0 and remove color data
finished_drops = self.drop_frames >= self.n_frames - 1
self.drop_frames[finished_drops] = 0
self.drop_colours[:, finished_drops] = 0
self.drop_colors[:, finished_drops] = 0
# Add one to any running frames
self.drop_frames[self.drop_frames > 0] += 1
def render(self):
"""
Get coloured pixel data of all drops overlaid
Get colored pixel data of all drops overlaid
"""
# 2d array containing colour intensity data
# 2d array containing color intensity data
overlaid_frames = np.zeros((3, self.pixel_count + self.frame_width))
# Indexes of active drop animations
drop_indices = np.flatnonzero(self.drop_frames)
# TODO vectorize this to remove for loop
for index in drop_indices:
coloured_frame = [
colored_frame = [
self.drop_animation[self.drop_frames[index]]
* self.drop_colours[colour, index]
for colour in range(3)
* self.drop_colors[color, index]
for color in range(3)
]
overlaid_frames[
:, index : index + self.frame_width
] += coloured_frame
] += colored_frame
np.clip(overlaid_frames, 0, 255, out=overlaid_frames)
self.pixels = overlaid_frames[
@ -136,7 +136,7 @@ class RainAudioEffect(AudioReactiveEffect):
):
self.new_drop(
randint(0, self.pixel_count - 1),
parse_color(self._config["lows_colour"]),
parse_color(self._config["lows_color"]),
)
if (
intensities[1] - self.filtered_intensities[1]
@ -144,7 +144,7 @@ class RainAudioEffect(AudioReactiveEffect):
):
self.new_drop(
randint(0, self.pixel_count - 1),
parse_color(self._config["mids_colour"]),
parse_color(self._config["mids_color"]),
)
if (
intensities[2] - self.filtered_intensities[2]
@ -152,7 +152,7 @@ class RainAudioEffect(AudioReactiveEffect):
):
self.new_drop(
randint(0, self.pixel_count - 1),
parse_color(self._config["high_colour"]),
parse_color(self._config["high_color"]),
)
self.filtered_intensities = self.intensity_filter.update(intensities)

View File

@ -34,7 +34,7 @@ class Strobe(AudioReactiveEffect, GradientEffect):
): vol.All(vol.Coerce(float), vol.Range(min=0, max=1)),
vol.Optional(
"strobe_color",
description="Colour for percussive strobes",
description="color for percussive strobes",
default="#FFFFFF",
): validate_color,
vol.Optional(
@ -57,7 +57,7 @@ class Strobe(AudioReactiveEffect, GradientEffect):
self.onsets_queue = queue.Queue()
def deactivate(self):
empty_queue(self.onsets_queue)
self.onsets_queue = None
return super().deactivate()

View File

@ -62,13 +62,13 @@ class ScrollAudioEffect(AudioReactiveEffect):
# is bound to a device while the config gets updated. Might need
# to move to a model where effects are created for a device and
# must be destroyed and recreated to be moved to another device.
self.lows_colour = np.array(
self.lows_color = np.array(
parse_color(self._config["color_lows"]), dtype=float
)
self.mids_colour = np.array(
self.mids_color = np.array(
parse_color(self._config["color_mids"]), dtype=float
)
self.high_colour = np.array(
self.high_color = np.array(
parse_color(self._config["color_high"]), dtype=float
)
@ -96,6 +96,6 @@ class ScrollAudioEffect(AudioReactiveEffect):
self.pixels[speed:, :] = self.pixels[:-speed, :]
self.pixels *= self.config["decay"]
self.pixels[:speed] = self.lows_colour * self.intensities[0]
self.pixels[:speed] += self.mids_colour * self.intensities[1]
self.pixels[:speed] += self.high_colour * self.intensities[2]
self.pixels[:speed] = self.lows_color * self.intensities[0]
self.pixels[:speed] += self.mids_color * self.intensities[1]
self.pixels[:speed] += self.high_color * self.intensities[2]

View File

@ -33,7 +33,7 @@ from ledfx.virtuals import Virtual
# DIMENSIONALITY 2:
# input type
# 0: [virtuals] set effect preset (configurable list of effect presets eg. select effect -> select preset)
# 1: [effects common] blur, brightness, (bkg_brightness?), gradient, colour
# 1: [effects common] blur, brightness, (bkg_brightness?), gradient, color
# 1: [effects specific] {TODO} any ranged value, ordered. difficult to show user what each knob does, maybe omit: each knob would control something different for each effect!
# DIMENSIONALITY 1:
@ -42,8 +42,8 @@ from ledfx.virtuals import Virtual
# 0: [virtuals] preview_only
# 1: [virtuals] transition time, min/max frequency range, max brightness
# 0: [effects common] flip, mirror
# 1: [effects common] blur, brightness, (bkg_brightness?), gradient, colour
# 2: [effects common] gradient, colour (???)
# 1: [effects common] blur, brightness, (bkg_brightness?), gradient, color
# 2: [effects common] gradient, color (???)
# 0: [effects specific] {TODO} any bool value, ordered
# 1: [effects specific] {TODO} any ranged value, ordered
@ -53,8 +53,8 @@ from ledfx.virtuals import Virtual
# 0: [global, virtuals] preview_only (blackout)
# 1: [global, virtuals] transition time, min/max frequency range, max brightness
# 0: [global, effects common] flip, mirror
# 1: [global, effects common] blur, brightness, (bkg_brightness?), gradient, colour
# 2: [global, effects common] gradient, colour (???)
# 1: [global, effects common] blur, brightness, (bkg_brightness?), gradient, color
# 2: [global, effects common] gradient, color (???)
_LOGGER = logging.getLogger(__name__)
@ -710,7 +710,7 @@ class Driver:
input type 1 generic : option key and a lambda to scale midi input to endpoint range
eg. ("blur", <lambda>)
input type 2 generic : option key and available choices
eg. ("bg_colour", "red", "green", "purple", ... )
eg. ("bg_color", "red", "green", "purple", ... )
"""
@ -852,7 +852,7 @@ class Mapping:
region["DIMENSIONALITY"],
region["INPUT_TYPE"],
region["MIDI_INPUT"],
region["LED_COLOUR_RANGE"],
region["LED_COLOR_RANGE"],
region["LED_STATE_MAPPINGS"],
)
for region in mapping["regions"]
@ -867,7 +867,7 @@ class Region:
dimensionality: int,
input_type: int,
midi_input: dict,
led_colour_range: list,
led_color_range: list,
led_state_mappings: list,
):
"""
@ -879,7 +879,7 @@ class Region:
self.dimensionality = dimensionality
self.input_type = input_type
self.midi_input = midi_input
self.led_colour_range = led_colour_range
self.led_color_range = led_color_range
self.led_state_mappings = led_state_mappings
self.has_leds = bool(self.led_state_mappings)
@ -927,30 +927,30 @@ class Region:
def set_led(
self,
state: int, # colour state, defined in mapping [0 off, 1,2,3 for each state]
state: int, # color state, defined in mapping [0 off, 1,2,3 for each state]
index: int, # index of led
):
"""
returns a message that when sent will set the led to the appropriate colour
returns a message that when sent will set the led to the appropriate color
"""
if not self.has_leds:
_LOGGER.warning(
f"Cannot set LED colour on MIDI region '{self.name}'"
f"Cannot set LED color on MIDI region '{self.name}'"
)
return
msg = self._input_positions[index]
if state == 0:
msg_type = self.mapping.led_config["led_off"]["msg_type"]
msg_colour = self.mapping.led_config["led_off"]["colour_data"]
msg_color = self.mapping.led_config["led_off"]["color_data"]
else:
msg_type = self.mapping.led_config["led_on"]["msg_type"]
msg_colour = self.led_state_mappings[state]
msg_color = self.led_state_mappings[state]
if self.has_leds:
self.led_states[index] = state
return mido.Message(
msg_type, channel=msg.channel, note=msg.note, velocity=msg_colour
msg_type, channel=msg.channel, note=msg.note, velocity=msg_color
)
def where(self, msg):

View File

@ -145,7 +145,7 @@ class MQTT_HASS(Integration):
paused_state,
)
def publish_single_colour_updated(event):
def publish_single_color_updated(event):
color = parse_color(event.effect_config.get("color"))
client.publish(
f"{self._config['topic']}/light/{event.virtual_id}/state",
@ -177,7 +177,7 @@ class MQTT_HASS(Integration):
self._listeners.append(
self._ledfx.events.add_listener(
publish_single_colour_updated,
publish_single_color_updated,
Event.EFFECT_SET,
event_filter={"effect_name": "Single Color"},
)
@ -540,7 +540,7 @@ class MQTT_HASS(Integration):
virtual = self._ledfx.virtuals.get(virtualid, None)
if virtual:
# SET VIRTUAL COLOR AND ACTIVE
colour = payload.get("effect", "orange")
color = payload.get("effect", "orange")
color = payload.get("color", None)
if color is not None:
@ -553,7 +553,7 @@ class MQTT_HASS(Integration):
effect = self._ledfx.effects.create(
ledfx=self._ledfx,
type="singleColor",
config={"color": colour},
config={"color": color},
)
try:
virtual.set_effect(effect)
@ -567,7 +567,7 @@ class MQTT_HASS(Integration):
item["active"] = virtual.active
item["effect"] = {}
item["effect"]["type"] = "singleColor"
item["effect"]["config"] = {"color": colour}
item["effect"]["config"] = {"color": color}
self._ledfx.config["virtuals"][idx] = item
break

View File

@ -529,11 +529,11 @@ ledfx_presets = {
"blur": 1.0,
"brightness": 1.0,
"flip": False,
"high_colour": "pink",
"high_color": "pink",
"high_sensitivity": 0.1,
"lows_colour": "white",
"lows_color": "white",
"lows_sensitivity": 0.1,
"mids_colour": "cyan",
"mids_color": "cyan",
"mids_sensitivity": 0.05,
"mirror": True,
"raindrop_animation": "droplet_1.npy",
@ -547,11 +547,11 @@ ledfx_presets = {
"blur": 2.3,
"brightness": 1,
"flip": False,
"high_colour": "yellow",
"high_color": "yellow",
"high_sensitivity": 0.1,
"lows_colour": "red",
"lows_color": "red",
"lows_sensitivity": 0.1,
"mids_colour": "orange",
"mids_color": "orange",
"mids_sensitivity": 0.05,
"mirror": False,
"raindrop_animation": "droplet_2.npy",
@ -565,11 +565,11 @@ ledfx_presets = {
"blur": 4.9,
"brightness": 1,
"flip": False,
"high_colour": "pink",
"high_color": "pink",
"high_sensitivity": 0.1,
"lows_colour": "orange",
"lows_color": "orange",
"lows_sensitivity": 0.1,
"mids_colour": "green",
"mids_color": "green",
"mids_sensitivity": 0.05,
"mirror": True,
"raindrop_animation": "droplet_1.npy",
@ -583,11 +583,11 @@ ledfx_presets = {
"blur": 0.8,
"brightness": 1,
"flip": False,
"high_colour": "cyan",
"high_color": "cyan",
"high_sensitivity": 0.1,
"lows_colour": "orange-deep",
"lows_color": "orange-deep",
"lows_sensitivity": 0.1,
"mids_colour": "yellow-acid",
"mids_color": "yellow-acid",
"mids_sensitivity": 0.05,
"mirror": True,
"raindrop_animation": "droplet_0.npy",
@ -604,11 +604,11 @@ ledfx_presets = {
"flip": False,
"gradient_name": "Dancefloor",
"gradient_roll": 8,
"high_colour": "blue",
"high_color": "blue",
"high_sensitivity": 0.1,
"lows_colour": "white",
"lows_color": "white",
"lows_sensitivity": 0.1,
"mids_colour": "red",
"mids_color": "red",
"mids_sensitivity": 0.05,
"mirror": False,
"raindrop_animation": "droplet_0.npy",

View File

@ -80,7 +80,7 @@ class Region:
"CONST_VALUE": None, # optional, str
"CONST_DATA": None # optional, int
}
LED_COLOUR_RANGE = None # range(min, max)
LED_COLOR_RANGE = None # range(min, max)
LED_STATE_MAPPINGS = None
@ -107,7 +107,7 @@ class Region:
"DIMENSIONALITY" : self.DIMENSIONALITY,
"INPUT_TYPE" : self.INPUT_TYPE,
"MIDI_INPUT" : self.MIDI_INPUT,
"LED_COLOUR_RANGE" : self.LED_COLOUR_RANGE,
"LED_COLOR_RANGE" : self.LED_COLOR_RANGE,
"LED_STATE_MAPPINGS" : self.LED_STATE_MAPPINGS
}
@ -463,7 +463,7 @@ def add_region():
"CONST_VALUE": const_value, # optional, str
"CONST_DATA": const_data # optional, int
}
region.LED_COLOUR_RANGE = []
region.LED_COLOR_RANGE = []
region.LED_STATE_MAPPINGS = []
@ -478,19 +478,19 @@ def add_region():
)
continue_input()
led_on_msg_type = mapping["led_config"]["led_on"]["msg_type"]
led_on_colour_value = mapping["led_config"]["led_on"]["colour_value"]
led_on_color_value = mapping["led_config"]["led_on"]["color_value"]
led_off_msg_type = mapping["led_config"]["led_off"]["msg_type"]
led_off_colour_data = mapping["led_config"]["led_off"]["colour_data"]
led_off_color_data = mapping["led_config"]["led_off"]["color_data"]
led_on_min_val = int_input(
between=PARAM_RANGES[led_on_colour_value],
msg=f"What is the {led_on_colour_value} for this region's first colour/state? NOT any number corresponding to LED OFF",
between=PARAM_RANGES[led_on_color_value],
msg=f"What is the {led_on_color_value} for this region's first color/state? NOT any number corresponding to LED OFF",
)
led_on_max_val = int_input(
between=PARAM_RANGES[led_on_colour_value],
msg=f"What is the {led_on_colour_value} for this region's last colour/state? If your buttons are full RGB, this could be as high as 127.",
between=PARAM_RANGES[led_on_color_value],
msg=f"What is the {led_on_color_value} for this region's last color/state? If your buttons are full RGB, this could be as high as 127.",
)
led_colour_range = range(led_on_min_val, led_on_max_val)
region.LED_COLOUR_RANGE = [led_colour_range.start, led_colour_range.stop] # range(min, max)
led_color_range = range(led_on_min_val, led_on_max_val)
region.LED_color_RANGE = [led_color_range.start, led_color_range.stop] # range(min, max)
region.LED_STATE_MAPPINGS = []
print(
@ -498,31 +498,31 @@ def add_region():
)
for i, x in enumerate(INPUT_VISUAL_STATES):
print(f"{i}. {x}")
print(f"You will assign an LED colour (or off) to each.")
print(f"You will assign an LED color (or off) to each.")
continue_input()
led_states = ["LED OFF", *(f"LED ON, colour # {v}" for v in range(led_on_min_val, led_on_max_val + 1))]
led_states = ["LED OFF", *(f"LED ON, color # {v}" for v in range(led_on_min_val, led_on_max_val + 1))]
for i, x in enumerate(INPUT_VISUAL_STATES):
while True:
colour = choose_from(
color = choose_from(
led_states,
return_idx=True,
msg=f"Which colour will be used for this input state?\n{i}. {x}",
msg=f"Which color will be used for this input state?\n{i}. {x}",
)
print(colour)
print(color)
for msg in region:
channel = msg.channel
position = getattr(msg, region.MIDI_INPUT["POSITION_VALUE"])
if colour == 0:
led_msg = mido.Message(led_off_msg_type, channel=channel, note=position, velocity=led_off_colour_data)
if color == 0:
led_msg = mido.Message(led_off_msg_type, channel=channel, note=position, velocity=led_off_color_data)
else:
led_msg = mido.Message(led_on_msg_type, channel=channel, note=position, velocity=colour)
led_msg = mido.Message(led_on_msg_type, channel=channel, note=position, velocity=color)
port.send(led_msg)
if yesno_input("Are you happy with this colour? To try a different colour, choose NO"):
if yesno_input("Are you happy with this color? To try a different color, choose NO"):
break
region.LED_STATE_MAPPINGS.append(colour)
region.LED_STATE_MAPPINGS.append(color)
return region
def configure_leds():
@ -551,7 +551,7 @@ def configure_leds():
)
mapping["led_config"] = False
return False
led_colour_value = "velocity"
led_color_value = "velocity"
led_on_msg_type = "note_on"
led_off_msg_type = choose_from(
MIDO_MESSAGE_TYPES,
@ -559,17 +559,17 @@ def configure_leds():
)
if led_off_msg_type == "note_on":
led_off_velocity = int_input(
between=PARAM_RANGES[led_colour_value],
msg=f"What {led_colour_value} would turn off the LED?",
between=PARAM_RANGES[led_color_value],
msg=f"What {led_color_value} would turn off the LED?",
)
else:
led_off_velocity = 0
mapping["led_config"] = {
"led_on": {"msg_type": "note_on", "colour_value": led_colour_value},
"led_on": {"msg_type": "note_on", "color_value": led_color_value},
"led_off": {
"msg_type": led_off_msg_type,
"colour_value": led_colour_value,
"colour_data": led_off_velocity
"color_value": led_color_value,
"color_data": led_off_velocity
},
}
return True