developers.home-assistant/blog/2025-02-19-new-config-entry...

72 lines
3.2 KiB
Markdown

---
author: Erik Montnemery
authorURL: https://github.com/emontnemery
title: "Changed config entry state transitions"
---
Config entry state transitions when unloading and removing entries has been modified:
- A new state `ConfigEntryState.UNLOAD_IN_PROGRESS` is added, which is set before calling the integration's `async_unload_entry`<br />
Rationale:
- Make it easier to write cleanup code which should run after the last config entry has been unloaded
- Improve debugging of issues related to reload and unload of config entries
- The config entry state is set to `ConfigEntryState.FAILED_UNLOAD` when the integration's `async_unload_entry` returns False<br />
Rationale:
- If `async_unload_entry` returns `False`, we can't assume the integration is still loaded, most likely it has partially unloaded itself, especially considering this is the pattern we recommend:
```py
async def async_unload_entry(hass: HomeAssistant, entry: MyConfigEntry) -> bool:
"""Unload a config entry."""
# async_unload_platforms returns False if at least one platform did not unload
if (unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS)):
entry.runtime_data.listener()
# Finish cleanup not related to platforms
return unload_ok
```
- The config entry is removed from `hass.config_entries` before calling the integration's `async_remove_entry` is called<br />
Rationale:
- Make it easier to write cleanup code which should run after the last config entry has been removed
Custom integration authors need to review and update their integrations' `async_unload_entry` and `async_remove_entry` if needed.
The most common pattern which requires an update is this:
```python
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
loaded_entries = [
entry
for entry in hass.config_entries.async_entries(DOMAIN)
if entry.state is ConfigEntryState.LOADED
]
if len(loaded_entries) == 1:
# The last config entry is being unloaded, release shared resources, unregister services etc.
...
```
This can now be simplified, if the custom integration's minimum Home Assistant version is set to 2025.3.0:
```python
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
if not hass.config_entries.async_loaded_entries(DOMAIN):
# The last config entry is being unloaded, release shared resources, unregister services etc.
...
```
If the custom integration needs to be backwards compatible with previous releases of Home Assistant Core:
```python
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
other_loaded_entries = [
_entry
for _entry in hass.config_entries.async_loaded_entries(DOMAIN)
if _entry.entry_id != entry.entry_id
]
if not other_loaded_entries:
# The last config entry is being unloaded, release shared resources, unregister services etc.
...
```
Check the [config entry documentation](/docs/config_entries_index), and the [home assistant core PR #138522](https://github.com/home-assistant/core/pull/138522) for additional background.