1 """Config flow for Bond integration."""
3 from __future__
import annotations
6 from http
import HTTPStatus
10 from aiohttp
import ClientConnectionError, ClientResponseError
11 from bond_async
import Bond
12 import voluptuous
as vol
21 from .const
import DOMAIN
22 from .utils
import BondHub
24 _LOGGER = logging.getLogger(__name__)
27 USER_SCHEMA = vol.Schema(
28 {vol.Required(CONF_HOST): str, vol.Required(CONF_ACCESS_TOKEN): str}
30 DISCOVERY_SCHEMA = vol.Schema({vol.Required(CONF_ACCESS_TOKEN): str})
31 TOKEN_SCHEMA = vol.Schema({})
35 """Try to fetch the token from the bond device."""
37 response: dict[str, str] = {}
38 with contextlib.suppress(ClientConnectionError):
39 response = await bond.token()
40 return response.get(
"token")
43 async
def _validate_input(hass: HomeAssistant, data: dict[str, Any]) -> tuple[str, str]:
44 """Validate the user input allows us to connect."""
50 hub =
BondHub(bond, data[CONF_HOST])
51 await hub.setup(max_devices=1)
52 except ClientConnectionError
as error:
54 except ClientResponseError
as error:
55 if error.status == HTTPStatus.UNAUTHORIZED:
58 except Exception
as error:
59 _LOGGER.exception(
"Unexpected exception")
66 return hub.bond_id, hub.name
70 """Handle a config flow for Bond."""
75 """Initialize config flow."""
79 """Try to auto configure the device.
81 Failure is acceptable here since the device may have been
82 online longer then the allowed setup period, and we will
83 instead ask them to manually enter the token.
92 self.
_discovered_discovered[CONF_ACCESS_TOKEN] = token
95 except InputValidationError:
100 self, discovery_info: zeroconf.ZeroconfServiceInfo
101 ) -> ConfigFlowResult:
102 """Handle a flow initialized by zeroconf discovery."""
103 name: str = discovery_info.name
104 host: str = discovery_info.host
105 bond_id = name.partition(
".")[0]
108 if entry.unique_id != bond_id:
110 updates = {CONF_HOST: host}
111 if entry.state == ConfigEntryState.SETUP_ERROR
and (
114 updates[CONF_ACCESS_TOKEN] = token
117 data={**entry.data, **updates},
118 reason=
"already_configured",
119 reload_even_if_entry_is_unchanged=
False,
122 self.
_discovered_discovered = {CONF_HOST: host, CONF_NAME: bond_id}
127 "title_placeholders": {
137 self, user_input: dict[str, Any] |
None =
None
138 ) -> ConfigFlowResult:
139 """Handle confirmation flow for discovered bond hub."""
141 if user_input
is not None:
142 if CONF_ACCESS_TOKEN
in self.
_discovered_discovered:
146 CONF_ACCESS_TOKEN: self.
_discovered_discovered[CONF_ACCESS_TOKEN],
152 CONF_ACCESS_TOKEN: user_input[CONF_ACCESS_TOKEN],
157 except InputValidationError
as error:
158 errors[
"base"] = error.base
165 if CONF_ACCESS_TOKEN
in self.
_discovered_discovered:
166 data_schema = TOKEN_SCHEMA
168 data_schema = DISCOVERY_SCHEMA
172 data_schema=data_schema,
174 description_placeholders=self.
_discovered_discovered,
178 self, user_input: dict[str, Any] |
None =
None
179 ) -> ConfigFlowResult:
180 """Handle a flow initialized by the user."""
182 if user_input
is not None:
185 except InputValidationError
as error:
186 errors[
"base"] = error.base
193 step_id=
"user", data_schema=USER_SCHEMA, errors=errors
198 """Error to indicate we cannot proceed due to invalid input."""
201 """Initialize with error base."""
ConfigFlowResult async_step_zeroconf(self, zeroconf.ZeroconfServiceInfo discovery_info)
ConfigFlowResult async_step_confirm(self, dict[str, Any]|None user_input=None)
None _async_try_automatic_configure(self)
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
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)
list[ConfigEntry] _async_current_entries(self, bool|None include_ignore=None)
ConfigFlowResult async_update_reload_and_abort(self, ConfigEntry entry, *str|None|UndefinedType unique_id=UNDEFINED, str|UndefinedType title=UNDEFINED, Mapping[str, Any]|UndefinedType data=UNDEFINED, Mapping[str, Any]|UndefinedType data_updates=UNDEFINED, Mapping[str, Any]|UndefinedType options=UNDEFINED, str|UndefinedType reason=UNDEFINED, bool reload_even_if_entry_is_unchanged=True)
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)
str|None async_get_token(HomeAssistant hass, str host)
tuple[str, str] _validate_input(HomeAssistant hass, dict[str, Any] data)
IssData update(pyiss.ISS iss)
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)