Home Assistant Unofficial Reference 2024.12.1
device_info.py
Go to the documentation of this file.
1 """Library for extracting device specific information common to entities."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Mapping
6 
7 from google_nest_sdm.device import Device
8 from google_nest_sdm.device_traits import ConnectivityTrait, InfoTrait
9 
10 from homeassistant.core import HomeAssistant, callback
11 from homeassistant.helpers import device_registry as dr
12 from homeassistant.helpers.device_registry import DeviceInfo
13 
14 from .const import CONNECTIVITY_TRAIT_OFFLINE, DATA_DEVICE_MANAGER, DOMAIN
15 
16 DEVICE_TYPE_MAP: dict[str, str] = {
17  "sdm.devices.types.CAMERA": "Camera",
18  "sdm.devices.types.DISPLAY": "Display",
19  "sdm.devices.types.DOORBELL": "Doorbell",
20  "sdm.devices.types.THERMOSTAT": "Thermostat",
21 }
22 
23 
25  """Provide device info from the SDM device, shared across platforms."""
26 
27  device_brand = "Google Nest"
28 
29  def __init__(self, device: Device) -> None:
30  """Initialize the DeviceInfo."""
31  self._device_device = device
32 
33  @property
34  def available(self) -> bool:
35  """Return device availability."""
36  if ConnectivityTrait.NAME in self._device_device.traits:
37  trait: ConnectivityTrait = self._device_device.traits[ConnectivityTrait.NAME]
38  if trait.status == CONNECTIVITY_TRAIT_OFFLINE:
39  return False
40  return True
41 
42  @property
43  def device_info(self) -> DeviceInfo:
44  """Return device specific attributes."""
45  return DeviceInfo(
46  # The API "name" field is a unique device identifier.
47  identifiers={(DOMAIN, self._device_device.name)},
48  manufacturer=self.device_branddevice_brand,
49  model=self.device_modeldevice_model,
50  name=self.device_namedevice_name,
51  suggested_area=self.suggested_areasuggested_area,
52  )
53 
54  @property
55  def device_name(self) -> str | None:
56  """Return the name of the physical device that includes the sensor."""
57  if InfoTrait.NAME in self._device_device.traits:
58  trait: InfoTrait = self._device_device.traits[InfoTrait.NAME]
59  if trait.custom_name:
60  return str(trait.custom_name)
61  # Build a name from the room/structure if not set explicitly
62  if area := self.suggested_areasuggested_area:
63  return area
64  return self.device_modeldevice_model
65 
66  @property
67  def device_model(self) -> str | None:
68  """Return device model information."""
69  return DEVICE_TYPE_MAP.get(self._device_device.type) if self._device_device.type else None
70 
71  @property
72  def suggested_area(self) -> str | None:
73  """Return device suggested area based on the Google Home room."""
74  if parent_relations := self._device_device.parent_relations:
75  items = sorted(parent_relations.items())
76  names = [name for _, name in items]
77  return " ".join(names)
78  return None
79 
80 
81 @callback
82 def async_nest_devices(hass: HomeAssistant) -> Mapping[str, Device]:
83  """Return a mapping of all nest devices for all config entries."""
84  devices = {}
85  for entry_id in hass.data[DOMAIN]:
86  if not (device_manager := hass.data[DOMAIN][entry_id].get(DATA_DEVICE_MANAGER)):
87  continue
88  devices.update(
89  {device.name: device for device in device_manager.devices.values()}
90  )
91  return devices
92 
93 
94 @callback
95 def async_nest_devices_by_device_id(hass: HomeAssistant) -> Mapping[str, Device]:
96  """Return a mapping of all nest devices by home assistant device id, for all config entries."""
97  device_registry = dr.async_get(hass)
98  devices = {}
99  for nest_device_id, device in async_nest_devices(hass).items():
100  if device_entry := device_registry.async_get_device(
101  identifiers={(DOMAIN, nest_device_id)}
102  ):
103  devices[device_entry.id] = device
104  return devices
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88
Mapping[str, Device] async_nest_devices(HomeAssistant hass)
Definition: device_info.py:82
Mapping[str, Device] async_nest_devices_by_device_id(HomeAssistant hass)
Definition: device_info.py:95