1 """Config flow to configure the Bluetooth integration."""
3 from __future__
import annotations
6 from typing
import Any, cast
8 from bluetooth_adapters
import (
17 from habluetooth
import get_manager
18 import voluptuous
as vol
25 SchemaOptionsFlowHandler,
29 from .const
import CONF_ADAPTER, CONF_DETAILS, CONF_PASSIVE, DOMAIN
30 from .util
import adapter_title
32 OPTIONS_SCHEMA = vol.Schema(
34 vol.Required(CONF_PASSIVE, default=
False): bool,
43 """Return the adapter display info."""
44 name = adapter_human_name(adapter, details[ADAPTER_ADDRESS])
45 model = adapter_model(details)
46 manufacturer = details[ADAPTER_MANUFACTURER]
or "Unknown"
47 return f
"{name} {manufacturer} {model}"
51 """Config flow for Bluetooth."""
56 """Initialize the config flow."""
57 self.
_adapter_adapter: str |
None =
None
58 self.
_details_details: AdapterDetails |
None =
None
59 self.
_adapters_adapters: dict[str, AdapterDetails] = {}
63 self, discovery_info: DiscoveryInfoType
64 ) -> ConfigFlowResult:
65 """Handle a flow initialized by discovery."""
66 self.
_adapter_adapter = cast(str, discovery_info[CONF_ADAPTER])
67 self.
_details_details = cast(AdapterDetails, discovery_info[CONF_DETAILS])
76 """Set the adapter info."""
77 name = adapter_human_name(adapter, details[ADAPTER_ADDRESS])
78 model = adapter_model(details)
79 manufacturer = details[ADAPTER_MANUFACTURER]
83 "manufacturer": manufacturer
or "Unknown",
85 self.context[
"title_placeholders"] = self.
_placeholders_placeholders
88 self, user_input: dict[str, Any] |
None =
None
89 ) -> ConfigFlowResult:
90 """Select an adapter."""
93 assert adapter
is not None
94 assert details
is not None
97 address = details[ADAPTER_ADDRESS]
99 if user_input
is not None or not onboarding.async_is_onboarded(self.hass):
107 step_id=
"single_adapter",
112 self, user_input: dict[str, Any] |
None =
None
113 ) -> ConfigFlowResult:
114 """Handle a flow initialized by the user."""
115 if user_input
is not None:
116 assert self.
_adapters_adapters
is not None
117 adapter = user_input[CONF_ADAPTER]
118 details = self.
_adapters_adapters[adapter]
119 address = details[ADAPTER_ADDRESS]
127 bluetooth_adapters = get_adapters()
128 await bluetooth_adapters.refresh()
130 system = platform.system()
131 unconfigured_adapters = [
133 for adapter, details
in self.
_adapters_adapters.items()
134 if details[ADAPTER_ADDRESS]
not in configured_addresses
138 and not (system ==
"Linux" and details[ADAPTER_ADDRESS] == DEFAULT_ADDRESS)
140 if not unconfigured_adapters:
141 ignored_adapters = len(
145 reason=
"no_adapters",
146 description_placeholders={
"ignored_adapters":
str(ignored_adapters)},
148 if len(unconfigured_adapters) == 1:
155 step_id=
"multiple_adapters",
156 data_schema=vol.Schema(
158 vol.Required(CONF_ADAPTER): vol.In(
161 adapter, self.
_adapters_adapters[adapter]
163 for adapter
in sorted(unconfigured_adapters)
171 self, user_input: dict[str, Any] |
None =
None
172 ) -> ConfigFlowResult:
173 """Handle a flow initialized by the user."""
179 config_entry: ConfigEntry,
180 ) -> SchemaOptionsFlowHandler:
181 """Get the options flow for this handler."""
187 """Return options flow support for this handler."""
188 return bool((manager := get_manager())
and manager.supports_passive_scan)
bool async_supports_options_flow(cls, ConfigEntry config_entry)
SchemaOptionsFlowHandler async_get_options_flow(ConfigEntry config_entry)
ConfigFlowResult async_step_single_adapter(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_multiple_adapters(self, dict[str, Any]|None user_input=None)
None _async_set_adapter_info(self, str adapter, AdapterDetails details)
ConfigFlowResult async_step_integration_discovery(self, DiscoveryInfoType discovery_info)
None _abort_if_unique_id_configured(self, dict[str, Any]|None updates=None, bool reload_on_update=True, *str error="already_configured")
set[str|None] _async_current_ids(self, bool include_ignore=True)
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_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 adapter_display_info(str adapter, AdapterDetails details)
str adapter_title(str adapter, AdapterDetails details)