From 4e00a8a3d0210c594198522eedc17a866d0080c6 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 14 Nov 2020 10:47:38 -1000 Subject: [PATCH] Eliminate doorbird switch polling (#43215) --- homeassistant/components/doorbird/switch.py | 36 +++++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/doorbird/switch.py b/homeassistant/components/doorbird/switch.py index 358f4172346..f1f146aebb9 100644 --- a/homeassistant/components/doorbird/switch.py +++ b/homeassistant/components/doorbird/switch.py @@ -2,6 +2,8 @@ import datetime from homeassistant.components.switch import SwitchEntity +from homeassistant.core import callback +from homeassistant.helpers.event import async_track_point_in_utc_time import homeassistant.util.dt as dt_util from .const import DOMAIN, DOOR_STATION, DOOR_STATION_INFO @@ -37,13 +39,13 @@ class DoorBirdSwitch(DoorBirdEntity, SwitchEntity): self._doorstation = doorstation self._relay = relay self._state = False - self._assume_off = datetime.datetime.min if relay == IR_RELAY: self._time = datetime.timedelta(minutes=5) else: self._time = datetime.timedelta(seconds=5) self._unique_id = f"{self._mac_addr}_{self._relay}" + self._reset_sub = None @property def unique_id(self): @@ -63,27 +65,41 @@ class DoorBirdSwitch(DoorBirdEntity, SwitchEntity): """Return the icon to display.""" return "mdi:lightbulb" if self._relay == IR_RELAY else "mdi:dip-switch" + @property + def should_poll(self): + """No need to poll.""" + return False + @property def is_on(self): """Get the assumed state of the relay.""" return self._state - def turn_on(self, **kwargs): + async def async_turn_on(self, **kwargs): + """Power the relay.""" + if self._reset_sub is not None: + self._reset_sub() + self._reset_sub = None + self._reset_sub = async_track_point_in_utc_time( + self.hass, self._async_turn_off, dt_util.utcnow() + self._time + ) + await self.hass.async_add_executor_job(self._turn_on) + self.async_write_ha_state() + + def _turn_on(self): """Power the relay.""" if self._relay == IR_RELAY: self._state = self._doorstation.device.turn_light_on() else: self._state = self._doorstation.device.energize_relay(self._relay) - now = dt_util.utcnow() - self._assume_off = now + self._time - - def turn_off(self, **kwargs): + async def async_turn_off(self, **kwargs): """Turn off the relays is not needed. They are time-based.""" raise NotImplementedError("DoorBird relays cannot be manually turned off.") - async def async_update(self): + @callback + def _async_turn_off(self, *_): """Wait for the correct amount of assumed time to pass.""" - if self._state and self._assume_off <= dt_util.utcnow(): - self._state = False - self._assume_off = datetime.datetime.min + self._state = False + self._reset_sub = None + self.async_write_ha_state()