From 0a51914740c8fc4810f8cd4625c62e3d01b1d548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Huryn?= Date: Tue, 28 Mar 2023 17:11:48 +0200 Subject: [PATCH] Blebox cover tilt (#85515) * feature: added tilt for shutterBox * test: include tilt in tests --- homeassistant/components/blebox/cover.py | 17 ++++++++ tests/components/blebox/test_cover.py | 49 ++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/homeassistant/components/blebox/cover.py b/homeassistant/components/blebox/cover.py index 80e2fbd30e7..658a9bc30cc 100644 --- a/homeassistant/components/blebox/cover.py +++ b/homeassistant/components/blebox/cover.py @@ -8,6 +8,7 @@ import blebox_uniapi.cover from homeassistant.components.cover import ( ATTR_POSITION, + ATTR_TILT_POSITION, CoverDeviceClass, CoverEntity, CoverEntityFeature, @@ -67,6 +68,10 @@ class BleBoxCoverEntity(BleBoxEntity[blebox_uniapi.cover.Cover], CoverEntity): self._attr_supported_features = ( position | stop | CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE ) + if feature.has_tilt: + self._attr_supported_features = ( + self._attr_supported_features | CoverEntityFeature.SET_TILT_POSITION + ) @property def current_cover_position(self) -> int | None: @@ -77,6 +82,12 @@ class BleBoxCoverEntity(BleBoxEntity[blebox_uniapi.cover.Cover], CoverEntity): return None if position is None else 100 - position + @property + def current_cover_tilt_position(self) -> int | None: + """Return the current tilt of shutter.""" + position = self._feature.tilt_current + return None if position is None else 100 - position + @property def is_opening(self) -> bool | None: """Return whether cover is opening.""" @@ -110,6 +121,12 @@ class BleBoxCoverEntity(BleBoxEntity[blebox_uniapi.cover.Cover], CoverEntity): """Stop the cover.""" await self._feature.async_stop() + async def async_set_cover_tilt_position(self, **kwargs: Any) -> None: + """Set the tilt position.""" + + position = kwargs[ATTR_TILT_POSITION] + await self._feature.async_set_tilt_position(100 - position) + def _is_state(self, state_name) -> bool | None: value = BLEBOX_TO_HASS_COVER_STATES[self._feature.state] return None if value is None else value == state_name diff --git a/tests/components/blebox/test_cover.py b/tests/components/blebox/test_cover.py index ce7006951fb..d0a10cb5bde 100644 --- a/tests/components/blebox/test_cover.py +++ b/tests/components/blebox/test_cover.py @@ -7,7 +7,9 @@ import pytest from homeassistant.components.cover import ( ATTR_CURRENT_POSITION, + ATTR_CURRENT_TILT_POSITION, ATTR_POSITION, + ATTR_TILT_POSITION, STATE_CLOSED, STATE_CLOSING, STATE_OPEN, @@ -21,6 +23,7 @@ from homeassistant.const import ( SERVICE_CLOSE_COVER, SERVICE_OPEN_COVER, SERVICE_SET_COVER_POSITION, + SERVICE_SET_COVER_TILT_POSITION, SERVICE_STOP_COVER, STATE_UNKNOWN, ) @@ -43,8 +46,10 @@ def shutterbox_fixture(): full_name="shutterBox-position", device_class="shutter", current=None, + tilt_current=None, state=None, has_stop=True, + has_tilt=True, is_slider=True, ) product = feature.product @@ -420,3 +425,47 @@ async def test_closed_state(feature, hass: HomeAssistant) -> None: feature_mock.async_update = AsyncMock(side_effect=initial_update) await async_setup_entity(hass, entity_id) assert hass.states.get(entity_id).state == STATE_CLOSED + + +async def test_tilt_position(shutterbox, hass): + """Test tilt capability is available.""" + + feature_mock, entity_id = shutterbox + + def tilt_update(): + feature_mock.tilt_current = 90 + + feature_mock.async_update = AsyncMock(side_effect=tilt_update) + + await async_setup_entity(hass, entity_id) + + state = hass.states.get(entity_id) + assert state.attributes[ATTR_CURRENT_TILT_POSITION] == 10 + + +async def test_set_tilt_position(shutterbox, hass): + """Test tilt position setting.""" + + feature_mock, entity_id = shutterbox + + def initial_update(): + feature_mock.state = 3 + + def set_tilt(tilt_position): + assert tilt_position == 20 + feature_mock.state = 1 + + feature_mock.async_update = AsyncMock(side_effect=initial_update) + feature_mock.async_set_tilt_position = AsyncMock(side_effect=set_tilt) + + await async_setup_entity(hass, entity_id) + assert hass.states.get(entity_id).state == STATE_CLOSED + + feature_mock.async_update = AsyncMock() + await hass.services.async_call( + "cover", + SERVICE_SET_COVER_TILT_POSITION, + {"entity_id": entity_id, ATTR_TILT_POSITION: 80}, + blocking=True, + ) + assert hass.states.get(entity_id).state == STATE_OPENING