From 700c8e121456c634ee2e81057a66a45fd1267d47 Mon Sep 17 00:00:00 2001 From: John Lancaster <32917998+jsl12@users.noreply.github.com> Date: Sun, 30 Apr 2023 17:08:50 -0500 Subject: [PATCH] reworked callback cancellation --- apps/basic_motion.py | 69 ++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/apps/basic_motion.py b/apps/basic_motion.py index 7120518..6b0e906 100755 --- a/apps/basic_motion.py +++ b/apps/basic_motion.py @@ -40,8 +40,6 @@ class MotionLight(Hass): new='on' ) - self.log(f'All off: {self.all_off}') - @property def sensor(self) -> str: return self.args['sensor'] @@ -66,7 +64,7 @@ class MotionLight(Hass): 'off_duration', self.args.get('off_duration', '00:00:00') ) - + try: hours, minutes, seconds = map(int, duration_str.split(':')) return timedelta(hours=hours, minutes=minutes, seconds=seconds) @@ -142,7 +140,7 @@ class MotionLight(Hass): states = sorted(gen(), key=lambda s: s['time']) return states - + def current_state(self, time: time = None): if self.sleeping_active: if (state := self.args.get('sleep_state')): @@ -232,7 +230,8 @@ class MotionLight(Hass): self.callback_light_off() def listen_motion_on(self): - self.log(f'Waiting for motion on {self.friendly_name(self.sensor)} to turn on {self.friendly_name(self.entity)}') + self.log( + f'Waiting for motion on {self.friendly_name(self.sensor)} to turn on {self.friendly_name(self.entity)}') self.motion_on_handle = self.listen_state( callback=self.activate, entity_id=self.sensor, @@ -241,7 +240,8 @@ class MotionLight(Hass): ) def listen_motion_off(self, duration: timedelta): - self.log(f'Waiting for motion to stop on {self.friendly_name(self.sensor)} for {duration} to turn off {self.friendly_name(self.entity)}') + self.log( + f'Waiting for motion to stop on {self.friendly_name(self.sensor)} for {duration} to turn off {self.friendly_name(self.entity)}') self.motion_off_handle = self.listen_state( callback=self.deactivate, entity_id=self.sensor, @@ -250,20 +250,20 @@ class MotionLight(Hass): oneshot=True ) - def cancel_motion(self, handle_name): - if hasattr(self, handle_name): - handle = getattr(self, handle_name) - try: - self.log(f'{handle_name}: {self.info_listen_state(handle)}') - except ValueError: - self.log(f'Error getting {handle_name} info') - else: - self.cancel_listen_state(handle) - self.log(f'Cancelled handle: {handle_name}') - finally: - delattr(self, handle_name) - else: - self.log(f'No attribute: {handle_name}') + # def cancel_motion(self, handle_name): + # if hasattr(self, handle_name): + # handle = getattr(self, handle_name) + # try: + # self.log(f'{handle_name}: {self.info_listen_state(handle)}') + # except ValueError: + # self.log(f'Error getting {handle_name} info') + # else: + # self.cancel_listen_state(handle) + # self.log(f'Cancelled handle: {handle_name}') + # finally: + # delattr(self, handle_name) + # else: + # self.log(f'No attribute: {handle_name}') def state_change(self, entity=None, attribute=None, old=None, new=None, kwargs=None): """Callback attached to the state change of the light. @@ -279,7 +279,7 @@ class MotionLight(Hass): """Called when the light turns on """ self.log('Light on callback') - self.cancel_motion('motion_on_handle') + self.cancel_motion_callback(new='on') self.listen_motion_off(self.off_duration) # if self.is_stateful: # self.activate() @@ -288,7 +288,7 @@ class MotionLight(Hass): """Called when the light turns on """ self.log('Light off callback') - self.cancel_motion('motion_off_handle') + self.cancel_motion_callback(new='off') self.listen_motion_on() def activate(self, *args, **kwargs): @@ -373,7 +373,7 @@ class MotionLight(Hass): elif data['event'] == 1001: self.log(f'{data["id"]} long press down') if 'delay' in self.args and self.entity_state: - self.cancel_motion('motion_off_handle') + self.cancel_motion_callback(new='off') self.listen_motion_off(self.delay) self.turn_on(self.entity, brightness_pct=100) @@ -382,6 +382,25 @@ class MotionLight(Hass): self.log(f'{data["id"]} double click') if 'sleep' in self.args: self.sleep_bool = not self.sleep_bool - self.cancel_motion('motion_off_handle') - self.callback_light_on() + # self.cancel_motion_callback(new='off') + # self.callback_light_on() self.activate() + + def get_app_callbacks(self, name: str = None): + name = name or self.name + for app_name, callbacks in self.get_callback_entries().items(): + if app_name == name: + return callbacks + + def get_motion_callback(self): + return { + handle: info + for handle, info in self.get_app_callbacks().items() + if info['entity'] == self.sensor + } + + def cancel_motion_callback(self, new: str): + for handle, info in self.get_motion_callback().items(): + if f'new={new}' in info['kwargs']: + self.log(f'Cancelling callback for {info}') + self.cancel_listen_state(handle)