From 82001017856fd647ff2386efb70e4cd3afac422b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 12 Dec 2021 17:10:40 -0500 Subject: [PATCH] Fix HomeKit covers with device class window and no tilt (#61566) --- .../components/homekit/type_covers.py | 17 ++++++---- tests/components/homekit/test_type_covers.py | 33 +++++++++++++++++-- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/homekit/type_covers.py b/homeassistant/components/homekit/type_covers.py index 0c889d9aee4..b9153ef1372 100644 --- a/homeassistant/components/homekit/type_covers.py +++ b/homeassistant/components/homekit/type_covers.py @@ -249,14 +249,17 @@ class OpeningDeviceBase(HomeAccessory): def async_update_state(self, new_state): """Update cover position and tilt after state changed.""" # update tilt + if not self._supports_tilt: + return current_tilt = new_state.attributes.get(ATTR_CURRENT_TILT_POSITION) - if isinstance(current_tilt, (float, int)): - # HomeKit sends values between -90 and 90. - # We'll have to normalize to [0,100] - current_tilt = (current_tilt / 100.0 * 180.0) - 90.0 - current_tilt = int(current_tilt) - self.char_current_tilt.set_value(current_tilt) - self.char_target_tilt.set_value(current_tilt) + if not isinstance(current_tilt, (float, int)): + return + # HomeKit sends values between -90 and 90. + # We'll have to normalize to [0,100] + current_tilt = (current_tilt / 100.0 * 180.0) - 90.0 + current_tilt = int(current_tilt) + self.char_current_tilt.set_value(current_tilt) + self.char_target_tilt.set_value(current_tilt) class OpeningDevice(OpeningDeviceBase, HomeAccessory): diff --git a/tests/components/homekit/test_type_covers.py b/tests/components/homekit/test_type_covers.py index c357598a3df..44c9365fc04 100644 --- a/tests/components/homekit/test_type_covers.py +++ b/tests/components/homekit/test_type_covers.py @@ -223,11 +223,15 @@ async def test_windowcovering_set_cover_position(hass, hk_driver, events): assert events[-1].data[ATTR_VALUE] == 75 -async def test_window_instantiate(hass, hk_driver, events): - """Test if Window accessory is instantiated correctly.""" +async def test_window_instantiate_set_position(hass, hk_driver, events): + """Test if Window accessory is instantiated correctly and can set position.""" entity_id = "cover.window" - hass.states.async_set(entity_id, None) + hass.states.async_set( + entity_id, + STATE_OPEN, + {ATTR_SUPPORTED_FEATURES: SUPPORT_SET_POSITION, ATTR_CURRENT_POSITION: 0}, + ) await hass.async_block_till_done() acc = Window(hass, hk_driver, "Window", entity_id, 2, None) await acc.run() @@ -239,6 +243,29 @@ async def test_window_instantiate(hass, hk_driver, events): assert acc.char_current_position.value == 0 assert acc.char_target_position.value == 0 + hass.states.async_set( + entity_id, + STATE_OPEN, + {ATTR_SUPPORTED_FEATURES: SUPPORT_SET_POSITION, ATTR_CURRENT_POSITION: 50}, + ) + await hass.async_block_till_done() + assert acc.char_current_position.value == 50 + assert acc.char_target_position.value == 50 + assert acc.char_position_state.value == 2 + + hass.states.async_set( + entity_id, + STATE_OPEN, + { + ATTR_SUPPORTED_FEATURES: SUPPORT_SET_POSITION, + ATTR_CURRENT_POSITION: "GARBAGE", + }, + ) + await hass.async_block_till_done() + assert acc.char_current_position.value == 50 + assert acc.char_target_position.value == 50 + assert acc.char_position_state.value == 2 + async def test_windowcovering_cover_set_tilt(hass, hk_driver, events): """Test if accessory and HA update slat tilt accordingly."""