Simplify scenes to capture only target state, add target selector

- Remove DeviceBrightnessSnapshot and AutomationSnapshot from scene data model
- Simplify capture_current_snapshot and apply_scene_state to targets only
- Remove device/automation dependencies from scene preset API routes
- Add target selector (combobox + add/remove) to scene capture modal
- Fix stale profiles reference bug in scene_preset_store recapture
- Update automation engine call sites for simplified scene functions
- Sync scene presets cache between automations and scene-presets modules

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-28 18:55:11 +03:00
parent 0eb0f44ddb
commit ff4e7f8adb
14 changed files with 157 additions and 204 deletions

View File

@@ -1,8 +1,8 @@
"""Scene preset data models — snapshot of current system state."""
"""Scene preset data models — snapshot of target state."""
from dataclasses import dataclass, field
from datetime import datetime
from typing import Dict, List, Optional
from typing import List
@dataclass
@@ -38,59 +38,15 @@ class TargetSnapshot:
)
@dataclass
class DeviceBrightnessSnapshot:
"""Snapshot of a device's software brightness."""
device_id: str
software_brightness: int = 255
def to_dict(self) -> dict:
return {
"device_id": self.device_id,
"software_brightness": self.software_brightness,
}
@classmethod
def from_dict(cls, data: dict) -> "DeviceBrightnessSnapshot":
return cls(
device_id=data["device_id"],
software_brightness=data.get("software_brightness", 255),
)
@dataclass
class AutomationSnapshot:
"""Snapshot of an automation's enabled state."""
automation_id: str
enabled: bool = True
def to_dict(self) -> dict:
return {
"automation_id": self.automation_id,
"enabled": self.enabled,
}
@classmethod
def from_dict(cls, data: dict) -> "AutomationSnapshot":
return cls(
automation_id=data.get("automation_id", ""),
enabled=data.get("enabled", True),
)
@dataclass
class ScenePreset:
"""A named snapshot of system state that can be restored."""
"""A named snapshot of target state that can be restored."""
id: str
name: str
description: str = ""
color: str = "#4fc3f7" # accent color for the card
targets: List[TargetSnapshot] = field(default_factory=list)
devices: List[DeviceBrightnessSnapshot] = field(default_factory=list)
automations: List[AutomationSnapshot] = field(default_factory=list)
order: int = 0
created_at: datetime = field(default_factory=datetime.utcnow)
updated_at: datetime = field(default_factory=datetime.utcnow)
@@ -102,8 +58,6 @@ class ScenePreset:
"description": self.description,
"color": self.color,
"targets": [t.to_dict() for t in self.targets],
"devices": [d.to_dict() for d in self.devices],
"automations": [a.to_dict() for a in self.automations],
"order": self.order,
"created_at": self.created_at.isoformat(),
"updated_at": self.updated_at.isoformat(),
@@ -117,8 +71,6 @@ class ScenePreset:
description=data.get("description", ""),
color=data.get("color", "#4fc3f7"),
targets=[TargetSnapshot.from_dict(t) for t in data.get("targets", [])],
devices=[DeviceBrightnessSnapshot.from_dict(d) for d in data.get("devices", [])],
automations=[AutomationSnapshot.from_dict(a) for a in data.get("automations", [])],
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())),

View File

@@ -115,8 +115,6 @@ class ScenePresetStore:
existing = self._presets[preset_id]
existing.targets = preset.targets
existing.devices = preset.devices
existing.profiles = preset.profiles
existing.updated_at = datetime.utcnow()
self._save()
logger.info(f"Recaptured scene preset: {preset_id}")