67 lines
1.8 KiB
Python
67 lines
1.8 KiB
Python
"""Party animation – slow color drift + irregular beat pulses."""
|
||
|
||
from __future__ import annotations
|
||
|
||
import colorsys
|
||
import random
|
||
import time
|
||
|
||
from .base import Animation
|
||
|
||
|
||
class PartyAnimation(Animation):
|
||
name = "party"
|
||
interval = 0.10
|
||
|
||
def on_start(self) -> None:
|
||
super().on_start()
|
||
self._hue = 210.0 # start blue-ish
|
||
self._brightness = 35.0
|
||
self._direction = 1.0
|
||
self._pulse = 0.0
|
||
self._next_pulse = time.monotonic() + 1.2
|
||
self._next_color_jump = time.monotonic() + 2.5
|
||
|
||
def tick(self) -> None:
|
||
now = time.monotonic()
|
||
|
||
# slow hue drift (blue → cyan → violet → magenta → blue)
|
||
self._hue += 1.2
|
||
if self._hue >= 330:
|
||
self._hue = 210.0
|
||
|
||
# gentle base breathing
|
||
self._brightness += self._direction * 0.7
|
||
if self._brightness >= 55:
|
||
self._brightness = 55
|
||
self._direction = -1
|
||
if self._brightness <= 28:
|
||
self._brightness = 28
|
||
self._direction = 1
|
||
|
||
# irregular beat pulses
|
||
if now >= self._next_pulse:
|
||
self._pulse = 20
|
||
self._next_pulse = now + 0.6 + random.random() * 1.2
|
||
|
||
if self._pulse > 0:
|
||
self._brightness += self._pulse
|
||
self._pulse *= 0.65
|
||
|
||
brightness = max(20, min(80, self._brightness))
|
||
|
||
# occasional stronger color jump
|
||
if now >= self._next_color_jump:
|
||
self._hue += 25 + random.random() * 60
|
||
if self._hue >= 330:
|
||
self._hue = 210.0
|
||
self._next_color_jump = now + 1.8 + random.random() * 3.0
|
||
|
||
r, g, b = colorsys.hsv_to_rgb(self._hue / 360.0, 1.0, 1.0)
|
||
self.shelly.set_color(
|
||
int(r * 255),
|
||
int(g * 255),
|
||
int(b * 255),
|
||
gain=int(brightness),
|
||
)
|