mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 08:47:57 +00:00
Mark integrations as single_config_entry in manifest [a-i] (#128189)
* mark integrations as single_config_entry in manifest * fix ecobee tests * fix iaqualink test
This commit is contained in:
parent
1484a9c0ee
commit
c50d0646ab
@ -47,18 +47,12 @@ class FlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle a flow initialized by the user."""
|
||||
if self._async_current_entries():
|
||||
return self.async_abort(reason="single_instance_allowed")
|
||||
|
||||
return await self.async_step_config()
|
||||
|
||||
async def async_step_zeroconf(
|
||||
self, discovery_info: zeroconf.ZeroconfServiceInfo
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle a flow initialized by zeroconf discovery."""
|
||||
if self._async_in_progress() or self._async_current_entries():
|
||||
return self.async_abort(reason="single_instance_allowed")
|
||||
|
||||
await self.async_set_unique_id(DOMAIN)
|
||||
|
||||
return await self.async_step_confirm()
|
||||
|
@ -15,5 +15,6 @@
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["casttube", "pychromecast"],
|
||||
"requirements": ["PyChromecast==14.0.4"],
|
||||
"single_config_entry": true,
|
||||
"zeroconf": ["_googlecast._tcp.local."]
|
||||
}
|
||||
|
@ -12,9 +12,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
|
||||
},
|
||||
"error": {
|
||||
"invalid_known_hosts": "Known hosts must be a comma separated list of hosts."
|
||||
}
|
||||
|
@ -18,6 +18,4 @@ class CloudConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle the system step."""
|
||||
if self._async_current_entries():
|
||||
return self.async_abort(reason="single_instance_allowed")
|
||||
return self.async_create_entry(title="Home Assistant Cloud", data={})
|
||||
|
@ -8,5 +8,6 @@
|
||||
"integration_type": "system",
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["hass_nabucasa"],
|
||||
"requirements": ["hass-nabucasa==0.81.1"]
|
||||
"requirements": ["hass-nabucasa==0.81.1"],
|
||||
"single_config_entry": true
|
||||
}
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"config": {
|
||||
"step": {},
|
||||
"abort": {
|
||||
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
|
||||
}
|
||||
},
|
||||
"system_health": {
|
||||
"info": {
|
||||
"can_reach_cert_server": "Reach certificate server",
|
||||
|
@ -118,9 +118,6 @@ class CloudflareConfigFlow(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")
|
||||
|
||||
persistent_notification.async_dismiss(self.hass, "cloudflare_setup")
|
||||
|
||||
errors: dict[str, str] = {}
|
||||
|
@ -6,5 +6,6 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/cloudflare",
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["pycfdns"],
|
||||
"requirements": ["pycfdns==3.0.0"]
|
||||
"requirements": ["pycfdns==3.0.0"],
|
||||
"single_config_entry": true
|
||||
}
|
||||
|
@ -34,8 +34,7 @@
|
||||
"unknown": "[%key:common::config_flow::error::unknown%]"
|
||||
},
|
||||
"abort": {
|
||||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
|
||||
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
|
||||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
|
@ -39,9 +39,6 @@ class DemoConfigFlow(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="Demo", data=import_data)
|
||||
|
||||
|
||||
|
@ -5,5 +5,6 @@
|
||||
"dependencies": ["conversation", "group", "zone"],
|
||||
"documentation": "https://www.home-assistant.io/integrations/demo",
|
||||
"iot_class": "calculated",
|
||||
"quality_scale": "internal"
|
||||
"quality_scale": "internal",
|
||||
"single_config_entry": true
|
||||
}
|
||||
|
@ -34,9 +34,6 @@ class DuoTecnoConfigFlow(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")
|
||||
|
||||
errors: dict[str, str] = {}
|
||||
if user_input is not None:
|
||||
try:
|
||||
|
@ -7,5 +7,6 @@
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["pyduotecno", "pyduotecno-node", "pyduotecno-unit"],
|
||||
"quality_scale": "silver",
|
||||
"requirements": ["pyDuotecno==2024.10.0"]
|
||||
"requirements": ["pyDuotecno==2024.10.0"],
|
||||
"single_config_entry": true
|
||||
}
|
||||
|
@ -13,9 +13,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
|
||||
|
@ -29,10 +29,6 @@ class EcobeeFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle a flow initiated by the user."""
|
||||
if self._async_current_entries():
|
||||
# Config entry already exists, only one allowed.
|
||||
return self.async_abort(reason="single_instance_allowed")
|
||||
|
||||
errors = {}
|
||||
stored_api_key = (
|
||||
self.hass.data[DATA_ECOBEE_CONFIG].get(CONF_API_KEY)
|
||||
|
@ -10,6 +10,7 @@
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["pyecobee"],
|
||||
"requirements": ["python-ecobee-api==0.2.20"],
|
||||
"single_config_entry": true,
|
||||
"zeroconf": [
|
||||
{
|
||||
"type": "_ecobee._tcp.local."
|
||||
|
@ -38,9 +38,6 @@ class EnOceanFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle an EnOcean config flow start."""
|
||||
if self._async_current_entries():
|
||||
return self.async_abort(reason="single_instance_allowed")
|
||||
|
||||
return await self.async_step_detect()
|
||||
|
||||
async def async_step_detect(
|
||||
|
@ -6,5 +6,6 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/enocean",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["enocean"],
|
||||
"requirements": ["enocean==0.50"]
|
||||
"requirements": ["enocean==0.50"],
|
||||
"single_config_entry": true
|
||||
}
|
||||
|
@ -18,8 +18,7 @@
|
||||
"invalid_dongle_path": "No valid dongle found for this path"
|
||||
},
|
||||
"abort": {
|
||||
"invalid_dongle_path": "Invalid dongle path",
|
||||
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
|
||||
"invalid_dongle_path": "Invalid dongle path"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,11 +27,6 @@ class AqualinkFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle a flow start."""
|
||||
# Supporting a single account.
|
||||
entries = self._async_current_entries()
|
||||
if 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/iaqualink",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["iaqualink"],
|
||||
"requirements": ["iaqualink==0.5.0", "h2==4.1.0"]
|
||||
"requirements": ["iaqualink==0.5.0", "h2==4.1.0"],
|
||||
"single_config_entry": true
|
||||
}
|
||||
|
@ -13,9 +13,6 @@
|
||||
"error": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]"
|
||||
},
|
||||
"abort": {
|
||||
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,9 +30,6 @@ class IBeaconConfigFlow(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 not bluetooth.async_scanner_count(self.hass, connectable=False):
|
||||
return self.async_abort(reason="bluetooth_not_available")
|
||||
|
||||
|
@ -13,5 +13,6 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/ibeacon",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["bleak"],
|
||||
"requirements": ["ibeacon-ble==1.2.0"]
|
||||
"requirements": ["ibeacon-ble==1.2.0"],
|
||||
"single_config_entry": true
|
||||
}
|
||||
|
@ -6,8 +6,7 @@
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
"bluetooth_not_available": "At least one Bluetooth adapter or remote must be configured to use iBeacon Tracker.",
|
||||
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
|
||||
"bluetooth_not_available": "At least one Bluetooth adapter or remote must be configured to use iBeacon Tracker."
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
|
@ -59,8 +59,6 @@ class InsteonFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Init the config flow."""
|
||||
if self._async_current_entries():
|
||||
return self.async_abort(reason="single_instance_allowed")
|
||||
modem_types = [STEP_PLM, STEP_HUB_V1, STEP_HUB_V2]
|
||||
return self.async_show_menu(step_id="user", menu_options=modem_types)
|
||||
|
||||
@ -135,9 +133,6 @@ class InsteonFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
self, discovery_info: usb.UsbServiceInfo
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle USB discovery."""
|
||||
if self._async_current_entries():
|
||||
return self.async_abort(reason="single_instance_allowed")
|
||||
|
||||
self._device_path = discovery_info.device
|
||||
self._device_name = usb.human_readable_device_name(
|
||||
discovery_info.device,
|
||||
|
@ -20,6 +20,7 @@
|
||||
"pyinsteon==1.6.3",
|
||||
"insteon-frontend-home-assistant==0.5.0"
|
||||
],
|
||||
"single_config_entry": true,
|
||||
"usb": [
|
||||
{
|
||||
"vid": "10BF"
|
||||
|
@ -44,7 +44,6 @@
|
||||
},
|
||||
"abort": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]",
|
||||
"not_insteon_device": "Discovered device not an Insteon device"
|
||||
}
|
||||
},
|
||||
|
@ -29,10 +29,6 @@ class ISSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
|
||||
async def async_step_user(self, user_input=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=DEFAULT_NAME,
|
||||
|
@ -7,5 +7,6 @@
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["pyiss"],
|
||||
"requirements": ["pyiss==1.0.1"]
|
||||
"requirements": ["pyiss==1.0.1"],
|
||||
"single_config_entry": true
|
||||
}
|
||||
|
@ -6,7 +6,6 @@
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]",
|
||||
"latitude_longitude_not_defined": "Latitude and longitude are not defined in Home Assistant."
|
||||
}
|
||||
},
|
||||
|
@ -958,7 +958,8 @@
|
||||
"name": "Cloudflare",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "cloud_push"
|
||||
"iot_class": "cloud_push",
|
||||
"single_config_entry": true
|
||||
},
|
||||
"cmus": {
|
||||
"name": "cmus",
|
||||
@ -1160,7 +1161,8 @@
|
||||
"demo": {
|
||||
"integration_type": "hub",
|
||||
"config_flow": false,
|
||||
"iot_class": "calculated"
|
||||
"iot_class": "calculated",
|
||||
"single_config_entry": true
|
||||
},
|
||||
"denon": {
|
||||
"name": "Denon",
|
||||
@ -1403,7 +1405,8 @@
|
||||
"name": "Duotecno",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "local_push"
|
||||
"iot_class": "local_push",
|
||||
"single_config_entry": true
|
||||
},
|
||||
"duquesne_light": {
|
||||
"name": "Duquesne Light",
|
||||
@ -1461,7 +1464,8 @@
|
||||
"name": "ecobee",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "cloud_polling"
|
||||
"iot_class": "cloud_polling",
|
||||
"single_config_entry": true
|
||||
},
|
||||
"ecoforest": {
|
||||
"name": "Ecoforest",
|
||||
@ -1659,7 +1663,8 @@
|
||||
"name": "EnOcean",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "local_push"
|
||||
"iot_class": "local_push",
|
||||
"single_config_entry": true
|
||||
},
|
||||
"enphase_envoy": {
|
||||
"name": "Enphase Envoy",
|
||||
@ -2732,7 +2737,8 @@
|
||||
"name": "Jandy iAqualink",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "cloud_polling"
|
||||
"iot_class": "cloud_polling",
|
||||
"single_config_entry": true
|
||||
},
|
||||
"ibm": {
|
||||
"name": "IBM",
|
||||
@ -2861,7 +2867,8 @@
|
||||
"name": "Insteon",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "local_push"
|
||||
"iot_class": "local_push",
|
||||
"single_config_entry": true
|
||||
},
|
||||
"intellifire": {
|
||||
"name": "IntelliFire",
|
||||
@ -2960,7 +2967,8 @@
|
||||
"name": "International Space Station (ISS)",
|
||||
"integration_type": "service",
|
||||
"config_flow": true,
|
||||
"iot_class": "cloud_polling"
|
||||
"iot_class": "cloud_polling",
|
||||
"single_config_entry": true
|
||||
},
|
||||
"ista_ecotrend": {
|
||||
"name": "ista EcoTrend",
|
||||
|
@ -11,6 +11,7 @@ from homeassistant.components.ecobee.const import (
|
||||
DATA_ECOBEE_CONFIG,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_USER
|
||||
from homeassistant.const import CONF_API_KEY
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
@ -20,12 +21,11 @@ from tests.common import MockConfigEntry
|
||||
|
||||
async def test_abort_if_already_setup(hass: HomeAssistant) -> None:
|
||||
"""Test we abort if ecobee is already setup."""
|
||||
flow = config_flow.EcobeeFlowHandler()
|
||||
flow.hass = hass
|
||||
|
||||
MockConfigEntry(domain=DOMAIN).add_to_hass(hass)
|
||||
|
||||
result = await flow.async_step_user()
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "single_instance_allowed"
|
||||
|
@ -7,7 +7,8 @@ from iaqualink.exception import (
|
||||
AqualinkServiceUnauthorizedException,
|
||||
)
|
||||
|
||||
from homeassistant.components.iaqualink import config_flow
|
||||
from homeassistant.components.iaqualink import DOMAIN, config_flow
|
||||
from homeassistant.config_entries import SOURCE_USER
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
|
||||
@ -18,13 +19,12 @@ async def test_already_configured(
|
||||
"""Test config flow when iaqualink component is already setup."""
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
flow = config_flow.AqualinkFlowHandler()
|
||||
flow.hass = hass
|
||||
flow.context = {}
|
||||
|
||||
result = await flow.async_step_user(config_data)
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "single_instance_allowed"
|
||||
|
||||
|
||||
async def test_without_config(hass: HomeAssistant) -> None:
|
||||
|
Loading…
x
Reference in New Issue
Block a user