diff --git a/motion.py b/motion.py index 2a284e5..cf8fd63 100644 --- a/motion.py +++ b/motion.py @@ -1,4 +1,3 @@ -import asyncio import re from datetime import timedelta @@ -38,25 +37,24 @@ class Motion(Hass): self.listen_state(**base_kwargs, attribute='brightness', callback=self.callback_light_on) self.listen_state(**base_kwargs, new='off', callback=self.callback_light_off) - @utils.sync_wrapper async def listen_motion_on(self): """Sets up the motion on callback to activate the room """ - self.log(f'Waiting for motion on {self.sensor.friendly_name}') - self.listen_state( + await self.cancel_motion_callback() + await self.listen_state( callback=self.app.activate_all_off, entity_id=self.sensor.entity_id, new='on', oneshot=True, cause='motion on' ) + self.log(f'Waiting for motion on {self.sensor.friendly_name}') - @utils.sync_wrapper async def listen_motion_off(self, duration: timedelta): """Sets up the motion off callback to deactivate the room """ - self.log(f'Waiting for motion to stop on {self.sensor.friendly_name} for {duration}') - self.listen_state( + await self.cancel_motion_callback() + await self.listen_state( callback=self.app.deactivate, entity_id=self.sensor.entity_id, new='off', @@ -64,6 +62,7 @@ class Motion(Hass): oneshot=True, cause='motion off' ) + self.log(f'Waiting for motion to stop on {self.sensor.friendly_name} for {duration}') @utils.sync_wrapper async def callback_light_on(self, entity=None, attribute=None, old=None, new=None, kwargs=None): @@ -71,18 +70,15 @@ class Motion(Hass): """ if new is not None: self.log(f'{entity} turned on') - # need this one to finish before continuing to the next line - await self.cancel_motion_callback(new='on') - self.listen_motion_off(await self.app.off_duration()) + duration = await self.app.off_duration() + await self.listen_motion_off(duration) @utils.sync_wrapper async def callback_light_off(self, entity=None, attribute=None, old=None, new=None, kwargs=None): """Called when the light turns off """ self.log(f'{entity} turned off') - # need this one to finish before continuing to the next line - await self.cancel_motion_callback(new='off') - self.listen_motion_on() + await self.listen_motion_on() async def get_app_callbacks(self, name: str = None): """Gets all the callbacks associated with the app @@ -103,13 +99,13 @@ class Motion(Hass): if info['entity'] == self.sensor.entity_id } - async def cancel_motion_callback(self, new: str): + async def cancel_motion_callback(self): callbacks = await self.get_sensor_callbacks() - # self.log(f'Found {len(callbacks)}') + self.log(f'Found {len(callbacks)} callbacks for {self.sensor.entity_id}') for handle, info in callbacks.items(): entity = info["entity"] - new_match = re.match('new=(?P.*?)\s', info['kwargs']) - # self.log(f'{handle}: {info["entity"]}: {info["kwargs"]}') - if new_match is not None and new_match.group("new") == new: + kwargs = info['kwargs'] + if (m := re.match('new=(?P.*?)\s', kwargs)) is not None: + new = m.group('new') await self.cancel_listen_state(handle) - self.log(f'cancelled {new} callback for sensor {await self.friendly_name(entity)}') + self.log(f'cancelled callback for sensor {entity} turning {new}')