Home Assistant Unofficial Reference 2024.12.1
entity.py
Go to the documentation of this file.
1 """Base class for IKEA TRADFRI."""
2 
3 from __future__ import annotations
4 
5 from abc import abstractmethod
6 from collections.abc import Callable, Coroutine
7 from functools import wraps
8 from typing import Any, cast
9 
10 from pytradfri.command import Command
11 from pytradfri.device import Device
12 from pytradfri.error import RequestError
13 
14 from homeassistant.core import callback
15 from homeassistant.helpers.device_registry import DeviceInfo
16 from homeassistant.helpers.update_coordinator import CoordinatorEntity
17 
18 from .const import DOMAIN, LOGGER
19 from .coordinator import TradfriDeviceDataUpdateCoordinator
20 
21 
23  func: Callable[[Command | list[Command]], Any],
24 ) -> Callable[[Command | list[Command]], Coroutine[Any, Any, None]]:
25  """Handle tradfri api call error."""
26 
27  @wraps(func)
28  async def wrapper(command: Command | list[Command]) -> None:
29  """Decorate api call."""
30  try:
31  await func(command)
32  except RequestError as err:
33  LOGGER.error("Unable to execute command %s: %s", command, err)
34 
35  return wrapper
36 
37 
38 class TradfriBaseEntity(CoordinatorEntity[TradfriDeviceDataUpdateCoordinator]):
39  """Base Tradfri device."""
40 
41  _attr_has_entity_name = True
42 
43  def __init__(
44  self,
45  device_coordinator: TradfriDeviceDataUpdateCoordinator,
46  gateway_id: str,
47  api: Callable[[Command | list[Command]], Any],
48  ) -> None:
49  """Initialize a device."""
50  super().__init__(device_coordinator)
51 
52  self._gateway_id_gateway_id = gateway_id
53 
54  self._device: Device = device_coordinator.data
55 
56  self._device_id_device_id = self._device.id
57  self._api_api = handle_error(api)
58 
59  info = self._device.device_info
60  self._attr_device_info_attr_device_info = DeviceInfo(
61  identifiers={(DOMAIN, self._device_id_device_id)},
62  manufacturer=info.manufacturer,
63  model=info.model_number,
64  name=self._device.name,
65  sw_version=info.firmware_version,
66  via_device=(DOMAIN, gateway_id),
67  )
68  self._attr_unique_id_attr_unique_id = f"{gateway_id}-{self._device_id}"
69 
70  @abstractmethod
71  @callback
72  def _refresh(self) -> None:
73  """Refresh device data."""
74 
75  @callback
76  def _handle_coordinator_update(self) -> None:
77  """Handle updated data from the coordinator.
78 
79  Tests fails without this method.
80  """
81  self._refresh_refresh()
83 
84  @property
85  def available(self) -> bool:
86  """Return if entity is available."""
87  return cast(bool, self._device.reachable) and super().available
None __init__(self, TradfriDeviceDataUpdateCoordinator device_coordinator, str gateway_id, Callable[[Command|list[Command]], Any] api)
Definition: entity.py:48
Callable[[Command|list[Command]], Coroutine[Any, Any, None]] handle_error(Callable[[Command|list[Command]], Any] func)
Definition: entity.py:24