Home Assistant Unofficial Reference 2024.12.1
config_flow.py
Go to the documentation of this file.
1 """Config flow for Geniushub integration."""
2 
3 from __future__ import annotations
4 
5 from http import HTTPStatus
6 import logging
7 import socket
8 from typing import Any
9 
10 import aiohttp
11 from geniushubclient import GeniusService
12 import voluptuous as vol
13 
14 from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
15 from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_TOKEN, CONF_USERNAME
16 from homeassistant.helpers.aiohttp_client import async_get_clientsession
17 
18 from .const import DOMAIN
19 
20 _LOGGER = logging.getLogger(__name__)
21 
22 CLOUD_API_SCHEMA = vol.Schema(
23  {
24  vol.Required(CONF_TOKEN): str,
25  }
26 )
27 
28 
29 LOCAL_API_SCHEMA = vol.Schema(
30  {
31  vol.Required(CONF_HOST): str,
32  vol.Required(CONF_USERNAME): str,
33  vol.Required(CONF_PASSWORD): str,
34  }
35 )
36 
37 
38 class GeniusHubConfigFlow(ConfigFlow, domain=DOMAIN):
39  """Handle a config flow for Geniushub."""
40 
41  VERSION = 1
42 
43  async def async_step_user(
44  self, user_input: dict[str, Any] | None = None
45  ) -> ConfigFlowResult:
46  """User config step for determine cloud or local."""
47  return self.async_show_menuasync_show_menu(
48  step_id="user",
49  menu_options=["local_api", "cloud_api"],
50  )
51 
53  self, user_input: dict[str, Any] | None = None
54  ) -> ConfigFlowResult:
55  """Version 3 configuration."""
56  errors: dict[str, str] = {}
57  if user_input is not None:
58  self._async_abort_entries_match_async_abort_entries_match(
59  {
60  CONF_HOST: user_input[CONF_HOST],
61  CONF_USERNAME: user_input[CONF_USERNAME],
62  }
63  )
64  service = GeniusService(
65  user_input[CONF_HOST],
66  username=user_input[CONF_USERNAME],
67  password=user_input[CONF_PASSWORD],
68  session=async_get_clientsession(self.hass),
69  )
70  try:
71  response = await service.request("GET", "auth/release")
72  except socket.gaierror:
73  errors["base"] = "invalid_host"
74  except aiohttp.ClientResponseError as err:
75  if err.status == HTTPStatus.UNAUTHORIZED:
76  errors["base"] = "invalid_auth"
77  else:
78  errors["base"] = "invalid_host"
79  except (TimeoutError, aiohttp.ClientConnectionError):
80  errors["base"] = "cannot_connect"
81  except Exception: # noqa: BLE001
82  _LOGGER.exception("Unexpected exception")
83  errors["base"] = "unknown"
84  else:
85  await self.async_set_unique_idasync_set_unique_id(response["data"]["UID"])
86  self._abort_if_unique_id_configured_abort_if_unique_id_configured()
87  return self.async_create_entryasync_create_entryasync_create_entry(
88  title=user_input[CONF_HOST], data=user_input
89  )
90 
91  return self.async_show_formasync_show_formasync_show_form(
92  step_id="local_api", errors=errors, data_schema=LOCAL_API_SCHEMA
93  )
94 
96  self, user_input: dict[str, Any] | None = None
97  ) -> ConfigFlowResult:
98  """Version 1 configuration."""
99  errors: dict[str, str] = {}
100  if user_input is not None:
101  self._async_abort_entries_match_async_abort_entries_match(user_input)
102  service = GeniusService(
103  user_input[CONF_TOKEN], session=async_get_clientsession(self.hass)
104  )
105  try:
106  await service.request("GET", "version")
107  except aiohttp.ClientResponseError as err:
108  if err.status == HTTPStatus.UNAUTHORIZED:
109  errors["base"] = "invalid_auth"
110  else:
111  errors["base"] = "invalid_host"
112  except socket.gaierror:
113  errors["base"] = "invalid_host"
114  except (TimeoutError, aiohttp.ClientConnectionError):
115  errors["base"] = "cannot_connect"
116  except Exception: # noqa: BLE001
117  _LOGGER.exception("Unexpected exception")
118  errors["base"] = "unknown"
119  else:
120  return self.async_create_entryasync_create_entryasync_create_entry(title="Genius hub", data=user_input)
121 
122  return self.async_show_formasync_show_formasync_show_form(
123  step_id="cloud_api", errors=errors, data_schema=CLOUD_API_SCHEMA
124  )
ConfigFlowResult async_step_local_api(self, dict[str, Any]|None user_input=None)
Definition: config_flow.py:54
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
Definition: config_flow.py:45
ConfigFlowResult async_step_cloud_api(self, dict[str, Any]|None user_input=None)
Definition: config_flow.py:97
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)
None _async_abort_entries_match(self, dict[str, Any]|None match_dict=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_show_menu(self, *str|None step_id=None, Container[str] menu_options, Mapping[str, str]|None description_placeholders=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)
aiohttp.ClientSession async_get_clientsession(HomeAssistant hass, bool verify_ssl=True, socket.AddressFamily family=socket.AF_UNSPEC, ssl_util.SSLCipherList ssl_cipher=ssl_util.SSLCipherList.PYTHON_DEFAULT)