added some sleep behavior
This commit is contained in:
@@ -20,12 +20,13 @@ class ControllerEntities(Hass):
|
|||||||
|
|
||||||
for entity in self.entities:
|
for entity in self.entities:
|
||||||
assert self.entity_exists(entity), f'{entity} does not exist'
|
assert self.entity_exists(entity), f'{entity} does not exist'
|
||||||
|
|
||||||
self.entities = [self.get_entity(e) for e in self.entities]
|
self.entities = [self.get_entity(e) for e in self.entities]
|
||||||
|
|
||||||
|
|
||||||
@dataclass(init=False)
|
@dataclass(init=False)
|
||||||
class ControllerRoomLights(ControllerEntities):
|
class ControllerRoomLights(ControllerEntities):
|
||||||
|
sleep: str
|
||||||
|
|
||||||
def initialize(self):
|
def initialize(self):
|
||||||
super().initialize()
|
super().initialize()
|
||||||
self.log(f'Initialized light controller for {[e.friendly_name for e in self.entities]}')
|
self.log(f'Initialized light controller for {[e.friendly_name for e in self.entities]}')
|
||||||
@@ -33,7 +34,10 @@ class ControllerRoomLights(ControllerEntities):
|
|||||||
self.register_service(f'{self.name}/deactivate', self.deactivate)
|
self.register_service(f'{self.name}/deactivate', self.deactivate)
|
||||||
|
|
||||||
def activate(self, namespace: str = None, domain: str = None, service=None, kwargs=None):
|
def activate(self, namespace: str = None, domain: str = None, service=None, kwargs=None):
|
||||||
self.log(self.entities)
|
# if self.is_sleeping:
|
||||||
|
# self.log(f'Sleep mode is on, returning early')
|
||||||
|
# return
|
||||||
|
|
||||||
for entity in self.entities:
|
for entity in self.entities:
|
||||||
self.log(f'Turning on {entity.name}')
|
self.log(f'Turning on {entity.name}')
|
||||||
entity.turn_on()
|
entity.turn_on()
|
||||||
@@ -48,6 +52,17 @@ class ControllerRoomLights(ControllerEntities):
|
|||||||
def state(self) -> bool:
|
def state(self) -> bool:
|
||||||
return any([e.get_state() == 'on' for e in self.entities])
|
return any([e.get_state() == 'on' for e in self.entities])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_sleeping(self) -> bool:
|
||||||
|
if 'sleep' in self.args:
|
||||||
|
return self.get_entity(self.args['sleep']).is_state('on')
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@is_sleeping.setter
|
||||||
|
def is_sleeping(self, val: bool):
|
||||||
|
if 'sleep' in self.args:
|
||||||
|
self.get_entity(self.args['sleep']).set_state(state='on' if val else 'off')
|
||||||
|
|
||||||
@dataclass(init=False)
|
@dataclass(init=False)
|
||||||
class ControllerMotion(ControllerEntities):
|
class ControllerMotion(ControllerEntities):
|
||||||
@@ -97,6 +112,7 @@ class ControllerMotion(ControllerEntities):
|
|||||||
|
|
||||||
def callback_motion_on(self, entity, attribute, old, new, kwargs):
|
def callback_motion_on(self, entity, attribute, old, new, kwargs):
|
||||||
self.log(f'Motion detected on {self.friendly_name(entity)}')
|
self.log(f'Motion detected on {self.friendly_name(entity)}')
|
||||||
|
if not self.room.is_sleeping:
|
||||||
self.room.activate()
|
self.room.activate()
|
||||||
|
|
||||||
def callback_motion_off(self, entity, attribute, old, new, kwargs):
|
def callback_motion_off(self, entity, attribute, old, new, kwargs):
|
||||||
@@ -132,24 +148,47 @@ class ControllerButton(Hass):
|
|||||||
else:
|
else:
|
||||||
self.room.activate()
|
self.room.activate()
|
||||||
|
|
||||||
|
# double click
|
||||||
|
elif data['event'] == 1004:
|
||||||
|
self.log(f'{data["id"]} double click')
|
||||||
|
self.room.is_sleeping = not self.room.is_sleeping
|
||||||
|
if not self.room.is_sleeping:
|
||||||
|
self.room.activate()
|
||||||
|
|
||||||
|
|
||||||
@dataclass(init=False)
|
@dataclass(init=False)
|
||||||
class ControllerDaylight(ControllerEntities):
|
class ControllerDaylight(Hass):
|
||||||
|
room: ControllerRoomLights
|
||||||
|
entities: List[str]
|
||||||
latitude: float
|
latitude: float
|
||||||
longitude: float
|
longitude: float
|
||||||
|
enable: bool = field(init=False, default=True)
|
||||||
|
|
||||||
def initialize(self):
|
def initialize(self):
|
||||||
super().initialize()
|
# convert room to App
|
||||||
|
self.room: ControllerRoomLights = self.get_app(self.args['room'])
|
||||||
|
|
||||||
|
# convert entities
|
||||||
|
for entity in self.args['entities']:
|
||||||
|
assert self.entity_exists(entity), f'{entity} does not exist'
|
||||||
|
self.entities = [self.get_entity(e) for e in self.args['entities']]
|
||||||
|
# self.log(self.entities)
|
||||||
|
|
||||||
|
# create Adjuster
|
||||||
self.adjuster = DaylightAdjuster(
|
self.adjuster = DaylightAdjuster(
|
||||||
latitude=self.args['latitude'],
|
latitude=self.args['latitude'],
|
||||||
longitude=self.args['longitude'],
|
longitude=self.args['longitude'],
|
||||||
periods=self.args['periods'],
|
periods=self.args['periods'],
|
||||||
resolution=500
|
resolution=500
|
||||||
)
|
)
|
||||||
self.log(self.adjuster)
|
# self.log(self.adjuster)
|
||||||
|
|
||||||
self.listen_state(callback=self.handle_state_change, entity_id=[e.entity_id for e in self.entities])
|
self.listen_state(callback=self.handle_state_change, entity_id=[e.entity_id for e in self.entities])
|
||||||
self.log(f'Listening for state {[e.friendly_name for e in self.entities]}')
|
ents = [e.friendly_name for e in self.entities]
|
||||||
|
if len(ents) > 1:
|
||||||
|
ents[-1] = f'and {ents[-1]}'
|
||||||
|
delim = ', ' if len(ents) >= 3 else ' '
|
||||||
|
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=5.0)
|
||||||
|
|
||||||
@@ -165,9 +204,18 @@ class ControllerDaylight(ControllerEntities):
|
|||||||
else:
|
else:
|
||||||
if hasattr(self, 'adjustment_handle'):
|
if hasattr(self, 'adjustment_handle'):
|
||||||
self.cancel_timer(self.adjustment_handle)
|
self.cancel_timer(self.adjustment_handle)
|
||||||
|
del self.adjustment_handle
|
||||||
self.log(f'Cancelled adjustments')
|
self.log(f'Cancelled adjustments')
|
||||||
|
|
||||||
def matching_state(self, entity_id: str):
|
def matching_state(self, entity_id: str) -> bool:
|
||||||
|
"""Checks whether the current state of the light matches the settings from the DaylightAdjuster
|
||||||
|
|
||||||
|
Args:
|
||||||
|
entity_id (str): full entity ID
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool
|
||||||
|
"""
|
||||||
state = self.get_state(entity_id=entity_id, attribute='all')['attributes']
|
state = self.get_state(entity_id=entity_id, attribute='all')['attributes']
|
||||||
settings = self.adjuster.current_settings
|
settings = self.adjuster.current_settings
|
||||||
try:
|
try:
|
||||||
@@ -181,8 +229,8 @@ class ControllerDaylight(ControllerEntities):
|
|||||||
def ongoing_adjustment(self, kwargs):
|
def ongoing_adjustment(self, kwargs):
|
||||||
self.log(f'Ongoing adjustment')
|
self.log(f'Ongoing adjustment')
|
||||||
settings = self.adjuster.current_settings
|
settings = self.adjuster.current_settings
|
||||||
valid = self.matching_state(entity_id=kwargs['entity'])
|
matching = self.matching_state(entity_id=kwargs['entity'])
|
||||||
if not valid:
|
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}')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user