Only callback when value or status changes for processing HKC events (#102370)

pull/102431/head
J. Nick Koston 2023-10-20 12:46:18 -10:00 committed by GitHub
parent 55a8f01dcf
commit a2c60d9015
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 6 deletions

View File

@ -833,10 +833,8 @@ class HKDevice:
# Process any stateless events (via device_triggers)
async_fire_triggers(self, new_values_dict)
self.entity_map.process_changes(new_values_dict)
to_callback: set[CALLBACK_TYPE] = set()
for aid_iid in new_values_dict:
for aid_iid in self.entity_map.process_changes(new_values_dict):
if callbacks := self._subscriptions.get(aid_iid):
to_callback.update(callbacks)

View File

@ -219,7 +219,11 @@ class HomeKitEntity(Entity):
@property
def available(self) -> bool:
"""Return True if entity is available."""
return self._accessory.available and self.service.available
return self._accessory.available and all(
c.available
for c in self.service.characteristics
if (self._aid, c.iid) in self.all_characteristics
)
@property
def device_info(self) -> DeviceInfo:

View File

@ -155,6 +155,13 @@ class Helper:
assert state is not None
return state
async def async_set_aid_iid_status(
self, aid_iid_status: list[tuple[int, int, int]]
) -> None:
"""Set the status of a set of aid/iid pairs."""
self.pairing.testing.set_aid_iid_status(aid_iid_status)
await self.hass.async_block_till_done()
@callback
def async_assert_service_values(
self, service: str, characteristics: dict[str, Any]

View File

@ -311,10 +311,9 @@ async def test_sensor_unavailable(hass: HomeAssistant, utcnow) -> None:
"""Test a sensor becoming unavailable."""
helper = await setup_test_component(hass, create_switch_with_sensor)
# Find the energy sensor and mark it as offline
outlet = helper.accessory.services.first(service_type=ServicesTypes.OUTLET)
on_char = outlet[CharacteristicsTypes.ON]
realtime_energy = outlet[CharacteristicsTypes.VENDOR_KOOGEEK_REALTIME_ENERGY]
realtime_energy.status = HapStatusCode.UNABLE_TO_COMMUNICATE
# Helper will be for the primary entity, which is the outlet. Make a helper for the sensor.
energy_helper = Helper(
@ -325,10 +324,32 @@ async def test_sensor_unavailable(hass: HomeAssistant, utcnow) -> None:
helper.config_entry,
)
# Find the outlet on char and mark it as offline
await helper.async_set_aid_iid_status(
[
(
helper.accessory.aid,
on_char.iid,
HapStatusCode.UNABLE_TO_COMMUNICATE.value,
)
]
)
# Outlet has non-responsive characteristics so should be unavailable
state = await helper.poll_and_get_state()
assert state.state == "unavailable"
# Find the energy sensor and mark it as offline
await helper.async_set_aid_iid_status(
[
(
energy_helper.accessory.aid,
realtime_energy.iid,
HapStatusCode.UNABLE_TO_COMMUNICATE.value,
)
]
)
# Energy sensor has non-responsive characteristics so should be unavailable
state = await energy_helper.poll_and_get_state()
assert state.state == "unavailable"