Home Assistant Unofficial Reference 2024.12.1
entity.py
Go to the documentation of this file.
1 """Component for interacting with a Lutron Caseta system."""
2 
3 from __future__ import annotations
4 
5 import logging
6 from typing import Any
7 
8 from homeassistant.const import ATTR_SUGGESTED_AREA
9 from homeassistant.helpers.device_registry import DeviceInfo
10 from homeassistant.helpers.entity import Entity
11 
12 from .const import CONFIG_URL, DOMAIN, MANUFACTURER, UNASSIGNED_AREA
13 from .models import LutronCasetaData
14 from .util import area_name_from_id, serial_to_unique_id
15 
16 _LOGGER = logging.getLogger(__name__)
17 
18 
20  """Common base class for all Lutron Caseta devices."""
21 
22  _attr_should_poll = False
23 
24  def __init__(self, device: dict[str, Any], data: LutronCasetaData) -> None:
25  """Set up the base class.
26 
27  [:param]device the device metadata
28  [:param]bridge the smartbridge object
29  [:param]bridge_device a dict with the details of the bridge
30  """
31  self._device_device = device
32  self._smartbridge_smartbridge = data.bridge
33  self._bridge_device_bridge_device = data.bridge_device
34  self._bridge_unique_id_bridge_unique_id = serial_to_unique_id(data.bridge_device["serial"])
35  if "serial" not in self._device_device:
36  return
37 
38  if "parent_device" in device:
39  # This is a child entity, handle the naming in button.py and switch.py
40  return
41  area = area_name_from_id(self._smartbridge_smartbridge.areas, device["area"])
42  name = device["name"].split("_")[-1]
43  self._attr_name_attr_name = full_name = f"{area} {name}"
44  info = DeviceInfo(
45  # Historically we used the device serial number for the identifier
46  # but the serial is usually an integer and a string is expected
47  # here. Since it would be a breaking change to change the identifier
48  # we are ignoring the type error here until it can be migrated to
49  # a string in a future release.
50  identifiers={
51  (
52  DOMAIN,
53  self._handle_none_serial_handle_none_serial(self.serialserial), # type: ignore[arg-type]
54  )
55  },
56  manufacturer=MANUFACTURER,
57  model=f"{device['model']} ({device['type']})",
58  name=full_name,
59  via_device=(DOMAIN, self._bridge_device_bridge_device["serial"]),
60  configuration_url=CONFIG_URL,
61  )
62  if area != UNASSIGNED_AREA:
63  info[ATTR_SUGGESTED_AREA] = area
64  self._attr_device_info_attr_device_info = info
65 
66  async def async_added_to_hass(self):
67  """Register callbacks."""
68  self._smartbridge_smartbridge.add_subscriber(self.device_iddevice_id, self.async_write_ha_stateasync_write_ha_state)
69 
70  def _handle_none_serial(self, serial: str | int | None) -> str | int:
71  """Handle None serial returned by RA3 and QSX processors."""
72  if serial is None:
73  return f"{self._bridge_unique_id}_{self.device_id}"
74  return serial
75 
76  @property
77  def device_id(self):
78  """Return the device ID used for calling pylutron_caseta."""
79  return self._device_device["device_id"]
80 
81  @property
82  def serial(self) -> int | None:
83  """Return the serial number of the device."""
84  return self._device_device["serial"]
85 
86  @property
87  def unique_id(self) -> str:
88  """Return the unique ID of the device (serial)."""
89  return str(self._handle_none_serial_handle_none_serial(self.serialserial))
90 
91  @property
93  """Return the state attributes."""
94  attributes = {
95  "device_id": self.device_iddevice_id,
96  }
97  if zone := self._device_device.get("zone"):
98  attributes["zone_id"] = zone
99  return attributes
100 
101 
103  """A lutron_caseta entity that can update by syncing data from the bridge."""
104 
105  async def async_update(self) -> None:
106  """Update when forcing a refresh of the device."""
107  self._device_device_device = self._smartbridge_smartbridge.get_device_by_id(self.device_iddevice_id)
108  _LOGGER.debug(self._device_device_device)
None __init__(self, dict[str, Any] device, LutronCasetaData data)
Definition: entity.py:24
str|int _handle_none_serial(self, str|int|None serial)
Definition: entity.py:70
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88
str area_name_from_id(dict[str, dict] areas, str|None area_id)
Definition: util.py:13