Add support for generic device (switch) to bond integration (#37837)

This commit is contained in:
Eugene Prystupa 2020-07-14 09:54:33 -04:00 committed by GitHub
parent f0916aeb86
commit 515ad6164d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 152 additions and 2 deletions

View File

@ -11,7 +11,7 @@ from homeassistant.helpers import device_registry as dr
from .const import DOMAIN
from .utils import BondHub
PLATFORMS = ["cover", "fan", "light"]
PLATFORMS = ["cover", "fan", "light", "switch"]
async def async_setup(hass: HomeAssistant, config: dict):

View File

@ -0,0 +1,60 @@
"""Support for Bond generic devices."""
from typing import Any, Callable, List, Optional
from bond import DeviceTypes
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import Entity
from ..switch import SwitchEntity
from .const import DOMAIN
from .entity import BondEntity
from .utils import BondDevice, BondHub
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: Callable[[List[Entity], bool], None],
) -> None:
"""Set up Bond generic devices."""
hub: BondHub = hass.data[DOMAIN][entry.entry_id]
devices = await hass.async_add_executor_job(hub.get_bond_devices)
switches = [
BondSwitch(hub, device)
for device in devices
if device.type == DeviceTypes.GENERIC_DEVICE
]
async_add_entities(switches, True)
class BondSwitch(BondEntity, SwitchEntity):
"""Representation of a Bond generic device."""
def __init__(self, hub: BondHub, device: BondDevice):
"""Create HA entity representing Bond generic device (switch)."""
super().__init__(hub, device)
self._power: Optional[bool] = None
@property
def is_on(self) -> bool:
"""Return True if power is on."""
return self._power == 1
def turn_on(self, **kwargs: Any) -> None:
"""Turn the device on."""
self._hub.bond.turnOn(self._device.device_id)
def turn_off(self, **kwargs: Any) -> None:
"""Turn the device off."""
self._hub.bond.turnOff(self._device.device_id)
def update(self):
"""Fetch assumed state of the device from the hub using API."""
state: dict = self._hub.bond.getDeviceState(self._device.device_id)
self._power = state.get("power")

View File

@ -31,7 +31,9 @@ async def test_async_setup_entry_sets_up_hub_and_supported_domains(hass: HomeAss
"homeassistant.components.bond.fan.async_setup_entry"
) as mock_fan_async_setup_entry, patch(
"homeassistant.components.bond.light.async_setup_entry"
) as mock_light_async_setup_entry:
) as mock_light_async_setup_entry, patch(
"homeassistant.components.bond.switch.async_setup_entry"
) as mock_switch_async_setup_entry:
result = await setup_bond_entity(
hass,
config_entry,
@ -61,6 +63,7 @@ async def test_async_setup_entry_sets_up_hub_and_supported_domains(hass: HomeAss
assert len(mock_cover_async_setup_entry.mock_calls) == 1
assert len(mock_fan_async_setup_entry.mock_calls) == 1
assert len(mock_light_async_setup_entry.mock_calls) == 1
assert len(mock_switch_async_setup_entry.mock_calls) == 1
async def test_unload_config_entry(hass: HomeAssistant):

View File

@ -0,0 +1,87 @@
"""Tests for the Bond switch device."""
from datetime import timedelta
import logging
from bond import DeviceTypes
from homeassistant import core
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_OFF, SERVICE_TURN_ON
from homeassistant.helpers.entity_registry import EntityRegistry
from homeassistant.util import utcnow
from .common import setup_platform
from tests.async_mock import patch
from tests.common import async_fire_time_changed
_LOGGER = logging.getLogger(__name__)
def generic_device(name: str):
"""Create a generic device with given name."""
return {"name": name, "type": DeviceTypes.GENERIC_DEVICE}
async def test_entity_registry(hass: core.HomeAssistant):
"""Tests that the devices are registered in the entity registry."""
await setup_platform(hass, SWITCH_DOMAIN, generic_device("name-1"))
registry: EntityRegistry = await hass.helpers.entity_registry.async_get_registry()
assert [key for key in registry.entities] == ["switch.name_1"]
async def test_turn_on_switch(hass: core.HomeAssistant):
"""Tests that turn on command delegates to API."""
await setup_platform(hass, SWITCH_DOMAIN, generic_device("name-1"))
with patch("homeassistant.components.bond.Bond.turnOn") as mock_turn_on:
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "switch.name_1"},
blocking=True,
)
await hass.async_block_till_done()
mock_turn_on.assert_called_once()
async def test_turn_off_switch(hass: core.HomeAssistant):
"""Tests that turn off command delegates to API."""
await setup_platform(hass, SWITCH_DOMAIN, generic_device("name-1"))
with patch("homeassistant.components.bond.Bond.turnOff") as mock_turn_off:
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: "switch.name_1"},
blocking=True,
)
await hass.async_block_till_done()
mock_turn_off.assert_called_once()
async def test_update_reports_switch_is_on(hass: core.HomeAssistant):
"""Tests that update command sets correct state when Bond API reports the device is on."""
await setup_platform(hass, SWITCH_DOMAIN, generic_device("name-1"))
with patch(
"homeassistant.components.bond.Bond.getDeviceState", return_value={"power": 1}
):
async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
await hass.async_block_till_done()
assert hass.states.get("switch.name_1").state == "on"
async def test_update_reports_switch_is_off(hass: core.HomeAssistant):
"""Tests that update command sets correct state when Bond API reports the device is off."""
await setup_platform(hass, SWITCH_DOMAIN, generic_device("name-1"))
with patch(
"homeassistant.components.bond.Bond.getDeviceState", return_value={"power": 0}
):
async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
await hass.async_block_till_done()
assert hass.states.get("switch.name_1").state == "off"