1 """Config flow for Husqvarna Bluetooth integration."""
3 from __future__
import annotations
8 from automower_ble.mower
import Mower
9 from bleak
import BleakError
10 import voluptuous
as vol
17 from .const
import DOMAIN, LOGGER
21 """Check if device is supported."""
24 "%s manufacturer data: %s",
25 discovery_info.address,
26 discovery_info.manufacturer_data,
29 manufacturer = any(key == 1062
for key
in discovery_info.manufacturer_data)
30 service_husqvarna = any(
31 service ==
"98bd0001-0b0e-421a-84e5-ddbf75dc6de4"
32 for service
in discovery_info.service_uuids
34 service_generic = any(
35 service ==
"00001800-0000-1000-8000-00805f9b34fb"
36 for service
in discovery_info.service_uuids
39 return manufacturer
and service_husqvarna
and service_generic
43 """Handle a config flow for Husqvarna Bluetooth."""
48 """Initialize the config flow."""
52 self, discovery_info: BluetoothServiceInfo
53 ) -> ConfigFlowResult:
54 """Handle the bluetooth discovery step."""
56 LOGGER.debug(
"Discovered device: %s", discovery_info)
60 self.
addressaddress = discovery_info.address
66 self, user_input: dict[str, Any] |
None =
None
67 ) -> ConfigFlowResult:
68 """Confirm discovery."""
71 device = bluetooth.async_ble_device_from_address(
72 self.hass, self.
addressaddress, connectable=
True
74 channel_id = random.randint(1, 0xFFFFFFFF)
77 (manufacturer, device_type, model) = await Mower(
80 except (BleakError, TimeoutError)
as exception:
81 LOGGER.exception(
"Failed to connect to device: %s", exception)
84 title = manufacturer +
" " + device_type
86 LOGGER.debug(
"Found device: %s", title)
88 if user_input
is not None:
91 data={CONF_ADDRESS: self.
addressaddress, CONF_CLIENT_ID: channel_id},
94 self.context[
"title_placeholders"] = {
101 description_placeholders=self.context[
"title_placeholders"],
105 self, user_input: dict[str, Any] |
None =
None
106 ) -> ConfigFlowResult:
107 """Handle the initial step."""
108 if user_input
is not None:
109 self.
addressaddress = user_input[CONF_ADDRESS]
116 data_schema=vol.Schema(
118 vol.Required(CONF_ADDRESS): str,
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_confirm(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_bluetooth(self, BluetoothServiceInfo discovery_info)
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)
def _is_supported(BluetoothServiceInfo discovery_info)