Skip to content

Commit

Permalink
Mega cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
meowmeowahr committed Feb 19, 2024
1 parent b1339a8 commit a2e9530
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 61 deletions.
92 changes: 34 additions & 58 deletions animator/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
import neopixel

import animator.light_funcs as light_funcs
from animator.light_funcs import square_wave
from animator.light_funcs import rindex
from animator.light_funcs import mix_colors

COLORS = [
(255, 0, 0), # Red
Expand All @@ -22,6 +25,7 @@

@dataclass
class AnimationState:
"State of animations and neopixels"
state: str = "OFF"
color: tuple = (255, 255, 255)
effect: str = "SingleColor"
Expand All @@ -30,11 +34,13 @@ class AnimationState:

@dataclass
class SingleColorArgs:
"Single Color mode options"
color: tuple = (255, 0, 0)


@dataclass
class FadeArgs:
"Fade Animation options"
colora: tuple = (255, 0, 0)
colorb: tuple = (0, 0, 0)

Expand Down Expand Up @@ -65,15 +71,23 @@ class AnimationArgs:


# Set the desired FPS for your animation
slow_fps = 5
basic_fps = 30
regular_fps = 45
fast_fps = 60
ufast_fps = 120
SLOW_FPS = 5
BASIC_FPS = 30
REGULAR_FPS = 45
FAST_FPS = 60
UFAST_FPS = 120


# Animation-specific functions
def generate_color_pattern(length):
def generate_color_pattern(length: int) -> list:
"""Generate list of colors for ColoredLights animation
Args:
length (int): Length of output
Returns:
list: Output
"""
colors = [
(255, 0, 0), # Red
(0, 255, 0), # Green
Expand All @@ -90,46 +104,8 @@ def generate_color_pattern(length):
return pattern[:length]


def mix_colors(color1, color2, position):
"""
Mix two RGB colors based on a position value.
Parameters:
- color1: Tuple representing the first RGB color (e.g., (255, 0, 0) for red).
- color2: Tuple representing the second RGB color.
- position: A value between 0 and 1 indicating the position between the two colors.
Returns:
- A tuple representing the resulting mixed color.
"""
mixed_color = tuple(
int((1 - position) * c1 + position * c2) for c1, c2 in zip(color1, color2)
)
return mixed_color


def rindex(lst, value):
lst.reverse()
try:
i = lst.index(value)
except ValueError:
return None
lst.reverse()
return len(lst) - i - 1


def square_wave(t, period, amplitude):
# Calculate the remainder when t is divided by T
remainder = t % period

# Determine the value of the square wave based on the remainder
if remainder < period / 2:
return amplitude
else:
return -amplitude


class Animator:
"""NeoPixel Animation class"""
def __init__(
self,
pixels: neopixel.NeoPixel,
Expand Down Expand Up @@ -168,7 +144,7 @@ def cycle(self) -> None:
):
self.pixels.fill(self.animation_args.single_color.color)
self.pixels.brightness = self.animation_state.brightness / 255.0
time.sleep(1 / basic_fps)
time.sleep(1 / BASIC_FPS)
elif (
self.animation_state.effect == "Rainbow"
and self.animation_state.state == "ON"
Expand All @@ -177,7 +153,7 @@ def cycle(self) -> None:
pixel_index = (i * 256 // self.num_pixels) + self.animation_step
self.pixels[i] = light_funcs.wheel(pixel_index & 255)
self.pixels.brightness = self.animation_state.brightness / 255.0
time.sleep(1 / fast_fps)
time.sleep(1 / FAST_FPS)
elif (
self.animation_state.effect == "GlitterRainbow"
and self.animation_state.state == "ON"
Expand All @@ -188,14 +164,14 @@ def cycle(self) -> None:
self.pixels.brightness = self.animation_state.brightness / 255.0
led = random.randint(0, self.num_pixels - 1)
self.pixels[led] = (255, 255, 255)
time.sleep(1 / fast_fps)
time.sleep(1 / FAST_FPS)
elif (
self.animation_state.effect == "Colorloop"
and self.animation_state.state == "ON"
):
self.pixels.fill(light_funcs.wheel(self.animation_step))
self.pixels.brightness = self.animation_state.brightness / 255.0
time.sleep(1 / fast_fps)
time.sleep(1 / FAST_FPS)
elif (
self.animation_state.effect == "Magic"
and self.animation_state.state == "ON"
Expand All @@ -207,7 +183,7 @@ def cycle(self) -> None:
color = light_funcs.map_range(color, -1, 1, 120, 200)
self.pixels[i] = light_funcs.wheel(int(color) & 255)
self.pixels.brightness = self.animation_state.brightness / 255.0
time.sleep(1 / basic_fps)
time.sleep(1 / BASIC_FPS)
elif (
self.animation_state.effect == "Fire" and self.animation_state.state == "ON"
):
Expand All @@ -218,15 +194,15 @@ def cycle(self) -> None:
color = light_funcs.map_range(color, -1, 1, 70, 85)
self.pixels[i] = light_funcs.wheel(int(color) & 255)
self.pixels.brightness = self.animation_state.brightness / 255.0
time.sleep(1 / regular_fps)
time.sleep(1 / REGULAR_FPS)
elif (
self.animation_state.effect == "ColoredLights"
and self.animation_state.state == "ON"
):
for index, color in enumerate(generate_color_pattern(self.num_pixels)):
self.pixels[index - 1] = color
self.pixels.brightness = self.animation_state.brightness / 255.0
time.sleep(1 / basic_fps)
time.sleep(1 / BASIC_FPS)
elif (
self.animation_state.effect == "Fade" and self.animation_state.state == "ON"
):
Expand All @@ -241,7 +217,7 @@ def cycle(self) -> None:
)
self.pixels.show()
self.pixels.brightness = self.animation_state.brightness / 255.0
time.sleep(1 / fast_fps)
time.sleep(1 / FAST_FPS)
elif (
self.animation_state.effect == "Flash"
and self.animation_state.state == "ON"
Expand All @@ -255,7 +231,7 @@ def cycle(self) -> None:
self.pixels.fill(self.animation_args.flash.colorb)

self.pixels.brightness = self.animation_state.brightness / 255.0
time.sleep(1 / basic_fps)
time.sleep(1 / BASIC_FPS)
elif (
self.animation_state.effect == "Wipe" and self.animation_state.state == "ON"
):
Expand Down Expand Up @@ -284,7 +260,7 @@ def cycle(self) -> None:
self.pixels[last_pixel + 1] = self.animation_args.wipe.colorb

self.pixels.brightness = self.animation_state.brightness / 255.0
time.sleep(1 / fast_fps)
time.sleep(1 / FAST_FPS)
elif (
self.animation_state.effect == "Random"
and self.animation_state.state == "ON"
Expand All @@ -295,7 +271,7 @@ def cycle(self) -> None:
)

self.pixels.brightness = self.animation_state.brightness / 255.0
time.sleep(1 / slow_fps)
time.sleep(1 / SLOW_FPS)
elif (
self.animation_state.effect == "RandomColor"
and self.animation_state.state == "ON"
Expand All @@ -304,11 +280,11 @@ def cycle(self) -> None:
self.pixels[i] = COLORS[random.randint(0, 5)]

self.pixels.brightness = self.animation_state.brightness / 255.0
time.sleep(1 / slow_fps)
time.sleep(1 / SLOW_FPS)
else: # off state / animation unknown
self.pixels.fill((0, 0, 0))
self.pixels.brightness = 0.0
time.sleep(1 / basic_fps)
time.sleep(1 / BASIC_FPS)

self.pixels.show()
self.animation_step += 1
Expand Down
58 changes: 58 additions & 0 deletions animator/light_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,61 @@ def wheel(pos: float) -> tuple:
g = int(pos * 3)
b = int(255 - pos * 3)
return (r, g, b)


def square_wave(t, period, amplitude):
"""Generate square wave
Args:
t (float): X input
period (float): Period of square wave
amplitude (float): Amplitude of wave
Returns:
float: Y output
"""
# Calculate the remainder when t is divided by T
remainder = t % period

# Determine the value of the square wave based on the remainder
if remainder < period / 2:
return amplitude
else:
return -amplitude


def rindex(lst: list, value: any) -> int:
"""Get last occurrence of object in list
Args:
lst (list): List to search
value (any): obect to find last occurrence of
Returns:
int: Last index
"""
lst.reverse()
try:
i = lst.index(value)
except ValueError:
return None
lst.reverse()
return len(lst) - i - 1


def mix_colors(color1, color2, position):
"""
Mix two RGB colors based on a position value.
Parameters:
- color1: Tuple representing the first RGB color (e.g., (255, 0, 0) for red).
- color2: Tuple representing the second RGB color.
- position: A value between 0 and 1 indicating the position between the two colors.
Returns:
- A tuple representing the resulting mixed color.
"""
mixed_color = tuple(
int((1 - position) * c1 + position * c2) for c1, c2 in zip(color1, color2)
)
return mixed_color
6 changes: 3 additions & 3 deletions mqtt_animator.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@
animator = animator.Animator(pixels, num_pixels, animation_state, animation_args)


def on_connect(cli, userdata, flags, rc):
def on_connect(_, __, ___, rc):
"On disconnection of mqtt"
if rc == 0:
logging.info("MQTT Connection Success")
else:
logging.critical("Failed to connect, return code %d\n", rc)


def on_disconnect(cli, userdata, rc):
def on_disconnect(cli, _, rc):
"On connection of mqtt"
logging.info("Disconnected with result code: %s", rc)
reconnect_count, reconnect_delay = 0, first_reconnect_delay
Expand All @@ -99,7 +99,7 @@ def on_disconnect(cli, userdata, rc):
) # Set Connecting Client ID


def on_message(cli, userdata, msg):
def on_message(_, __, msg):
"Callback for mqtt message recieved"
print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")

Expand Down

0 comments on commit a2e9530

Please sign in to comment.