added conditions and transtions

This commit is contained in:
John Lancaster
2025-11-30 23:05:21 -06:00
parent 25892e1de8
commit b33016089f

View File

@@ -18,6 +18,13 @@ class StagedControlEvent(str, Enum):
DEACTIVATE = 'deactivate' DEACTIVATE = 'deactivate'
class StageCondition(str, Enum):
"""Enum to define the different types of conditions for an event"""
ANY_ON = 'any_on'
ALL_OFF = 'all_off'
class StagedLight(Hass): class StagedLight(Hass):
def initialize(self): def initialize(self):
self.set_log_level('DEBUG') self.set_log_level('DEBUG')
@@ -30,6 +37,10 @@ class StagedLight(Hass):
if self.args.get('activate-at-start', False): if self.args.get('activate-at-start', False):
self.activate() self.activate()
# self._check_transition()
self.schedule_transition_checks()
self.run_daily(self.schedule_transition_checks, start='00:00:00')
### Stages ### Stages
def _stage_starts(self) -> Generator[datetime]: def _stage_starts(self) -> Generator[datetime]:
@@ -56,38 +67,74 @@ class StagedLight(Hass):
def current_scene(self): def current_scene(self):
return self.current_stage().scene_json() return self.current_stage().scene_json()
### Transitions
def schedule_transition_checks(self, **kwargs: Any):
now = self.get_now()
for stage in self._stages:
dt = self.parse_datetime(stage.start, aware=True, today=True)
if dt > now:
self.log(f'Scehduling transition at: {dt.isoformat()}', level='DEBUG')
self.run_at(self._check_transition, start=dt)
def _check_transition(self, **kwargs: Any):
self.log('Firing transition event', level='DEBUG')
self.fire_event(
'stage_control',
app=self.name,
condition=StageCondition.ANY_ON,
action=StagedControlEvent.ACTIVATE,
)
### Events ### Events
def handle_event(self, event_type: str, data: dict[str, Any], **kwargs: Any) -> None: def handle_event(self, event_type: str, data: dict[str, Any], **kwargs: Any) -> None:
self.log(f'Event handler: {event_type}', level='DEBUG') self.log(f'Event handler: {event_type}', level='DEBUG')
stage = self.current_stage() stage = self.current_stage()
start_time_str = stage.formatted_start('%I:%M %p') scene = stage.scene_json()
match data:
case {'condition': StageCondition.ANY_ON}:
any_on = any(self.get_state(e) == 'on' for e in scene)
if not any_on:
self.log('Nothing is on, skipping', level='DEBUG')
return
case {'condition': StageCondition.ALL_OFF}:
all_off = all(self.get_state(e) == 'off' for e in scene)
if not all_off:
self.log('Everything is not off, skipping', level='DEBUG')
return
match data: match data:
case {'action': StagedControlEvent.ACTIVATE}: case {'action': StagedControlEvent.ACTIVATE}:
self.log(f'Activating current stage: {start_time_str}') self.activate(stage)
self.activate(scene=stage.scene_json())
case {'action': StagedControlEvent.DEACTIVATE}: case {'action': StagedControlEvent.DEACTIVATE}:
self.log(f'Deactivating current stage: {start_time_str}') self.deactivate(stage)
self.deactivate()
case _: case _:
self.log(str(data), level='DEBUG') self.log(str(data), level='DEBUG')
self.log(str(kwargs), level='DEBUG') self.log(str(kwargs), level='DEBUG')
### Actions ### Actions
def activate(self, scene: dict | None = None, **kwargs: Any): def activate(self, stage: Stage | None = None, **kwargs: Any):
if scene is None: if stage is None:
stage = self.current_stage() stage = self.current_stage()
kwargs['entities'] = stage.scene_json() kwargs['entities'] = stage.scene_json()
else: else:
kwargs['entities'] = scene kwargs['entities'] = stage.scene_json()
if t := self.args.get('transition'): if t := self.args.get('transition'):
kwargs['transition'] = t kwargs['transition'] = t
start_time_str = stage.formatted_start('%I:%M %p')
self.log(f'Activating current stage: {start_time_str}')
return self.call_service('scene/apply', **kwargs) return self.call_service('scene/apply', **kwargs)
def deactivate(self, stage: Stage | None = None, **kwargs): def deactivate(self, stage: Stage | None = None, **kwargs):
stage = stage if stage is not None else self.current_stage() stage = stage if stage is not None else self.current_stage()
start_time_str = stage.formatted_start('%I:%M %p')
self.log(f'Deactivating current stage: {start_time_str}')
for entity in stage.scene: for entity in stage.scene:
self.turn_off(entity) self.turn_off(entity)