Fix covers moving state in HomeKit (#77101)

Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
Artem Draft 2022-08-21 19:54:37 +03:00 committed by GitHub
parent 5d8f5708f4
commit ac56b3306a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 8 deletions

View File

@ -29,7 +29,7 @@ from homeassistant.const import (
STATE_OPEN,
STATE_OPENING,
)
from homeassistant.core import callback
from homeassistant.core import State, callback
from homeassistant.helpers.event import async_track_state_change_event
from .accessories import TYPES, HomeAccessory
@ -79,6 +79,8 @@ DOOR_TARGET_HASS_TO_HK = {
STATE_CLOSING: HK_DOOR_CLOSED,
}
MOVING_STATES = {STATE_OPENING, STATE_CLOSING}
_LOGGER = logging.getLogger(__name__)
@ -301,13 +303,16 @@ class OpeningDevice(OpeningDeviceBase, HomeAccessory):
self.async_call_service(DOMAIN, SERVICE_SET_COVER_POSITION, params, value)
@callback
def async_update_state(self, new_state):
def async_update_state(self, new_state: State) -> None:
"""Update cover position and tilt after state changed."""
current_position = new_state.attributes.get(ATTR_CURRENT_POSITION)
if isinstance(current_position, (float, int)):
current_position = int(current_position)
self.char_current_position.set_value(current_position)
self.char_target_position.set_value(current_position)
# Writing target_position on a moving cover
# will break the moving state in HK.
if new_state.state not in MOVING_STATES:
self.char_target_position.set_value(current_position)
position_state = _hass_state_to_position_start(new_state.state)
self.char_position_state.set_value(position_state)
@ -390,14 +395,16 @@ class WindowCoveringBasic(OpeningDeviceBase, HomeAccessory):
self.char_target_position.set_value(position)
@callback
def async_update_state(self, new_state):
def async_update_state(self, new_state: State) -> None:
"""Update cover position after state changed."""
position_mapping = {STATE_OPEN: 100, STATE_CLOSED: 0}
hk_position = position_mapping.get(new_state.state)
if hk_position is not None:
is_moving = new_state.state in MOVING_STATES
if self.char_current_position.value != hk_position:
self.char_current_position.set_value(hk_position)
if self.char_target_position.value != hk_position:
if self.char_target_position.value != hk_position and not is_moving:
self.char_target_position.set_value(hk_position)
position_state = _hass_state_to_position_start(new_state.state)
if self.char_position_state.value != position_state:

View File

@ -166,7 +166,7 @@ async def test_windowcovering_set_cover_position(hass, hk_driver, events):
)
await hass.async_block_till_done()
assert acc.char_current_position.value == 60
assert acc.char_target_position.value == 60
assert acc.char_target_position.value == 0
assert acc.char_position_state.value == 1
hass.states.async_set(
@ -176,7 +176,7 @@ async def test_windowcovering_set_cover_position(hass, hk_driver, events):
)
await hass.async_block_till_done()
assert acc.char_current_position.value == 70
assert acc.char_target_position.value == 70
assert acc.char_target_position.value == 0
assert acc.char_position_state.value == 1
hass.states.async_set(
@ -186,7 +186,7 @@ async def test_windowcovering_set_cover_position(hass, hk_driver, events):
)
await hass.async_block_till_done()
assert acc.char_current_position.value == 50
assert acc.char_target_position.value == 50
assert acc.char_target_position.value == 0
assert acc.char_position_state.value == 0
hass.states.async_set(