fddbd771f2
- Add `startup` automation condition type that activates on server boot, replacing the per-target `auto_start` flag - Remove `auto_start` field from targets, scene snapshots, and all API layers - Remove auto-start UI section and star buttons from dashboard and target cards - Remove `color` field from scene presets (backend, API, modal, frontend) - Add card color support to scene preset cards (color picker + border style) - Show localStorage-backed card colors on all dashboard cards (targets, automations, sync clocks, scene presets) - Fix card color picker updating wrong card when duplicate data attributes exist by using closest() from picker wrapper instead of global querySelector - Add sync clocks step to Sources tab tutorial - Bump SW cache v9 → v10 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
72 lines
2.3 KiB
Python
72 lines
2.3 KiB
Python
"""Scene preset data models — snapshot of target state."""
|
|
|
|
from dataclasses import dataclass, field
|
|
from datetime import datetime
|
|
from typing import List
|
|
|
|
|
|
@dataclass
|
|
class TargetSnapshot:
|
|
"""Snapshot of a single target's mutable state."""
|
|
|
|
target_id: str
|
|
running: bool = False
|
|
color_strip_source_id: str = ""
|
|
brightness_value_source_id: str = ""
|
|
fps: int = 30
|
|
|
|
def to_dict(self) -> dict:
|
|
return {
|
|
"target_id": self.target_id,
|
|
"running": self.running,
|
|
"color_strip_source_id": self.color_strip_source_id,
|
|
"brightness_value_source_id": self.brightness_value_source_id,
|
|
"fps": self.fps,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: dict) -> "TargetSnapshot":
|
|
return cls(
|
|
target_id=data["target_id"],
|
|
running=data.get("running", False),
|
|
color_strip_source_id=data.get("color_strip_source_id", ""),
|
|
brightness_value_source_id=data.get("brightness_value_source_id", ""),
|
|
fps=data.get("fps", 30),
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class ScenePreset:
|
|
"""A named snapshot of target state that can be restored."""
|
|
|
|
id: str
|
|
name: str
|
|
description: str = ""
|
|
targets: List[TargetSnapshot] = field(default_factory=list)
|
|
order: int = 0
|
|
created_at: datetime = field(default_factory=datetime.utcnow)
|
|
updated_at: datetime = field(default_factory=datetime.utcnow)
|
|
|
|
def to_dict(self) -> dict:
|
|
return {
|
|
"id": self.id,
|
|
"name": self.name,
|
|
"description": self.description,
|
|
"targets": [t.to_dict() for t in self.targets],
|
|
"order": self.order,
|
|
"created_at": self.created_at.isoformat(),
|
|
"updated_at": self.updated_at.isoformat(),
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: dict) -> "ScenePreset":
|
|
return cls(
|
|
id=data["id"],
|
|
name=data["name"],
|
|
description=data.get("description", ""),
|
|
targets=[TargetSnapshot.from_dict(t) for t in data.get("targets", [])],
|
|
order=data.get("order", 0),
|
|
created_at=datetime.fromisoformat(data.get("created_at", datetime.utcnow().isoformat())),
|
|
updated_at=datetime.fromisoformat(data.get("updated_at", datetime.utcnow().isoformat())),
|
|
)
|