1 """Config flow for the Bang & Olufsen integration."""
3 from __future__
import annotations
5 from ipaddress
import AddressValueError, IPv4Address
6 from typing
import Any, TypedDict
8 from aiohttp.client_exceptions
import ClientConnectorError
9 from mozart_api.exceptions
import ApiException
10 from mozart_api.mozart_client
import MozartClient
11 import voluptuous
as vol
29 from .util
import get_serial_number_from_jid
33 """TypedDict for config_entry data."""
43 ApiException:
"api_exception",
44 ClientConnectorError:
"client_connector_error",
45 TimeoutError:
"timeout_error",
46 AddressValueError:
"invalid_ip",
51 """Handle a config flow."""
61 """Init the config flow."""
66 self, user_input: dict[str, Any] |
None =
None
67 ) -> ConfigFlowResult:
68 """Handle the initial step."""
69 data_schema = vol.Schema(
71 vol.Required(CONF_HOST): str,
78 if user_input
is not None:
85 except AddressValueError
as error:
88 data_schema=data_schema,
89 errors={
"base": _exception_map[type(error)]},
99 beolink_self = await self.
_client_client.get_beolink_self(
104 ClientConnectorError,
109 data_schema=data_schema,
110 errors={
"base": _exception_map[type(error)]},
123 data_schema=data_schema,
127 self, discovery_info: ZeroconfServiceInfo
128 ) -> ConfigFlowResult:
129 """Handle discovery using Zeroconf."""
132 if ATTR_FRIENDLY_NAME
not in discovery_info.properties:
139 except AddressValueError:
145 async
with self.
_client_client:
147 await self.
_client_client.get_beolink_self(_request_timeout=3)
148 except (ClientConnectorError, TimeoutError):
151 self.
_model_model_model = discovery_info.hostname[:-16].replace(
"-",
" ")
153 self.
_beolink_jid_beolink_jid_beolink_jid = f
"{discovery_info.properties[ATTR_TYPE_NUMBER]}.{discovery_info.properties[ATTR_ITEM_NUMBER]}.{self._serial_number}@products.bang-olufsen.com"
159 self.context[
"title_placeholders"] = {
160 "name": discovery_info.properties[ATTR_FRIENDLY_NAME]
166 """Create the config entry for a discovered or manually configured Bang & Olufsen device."""
168 self.
_name_name_name = f
"{self._model}-{self._serial_number}"
181 self, user_input: dict[str, Any] |
None =
None
182 ) -> ConfigFlowResult:
183 """Confirm the configuration of the device."""
184 if user_input
is not None:
190 step_id=
"zeroconf_confirm",
191 description_placeholders={
ConfigFlowResult async_step_zeroconf_confirm(self, dict[str, Any]|None user_input=None)
ConfigFlowResult _create_entry(self)
ConfigFlowResult async_step_zeroconf(self, ZeroconfServiceInfo discovery_info)
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")
None _set_confirm_only(self)
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)
str get_serial_number_from_jid(str jid)
ssl.SSLContext get_default_context()