Refactor bond integration to be completely async (#38066)

This commit is contained in:
Eugene Prystupa 2020-07-22 18:22:25 -07:00 committed by GitHub
parent 15fe727f2c
commit 3480fb6996
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 251 additions and 259 deletions

View file

@ -1,7 +1,7 @@
"""The Bond integration.""" """The Bond integration."""
import asyncio import asyncio
from bond import Bond from bond_api import Bond
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST
@ -25,9 +25,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
host = entry.data[CONF_HOST] host = entry.data[CONF_HOST]
token = entry.data[CONF_ACCESS_TOKEN] token = entry.data[CONF_ACCESS_TOKEN]
bond = Bond(bondIp=host, bondToken=token) bond = Bond(host=host, token=token)
hub = BondHub(bond) hub = BondHub(bond)
await hass.async_add_executor_job(hub.setup) await hub.setup()
hass.data[DOMAIN][entry.entry_id] = hub hass.data[DOMAIN][entry.entry_id] = hub
device_registry = await dr.async_get_registry(hass) device_registry = await dr.async_get_registry(hass)

View file

@ -1,12 +1,11 @@
"""Config flow for Bond integration.""" """Config flow for Bond integration."""
from json import JSONDecodeError
import logging import logging
from bond import Bond from aiohttp import ClientConnectionError, ClientResponseError
from requests.exceptions import ConnectionError as RequestConnectionError from bond_api import Bond
import voluptuous as vol import voluptuous as vol
from homeassistant import config_entries, core, exceptions from homeassistant import config_entries, exceptions
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST
from .const import DOMAIN # pylint:disable=unused-import from .const import DOMAIN # pylint:disable=unused-import
@ -18,24 +17,20 @@ DATA_SCHEMA = vol.Schema(
) )
async def validate_input(hass: core.HomeAssistant, data): async def validate_input(data):
"""Validate the user input allows us to connect.""" """Validate the user input allows us to connect."""
def authenticate(bond_hub: Bond) -> bool: try:
try: bond = Bond(data[CONF_HOST], data[CONF_ACCESS_TOKEN])
bond_hub.getDeviceIds() await bond.devices()
return True except ClientConnectionError:
except RequestConnectionError: raise CannotConnect
raise CannotConnect except ClientResponseError as error:
except JSONDecodeError: if error.status == 401:
return False raise InvalidAuth
raise
bond = Bond(data[CONF_HOST], data[CONF_ACCESS_TOKEN]) # Return info to be stored in the config entry.
if not await hass.async_add_executor_job(authenticate, bond):
raise InvalidAuth
# Return info that you want to store in the config entry.
return {"title": data[CONF_HOST]} return {"title": data[CONF_HOST]}
@ -50,7 +45,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
errors = {} errors = {}
if user_input is not None: if user_input is not None:
try: try:
info = await validate_input(self.hass, user_input) info = await validate_input(user_input)
except CannotConnect: except CannotConnect:
errors["base"] = "cannot_connect" errors["base"] = "cannot_connect"
except InvalidAuth: except InvalidAuth:

View file

