Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Support for Google Nest SDM sensors."""
2 
3 from __future__ import annotations
4 
5 import logging
6 
7 from google_nest_sdm.device import Device
8 from google_nest_sdm.device_manager import DeviceManager
9 from google_nest_sdm.device_traits import HumidityTrait, TemperatureTrait
10 
12  SensorDeviceClass,
13  SensorEntity,
14  SensorStateClass,
15 )
16 from homeassistant.config_entries import ConfigEntry
17 from homeassistant.const import PERCENTAGE, UnitOfTemperature
18 from homeassistant.core import HomeAssistant
19 from homeassistant.helpers.entity_platform import AddEntitiesCallback
20 
21 from .const import DATA_DEVICE_MANAGER, DOMAIN
22 from .device_info import NestDeviceInfo
23 
24 _LOGGER = logging.getLogger(__name__)
25 
26 
27 DEVICE_TYPE_MAP = {
28  "sdm.devices.types.CAMERA": "Camera",
29  "sdm.devices.types.DISPLAY": "Display",
30  "sdm.devices.types.DOORBELL": "Doorbell",
31  "sdm.devices.types.THERMOSTAT": "Thermostat",
32 }
33 
34 
36  hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
37 ) -> None:
38  """Set up the sensors."""
39 
40  device_manager: DeviceManager = hass.data[DOMAIN][entry.entry_id][
41  DATA_DEVICE_MANAGER
42  ]
43  entities: list[SensorEntity] = []
44  for device in device_manager.devices.values():
45  if TemperatureTrait.NAME in device.traits:
46  entities.append(TemperatureSensor(device))
47  if HumidityTrait.NAME in device.traits:
48  entities.append(HumiditySensor(device))
49  async_add_entities(entities)
50 
51 
53  """Representation of a dynamically updated Sensor."""
54 
55  _attr_should_poll = False
56  _attr_state_class = SensorStateClass.MEASUREMENT
57  _attr_has_entity_name = True
58 
59  def __init__(self, device: Device) -> None:
60  """Initialize the sensor."""
61  self._device_device = device
62  self._device_info_device_info = NestDeviceInfo(device)
63  self._attr_unique_id_attr_unique_id = f"{device.name}-{self.device_class}"
64  self._attr_device_info_attr_device_info = self._device_info_device_info.device_info
65 
66  @property
67  def available(self) -> bool:
68  """Return the device availability."""
69  return self._device_info_device_info.available
70 
71  async def async_added_to_hass(self) -> None:
72  """Run when entity is added to register update signal handler."""
73  self.async_on_removeasync_on_remove(
74  self._device_device.add_update_listener(self.async_write_ha_stateasync_write_ha_state)
75  )
76 
77 
79  """Representation of a Temperature Sensor."""
80 
81  _attr_device_class = SensorDeviceClass.TEMPERATURE
82  _attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS
83 
84  @property
85  def native_value(self) -> float:
86  """Return the state of the sensor."""
87  trait: TemperatureTrait = self._device_device.traits[TemperatureTrait.NAME]
88  # Round for display purposes because the API returns 5 decimal places.
89  # This can be removed if the SDM API issue is fixed, or a frontend
90  # display fix is added for all integrations.
91  return float(round(trait.ambient_temperature_celsius, 1))
92 
93 
95  """Representation of a Humidity Sensor."""
96 
97  _attr_device_class = SensorDeviceClass.HUMIDITY
98  _attr_native_unit_of_measurement = PERCENTAGE
99 
100  @property
101  def native_value(self) -> int:
102  """Return the state of the sensor."""
103  trait: HumidityTrait = self._device_device.traits[HumidityTrait.NAME]
104  # Cast without loss of precision because the API always returns an integer.
105  return int(trait.ambient_humidity_percent)
None __init__(self, Device device)
Definition: sensor.py:59
None async_on_remove(self, CALLBACK_TYPE func)
Definition: entity.py:1331
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:37