Add auto-start targets feature with dashboard section
- Add auto_start boolean field to PictureTarget model (persisted per-target) - Wire auto_start through API schemas, routes, and store - Auto-start targets on server boot in main.py lifespan - Add star toggle button on target cards (next to delete button) - Add auto-start section on dashboard between performance and profiles - Remove auto-start section from profiles tab Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -100,9 +100,9 @@ class KeyColorsPictureTarget(PictureTarget):
|
||||
|
||||
def update_fields(self, *, name=None, device_id=None, picture_source_id=None,
|
||||
settings=None, key_colors_settings=None, description=None,
|
||||
**_kwargs) -> None:
|
||||
auto_start=None, **_kwargs) -> None:
|
||||
"""Apply mutable field updates for KC targets."""
|
||||
super().update_fields(name=name, description=description)
|
||||
super().update_fields(name=name, description=description, auto_start=auto_start)
|
||||
if picture_source_id is not None:
|
||||
self.picture_source_id = picture_source_id
|
||||
if key_colors_settings is not None:
|
||||
@@ -130,6 +130,7 @@ class KeyColorsPictureTarget(PictureTarget):
|
||||
picture_source_id=data.get("picture_source_id", ""),
|
||||
settings=settings,
|
||||
description=data.get("description"),
|
||||
auto_start=data.get("auto_start", False),
|
||||
created_at=datetime.fromisoformat(data.get("created_at", datetime.utcnow().isoformat())),
|
||||
updated_at=datetime.fromisoformat(data.get("updated_at", datetime.utcnow().isoformat())),
|
||||
)
|
||||
|
||||
@@ -15,6 +15,7 @@ class PictureTarget:
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
description: Optional[str] = None
|
||||
auto_start: bool = False
|
||||
|
||||
def register_with_manager(self, manager) -> None:
|
||||
"""Register this target with the processor manager. Subclasses override."""
|
||||
@@ -25,12 +26,15 @@ class PictureTarget:
|
||||
pass
|
||||
|
||||
def update_fields(self, *, name=None, device_id=None, picture_source_id=None,
|
||||
settings=None, key_colors_settings=None, description=None) -> None:
|
||||
settings=None, key_colors_settings=None, description=None,
|
||||
auto_start=None) -> None:
|
||||
"""Apply mutable field updates. Base handles common fields; subclasses handle type-specific ones."""
|
||||
if name is not None:
|
||||
self.name = name
|
||||
if description is not None:
|
||||
self.description = description
|
||||
if auto_start is not None:
|
||||
self.auto_start = auto_start
|
||||
|
||||
@property
|
||||
def has_picture_source(self) -> bool:
|
||||
@@ -44,6 +48,7 @@ class PictureTarget:
|
||||
"name": self.name,
|
||||
"target_type": self.target_type,
|
||||
"description": self.description,
|
||||
"auto_start": self.auto_start,
|
||||
"created_at": self.created_at.isoformat(),
|
||||
"updated_at": self.updated_at.isoformat(),
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@ class PictureTargetStore:
|
||||
key_colors_settings: Optional[KeyColorsSettings] = None,
|
||||
description: Optional[str] = None,
|
||||
picture_source_id: str = "",
|
||||
auto_start: bool = False,
|
||||
) -> PictureTarget:
|
||||
"""Create a new picture target.
|
||||
|
||||
@@ -138,6 +139,7 @@ class PictureTargetStore:
|
||||
keepalive_interval=keepalive_interval,
|
||||
state_check_interval=state_check_interval,
|
||||
description=description,
|
||||
auto_start=auto_start,
|
||||
created_at=now,
|
||||
updated_at=now,
|
||||
)
|
||||
@@ -149,6 +151,7 @@ class PictureTargetStore:
|
||||
picture_source_id=picture_source_id,
|
||||
settings=key_colors_settings or KeyColorsSettings(),
|
||||
description=description,
|
||||
auto_start=auto_start,
|
||||
created_at=now,
|
||||
updated_at=now,
|
||||
)
|
||||
@@ -173,6 +176,7 @@ class PictureTargetStore:
|
||||
state_check_interval: Optional[int] = None,
|
||||
key_colors_settings: Optional[KeyColorsSettings] = None,
|
||||
description: Optional[str] = None,
|
||||
auto_start: Optional[bool] = None,
|
||||
) -> PictureTarget:
|
||||
"""Update a picture target.
|
||||
|
||||
@@ -200,6 +204,7 @@ class PictureTargetStore:
|
||||
state_check_interval=state_check_interval,
|
||||
key_colors_settings=key_colors_settings,
|
||||
description=description,
|
||||
auto_start=auto_start,
|
||||
)
|
||||
|
||||
target.updated_at = datetime.utcnow()
|
||||
|
||||
@@ -54,9 +54,9 @@ class WledPictureTarget(PictureTarget):
|
||||
def update_fields(self, *, name=None, device_id=None, color_strip_source_id=None,
|
||||
brightness_value_source_id=None,
|
||||
fps=None, keepalive_interval=None, state_check_interval=None,
|
||||
description=None, **_kwargs) -> None:
|
||||
description=None, auto_start=None, **_kwargs) -> None:
|
||||
"""Apply mutable field updates for WLED targets."""
|
||||
super().update_fields(name=name, description=description)
|
||||
super().update_fields(name=name, description=description, auto_start=auto_start)
|
||||
if device_id is not None:
|
||||
self.device_id = device_id
|
||||
if color_strip_source_id is not None:
|
||||
@@ -109,6 +109,7 @@ class WledPictureTarget(PictureTarget):
|
||||
keepalive_interval=data.get("keepalive_interval", data.get("standby_interval", 1.0)),
|
||||
state_check_interval=data.get("state_check_interval", DEFAULT_STATE_CHECK_INTERVAL),
|
||||
description=data.get("description"),
|
||||
auto_start=data.get("auto_start", False),
|
||||
created_at=datetime.fromisoformat(data.get("created_at", datetime.utcnow().isoformat())),
|
||||
updated_at=datetime.fromisoformat(data.get("updated_at", datetime.utcnow().isoformat())),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user