Fix covers moving state in HomeKit (#77101)
Co-authored-by: J. Nick Koston <nick@koston.org>pull/76718/head^2
parent
5d8f5708f4
commit
ac56b3306a
|
@ -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:
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue