mirror of
https://github.com/home-assistant/core.git
synced 2025-08-30 01:42:21 +02:00
Fix HomeKit Controller entity state restore issues for IP/COAP devices (#151087)
This commit is contained in:
@@ -228,7 +228,9 @@ class HKDevice:
|
||||
_LOGGER.debug(
|
||||
"Called async_set_available_state with %s for %s", available, self.unique_id
|
||||
)
|
||||
if self.available == available:
|
||||
# Don't mark entities as unavailable during shutdown to preserve their last known state
|
||||
# Also skip if the availability state hasn't changed
|
||||
if (self.hass.is_stopping and not available) or self.available == available:
|
||||
return
|
||||
self.available = available
|
||||
for callback_ in self._availability_callbacks:
|
||||
@@ -294,7 +296,6 @@ class HKDevice:
|
||||
await self.pairing.async_populate_accessories_state(
|
||||
force_update=True, attempts=attempts
|
||||
)
|
||||
self._async_start_polling()
|
||||
|
||||
entry.async_on_unload(pairing.dispatcher_connect(self.process_new_events))
|
||||
entry.async_on_unload(
|
||||
@@ -307,6 +308,12 @@ class HKDevice:
|
||||
|
||||
await self.async_process_entity_map()
|
||||
|
||||
if transport != Transport.BLE:
|
||||
# Do a single poll to make sure the chars are
|
||||
# up to date so we don't restore old data.
|
||||
await self.async_update()
|
||||
self._async_start_polling()
|
||||
|
||||
# If everything is up to date, we can create the entities
|
||||
# since we know the data is not stale.
|
||||
await self.async_add_new_entities()
|
||||
@@ -711,9 +718,11 @@ class HKDevice:
|
||||
"""Stop interacting with device and prepare for removal from hass."""
|
||||
await self.pairing.shutdown()
|
||||
|
||||
await self.hass.config_entries.async_unload_platforms(
|
||||
self.config_entry, self.platforms
|
||||
)
|
||||
# Skip platform unloading during shutdown to preserve entity states
|
||||
if not self.hass.is_stopping:
|
||||
await self.hass.config_entries.async_unload_platforms(
|
||||
self.config_entry, self.platforms
|
||||
)
|
||||
|
||||
def process_config_changed(self, config_num: int) -> None:
|
||||
"""Handle a config change notification from the pairing."""
|
||||
|
@@ -900,7 +900,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery-20',
|
||||
'original_name': 'eufyCam2-0000 Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -1156,7 +1156,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery-40',
|
||||
'original_name': 'eufyCam2-000A Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -1412,7 +1412,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery-alert',
|
||||
'original_name': 'eufyCam2-000A Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -1848,7 +1848,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Contact Sensor Battery Sensor',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -2270,7 +2270,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Programmable Switch Battery Sensor',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -2601,7 +2601,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery-80',
|
||||
'original_name': 'ArloBabyA0 Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -4473,7 +4473,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Basement Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -4780,7 +4780,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Basement Window 1 Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -5037,7 +5037,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Deck Door Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -5294,7 +5294,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Front Door Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -5551,7 +5551,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Garage Door Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -5765,7 +5765,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Living Room Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -6072,7 +6072,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Living Room Window 1 Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -6329,7 +6329,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Loft window Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -6543,7 +6543,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Master BR Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -6850,7 +6850,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Master BR Window Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -7462,7 +7462,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Upstairs BR Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -7769,7 +7769,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Upstairs BR Window Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -10111,7 +10111,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery-60',
|
||||
'original_name': 'Eve Degree AA11 Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -11099,7 +11099,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Family Room North Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -11351,7 +11351,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Kitchen Window Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -12392,7 +12392,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Laundry Smoke ED78 Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -12568,7 +12568,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Family Room North Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -12820,7 +12820,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Kitchen Window Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -14645,7 +14645,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Laundry Smoke ED78 Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -16083,7 +16083,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Hue dimmer switch battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -20820,7 +20820,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'Master Bath South RYSE Shade Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -21072,7 +21072,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'RYSE SmartShade RYSE Shade Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -21248,7 +21248,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'BR Left RYSE Shade Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -21420,7 +21420,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery-90',
|
||||
'original_name': 'LR Left RYSE Shade Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -21592,7 +21592,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery',
|
||||
'original_name': 'LR Right RYSE Shade Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
@@ -21844,7 +21844,7 @@
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': 'mdi:battery-unknown',
|
||||
'original_icon': 'mdi:battery-alert',
|
||||
'original_name': 'RZSS RYSE Shade Battery',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
|
@@ -88,3 +88,32 @@ async def test_storage_is_updated_on_add(
|
||||
# Is saved out to store?
|
||||
await flush_store(entity_map.store)
|
||||
assert hkid in hass_storage[ENTITY_MAP]["data"]["pairings"]
|
||||
|
||||
|
||||
async def test_storage_is_saved_on_stop(
|
||||
hass: HomeAssistant, hass_storage: dict[str, Any], get_next_aid: Callable[[], int]
|
||||
) -> None:
|
||||
"""Test entity map storage is saved when Home Assistant stops."""
|
||||
await setup_test_component(hass, get_next_aid(), create_lightbulb_service)
|
||||
|
||||
entity_map: EntityMapStorage = hass.data[ENTITY_MAP]
|
||||
hkid = "00:00:00:00:00:00"
|
||||
|
||||
# Verify the device is in memory
|
||||
assert hkid in entity_map.storage_data
|
||||
|
||||
# Clear the storage to verify it gets saved on stop
|
||||
del hass_storage[ENTITY_MAP]
|
||||
|
||||
# Make a change to trigger a save
|
||||
entity_map.async_create_or_update_map(hkid, 2, []) # Update config_num
|
||||
|
||||
# Simulate Home Assistant stopping (sets the state and fires the event)
|
||||
await hass.async_stop()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify the storage was saved
|
||||
assert ENTITY_MAP in hass_storage
|
||||
assert hkid in hass_storage[ENTITY_MAP]["data"]["pairings"]
|
||||
# Verify the updated data was saved
|
||||
assert hass_storage[ENTITY_MAP]["data"]["pairings"][hkid]["config_num"] == 2
|
||||
|
Reference in New Issue
Block a user