diff --git a/homeassistant/components/airly/strings.json b/homeassistant/components/airly/strings.json index bf0d950fa7c0..eac4251135ef 100644 --- a/homeassistant/components/airly/strings.json +++ b/homeassistant/components/airly/strings.json @@ -2,7 +2,6 @@ "config": { "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_location%]", - "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]", "wrong_location": "[%key:component::airly::config::error::wrong_location%]" }, "error": { diff --git a/homeassistant/components/apple_tv/config_flow.py b/homeassistant/components/apple_tv/config_flow.py index 6670c095e17b..198346bda80e 100644 --- a/homeassistant/components/apple_tv/config_flow.py +++ b/homeassistant/components/apple_tv/config_flow.py @@ -25,7 +25,7 @@ from homeassistant.config_entries import ( ConfigFlowResult, ) from homeassistant.const import CONF_ADDRESS, CONF_NAME, CONF_PIN -from homeassistant.core import HomeAssistant, callback +from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant, callback from homeassistant.data_entry_flow import AbortFlow from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv @@ -289,7 +289,9 @@ class AppleTVConfigFlow(ConfigFlow, domain=DOMAIN): def _async_check_and_update_in_progress(self, host: str, unique_id: str) -> None: """Check for in-progress flows and update them with identifiers if needed.""" if self.hass.config_entries.flow.async_has_matching_flow(self): - raise AbortFlow("already_in_progress") + raise AbortFlow( + "already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN + ) @override def is_matching(self, other_flow: Self) -> bool: diff --git a/homeassistant/components/apple_tv/strings.json b/homeassistant/components/apple_tv/strings.json index 786f0e7fc96c..8b0a43496624 100644 --- a/homeassistant/components/apple_tv/strings.json +++ b/homeassistant/components/apple_tv/strings.json @@ -2,7 +2,6 @@ "config": { "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", - "already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]", "backoff": "Device does not accept pairing requests at this time (you might have entered an invalid PIN code too many times), try again later.", "device_did_not_pair": "No attempt to finish pairing process was made from the device.", "device_not_found": "Device was not found during discovery, please try adding it again.", diff --git a/homeassistant/components/bthome/config_flow.py b/homeassistant/components/bthome/config_flow.py index 59258a114bfe..7484c016917e 100644 --- a/homeassistant/components/bthome/config_flow.py +++ b/homeassistant/components/bthome/config_flow.py @@ -15,6 +15,7 @@ from homeassistant.components.bluetooth import ( ) from homeassistant.config_entries import SOURCE_REAUTH, ConfigFlow, ConfigFlowResult from homeassistant.const import CONF_ADDRESS +from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN from .const import DOMAIN @@ -174,7 +175,9 @@ class BTHomeConfigFlow(ConfigFlow, domain=DOMAIN): return await self.async_step_get_encryption_key() # Otherwise there wasn't actually encryption so abort - return self.async_abort(reason="reauth_successful") + return self.async_abort( + reason="reauth_successful", translation_domain=HOMEASSISTANT_DOMAIN + ) def _async_get_or_create_entry( self, bindkey: str | None = None diff --git a/homeassistant/components/bthome/strings.json b/homeassistant/components/bthome/strings.json index dfee8e5dce2b..49af40fc6f81 100644 --- a/homeassistant/components/bthome/strings.json +++ b/homeassistant/components/bthome/strings.json @@ -2,8 +2,7 @@ "config": { "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", - "no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]", - "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]" + "no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]" }, "error": { "decryption_failed": "The provided bindkey did not work, sensor data could not be decrypted. Please check it and try again.", diff --git a/homeassistant/components/elkm1/config_flow.py b/homeassistant/components/elkm1/config_flow.py index f80518b5ab47..50797f4910cb 100644 --- a/homeassistant/components/elkm1/config_flow.py +++ b/homeassistant/components/elkm1/config_flow.py @@ -17,6 +17,7 @@ from homeassistant.const import ( CONF_PROTOCOL, CONF_USERNAME, ) +from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import device_registry as dr from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo @@ -192,7 +193,9 @@ class Elkm1ConfigFlow(ConfigFlow, domain=DOMAIN): return self.async_abort(reason="already_configured") self.host = host if self.hass.config_entries.flow.async_has_matching_flow(self): - return self.async_abort(reason="already_in_progress") + return self.async_abort( + reason="already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN + ) # Handled ignored case since _async_current_entries # is called with include_ignore=False self._abort_if_unique_id_configured() diff --git a/homeassistant/components/elkm1/strings.json b/homeassistant/components/elkm1/strings.json index 724067cb6c22..b1c44d14beba 100644 --- a/homeassistant/components/elkm1/strings.json +++ b/homeassistant/components/elkm1/strings.json @@ -3,7 +3,6 @@ "abort": { "address_already_configured": "An Elk-M1 with this address is already configured", "already_configured": "An Elk-M1 with this prefix is already configured", - "already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]", "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", "invalid_auth": "[%key:common::config_flow::error::invalid_auth%]", "reconfigure_successful": "Successfully reconfigured Elk-M1 integration", diff --git a/homeassistant/components/enphase_envoy/config_flow.py b/homeassistant/components/enphase_envoy/config_flow.py index 8ea1b2617f6b..a0a601b2bfce 100644 --- a/homeassistant/components/enphase_envoy/config_flow.py +++ b/homeassistant/components/enphase_envoy/config_flow.py @@ -260,6 +260,7 @@ class EnphaseConfigFlow(ConfigFlow, domain=DOMAIN): ) if not errors: # successful authentication, update config + # Shares the local string with the unique ID abort in async_step_user return self.async_update_reload_and_abort( reauth_entry, data_updates=user_input @@ -268,6 +269,7 @@ class EnphaseConfigFlow(ConfigFlow, domain=DOMAIN): if isinstance(envoy.auth, EnvoyTokenAuth) else {} ), + reason="reauth_successful", ) if token: token_days_left = token_lifetime(token) diff --git a/homeassistant/components/flux_led/config_flow.py b/homeassistant/components/flux_led/config_flow.py index 239b7ceaf5e6..79081943d8a3 100644 --- a/homeassistant/components/flux_led/config_flow.py +++ b/homeassistant/components/flux_led/config_flow.py @@ -22,7 +22,7 @@ from homeassistant.config_entries import ( OptionsFlow, ) from homeassistant.const import CONF_DEVICE, CONF_HOST -from homeassistant.core import callback +from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, callback from homeassistant.data_entry_flow import AbortFlow from homeassistant.helpers import device_registry as dr from homeassistant.helpers.dispatcher import async_dispatcher_send @@ -156,7 +156,9 @@ class FluxLedConfigFlow(ConfigFlow, domain=DOMAIN): host = device[ATTR_IPADDR] self.host = host if self.hass.config_entries.flow.async_has_matching_flow(self): - return self.async_abort(reason="already_in_progress") + return self.async_abort( + reason="already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN + ) if not device[ATTR_MODEL_DESCRIPTION]: mac_address = device[ATTR_ID] assert mac_address is not None diff --git a/homeassistant/components/flux_led/strings.json b/homeassistant/components/flux_led/strings.json index f8bfb39d9f4f..cc36bd0fba82 100644 --- a/homeassistant/components/flux_led/strings.json +++ b/homeassistant/components/flux_led/strings.json @@ -2,7 +2,6 @@ "config": { "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", - "already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]", "no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]" }, "error": { diff --git a/homeassistant/components/fritzbox/config_flow.py b/homeassistant/components/fritzbox/config_flow.py index 57713ef42959..9a028306f07c 100644 --- a/homeassistant/components/fritzbox/config_flow.py +++ b/homeassistant/components/fritzbox/config_flow.py @@ -17,6 +17,7 @@ from homeassistant.const import ( CONF_USERNAME, CONF_VERIFY_SSL, ) +from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN from homeassistant.helpers.selector import ( TextSelector, TextSelectorConfig, @@ -166,7 +167,9 @@ class FritzboxConfigFlow(ConfigFlow, domain=DOMAIN): self._abort_if_unique_id_configured({CONF_HOST: self._url}) if self.hass.config_entries.flow.async_has_matching_flow(self): - return self.async_abort(reason="already_in_progress") + return self.async_abort( + reason="already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN + ) # update old and user-configured config entries for entry in self._async_current_entries(include_ignore=False): diff --git a/homeassistant/components/fritzbox/strings.json b/homeassistant/components/fritzbox/strings.json index 6db4981baf2b..99ed3317dccf 100644 --- a/homeassistant/components/fritzbox/strings.json +++ b/homeassistant/components/fritzbox/strings.json @@ -8,7 +8,6 @@ "config": { "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", - "already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]", "ignore_ip6_link_local": "IPv6 link local address is not supported.", "no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]", "not_supported": "Connected to FRITZ!Box but it's unable to control Smart Home devices." diff --git a/homeassistant/components/heos/strings.json b/homeassistant/components/heos/strings.json index 142a1b9872eb..724e353be93e 100644 --- a/homeassistant/components/heos/strings.json +++ b/homeassistant/components/heos/strings.json @@ -2,7 +2,6 @@ "config": { "abort": { "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", - "reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]", "single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]" }, "error": { diff --git a/homeassistant/components/homewizard/strings.json b/homeassistant/components/homewizard/strings.json index cf7efba2f262..14e2e7549349 100644 --- a/homeassistant/components/homewizard/strings.json +++ b/homeassistant/components/homewizard/strings.json @@ -5,7 +5,6 @@ "device_not_supported": "This device is not supported", "invalid_discovery_parameters": "Invalid discovery parameters", "reauth_enable_api_successful": "Enabling API was successful", - "reauth_successful": "Authorization successful", "unknown_error": "[%key:common::config_flow::error::unknown%]", "unsupported_api_version": "Detected unsupported API version", "wrong_device": "The configured device is not the same found on this IP address." diff --git a/homeassistant/components/izone/config_flow.py b/homeassistant/components/izone/config_flow.py index 03daad4d382b..c77bd180868f 100644 --- a/homeassistant/components/izone/config_flow.py +++ b/homeassistant/components/izone/config_flow.py @@ -13,7 +13,7 @@ import probatio from homeassistant import config_entries from homeassistant.config_entries import ConfigFlow, ConfigFlowResult, FlowType from homeassistant.const import CONF_HOST -from homeassistant.core import callback +from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, callback from homeassistant.helpers.selector import ( SelectOptionDict, SelectSelector, @@ -88,7 +88,9 @@ class IZoneConfigFlow(ConfigFlow, domain=DOMAIN): request as part of start-up, and the import step itself will not be repeated. """ if self._async_in_progress(include_uninitialized=True): - return self.async_abort(reason="already_in_progress") + return self.async_abort( + reason="already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN + ) try: await izone_discovery.async_ensure_discovery(self.hass) diff --git a/homeassistant/components/izone/strings.json b/homeassistant/components/izone/strings.json index 90bfed3fa355..23181648d4a2 100644 --- a/homeassistant/components/izone/strings.json +++ b/homeassistant/components/izone/strings.json @@ -2,7 +2,6 @@ "config": { "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", - "already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]", "continue_setup": "Continue setting up the discovered iZone controller.", "discovery_failed": "Failed to start iZone discovery. Make sure your network is properly configured.", "discovery_started": "iZone discovery has started. Your controllers will appear as discovered devices under Settings \u003e Devices \u0026 services.", diff --git a/homeassistant/components/librenms/strings.json b/homeassistant/components/librenms/strings.json index 66f688606039..795d63b3dcdb 100644 --- a/homeassistant/components/librenms/strings.json +++ b/homeassistant/components/librenms/strings.json @@ -6,9 +6,7 @@ }, "config": { "abort": { - "already_configured": "This LibreNMS instance is already configured.", - "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]", - "reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]" + "already_configured": "This LibreNMS instance is already configured." }, "error": { "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", diff --git a/homeassistant/components/lifx/strings.json b/homeassistant/components/lifx/strings.json index 7f42616ac1d1..75552010b889 100644 --- a/homeassistant/components/lifx/strings.json +++ b/homeassistant/components/lifx/strings.json @@ -5,7 +5,6 @@ "already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]", "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", "no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]", - "reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]", "wrong_device": "The device at this address is not the one this entry was set up for." }, "error": { diff --git a/homeassistant/components/mikrotik/strings.json b/homeassistant/components/mikrotik/strings.json index 2fdf0a7ed734..b0a833969939 100644 --- a/homeassistant/components/mikrotik/strings.json +++ b/homeassistant/components/mikrotik/strings.json @@ -1,8 +1,7 @@ { "config": { "abort": { - "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", - "reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]" + "already_configured": "[%key:common::config_flow::abort::already_configured_device%]" }, "error": { "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", diff --git a/homeassistant/components/monarch_money/strings.json b/homeassistant/components/monarch_money/strings.json index a3443c4bbba9..d845157fb686 100644 --- a/homeassistant/components/monarch_money/strings.json +++ b/homeassistant/components/monarch_money/strings.json @@ -2,7 +2,6 @@ "config": { "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", - "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]", "unique_id_mismatch": "The authenticated Monarch Money account does not match the configured account." }, "error": { diff --git a/homeassistant/components/nobo_hub/config_flow.py b/homeassistant/components/nobo_hub/config_flow.py index 53baf9b08ea3..5842b90320c3 100644 --- a/homeassistant/components/nobo_hub/config_flow.py +++ b/homeassistant/components/nobo_hub/config_flow.py @@ -13,7 +13,7 @@ from homeassistant.config_entries import ( OptionsFlowWithReload, ) from homeassistant.const import CONF_IP_ADDRESS, CONF_MAC -from homeassistant.core import callback +from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import format_mac from homeassistant.helpers.selector import SelectSelector, SelectSelectorConfig @@ -244,7 +244,10 @@ class NoboHubConfigFlow(ConfigFlow, domain=DOMAIN): # No-op: IP unchanged and the running integration already # proves it works. Skip the reload to avoid a needless # reconnect. - return self.async_abort(reason="reconfigure_successful") + return self.async_abort( + reason="reconfigure_successful", + translation_domain=HOMEASSISTANT_DOMAIN, + ) return self.async_update_reload_and_abort( reconfigure_entry, data_updates={CONF_IP_ADDRESS: new_ip}, diff --git a/homeassistant/components/nobo_hub/strings.json b/homeassistant/components/nobo_hub/strings.json index 88ee15ac5e36..ab62847a5897 100644 --- a/homeassistant/components/nobo_hub/strings.json +++ b/homeassistant/components/nobo_hub/strings.json @@ -2,8 +2,7 @@ "config": { "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", - "cannot_discover": "Could not detect a Nobø Ecohub at the discovered IP address.", - "reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]" + "cannot_discover": "Could not detect a Nobø Ecohub at the discovered IP address." }, "error": { "cannot_connect": "Failed to connect - check serial number", diff --git a/homeassistant/components/samsungtv/config_flow.py b/homeassistant/components/samsungtv/config_flow.py index 92b492d77777..0abfd7695dbb 100644 --- a/homeassistant/components/samsungtv/config_flow.py +++ b/homeassistant/components/samsungtv/config_flow.py @@ -26,7 +26,7 @@ from homeassistant.const import ( CONF_PORT, CONF_TOKEN, ) -from homeassistant.core import callback +from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, callback from homeassistant.data_entry_flow import AbortFlow from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.device_registry import format_mac @@ -489,7 +489,9 @@ class SamsungTVConfigFlow(ConfigFlow, domain=DOMAIN): @callback def _async_abort_if_host_already_in_progress(self) -> None: if self.hass.config_entries.flow.async_has_matching_flow(self): - raise AbortFlow("already_in_progress") + raise AbortFlow( + "already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN + ) @override def is_matching(self, other_flow: Self) -> bool: diff --git a/homeassistant/components/samsungtv/strings.json b/homeassistant/components/samsungtv/strings.json index 25bf032b1024..32474ad7fa1b 100644 --- a/homeassistant/components/samsungtv/strings.json +++ b/homeassistant/components/samsungtv/strings.json @@ -2,7 +2,6 @@ "config": { "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", - "already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]", "auth_missing": "Home Assistant is not authorized to connect to this Samsung TV. Check your TV's External Device Manager settings to authorize Home Assistant.", "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", "id_missing": "This Samsung device doesn't have a serial number to identify it.", diff --git a/homeassistant/components/steamist/config_flow.py b/homeassistant/components/steamist/config_flow.py index 49ec9b4c025a..9cf606774905 100644 --- a/homeassistant/components/steamist/config_flow.py +++ b/homeassistant/components/steamist/config_flow.py @@ -9,7 +9,7 @@ import probatio from homeassistant.config_entries import ConfigEntryState, ConfigFlow, ConfigFlowResult from homeassistant.const import CONF_DEVICE, CONF_HOST, CONF_MODEL, CONF_NAME -from homeassistant.core import callback +from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, callback from homeassistant.helpers import device_registry as dr from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo @@ -82,7 +82,9 @@ class SteamistConfigFlow(ConfigFlow, domain=DOMAIN): return self.async_abort(reason="already_configured") self.host = host if self.hass.config_entries.flow.async_has_matching_flow(self): - return self.async_abort(reason="already_in_progress") + return self.async_abort( + reason="already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN + ) if not device.name: discovery = await async_discover_device(self.hass, device.ipaddress) if not discovery: diff --git a/homeassistant/components/steamist/strings.json b/homeassistant/components/steamist/strings.json index 4a6317aa90b0..f5679986fbda 100644 --- a/homeassistant/components/steamist/strings.json +++ b/homeassistant/components/steamist/strings.json @@ -2,7 +2,6 @@ "config": { "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", - "already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]", "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", "no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]", "not_steamist_device": "Not a steamist device" diff --git a/homeassistant/components/tplink/config_flow.py b/homeassistant/components/tplink/config_flow.py index 03d9f0c2fac0..7e9180f16759 100644 --- a/homeassistant/components/tplink/config_flow.py +++ b/homeassistant/components/tplink/config_flow.py @@ -36,7 +36,7 @@ from homeassistant.const import ( CONF_PORT, CONF_USERNAME, ) -from homeassistant.core import callback +from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, callback from homeassistant.helpers import device_registry as dr from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo from homeassistant.helpers.typing import DiscoveryInfoType @@ -793,7 +793,10 @@ class TPLinkConfigFlow(ConfigFlow, domain=DOMAIN): self.hass.async_create_task( self._async_reload_requires_auth_entries(), eager_start=False ) - return self.async_abort(reason="reauth_successful") + return self.async_abort( + reason="reauth_successful", + translation_domain=HOMEASSISTANT_DOMAIN, + ) # Old config entries will not have these values. alias = entry_data.get(CONF_ALIAS) or "unknown" diff --git a/homeassistant/components/tplink/strings.json b/homeassistant/components/tplink/strings.json index b47a9bca2d83..5529161f49e7 100644 --- a/homeassistant/components/tplink/strings.json +++ b/homeassistant/components/tplink/strings.json @@ -3,8 +3,7 @@ "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", - "no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]", - "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]" + "no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]" }, "error": { "camera_creds": "You have to set both username and password", diff --git a/homeassistant/components/unifi/strings.json b/homeassistant/components/unifi/strings.json index 84b8a6dfe2d4..5dd9e6f59426 100644 --- a/homeassistant/components/unifi/strings.json +++ b/homeassistant/components/unifi/strings.json @@ -4,8 +4,6 @@ "already_configured": "UniFi Network site is already configured", "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", "configuration_updated": "Configuration updated", - "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]", - "reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]", "unknown_site_id": "Previously configured UniFi Network site can no longer be found" }, "error": { diff --git a/homeassistant/components/xiaomi_ble/config_flow.py b/homeassistant/components/xiaomi_ble/config_flow.py index 352bc00662b5..12744b972a5e 100644 --- a/homeassistant/components/xiaomi_ble/config_flow.py +++ b/homeassistant/components/xiaomi_ble/config_flow.py @@ -23,6 +23,7 @@ from homeassistant.components.bluetooth import ( ) from homeassistant.config_entries import SOURCE_REAUTH, ConfigFlow, ConfigFlowResult from homeassistant.const import CONF_ADDRESS, CONF_PASSWORD, CONF_USERNAME +from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN from homeassistant.data_entry_flow import AbortFlow from homeassistant.helpers.aiohttp_client import async_get_clientsession @@ -354,7 +355,9 @@ class XiaomiConfigFlow(ConfigFlow, domain=DOMAIN): return await self.async_step_get_encryption_key_4_5_choose_method() # Otherwise there wasn't actually encryption so abort - return self.async_abort(reason="reauth_successful") + return self.async_abort( + reason="reauth_successful", translation_domain=HOMEASSISTANT_DOMAIN + ) def _async_get_or_create_entry( self, bindkey: str | None = None diff --git a/homeassistant/components/xiaomi_ble/strings.json b/homeassistant/components/xiaomi_ble/strings.json index 6b18d34203c9..79a2098f7197 100644 --- a/homeassistant/components/xiaomi_ble/strings.json +++ b/homeassistant/components/xiaomi_ble/strings.json @@ -3,8 +3,7 @@ "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", "api_error": "Error while communicating with Mi API: {error_detail}", - "no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]", - "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]" + "no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]" }, "error": { "api_device_not_found": "The device was not found in your Mi account.", diff --git a/homeassistant/components/zwave_js/config_flow.py b/homeassistant/components/zwave_js/config_flow.py index 3c67c4a67f8d..52e43ef9516d 100644 --- a/homeassistant/components/zwave_js/config_flow.py +++ b/homeassistant/components/zwave_js/config_flow.py @@ -30,7 +30,7 @@ from homeassistant.config_entries import ( ConfigFlowResult, ) from homeassistant.const import CONF_NAME, CONF_URL -from homeassistant.core import HomeAssistant, callback +from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant, callback from homeassistant.data_entry_flow import AbortFlow from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import selector @@ -468,7 +468,10 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN): return await self.async_step_rf_region() if config_updates := self._addon_config_updates: if not self._async_acquire_addon_ownership(): - return self.async_abort(reason="already_in_progress") + return self.async_abort( + reason="already_in_progress", + translation_domain=HOMEASSISTANT_DOMAIN, + ) # If we have updates to the add-on config, # set them before starting the add-on. self._addon_config_updates = {} @@ -634,7 +637,9 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN): # at least for a short time. # Zeroconf flows never touch the add-on, # so an idle discovery prompt should not block USB discovery. - return self.async_abort(reason="already_in_progress") + return self.async_abort( + reason="already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN + ) if current_config_entries := self._async_current_entries(include_ignore=False): self._reconfigure_config_entry = next( ( @@ -785,7 +790,9 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN): # prompt should not block the add-on discovery. if flow["context"].get("source") != SOURCE_ZEROCONF ): - return self.async_abort(reason="already_in_progress") + return self.async_abort( + reason="already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN + ) if discovery_info.slug != ADDON_SLUG: return self.async_abort(reason="not_zwave_js_addon") @@ -1270,7 +1277,9 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN): ) if not self._async_acquire_addon_ownership(): - return self.async_abort(reason="already_in_progress") + return self.async_abort( + reason="already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN + ) # Remaining prompts, e.g. for other discovered adapters, # are superseded by this migration. @@ -1477,7 +1486,10 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN): } if not self._async_acquire_addon_ownership(): - return self.async_abort(reason="already_in_progress") + return self.async_abort( + reason="already_in_progress", + translation_domain=HOMEASSISTANT_DOMAIN, + ) addon_config_updates = self._addon_config_updates | addon_config_updates self._addon_config_updates = {} @@ -1719,7 +1731,10 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN): # Config entry already has correct config return self.async_abort(reason="already_configured") if not self._async_acquire_addon_ownership(): - return self.async_abort(reason="already_in_progress") + return self.async_abort( + reason="already_in_progress", + translation_domain=HOMEASSISTANT_DOMAIN, + ) await self._addon_setup.async_set_addon_config( {CONF_ADDON_SOCKET: discovery_info.socket_path} ) @@ -1741,7 +1756,10 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN): flow["context"].get("unique_id") == placeholder_unique_id for flow in self._async_in_progress() ): - return self.async_abort(reason="already_in_progress") + return self.async_abort( + reason="already_in_progress", + translation_domain=HOMEASSISTANT_DOMAIN, + ) # We are not aborting if home ID configured # here, we just want to make sure that it's set # We will update a USB based config entry diff --git a/homeassistant/components/zwave_js/strings.json b/homeassistant/components/zwave_js/strings.json index 4fd747641509..3356ac8288c7 100644 --- a/homeassistant/components/zwave_js/strings.json +++ b/homeassistant/components/zwave_js/strings.json @@ -104,7 +104,6 @@ "addon_start_failed": "Failed to start the Z-Wave JS app.", "addon_stop_failed": "Failed to stop the Z-Wave JS app.", "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", - "already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]", "backup_failed": "Failed to back up network.", "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", "config_entry_not_loaded": "The Z-Wave configuration entry is not loaded. Please try again when the configuration entry is loaded.", diff --git a/tests/components/conftest.py b/tests/components/conftest.py index 83ed632784ab..69507ce4a433 100644 --- a/tests/components/conftest.py +++ b/tests/components/conftest.py @@ -60,6 +60,7 @@ from homeassistant.components import repairs from homeassistant.config_entries import ( DISCOVERY_SOURCES, ConfigEntriesFlowManager, + ConfigSubentryFlowManager, FlowResult, OptionsFlowManager, ) @@ -1013,6 +1014,45 @@ async def _validate_translation( ) +async def _validate_abort_translation_not_duplicated( + hass: HomeAssistant, + translation_errors: dict[str, str], + ignore_translations_for_mock_domains: set[str], + category: str, + component: str, + translation_domain: str, + key: str, + *, + shared_category: str | None = None, + shared_key: str | None = None, +) -> None: + """Raise if an integration duplicates an abort translated by another domain. + + A local translation with different wording is kept, since the integration + may raise the same reason itself to show its own wording. + """ + if component in ignore_translations_for_mock_domains: + return + full_key = f"component.{component}.{category}.{key}" + translations = await async_get_translations(hass, "en", category, [component]) + if (translation := translations.get(full_key)) is None: + return + shared_category = shared_category or category + shared_translations = await async_get_translations( + hass, "en", shared_category, [translation_domain] + ) + if translation == shared_translations.get( + f"component.{translation_domain}.{shared_category}.{shared_key or key}" + ): + translation_errors[full_key] = ( + f"Translation `{category}.{key}` of {component} duplicates the one of " + f"{translation_domain}, which translates this abort. Please remove it " + f"from homeassistant/components/{component}/strings.json and pass " + f'translation_domain="{translation_domain}" wherever {component} ' + "raises this reason itself" + ) + + @pytest.fixture def ignore_missing_translations() -> str | list[str]: """Ignore specific missing translations. @@ -1147,6 +1187,27 @@ async def _check_config_flow_result_translations( **(issue.translation_placeholders or {}), **(description_placeholders or {}), } + elif isinstance(manager, ConfigSubentryFlowManager): + # Subentry flows are only checked for duplicated shared abort translations + if ( + result["type"] is FlowResultType.ABORT + and (abort_domain := result.get("translation_domain")) is not None + and (entry := flow.hass.config_entries.async_get_entry(flow.handler[0])) + and abort_domain != entry.domain + ): + # The frontend resolves a shared subentry abort from the config section + await _validate_abort_translation_not_duplicated( + flow.hass, + translation_errors, + ignore_translations_for_mock_domains, + "config_subentries", + entry.domain, + abort_domain, + f"{flow.handler[1]}.abort.{result['reason']}", + shared_category="config", + shared_key=f"abort.{result['reason']}", + ) + return else: return @@ -1181,11 +1242,22 @@ async def _check_config_flow_result_translations( return if result["type"] is FlowResultType.ABORT: + abort_domain = result.get("translation_domain") + if abort_domain is not None and abort_domain != integration: + await _validate_abort_translation_not_duplicated( + flow.hass, + translation_errors, + ignore_translations_for_mock_domains, + category, + integration, + abort_domain, + f"{key_prefix}abort.{result['reason']}", + ) # We don't need translations for a discovery flow which immediately # aborts, since such flows won't be seen by users if not flow.__flow_seen_before and flow.source in DISCOVERY_SOURCES: return - if (abort_domain := result.get("translation_domain")) is not None: + if abort_domain is not None: integration = abort_domain await _validate_translation( flow.hass, @@ -1330,6 +1402,8 @@ async def check_translations( Current checks: - data entry flow results (ConfigFlow/OptionsFlow/RepairFlow) + - data entry flow aborts translated by another domain are not duplicated locally + (also for ConfigSubentryFlow) - issue registry entries - action (service) exceptions """