Remove per-source speed, fix device dirty check, and add frontend caching
Speed is now exclusively controlled via sync clocks — CSS sources no longer carry their own speed/cycle_speed fields. Streams default to 1.0× when no clock is assigned. Also fixes false-positive dirty check on the device settings modal (array reference comparison) and converts several frontend modules to use DataCache for consistent API response caching. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -69,7 +69,6 @@ class ColorStripSource:
|
||||
"stops": None,
|
||||
"animation": None,
|
||||
"colors": None,
|
||||
"cycle_speed": None,
|
||||
"effect_type": None,
|
||||
"palette": None,
|
||||
"intensity": None,
|
||||
@@ -149,7 +148,6 @@ class ColorStripSource:
|
||||
id=sid, name=name, source_type="color_cycle",
|
||||
created_at=created_at, updated_at=updated_at, description=description,
|
||||
clock_id=clock_id, colors=colors,
|
||||
cycle_speed=float(data.get("cycle_speed") or 1.0),
|
||||
led_count=data.get("led_count") or 0,
|
||||
)
|
||||
|
||||
@@ -198,7 +196,6 @@ class ColorStripSource:
|
||||
id=sid, name=name, source_type="effect",
|
||||
created_at=created_at, updated_at=updated_at, description=description,
|
||||
clock_id=clock_id, effect_type=data.get("effect_type") or "fire",
|
||||
speed=float(data.get("speed") or 1.0),
|
||||
led_count=data.get("led_count") or 0,
|
||||
palette=data.get("palette") or "fire",
|
||||
color=color,
|
||||
@@ -340,13 +337,11 @@ class ColorCycleColorStripSource(ColorStripSource):
|
||||
[255, 0, 0], [255, 255, 0], [0, 255, 0],
|
||||
[0, 255, 255], [0, 0, 255], [255, 0, 255],
|
||||
])
|
||||
cycle_speed: float = 1.0 # speed multiplier; 1.0 ≈ one full cycle every 20 seconds
|
||||
led_count: int = 0 # 0 = use device LED count
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
d = super().to_dict()
|
||||
d["colors"] = [list(c) for c in self.colors]
|
||||
d["cycle_speed"] = self.cycle_speed
|
||||
d["led_count"] = self.led_count
|
||||
return d
|
||||
|
||||
@@ -361,7 +356,6 @@ class EffectColorStripSource(ColorStripSource):
|
||||
"""
|
||||
|
||||
effect_type: str = "fire" # fire | meteor | plasma | noise | aurora
|
||||
speed: float = 1.0 # animation speed multiplier (0.1–10.0)
|
||||
led_count: int = 0 # 0 = use device LED count
|
||||
palette: str = "fire" # named color palette
|
||||
color: list = field(default_factory=lambda: [255, 80, 0]) # [R,G,B] for meteor head
|
||||
@@ -372,7 +366,6 @@ class EffectColorStripSource(ColorStripSource):
|
||||
def to_dict(self) -> dict:
|
||||
d = super().to_dict()
|
||||
d["effect_type"] = self.effect_type
|
||||
d["speed"] = self.speed
|
||||
d["led_count"] = self.led_count
|
||||
d["palette"] = self.palette
|
||||
d["color"] = list(self.color)
|
||||
|
||||
@@ -106,9 +106,7 @@ class ColorStripStore:
|
||||
frame_interpolation: bool = False,
|
||||
animation: Optional[dict] = None,
|
||||
colors: Optional[list] = None,
|
||||
cycle_speed: float = 1.0,
|
||||
effect_type: str = "fire",
|
||||
speed: float = 1.0,
|
||||
palette: str = "fire",
|
||||
intensity: float = 1.0,
|
||||
scale: float = 1.0,
|
||||
@@ -182,7 +180,6 @@ class ColorStripStore:
|
||||
description=description,
|
||||
clock_id=clock_id,
|
||||
colors=colors if isinstance(colors, list) and len(colors) >= 2 else default_colors,
|
||||
cycle_speed=float(cycle_speed) if cycle_speed else 1.0,
|
||||
led_count=led_count,
|
||||
)
|
||||
elif source_type == "effect":
|
||||
@@ -196,7 +193,6 @@ class ColorStripStore:
|
||||
description=description,
|
||||
clock_id=clock_id,
|
||||
effect_type=effect_type or "fire",
|
||||
speed=float(speed) if speed else 1.0,
|
||||
led_count=led_count,
|
||||
palette=palette or "fire",
|
||||
color=rgb,
|
||||
@@ -311,9 +307,7 @@ class ColorStripStore:
|
||||
frame_interpolation: Optional[bool] = None,
|
||||
animation: Optional[dict] = None,
|
||||
colors: Optional[list] = None,
|
||||
cycle_speed: Optional[float] = None,
|
||||
effect_type: Optional[str] = None,
|
||||
speed: Optional[float] = None,
|
||||
palette: Optional[str] = None,
|
||||
intensity: Optional[float] = None,
|
||||
scale: Optional[float] = None,
|
||||
@@ -389,15 +383,11 @@ class ColorStripStore:
|
||||
elif isinstance(source, ColorCycleColorStripSource):
|
||||
if colors is not None and isinstance(colors, list) and len(colors) >= 2:
|
||||
source.colors = colors
|
||||
if cycle_speed is not None:
|
||||
source.cycle_speed = float(cycle_speed)
|
||||
if led_count is not None:
|
||||
source.led_count = led_count
|
||||
elif isinstance(source, EffectColorStripSource):
|
||||
if effect_type is not None:
|
||||
source.effect_type = effect_type
|
||||
if speed is not None:
|
||||
source.speed = float(speed)
|
||||
if led_count is not None:
|
||||
source.led_count = led_count
|
||||
if palette is not None:
|
||||
|
||||
Reference in New Issue
Block a user