Home Assistant Unofficial Reference 2024.12.1
entity.py
Go to the documentation of this file.
1 """An abstract class common to all Switchbot entities."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Mapping
6 import logging
7 from typing import Any
8 
9 from switchbot import Switchbot, SwitchbotDevice
10 
12  PassiveBluetoothCoordinatorEntity,
13 )
14 from homeassistant.const import ATTR_CONNECTIONS
15 from homeassistant.core import callback
16 from homeassistant.helpers import device_registry as dr
17 from homeassistant.helpers.device_registry import DeviceInfo
18 from homeassistant.helpers.entity import ToggleEntity
19 
20 from .const import MANUFACTURER
21 from .coordinator import SwitchbotDataUpdateCoordinator
22 
23 _LOGGER = logging.getLogger(__name__)
24 
25 
27  PassiveBluetoothCoordinatorEntity[SwitchbotDataUpdateCoordinator]
28 ):
29  """Generic entity encapsulating common features of Switchbot device."""
30 
31  _device: SwitchbotDevice
32  _attr_has_entity_name = True
33 
34  def __init__(self, coordinator: SwitchbotDataUpdateCoordinator) -> None:
35  """Initialize the entity."""
36  super().__init__(coordinator)
37  self._device_device = coordinator.device
38  self._last_run_success: bool | None = None
39  self._address_address = coordinator.ble_device.address
40  self._attr_unique_id_attr_unique_id = coordinator.base_unique_id
41  self._attr_device_info_attr_device_info = DeviceInfo(
42  connections={(dr.CONNECTION_BLUETOOTH, self._address_address)},
43  manufacturer=MANUFACTURER,
44  model=coordinator.model, # Sometimes the modelName is missing from the advertisement data
45  name=coordinator.device_name,
46  )
47  if ":" not in self._address_address:
48  # MacOS Bluetooth addresses are not mac addresses
49  return
50  # If the bluetooth address is also a mac address,
51  # add this connection as well to prevent a new device
52  # entry from being created when upgrading from a previous
53  # version of the integration.
54  self._attr_device_info_attr_device_info[ATTR_CONNECTIONS].add(
55  (dr.CONNECTION_NETWORK_MAC, self._address_address)
56  )
57 
58  @property
59  def parsed_data(self) -> dict[str, Any]:
60  """Return parsed device data for this entity."""
61  return self.coordinator.device.parsed_data
62 
63  @property
64  def extra_state_attributes(self) -> Mapping[Any, Any]:
65  """Return the state attributes."""
66  return {"last_run_success": self._last_run_success}
67 
68  @callback
69  def _async_update_attrs(self) -> None:
70  """Update the entity attributes."""
71 
72  @callback
73  def _handle_coordinator_update(self) -> None:
74  """Handle data update."""
75  self._async_update_attrs_async_update_attrs()
76  self.async_write_ha_state()
77 
78  async def async_added_to_hass(self) -> None:
79  """Register callbacks."""
80  self.async_on_remove(self._device_device.subscribe(self._handle_coordinator_update_handle_coordinator_update))
81  return await super().async_added_to_hass()
82 
83  async def async_update(self) -> None:
84  """Update the entity.
85 
86  Only used by the generic entity update service.
87  """
88  await self._device_device.update()
89 
90 
92  """Base class for Switchbot entities that can be turned on and off."""
93 
94  _device: Switchbot
95 
96  async def async_turn_on(self, **kwargs: Any) -> None:
97  """Turn device on."""
98  _LOGGER.debug("Turn Switchbot device on %s", self._address_address)
99 
100  self._last_run_success_last_run_success = bool(await self._device_device.turn_on())
101  if self._last_run_success_last_run_success:
102  self._attr_is_on_attr_is_on = True
103  self.async_write_ha_stateasync_write_ha_state()
104 
105  async def async_turn_off(self, **kwargs: Any) -> None:
106  """Turn device off."""
107  _LOGGER.debug("Turn Switchbot device off %s", self._address_address)
108 
109  self._last_run_success_last_run_success = bool(await self._device_device.turn_off())
110  if self._last_run_success_last_run_success:
111  self._attr_is_on_attr_is_on = False
112  self.async_write_ha_stateasync_write_ha_state()
None __init__(self, SwitchbotDataUpdateCoordinator coordinator)
Definition: entity.py:34
None turn_off(self, **Any kwargs)
Definition: entity.py:1705
None turn_on(self, **Any kwargs)
Definition: entity.py:1697
bool add(self, _T matcher)
Definition: match.py:185
Callable[[], None] subscribe(HomeAssistant hass, str topic, MessageCallbackType msg_callback, int qos=DEFAULT_QOS, str encoding="utf-8")
Definition: client.py:247