Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Support for Blink system camera sensors."""
2 
3 from __future__ import annotations
4 
5 import logging
6 
8  SensorDeviceClass,
9  SensorEntity,
10  SensorEntityDescription,
11  SensorStateClass,
12 )
13 from homeassistant.const import (
14  SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
15  EntityCategory,
16  UnitOfTemperature,
17 )
18 from homeassistant.core import HomeAssistant, callback
19 from homeassistant.helpers.device_registry import DeviceInfo
20 from homeassistant.helpers.entity_platform import AddEntitiesCallback
21 from homeassistant.helpers.update_coordinator import CoordinatorEntity
22 
23 from .const import DEFAULT_BRAND, DOMAIN, TYPE_TEMPERATURE, TYPE_WIFI_STRENGTH
24 from .coordinator import BlinkConfigEntry, BlinkUpdateCoordinator
25 
26 _LOGGER = logging.getLogger(__name__)
27 
28 SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
30  key=TYPE_TEMPERATURE,
31  native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
32  device_class=SensorDeviceClass.TEMPERATURE,
33  entity_category=EntityCategory.DIAGNOSTIC,
34  state_class=SensorStateClass.MEASUREMENT,
35  ),
37  key=TYPE_WIFI_STRENGTH,
38  translation_key="wifi_strength",
39  native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
40  device_class=SensorDeviceClass.SIGNAL_STRENGTH,
41  entity_category=EntityCategory.DIAGNOSTIC,
42  state_class=SensorStateClass.MEASUREMENT,
43  ),
44 )
45 
46 
48  hass: HomeAssistant,
49  config_entry: BlinkConfigEntry,
50  async_add_entities: AddEntitiesCallback,
51 ) -> None:
52  """Initialize a Blink sensor."""
53 
54  coordinator = config_entry.runtime_data
55  entities = [
56  BlinkSensor(coordinator, camera, description)
57  for camera in coordinator.api.cameras
58  for description in SENSOR_TYPES
59  ]
60 
61  async_add_entities(entities)
62 
63 
64 class BlinkSensor(CoordinatorEntity[BlinkUpdateCoordinator], SensorEntity):
65  """A Blink camera sensor."""
66 
67  _attr_has_entity_name = True
68 
69  def __init__(
70  self,
71  coordinator: BlinkUpdateCoordinator,
72  camera,
73  description: SensorEntityDescription,
74  ) -> None:
75  """Initialize sensors from Blink camera."""
76  super().__init__(coordinator)
77  self.entity_descriptionentity_description = description
78 
79  self._camera_camera = coordinator.api.cameras[camera]
80  serial = self._camera_camera.serial
81  self._attr_unique_id_attr_unique_id = f"{serial}-{description.key}"
82  self._sensor_key_sensor_key = (
83  "temperature_calibrated"
84  if description.key == "temperature"
85  else description.key
86  )
87  self._attr_device_info_attr_device_info = DeviceInfo(
88  identifiers={(DOMAIN, serial)},
89  serial_number=serial,
90  name=f"{DOMAIN} {camera}",
91  manufacturer=DEFAULT_BRAND,
92  model=self._camera_camera.camera_type,
93  )
94  self._update_attr_update_attr()
95 
96  @callback
97  def _handle_coordinator_update(self) -> None:
98  """Handle coordinator update."""
99  self._update_attr_update_attr()
101 
102  @callback
103  def _update_attr(self) -> None:
104  """Update attributes for sensor."""
105  try:
106  self._attr_native_value_attr_native_value = self._camera_camera.attributes[self._sensor_key_sensor_key]
107  _LOGGER.debug(
108  "'%s' %s = %s",
109  self._camera_camera.attributes["name"],
110  self._sensor_key_sensor_key,
111  self._attr_native_value_attr_native_value,
112  )
113  except KeyError:
114  self._attr_native_value_attr_native_value = None
115  _LOGGER.error(
116  "%s not a valid camera attribute. Did the API change?", self._sensor_key_sensor_key
117  )