Add state belief services to bond integration (#54735)

Co-authored-by: J. Nick Koston <nick@koston.org>
pull/56026/head
joshs85 2021-09-09 09:32:32 -04:00 committed by GitHub
parent cbbbc3c4f0
commit 011817b122
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 678 additions and 10 deletions

View File

@ -73,7 +73,7 @@ homeassistant/components/blink/* @fronzbot
homeassistant/components/blueprint/* @home-assistant/core
homeassistant/components/bmp280/* @belidzs
homeassistant/components/bmw_connected_drive/* @gerard33 @rikroe
homeassistant/components/bond/* @prystupa
homeassistant/components/bond/* @prystupa @joshs85
homeassistant/components/bosch_shc/* @tschamm
homeassistant/components/braviatv/* @bieniu @Drafteed
homeassistant/components/broadlink/* @danielhiversen @felipediel

View File

@ -10,3 +10,9 @@ CONF_BOND_ID: str = "bond_id"
HUB = "hub"
BPUP_SUBS = "bpup_subs"
BPUP_STOP = "bpup_stop"
SERVICE_SET_FAN_SPEED_BELIEF = "set_fan_speed_belief"
SERVICE_SET_POWER_BELIEF = "set_switch_power_belief"
SERVICE_SET_LIGHT_POWER_BELIEF = "set_light_power_belief"
SERVICE_SET_LIGHT_BRIGHTNESS_BELIEF = "set_light_brightness_belief"
ATTR_POWER_STATE = "power_state"

View File

@ -5,9 +5,12 @@ import logging
import math
from typing import Any
from aiohttp.client_exceptions import ClientResponseError
from bond_api import Action, BPUPSubscriptions, DeviceType, Direction
import voluptuous as vol
from homeassistant.components.fan import (
ATTR_SPEED,
DIRECTION_FORWARD,
DIRECTION_REVERSE,
SUPPORT_DIRECTION,
@ -16,6 +19,8 @@ from homeassistant.components.fan import (
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_platform
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util.percentage import (
@ -24,7 +29,7 @@ from homeassistant.util.percentage import (
ranged_value_to_percentage,
)
from .const import BPUP_SUBS, DOMAIN, HUB
from .const import BPUP_SUBS, DOMAIN, HUB, SERVICE_SET_FAN_SPEED_BELIEF
from .entity import BondEntity
from .utils import BondDevice, BondHub
@ -40,6 +45,7 @@ async def async_setup_entry(
data = hass.data[DOMAIN][entry.entry_id]
hub: BondHub = data[HUB]
bpup_subs: BPUPSubscriptions = data[BPUP_SUBS]
platform = entity_platform.async_get_current_platform()
fans: list[Entity] = [
BondFan(hub, device, bpup_subs)
@ -47,6 +53,12 @@ async def async_setup_entry(
if DeviceType.is_fan(device.type)
]
platform.async_register_entity_service(
SERVICE_SET_FAN_SPEED_BELIEF,
{vol.Required(ATTR_SPEED): vol.All(vol.Number(scale=0), vol.Range(0, 100))},
"async_set_speed_belief",
)
async_add_entities(fans, True)
@ -128,6 +140,41 @@ class BondFan(BondEntity, FanEntity):
self._device.device_id, Action.set_speed(bond_speed)
)
async def async_set_power_belief(self, power_state: bool) -> None:
"""Set the believed state to on or off."""
try:
await self._hub.bond.action(
self._device.device_id, Action.set_power_state_belief(power_state)
)
except ClientResponseError as ex:
raise HomeAssistantError(
f"The bond API returned an error calling set_power_state_belief for {self.entity_id}. Code: {ex.code} Message: {ex.message}"
) from ex
async def async_set_speed_belief(self, speed: int) -> None:
"""Set the believed speed for the fan."""
_LOGGER.debug("async_set_speed_belief called with percentage %s", speed)
if speed == 0:
await self.async_set_power_belief(False)
return
await self.async_set_power_belief(True)
bond_speed = math.ceil(percentage_to_ranged_value(self._speed_range, speed))
_LOGGER.debug(
"async_set_percentage converted percentage %s to bond speed %s",
speed,
bond_speed,
)
try:
await self._hub.bond.action(
self._device.device_id, Action.set_speed_belief(bond_speed)
)
except ClientResponseError as ex:
raise HomeAssistantError(
f"The bond API returned an error calling set_speed_belief for {self.entity_id}. Code: {ex.code} Message: {ex.message}"
) from ex
async def async_turn_on(
self,
speed: str | None = None,

View File

@ -4,7 +4,9 @@ from __future__ import annotations
import logging
from typing import Any
from aiohttp.client_exceptions import ClientResponseError
from bond_api import Action, BPUPSubscriptions, DeviceType
import voluptuous as vol
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
@ -14,12 +16,19 @@ from homeassistant.components.light import (
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_platform
from homeassistant.helpers import config_validation as cv, entity_platform
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import BondHub
from .const import BPUP_SUBS, DOMAIN, HUB
from .const import (
ATTR_POWER_STATE,
BPUP_SUBS,
DOMAIN,
HUB,
SERVICE_SET_LIGHT_BRIGHTNESS_BELIEF,
SERVICE_SET_LIGHT_POWER_BELIEF,
)
from .entity import BondEntity
from .utils import BondDevice
@ -45,6 +54,7 @@ async def async_setup_entry(
data = hass.data[DOMAIN][entry.entry_id]
hub: BondHub = data[HUB]
bpup_subs: BPUPSubscriptions = data[BPUP_SUBS]
platform = entity_platform.async_get_current_platform()
platform = entity_platform.async_get_current_platform()
for service in ENTITY_SERVICES:
@ -92,6 +102,22 @@ async def async_setup_entry(
if DeviceType.is_light(device.type)
]
platform.async_register_entity_service(
SERVICE_SET_LIGHT_BRIGHTNESS_BELIEF,
{
vol.Required(ATTR_BRIGHTNESS): vol.All(
vol.Number(scale=0), vol.Range(0, 255)
)
},
"async_set_brightness_belief",
)
platform.async_register_entity_service(
SERVICE_SET_LIGHT_POWER_BELIEF,
{vol.Required(ATTR_POWER_STATE): vol.All(cv.boolean)},
"async_set_power_belief",
)
async_add_entities(
fan_lights + fan_up_lights + fan_down_lights + fireplaces + fp_lights + lights,
True,
@ -103,6 +129,34 @@ class BondBaseLight(BondEntity, LightEntity):
_attr_supported_features = 0
async def async_set_brightness_belief(self, brightness: int) -> None:
"""Set the belief state of the light."""
if not self._device.supports_set_brightness():
raise HomeAssistantError("This device does not support setting brightness")
if brightness == 0:
await self.async_set_power_belief(False)
return
try:
await self._hub.bond.action(
self._device.device_id,
Action.set_brightness_belief(round((brightness * 100) / 255)),
)
except ClientResponseError as ex:
raise HomeAssistantError(
f"The bond API returned an error calling set_brightness_belief for {self.entity_id}. Code: {ex.code} Message: {ex.message}"
) from ex
async def async_set_power_belief(self, power_state: bool) -> None:
"""Set the belief state of the light."""
try:
await self._hub.bond.action(
self._device.device_id, Action.set_light_state_belief(power_state)
)
except ClientResponseError as ex:
raise HomeAssistantError(
f"The bond API returned an error calling set_light_state_belief for {self.entity_id}. Code: {ex.code} Message: {ex.message}"
) from ex
class BondLight(BondBaseLight, BondEntity, LightEntity):
"""Representation of a Bond light."""
@ -231,3 +285,31 @@ class BondFireplace(BondEntity, LightEntity):
_LOGGER.debug("Fireplace async_turn_off called with: %s", kwargs)
await self._hub.bond.action(self._device.device_id, Action.turn_off())
async def async_set_brightness_belief(self, brightness: int) -> None:
"""Set the belief state of the light."""
if not self._device.supports_set_brightness():
raise HomeAssistantError("This device does not support setting brightness")
if brightness == 0:
await self.async_set_power_belief(False)
return
try:
await self._hub.bond.action(
self._device.device_id,
Action.set_brightness_belief(round((brightness * 100) / 255)),
)
except ClientResponseError as ex:
raise HomeAssistantError(
f"The bond API returned an error calling set_brightness_belief for {self.entity_id}. Code: {ex.code} Message: {ex.message}"
) from ex
async def async_set_power_belief(self, power_state: bool) -> None:
"""Set the belief state of the light."""
try:
await self._hub.bond.action(
self._device.device_id, Action.set_power_state_belief(power_state)
)
except ClientResponseError as ex:
raise HomeAssistantError(
f"The bond API returned an error calling set_power_state_belief for {self.entity_id}. Code: {ex.code} Message: {ex.message}"
) from ex

View File

@ -3,9 +3,9 @@
"name": "Bond",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/bond",
"requirements": ["bond-api==0.1.12"],
"requirements": ["bond-api==0.1.13"],
"zeroconf": ["_bond._tcp.local."],
"codeowners": ["@prystupa"],
"codeowners": ["@prystupa", "@joshs85"],
"quality_scale": "platinum",
"iot_class": "local_push"
}

View File

@ -1,3 +1,97 @@
# Describes the format for available bond services
set_fan_speed_belief:
name: Set believed fan speed
description: Sets the believed fan speed for a bond fan
fields:
entity_id:
description: Name(s) of entities to set the believed fan speed.
example: "fan.living_room_fan"
name: Entity
required: true
selector:
entity:
integration: bond
domain: fan
speed:
required: true
name: Fan Speed
description: Fan Speed as %.
example: 50
selector:
number:
min: 0
max: 100
step: 1
mode: slider
set_switch_power_belief:
name: Set believed switch power state
description: Sets the believed power state of a bond switch
fields:
entity_id:
description: Name(s) of entities to set the believed power state of.
example: "switch.whatever"
name: Entity
required: true
selector:
entity:
integration: bond
domain: switch
power_state:
required: true
name: Power state
description: Power state
example: true
selector:
boolean:
set_light_power_belief:
name: Set believed light power state
description: Sets the believed light power state of a bond light
fields:
entity_id:
description: Name(s) of entities to set the believed power state of.
example: "light.living_room_lights"
name: Entity
required: true
selector:
entity:
integration: bond
domain: light
power_state:
required: true
name: Power state
description: Power state
example: true
selector:
boolean:
set_light_brightness_belief:
name: Set believed light brightness state
description: Sets the believed light brightness state of a bond light
fields:
entity_id:
description: Name(s) of entities to set the believed power state of.
example: "light.living_room_lights"
name: Entity
required: true
selector:
entity:
integration: bond
domain: light
brightness:
required: true
name: Brightness
description: Brightness
example: 50
selector:
number:
min: 0
max: 255
step: 1
mode: slider
start_increasing_brightness:
name: Start increasing brightness
description: "Start increasing the brightness of the light."
@ -21,3 +115,4 @@ stop:
entity:
integration: bond
domain: light

View File

@ -3,15 +3,19 @@ from __future__ import annotations
from typing import Any
from aiohttp.client_exceptions import ClientResponseError
from bond_api import Action, BPUPSubscriptions, DeviceType
import voluptuous as vol
from homeassistant.components.switch import SwitchEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import config_validation as cv, entity_platform
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import BPUP_SUBS, DOMAIN, HUB
from .const import ATTR_POWER_STATE, BPUP_SUBS, DOMAIN, HUB, SERVICE_SET_POWER_BELIEF
from .entity import BondEntity
from .utils import BondHub
@ -25,6 +29,7 @@ async def async_setup_entry(
data = hass.data[DOMAIN][entry.entry_id]
hub: BondHub = data[HUB]
bpup_subs: BPUPSubscriptions = data[BPUP_SUBS]
platform = entity_platform.async_get_current_platform()
switches: list[Entity] = [
BondSwitch(hub, device, bpup_subs)
@ -32,6 +37,12 @@ async def async_setup_entry(
if DeviceType.is_generic(device.type)
]
platform.async_register_entity_service(
SERVICE_SET_POWER_BELIEF,
{vol.Required(ATTR_POWER_STATE): cv.boolean},
"async_set_power_belief",
)
async_add_entities(switches, True)
@ -48,3 +59,14 @@ 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_set_power_belief(self, power_state: bool) -> None:
"""Set switch power belief."""
try:
await self._hub.bond.action(
self._device.device_id, Action.set_power_state_belief(power_state)
)
except ClientResponseError as ex:
raise HomeAssistantError(
f"The bond API returned an error calling set_power_state_belief for {self.entity_id}. Code: {ex.code} Message: {ex.message}"
) from ex

View File

@ -406,7 +406,7 @@ blockchain==1.4.4
# bme680==1.0.5
# homeassistant.components.bond
bond-api==0.1.12
bond-api==0.1.13
# homeassistant.components.bosch_shc
boschshcpy==0.2.19

View File

@ -239,7 +239,7 @@ blebox_uniapi==1.3.3
blinkpy==0.17.0
# homeassistant.components.bond
bond-api==0.1.12
bond-api==0.1.13
# homeassistant.components.bosch_shc
boschshcpy==0.2.19

View File

@ -7,6 +7,8 @@ from datetime import timedelta
from typing import Any
from unittest.mock import MagicMock, patch
from aiohttp.client_exceptions import ClientResponseError
from homeassistant import core
from homeassistant.components.bond.const import DOMAIN as BOND_DOMAIN
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST, STATE_UNAVAILABLE
@ -184,6 +186,16 @@ def patch_bond_action():
return patch("homeassistant.components.bond.Bond.action")
def patch_bond_action_returns_clientresponseerror():
"""Patch Bond API action endpoint to throw ClientResponseError."""
return patch(
"homeassistant.components.bond.Bond.action",
side_effect=ClientResponseError(
request_info=None, history=None, code=405, message="Method Not Allowed"
),
)
def patch_bond_device_properties(return_value=None):
"""Patch Bond API device properties endpoint."""
if return_value is None:

View File

@ -4,9 +4,14 @@ from __future__ import annotations
from datetime import timedelta
from bond_api import Action, DeviceType, Direction
import pytest
from homeassistant import core
from homeassistant.components import fan
from homeassistant.components.bond.const import (
DOMAIN as BOND_DOMAIN,
SERVICE_SET_FAN_SPEED_BELIEF,
)
from homeassistant.components.fan import (
ATTR_DIRECTION,
ATTR_SPEED,
@ -19,6 +24,7 @@ from homeassistant.components.fan import (
SPEED_OFF,
)
from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_OFF, SERVICE_TURN_ON
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_registry import EntityRegistry
from homeassistant.util import utcnow
@ -26,6 +32,7 @@ from homeassistant.util import utcnow
from .common import (
help_test_entity_available,
patch_bond_action,
patch_bond_action_returns_clientresponseerror,
patch_bond_device_state,
setup_platform,
)
@ -254,6 +261,63 @@ async def test_turn_off_fan(hass: core.HomeAssistant):
mock_turn_off.assert_called_once_with("test-device-id", Action.turn_off())
async def test_set_speed_belief_speed_zero(hass: core.HomeAssistant):
"""Tests that set power belief service delegates to API."""
await setup_platform(
hass, FAN_DOMAIN, ceiling_fan("name-1"), bond_device_id="test-device-id"
)
with patch_bond_action() as mock_action, patch_bond_device_state():
await hass.services.async_call(
BOND_DOMAIN,
SERVICE_SET_FAN_SPEED_BELIEF,
{ATTR_ENTITY_ID: "fan.name_1", ATTR_SPEED: 0},
blocking=True,
)
await hass.async_block_till_done()
mock_action.assert_called_once_with(
"test-device-id", Action.set_power_state_belief(False)
)
async def test_set_speed_belief_speed_api_error(hass: core.HomeAssistant):
"""Tests that set power belief service delegates to API."""
await setup_platform(
hass, FAN_DOMAIN, ceiling_fan("name-1"), bond_device_id="test-device-id"
)
with pytest.raises(
HomeAssistantError
), patch_bond_action_returns_clientresponseerror(), patch_bond_device_state():
await hass.services.async_call(
BOND_DOMAIN,
SERVICE_SET_FAN_SPEED_BELIEF,
{ATTR_ENTITY_ID: "fan.name_1", ATTR_SPEED: 100},
blocking=True,
)
await hass.async_block_till_done()
async def test_set_speed_belief_speed_100(hass: core.HomeAssistant):
"""Tests that set power belief service delegates to API."""
await setup_platform(
hass, FAN_DOMAIN, ceiling_fan("name-1"), bond_device_id="test-device-id"
)
with patch_bond_action() as mock_action, patch_bond_device_state():
await hass.services.async_call(
BOND_DOMAIN,
SERVICE_SET_FAN_SPEED_BELIEF,
{ATTR_ENTITY_ID: "fan.name_1", ATTR_SPEED: 100},
blocking=True,
)
await hass.async_block_till_done()
mock_action.assert_any_call("test-device-id", Action.set_power_state_belief(True))
mock_action.assert_called_with("test-device-id", Action.set_speed_belief(3))
async def test_update_reports_fan_on(hass: core.HomeAssistant):
"""Tests that update command sets correct state when Bond API reports fan power is on."""
await setup_platform(hass, FAN_DOMAIN, ceiling_fan("name-1"))

View File

@ -5,7 +5,12 @@ from bond_api import Action, DeviceType
import pytest
from homeassistant import core
from homeassistant.components.bond.const import DOMAIN
from homeassistant.components.bond.const import (
ATTR_POWER_STATE,
DOMAIN,
SERVICE_SET_LIGHT_BRIGHTNESS_BELIEF,
SERVICE_SET_LIGHT_POWER_BELIEF,
)
from homeassistant.components.bond.light import (
SERVICE_START_DECREASING_BRIGHTNESS,
SERVICE_START_INCREASING_BRIGHTNESS,
@ -31,6 +36,7 @@ from homeassistant.util import utcnow
from .common import (
help_test_entity_available,
patch_bond_action,
patch_bond_action_returns_clientresponseerror,
patch_bond_device_state,
setup_platform,
)
@ -47,6 +53,15 @@ def light(name: str):
}
def light_no_brightness(name: str):
"""Create a light with a given name."""
return {
"name": name,
"type": DeviceType.LIGHT,
"actions": [Action.TURN_LIGHT_ON, Action.TURN_LIGHT_OFF],
}
def ceiling_fan(name: str):
"""Create a ceiling fan (that has built-in light) with given name."""
return {
@ -106,6 +121,21 @@ def fireplace_with_light(name: str):
}
def fireplace_with_light_supports_brightness(name: str):
"""Create a fireplace with given name."""
return {
"name": name,
"type": DeviceType.FIREPLACE,
"actions": [
Action.TURN_ON,
Action.TURN_OFF,
Action.TURN_LIGHT_ON,
Action.TURN_LIGHT_OFF,
Action.SET_BRIGHTNESS,
],
}
def light_brightness_increase_decrease_only(name: str):
"""Create a light that can only increase or decrease brightness."""
return {
@ -254,6 +284,270 @@ async def test_no_trust_state(hass: core.HomeAssistant):
assert device.attributes.get(ATTR_ASSUMED_STATE) is not True
async def test_light_set_brightness_belief_full(hass: core.HomeAssistant):
"""Tests that the set brightness belief function of a light delegates to API."""
await setup_platform(
hass,
LIGHT_DOMAIN,
light("name-1"),
bond_device_id="test-device-id",
)
with patch_bond_action() as mock_bond_action, patch_bond_device_state():
await hass.services.async_call(
DOMAIN,
SERVICE_SET_LIGHT_BRIGHTNESS_BELIEF,
{ATTR_ENTITY_ID: "light.name_1", ATTR_BRIGHTNESS: 255},
blocking=True,
)
await hass.async_block_till_done()
mock_bond_action.assert_called_once_with(
"test-device-id", Action.set_brightness_belief(brightness=100)
)
async def test_light_set_brightness_belief_api_error(hass: core.HomeAssistant):
"""Tests that the set brightness belief throws HomeAssistantError in the event of an api error."""
await setup_platform(
hass,
LIGHT_DOMAIN,
light("name-1"),
bond_device_id="test-device-id",
)
with pytest.raises(
HomeAssistantError
), patch_bond_action_returns_clientresponseerror(), patch_bond_device_state():
await hass.services.async_call(
DOMAIN,
SERVICE_SET_LIGHT_BRIGHTNESS_BELIEF,
{ATTR_ENTITY_ID: "light.name_1", ATTR_BRIGHTNESS: 255},
blocking=True,
)
await hass.async_block_till_done()
async def test_fp_light_set_brightness_belief_full(hass: core.HomeAssistant):
"""Tests that the set brightness belief function of a light delegates to API."""
await setup_platform(
hass,
LIGHT_DOMAIN,
fireplace_with_light_supports_brightness("name-1"),
bond_device_id="test-device-id",
)
with patch_bond_action() as mock_bond_action, patch_bond_device_state():
await hass.services.async_call(
DOMAIN,
SERVICE_SET_LIGHT_BRIGHTNESS_BELIEF,
{ATTR_ENTITY_ID: "light.name_1", ATTR_BRIGHTNESS: 255},
blocking=True,
)
await hass.async_block_till_done()
mock_bond_action.assert_called_once_with(
"test-device-id", Action.set_brightness_belief(brightness=100)
)
async def test_fp_light_set_brightness_belief_api_error(hass: core.HomeAssistant):
"""Tests that the set brightness belief throws HomeAssistantError in the event of an api error."""
await setup_platform(
hass,
LIGHT_DOMAIN,
fireplace_with_light_supports_brightness("name-1"),
bond_device_id="test-device-id",
)
with pytest.raises(
HomeAssistantError
), patch_bond_action_returns_clientresponseerror(), patch_bond_device_state():
await hass.services.async_call(
DOMAIN,
SERVICE_SET_LIGHT_BRIGHTNESS_BELIEF,
{ATTR_ENTITY_ID: "light.name_1", ATTR_BRIGHTNESS: 255},
blocking=True,
)
await hass.async_block_till_done()
async def test_light_set_brightness_belief_brightnes_not_supported(
hass: core.HomeAssistant,
):
"""Tests that the set brightness belief function of a light that doesn't support setting brightness returns an error."""
await setup_platform(
hass,
LIGHT_DOMAIN,
light_no_brightness("name-1"),
bond_device_id="test-device-id",
)
with pytest.raises(HomeAssistantError), patch_bond_device_state():
await hass.services.async_call(
DOMAIN,
SERVICE_SET_LIGHT_BRIGHTNESS_BELIEF,
{ATTR_ENTITY_ID: "light.name_1", ATTR_BRIGHTNESS: 255},
blocking=True,
)
await hass.async_block_till_done()
async def test_light_set_brightness_belief_zero(hass: core.HomeAssistant):
"""Tests that the set brightness belief function of a light delegates to API."""
await setup_platform(
hass,
LIGHT_DOMAIN,
light("name-1"),
bond_device_id="test-device-id",
)
with patch_bond_action() as mock_bond_action, patch_bond_device_state():
await hass.services.async_call(
DOMAIN,
SERVICE_SET_LIGHT_BRIGHTNESS_BELIEF,
{ATTR_ENTITY_ID: "light.name_1", ATTR_BRIGHTNESS: 0},
blocking=True,
)
await hass.async_block_till_done()
mock_bond_action.assert_called_once_with(
"test-device-id", Action.set_light_state_belief(False)
)
async def test_fp_light_set_brightness_belief_zero(hass: core.HomeAssistant):
"""Tests that the set brightness belief function of a light delegates to API."""
await setup_platform(
hass,
LIGHT_DOMAIN,
fireplace_with_light_supports_brightness("name-1"),
bond_device_id="test-device-id",
)
with patch_bond_action() as mock_bond_action, patch_bond_device_state():
await hass.services.async_call(
DOMAIN,
SERVICE_SET_LIGHT_BRIGHTNESS_BELIEF,
{ATTR_ENTITY_ID: "light.name_1", ATTR_BRIGHTNESS: 0},
blocking=True,
)
await hass.async_block_till_done()
mock_bond_action.assert_called_once_with(
"test-device-id", Action.set_power_state_belief(False)
)
async def test_light_set_power_belief(hass: core.HomeAssistant):
"""Tests that the set brightness belief function of a light delegates to API."""
await setup_platform(
hass,
LIGHT_DOMAIN,
light("name-1"),
bond_device_id="test-device-id",
)
with patch_bond_action() as mock_bond_action, patch_bond_device_state():
await hass.services.async_call(
DOMAIN,
SERVICE_SET_LIGHT_POWER_BELIEF,
{ATTR_ENTITY_ID: "light.name_1", ATTR_POWER_STATE: False},
blocking=True,
)
await hass.async_block_till_done()
mock_bond_action.assert_called_once_with(
"test-device-id", Action.set_light_state_belief(False)
)
async def test_light_set_power_belief_api_error(hass: core.HomeAssistant):
"""Tests that the set brightness belief function of a light throws HomeAssistantError in the event of an api error."""
await setup_platform(
hass,
LIGHT_DOMAIN,
light("name-1"),
bond_device_id="test-device-id",
)
with pytest.raises(
HomeAssistantError
), patch_bond_action_returns_clientresponseerror(), patch_bond_device_state():
await hass.services.async_call(
DOMAIN,
SERVICE_SET_LIGHT_POWER_BELIEF,
{ATTR_ENTITY_ID: "light.name_1", ATTR_POWER_STATE: False},
blocking=True,
)
await hass.async_block_till_done()
async def test_fp_light_set_power_belief(hass: core.HomeAssistant):
"""Tests that the set brightness belief function of a light delegates to API."""
await setup_platform(
hass,
LIGHT_DOMAIN,
fireplace_with_light("name-1"),
bond_device_id="test-device-id",
)
with patch_bond_action() as mock_bond_action, patch_bond_device_state():
await hass.services.async_call(
DOMAIN,
SERVICE_SET_LIGHT_POWER_BELIEF,
{ATTR_ENTITY_ID: "light.name_1", ATTR_POWER_STATE: False},
blocking=True,
)
await hass.async_block_till_done()
mock_bond_action.assert_called_once_with(
"test-device-id", Action.set_power_state_belief(False)
)
async def test_fp_light_set_power_belief_api_error(hass: core.HomeAssistant):
"""Tests that the set brightness belief function of a light throws HomeAssistantError in the event of an api error."""
await setup_platform(
hass,
LIGHT_DOMAIN,
fireplace_with_light("name-1"),
bond_device_id="test-device-id",
)
with pytest.raises(
HomeAssistantError
), patch_bond_action_returns_clientresponseerror(), patch_bond_device_state():
await hass.services.async_call(
DOMAIN,
SERVICE_SET_LIGHT_POWER_BELIEF,
{ATTR_ENTITY_ID: "light.name_1", ATTR_POWER_STATE: False},
blocking=True,
)
await hass.async_block_till_done()
async def test_fp_light_set_brightness_belief_brightnes_not_supported(
hass: core.HomeAssistant,
):
"""Tests that the set brightness belief function of a fireplace light that doesn't support setting brightness returns an error."""
await setup_platform(
hass,
LIGHT_DOMAIN,
fireplace_with_light("name-1"),
bond_device_id="test-device-id",
)
with pytest.raises(HomeAssistantError), patch_bond_device_state():
await hass.services.async_call(
DOMAIN,
SERVICE_SET_LIGHT_BRIGHTNESS_BELIEF,
{ATTR_ENTITY_ID: "light.name_1", ATTR_BRIGHTNESS: 255},
blocking=True,
)
await hass.async_block_till_done()
async def test_light_start_increasing_brightness(hass: core.HomeAssistant):
"""Tests a light that can only increase or decrease brightness delegates to API can start increasing brightness."""
await setup_platform(

View File

@ -2,10 +2,17 @@
from datetime import timedelta
from bond_api import Action, DeviceType
import pytest
from homeassistant import core
from homeassistant.components.bond.const import (
ATTR_POWER_STATE,
DOMAIN as BOND_DOMAIN,
SERVICE_SET_POWER_BELIEF,
)
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_OFF, SERVICE_TURN_ON
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_registry import EntityRegistry
from homeassistant.util import utcnow
@ -13,6 +20,7 @@ from homeassistant.util import utcnow
from .common import (
help_test_entity_available,
patch_bond_action,
patch_bond_action_returns_clientresponseerror,
patch_bond_device_state,
setup_platform,
)
@ -76,6 +84,44 @@ async def test_turn_off_switch(hass: core.HomeAssistant):
mock_turn_off.assert_called_once_with("test-device-id", Action.turn_off())
async def test_switch_set_power_belief(hass: core.HomeAssistant):
"""Tests that the set power belief service delegates to API."""
await setup_platform(
hass, SWITCH_DOMAIN, generic_device("name-1"), bond_device_id="test-device-id"
)
with patch_bond_action() as mock_bond_action, patch_bond_device_state():
await hass.services.async_call(
BOND_DOMAIN,
SERVICE_SET_POWER_BELIEF,
{ATTR_ENTITY_ID: "switch.name_1", ATTR_POWER_STATE: False},
blocking=True,
)
await hass.async_block_till_done()
mock_bond_action.assert_called_once_with(
"test-device-id", Action.set_power_state_belief(False)
)
async def test_switch_set_power_belief_api_error(hass: core.HomeAssistant):
"""Tests that the set power belief service throws HomeAssistantError in the event of an api error."""
await setup_platform(
hass, SWITCH_DOMAIN, generic_device("name-1"), bond_device_id="test-device-id"
)
with pytest.raises(
HomeAssistantError
), patch_bond_action_returns_clientresponseerror(), patch_bond_device_state():
await hass.services.async_call(
BOND_DOMAIN,
SERVICE_SET_POWER_BELIEF,
{ATTR_ENTITY_ID: "switch.name_1", ATTR_POWER_STATE: False},
blocking=True,
)
await hass.async_block_till_done()
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"))