Home Assistant Unofficial Reference 2024.12.1
config_flow.py
Go to the documentation of this file.
1 """Config flow for ROMY integration."""
2 
3 from __future__ import annotations
4 
5 import romy
6 import voluptuous as vol
7 
8 from homeassistant.components import zeroconf
9 from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
10 from homeassistant.const import CONF_HOST, CONF_PASSWORD
12 
13 from .const import DOMAIN, LOGGER
14 
15 
16 class RomyConfigFlow(ConfigFlow, domain=DOMAIN):
17  """Handle config flow for ROMY."""
18 
19  VERSION = 1
20 
21  def __init__(self) -> None:
22  """Handle a config flow for ROMY."""
23  self.hosthost: str = ""
24  self.passwordpassword: str = ""
25  self.robot_name_given_by_userrobot_name_given_by_user: str = ""
26 
27  async def async_step_user(
28  self, user_input: dict[str, str] | None = None
29  ) -> ConfigFlowResult:
30  """Handle the user step."""
31  errors: dict[str, str] = {}
32 
33  if user_input:
34  self.hosthost = user_input[CONF_HOST]
35 
36  new_romy = await romy.create_romy(self.hosthost, "")
37 
38  if not new_romy.is_initialized:
39  errors[CONF_HOST] = "cannot_connect"
40  else:
41  await self.async_set_unique_idasync_set_unique_id(new_romy.unique_id)
42  self._abort_if_unique_id_configured_abort_if_unique_id_configured()
43 
44  self.robot_name_given_by_userrobot_name_given_by_user = new_romy.user_name
45 
46  if not new_romy.is_unlocked:
47  return await self.async_step_passwordasync_step_password()
48  return await self._async_step_finish_config_async_step_finish_config()
49 
50  return self.async_show_formasync_show_formasync_show_form(
51  step_id="user",
52  data_schema=vol.Schema(
53  {
54  vol.Required(CONF_HOST): cv.string,
55  },
56  ),
57  errors=errors,
58  )
59 
61  self, user_input: dict[str, str] | None = None
62  ) -> ConfigFlowResult:
63  """Unlock the robots local http interface with password."""
64  errors: dict[str, str] = {}
65 
66  if user_input:
67  self.passwordpassword = user_input[CONF_PASSWORD]
68  new_romy = await romy.create_romy(self.hosthost, self.passwordpassword)
69 
70  if not new_romy.is_initialized:
71  errors[CONF_PASSWORD] = "cannot_connect"
72  elif not new_romy.is_unlocked:
73  errors[CONF_PASSWORD] = "invalid_auth"
74 
75  if not errors:
76  return await self._async_step_finish_config_async_step_finish_config()
77 
78  return self.async_show_formasync_show_formasync_show_form(
79  step_id="password",
80  data_schema=vol.Schema(
81  {vol.Required(CONF_PASSWORD): vol.All(cv.string, vol.Length(8))},
82  ),
83  errors=errors,
84  )
85 
87  self, discovery_info: zeroconf.ZeroconfServiceInfo
88  ) -> ConfigFlowResult:
89  """Handle zeroconf discovery."""
90 
91  LOGGER.debug("Zeroconf discovery_info: %s", discovery_info)
92 
93  # connect and gather information from your ROMY
94  self.hosthost = discovery_info.host
95  LOGGER.debug("ZeroConf Host: %s", self.hosthost)
96 
97  new_discovered_romy = await romy.create_romy(self.hosthost, "")
98 
99  self.robot_name_given_by_userrobot_name_given_by_user = new_discovered_romy.user_name
100  LOGGER.debug("ZeroConf Name: %s", self.robot_name_given_by_userrobot_name_given_by_user)
101 
102  # get unique id and stop discovery if robot is already added
103  unique_id = new_discovered_romy.unique_id
104  LOGGER.debug("ZeroConf Unique_id: %s", unique_id)
105  await self.async_set_unique_idasync_set_unique_id(unique_id)
106  self._abort_if_unique_id_configured_abort_if_unique_id_configured(updates={CONF_HOST: discovery_info.host})
107 
108  self.context.update(
109  {
110  "title_placeholders": {
111  "name": f"{self.robot_name_given_by_user} ({self.host} / {unique_id})"
112  },
113  "configuration_url": f"http://{self.host}:{new_discovered_romy.port}",
114  }
115  )
116 
117  # if robot got already unlocked with password add it directly
118  if not new_discovered_romy.is_initialized:
119  return self.async_abortasync_abortasync_abort(reason="cannot_connect")
120 
121  if new_discovered_romy.is_unlocked:
122  return await self.async_step_zeroconf_confirmasync_step_zeroconf_confirm()
123 
124  return await self.async_step_passwordasync_step_password()
125 
127  self, user_input: dict[str, str] | None = None
128  ) -> ConfigFlowResult:
129  """Handle a confirmation flow initiated by zeroconf."""
130  if user_input is None:
131  return self.async_show_formasync_show_formasync_show_form(
132  step_id="zeroconf_confirm",
133  description_placeholders={
134  "name": self.robot_name_given_by_userrobot_name_given_by_user,
135  "host": self.hosthost,
136  },
137  )
138  return await self._async_step_finish_config_async_step_finish_config()
139 
140  async def _async_step_finish_config(self) -> ConfigFlowResult:
141  """Finish the configuration setup."""
142  return self.async_create_entryasync_create_entryasync_create_entry(
143  title=self.robot_name_given_by_userrobot_name_given_by_user,
144  data={
145  CONF_HOST: self.hosthost,
146  CONF_PASSWORD: self.passwordpassword,
147  },
148  )
ConfigFlowResult async_step_user(self, dict[str, str]|None user_input=None)
Definition: config_flow.py:29
ConfigFlowResult async_step_password(self, dict[str, str]|None user_input=None)
Definition: config_flow.py:62
ConfigFlowResult async_step_zeroconf(self, zeroconf.ZeroconfServiceInfo discovery_info)
Definition: config_flow.py:88
ConfigFlowResult async_step_zeroconf_confirm(self, dict[str, str]|None user_input=None)
Definition: config_flow.py:128
None _abort_if_unique_id_configured(self, dict[str, Any]|None updates=None, bool reload_on_update=True, *str error="already_configured")
ConfigEntry|None async_set_unique_id(self, str|None unique_id=None, *bool raise_on_progress=True)
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)
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)
IssData update(pyiss.ISS iss)
Definition: __init__.py:33