1 """Helpers for data entry flows for config entries."""
3 from __future__
import annotations
5 from collections.abc
import Awaitable, Callable
7 from typing
import TYPE_CHECKING, Any, cast
9 from homeassistant
import config_entries
13 from .typing
import DiscoveryInfoType
23 from .service_info.mqtt
import MqttServiceInfo
25 type DiscoveryFunctionType[_R] = Callable[[HomeAssistant], _R]
27 _LOGGER = logging.getLogger(__name__)
31 """Handle a discovery config flow."""
39 discovery_function: DiscoveryFunctionType[_R],
41 """Initialize the discovery config flow."""
44 self._discovery_function = discovery_function
47 self, user_input: dict[str, Any] |
None =
None
49 """Handle a flow initialized by the user."""
50 if self._async_current_entries():
51 return self.async_abort(reason=
"single_instance_allowed")
53 await self.async_set_unique_id(self._domain, raise_on_progress=
False)
55 return await self.async_step_confirm()
58 self, user_input: dict[str, Any] |
None =
None
61 if user_input
is None and onboarding.async_is_onboarded(self.hass):
62 self._set_confirm_only()
63 return self.async_show_form(step_id=
"confirm")
65 if self.source == config_entries.SOURCE_USER:
67 in_progress = self._async_in_progress()
69 if not (has_devices := bool(in_progress)):
70 has_devices = await cast(
71 "asyncio.Future[bool]", self._discovery_function(self.hass)
75 return self.async_abort(reason=
"no_devices_found")
78 for flow
in in_progress:
79 self.hass.config_entries.flow.async_abort(flow[
"flow_id"])
81 if self._async_current_entries():
82 return self.async_abort(reason=
"single_instance_allowed")
84 return self.async_create_entry(title=self._title, data={})
87 self, discovery_info: DiscoveryInfoType
89 """Handle a flow initialized by discovery."""
90 if self._async_in_progress()
or self._async_current_entries():
91 return self.async_abort(reason=
"single_instance_allowed")
93 await self.async_set_unique_id(self._domain)
95 return await self.async_step_confirm()
98 self, discovery_info: BluetoothServiceInfoBleak
100 """Handle a flow initialized by bluetooth discovery."""
101 if self._async_in_progress()
or self._async_current_entries():
102 return self.async_abort(reason=
"single_instance_allowed")
104 await self.async_set_unique_id(self._domain)
106 return await self.async_step_confirm()
109 self, discovery_info: DhcpServiceInfo
111 """Handle a flow initialized by dhcp discovery."""
112 if self._async_in_progress()
or self._async_current_entries():
113 return self.async_abort(reason=
"single_instance_allowed")
115 await self.async_set_unique_id(self._domain)
117 return await self.async_step_confirm()
120 self, discovery_info: ZeroconfServiceInfo
122 """Handle a flow initialized by Homekit discovery."""
123 if self._async_in_progress()
or self._async_current_entries():
124 return self.async_abort(reason=
"single_instance_allowed")
126 await self.async_set_unique_id(self._domain)
128 return await self.async_step_confirm()
131 self, discovery_info: MqttServiceInfo
133 """Handle a flow initialized by mqtt discovery."""
134 if self._async_in_progress()
or self._async_current_entries():
135 return self.async_abort(reason=
"single_instance_allowed")
137 await self.async_set_unique_id(self._domain)
139 return await self.async_step_confirm()
142 self, discovery_info: ZeroconfServiceInfo
144 """Handle a flow initialized by Zeroconf discovery."""
145 if self._async_in_progress()
or self._async_current_entries():
146 return self.async_abort(reason=
"single_instance_allowed")
148 await self.async_set_unique_id(self._domain)
150 return await self.async_step_confirm()
153 self, discovery_info: SsdpServiceInfo
155 """Handle a flow initialized by Ssdp discovery."""
156 if self._async_in_progress()
or self._async_current_entries():
157 return self.async_abort(reason=
"single_instance_allowed")
159 await self.async_set_unique_id(self._domain)
161 return await self.async_step_confirm()
164 self, _: dict[str, Any] |
None
166 """Handle a flow initialized by import."""
167 if self._async_current_entries():
168 return self.async_abort(reason=
"single_instance_allowed")
171 in_progress = self._async_in_progress()
172 for flow
in in_progress:
173 self.hass.config_entries.flow.async_abort(flow[
"flow_id"])
175 return self.async_create_entry(title=self._title, data={})
181 discovery_function: DiscoveryFunctionType[Awaitable[bool] | bool],
183 """Register flow for discovered integrations that not require auth."""
186 """Discovery flow handler."""
189 super().
__init__(domain, title, discovery_function)
191 config_entries.HANDLERS.register(domain)(DiscoveryFlow)
195 """Handle a webhook config flow."""
203 description_placeholder: dict,
204 allow_multiple: bool,
206 """Initialize the discovery config flow."""
213 self, user_input: dict[str, Any] |
None =
None
215 """Handle a user initiated set up flow to create a webhook."""
219 if user_input
is None:
225 async_active_subscription,
226 async_create_cloudhook,
255 data={
"webhook_id": webhook_id,
"cloudhook": cloudhook},
261 domain: str, title: str, description_placeholder: dict, allow_multiple: bool =
False
263 """Register flow for webhook integrations."""
266 """Webhook flow handler."""
269 super().
__init__(domain, title, description_placeholder, allow_multiple)
271 config_entries.HANDLERS.register(domain)(WebhookFlow)
277 """Remove a webhook config entry."""
278 if not entry.data.get(
"cloudhook")
or "cloud" not in hass.config.components:
ConfigFlowResult async_create_entry(self, *str title, Mapping[str, Any] data, str|None description=None, Mapping[str, str]|None description_placeholders=None, Mapping[str, Any]|None options=None)
list[ConfigEntry] _async_current_entries(self, bool|None include_ignore=None)
ConfigFlowResult async_abort(self, *str reason, Mapping[str, str]|None description_placeholders=None)
ConfigFlowResult async_show_form(self, *str|None step_id=None, vol.Schema|None data_schema=None, dict[str, str]|None errors=None, Mapping[str, str]|None description_placeholders=None, bool|None last_step=None, str|None preview=None)
_FlowResultT async_show_form(self, *str|None step_id=None, vol.Schema|None data_schema=None, dict[str, str]|None errors=None, Mapping[str, str]|None description_placeholders=None, bool|None last_step=None, str|None preview=None)
_FlowResultT async_create_entry(self, *str|None title=None, Mapping[str, Any] data, str|None description=None, Mapping[str, str]|None description_placeholders=None)
_FlowResultT async_abort(self, *str reason, Mapping[str, str]|None description_placeholders=None)
None __init__(self, str domain, str title, dict description_placeholder, bool allow_multiple)
config_entries.ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
None async_delete_cloudhook(HomeAssistant hass, str webhook_id)
str async_create_cloudhook(HomeAssistant hass, str webhook_id)
bool async_active_subscription(HomeAssistant hass)
bool async_is_connected(HomeAssistant hass)
str async_generate_url(HomeAssistant hass, str webhook_id, bool allow_internal=True, bool allow_external=True, bool|None allow_ip=None, bool|None prefer_external=True)
config_entries.ConfigFlowResult async_step_discovery(self, DiscoveryInfoType discovery_info)
config_entries.ConfigFlowResult async_step_confirm(self, dict[str, Any]|None user_input=None)
config_entries.ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
config_entries.ConfigFlowResult async_step_bluetooth(self, BluetoothServiceInfoBleak discovery_info)
config_entries.ConfigFlowResult async_step_import(self, dict[str, Any]|None _)
None webhook_async_remove_entry(HomeAssistant hass, config_entries.ConfigEntry entry)
None register_webhook_flow(str domain, str title, dict description_placeholder, bool allow_multiple=False)
config_entries.ConfigFlowResult async_step_ssdp(self, SsdpServiceInfo discovery_info)
None __init__(self, str domain, str title, DiscoveryFunctionType[_R] discovery_function)
config_entries.ConfigFlowResult async_step_mqtt(self, MqttServiceInfo discovery_info)
config_entries.ConfigFlowResult async_step_homekit(self, ZeroconfServiceInfo discovery_info)
config_entries.ConfigFlowResult async_step_dhcp(self, DhcpServiceInfo discovery_info)
None register_discovery_flow(str domain, str title, DiscoveryFunctionType[Awaitable[bool]|bool] discovery_function)
config_entries.ConfigFlowResult async_step_zeroconf(self, ZeroconfServiceInfo discovery_info)