From 4b327be925864b80d9ac1158072e2e788f692fb5 Mon Sep 17 00:00:00 2001 From: HarvsG <11440490+HarvsG@users.noreply.github.com> Date: Thu, 19 Jun 2025 15:53:16 +0100 Subject: [PATCH 1/7] Improve subentry documentation. --- docs/config_entries_config_flow_handler.md | 72 +++++++++++++++++++++- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/docs/config_entries_config_flow_handler.md b/docs/config_entries_config_flow_handler.md index 6d2ef0ca92c..58de70551be 100644 --- a/docs/config_entries_config_flow_handler.md +++ b/docs/config_entries_config_flow_handler.md @@ -434,8 +434,42 @@ class LocationSubentryFlowHandler(ConfigSubentryFlow): async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> SubentryFlowResult: - """User flow to add a new location.""" - ... + """User flow to add a new location. + + Fnction name must be in the format "async_step_{step_id}" + The first step is always "user" + """ + + errors: dict[str, str] = {} + + # The function is called once to start the step and then again + # each time the user submits an input. This handles the latter + if user_input is not None: + try: + user_input = await _validate_subentry(user_input) + return self.async_create_entry( + title=user_input.get(CONF_NAME), + data=user_input, + ) + except (SchemaFlowError) as err: + _LOGGER.error("Error validating subentry: %s", err) + # errors can be attached the base of a form or to a specific field + errors["base"] = str(err) + + # This runs when the step starts or after a failed validation + return self.async_show_form( + step_id=str(ObservationTypes.STATE), + data_schema=self.add_suggested_values_to_schema( + data_schema=LOCATION_SUBSCHEMA, suggested_values=user_input + ), + last_step=True, + errors=errors, + description_placeholders={ + # the parent config entry can be accessed with self._get_entry() + "parent_entry_title": self._get_entry().title, + }, + ) + ``` ### Subentry unique ID @@ -492,7 +526,39 @@ class LocationSubentryFlowHandler(ConfigSubentryFlow): config_entry = self._get_reconfigure_entry() # Retrieve the specific subentry targeted for update. config_subentry = self._get_reconfigure_subentry() - ... + + if user_input is not None: + # validate user_input, possibly with some checks on ther subentries + # If checking for duplicates remeber to remove the entry you are reconfiguring + other_subentries = [ + dict(se.data) for se in self._get_entry().subentries.values() + ] + other_subentries.remove(dict(config_subentry.data)) + try: + ... #validation + return self.async_update_and_abort( + self._get_entry(), + config_subentry, + title=user_input.get(CONF_NAME, config_subentry.data[CONF_NAME]), + data_updates=user_input, + ) + except (SchemaFlowError) as err: + _LOGGER.error("Error reconfiguring subentry: %s", err) + # errors can be attached the base of a form or to a specific field + errors["base"] = str(err) + + return self.async_show_form( + step_id="reconfigure", + # You will likely want to fetch original values + data_schema=self.add_suggested_values_to_schema( + data_schema=SUBENTRY_SCHEMA, + suggested_values=config_subentry.data, + ), + errors=errors, + description_placeholders={ + "parent_entry_title": self._get_entry().title, + }, + ) ``` From ac7c02e55bca6ec771e080f3da68679a7c24277e Mon Sep 17 00:00:00 2001 From: HarvsG <11440490+HarvsG@users.noreply.github.com> Date: Thu, 19 Jun 2025 15:57:13 +0100 Subject: [PATCH 2/7] Update config_entries_config_flow_handler.md --- docs/config_entries_config_flow_handler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config_entries_config_flow_handler.md b/docs/config_entries_config_flow_handler.md index 58de70551be..16a2bf12a0b 100644 --- a/docs/config_entries_config_flow_handler.md +++ b/docs/config_entries_config_flow_handler.md @@ -531,7 +531,7 @@ class LocationSubentryFlowHandler(ConfigSubentryFlow): # validate user_input, possibly with some checks on ther subentries # If checking for duplicates remeber to remove the entry you are reconfiguring other_subentries = [ - dict(se.data) for se in self._get_entry().subentries.values() + dict(se.data) for se in config_entry.subentries.values() ] other_subentries.remove(dict(config_subentry.data)) try: From 36c2e43d68dc990b3ed045b864a9dbc8f24dea70 Mon Sep 17 00:00:00 2001 From: HarvsG <11440490+HarvsG@users.noreply.github.com> Date: Thu, 19 Jun 2025 16:12:36 +0100 Subject: [PATCH 3/7] Update config_entries_config_flow_handler.md --- docs/config_entries_config_flow_handler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config_entries_config_flow_handler.md b/docs/config_entries_config_flow_handler.md index 16a2bf12a0b..91f98d19e08 100644 --- a/docs/config_entries_config_flow_handler.md +++ b/docs/config_entries_config_flow_handler.md @@ -488,7 +488,7 @@ Subentries can set a unique ID. The rules are similar to [unique IDs](#unique-id "step": { "user": { "title": "Add location", - "description": "Configure the weather location" + "description": "Configure a weather location for {parent_entry_title}." }, "reconfigure": { "title": "Update location", From c9d268aa95865658f110e544423962d1bd669451 Mon Sep 17 00:00:00 2001 From: HarvsG <11440490+HarvsG@users.noreply.github.com> Date: Thu, 19 Jun 2025 16:15:00 +0100 Subject: [PATCH 4/7] Update config_entries_config_flow_handler.md --- docs/config_entries_config_flow_handler.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/config_entries_config_flow_handler.md b/docs/config_entries_config_flow_handler.md index 91f98d19e08..bd6213ef529 100644 --- a/docs/config_entries_config_flow_handler.md +++ b/docs/config_entries_config_flow_handler.md @@ -522,6 +522,8 @@ class LocationSubentryFlowHandler(ConfigSubentryFlow): self, user_input: dict[str, Any] | None = None ) -> SubentryFlowResult: """User flow to modify an existing location.""" + + errors: dict[str, str] = {} # Retrieve the parent config entry for reference. config_entry = self._get_reconfigure_entry() # Retrieve the specific subentry targeted for update. From ea77a1d7680632fa48a446ded46e3180c205c8fa Mon Sep 17 00:00:00 2001 From: HarvsG <11440490+HarvsG@users.noreply.github.com> Date: Thu, 19 Jun 2025 16:15:53 +0100 Subject: [PATCH 5/7] Update config_entries_config_flow_handler.md --- docs/config_entries_config_flow_handler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config_entries_config_flow_handler.md b/docs/config_entries_config_flow_handler.md index bd6213ef529..19a26035be1 100644 --- a/docs/config_entries_config_flow_handler.md +++ b/docs/config_entries_config_flow_handler.md @@ -436,7 +436,7 @@ class LocationSubentryFlowHandler(ConfigSubentryFlow): ) -> SubentryFlowResult: """User flow to add a new location. - Fnction name must be in the format "async_step_{step_id}" + Function name must be in the format "async_step_{step_id}" The first step is always "user" """ From b4b935b370170a42c810ff889d3313803f54212a Mon Sep 17 00:00:00 2001 From: HarvsG <11440490+HarvsG@users.noreply.github.com> Date: Thu, 19 Jun 2025 16:33:32 +0100 Subject: [PATCH 6/7] Don't log errors being shown to the user --- docs/config_entries_config_flow_handler.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/config_entries_config_flow_handler.md b/docs/config_entries_config_flow_handler.md index 19a26035be1..c7f403e390e 100644 --- a/docs/config_entries_config_flow_handler.md +++ b/docs/config_entries_config_flow_handler.md @@ -452,7 +452,6 @@ class LocationSubentryFlowHandler(ConfigSubentryFlow): data=user_input, ) except (SchemaFlowError) as err: - _LOGGER.error("Error validating subentry: %s", err) # errors can be attached the base of a form or to a specific field errors["base"] = str(err) @@ -545,7 +544,6 @@ class LocationSubentryFlowHandler(ConfigSubentryFlow): data_updates=user_input, ) except (SchemaFlowError) as err: - _LOGGER.error("Error reconfiguring subentry: %s", err) # errors can be attached the base of a form or to a specific field errors["base"] = str(err) From 14795c654977913197164aef4974e734d8842e6d Mon Sep 17 00:00:00 2001 From: HarvsG <11440490+HarvsG@users.noreply.github.com> Date: Thu, 19 Jun 2025 16:45:29 +0100 Subject: [PATCH 7/7] Update docs/config_entries_config_flow_handler.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- docs/config_entries_config_flow_handler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config_entries_config_flow_handler.md b/docs/config_entries_config_flow_handler.md index c7f403e390e..10a693badd4 100644 --- a/docs/config_entries_config_flow_handler.md +++ b/docs/config_entries_config_flow_handler.md @@ -538,7 +538,7 @@ class LocationSubentryFlowHandler(ConfigSubentryFlow): try: ... #validation return self.async_update_and_abort( - self._get_entry(), + config_entry, config_subentry, title=user_input.get(CONF_NAME, config_subentry.data[CONF_NAME]), data_updates=user_input,