1 """Config flow for Gardena Bluetooth integration."""
3 from __future__
import annotations
8 from gardena_bluetooth.client
import Client
9 from gardena_bluetooth.const
import PRODUCT_NAMES, DeviceInformation, ScanService
10 from gardena_bluetooth.exceptions
import CharacteristicNotFound, CommunicationFailure
11 from gardena_bluetooth.parse
import ManufacturerData, ProductType
12 import voluptuous
as vol
16 async_discovered_service_info,
22 from .
import get_connection
23 from .const
import DOMAIN
25 _LOGGER = logging.getLogger(__name__)
29 """Check if device is supported."""
30 if ScanService
not in discovery_info.service_uuids:
33 if not (data := discovery_info.manufacturer_data.get(ManufacturerData.company)):
34 _LOGGER.debug(
"Missing manufacturer data: %s", discovery_info)
37 manufacturer_data = ManufacturerData.decode(data)
38 product_type = ProductType.from_manufacturer_data(manufacturer_data)
40 if product_type
not in (
43 ProductType.WATER_COMPUTER,
45 _LOGGER.debug(
"Unsupported device: %s", manufacturer_data)
51 def _get_name(discovery_info: BluetoothServiceInfo):
52 data = discovery_info.manufacturer_data[ManufacturerData.company]
53 manufacturer_data = ManufacturerData.decode(data)
54 product_type = ProductType.from_manufacturer_data(manufacturer_data)
56 return PRODUCT_NAMES.get(product_type,
"Gardena Device")
60 """Handle a config flow for Gardena Bluetooth."""
65 """Initialize the config flow."""
66 self.
devicesdevices: dict[str, str] = {}
70 """Try to connect to device and extract information."""
73 model = await client.read_char(DeviceInformation.model_number)
74 _LOGGER.debug(
"Found device with model: %s", model)
75 except (CharacteristicNotFound, CommunicationFailure)
as exception:
77 "cannot_connect", description_placeholders={
"error":
str(exception)}
80 await client.disconnect()
82 return {CONF_ADDRESS: self.
addressaddress}
85 self, discovery_info: BluetoothServiceInfo
86 ) -> ConfigFlowResult:
87 """Handle the bluetooth discovery step."""
88 _LOGGER.debug(
"Discovered device: %s", discovery_info)
92 self.
addressaddress = discovery_info.address
99 self, user_input: dict[str, Any] |
None =
None
100 ) -> ConfigFlowResult:
101 """Confirm discovery."""
105 if user_input
is not None:
109 self.context[
"title_placeholders"] = {
116 description_placeholders=self.context[
"title_placeholders"],
120 self, user_input: dict[str, Any] |
None =
None
121 ) -> ConfigFlowResult:
122 """Handle the initial step."""
123 if user_input
is not None:
124 self.
addressaddress = user_input[CONF_ADDRESS]
131 address = discovery_info.address
132 if address
in current_addresses
or not _is_supported(discovery_info):
142 data_schema=vol.Schema(
144 vol.Required(CONF_ADDRESS): vol.In(self.
devicesdevices),
def async_read_data(self)
ConfigFlowResult async_step_confirm(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_user(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)
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)
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)
Iterable[BluetoothServiceInfoBleak] async_discovered_service_info(HomeAssistant hass, bool connectable=True)
def _is_supported(BluetoothServiceInfo discovery_info)
def _get_name(BluetoothServiceInfo discovery_info)
CachedConnection get_connection(HomeAssistant hass, str address)