Fix HomeKit handling of unavailable state (#101021)
parent
6a52283ce0
commit
7d07694496
|
@ -465,7 +465,9 @@ class HomeAccessory(Accessory): # type: ignore[misc]
|
|||
def async_update_state_callback(self, new_state: State | None) -> None:
|
||||
"""Handle state change listener callback."""
|
||||
_LOGGER.debug("New_state: %s", new_state)
|
||||
if new_state is None:
|
||||
# HomeKit handles unavailable state via the available property
|
||||
# so we should not propagate it here
|
||||
if new_state is None or new_state.state == STATE_UNAVAILABLE:
|
||||
return
|
||||
battery_state = None
|
||||
battery_charging_state = None
|
||||
|
|
|
@ -74,17 +74,19 @@ async def test_garage_door_open_close(hass: HomeAssistant, hk_driver, events) ->
|
|||
assert acc.char_obstruction_detected.value is True
|
||||
|
||||
hass.states.async_set(
|
||||
entity_id, STATE_UNAVAILABLE, {ATTR_OBSTRUCTION_DETECTED: False}
|
||||
entity_id, STATE_UNAVAILABLE, {ATTR_OBSTRUCTION_DETECTED: True}
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert acc.char_current_state.value == HK_DOOR_OPEN
|
||||
assert acc.char_target_state.value == HK_DOOR_OPEN
|
||||
assert acc.char_obstruction_detected.value is False
|
||||
assert acc.char_obstruction_detected.value is True
|
||||
assert acc.available is False
|
||||
|
||||
hass.states.async_set(entity_id, STATE_UNKNOWN)
|
||||
await hass.async_block_till_done()
|
||||
assert acc.char_current_state.value == HK_DOOR_OPEN
|
||||
assert acc.char_target_state.value == HK_DOOR_OPEN
|
||||
assert acc.available is True
|
||||
|
||||
# Set from HomeKit
|
||||
call_close_cover = async_mock_service(hass, DOMAIN, "close_cover")
|
||||
|
|
|
@ -13,6 +13,7 @@ from homeassistant.const import (
|
|||
ATTR_CODE,
|
||||
ATTR_ENTITY_ID,
|
||||
STATE_LOCKED,
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
STATE_UNLOCKED,
|
||||
)
|
||||
|
@ -68,10 +69,32 @@ async def test_lock_unlock(hass: HomeAssistant, hk_driver, events) -> None:
|
|||
assert acc.char_current_state.value == 3
|
||||
assert acc.char_target_state.value == 0
|
||||
|
||||
hass.states.async_remove(entity_id)
|
||||
# Unavailable should keep last state
|
||||
# but set the accessory to not available
|
||||
hass.states.async_set(entity_id, STATE_UNAVAILABLE)
|
||||
await hass.async_block_till_done()
|
||||
assert acc.char_current_state.value == 3
|
||||
assert acc.char_target_state.value == 0
|
||||
assert acc.available is False
|
||||
|
||||
hass.states.async_set(entity_id, STATE_UNLOCKED)
|
||||
await hass.async_block_till_done()
|
||||
assert acc.char_current_state.value == 0
|
||||
assert acc.char_target_state.value == 0
|
||||
assert acc.available is True
|
||||
|
||||
# Unavailable should keep last state
|
||||
# but set the accessory to not available
|
||||
hass.states.async_set(entity_id, STATE_UNAVAILABLE)
|
||||
await hass.async_block_till_done()
|
||||
assert acc.char_current_state.value == 0
|
||||
assert acc.char_target_state.value == 0
|
||||
assert acc.available is False
|
||||
|
||||
hass.states.async_remove(entity_id)
|
||||
await hass.async_block_till_done()
|
||||
assert acc.char_current_state.value == 0
|
||||
assert acc.char_target_state.value == 0
|
||||
|
||||
# Set from HomeKit
|
||||
call_lock = async_mock_service(hass, DOMAIN, "lock")
|
||||
|
|
Loading…
Reference in New Issue