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:
|
def async_update_state_callback(self, new_state: State | None) -> None:
|
||||||
"""Handle state change listener callback."""
|
"""Handle state change listener callback."""
|
||||||
_LOGGER.debug("New_state: %s", new_state)
|
_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
|
return
|
||||||
battery_state = None
|
battery_state = None
|
||||||
battery_charging_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
|
assert acc.char_obstruction_detected.value is True
|
||||||
|
|
||||||
hass.states.async_set(
|
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()
|
await hass.async_block_till_done()
|
||||||
assert acc.char_current_state.value == HK_DOOR_OPEN
|
assert acc.char_current_state.value == HK_DOOR_OPEN
|
||||||
assert acc.char_target_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)
|
hass.states.async_set(entity_id, STATE_UNKNOWN)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert acc.char_current_state.value == HK_DOOR_OPEN
|
assert acc.char_current_state.value == HK_DOOR_OPEN
|
||||||
assert acc.char_target_state.value == HK_DOOR_OPEN
|
assert acc.char_target_state.value == HK_DOOR_OPEN
|
||||||
|
assert acc.available is True
|
||||||
|
|
||||||
# Set from HomeKit
|
# Set from HomeKit
|
||||||
call_close_cover = async_mock_service(hass, DOMAIN, "close_cover")
|
call_close_cover = async_mock_service(hass, DOMAIN, "close_cover")
|
||||||
|
|
|
@ -13,6 +13,7 @@ from homeassistant.const import (
|
||||||
ATTR_CODE,
|
ATTR_CODE,
|
||||||
ATTR_ENTITY_ID,
|
ATTR_ENTITY_ID,
|
||||||
STATE_LOCKED,
|
STATE_LOCKED,
|
||||||
|
STATE_UNAVAILABLE,
|
||||||
STATE_UNKNOWN,
|
STATE_UNKNOWN,
|
||||||
STATE_UNLOCKED,
|
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_current_state.value == 3
|
||||||
assert acc.char_target_state.value == 0
|
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()
|
await hass.async_block_till_done()
|
||||||
assert acc.char_current_state.value == 3
|
assert acc.char_current_state.value == 3
|
||||||
assert acc.char_target_state.value == 0
|
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
|
# Set from HomeKit
|
||||||
call_lock = async_mock_service(hass, DOMAIN, "lock")
|
call_lock = async_mock_service(hass, DOMAIN, "lock")
|
||||||
|
|
Loading…
Reference in New Issue