diff --git a/homeassistant/components/august/__init__.py b/homeassistant/components/august/__init__.py index a646ee2bad5..c6a0f90fcaa 100644 --- a/homeassistant/components/august/__init__.py +++ b/homeassistant/components/august/__init__.py @@ -205,6 +205,7 @@ class AugustData: self._house_ids.add(device.house_id) self._doorbell_detail_by_id = {} + self._door_last_state_update_time_utc_by_id = {} self._lock_last_status_update_time_utc_by_id = {} self._lock_status_by_id = {} self._lock_detail_by_id = {} @@ -290,6 +291,16 @@ class AugustData: _LOGGER.debug("Completed retrieving doorbell details") self._doorbell_detail_by_id = detail_by_id + def update_door_state(self, lock_id, door_state, update_start_time_utc): + """Set the door status and last status update time. + + This is called when newer activity is detected on the activity feed + in order to keep the internal data in sync + """ + self._door_state_by_id[lock_id] = door_state + self._door_last_state_update_time_utc_by_id[lock_id] = update_start_time_utc + return True + def update_lock_status(self, lock_id, lock_status, update_start_time_utc): """Set the lock status and last status update time. @@ -330,7 +341,8 @@ class AugustData: def _update_locks_status(self): status_by_id = {} state_by_id = {} - last_status_update_by_id = {} + lock_last_status_update_by_id = {} + door_last_state_update_by_id = {} _LOGGER.debug("Start retrieving lock and door status") for lock in self._locks: @@ -346,9 +358,10 @@ class AugustData: # Since there is a a race condition between calling the # lock and activity apis, we set the last update time # BEFORE making the api call since we will compare this - # to activity later we want activity to win over stale lock + # to activity later we want activity to win over stale lock/door # state. - last_status_update_by_id[lock.device_id] = update_start_time_utc + lock_last_status_update_by_id[lock.device_id] = update_start_time_utc + door_last_state_update_by_id[lock.device_id] = update_start_time_utc except RequestException as ex: _LOGGER.error( "Request error trying to retrieve lock and door status for %s. %s", @@ -365,7 +378,8 @@ class AugustData: _LOGGER.debug("Completed retrieving lock and door status") self._lock_status_by_id = status_by_id self._door_state_by_id = state_by_id - self._lock_last_status_update_time_utc_by_id = last_status_update_by_id + self._door_last_state_update_time_utc_by_id = door_last_state_update_by_id + self._lock_last_status_update_time_utc_by_id = lock_last_status_update_by_id def get_last_lock_status_update_time_utc(self, lock_id): """Return the last time that a lock status update was seen from the august API.""" @@ -377,6 +391,16 @@ class AugustData: return self._lock_last_status_update_time_utc_by_id[lock_id] + def get_last_door_state_update_time_utc(self, lock_id): + """Return the last time that a door status update was seen from the august API.""" + # Since the activity api is called more frequently than + # the lock api it is possible that the door has not + # been updated yet + if lock_id not in self._door_last_state_update_time_utc_by_id: + return dt.utc_from_timestamp(0) + + return self._door_last_state_update_time_utc_by_id[lock_id] + @Throttle(MIN_TIME_BETWEEN_LOCK_DETAIL_UPDATES) def _update_locks_detail(self): detail_by_id = {} diff --git a/homeassistant/components/august/binary_sensor.py b/homeassistant/components/august/binary_sensor.py index f840d3db532..0984eb0629f 100644 --- a/homeassistant/components/august/binary_sensor.py +++ b/homeassistant/components/august/binary_sensor.py @@ -6,6 +6,7 @@ from august.activity import ActivityType from august.lock import LockDoorStatus from homeassistant.components.binary_sensor import BinarySensorDevice +from homeassistant.util import dt from . import DATA_AUGUST @@ -137,6 +138,52 @@ class AugustDoorBinarySensor(BinarySensorDevice): self._state = self._state == LockDoorStatus.OPEN + activity = self._data.get_latest_device_activity( + self._door.device_id, ActivityType.DOOR_OPERATION + ) + + if activity is not None: + self._sync_door_activity(activity) + + def _update_door_state(self, door_state, update_start_time): + new_state = door_state == LockDoorStatus.OPEN + if self._state != new_state: + self._state = new_state + self._data.update_door_state( + self._door.device_id, door_state, update_start_time + ) + + def _sync_door_activity(self, activity): + """Check the activity for the latest door open/close activity (events). + + We use this to determine the door state in between calls to the lock + api as we update it more frequently + """ + last_door_state_update_time_utc = self._data.get_last_door_state_update_time_utc( + self._door.device_id + ) + activity_end_time_utc = dt.as_utc(activity.activity_end_time) + + if activity_end_time_utc > last_door_state_update_time_utc: + _LOGGER.debug( + "The activity log has new events for %s: [action=%s] [activity_end_time_utc=%s] > [last_door_state_update_time_utc=%s]", + self.name, + activity.action, + activity_end_time_utc, + last_door_state_update_time_utc, + ) + activity_start_time_utc = dt.as_utc(activity.activity_start_time) + if activity.action == "doorclosed": + self._update_door_state(LockDoorStatus.CLOSED, activity_start_time_utc) + elif activity.action == "dooropen": + self._update_door_state(LockDoorStatus.OPEN, activity_start_time_utc) + else: + _LOGGER.info( + "Unhandled door activity action %s for %s", + activity.action, + self.name, + ) + @property def unique_id(self) -> str: """Get the unique of the door open binary sensor.""" diff --git a/homeassistant/components/august/manifest.json b/homeassistant/components/august/manifest.json index bacd7346ca7..f74e20f38c2 100644 --- a/homeassistant/components/august/manifest.json +++ b/homeassistant/components/august/manifest.json @@ -2,7 +2,7 @@ "domain": "august", "name": "August", "documentation": "https://www.home-assistant.io/integrations/august", - "requirements": ["py-august==0.8.1"], + "requirements": ["py-august==0.11.0"], "dependencies": ["configurator"], "codeowners": [] } diff --git a/requirements_all.txt b/requirements_all.txt index a80435d71ff..0dac9a0b481 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1074,7 +1074,7 @@ pushover_complete==1.1.1 pwmled==1.4.1 # homeassistant.components.august -py-august==0.8.1 +py-august==0.11.0 # homeassistant.components.canary py-canary==0.5.0