Add documentation for config subentries (#2561)

* Add documentation for config subentries

* Address review comments

* component -> integration

* Add blog

* Fix links

* Address review comments

* Add section
This commit is contained in:
Erik Montnemery 2025-02-17 10:02:29 +01:00 committed by GitHub
parent e1b99a12d7
commit 1e3a3f154b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 116 additions and 9 deletions

View File

@ -0,0 +1,11 @@
---
author: Erik Montnemery
authorURL: https://github.com/emontnemery
title: "Support for config subentries"
---
Config entries now have a new data type called “config subentry”. [Config subentries](/docs/config_entries_index#config-subentries) are owned by a config entry and set up as part of `async_setup_entry`. Config subentries are created by [config subentry flows](/docs/config_entries_config_flow_handler#subentry-flows) and updated by config subentry reconfigure flows. This works similarly to how we create/edit config entries.
This makes it easier for integration authors to allow users to add, modify and remove pieces of configuration which share some common resource, for example a cloud account or an MQTT broker.
The [architecture discussion](https://github.com/home-assistant/architecture/discussions/1070) gives more background.

View File

@ -2,11 +2,11 @@
title: Config flow
---
Integrations can be set up via the user interface by adding support for a config flow to create a config entry. Components that want to support config entries will need to define a Config Flow Handler. This handler will manage the creation of entries from user input, discovery or other sources (like Home Assistant OS).
Integrations can be set up via the user interface by adding support for a config flow to create a config entry. Integrations that want to support config entries will need to define a Config Flow Handler. This handler will manage the creation of entries from user input, discovery or other sources (like Home Assistant OS).
Config Flow Handlers control the data that is stored in a config entry. This means that there is no need to validate that the config is correct when Home Assistant starts up. It will also prevent breaking changes because we will be able to migrate configuration entries to new formats if the version changes.
When instantiating the handler, Home Assistant will make sure to load all dependencies and install the requirements of the component.
When instantiating the handler, Home Assistant will make sure to load all dependencies and install the requirements of the integration.
## Updating the manifest
@ -83,7 +83,7 @@ There are a few step names reserved for system use:
## Unique IDs
A config flow can attach a unique ID, which must be a string, to a config flow to avoid the same device being set up twice.
A config flow can attach a unique ID, which must be a string, to a config flow to avoid the same device being set up twice. The unique ID does not need to be globally unique, it only needs to be unique within an integration domain.
By setting a unique ID, users will have the option to ignore the discovery of your config entry. That way, they won't be bothered about it anymore.
If the integration uses Bluetooth, DHCP, HomeKit, Zeroconf/mDNS, USB, or SSDP/uPnP to be discovered, supplying a unique ID is required.
@ -198,7 +198,7 @@ To get started, run `python3 -m script.scaffold config_flow_oauth2` and follow t
## Translations
[Translations for the config flow](/docs/internationalization/core#config--options) handlers are defined under the `config` key in the component translation file `strings.json`. Example of the Hue component:
[Translations for the config flow](/docs/internationalization/core#config--options--subentry-flows) handlers are defined under the `config` key in the integration translation file `strings.json`. Example of the Hue integration:
```json
{
@ -238,7 +238,7 @@ When the translations are merged into Home Assistant, they will be automatically
As mentioned above - each Config Entry has a version assigned to it. This is to be able to migrate Config Entry data to new formats when Config Entry schema changes.
Migration can be handled programatically by implementing function `async_migrate_entry` in your component's `__init__.py` file. The function should return `True` if migration is successful.
Migration can be handled programatically by implementing function `async_migrate_entry` in your integration's `__init__.py` file. The function should return `True` if migration is successful.
The version is made of a major and minor version. If minor versions differ but major versions are the same, integration setup will be allowed to continue even if the integration does not implement `async_migrate_entry`. This means a minor version bump is backwards compatible unlike a major version bump which causes the integration to fail setup if the user downgrades Home Assistant Core without restoring their configuration from backup.
@ -331,7 +331,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
except TokenExpiredError as err:
raise ConfigEntryAuthFailed(err) from err
# TODO: Proceed with component setup
# TODO: Proceed with integration setup
```
The flow handler in `config_flow.py` also needs to have some additional steps to support reauth which include showing a confirmation, starting the reauth flow, updating the existing config entry, and reloading to invoke setup again.
@ -408,6 +408,94 @@ It is also possible to access the corresponding config entry using `self._get_re
Ensuring that the `unique_id` is unchanged should be done using `await self.async_set_unique_id` followed by `self._abort_if_unique_id_mismatch()`.
## Subentry flows
An integration can implement subentry flows to allow users to add, and optionally reconfigure, subentries. An example of this is an integration providing weather forecasts, where the config entry stores authentication details and each location for which weather forecasts should be provided is stored as a subentry.
Subentry flows are similar to config flows, except that subentry flows don't support reauthentication or discovery; a subentry flow can only be initiated via the `user` or `reconfigure` steps.
```python
class ExampleConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Config flow for Example integration."""
...
@classmethod
@callback
def async_get_supported_subentry_types(
cls, config_entry: ConfigEntry
) -> dict[str, type[ConfigSubentryFlow]]:
"""Return subentries supported by this integration."""
return {"location": LocationSubentryFlowHandler}
class LocationSubentryFlowHandler(ConfigSubentryFlow):
"""Handle subentry flow for adding and modifying a location."""
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> SubentryFlowResult:
"""User flow to add a new location."""
...
```
### Subentry unique ID
Subentries can set a unique ID. The rules are similar to [unique IDs](#unique-ids) of config entries, except that subentry unique IDs only need to be unique within the config entry.
### Subentry translations
[Translations for subentry flow](/docs/internationalization/core#config--options--subentry-flows) handlers are defined under the `config_subentries` key in the integration translation file `strings.json`, for example:
```json
{
"config_subentries": {
"location": {
"title": "Weather location",
"step": {
"user": {
"title": "Add location",
"description": "Configure the weather location"
},
"reconfigure": {
"title": "Update location",
"description": "..."
}
},
"error": {
},
"abort": {
}
}
}
}
```
### Subentry reconfigure
Subentries can be reconfigured, similar to how [config entries can be reconfigured](#reconfigure). To add support for reconfigure to a subentry flow, implement a `reconfigure` step.
```python
class LocationSubentryFlowHandler(ConfigSubentryFlow):
"""Handle subentry flow for adding and modifying a location."""
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> SubentryFlowResult:
"""User flow to add a new location."""
...
async def async_step_reconfigure(
self, user_input: dict[str, Any] | None = None
) -> SubentryFlowResult:
"""User flow to modify an existing location."""
# Retrieve the parent config entry for reference.
config_entry = self._get_reconfigure_entry()
# Retrieve the specific subentry targeted for update.
config_subentry = self._get_reconfigure_subentry()
...
```
## Testing your config flow
Integrations with a config flow require full test coverage of all code in `config_flow.py` to be accepted into core. [Test your code](development_testing.md#running-a-limited-test-suite) includes more details on how to generate a coverage report.

View File

@ -2,7 +2,15 @@
title: Config entries
---
Config Entries are configuration data that are persistently stored by Home Assistant. A config entry is created by a user via the UI. The UI flow is powered by a [config flow handler](config_entries_config_flow_handler.md) as defined by the component. Config entries can also have an extra [options flow handler](config_entries_options_flow_handler.md), also defined by the component.
Config entries are configuration data that are persistently stored by Home Assistant. A config entry is created by a user via the UI. The UI flow is powered by a [config flow handler](config_entries_config_flow_handler.md) as defined by the integration.
Once created, config entries can be removed by the user. Optionally, config entries can be changed by the user via a [reconfigure step](config_entries_config_flow_handler.md#reconfigure) or [options flow handler](config_entries_options_flow_handler.md), also defined by the integration.
### Config subentries
Config entries can logically separate the stored configuration data into subentries, which can be added by the user via the UI to an existing config entry. An example of this is an integration providing weather forecasts, where the config entry stores authentication details and each location for which weather forecasts should be provided is stored as a subentry.
Similar to config entries, subentries can optionally support a reconfigure step.
## Lifecycle

View File

@ -54,9 +54,9 @@ Strings which are used more than once should be not be duplicated, instead refer
}
```
### Config / Options
### Config / Options / Subentry flows
The translation strings for the configuration flow handler and the option flow handler are defined under the `config` and `options` keys respectively. An example strings file below describes the different supported keys. Although the example shows translations for a configuration flow, the translations for an option flow is exactly the same.
The translation strings for the configuration flow handler, the option flow handler and config subentry handlers are defined under the `config`, `options` and `config_subentries` keys respectively. An example strings file below describes the different supported keys. Although the example shows translations for a configuration flow, the translations for an option flow is exactly the same.
```json
{