Fix fallback to polling HomeKit devices that fail to subscribe

fixes #https://github.com/home-assistant/core/issues/124099
needs https://github.com/Jc2k/aiohomekit/pull/378
This commit is contained in:
J. Nick Koston 2024-08-25 13:36:13 -10:00
parent 8bc9fd23bb
commit fcc10e3a52
No known key found for this signature in database
2 changed files with 34 additions and 5 deletions

View file

@ -849,16 +849,15 @@ class HKDevice:
"""Poll state of all entities attached to this bridge/accessory."""
to_poll = self.pollable_characteristics
accessories = self.entity_map.accessories
pairing = self.pairing
if (
not self._full_update_requested
and pairing.supports_subscribe
and len(accessories) == 1
and self.available
and not (to_poll - self.watchable_characteristics)
and self.pairing.is_available
and await self.pairing.controller.async_reachable(
self.unique_id, timeout=5.0
)
and pairing.is_available
and await pairing.controller.async_reachable(self.unique_id, timeout=5.0)
):
# If its a single accessory and all chars are watchable,
# only poll the firmware version to keep the connection alive

View file

@ -439,3 +439,33 @@ async def test_manual_poll_all_chars(
await time_changed(hass, DEBOUNCE_COOLDOWN)
await hass.async_block_till_done()
assert len(mock_get_characteristics.call_args_list[0][0][0]) > 1
async def test_device_has_broken_subscribe(
hass: HomeAssistant, get_next_aid: Callable[[], int]
) -> None:
"""Test device that does not support subscribe."""
def _create_accessory(accessory: Accessory) -> Service:
service = accessory.add_service(ServicesTypes.LIGHTBULB, name="TestDevice")
on_char = service.add_char(CharacteristicsTypes.ON)
on_char.value = 0
brightness = service.add_char(CharacteristicsTypes.BRIGHTNESS)
brightness.value = 0
return service
helper = await setup_test_component(hass, get_next_aid(), _create_accessory)
helper.pairing.supports_subscribe = False
with mock.patch.object(
helper.pairing,
"get_characteristics",
wraps=helper.pairing.get_characteristics,
) as mock_get_characteristics:
# Initial state is that the light is off
await helper.poll_and_get_state()
# Verify everything is polled because subscribe is not supported
assert len(mock_get_characteristics.call_args_list[0][0][0]) > 1