WIP
This commit is contained in:
@@ -54,9 +54,9 @@ class ControllerStateConfig(BaseModel):
|
|||||||
@model_validator(mode='before')
|
@model_validator(mode='before')
|
||||||
def check_args(cls, values):
|
def check_args(cls, values):
|
||||||
time, elevation = values.get('time'), values.get('elevation')
|
time, elevation = values.get('time'), values.get('elevation')
|
||||||
if time is not None and elevation is not None:
|
# if time is not None and elevation is not None:
|
||||||
raise PydanticCustomError('bad_time_spec', 'Only one of time or elevation can be set.')
|
# raise PydanticCustomError('bad_time_spec', 'Only one of time or elevation can be set.')
|
||||||
elif elevation is not None and 'direction' not in values:
|
if elevation is not None and 'direction' not in values:
|
||||||
raise PydanticCustomError('no_sun_dir', 'Needs sun direction with elevation')
|
raise PydanticCustomError('no_sun_dir', 'Needs sun direction with elevation')
|
||||||
return values
|
return values
|
||||||
|
|
||||||
|
|||||||
@@ -54,39 +54,27 @@ class RoomController(Hass):
|
|||||||
self.register_service(f'{self.name}/activate', self.service_activate)
|
self.register_service(f'{self.name}/activate', self.service_activate)
|
||||||
self.register_service(f'{self.name}/deactivate', self.service_deactivate)
|
self.register_service(f'{self.name}/deactivate', self.service_deactivate)
|
||||||
|
|
||||||
self.app_entities = self.gather_app_entities()
|
|
||||||
# self.log(f'entities: {self.app_entities}')
|
|
||||||
|
|
||||||
self.refresh_state_times()
|
self.refresh_state_times()
|
||||||
self.run_daily(callback=self.refresh_state_times, start='00:00:00')
|
self.run_daily(callback=self.refresh_state_times, start='00:00:00')
|
||||||
|
|
||||||
|
self.app_entities = set(self.gather_app_entities())
|
||||||
|
self.log(f'entities: {self.app_entities}', level='DEBUG')
|
||||||
|
|
||||||
self.log(f'Initialized [bold green]{type(self).__name__}[/]')
|
self.log(f'Initialized [bold green]{type(self).__name__}[/]')
|
||||||
|
|
||||||
def terminate(self):
|
def terminate(self):
|
||||||
self.log('[bold red]Terminating[/]', level='DEBUG')
|
self.log('[bold red]Terminating[/]', level='DEBUG')
|
||||||
|
|
||||||
def gather_app_entities(self) -> List[str]:
|
def gather_app_entities(self):
|
||||||
"""Returns a list of all the entities involved in any of the states"""
|
"""Yields all the entities involved in any of the states"""
|
||||||
|
|
||||||
def generator():
|
for state in self._room_config.states:
|
||||||
for settings in deepcopy(self.args['states']):
|
if isinstance(state.scene, str):
|
||||||
if scene := settings.get('scene'):
|
assert state.scene.startswith('scene.'), "Scene definition must start with 'scene.'"
|
||||||
if isinstance(scene, str):
|
entities = self.get_state(state.scene, namespace='default', attribute='entity_id')
|
||||||
assert scene.startswith(
|
yield from entities
|
||||||
'scene.'
|
else:
|
||||||
), f"Scene definition must start with 'scene.' for app {self.name}"
|
yield from state.scene.keys()
|
||||||
entity: Entity = self.get_entity(scene)
|
|
||||||
entity_state = entity.get_state('all')
|
|
||||||
attributes = entity_state['attributes']
|
|
||||||
for entity in attributes['entity_id']:
|
|
||||||
yield entity
|
|
||||||
else:
|
|
||||||
for key in scene.keys():
|
|
||||||
yield key
|
|
||||||
else:
|
|
||||||
yield self.args['entity']
|
|
||||||
|
|
||||||
return set(list(generator()))
|
|
||||||
|
|
||||||
def refresh_state_times(self, *args, **kwargs):
|
def refresh_state_times(self, *args, **kwargs):
|
||||||
"""Resets the `self.states` attribute to a newly parsed version of the states.
|
"""Resets the `self.states` attribute to a newly parsed version of the states.
|
||||||
@@ -102,18 +90,18 @@ class RoomController(Hass):
|
|||||||
|
|
||||||
for state in self._room_config.states:
|
for state in self._room_config.states:
|
||||||
if state.time is None and state.elevation is not None:
|
if state.time is None and state.elevation is not None:
|
||||||
transition_time = self.time_at_elevation(
|
state.time = self.time_at_elevation(
|
||||||
elevation=state.elevation, direction=state.direction
|
elevation=state.elevation, direction=state.direction
|
||||||
).time()
|
).time()
|
||||||
elif isinstance(state.time, str):
|
elif isinstance(state.time, str):
|
||||||
transition_time = self.parse_time(state.time)
|
state.time = self.parse_time(state.time)
|
||||||
|
|
||||||
assert isinstance(state.time, datetime.time), f'Invalid time: {state.time}'
|
assert isinstance(state.time, datetime.time), f'Invalid time: {state.time}'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.run_at(
|
self.run_at(
|
||||||
callback=lambda cb_args: self.set_controller_scene(cb_args['state']),
|
callback=lambda cb_args: self.set_controller_scene(cb_args['state']),
|
||||||
start=transition_time.strftime('%H:%M:%S'),
|
start=state.time.strftime('%H:%M:%S'),
|
||||||
state=state,
|
state=state,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user