first version of presence simulation with light
This commit is contained in:
@@ -114,6 +114,8 @@ from ad_toolbox.eventhandler import EventHandler
|
||||
class SmartLight(SmartSwitch):
|
||||
|
||||
def on_initialize_smart_object(self):
|
||||
self.presence_simulation_slots_active = set()
|
||||
|
||||
# light_brightness_pct_list : ordered list of (Evaluator, label) pairs
|
||||
# light_brightness_pct : currently active brightness % (str label)
|
||||
self.light_brightness_pct_list = list()
|
||||
@@ -196,6 +198,15 @@ class SmartLight(SmartSwitch):
|
||||
# SmartSwitch overrides
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
# While simulation is active for this light, ignore auto-off transitions
|
||||
# from smart_conditions to keep deterministic on-duration windows.
|
||||
def on_smart_conditions_change(self,prev_result,result):
|
||||
if len(self.presence_simulation_slots_active) > 0:
|
||||
if result == SmartCondition.Result.Succeeded and self.is_off():
|
||||
self.switch_on()
|
||||
return
|
||||
super().on_smart_conditions_change(prev_result,result)
|
||||
|
||||
# Override: apply light_brightness_pct when turning on, if one is active.
|
||||
def switch_on(self):
|
||||
if self.light_brightness_pct != None:
|
||||
@@ -225,4 +236,61 @@ class SmartLight(SmartSwitch):
|
||||
self.log_info("Turning off")
|
||||
self.call_service("light/turn_off", entity_id = self.entity_id)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Presence simulation API (called by HomeAlarm)
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def start_presence_simulation(self, source_app=None, slot_name=None, payload=None):
|
||||
if slot_name:
|
||||
self.presence_simulation_slots_active.add(slot_name)
|
||||
|
||||
if not isinstance(payload, dict):
|
||||
payload = {}
|
||||
|
||||
brightness_pct = payload.get('brightness_pct')
|
||||
transition = payload.get('transition')
|
||||
|
||||
if brightness_pct is None and transition is None:
|
||||
self.switch_on()
|
||||
return
|
||||
|
||||
service_kwargs = {'entity_id': self.entity_id}
|
||||
if brightness_pct is not None:
|
||||
service_kwargs['brightness_pct'] = brightness_pct
|
||||
if transition is not None:
|
||||
service_kwargs['transition'] = transition
|
||||
|
||||
self.call_service("light/turn_on", **service_kwargs)
|
||||
|
||||
def stop_presence_simulation(self, source_app=None, slot_name=None, payload=None):
|
||||
if slot_name and slot_name in self.presence_simulation_slots_active:
|
||||
self.presence_simulation_slots_active.remove(slot_name)
|
||||
|
||||
if not isinstance(payload, dict):
|
||||
payload = {}
|
||||
|
||||
if payload.get('keep_on', False):
|
||||
return
|
||||
|
||||
transition = payload.get('transition')
|
||||
if transition is None:
|
||||
self.switch_off()
|
||||
else:
|
||||
self.call_service(
|
||||
"light/turn_off",
|
||||
entity_id=self.entity_id,
|
||||
transition=transition,
|
||||
)
|
||||
|
||||
# If no simulation slot is still active, re-apply current automation
|
||||
# state so the light immediately converges to the expected result.
|
||||
if len(self.presence_simulation_slots_active) == 0 and self.smart_conditions_evaluator:
|
||||
result = self.smart_conditions_evaluator.evaluate(False)
|
||||
if result == SmartCondition.Result.Succeeded:
|
||||
if self.is_off():
|
||||
self.switch_on()
|
||||
else:
|
||||
if self.is_on():
|
||||
self.switch_off()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user