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
This commit is contained in:
David K 2020-01-03 14:19:03 +01:00 committed by Charles Garwood
parent b57da2f862
commit 859935e8bc
2 changed files with 44 additions and 1 deletions

View file

@ -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)

View file

@ -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