From 8236a9529f3db4ab2988346eff0858e02d8b1c1f Mon Sep 17 00:00:00 2001 From: Michael <35783820+mib1185@users.noreply.github.com> Date: Sat, 12 Oct 2024 09:03:17 +0200 Subject: [PATCH] Mark integrations as single_config_entry in manifest [k-r] (#128191) * mark integrations as single_config_entry in manifest * fix owntracks test --- .../components/kitchen_sink/config_flow.py | 3 -- .../components/kitchen_sink/manifest.json | 3 +- .../components/launch_library/config_flow.py | 4 --- .../components/launch_library/manifest.json | 3 +- .../components/launch_library/strings.json | 3 -- .../components/litejet/config_flow.py | 3 -- .../components/litejet/manifest.json | 3 +- homeassistant/components/litejet/strings.json | 3 -- .../components/local_ip/config_flow.py | 3 -- .../components/local_ip/manifest.json | 3 +- .../components/local_ip/strings.json | 3 -- .../components/lutron/config_flow.py | 5 ---- homeassistant/components/lutron/manifest.json | 3 +- homeassistant/components/lutron/strings.json | 3 -- .../components/nzbget/config_flow.py | 3 -- homeassistant/components/nzbget/manifest.json | 3 +- homeassistant/components/nzbget/strings.json | 1 - .../components/omnilogic/config_flow.py | 6 ---- .../components/omnilogic/manifest.json | 3 +- .../components/omnilogic/strings.json | 3 +- .../components/ondilo_ico/config_flow.py | 3 -- .../components/ondilo_ico/manifest.json | 3 +- .../components/owntracks/config_flow.py | 3 -- .../components/owntracks/manifest.json | 3 +- .../components/owntracks/strings.json | 3 +- .../components/profiler/config_flow.py | 3 -- .../components/profiler/manifest.json | 3 +- .../components/profiler/strings.json | 3 -- .../components/radio_browser/config_flow.py | 3 -- .../components/radio_browser/manifest.json | 3 +- .../components/radio_browser/strings.json | 3 -- homeassistant/generated/integrations.json | 30 ++++++++++++------- .../components/owntracks/test_config_flow.py | 7 +++-- 33 files changed, 48 insertions(+), 86 deletions(-) diff --git a/homeassistant/components/kitchen_sink/config_flow.py b/homeassistant/components/kitchen_sink/config_flow.py index 8cff9321729..986879e3058 100644 --- a/homeassistant/components/kitchen_sink/config_flow.py +++ b/homeassistant/components/kitchen_sink/config_flow.py @@ -37,9 +37,6 @@ class KitchenSinkConfigFlow(ConfigFlow, domain=DOMAIN): async def async_step_import(self, import_data: dict[str, Any]) -> ConfigFlowResult: """Set the config entry up from yaml.""" - if self._async_current_entries(): - return self.async_abort(reason="single_instance_allowed") - return self.async_create_entry(title="Kitchen Sink", data=import_data) async def async_step_reauth( diff --git a/homeassistant/components/kitchen_sink/manifest.json b/homeassistant/components/kitchen_sink/manifest.json index e2f9468f7e0..ae2462afbbd 100644 --- a/homeassistant/components/kitchen_sink/manifest.json +++ b/homeassistant/components/kitchen_sink/manifest.json @@ -5,5 +5,6 @@ "codeowners": ["@home-assistant/core"], "documentation": "https://www.home-assistant.io/integrations/kitchen_sink", "iot_class": "calculated", - "quality_scale": "internal" + "quality_scale": "internal", + "single_config_entry": true } diff --git a/homeassistant/components/launch_library/config_flow.py b/homeassistant/components/launch_library/config_flow.py index 3cdff3650b3..37b80fbff8a 100644 --- a/homeassistant/components/launch_library/config_flow.py +++ b/homeassistant/components/launch_library/config_flow.py @@ -18,10 +18,6 @@ class LaunchLibraryFlowHandler(ConfigFlow, domain=DOMAIN): self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Handle a flow initialized by the user.""" - # Check if already configured - if self._async_current_entries(): - return self.async_abort(reason="single_instance_allowed") - if user_input is not None: return self.async_create_entry(title="Launch Library", data=user_input) diff --git a/homeassistant/components/launch_library/manifest.json b/homeassistant/components/launch_library/manifest.json index 00f11f95a44..3258a9a34fb 100644 --- a/homeassistant/components/launch_library/manifest.json +++ b/homeassistant/components/launch_library/manifest.json @@ -6,5 +6,6 @@ "documentation": "https://www.home-assistant.io/integrations/launch_library", "integration_type": "service", "iot_class": "cloud_polling", - "requirements": ["pylaunches==2.0.0"] + "requirements": ["pylaunches==2.0.0"], + "single_config_entry": true } diff --git a/homeassistant/components/launch_library/strings.json b/homeassistant/components/launch_library/strings.json index f3cca9fc581..a587544f836 100644 --- a/homeassistant/components/launch_library/strings.json +++ b/homeassistant/components/launch_library/strings.json @@ -4,9 +4,6 @@ "user": { "description": "Do you want to configure the Launch Library?" } - }, - "abort": { - "single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]" } }, "entity": { diff --git a/homeassistant/components/litejet/config_flow.py b/homeassistant/components/litejet/config_flow.py index 19ddf0122c4..b9f8a0f4b66 100644 --- a/homeassistant/components/litejet/config_flow.py +++ b/homeassistant/components/litejet/config_flow.py @@ -57,9 +57,6 @@ class LiteJetConfigFlow(ConfigFlow, domain=DOMAIN): self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Create a LiteJet config entry based upon user input.""" - if self._async_current_entries(): - return self.async_abort(reason="single_instance_allowed") - errors = {} if user_input is not None: port = user_input[CONF_PORT] diff --git a/homeassistant/components/litejet/manifest.json b/homeassistant/components/litejet/manifest.json index 3cff83707f5..1df907029a9 100644 --- a/homeassistant/components/litejet/manifest.json +++ b/homeassistant/components/litejet/manifest.json @@ -8,5 +8,6 @@ "iot_class": "local_push", "loggers": ["pylitejet"], "quality_scale": "platinum", - "requirements": ["pylitejet==0.6.3"] + "requirements": ["pylitejet==0.6.3"], + "single_config_entry": true } diff --git a/homeassistant/components/litejet/strings.json b/homeassistant/components/litejet/strings.json index 398f1a1e5aa..c55df54c931 100644 --- a/homeassistant/components/litejet/strings.json +++ b/homeassistant/components/litejet/strings.json @@ -9,9 +9,6 @@ } } }, - "abort": { - "single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]" - }, "error": { "open_failed": "Cannot open the specified serial port." } diff --git a/homeassistant/components/local_ip/config_flow.py b/homeassistant/components/local_ip/config_flow.py index 3a4612d84aa..6bf9f865489 100644 --- a/homeassistant/components/local_ip/config_flow.py +++ b/homeassistant/components/local_ip/config_flow.py @@ -16,9 +16,6 @@ class SimpleConfigFlow(ConfigFlow, domain=DOMAIN): self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Handle the initial step.""" - if self._async_current_entries(): - return self.async_abort(reason="single_instance_allowed") - if user_input is None: return self.async_show_form(step_id="user") diff --git a/homeassistant/components/local_ip/manifest.json b/homeassistant/components/local_ip/manifest.json index 11d86ea0230..6a68ed59628 100644 --- a/homeassistant/components/local_ip/manifest.json +++ b/homeassistant/components/local_ip/manifest.json @@ -5,5 +5,6 @@ "config_flow": true, "dependencies": ["network"], "documentation": "https://www.home-assistant.io/integrations/local_ip", - "iot_class": "local_polling" + "iot_class": "local_polling", + "single_config_entry": true } diff --git a/homeassistant/components/local_ip/strings.json b/homeassistant/components/local_ip/strings.json index a4d9138d88e..7f7508aa9b3 100644 --- a/homeassistant/components/local_ip/strings.json +++ b/homeassistant/components/local_ip/strings.json @@ -6,9 +6,6 @@ "title": "[%key:component::local_ip::title%]", "description": "[%key:common::config_flow::description::confirm_setup%]" } - }, - "abort": { - "single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]" } } } diff --git a/homeassistant/components/lutron/config_flow.py b/homeassistant/components/lutron/config_flow.py index e14d56fde57..6a48e0d4b67 100644 --- a/homeassistant/components/lutron/config_flow.py +++ b/homeassistant/components/lutron/config_flow.py @@ -26,11 +26,6 @@ class LutronConfigFlow(ConfigFlow, domain=DOMAIN): self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """First step in the config flow.""" - - # Check if a configuration entry already exists - if self._async_current_entries(): - return self.async_abort(reason="single_instance_allowed") - errors = {} if user_input is not None: diff --git a/homeassistant/components/lutron/manifest.json b/homeassistant/components/lutron/manifest.json index d9432f77bba..5dbf3c45f2a 100644 --- a/homeassistant/components/lutron/manifest.json +++ b/homeassistant/components/lutron/manifest.json @@ -6,5 +6,6 @@ "documentation": "https://www.home-assistant.io/integrations/lutron", "iot_class": "local_polling", "loggers": ["pylutron"], - "requirements": ["pylutron==0.2.15"] + "requirements": ["pylutron==0.2.15"], + "single_config_entry": true } diff --git a/homeassistant/components/lutron/strings.json b/homeassistant/components/lutron/strings.json index 770a453eb9e..b73e0bd15ed 100644 --- a/homeassistant/components/lutron/strings.json +++ b/homeassistant/components/lutron/strings.json @@ -17,9 +17,6 @@ "description": "Please enter the main repeater login information", "title": "Main repeater setup" } - }, - "abort": { - "single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]" } }, "entity": { diff --git a/homeassistant/components/nzbget/config_flow.py b/homeassistant/components/nzbget/config_flow.py index 47d35f32f9f..a99d3d3f328 100644 --- a/homeassistant/components/nzbget/config_flow.py +++ b/homeassistant/components/nzbget/config_flow.py @@ -50,9 +50,6 @@ class NZBGetConfigFlow(ConfigFlow, domain=DOMAIN): self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Handle a flow initiated by the user.""" - if self._async_current_entries(): - return self.async_abort(reason="single_instance_allowed") - errors = {} if user_input is not None: diff --git a/homeassistant/components/nzbget/manifest.json b/homeassistant/components/nzbget/manifest.json index 34f6f37873b..60e90e372ff 100644 --- a/homeassistant/components/nzbget/manifest.json +++ b/homeassistant/components/nzbget/manifest.json @@ -6,5 +6,6 @@ "documentation": "https://www.home-assistant.io/integrations/nzbget", "iot_class": "local_polling", "loggers": ["pynzbgetapi"], - "requirements": ["pynzbgetapi==0.2.0"] + "requirements": ["pynzbgetapi==0.2.0"], + "single_config_entry": true } diff --git a/homeassistant/components/nzbget/strings.json b/homeassistant/components/nzbget/strings.json index 4da9a0b505e..84a2ed0b821 100644 --- a/homeassistant/components/nzbget/strings.json +++ b/homeassistant/components/nzbget/strings.json @@ -19,7 +19,6 @@ "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]" }, "abort": { - "single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]", "unknown": "[%key:common::config_flow::error::unknown%]" } }, diff --git a/homeassistant/components/omnilogic/config_flow.py b/homeassistant/components/omnilogic/config_flow.py index 77bca0039a9..489c8e6f601 100644 --- a/homeassistant/components/omnilogic/config_flow.py +++ b/homeassistant/components/omnilogic/config_flow.py @@ -42,12 +42,6 @@ class OmniLogicConfigFlow(ConfigFlow, domain=DOMAIN): """Handle the initial step.""" errors: dict[str, str] = {} - config_entry = self._async_current_entries() - if config_entry: - return self.async_abort(reason="single_instance_allowed") - - errors = {} - if user_input is not None: username = user_input[CONF_USERNAME] password = user_input[CONF_PASSWORD] diff --git a/homeassistant/components/omnilogic/manifest.json b/homeassistant/components/omnilogic/manifest.json index 252718d2c21..361a15e2d9c 100644 --- a/homeassistant/components/omnilogic/manifest.json +++ b/homeassistant/components/omnilogic/manifest.json @@ -6,5 +6,6 @@ "documentation": "https://www.home-assistant.io/integrations/omnilogic", "iot_class": "cloud_polling", "loggers": ["config", "omnilogic"], - "requirements": ["omnilogic==0.4.5"] + "requirements": ["omnilogic==0.4.5"], + "single_config_entry": true } diff --git a/homeassistant/components/omnilogic/strings.json b/homeassistant/components/omnilogic/strings.json index 454644be244..5b193b7f5ba 100644 --- a/homeassistant/components/omnilogic/strings.json +++ b/homeassistant/components/omnilogic/strings.json @@ -14,8 +14,7 @@ "unknown": "[%key:common::config_flow::error::unknown%]" }, "abort": { - "already_configured": "[%key:common::config_flow::abort::already_configured_account%]", - "single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]" + "already_configured": "[%key:common::config_flow::abort::already_configured_account%]" } }, "options": { diff --git a/homeassistant/components/ondilo_ico/config_flow.py b/homeassistant/components/ondilo_ico/config_flow.py index d65c1b15e2a..fe0b89e7258 100644 --- a/homeassistant/components/ondilo_ico/config_flow.py +++ b/homeassistant/components/ondilo_ico/config_flow.py @@ -21,9 +21,6 @@ class OndiloIcoOAuth2FlowHandler(AbstractOAuth2FlowHandler, domain=DOMAIN): """Handle a flow initialized by the user.""" await self.async_set_unique_id(DOMAIN) - if self._async_current_entries(): - return self.async_abort(reason="single_instance_allowed") - self.async_register_implementation( self.hass, OndiloOauth2Implementation(self.hass), diff --git a/homeassistant/components/ondilo_ico/manifest.json b/homeassistant/components/ondilo_ico/manifest.json index 2f522f1b77c..84862a89fbb 100644 --- a/homeassistant/components/ondilo_ico/manifest.json +++ b/homeassistant/components/ondilo_ico/manifest.json @@ -8,5 +8,6 @@ "integration_type": "hub", "iot_class": "cloud_polling", "loggers": ["ondilo"], - "requirements": ["ondilo==0.5.0"] + "requirements": ["ondilo==0.5.0"], + "single_config_entry": true } diff --git a/homeassistant/components/owntracks/config_flow.py b/homeassistant/components/owntracks/config_flow.py index 390cc880c1e..b92f5d7ce06 100644 --- a/homeassistant/components/owntracks/config_flow.py +++ b/homeassistant/components/owntracks/config_flow.py @@ -23,9 +23,6 @@ class OwnTracksFlow(ConfigFlow, domain=DOMAIN): self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Handle a user initiated set up flow to create OwnTracks webhook.""" - if self._async_current_entries(): - return self.async_abort(reason="single_instance_allowed") - if user_input is None: return self.async_show_form(step_id="user") diff --git a/homeassistant/components/owntracks/manifest.json b/homeassistant/components/owntracks/manifest.json index 79af00627a4..7ff5a143451 100644 --- a/homeassistant/components/owntracks/manifest.json +++ b/homeassistant/components/owntracks/manifest.json @@ -8,5 +8,6 @@ "documentation": "https://www.home-assistant.io/integrations/owntracks", "iot_class": "local_push", "loggers": ["nacl"], - "requirements": ["PyNaCl==1.5.0"] + "requirements": ["PyNaCl==1.5.0"], + "single_config_entry": true } diff --git a/homeassistant/components/owntracks/strings.json b/homeassistant/components/owntracks/strings.json index 8fdd771b95e..3c08550dab7 100644 --- a/homeassistant/components/owntracks/strings.json +++ b/homeassistant/components/owntracks/strings.json @@ -7,8 +7,7 @@ } }, "abort": { - "cloud_not_connected": "[%key:common::config_flow::abort::cloud_not_connected%]", - "single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]" + "cloud_not_connected": "[%key:common::config_flow::abort::cloud_not_connected%]" }, "create_entry": { "default": "On Android, open [the OwnTracks app]({android_url}), go to Preferences > Connection. Change the following settings:\n - Mode: HTTP\n - Host: {webhook_url}\n - Identification:\n - Username: `'(Your name)'`\n - Device ID: `'(Your device name)'`\n\nOn iOS, open [the OwnTracks app]({ios_url}), tap (i) icon in top left > Settings. Change the following settings:\n - Mode: HTTP\n - URL: {webhook_url}\n - Turn on authentication\n - UserID: `'(Your name)'`\n\n{secret}\n\nSee [the documentation]({docs_url}) for more information." diff --git a/homeassistant/components/profiler/config_flow.py b/homeassistant/components/profiler/config_flow.py index 19995cf79aa..766d847e4a4 100644 --- a/homeassistant/components/profiler/config_flow.py +++ b/homeassistant/components/profiler/config_flow.py @@ -16,9 +16,6 @@ class ProfilerConfigFlow(ConfigFlow, domain=DOMAIN): self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Handle the initial step.""" - if self._async_current_entries(): - return self.async_abort(reason="single_instance_allowed") - if user_input is not None: return self.async_create_entry(title=DEFAULT_NAME, data={}) diff --git a/homeassistant/components/profiler/manifest.json b/homeassistant/components/profiler/manifest.json index ceaab458e69..9f27ee7f7d0 100644 --- a/homeassistant/components/profiler/manifest.json +++ b/homeassistant/components/profiler/manifest.json @@ -9,5 +9,6 @@ "pyprof2calltree==1.4.5", "guppy3==3.1.4.post1", "objgraph==3.5.0" - ] + ], + "single_config_entry": true } diff --git a/homeassistant/components/profiler/strings.json b/homeassistant/components/profiler/strings.json index 7a31c567040..f363b5a22cb 100644 --- a/homeassistant/components/profiler/strings.json +++ b/homeassistant/components/profiler/strings.json @@ -4,9 +4,6 @@ "user": { "description": "[%key:common::config_flow::description::confirm_setup%]" } - }, - "abort": { - "single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]" } }, "services": { diff --git a/homeassistant/components/radio_browser/config_flow.py b/homeassistant/components/radio_browser/config_flow.py index 137ee7c8e87..411259f31d3 100644 --- a/homeassistant/components/radio_browser/config_flow.py +++ b/homeassistant/components/radio_browser/config_flow.py @@ -18,9 +18,6 @@ class RadioBrowserConfigFlow(ConfigFlow, domain=DOMAIN): self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Handle the initial step.""" - if self._async_current_entries(): - return self.async_abort(reason="single_instance_allowed") - if user_input is not None: return self.async_create_entry(title="Radio Browser", data={}) diff --git a/homeassistant/components/radio_browser/manifest.json b/homeassistant/components/radio_browser/manifest.json index 5a52d29d27a..f29aa1fac1d 100644 --- a/homeassistant/components/radio_browser/manifest.json +++ b/homeassistant/components/radio_browser/manifest.json @@ -6,5 +6,6 @@ "documentation": "https://www.home-assistant.io/integrations/radio_browser", "integration_type": "service", "iot_class": "cloud_polling", - "requirements": ["radios==0.3.1", "pycountry==23.12.11"] + "requirements": ["radios==0.3.1", "pycountry==23.12.11"], + "single_config_entry": true } diff --git a/homeassistant/components/radio_browser/strings.json b/homeassistant/components/radio_browser/strings.json index fd0470d26dc..5dd0ad3dcf7 100644 --- a/homeassistant/components/radio_browser/strings.json +++ b/homeassistant/components/radio_browser/strings.json @@ -4,9 +4,6 @@ "user": { "description": "Do you want to add Radio Browser to Home Assistant?" } - }, - "abort": { - "single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]" } } } diff --git a/homeassistant/generated/integrations.json b/homeassistant/generated/integrations.json index d63322f99d5..9c1c46a7112 100644 --- a/homeassistant/generated/integrations.json +++ b/homeassistant/generated/integrations.json @@ -3107,7 +3107,8 @@ "name": "Everything but the Kitchen Sink", "integration_type": "hub", "config_flow": false, - "iot_class": "calculated" + "iot_class": "calculated", + "single_config_entry": true }, "kiwi": { "name": "KIWI", @@ -3221,7 +3222,8 @@ "name": "Launch Library", "integration_type": "service", "config_flow": true, - "iot_class": "cloud_polling" + "iot_class": "cloud_polling", + "single_config_entry": true }, "laundrify": { "name": "laundrify", @@ -3363,7 +3365,8 @@ "name": "LiteJet", "integration_type": "hub", "config_flow": true, - "iot_class": "local_push" + "iot_class": "local_push", + "single_config_entry": true }, "litterrobot": { "name": "Litter-Robot", @@ -3397,7 +3400,8 @@ "local_ip": { "integration_type": "hub", "config_flow": true, - "iot_class": "local_polling" + "iot_class": "local_polling", + "single_config_entry": true }, "local_todo": { "integration_type": "hub", @@ -4248,7 +4252,8 @@ "name": "NZBGet", "integration_type": "hub", "config_flow": true, - "iot_class": "local_polling" + "iot_class": "local_polling", + "single_config_entry": true }, "oasa_telematics": { "name": "OASA Telematics", @@ -4296,7 +4301,8 @@ "name": "Hayward Omnilogic", "integration_type": "hub", "config_flow": true, - "iot_class": "cloud_polling" + "iot_class": "cloud_polling", + "single_config_entry": true }, "oncue": { "name": "Oncue by Kohler", @@ -4308,7 +4314,8 @@ "name": "Ondilo ICO", "integration_type": "hub", "config_flow": true, - "iot_class": "cloud_polling" + "iot_class": "cloud_polling", + "single_config_entry": true }, "onewire": { "name": "1-Wire", @@ -4516,7 +4523,8 @@ "name": "OwnTracks", "integration_type": "hub", "config_flow": true, - "iot_class": "local_push" + "iot_class": "local_push", + "single_config_entry": true }, "p1_monitor": { "name": "P1 Monitor", @@ -4731,7 +4739,8 @@ "profiler": { "name": "Profiler", "integration_type": "hub", - "config_flow": true + "config_flow": true, + "single_config_entry": true }, "progettihwsw": { "name": "ProgettiHWSW Automation", @@ -4946,7 +4955,8 @@ "name": "Radio Browser", "integration_type": "service", "config_flow": true, - "iot_class": "cloud_polling" + "iot_class": "cloud_polling", + "single_config_entry": true }, "radiotherm": { "name": "Radio Thermostat", diff --git a/tests/components/owntracks/test_config_flow.py b/tests/components/owntracks/test_config_flow.py index b1172eb4a31..cbe51126eea 100644 --- a/tests/components/owntracks/test_config_flow.py +++ b/tests/components/owntracks/test_config_flow.py @@ -94,13 +94,14 @@ async def test_import_setup(hass: HomeAssistant) -> None: async def test_abort_if_already_setup(hass: HomeAssistant) -> None: """Test that we can't add more than one instance.""" - flow = await init_config_flow(hass) - MockConfigEntry(domain=DOMAIN, data={}).add_to_hass(hass) assert hass.config_entries.async_entries(DOMAIN) + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": config_entries.SOURCE_USER} + ) + # Should fail, already setup (flow) - result = await flow.async_step_user({}) assert result["type"] is FlowResultType.ABORT assert result["reason"] == "single_instance_allowed"