Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Support for govee ble sensors."""
2 
3 from __future__ import annotations
4 
5 from datetime import date, datetime
6 from decimal import Decimal
7 
8 from govee_ble import DeviceClass, SensorUpdate, Units
9 from govee_ble.parser import ERROR
10 
12  PassiveBluetoothDataProcessor,
13  PassiveBluetoothDataUpdate,
14  PassiveBluetoothProcessorEntity,
15 )
17  SensorDeviceClass,
18  SensorEntity,
19  SensorEntityDescription,
20  SensorStateClass,
21 )
22 from homeassistant.const import (
23  CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
24  PERCENTAGE,
25  SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
26  UnitOfTemperature,
27 )
28 from homeassistant.core import HomeAssistant
29 from homeassistant.helpers.entity_platform import AddEntitiesCallback
30 from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info
31 
32 from .coordinator import GoveeBLEConfigEntry, GoveeBLEPassiveBluetoothDataProcessor
33 from .device import device_key_to_bluetooth_entity_key
34 
35 type _SensorValueType = str | int | float | date | datetime | Decimal | None
36 
37 SENSOR_DESCRIPTIONS = {
38  (DeviceClass.TEMPERATURE, Units.TEMP_CELSIUS): SensorEntityDescription(
39  key=f"{DeviceClass.TEMPERATURE}_{Units.TEMP_CELSIUS}",
40  device_class=SensorDeviceClass.TEMPERATURE,
41  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
42  state_class=SensorStateClass.MEASUREMENT,
43  ),
44  (DeviceClass.HUMIDITY, Units.PERCENTAGE): SensorEntityDescription(
45  key=f"{DeviceClass.HUMIDITY}_{Units.PERCENTAGE}",
46  device_class=SensorDeviceClass.HUMIDITY,
47  native_unit_of_measurement=PERCENTAGE,
48  state_class=SensorStateClass.MEASUREMENT,
49  ),
50  (DeviceClass.BATTERY, Units.PERCENTAGE): SensorEntityDescription(
51  key=f"{DeviceClass.BATTERY}_{Units.PERCENTAGE}",
52  device_class=SensorDeviceClass.BATTERY,
53  native_unit_of_measurement=PERCENTAGE,
54  state_class=SensorStateClass.MEASUREMENT,
55  ),
56  (
57  DeviceClass.SIGNAL_STRENGTH,
58  Units.SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
60  key=f"{DeviceClass.SIGNAL_STRENGTH}_{Units.SIGNAL_STRENGTH_DECIBELS_MILLIWATT}",
61  device_class=SensorDeviceClass.SIGNAL_STRENGTH,
62  native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
63  state_class=SensorStateClass.MEASUREMENT,
64  entity_registry_enabled_default=False,
65  ),
66  (
67  DeviceClass.PM25,
68  Units.CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
70  key=f"{DeviceClass.PM25}_{Units.CONCENTRATION_MICROGRAMS_PER_CUBIC_METER}",
71  device_class=SensorDeviceClass.PM25,
72  native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
73  state_class=SensorStateClass.MEASUREMENT,
74  ),
75 }
76 
77 
79  sensor_update: SensorUpdate,
80 ) -> PassiveBluetoothDataUpdate[_SensorValueType]:
81  """Convert a sensor update to a bluetooth data update."""
83  devices={
84  device_id: sensor_device_info_to_hass_device_info(device_info)
85  for device_id, device_info in sensor_update.devices.items()
86  },
87  entity_descriptions={
88  device_key_to_bluetooth_entity_key(device_key): SENSOR_DESCRIPTIONS[
89  (description.device_class, description.native_unit_of_measurement)
90  ]
91  for device_key, description in sensor_update.entity_descriptions.items()
92  if description.device_class and description.native_unit_of_measurement
93  },
94  entity_data={
95  device_key_to_bluetooth_entity_key(device_key): sensor_values.native_value
96  for device_key, sensor_values in sensor_update.entity_values.items()
97  },
98  entity_names={
99  device_key_to_bluetooth_entity_key(device_key): sensor_values.name
100  for device_key, sensor_values in sensor_update.entity_values.items()
101  },
102  )
103 
104 
106  hass: HomeAssistant,
107  entry: GoveeBLEConfigEntry,
108  async_add_entities: AddEntitiesCallback,
109 ) -> None:
110  """Set up the Govee BLE sensors."""
111  coordinator = entry.runtime_data
112  processor = PassiveBluetoothDataProcessor(sensor_update_to_bluetooth_data_update)
113  entry.async_on_unload(
114  processor.async_add_entities_listener(
115  GoveeBluetoothSensorEntity, async_add_entities
116  )
117  )
118  entry.async_on_unload(
119  coordinator.async_register_processor(processor, SensorEntityDescription)
120  )
121 
122 
124  PassiveBluetoothProcessorEntity[
125  PassiveBluetoothDataProcessor[_SensorValueType, SensorUpdate]
126  ],
127  SensorEntity,
128 ):
129  """Representation of a govee ble sensor."""
130 
131  processor: GoveeBLEPassiveBluetoothDataProcessor[_SensorValueType]
132 
133  @property
134  def available(self) -> bool:
135  """Return False if sensor is in error."""
136  coordinator = self.processor.coordinator
137  return self.processor.entity_data.get(self.entity_key) != ERROR and (
138  ((model_info := coordinator.model_info) and model_info.sleepy)
139  or super().available
140  )
141 
142  @property
143  def native_value(self) -> _SensorValueType: # pylint: disable=hass-return-type
144  """Return the native value."""
145  return self.processor.entity_data.get(self.entity_key)
PassiveBluetoothEntityKey device_key_to_bluetooth_entity_key(DeviceKey device_key)
Definition: device.py:14
PassiveBluetoothDataUpdate[_SensorValueType] sensor_update_to_bluetooth_data_update(SensorUpdate sensor_update)
Definition: sensor.py:80
None async_setup_entry(HomeAssistant hass, GoveeBLEConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:109
DeviceInfo sensor_device_info_to_hass_device_info(SensorDeviceInfo sensor_device_info)
Definition: sensor.py:20