Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """The Gardena Bluetooth integration."""
2 
3 from __future__ import annotations
4 
5 import logging
6 
7 from bleak.backends.device import BLEDevice
8 from gardena_bluetooth.client import CachedConnection, Client
9 from gardena_bluetooth.const import DeviceConfiguration, DeviceInformation
10 from gardena_bluetooth.exceptions import CommunicationFailure
11 
12 from homeassistant.components import bluetooth
13 from homeassistant.config_entries import ConfigEntry
14 from homeassistant.const import CONF_ADDRESS, Platform
15 from homeassistant.core import HomeAssistant
16 from homeassistant.exceptions import ConfigEntryNotReady
17 from homeassistant.helpers.device_registry import DeviceInfo
18 import homeassistant.util.dt as dt_util
19 
20 from .const import DOMAIN
21 from .coordinator import DeviceUnavailable, GardenaBluetoothCoordinator
22 
23 PLATFORMS: list[Platform] = [
24  Platform.BINARY_SENSOR,
25  Platform.BUTTON,
26  Platform.NUMBER,
27  Platform.SENSOR,
28  Platform.SWITCH,
29  Platform.VALVE,
30 ]
31 LOGGER = logging.getLogger(__name__)
32 TIMEOUT = 20.0
33 DISCONNECT_DELAY = 5
34 
35 type GardenaBluetoothConfigEntry = ConfigEntry[GardenaBluetoothCoordinator]
36 
37 
38 def get_connection(hass: HomeAssistant, address: str) -> CachedConnection:
39  """Set up a cached client that keeps connection after last use."""
40 
41  def _device_lookup() -> BLEDevice:
42  device = bluetooth.async_ble_device_from_address(
43  hass, address, connectable=True
44  )
45  if not device:
46  raise DeviceUnavailable("Unable to find device")
47  return device
48 
49  return CachedConnection(DISCONNECT_DELAY, _device_lookup)
50 
51 
53  hass: HomeAssistant, entry: GardenaBluetoothConfigEntry
54 ) -> bool:
55  """Set up Gardena Bluetooth from a config entry."""
56 
57  address = entry.data[CONF_ADDRESS]
58  client = Client(get_connection(hass, address))
59  try:
60  sw_version = await client.read_char(DeviceInformation.firmware_version, None)
61  manufacturer = await client.read_char(DeviceInformation.manufacturer_name, None)
62  model = await client.read_char(DeviceInformation.model_number, None)
63  name = await client.read_char(
64  DeviceConfiguration.custom_device_name, entry.title
65  )
66  uuids = await client.get_all_characteristics_uuid()
67  await client.update_timestamp(dt_util.now())
68  except (TimeoutError, CommunicationFailure, DeviceUnavailable) as exception:
69  await client.disconnect()
70  raise ConfigEntryNotReady(
71  f"Unable to connect to device {address} due to {exception}"
72  ) from exception
73 
74  device = DeviceInfo(
75  identifiers={(DOMAIN, address)},
76  name=name,
77  sw_version=sw_version,
78  manufacturer=manufacturer,
79  model=model,
80  )
81 
82  coordinator = GardenaBluetoothCoordinator(
83  hass, LOGGER, client, uuids, device, address
84  )
85 
86  entry.runtime_data = coordinator
87  await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
88  await coordinator.async_refresh()
89 
90  return True
91 
92 
94  hass: HomeAssistant, entry: GardenaBluetoothConfigEntry
95 ) -> bool:
96  """Unload a config entry."""
97  if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
98  await entry.runtime_data.async_shutdown()
99 
100  return unload_ok
bool async_setup_entry(HomeAssistant hass, GardenaBluetoothConfigEntry entry)
Definition: __init__.py:54
bool async_unload_entry(HomeAssistant hass, GardenaBluetoothConfigEntry entry)
Definition: __init__.py:95
CachedConnection get_connection(HomeAssistant hass, str address)
Definition: __init__.py:38