From 393dbb6dc0469ce3d42ee32b07134817089e426f Mon Sep 17 00:00:00 2001 From: badewanne1234 <82471417+badewanne1234@users.noreply.github.com> Date: Thu, 25 May 2023 12:41:42 +0200 Subject: [PATCH] Fix of cover-tilt in homekit_controller (#91631) * Fix of cover-tilt in homekit_controller * Fix of cover-tilt and its tests --- .../components/homekit_controller/cover.py | 39 ++++++ .../homekit_controller/test_cover.py | 124 +++++++++++++++++- 2 files changed, 159 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/homekit_controller/cover.py b/homeassistant/components/homekit_controller/cover.py index fbe6f08bc75..73eb699007c 100644 --- a/homeassistant/components/homekit_controller/cover.py +++ b/homeassistant/components/homekit_controller/cover.py @@ -216,6 +216,26 @@ class HomeKitWindowCover(HomeKitEntity, CoverEntity): tilt_position = self.service.value( CharacteristicsTypes.HORIZONTAL_TILT_CURRENT ) + # Recalculate to convert from arcdegree scale to percentage scale. + if self.is_vertical_tilt: + scale = 0.9 + if ( + self.service[CharacteristicsTypes.VERTICAL_TILT_CURRENT].minValue == -90 + and self.service[CharacteristicsTypes.VERTICAL_TILT_CURRENT].maxValue + == 0 + ): + scale = -0.9 + tilt_position = int(tilt_position / scale) + elif self.is_horizontal_tilt: + scale = 0.9 + if ( + self.service[CharacteristicsTypes.HORIZONTAL_TILT_TARGET].minValue + == -90 + and self.service[CharacteristicsTypes.HORIZONTAL_TILT_TARGET].maxValue + == 0 + ): + scale = -0.9 + tilt_position = int(tilt_position / scale) return tilt_position async def async_stop_cover(self, **kwargs: Any) -> None: @@ -241,10 +261,29 @@ class HomeKitWindowCover(HomeKitEntity, CoverEntity): """Move the cover tilt to a specific position.""" tilt_position = kwargs[ATTR_TILT_POSITION] if self.is_vertical_tilt: + # Recalculate to convert from percentage scale to arcdegree scale. + scale = 0.9 + if ( + self.service[CharacteristicsTypes.VERTICAL_TILT_TARGET].minValue == -90 + and self.service[CharacteristicsTypes.VERTICAL_TILT_TARGET].maxValue + == 0 + ): + scale = -0.9 + tilt_position = int(tilt_position * scale) await self.async_put_characteristics( {CharacteristicsTypes.VERTICAL_TILT_TARGET: tilt_position} ) elif self.is_horizontal_tilt: + # Recalculate to convert from percentage scale to arcdegree scale. + scale = 0.9 + if ( + self.service[CharacteristicsTypes.HORIZONTAL_TILT_TARGET].minValue + == -90 + and self.service[CharacteristicsTypes.HORIZONTAL_TILT_TARGET].maxValue + == 0 + ): + scale = -0.9 + tilt_position = int(tilt_position * scale) await self.async_put_characteristics( {CharacteristicsTypes.HORIZONTAL_TILT_TARGET: tilt_position} ) diff --git a/tests/components/homekit_controller/test_cover.py b/tests/components/homekit_controller/test_cover.py index aa59c2af3ed..5a389311daa 100644 --- a/tests/components/homekit_controller/test_cover.py +++ b/tests/components/homekit_controller/test_cover.py @@ -39,9 +39,28 @@ def create_window_covering_service_with_h_tilt(accessory): tilt_current = service.add_char(CharacteristicsTypes.HORIZONTAL_TILT_CURRENT) tilt_current.value = 0 + tilt_current.minValue = 0 + tilt_current.maxValue = 90 tilt_target = service.add_char(CharacteristicsTypes.HORIZONTAL_TILT_TARGET) tilt_target.value = 0 + tilt_target.minValue = 0 + tilt_target.maxValue = 90 + + +def create_window_covering_service_with_h_tilt_2(accessory): + """Define a window-covering characteristics as per page 219 of HAP spec.""" + service = create_window_covering_service(accessory) + + tilt_current = service.add_char(CharacteristicsTypes.HORIZONTAL_TILT_CURRENT) + tilt_current.value = 0 + tilt_current.minValue = -90 + tilt_current.maxValue = 0 + + tilt_target = service.add_char(CharacteristicsTypes.HORIZONTAL_TILT_TARGET) + tilt_target.value = 0 + tilt_target.minValue = -90 + tilt_target.maxValue = 0 def create_window_covering_service_with_v_tilt(accessory): @@ -50,9 +69,28 @@ def create_window_covering_service_with_v_tilt(accessory): tilt_current = service.add_char(CharacteristicsTypes.VERTICAL_TILT_CURRENT) tilt_current.value = 0 + tilt_current.minValue = 0 + tilt_current.maxValue = 90 tilt_target = service.add_char(CharacteristicsTypes.VERTICAL_TILT_TARGET) tilt_target.value = 0 + tilt_target.minValue = 0 + tilt_target.maxValue = 90 + + +def create_window_covering_service_with_v_tilt_2(accessory): + """Define a window-covering characteristics as per page 219 of HAP spec.""" + service = create_window_covering_service(accessory) + + tilt_current = service.add_char(CharacteristicsTypes.VERTICAL_TILT_CURRENT) + tilt_current.value = 0 + tilt_current.minValue = -90 + tilt_current.maxValue = 0 + + tilt_target = service.add_char(CharacteristicsTypes.VERTICAL_TILT_TARGET) + tilt_target.value = 0 + tilt_target.minValue = -90 + tilt_target.maxValue = 0 async def test_change_window_cover_state(hass: HomeAssistant, utcnow) -> None: @@ -124,7 +162,23 @@ async def test_read_window_cover_tilt_horizontal(hass: HomeAssistant, utcnow) -> {CharacteristicsTypes.HORIZONTAL_TILT_CURRENT: 75}, ) state = await helper.poll_and_get_state() - assert state.attributes["current_tilt_position"] == 75 + # Expect converted value from arcdegree scale to percentage scale. + assert state.attributes["current_tilt_position"] == 83 + + +async def test_read_window_cover_tilt_horizontal_2(hass: HomeAssistant, utcnow) -> None: + """Test that horizontal tilt is handled correctly.""" + helper = await setup_test_component( + hass, create_window_covering_service_with_h_tilt_2 + ) + + await helper.async_update( + ServicesTypes.WINDOW_COVERING, + {CharacteristicsTypes.HORIZONTAL_TILT_CURRENT: -75}, + ) + state = await helper.poll_and_get_state() + # Expect converted value from arcdegree scale to percentage scale. + assert state.attributes["current_tilt_position"] == 83 async def test_read_window_cover_tilt_vertical(hass: HomeAssistant, utcnow) -> None: @@ -138,7 +192,23 @@ async def test_read_window_cover_tilt_vertical(hass: HomeAssistant, utcnow) -> N {CharacteristicsTypes.VERTICAL_TILT_CURRENT: 75}, ) state = await helper.poll_and_get_state() - assert state.attributes["current_tilt_position"] == 75 + # Expect converted value from arcdegree scale to percentage scale. + assert state.attributes["current_tilt_position"] == 83 + + +async def test_read_window_cover_tilt_vertical_2(hass: HomeAssistant, utcnow) -> None: + """Test that vertical tilt is handled correctly.""" + helper = await setup_test_component( + hass, create_window_covering_service_with_v_tilt_2 + ) + + await helper.async_update( + ServicesTypes.WINDOW_COVERING, + {CharacteristicsTypes.VERTICAL_TILT_CURRENT: -75}, + ) + state = await helper.poll_and_get_state() + # Expect converted value from arcdegree scale to percentage scale. + assert state.attributes["current_tilt_position"] == 83 async def test_write_window_cover_tilt_horizontal(hass: HomeAssistant, utcnow) -> None: @@ -153,10 +223,34 @@ async def test_write_window_cover_tilt_horizontal(hass: HomeAssistant, utcnow) - {"entity_id": helper.entity_id, "tilt_position": 90}, blocking=True, ) + # Expect converted value from percentage scale to arcdegree scale. helper.async_assert_service_values( ServicesTypes.WINDOW_COVERING, { - CharacteristicsTypes.HORIZONTAL_TILT_TARGET: 90, + CharacteristicsTypes.HORIZONTAL_TILT_TARGET: 81, + }, + ) + + +async def test_write_window_cover_tilt_horizontal_2( + hass: HomeAssistant, utcnow +) -> None: + """Test that horizontal tilt is written correctly.""" + helper = await setup_test_component( + hass, create_window_covering_service_with_h_tilt_2 + ) + + await hass.services.async_call( + "cover", + "set_cover_tilt_position", + {"entity_id": helper.entity_id, "tilt_position": 90}, + blocking=True, + ) + # Expect converted value from percentage scale to arcdegree scale. + helper.async_assert_service_values( + ServicesTypes.WINDOW_COVERING, + { + CharacteristicsTypes.HORIZONTAL_TILT_TARGET: -81, }, ) @@ -173,10 +267,32 @@ async def test_write_window_cover_tilt_vertical(hass: HomeAssistant, utcnow) -> {"entity_id": helper.entity_id, "tilt_position": 90}, blocking=True, ) + # Expect converted value from percentage scale to arcdegree scale. helper.async_assert_service_values( ServicesTypes.WINDOW_COVERING, { - CharacteristicsTypes.VERTICAL_TILT_TARGET: 90, + CharacteristicsTypes.VERTICAL_TILT_TARGET: 81, + }, + ) + + +async def test_write_window_cover_tilt_vertical_2(hass: HomeAssistant, utcnow) -> None: + """Test that vertical tilt is written correctly.""" + helper = await setup_test_component( + hass, create_window_covering_service_with_v_tilt_2 + ) + + await hass.services.async_call( + "cover", + "set_cover_tilt_position", + {"entity_id": helper.entity_id, "tilt_position": 90}, + blocking=True, + ) + # Expect converted value from percentage scale to arcdegree scale. + helper.async_assert_service_values( + ServicesTypes.WINDOW_COVERING, + { + CharacteristicsTypes.VERTICAL_TILT_TARGET: -81, }, )