hopefully simplified the state change callbacks

This commit is contained in:
John Lancaster
2023-04-23 23:40:45 -05:00
parent cf528c5252
commit 97a6da6815

View File

@@ -1,5 +1,6 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from datetime import datetime, timedelta from datetime import datetime, timedelta
import logging
from typing import List from typing import List
from appdaemon.entity import Entity from appdaemon.entity import Entity
@@ -184,46 +185,45 @@ class ControllerDaylight(Hass):
# self.log(self.adjuster) # self.log(self.adjuster)
self.listen_state(callback=self.handle_state_change, self.listen_state(callback=self.handle_state_change,
entity_id=[e.entity_id for e in self.entities]) entity_id=[e.entity_id for e in self.entities],
# self.listen_state(callback=self.handle_brightness_change, attribute='brightness')
# entity_id=[e.entity_id for e in self.entities], self.listen_state(callback=self.handle_state_change,
# attribute='brightness') entity_id=[e.entity_id for e in self.entities],
# self.listen_state(callback=self.handle_brightness_change, attribute='color_temp')
# entity_id=[e.entity_id for e in self.entities],
# attribute='color_temp')
ents = [e.friendly_name for e in self.entities] ents = [e.friendly_name for e in self.entities]
if len(ents) > 1: if len(ents) > 1:
ents[-1] = f'and {ents[-1]}' ents[-1] = f'and {ents[-1]}'
delim = ', ' if len(ents) >= 3 else ' ' delim = ', ' if len(ents) >= 3 else ' '
self.log(f'Listening for state changes on {delim.join(ents)}') self.log(f'Listening for state changes on {delim.join(ents)}')
self.run_every(callback=self.update_sensors, start='now', interval=5.0) self.run_every(
callback=self.update_sensors,
start='now',
interval=self.args.get('interval', 5)
)
for entity in self.entities: for entity in self.entities:
if entity.get_state() == 'on': self.run_every(
self.start_adjustments(entity.entity_id) callback=self.ongoing_adjustment,
start='now',
interval=self.args.get('interval', 5),
entity=entity
)
if (entity_name := self.args.get('enable')) is not None: if (entity_name := self.args.get('enable')) is not None:
self.enable_entity: Entity = self.get_entity(entity_name) self.enable_entity: Entity = self.get_entity(entity_name)
self.log(f'enabled by {self.enable_entity.friendly_name}[{entity_name}]') self.log(f'enabled by {self.enable_entity.friendly_name}[{entity_name}]')
# self.listen_state( self.listen_state(
# callback=lambda entity, attribute, old, new, kwargs: self.log(f'{self.enable_entity.friendly_name}: {old} -> {new}'), callback=lambda entity, attribute, old, new, kwargs: self.ongoing_adjustment({'entity': entity}),
# entity_id=entity_name entity_id=entity_name,
# ) new='on'
)
def handle_state_change(self, entity=None, attribute=None, old=None, new=None, kwargs=None): def handle_state_change(self, entity=None, attribute=None, old=None, new=None, kwargs=None):
self.log(f'{entity}: {old} -> {new}')
if new == 'on':
if old == 'off':
self.start_adjustments(entity)
else:
self.stop_adjustments()
def handle_brightness_change(self, entity=None, attribute=None, old=None, new=None, kwargs=None):
if not self.matching_state(entity): if not self.matching_state(entity):
self.log(f'{entity}.{attribute}: {old} -> {new}') self.log(f'{entity}.{attribute}: {old} -> {new}')
self.log(f'State does not match adjuster settings, disabling adjustments') self.log(f'State does not match adjuster settings, disabling adjustments')
self.stop_adjustments() self.enabled = False
def matching_state(self, entity_id: str) -> bool: def matching_state(self, entity_id: str) -> bool:
"""Checks whether the current state of the light matches the settings from the DaylightAdjuster """Checks whether the current state of the light matches the settings from the DaylightAdjuster
@@ -245,10 +245,10 @@ class ControllerDaylight(Hass):
return False return False
else: else:
valid = all((state[s] == val) for s, val in settings.items()) valid = all((state[s] == val) for s, val in settings.items())
if not valid: # if not valid:
for s, val in settings.items(): # for s, val in settings.items():
if state[s] != val: # if state[s] != val:
self.log(f'{entity_id}.{s}: {state[s]} != {val}') # self.log(f'{entity_id}.{s}: {state[s]} != {val}')
return valid return valid
@property @property
@@ -262,29 +262,18 @@ class ControllerDaylight(Hass):
def enabled(self, new: bool) -> bool: def enabled(self, new: bool) -> bool:
self.enable_entity.set_state(state='on' if new else 'off') self.enable_entity.set_state(state='on' if new else 'off')
def start_adjustments(self, entity: str): def ongoing_adjustment(self, kwargs=None):
self.adjustment_handle = self.run_every(
callback=self.ongoing_adjustment,
start='now',
interval=10,
entity=entity
)
self.log(f'Started adjustments')
def stop_adjustments(self):
if hasattr(self, 'adjustment_handle'):
self.cancel_timer(self.adjustment_handle)
del self.adjustment_handle
self.log(f'Cancelled adjustments')
def ongoing_adjustment(self, kwargs):
if self.enabled: if self.enabled:
self.log(f'Ongoing adjustment') entity: Entity = self.get_entity(kwargs['entity'])
if entity.get_state() == 'on':
self.log(f'Ongoing adjustment for {entity.friendly_name}')
settings = self.adjuster.current_settings settings = self.adjuster.current_settings
matching = self.matching_state(entity_id=kwargs['entity']) matching = self.matching_state(entity_id=kwargs['entity'])
if not matching and not self.room.is_sleeping: if not matching and not self.room.is_sleeping:
self.turn_on(entity_id=kwargs['entity'], **settings) self.turn_on(entity_id=kwargs['entity'], **settings)
self.log(f'Adjusted {self.friendly_name(kwargs["entity"])} with {settings}') self.log(f'Adjusted {self.friendly_name(kwargs["entity"])} with {settings}')
else:
self.log(f'{entity.friendly_name} is off - no adjustment')
else: else:
self.log(f'App disabled by {self.enable_entity.friendly_name}') self.log(f'App disabled by {self.enable_entity.friendly_name}')