49 lines
1.2 KiB
Python
49 lines
1.2 KiB
Python
"""Warm evening / chill breathing animation."""
|
||
|
||
from __future__ import annotations
|
||
|
||
import colorsys
|
||
import math
|
||
|
||
from .base import Animation
|
||
|
||
|
||
class ChillAnimation(Animation):
|
||
name = "chill"
|
||
interval = 0.12
|
||
|
||
# Warm hues (0–1 range for colorsys)
|
||
COLORS = [
|
||
(15 / 360, 1.0), # warm red-orange
|
||
(25 / 360, 0.95), # orange
|
||
(35 / 360, 0.90), # amber
|
||
(45 / 360, 0.85), # golden
|
||
(30 / 360, 1.0), # deep orange
|
||
(10 / 360, 1.0), # deep red
|
||
]
|
||
|
||
def on_start(self) -> None:
|
||
super().on_start()
|
||
self._phase = 0.0
|
||
self._color_idx = 0
|
||
|
||
def tick(self) -> None:
|
||
self._phase += 0.08
|
||
brightness = 40 + math.sin(self._phase) * 18 # ~22–58
|
||
brightness = max(20, min(70, brightness))
|
||
|
||
if self._phase >= math.pi * 2:
|
||
self._phase = 0.0
|
||
self._color_idx = (self._color_idx + 1) % len(self.COLORS)
|
||
|
||
h, s = self.COLORS[self._color_idx]
|
||
r, g, b = colorsys.hsv_to_rgb(h, s, 1.0)
|
||
gain = int(brightness)
|
||
|
||
self.shelly.set_color(
|
||
int(r * 255),
|
||
int(g * 255),
|
||
int(b * 255),
|
||
gain=gain,
|
||
)
|