@ -1,7 +1,7 @@
"""Support for Bond covers.""" """Support for Bond covers."""
from typing import Any, Callable, List, Optional from typing import Any, Callable, List, Optional
from bond import DeviceTypes from bond_api import Action, DeviceType
from homeassistant.components.cover import DEVICE_CLASS_SHADE, CoverEntity from homeassistant.components.cover import DEVICE_CLASS_SHADE, CoverEntity
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
@ -24,7 +24,7 @@ async def async_setup_entry(
covers = [ covers = [
BondCover(hub, device) BondCover(hub, device)
for device in hub.devices for device in hub.devices
if device.type == DeviceTypes.MOTORIZED_SHADES if device.type == DeviceType.MOTORIZED_SHADES
] ]
async_add_entities(covers, True) async_add_entities(covers, True)
@ -44,9 +44,9 @@ class BondCover(BondEntity, CoverEntity):
"""Get device class.""" """Get device class."""
return DEVICE_CLASS_SHADE return DEVICE_CLASS_SHADE
def update(self): async def async_update(self):
"""Fetch assumed state of the cover from the hub using API.""" """Fetch assumed state of the cover from the hub using API."""
state: dict = self._hub.bond.getDeviceState(self._device.device_id) state: dict = await self._hub.bond.device_state(self._device.device_id)
cover_open = state.get("open") cover_open = state.get("open")
self._closed = True if cover_open == 0 else False if cover_open == 1 else None self._closed = True if cover_open == 0 else False if cover_open == 1 else None
@ -55,14 +55,14 @@ class BondCover(BondEntity, CoverEntity):
"""Return if the cover is closed or not.""" """Return if the cover is closed or not."""
return self._closed return self._closed
def open_cover(self, **kwargs: Any) -> None: async def async_open_cover(self, **kwargs: Any) -> None:
"""Open the cover.""" """Open the cover."""
self._hub.bond.open(self._device.device_id) await self._hub.bond.action(self._device.device_id, Action.open())
def close_cover(self, **kwargs: Any) -> None: async def async_close_cover(self, **kwargs: Any) -> None:
"""Close cover.""" """Close cover."""
self._hub.bond.close(self._device.device_id) await self._hub.bond.action(self._device.device_id, Action.close())
def stop_cover(self, **kwargs): async def async_stop_cover(self, **kwargs):
"""Hold cover.""" """Hold cover."""
self._hub.bond.hold(self._device.device_id) await self._hub.bond.action(self._device.device_id, Action.hold())

View file

@ -2,7 +2,7 @@
import math import math
from typing import Any, Callable, List, Optional from typing import Any, Callable, List, Optional
from bond import DeviceTypes, Directions from bond_api import Action, DeviceType, Direction
from homeassistant.components.fan import ( from homeassistant.components.fan import (
DIRECTION_FORWARD, DIRECTION_FORWARD,
@ -33,9 +33,7 @@ async def async_setup_entry(
hub: BondHub = hass.data[DOMAIN][entry.entry_id] hub: BondHub = hass.data[DOMAIN][entry.entry_id]
fans = [ fans = [
BondFan(hub, device) BondFan(hub, device) for device in hub.devices if DeviceType.is_fan(device.type)
for device in hub.devices
if device.type == DeviceTypes.CEILING_FAN
] ]
async_add_entities(fans, True) async_add_entities(fans, True)
@ -85,21 +83,21 @@ class BondFan(BondEntity, FanEntity):
def current_direction(self) -> Optional[str]: def current_direction(self) -> Optional[str]:
"""Return fan rotation direction.""" """Return fan rotation direction."""
direction = None direction = None
if self._direction == Directions.FORWARD: if self._direction == Direction.FORWARD:
direction = DIRECTION_FORWARD direction = DIRECTION_FORWARD
elif self._direction == Directions.REVERSE: elif self._direction == Direction.REVERSE:
direction = DIRECTION_REVERSE direction = DIRECTION_REVERSE
return direction return direction
def update(self): async def async_update(self):
"""Fetch assumed state of the fan from the hub using API.""" """Fetch assumed state of the fan from the hub using API."""
state: dict = self._hub.bond.getDeviceState(self._device.device_id) state: dict = await self._hub.bond.device_state(self._device.device_id)
self._power = state.get("power") self._power = state.get("power")
self._speed = state.get("speed") self._speed = state.get("speed")
self._direction = state.get("direction") self._direction = state.get("direction")
def set_speed(self, speed: str) -> None: async def async_set_speed(self, speed: str) -> None:
"""Set the desired speed for the fan.""" """Set the desired speed for the fan."""
max_speed = self._device.props.get("max_speed", 3) max_speed = self._device.props.get("max_speed", 3)
if speed == SPEED_LOW: if speed == SPEED_LOW:
@ -108,21 +106,27 @@ class BondFan(BondEntity, FanEntity):
bond_speed = max_speed bond_speed = max_speed
else: else:
bond_speed = math.ceil(max_speed / 2) bond_speed = math.ceil(max_speed / 2)
self._hub.bond.setSpeed(self._device.device_id, speed=bond_speed)
def turn_on(self, speed: Optional[str] = None, **kwargs) -> None: await self._hub.bond.action(
self._device.device_id, Action.set_speed(bond_speed)
)
async def async_turn_on(self, speed: Optional[str] = None, **kwargs) -> None:
"""Turn on the fan.""" """Turn on the fan."""
if speed is not None: if speed is not None:
self.set_speed(speed) await self.async_set_speed(speed)
self._hub.bond.turnOn(self._device.device_id) else:
await self._hub.bond.action(self._device.device_id, Action.turn_on())
def turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the fan off.""" """Turn the fan off."""
self._hub.bond.turnOff(self._device.device_id) await self._hub.bond.action(self._device.device_id, Action.turn_off())
def set_direction(self, direction: str) -> None: async def async_set_direction(self, direction: str):
"""Set fan rotation direction.""" """Set fan rotation direction."""
bond_direction = ( bond_direction = (
Directions.REVERSE if direction == DIRECTION_REVERSE else Directions.FORWARD Direction.REVERSE if direction == DIRECTION_REVERSE else Direction.FORWARD
)
await self._hub.bond.action(
self._device.device_id, Action.set_direction(bond_direction)
) )
self._hub.bond.setDirection(self._device.device_id, bond_direction)

View file

@ -1,7 +1,7 @@
"""Support for Bond lights.""" """Support for Bond lights."""
from typing import Any, Callable, List, Optional from typing import Any, Callable, List, Optional
from bond import DeviceTypes from bond_api import Action, DeviceType
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_BRIGHTNESS,
@ -29,13 +29,13 @@ async def async_setup_entry(
lights: List[Entity] = [ lights: List[Entity] = [
BondLight(hub, device) BondLight(hub, device)
for device in hub.devices for device in hub.devices
if device.type == DeviceTypes.CEILING_FAN and device.supports_light() if DeviceType.is_fan(device.type) and device.supports_light()
] ]
fireplaces: List[Entity] = [ fireplaces: List[Entity] = [
BondFireplace(hub, device) BondFireplace(hub, device)
for device in hub.devices for device in hub.devices
if device.type == DeviceTypes.FIREPLACE if DeviceType.is_fireplace(device.type)
] ]
async_add_entities(lights + fireplaces, True) async_add_entities(lights + fireplaces, True)
@ -55,18 +55,18 @@ class BondLight(BondEntity, LightEntity):
"""Return if light is currently on.""" """Return if light is currently on."""
return self._light == 1 return self._light == 1
def update(self): async def async_update(self):
"""Fetch assumed state of the light from the hub using API.""" """Fetch assumed state of the light from the hub using API."""
state: dict = self._hub.bond.getDeviceState(self._device.device_id) state: dict = await self._hub.bond.device_state(self._device.device_id)
self._light = state.get("light") self._light = state.get("light")
def turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on the light.""" """Turn on the light."""
self._hub.bond.turnLightOn(self._device.device_id) await self._hub.bond.action(self._device.device_id, Action.turn_light_on())
def turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off the light.""" """Turn off the light."""
self._hub.bond.turnLightOff(self._device.device_id) await self._hub.bond.action(self._device.device_id, Action.turn_light_off())
class BondFireplace(BondEntity, LightEntity): class BondFireplace(BondEntity, LightEntity):
@ -90,18 +90,18 @@ class BondFireplace(BondEntity, LightEntity):
"""Return True if power is on.""" """Return True if power is on."""
return self._power == 1 return self._power == 1
def turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the fireplace on.""" """Turn the fireplace on."""
self._hub.bond.turnOn(self._device.device_id)
brightness = kwargs.get(ATTR_BRIGHTNESS) brightness = kwargs.get(ATTR_BRIGHTNESS)
if brightness: if brightness:
flame = round((brightness * 100) / 255) flame = round((brightness * 100) / 255)
self._hub.bond.setFlame(self._device.device_id, flame) await self._hub.bond.action(self._device.device_id, Action.set_flame(flame))
else:
await self._hub.bond.action(self._device.device_id, Action.turn_on())
def turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the fireplace off.""" """Turn the fireplace off."""
self._hub.bond.turnOff(self._device.device_id) await self._hub.bond.action(self._device.device_id, Action.turn_off())
@property @property
def brightness(self): def brightness(self):
@ -113,8 +113,8 @@ class BondFireplace(BondEntity, LightEntity):
"""Show fireplace icon for the entity.""" """Show fireplace icon for the entity."""
return "mdi:fireplace" if self._power == 1 else "mdi:fireplace-off" return "mdi:fireplace" if self._power == 1 else "mdi:fireplace-off"
def update(self): async def async_update(self):
"""Fetch assumed state of the device from the hub using API.""" """Fetch assumed state of the device from the hub using API."""
state: dict = self._hub.bond.getDeviceState(self._device.device_id) state: dict = await self._hub.bond.device_state(self._device.device_id)
self._power = state.get("power") self._power = state.get("power")
self._flame = state.get("flame") self._flame = state.get("flame")

View file

@ -4,7 +4,7 @@
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/bond", "documentation": "https://www.home-assistant.io/integrations/bond",
"requirements": [ "requirements": [
"bond-home==0.0.9" "bond-api==0.1.4"
], ],
"codeowners": [ "codeowners": [
"@prystupa" "@prystupa"

View file

@ -1,13 +1,13 @@
"""Support for Bond generic devices.""" """Support for Bond generic devices."""
from typing import Any, Callable, List, Optional from typing import Any, Callable, List, Optional
from bond import DeviceTypes from bond_api import Action, DeviceType
from homeassistant.components.switch import SwitchEntity
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from ..switch import SwitchEntity
from .const import DOMAIN from .const import DOMAIN
from .entity import BondEntity from .entity import BondEntity
from .utils import BondDevice, BondHub from .utils import BondDevice, BondHub
@ -24,7 +24,7 @@ async def async_setup_entry(
switches = [ switches = [
BondSwitch(hub, device) BondSwitch(hub, device)
for device in hub.devices for device in hub.devices
if device.type == DeviceTypes.GENERIC_DEVICE if DeviceType.is_generic(device.type)
] ]
async_add_entities(switches, True) async_add_entities(switches, True)
@ -44,15 +44,15 @@ class BondSwitch(BondEntity, SwitchEntity):
"""Return True if power is on.""" """Return True if power is on."""
return self._power == 1 return self._power == 1
def turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the device on.""" """Turn the device on."""
self._hub.bond.turnOn(self._device.device_id) await self._hub.bond.action(self._device.device_id, Action.turn_on())
def turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the device off.""" """Turn the device off."""
self._hub.bond.turnOff(self._device.device_id) await self._hub.bond.action(self._device.device_id, Action.turn_off())
def update(self): async def async_update(self):
"""Fetch assumed state of the device from the hub using API.""" """Fetch assumed state of the device from the hub using API."""
state: dict = self._hub.bond.getDeviceState(self._device.device_id) state: dict = await self._hub.bond.device_state(self._device.device_id)
self._power = state.get("power") self._power = state.get("power")

View file

@ -2,7 +2,7 @@
from typing import List, Optional from typing import List, Optional
from bond import Actions, Bond from bond_api import Action, Bond
class BondDevice: class BondDevice:
@ -27,18 +27,12 @@ class BondDevice:
def supports_speed(self) -> bool: def supports_speed(self) -> bool:
"""Return True if this device supports any of the speed related commands.""" """Return True if this device supports any of the speed related commands."""
actions: List[str] = self._attrs["actions"] actions: List[str] = self._attrs["actions"]
return bool([action for action in actions if action in [Actions.SET_SPEED]]) return bool([action for action in actions if action in [Action.SET_SPEED]])
def supports_direction(self) -> bool: def supports_direction(self) -> bool:
"""Return True if this device supports any of the direction related commands.""" """Return True if this device supports any of the direction related commands."""
actions: List[str] = self._attrs["actions"] actions: List[str] = self._attrs["actions"]
return bool( return bool([action for action in actions if action in [Action.SET_DIRECTION]])
[
action
for action in actions
if action in [Actions.SET_DIRECTION, Actions.TOGGLE_DIRECTION]
]
)
def supports_light(self) -> bool: def supports_light(self) -> bool:
"""Return True if this device supports any of the light related commands.""" """Return True if this device supports any of the light related commands."""
@ -47,7 +41,7 @@ class BondDevice:
[ [
action action
for action in actions for action in actions
if action in [Actions.TURN_LIGHT_ON, Actions.TOGGLE_LIGHT] if action in [Action.TURN_LIGHT_ON, Action.TURN_LIGHT_OFF]
] ]
) )
@ -61,17 +55,17 @@ class BondHub:
self._version: Optional[dict] = None self._version: Optional[dict] = None
self._devices: Optional[List[BondDevice]] = None self._devices: Optional[List[BondDevice]] = None
def setup(self): async def setup(self):
"""Read hub version information.""" """Read hub version information."""
self._version = self.bond.getVersion() self._version = await self.bond.version()
# Fetch all available devices using Bond API. # Fetch all available devices using Bond API.
device_ids = self.bond.getDeviceIds() device_ids = await self.bond.devices()
self._devices = [ self._devices = [
BondDevice( BondDevice(
device_id, device_id,
self.bond.getDevice(device_id), await self.bond.device(device_id),
self.bond.getProperties(device_id), await self.bond.device_properties(device_id),
) )
for device_id in device_ids for device_id in device_ids
] ]

View file

@ -356,7 +356,7 @@ blockchain==1.4.4
bomradarloop==0.1.4 bomradarloop==0.1.4
# homeassistant.components.bond # homeassistant.components.bond
bond-home==0.0.9 bond-api==0.1.4
# homeassistant.components.amazon_polly # homeassistant.components.amazon_polly
# homeassistant.components.route53 # homeassistant.components.route53

View file

@ -181,7 +181,7 @@ blinkpy==0.15.1
bomradarloop==0.1.4 bomradarloop==0.1.4
# homeassistant.components.bond # homeassistant.components.bond
bond-home==0.0.9 bond-api==0.1.4
# homeassistant.components.braviatv # homeassistant.components.braviatv
bravia-tv==1.0.6 bravia-tv==1.0.6

View file

@ -21,9 +21,7 @@ async def setup_bond_entity(
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
with patch( with patch("homeassistant.components.bond.Bond.version", return_value=hub_version):
"homeassistant.components.bond.Bond.getVersion", return_value=hub_version
):
return await hass.config_entries.async_setup(config_entry.entry_id) return await hass.config_entries.async_setup(config_entry.entry_id)
@ -45,13 +43,15 @@ async def setup_platform(
mock_entry.add_to_hass(hass) mock_entry.add_to_hass(hass)
with patch("homeassistant.components.bond.PLATFORMS", [platform]), patch( with patch("homeassistant.components.bond.PLATFORMS", [platform]), patch(
"homeassistant.components.bond.Bond.getVersion", return_value=MOCK_HUB_VERSION "homeassistant.components.bond.Bond.version", return_value=MOCK_HUB_VERSION
), patch_bond_device_ids(return_value=[bond_device_id],), patch( ), patch_bond_device_ids(return_value=[bond_device_id],), patch(
"homeassistant.components.bond.Bond.getDevice", return_value=discovered_device "homeassistant.components.bond.Bond.device", return_value=discovered_device
), patch_bond_device_state( ), patch_bond_device_state(
return_value={} return_value={}
), patch( ), patch(
"homeassistant.components.bond.Bond.getProperties", return_value=props "homeassistant.components.bond.Bond.device_properties", return_value=props
), patch(
"homeassistant.components.bond.Bond.device_state", return_value={}
): ):
assert await async_setup_component(hass, BOND_DOMAIN, {}) assert await async_setup_component(hass, BOND_DOMAIN, {})
await hass.async_block_till_done() await hass.async_block_till_done()
@ -60,70 +60,25 @@ async def setup_platform(
def patch_bond_device_ids(return_value=None): def patch_bond_device_ids(return_value=None):
"""Patch Bond API getDeviceIds command.""" """Patch Bond API devices command."""
if return_value is None: if return_value is None:
return_value = [] return_value = []
return patch( return patch(
"homeassistant.components.bond.Bond.getDeviceIds", return_value=return_value, "homeassistant.components.bond.Bond.devices", return_value=return_value,
) )
def patch_bond_turn_on(): def patch_bond_action():
"""Patch Bond API turnOn command.""" """Patch Bond API action command."""
return patch("homeassistant.components.bond.Bond.turnOn") return patch("homeassistant.components.bond.Bond.action")
def patch_bond_turn_off():
"""Patch Bond API turnOff command."""
return patch("homeassistant.components.bond.Bond.turnOff")
def patch_bond_set_speed():
"""Patch Bond API setSpeed command."""
return patch("homeassistant.components.bond.Bond.setSpeed")
def patch_bond_set_flame():
"""Patch Bond API setFlame command."""
return patch("homeassistant.components.bond.Bond.setFlame")
def patch_bond_open():
"""Patch Bond API open command."""
return patch("homeassistant.components.bond.Bond.open")
def patch_bond_close():
"""Patch Bond API close command."""
return patch("homeassistant.components.bond.Bond.close")
def patch_bond_hold():
"""Patch Bond API hold command."""
return patch("homeassistant.components.bond.Bond.hold")
def patch_bond_set_direction():
"""Patch Bond API setDirection command."""
return patch("homeassistant.components.bond.Bond.setDirection")
def patch_turn_light_on():
"""Patch Bond API turnLightOn command."""
return patch("homeassistant.components.bond.Bond.turnLightOn")
def patch_turn_light_off():
"""Patch Bond API turnLightOff command."""
return patch("homeassistant.components.bond.Bond.turnLightOff")
def patch_bond_device_state(return_value=None): def patch_bond_device_state(return_value=None):
"""Patch Bond API getDeviceState command.""" """Patch Bond API device state endpoint."""
if return_value is None: if return_value is None:
return_value = {} return_value = {}
return patch( return patch(
"homeassistant.components.bond.Bond.getDeviceState", return_value=return_value "homeassistant.components.bond.Bond.device_state", return_value=return_value
) )

View file

@ -1,13 +1,12 @@
"""Test the Bond config flow.""" """Test the Bond config flow."""
from json import JSONDecodeError
from requests.exceptions import ConnectionError from aiohttp import ClientConnectionError, ClientResponseError
from homeassistant import config_entries, core, setup from homeassistant import config_entries, core, setup
from homeassistant.components.bond.const import DOMAIN from homeassistant.components.bond.const import DOMAIN
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST
from tests.async_mock import patch from tests.async_mock import Mock, patch
async def test_form(hass: core.HomeAssistant): async def test_form(hass: core.HomeAssistant):
@ -20,7 +19,7 @@ async def test_form(hass: core.HomeAssistant):
assert result["errors"] == {} assert result["errors"] == {}
with patch( with patch(
"homeassistant.components.bond.config_flow.Bond.getDeviceIds", return_value=[], "homeassistant.components.bond.config_flow.Bond.devices", return_value=[],
), patch( ), patch(
"homeassistant.components.bond.async_setup", return_value=True "homeassistant.components.bond.async_setup", return_value=True
) as mock_setup, patch( ) as mock_setup, patch(
@ -48,8 +47,8 @@ async def test_form_invalid_auth(hass: core.HomeAssistant):
) )
with patch( with patch(
"homeassistant.components.bond.config_flow.Bond.getDeviceIds", "homeassistant.components.bond.config_flow.Bond.devices",
side_effect=JSONDecodeError("test-message", "test-doc", 0), side_effect=ClientResponseError(Mock(), Mock(), status=401),
): ):
result2 = await hass.config_entries.flow.async_configure( result2 = await hass.config_entries.flow.async_configure(
result["flow_id"], {CONF_HOST: "1.1.1.1", CONF_ACCESS_TOKEN: "test-token"}, result["flow_id"], {CONF_HOST: "1.1.1.1", CONF_ACCESS_TOKEN: "test-token"},
@ -66,8 +65,8 @@ async def test_form_cannot_connect(hass: core.HomeAssistant):
) )
with patch( with patch(
"homeassistant.components.bond.config_flow.Bond.getDeviceIds", "homeassistant.components.bond.config_flow.Bond.devices",
side_effect=ConnectionError, side_effect=ClientConnectionError(),
): ):
result2 = await hass.config_entries.flow.async_configure( result2 = await hass.config_entries.flow.async_configure(
result["flow_id"], {CONF_HOST: "1.1.1.1", CONF_ACCESS_TOKEN: "test-token"}, result["flow_id"], {CONF_HOST: "1.1.1.1", CONF_ACCESS_TOKEN: "test-token"},
@ -84,8 +83,8 @@ async def test_form_unexpected_error(hass: core.HomeAssistant):
) )
with patch( with patch(
"homeassistant.components.bond.config_flow.Bond.getDeviceIds", "homeassistant.components.bond.config_flow.Bond.devices",
side_effect=Exception, side_effect=ClientResponseError(Mock(), Mock(), status=500),
): ):
result2 = await hass.config_entries.flow.async_configure( result2 = await hass.config_entries.flow.async_configure(
result["flow_id"], {CONF_HOST: "1.1.1.1", CONF_ACCESS_TOKEN: "test-token"}, result["flow_id"], {CONF_HOST: "1.1.1.1", CONF_ACCESS_TOKEN: "test-token"},

View file

@ -2,7 +2,7 @@
from datetime import timedelta from datetime import timedelta
import logging import logging
from bond import DeviceTypes from bond_api import Action, DeviceType
from homeassistant import core from homeassistant import core
from homeassistant.components.cover import DOMAIN as COVER_DOMAIN from homeassistant.components.cover import DOMAIN as COVER_DOMAIN
@ -15,13 +15,7 @@ from homeassistant.const import (
from homeassistant.helpers.entity_registry import EntityRegistry from homeassistant.helpers.entity_registry import EntityRegistry
from homeassistant.util import utcnow from homeassistant.util import utcnow
from .common import ( from .common import patch_bond_action, patch_bond_device_state, setup_platform
patch_bond_close,
patch_bond_device_state,
patch_bond_hold,
patch_bond_open,
setup_platform,
)
from tests.common import async_fire_time_changed from tests.common import async_fire_time_changed
@ -30,7 +24,7 @@ _LOGGER = logging.getLogger(__name__)
def shades(name: str): def shades(name: str):
"""Create motorized shades with given name.""" """Create motorized shades with given name."""
return {"name": name, "type": DeviceTypes.MOTORIZED_SHADES} return {"name": name, "type": DeviceType.MOTORIZED_SHADES}
async def test_entity_registry(hass: core.HomeAssistant): async def test_entity_registry(hass: core.HomeAssistant):
@ -43,9 +37,11 @@ async def test_entity_registry(hass: core.HomeAssistant):
async def test_open_cover(hass: core.HomeAssistant): async def test_open_cover(hass: core.HomeAssistant):
"""Tests that open cover command delegates to API.""" """Tests that open cover command delegates to API."""
await setup_platform(hass, COVER_DOMAIN, shades("name-1")) await setup_platform(
hass, COVER_DOMAIN, shades("name-1"), bond_device_id="test-device-id"
)
with patch_bond_open() as mock_open, patch_bond_device_state(): with patch_bond_action() as mock_open, patch_bond_device_state():
await hass.services.async_call( await hass.services.async_call(
COVER_DOMAIN, COVER_DOMAIN,
SERVICE_OPEN_COVER, SERVICE_OPEN_COVER,
@ -53,14 +49,17 @@ async def test_open_cover(hass: core.HomeAssistant):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
mock_open.assert_called_once()
mock_open.assert_called_once_with("test-device-id", Action.open())
async def test_close_cover(hass: core.HomeAssistant): async def test_close_cover(hass: core.HomeAssistant):
"""Tests that close cover command delegates to API.""" """Tests that close cover command delegates to API."""
await setup_platform(hass, COVER_DOMAIN, shades("name-1")) await setup_platform(
hass, COVER_DOMAIN, shades("name-1"), bond_device_id="test-device-id"
)
with patch_bond_close() as mock_close, patch_bond_device_state(): with patch_bond_action() as mock_close, patch_bond_device_state():
await hass.services.async_call( await hass.services.async_call(
COVER_DOMAIN, COVER_DOMAIN,
SERVICE_CLOSE_COVER, SERVICE_CLOSE_COVER,
@ -68,14 +67,17 @@ async def test_close_cover(hass: core.HomeAssistant):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
mock_close.assert_called_once()
mock_close.assert_called_once_with("test-device-id", Action.close())
async def test_stop_cover(hass: core.HomeAssistant): async def test_stop_cover(hass: core.HomeAssistant):
"""Tests that stop cover command delegates to API.""" """Tests that stop cover command delegates to API."""
await setup_platform(hass, COVER_DOMAIN, shades("name-1")) await setup_platform(
hass, COVER_DOMAIN, shades("name-1"), bond_device_id="test-device-id"
)
with patch_bond_hold() as mock_hold, patch_bond_device_state(): with patch_bond_action() as mock_hold, patch_bond_device_state():
await hass.services.async_call( await hass.services.async_call(
COVER_DOMAIN, COVER_DOMAIN,
SERVICE_STOP_COVER, SERVICE_STOP_COVER,
@ -83,7 +85,8 @@ async def test_stop_cover(hass: core.HomeAssistant):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
mock_hold.assert_called_once()
mock_hold.assert_called_once_with("test-device-id", Action.hold())
async def test_update_reports_open_cover(hass: core.HomeAssistant): async def test_update_reports_open_cover(hass: core.HomeAssistant):

View file

@ -1,7 +1,8 @@
"""Tests for the Bond fan device.""" """Tests for the Bond fan device."""
from datetime import timedelta from datetime import timedelta
from typing import Optional
from bond import DeviceTypes, Directions from bond_api import Action, DeviceType, Direction
from homeassistant import core from homeassistant import core
from homeassistant.components import fan from homeassistant.components import fan
@ -17,14 +18,7 @@ from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_OFF, SERVICE_TURN_O
from homeassistant.helpers.entity_registry import EntityRegistry from homeassistant.helpers.entity_registry import EntityRegistry
from homeassistant.util import utcnow from homeassistant.util import utcnow
from .common import ( from .common import patch_bond_action, patch_bond_device_state, setup_platform
patch_bond_device_state,
patch_bond_set_direction,
patch_bond_set_speed,
patch_bond_turn_off,
patch_bond_turn_on,
setup_platform,
)
from tests.common import async_fire_time_changed from tests.common import async_fire_time_changed
@ -33,18 +27,20 @@ def ceiling_fan(name: str):
"""Create a ceiling fan with given name.""" """Create a ceiling fan with given name."""
return { return {
"name": name, "name": name,
"type": DeviceTypes.CEILING_FAN, "type": DeviceType.CEILING_FAN,
"actions": ["SetSpeed", "SetDirection"], "actions": ["SetSpeed", "SetDirection"],
} }
async def turn_fan_on(hass: core.HomeAssistant, fan_id: str, speed: str) -> None: async def turn_fan_on(
hass: core.HomeAssistant, fan_id: str, speed: Optional[str] = None
) -> None:
"""Turn the fan on at the specified speed.""" """Turn the fan on at the specified speed."""
service_data = {ATTR_ENTITY_ID: fan_id}
if speed:
service_data[fan.ATTR_SPEED] = speed
await hass.services.async_call( await hass.services.async_call(
FAN_DOMAIN, FAN_DOMAIN, SERVICE_TURN_ON, service_data=service_data, blocking=True,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: fan_id, fan.ATTR_SPEED: speed},
blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
@ -57,7 +53,7 @@ async def test_entity_registry(hass: core.HomeAssistant):
assert [key for key in registry.entities] == ["fan.name_1"] assert [key for key in registry.entities] == ["fan.name_1"]
async def test_entity_non_standard_speed_list(hass: core.HomeAssistant): async def test_non_standard_speed_list(hass: core.HomeAssistant):
"""Tests that the device is registered with custom speed list if number of supported speeds differs form 3.""" """Tests that the device is registered with custom speed list if number of supported speeds differs form 3."""
await setup_platform( await setup_platform(
hass, hass,
@ -76,41 +72,62 @@ async def test_entity_non_standard_speed_list(hass: core.HomeAssistant):
] ]
with patch_bond_device_state(): with patch_bond_device_state():
with patch_bond_turn_on(), patch_bond_set_speed() as mock_set_speed_low: with patch_bond_action() as mock_set_speed_low:
await turn_fan_on(hass, "fan.name_1", fan.SPEED_LOW) await turn_fan_on(hass, "fan.name_1", fan.SPEED_LOW)
mock_set_speed_low.assert_called_once_with("test-device-id", speed=1) mock_set_speed_low.assert_called_once_with(
"test-device-id", Action.set_speed(1)
)
with patch_bond_turn_on(), patch_bond_set_speed() as mock_set_speed_medium: with patch_bond_action() as mock_set_speed_medium:
await turn_fan_on(hass, "fan.name_1", fan.SPEED_MEDIUM) await turn_fan_on(hass, "fan.name_1", fan.SPEED_MEDIUM)
mock_set_speed_medium.assert_called_once_with("test-device-id", speed=3) mock_set_speed_medium.assert_called_once_with(
"test-device-id", Action.set_speed(3)
)
with patch_bond_turn_on(), patch_bond_set_speed() as mock_set_speed_high: with patch_bond_action() as mock_set_speed_high:
await turn_fan_on(hass, "fan.name_1", fan.SPEED_HIGH) await turn_fan_on(hass, "fan.name_1", fan.SPEED_HIGH)
mock_set_speed_high.assert_called_once_with("test-device-id", speed=6) mock_set_speed_high.assert_called_once_with(
"test-device-id", Action.set_speed(6)
)
async def test_turn_on_fan(hass: core.HomeAssistant): async def test_turn_on_fan_with_speed(hass: core.HomeAssistant):
"""Tests that turn on command delegates to API.""" """Tests that turn on command delegates to set speed API."""
await setup_platform(hass, FAN_DOMAIN, ceiling_fan("name-1")) await setup_platform(
hass, FAN_DOMAIN, ceiling_fan("name-1"), bond_device_id="test-device-id"
)
with patch_bond_turn_on() as mock_turn_on, patch_bond_set_speed() as mock_set_speed, patch_bond_device_state(): with patch_bond_action() as mock_set_speed, patch_bond_device_state():
await turn_fan_on(hass, "fan.name_1", fan.SPEED_LOW) await turn_fan_on(hass, "fan.name_1", fan.SPEED_LOW)
mock_set_speed.assert_called_once() mock_set_speed.assert_called_with("test-device-id", Action.set_speed(1))
mock_turn_on.assert_called_once()
async def test_turn_on_fan_without_speed(hass: core.HomeAssistant):
"""Tests that turn on command delegates to turn on API."""
await setup_platform(
hass, FAN_DOMAIN, ceiling_fan("name-1"), bond_device_id="test-device-id"
)
with patch_bond_action() as mock_turn_on, patch_bond_device_state():
await turn_fan_on(hass, "fan.name_1")
mock_turn_on.assert_called_with("test-device-id", Action.turn_on())
async def test_turn_off_fan(hass: core.HomeAssistant): async def test_turn_off_fan(hass: core.HomeAssistant):
"""Tests that turn off command delegates to API.""" """Tests that turn off command delegates to API."""
await setup_platform(hass, FAN_DOMAIN, ceiling_fan("name-1")) await setup_platform(
hass, FAN_DOMAIN, ceiling_fan("name-1"), bond_device_id="test-device-id"
)
with patch_bond_turn_off() as mock_turn_off, patch_bond_device_state(): with patch_bond_action() as mock_turn_off, patch_bond_device_state():
await hass.services.async_call( await hass.services.async_call(
FAN_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: "fan.name_1"}, blocking=True, FAN_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: "fan.name_1"}, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
mock_turn_off.assert_called_once() mock_turn_off.assert_called_once_with("test-device-id", Action.turn_off())
async def test_update_reports_fan_on(hass: core.HomeAssistant): async def test_update_reports_fan_on(hass: core.HomeAssistant):
@ -139,7 +156,7 @@ async def test_update_reports_direction_forward(hass: core.HomeAssistant):
"""Tests that update command sets correct direction when Bond API reports fan direction is forward.""" """Tests that update command sets correct direction when Bond API reports fan direction is forward."""
await setup_platform(hass, FAN_DOMAIN, ceiling_fan("name-1")) await setup_platform(hass, FAN_DOMAIN, ceiling_fan("name-1"))
with patch_bond_device_state(return_value={"direction": Directions.FORWARD}): with patch_bond_device_state(return_value={"direction": Direction.FORWARD}):
async_fire_time_changed(hass, utcnow() + timedelta(seconds=30)) async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
await hass.async_block_till_done() await hass.async_block_till_done()
@ -150,7 +167,7 @@ async def test_update_reports_direction_reverse(hass: core.HomeAssistant):
"""Tests that update command sets correct direction when Bond API reports fan direction is reverse.""" """Tests that update command sets correct direction when Bond API reports fan direction is reverse."""
await setup_platform(hass, FAN_DOMAIN, ceiling_fan("name-1")) await setup_platform(hass, FAN_DOMAIN, ceiling_fan("name-1"))
with patch_bond_device_state(return_value={"direction": Directions.REVERSE}): with patch_bond_device_state(return_value={"direction": Direction.REVERSE}):
async_fire_time_changed(hass, utcnow() + timedelta(seconds=30)) async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
await hass.async_block_till_done() await hass.async_block_till_done()
@ -159,9 +176,11 @@ async def test_update_reports_direction_reverse(hass: core.HomeAssistant):
async def test_set_fan_direction(hass: core.HomeAssistant): async def test_set_fan_direction(hass: core.HomeAssistant):
"""Tests that set direction command delegates to API.""" """Tests that set direction command delegates to API."""
await setup_platform(hass, FAN_DOMAIN, ceiling_fan("name-1")) await setup_platform(
hass, FAN_DOMAIN, ceiling_fan("name-1"), bond_device_id="test-device-id"
)
with patch_bond_set_direction() as mock_set_direction, patch_bond_device_state(): with patch_bond_action() as mock_set_direction, patch_bond_device_state():
await hass.services.async_call( await hass.services.async_call(
FAN_DOMAIN, FAN_DOMAIN,
SERVICE_SET_DIRECTION, SERVICE_SET_DIRECTION,
@ -169,4 +188,7 @@ async def test_set_fan_direction(hass: core.HomeAssistant):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
mock_set_direction.assert_called_once()
mock_set_direction.assert_called_once_with(
"test-device-id", Action.set_direction(Direction.FORWARD)
)

View file

@ -2,7 +2,7 @@
from datetime import timedelta from datetime import timedelta
import logging import logging
from bond import Actions, DeviceTypes from bond_api import Action, DeviceType
from homeassistant import core from homeassistant import core
from homeassistant.components.light import ATTR_BRIGHTNESS, DOMAIN as LIGHT_DOMAIN from homeassistant.components.light import ATTR_BRIGHTNESS, DOMAIN as LIGHT_DOMAIN
@ -10,15 +10,7 @@ from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_OFF, SERVICE_TURN_O
from homeassistant.helpers.entity_registry import EntityRegistry from homeassistant.helpers.entity_registry import EntityRegistry
from homeassistant.util import utcnow from homeassistant.util import utcnow
from .common import ( from .common import patch_bond_action, patch_bond_device_state, setup_platform
patch_bond_device_state,
patch_bond_set_flame,
patch_bond_turn_off,
patch_bond_turn_on,
patch_turn_light_off,
patch_turn_light_on,
setup_platform,
)
from tests.common import async_fire_time_changed from tests.common import async_fire_time_changed
@ -29,14 +21,14 @@ def ceiling_fan(name: str):
"""Create a ceiling fan (that has built-in light) with given name.""" """Create a ceiling fan (that has built-in light) with given name."""
return { return {
"name": name, "name": name,
"type": DeviceTypes.CEILING_FAN, "type": DeviceType.CEILING_FAN,
"actions": [Actions.TOGGLE_LIGHT], "actions": [Action.TURN_LIGHT_ON, Action.TURN_LIGHT_OFF],
} }
def fireplace(name: str): def fireplace(name: str):
"""Create a fireplace with given name.""" """Create a fireplace with given name."""
return {"name": name, "type": DeviceTypes.FIREPLACE} return {"name": name, "type": DeviceType.FIREPLACE}
async def test_entity_registry(hass: core.HomeAssistant): async def test_entity_registry(hass: core.HomeAssistant):
@ -49,9 +41,11 @@ async def test_entity_registry(hass: core.HomeAssistant):
async def test_turn_on_light(hass: core.HomeAssistant): async def test_turn_on_light(hass: core.HomeAssistant):
"""Tests that turn on command delegates to API.""" """Tests that turn on command delegates to API."""
await setup_platform(hass, LIGHT_DOMAIN, ceiling_fan("name-1")) await setup_platform(
hass, LIGHT_DOMAIN, ceiling_fan("name-1"), bond_device_id="test-device-id"
)
with patch_turn_light_on() as mock_turn_light_on, patch_bond_device_state(): with patch_bond_action() as mock_turn_light_on, patch_bond_device_state():
await hass.services.async_call( await hass.services.async_call(
LIGHT_DOMAIN, LIGHT_DOMAIN,
SERVICE_TURN_ON, SERVICE_TURN_ON,
@ -59,14 +53,17 @@ async def test_turn_on_light(hass: core.HomeAssistant):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
mock_turn_light_on.assert_called_once()
mock_turn_light_on.assert_called_once_with("test-device-id", Action.turn_light_on())
async def test_turn_off_light(hass: core.HomeAssistant): async def test_turn_off_light(hass: core.HomeAssistant):
"""Tests that turn off command delegates to API.""" """Tests that turn off command delegates to API."""
await setup_platform(hass, LIGHT_DOMAIN, ceiling_fan("name-1")) await setup_platform(
hass, LIGHT_DOMAIN, ceiling_fan("name-1"), bond_device_id="test-device-id"
)
with patch_turn_light_off() as mock_turn_light_off, patch_bond_device_state(): with patch_bond_action() as mock_turn_light_off, patch_bond_device_state():
await hass.services.async_call( await hass.services.async_call(
LIGHT_DOMAIN, LIGHT_DOMAIN,
SERVICE_TURN_OFF, SERVICE_TURN_OFF,
@ -74,7 +71,10 @@ async def test_turn_off_light(hass: core.HomeAssistant):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
mock_turn_light_off.assert_called_once()
mock_turn_light_off.assert_called_once_with(
"test-device-id", Action.turn_light_off()
)
async def test_update_reports_light_is_on(hass: core.HomeAssistant): async def test_update_reports_light_is_on(hass: core.HomeAssistant):
@ -99,13 +99,13 @@ async def test_update_reports_light_is_off(hass: core.HomeAssistant):
assert hass.states.get("light.name_1").state == "off" assert hass.states.get("light.name_1").state == "off"
async def test_turn_on_fireplace(hass: core.HomeAssistant): async def test_turn_on_fireplace_with_brightness(hass: core.HomeAssistant):
"""Tests that turn on command delegates to API.""" """Tests that turn on command delegates to set flame API."""
await setup_platform( await setup_platform(
hass, LIGHT_DOMAIN, fireplace("name-1"), bond_device_id="test-device-id" hass, LIGHT_DOMAIN, fireplace("name-1"), bond_device_id="test-device-id"
) )
with patch_bond_turn_on() as mock_turn_on, patch_bond_set_flame() as mock_set_flame, patch_bond_device_state(): with patch_bond_action() as mock_set_flame, patch_bond_device_state():
await hass.services.async_call( await hass.services.async_call(
LIGHT_DOMAIN, LIGHT_DOMAIN,
SERVICE_TURN_ON, SERVICE_TURN_ON,
@ -114,15 +114,34 @@ async def test_turn_on_fireplace(hass: core.HomeAssistant):
) )
await hass.async_block_till_done() await hass.async_block_till_done()
mock_turn_on.assert_called_once() mock_set_flame.assert_called_once_with("test-device-id", Action.set_flame(50))
mock_set_flame.assert_called_once_with("test-device-id", 50)
async def test_turn_on_fireplace_without_brightness(hass: core.HomeAssistant):
"""Tests that turn on command delegates to turn on API."""
await setup_platform(
hass, LIGHT_DOMAIN, fireplace("name-1"), bond_device_id="test-device-id"
)
with patch_bond_action() as mock_turn_on, patch_bond_device_state():
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "light.name_1"},
blocking=True,
)
await hass.async_block_till_done()
mock_turn_on.assert_called_once_with("test-device-id", Action.turn_on())
async def test_turn_off_fireplace(hass: core.HomeAssistant): async def test_turn_off_fireplace(hass: core.HomeAssistant):
"""Tests that turn off command delegates to API.""" """Tests that turn off command delegates to API."""
await setup_platform(hass, LIGHT_DOMAIN, fireplace("name-1")) await setup_platform(
hass, LIGHT_DOMAIN, fireplace("name-1"), bond_device_id="test-device-id"
)
with patch_bond_turn_off() as mock_turn_off, patch_bond_device_state(): with patch_bond_action() as mock_turn_off, patch_bond_device_state():
await hass.services.async_call( await hass.services.async_call(
LIGHT_DOMAIN, LIGHT_DOMAIN,
SERVICE_TURN_OFF, SERVICE_TURN_OFF,
@ -130,7 +149,8 @@ async def test_turn_off_fireplace(hass: core.HomeAssistant):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
mock_turn_off.assert_called_once()
mock_turn_off.assert_called_once_with("test-device-id", Action.turn_off())
async def test_flame_converted_to_brightness(hass: core.HomeAssistant): async def test_flame_converted_to_brightness(hass: core.HomeAssistant):
@ -141,5 +161,4 @@ async def test_flame_converted_to_brightness(hass: core.HomeAssistant):
async_fire_time_changed(hass, utcnow() + timedelta(seconds=30)) async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
await hass.async_block_till_done() await hass.async_block_till_done()
_LOGGER.warning(hass.states.get("light.name_1").attributes)
assert hass.states.get("light.name_1").attributes[ATTR_BRIGHTNESS] == 128 assert hass.states.get("light.name_1").attributes[ATTR_BRIGHTNESS] == 128

View file

@ -2,7 +2,7 @@
from datetime import timedelta from datetime import timedelta
import logging import logging
from bond import DeviceTypes from bond_api import Action, DeviceType
from homeassistant import core from homeassistant import core
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
@ -10,12 +10,7 @@ from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_OFF, SERVICE_TURN_O
from homeassistant.helpers.entity_registry import EntityRegistry from homeassistant.helpers.entity_registry import EntityRegistry
from homeassistant.util import utcnow from homeassistant.util import utcnow
from .common import ( from .common import patch_bond_action, patch_bond_device_state, setup_platform
patch_bond_device_state,
patch_bond_turn_off,
patch_bond_turn_on,
setup_platform,
)
from tests.common import async_fire_time_changed from tests.common import async_fire_time_changed
@ -24,7 +19,7 @@ _LOGGER = logging.getLogger(__name__)
def generic_device(name: str): def generic_device(name: str):
"""Create a generic device with given name.""" """Create a generic device with given name."""
return {"name": name, "type": DeviceTypes.GENERIC_DEVICE} return {"name": name, "type": DeviceType.GENERIC_DEVICE}
async def test_entity_registry(hass: core.HomeAssistant): async def test_entity_registry(hass: core.HomeAssistant):
@ -37,9 +32,11 @@ async def test_entity_registry(hass: core.HomeAssistant):
async def test_turn_on_switch(hass: core.HomeAssistant): async def test_turn_on_switch(hass: core.HomeAssistant):
"""Tests that turn on command delegates to API.""" """Tests that turn on command delegates to API."""
await setup_platform(hass, SWITCH_DOMAIN, generic_device("name-1")) await setup_platform(
hass, SWITCH_DOMAIN, generic_device("name-1"), bond_device_id="test-device-id"
)
with patch_bond_turn_on() as mock_turn_on, patch_bond_device_state(): with patch_bond_action() as mock_turn_on, patch_bond_device_state():
await hass.services.async_call( await hass.services.async_call(
SWITCH_DOMAIN, SWITCH_DOMAIN,
SERVICE_TURN_ON, SERVICE_TURN_ON,
@ -47,14 +44,17 @@ async def test_turn_on_switch(hass: core.HomeAssistant):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
mock_turn_on.assert_called_once()
mock_turn_on.assert_called_once_with("test-device-id", Action.turn_on())
async def test_turn_off_switch(hass: core.HomeAssistant): async def test_turn_off_switch(hass: core.HomeAssistant):
"""Tests that turn off command delegates to API.""" """Tests that turn off command delegates to API."""
await setup_platform(hass, SWITCH_DOMAIN, generic_device("name-1")) await setup_platform(
hass, SWITCH_DOMAIN, generic_device("name-1"), bond_device_id="test-device-id"
)
with patch_bond_turn_off() as mock_turn_off, patch_bond_device_state(): with patch_bond_action() as mock_turn_off, patch_bond_device_state():
await hass.services.async_call( await hass.services.async_call(
SWITCH_DOMAIN, SWITCH_DOMAIN,
SERVICE_TURN_OFF, SERVICE_TURN_OFF,
@ -62,7 +62,8 @@ async def test_turn_off_switch(hass: core.HomeAssistant):
blocking=True, blocking=True,
) )
await hass.async_block_till_done() await hass.async_block_till_done()
mock_turn_off.assert_called_once()
mock_turn_off.assert_called_once_with("test-device-id", Action.turn_off())
async def test_update_reports_switch_is_on(hass: core.HomeAssistant): async def test_update_reports_switch_is_on(hass: core.HomeAssistant):