mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Mark integrations as single_config_entry in manifest [k-r] (#128191)
* mark integrations as single_config_entry in manifest * fix owntracks test
This commit is contained in:
parent
c50d0646ab
commit
8236a9529f
@ -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(
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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": {
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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."
|
||||
}
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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": {
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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%]"
|
||||
}
|
||||
},
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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": {
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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."
|
||||
|
@ -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={})
|
||||
|
||||
|
@ -9,5 +9,6 @@
|
||||
"pyprof2calltree==1.4.5",
|
||||
"guppy3==3.1.4.post1",
|
||||
"objgraph==3.5.0"
|
||||
]
|
||||
],
|
||||
"single_config_entry": true
|
||||
}
|
||||
|
@ -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": {
|
||||
|
@ -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={})
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user