From a756d1e637a84cdcdc505d6fa4c748331cbbf775 Mon Sep 17 00:00:00 2001 From: Eugene Prystupa Date: Wed, 22 Jul 2020 19:15:27 -0700 Subject: [PATCH] Centralize bond update state logic (#38093) * Refactor bond integration to centralize update state logic in single superclass * Refactor bond integration to centralize update state logic in single superclass --- homeassistant/components/bond/cover.py | 10 ++++------ homeassistant/components/bond/entity.py | 13 ++++++++++++- homeassistant/components/bond/fan.py | 12 +++++------- homeassistant/components/bond/light.py | 18 +++++++----------- homeassistant/components/bond/switch.py | 8 +++----- 5 files changed, 31 insertions(+), 30 deletions(-) diff --git a/homeassistant/components/bond/cover.py b/homeassistant/components/bond/cover.py index 523a7f5c4d8..dc0fc6d500c 100644 --- a/homeassistant/components/bond/cover.py +++ b/homeassistant/components/bond/cover.py @@ -39,17 +39,15 @@ class BondCover(BondEntity, CoverEntity): self._closed: Optional[bool] = None + def _apply_state(self, state: dict): + cover_open = state.get("open") + self._closed = True if cover_open == 0 else False if cover_open == 1 else None + @property def device_class(self) -> Optional[str]: """Get device class.""" return DEVICE_CLASS_SHADE - async def async_update(self): - """Fetch assumed state of the cover from the hub using API.""" - state: dict = await self._hub.bond.device_state(self._device.device_id) - cover_open = state.get("open") - self._closed = True if cover_open == 0 else False if cover_open == 1 else None - @property def is_closed(self): """Return if the cover is closed or not.""" diff --git a/homeassistant/components/bond/entity.py b/homeassistant/components/bond/entity.py index 0916297c074..d6d314f2844 100644 --- a/homeassistant/components/bond/entity.py +++ b/homeassistant/components/bond/entity.py @@ -1,13 +1,15 @@ """An abstract class common to all Bond entities.""" +from abc import abstractmethod from typing import Any, Dict, Optional from homeassistant.const import ATTR_NAME +from homeassistant.helpers.entity import Entity from .const import DOMAIN from .utils import BondDevice, BondHub -class BondEntity: +class BondEntity(Entity): """Generic Bond entity encapsulating common features of any Bond controlled device.""" def __init__(self, hub: BondHub, device: BondDevice): @@ -38,3 +40,12 @@ class BondEntity: def assumed_state(self) -> bool: """Let HA know this entity relies on an assumed state tracked by Bond.""" return True + + async def async_update(self): + """Fetch assumed state of the cover from the hub using API.""" + state: dict = await self._hub.bond.device_state(self._device.device_id) + self._apply_state(state) + + @abstractmethod + def _apply_state(self, state: dict): + raise NotImplementedError diff --git a/homeassistant/components/bond/fan.py b/homeassistant/components/bond/fan.py index 82d437fd7b0..6f6a98036c7 100644 --- a/homeassistant/components/bond/fan.py +++ b/homeassistant/components/bond/fan.py @@ -50,6 +50,11 @@ class BondFan(BondEntity, FanEntity): self._speed: Optional[int] = None self._direction: Optional[int] = None + def _apply_state(self, state: dict): + self._power = state.get("power") + self._speed = state.get("speed") + self._direction = state.get("direction") + @property def supported_features(self) -> int: """Flag supported features.""" @@ -90,13 +95,6 @@ class BondFan(BondEntity, FanEntity): return direction - async def async_update(self): - """Fetch assumed state of the fan from the hub using API.""" - state: dict = await self._hub.bond.device_state(self._device.device_id) - self._power = state.get("power") - self._speed = state.get("speed") - self._direction = state.get("direction") - async def async_set_speed(self, speed: str) -> None: """Set the desired speed for the fan.""" max_speed = self._device.props.get("max_speed", 3) diff --git a/homeassistant/components/bond/light.py b/homeassistant/components/bond/light.py index daea1c02638..77afb188111 100644 --- a/homeassistant/components/bond/light.py +++ b/homeassistant/components/bond/light.py @@ -50,16 +50,14 @@ class BondLight(BondEntity, LightEntity): self._light: Optional[int] = None + def _apply_state(self, state: dict): + self._light = state.get("light") + @property def is_on(self) -> bool: """Return if light is currently on.""" return self._light == 1 - async def async_update(self): - """Fetch assumed state of the light from the hub using API.""" - state: dict = await self._hub.bond.device_state(self._device.device_id) - self._light = state.get("light") - async def async_turn_on(self, **kwargs: Any) -> None: """Turn on the light.""" await self._hub.bond.action(self._device.device_id, Action.turn_light_on()) @@ -80,6 +78,10 @@ class BondFireplace(BondEntity, LightEntity): # Bond flame level, 0-100 self._flame: Optional[int] = None + def _apply_state(self, state: dict): + self._power = state.get("power") + self._flame = state.get("flame") + @property def supported_features(self) -> Optional[int]: """Flag brightness as supported feature to represent flame level.""" @@ -112,9 +114,3 @@ class BondFireplace(BondEntity, LightEntity): def icon(self) -> Optional[str]: """Show fireplace icon for the entity.""" return "mdi:fireplace" if self._power == 1 else "mdi:fireplace-off" - - async def async_update(self): - """Fetch assumed state of the device from the hub using API.""" - state: dict = await self._hub.bond.device_state(self._device.device_id) - self._power = state.get("power") - self._flame = state.get("flame") diff --git a/homeassistant/components/bond/switch.py b/homeassistant/components/bond/switch.py index 3d5b467345e..d2f1797225d 100644 --- a/homeassistant/components/bond/switch.py +++ b/homeassistant/components/bond/switch.py @@ -39,6 +39,9 @@ class BondSwitch(BondEntity, SwitchEntity): self._power: Optional[bool] = None + def _apply_state(self, state: dict): + self._power = state.get("power") + @property def is_on(self) -> bool: """Return True if power is on.""" @@ -51,8 +54,3 @@ class BondSwitch(BondEntity, SwitchEntity): async def async_turn_off(self, **kwargs: Any) -> None: """Turn the device off.""" await self._hub.bond.action(self._device.device_id, Action.turn_off()) - - async def async_update(self): - """Fetch assumed state of the device from the hub using API.""" - state: dict = await self._hub.bond.device_state(self._device.device_id) - self._power = state.get("power")