"""Automation storage using SQLite.""" import uuid from datetime import datetime, timezone from typing import List, Optional from wled_controller.storage.automation import Automation, Rule from wled_controller.storage.base_sqlite_store import BaseSqliteStore from wled_controller.storage.database import Database from wled_controller.utils import get_logger logger = get_logger(__name__) class AutomationStore(BaseSqliteStore[Automation]): _table_name = "automations" _entity_name = "Automation" def __init__(self, db: Database): super().__init__(db, Automation.from_dict) # Backward-compatible aliases get_all_automations = BaseSqliteStore.get_all get_automation = BaseSqliteStore.get delete_automation = BaseSqliteStore.delete def create_automation( self, name: str, enabled: bool = True, rule_logic: str = "or", rules: Optional[List[Rule]] = None, scene_preset_id: Optional[str] = None, deactivation_mode: str = "none", deactivation_scene_preset_id: Optional[str] = None, tags: Optional[List[str]] = None, # Legacy parameter aliases condition_logic: Optional[str] = None, conditions: Optional[List[Rule]] = None, ) -> Automation: # Support legacy parameter names if condition_logic is not None and rule_logic == "or": rule_logic = condition_logic if conditions is not None and rules is None: rules = conditions for a in self._items.values(): if a.name == name: raise ValueError(f"Automation with name '{name}' already exists") automation_id = f"auto_{uuid.uuid4().hex[:8]}" now = datetime.now(timezone.utc) automation = Automation( id=automation_id, name=name, enabled=enabled, rule_logic=rule_logic, rules=rules or [], scene_preset_id=scene_preset_id, deactivation_mode=deactivation_mode, deactivation_scene_preset_id=deactivation_scene_preset_id, created_at=now, updated_at=now, tags=tags or [], ) self._items[automation_id] = automation self._save_item(automation_id, automation) logger.info(f"Created automation: {name} ({automation_id})") return automation def update_automation( self, automation_id: str, name: Optional[str] = None, enabled: Optional[bool] = None, rule_logic: Optional[str] = None, rules: Optional[List[Rule]] = None, scene_preset_id: str = "__unset__", deactivation_mode: Optional[str] = None, deactivation_scene_preset_id: str = "__unset__", tags: Optional[List[str]] = None, # Legacy parameter aliases condition_logic: Optional[str] = None, conditions: Optional[List[Rule]] = None, ) -> Automation: # Support legacy parameter names if condition_logic is not None and rule_logic is None: rule_logic = condition_logic if conditions is not None and rules is None: rules = conditions automation = self.get(automation_id) if name is not None: self._check_name_unique(name, exclude_id=automation_id) automation.name = name if enabled is not None: automation.enabled = enabled if rule_logic is not None: automation.rule_logic = rule_logic if rules is not None: automation.rules = rules if scene_preset_id != "__unset__": automation.scene_preset_id = None if scene_preset_id == "" else scene_preset_id if deactivation_mode is not None: automation.deactivation_mode = deactivation_mode if deactivation_scene_preset_id != "__unset__": automation.deactivation_scene_preset_id = ( None if deactivation_scene_preset_id == "" else deactivation_scene_preset_id ) if tags is not None: automation.tags = tags automation.updated_at = datetime.now(timezone.utc) self._save_item(automation_id, automation) logger.info(f"Updated automation: {automation_id}") return automation