Add tilt support to bond covers (#59505)
This commit is contained in:
parent
beb0650a81
commit
5d2eb8d3ff
6 changed files with 172 additions and 6 deletions
|
@ -5,7 +5,16 @@ from typing import Any
|
|||
|
||||
from bond_api import Action, BPUPSubscriptions, DeviceType
|
||||
|
||||
from homeassistant.components.cover import DEVICE_CLASS_SHADE, CoverEntity
|
||||
from homeassistant.components.cover import (
|
||||
DEVICE_CLASS_SHADE,
|
||||
SUPPORT_CLOSE,
|
||||
SUPPORT_CLOSE_TILT,
|
||||
SUPPORT_OPEN,
|
||||
SUPPORT_OPEN_TILT,
|
||||
SUPPORT_STOP,
|
||||
SUPPORT_STOP_TILT,
|
||||
CoverEntity,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
@ -45,6 +54,21 @@ class BondCover(BondEntity, CoverEntity):
|
|||
) -> None:
|
||||
"""Create HA entity representing Bond cover."""
|
||||
super().__init__(hub, device, bpup_subs)
|
||||
supported_features = 0
|
||||
if self._device.supports_open():
|
||||
supported_features |= SUPPORT_OPEN
|
||||
if self._device.supports_close():
|
||||
supported_features |= SUPPORT_CLOSE
|
||||
if self._device.supports_tilt_open():
|
||||
supported_features |= SUPPORT_OPEN_TILT
|
||||
if self._device.supports_tilt_close():
|
||||
supported_features |= SUPPORT_CLOSE_TILT
|
||||
if self._device.supports_hold():
|
||||
if self._device.supports_open() or self._device.supports_close():
|
||||
supported_features |= SUPPORT_STOP
|
||||
if self._device.supports_tilt_open() or self._device.supports_tilt_close():
|
||||
supported_features |= SUPPORT_STOP_TILT
|
||||
self._attr_supported_features = supported_features
|
||||
|
||||
def _apply_state(self, state: dict) -> None:
|
||||
cover_open = state.get("open")
|
||||
|
@ -63,3 +87,15 @@ class BondCover(BondEntity, CoverEntity):
|
|||
async def async_stop_cover(self, **kwargs: Any) -> None:
|
||||
"""Hold cover."""
|
||||
await self._hub.bond.action(self._device.device_id, Action.hold())
|
||||
|
||||
async def async_open_cover_tilt(self, **kwargs: Any) -> None:
|
||||
"""Open the cover tilt."""
|
||||
await self._hub.bond.action(self._device.device_id, Action.tilt_open())
|
||||
|
||||
async def async_close_cover_tilt(self, **kwargs: Any) -> None:
|
||||
"""Close the cover tilt."""
|
||||
await self._hub.bond.action(self._device.device_id, Action.tilt_close())
|
||||
|
||||
async def async_stop_cover_tilt(self, **kwargs: Any) -> None:
|
||||
"""Stop the cover."""
|
||||
await self._hub.bond.action(self._device.device_id, Action.hold())
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "Bond",
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/bond",
|
||||
"requirements": ["bond-api==0.1.14"],
|
||||
"requirements": ["bond-api==0.1.15"],
|
||||
"zeroconf": ["_bond._tcp.local."],
|
||||
"codeowners": ["@bdraco", "@prystupa", "@joshs85"],
|
||||
"quality_scale": "platinum",
|
||||
|
|
|
@ -82,6 +82,26 @@ class BondDevice:
|
|||
"""Return True if this device supports any of the direction related commands."""
|
||||
return self._has_any_action({Action.SET_DIRECTION})
|
||||
|
||||
def supports_open(self) -> bool:
|
||||
"""Return True if this device supports opening."""
|
||||
return self._has_any_action({Action.OPEN})
|
||||
|
||||
def supports_close(self) -> bool:
|
||||
"""Return True if this device supports closing."""
|
||||
return self._has_any_action({Action.CLOSE})
|
||||
|
||||
def supports_tilt_open(self) -> bool:
|
||||
"""Return True if this device supports tilt opening."""
|
||||
return self._has_any_action({Action.TILT_OPEN})
|
||||
|
||||
def supports_tilt_close(self) -> bool:
|
||||
"""Return True if this device supports tilt closing."""
|
||||
return self._has_any_action({Action.TILT_CLOSE})
|
||||
|
||||
def supports_hold(self) -> bool:
|
||||
"""Return True if this device supports hold aka stop."""
|
||||
return self._has_any_action({Action.HOLD})
|
||||
|
||||
def supports_light(self) -> bool:
|
||||
"""Return True if this device supports any of the light related commands."""
|
||||
return self._has_any_action({Action.TURN_LIGHT_ON, Action.TURN_LIGHT_OFF})
|
||||
|
|
|
@ -418,7 +418,7 @@ blockchain==1.4.4
|
|||
# bme680==1.0.5
|
||||
|
||||
# homeassistant.components.bond
|
||||
bond-api==0.1.14
|
||||
bond-api==0.1.15
|
||||
|
||||
# homeassistant.components.bosch_shc
|
||||
boschshcpy==0.2.19
|
||||
|
|
|
@ -263,7 +263,7 @@ blebox_uniapi==1.3.3
|
|||
blinkpy==0.17.0
|
||||
|
||||
# homeassistant.components.bond
|
||||
bond-api==0.1.14
|
||||
bond-api==0.1.15
|
||||
|
||||
# homeassistant.components.bosch_shc
|
||||
boschshcpy==0.2.19
|
||||
|
|
|
@ -4,12 +4,16 @@ from datetime import timedelta
|
|||
from bond_api import Action, DeviceType
|
||||
|
||||
from homeassistant import core
|
||||
from homeassistant.components.cover import DOMAIN as COVER_DOMAIN
|
||||
from homeassistant.components.cover import DOMAIN as COVER_DOMAIN, STATE_CLOSED
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
SERVICE_CLOSE_COVER,
|
||||
SERVICE_CLOSE_COVER_TILT,
|
||||
SERVICE_OPEN_COVER,
|
||||
SERVICE_OPEN_COVER_TILT,
|
||||
SERVICE_STOP_COVER,
|
||||
SERVICE_STOP_COVER_TILT,
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.entity_registry import EntityRegistry
|
||||
|
@ -27,7 +31,29 @@ from tests.common import async_fire_time_changed
|
|||
|
||||
def shades(name: str):
|
||||
"""Create motorized shades with given name."""
|
||||
return {"name": name, "type": DeviceType.MOTORIZED_SHADES}
|
||||
return {
|
||||
"name": name,
|
||||
"type": DeviceType.MOTORIZED_SHADES,
|
||||
"actions": ["Open", "Close", "Hold"],
|
||||
}
|
||||
|
||||
|
||||
def tilt_only_shades(name: str):
|
||||
"""Create motorized shades that only tilt."""
|
||||
return {
|
||||
"name": name,
|
||||
"type": DeviceType.MOTORIZED_SHADES,
|
||||
"actions": ["TiltOpen", "TiltClose", "Hold"],
|
||||
}
|
||||
|
||||
|
||||
def tilt_shades(name: str):
|
||||
"""Create motorized shades with given name that can also tilt."""
|
||||
return {
|
||||
"name": name,
|
||||
"type": DeviceType.MOTORIZED_SHADES,
|
||||
"actions": ["Open", "Close", "Hold", "TiltOpen", "TiltClose", "Hold"],
|
||||
}
|
||||
|
||||
|
||||
async def test_entity_registry(hass: core.HomeAssistant):
|
||||
|
@ -99,6 +125,90 @@ async def test_stop_cover(hass: core.HomeAssistant):
|
|||
mock_hold.assert_called_once_with("test-device-id", Action.hold())
|
||||
|
||||
|
||||
async def test_tilt_open_cover(hass: core.HomeAssistant):
|
||||
"""Tests that tilt open cover command delegates to API."""
|
||||
await setup_platform(
|
||||
hass, COVER_DOMAIN, tilt_only_shades("name-1"), bond_device_id="test-device-id"
|
||||
)
|
||||
|
||||
with patch_bond_action() as mock_open, patch_bond_device_state():
|
||||
await hass.services.async_call(
|
||||
COVER_DOMAIN,
|
||||
SERVICE_OPEN_COVER_TILT,
|
||||
{ATTR_ENTITY_ID: "cover.name_1"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
mock_open.assert_called_once_with("test-device-id", Action.tilt_open())
|
||||
assert hass.states.get("cover.name_1").state == STATE_UNKNOWN
|
||||
|
||||
|
||||
async def test_tilt_close_cover(hass: core.HomeAssistant):
|
||||
"""Tests that tilt close cover command delegates to API."""
|
||||
await setup_platform(
|
||||
hass, COVER_DOMAIN, tilt_only_shades("name-1"), bond_device_id="test-device-id"
|
||||
)
|
||||
|
||||
with patch_bond_action() as mock_close, patch_bond_device_state():
|
||||
await hass.services.async_call(
|
||||
COVER_DOMAIN,
|
||||
SERVICE_CLOSE_COVER_TILT,
|
||||
{ATTR_ENTITY_ID: "cover.name_1"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
mock_close.assert_called_once_with("test-device-id", Action.tilt_close())
|
||||
assert hass.states.get("cover.name_1").state == STATE_UNKNOWN
|
||||
|
||||
|
||||
async def test_tilt_stop_cover(hass: core.HomeAssistant):
|
||||
"""Tests that tilt stop cover command delegates to API."""
|
||||
await setup_platform(
|
||||
hass,
|
||||
COVER_DOMAIN,
|
||||
tilt_only_shades("name-1"),
|
||||
bond_device_id="test-device-id",
|
||||
state={"counter1": 123},
|
||||
)
|
||||
|
||||
with patch_bond_action() as mock_hold, patch_bond_device_state():
|
||||
await hass.services.async_call(
|
||||
COVER_DOMAIN,
|
||||
SERVICE_STOP_COVER_TILT,
|
||||
{ATTR_ENTITY_ID: "cover.name_1"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
mock_hold.assert_called_once_with("test-device-id", Action.hold())
|
||||
assert hass.states.get("cover.name_1").state == STATE_UNKNOWN
|
||||
|
||||
|
||||
async def test_tilt_and_open(hass: core.HomeAssistant):
|
||||
"""Tests that supports both tilt and open."""
|
||||
await setup_platform(
|
||||
hass,
|
||||
COVER_DOMAIN,
|
||||
tilt_shades("name-1"),
|
||||
bond_device_id="test-device-id",
|
||||
state={"open": False},
|
||||
)
|
||||
|
||||
with patch_bond_action() as mock_open, patch_bond_device_state():
|
||||
await hass.services.async_call(
|
||||
COVER_DOMAIN,
|
||||
SERVICE_OPEN_COVER_TILT,
|
||||
{ATTR_ENTITY_ID: "cover.name_1"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
mock_open.assert_called_once_with("test-device-id", Action.tilt_open())
|
||||
assert hass.states.get("cover.name_1").state == STATE_CLOSED
|
||||
|
||||
|
||||
async def test_update_reports_open_cover(hass: core.HomeAssistant):
|
||||
"""Tests that update command sets correct state when Bond API reports cover is open."""
|
||||
await setup_platform(hass, COVER_DOMAIN, shades("name-1"))
|
||||
|
|
Loading…
Add table
Reference in a new issue