From 859935e8bc1d421d6540f5dc83a032f943400e87 Mon Sep 17 00:00:00 2001 From: David K <142583+neffs@users.noreply.github.com> Date: Fri, 3 Jan 2020 14:19:03 +0100 Subject: [PATCH] Update HomeKit position state characteristic for covers (#27867) * HomeKit: update position state characteristic for covers position state is a mandatory characteristic for HK window coverings * Test position state characteristic --- .../components/homekit/type_covers.py | 17 ++++++++++- tests/components/homekit/test_type_covers.py | 28 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/homekit/type_covers.py b/homeassistant/components/homekit/type_covers.py index 3a33207e70e..8ad095faa13 100644 --- a/homeassistant/components/homekit/type_covers.py +++ b/homeassistant/components/homekit/type_covers.py @@ -18,6 +18,8 @@ from homeassistant.const import ( SERVICE_STOP_COVER, STATE_CLOSED, STATE_OPEN, + STATE_OPENING, + STATE_CLOSING, ) from . import TYPES @@ -101,6 +103,9 @@ class WindowCovering(HomeAccessory): self.char_target_position = serv_cover.configure_char( CHAR_TARGET_POSITION, value=0, setter_callback=self.move_cover ) + self.char_position_state = serv_cover.configure_char( + CHAR_POSITION_STATE, value=2 + ) @debounce def move_cover(self, value): @@ -122,6 +127,12 @@ class WindowCovering(HomeAccessory): ): self.char_target_position.set_value(current_position) self._homekit_target = None + if new_state.state == STATE_OPENING: + self.char_position_state.set_value(1) + elif new_state.state == STATE_CLOSING: + self.char_position_state.set_value(0) + else: + self.char_position_state.set_value(2) @TYPES.register("WindowCoveringBasic") @@ -175,7 +186,6 @@ class WindowCoveringBasic(HomeAccessory): # Snap the current/target position to the expected final position. self.char_current_position.set_value(position) self.char_target_position.set_value(position) - self.char_position_state.set_value(2) def update_state(self, new_state): """Update cover position after state changed.""" @@ -184,4 +194,9 @@ class WindowCoveringBasic(HomeAccessory): if hk_position is not None: self.char_current_position.set_value(hk_position) self.char_target_position.set_value(hk_position) + if new_state.state == STATE_OPENING: + self.char_position_state.set_value(1) + elif new_state.state == STATE_CLOSING: + self.char_position_state.set_value(0) + else: self.char_position_state.set_value(2) diff --git a/tests/components/homekit/test_type_covers.py b/tests/components/homekit/test_type_covers.py index d3cf24971ff..7ff65619bb6 100644 --- a/tests/components/homekit/test_type_covers.py +++ b/tests/components/homekit/test_type_covers.py @@ -15,6 +15,8 @@ from homeassistant.const import ( ATTR_SUPPORTED_FEATURES, STATE_CLOSED, STATE_OPEN, + STATE_OPENING, + STATE_CLOSING, STATE_UNAVAILABLE, STATE_UNKNOWN, ) @@ -138,11 +140,25 @@ async def test_window_set_cover_position(hass, hk_driver, cls, events): await hass.async_block_till_done() assert acc.char_current_position.value == 0 assert acc.char_target_position.value == 0 + assert acc.char_position_state.value == 2 + + hass.states.async_set(entity_id, STATE_OPENING, {ATTR_CURRENT_POSITION: 60}) + await hass.async_block_till_done() + assert acc.char_current_position.value == 60 + assert acc.char_target_position.value == 60 + assert acc.char_position_state.value == 1 + + hass.states.async_set(entity_id, STATE_CLOSING, {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 == 0 hass.states.async_set(entity_id, STATE_OPEN, {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 # Set from HomeKit call_set_cover_position = async_mock_service(hass, DOMAIN, "set_cover_position") @@ -189,12 +205,24 @@ async def test_window_open_close(hass, hk_driver, cls, events): assert acc.char_target_position.value == 0 assert acc.char_position_state.value == 2 + hass.states.async_set(entity_id, STATE_OPENING) + await hass.async_block_till_done() + assert acc.char_current_position.value == 0 + assert acc.char_target_position.value == 0 + assert acc.char_position_state.value == 1 + hass.states.async_set(entity_id, STATE_OPEN) await hass.async_block_till_done() assert acc.char_current_position.value == 100 assert acc.char_target_position.value == 100 assert acc.char_position_state.value == 2 + hass.states.async_set(entity_id, STATE_CLOSING) + await hass.async_block_till_done() + assert acc.char_current_position.value == 100 + assert acc.char_target_position.value == 100 + assert acc.char_position_state.value == 0 + hass.states.async_set(entity_id, STATE_CLOSED) await hass.async_block_till_done() assert acc.char_current_position.value == 0