Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Support for OralB sensors."""
2 
3 from __future__ import annotations
4 
5 from oralb_ble import OralBSensor, SensorUpdate
6 
8  PassiveBluetoothDataProcessor,
9  PassiveBluetoothDataUpdate,
10  PassiveBluetoothProcessorEntity,
11 )
13  SensorDeviceClass,
14  SensorEntity,
15  SensorEntityDescription,
16  SensorStateClass,
17 )
18 from homeassistant.const import (
19  PERCENTAGE,
20  SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
21  EntityCategory,
22  UnitOfTime,
23 )
24 from homeassistant.core import HomeAssistant
25 from homeassistant.helpers.entity_platform import AddEntitiesCallback
26 from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info
27 
28 from . import OralBConfigEntry
29 from .device import device_key_to_bluetooth_entity_key
30 
31 SENSOR_DESCRIPTIONS: dict[str, SensorEntityDescription] = {
32  OralBSensor.TIME: SensorEntityDescription(
33  key=OralBSensor.TIME,
34  device_class=SensorDeviceClass.DURATION,
35  state_class=SensorStateClass.TOTAL_INCREASING,
36  native_unit_of_measurement=UnitOfTime.SECONDS,
37  ),
38  OralBSensor.SECTOR: SensorEntityDescription(
39  key=OralBSensor.SECTOR,
40  translation_key="sector",
41  entity_category=EntityCategory.DIAGNOSTIC,
42  ),
43  OralBSensor.NUMBER_OF_SECTORS: SensorEntityDescription(
44  key=OralBSensor.NUMBER_OF_SECTORS,
45  translation_key="number_of_sectors",
46  entity_category=EntityCategory.DIAGNOSTIC,
47  ),
48  OralBSensor.SECTOR_TIMER: SensorEntityDescription(
49  key=OralBSensor.SECTOR_TIMER,
50  translation_key="sector_timer",
51  entity_category=EntityCategory.DIAGNOSTIC,
52  entity_registry_enabled_default=False,
53  ),
54  OralBSensor.TOOTHBRUSH_STATE: SensorEntityDescription(
55  key=OralBSensor.TOOTHBRUSH_STATE,
56  name=None,
57  ),
58  OralBSensor.PRESSURE: SensorEntityDescription(
59  key=OralBSensor.PRESSURE,
60  translation_key="pressure",
61  ),
62  OralBSensor.MODE: SensorEntityDescription(
63  key=OralBSensor.MODE,
64  translation_key="mode",
65  entity_category=EntityCategory.DIAGNOSTIC,
66  ),
67  OralBSensor.SIGNAL_STRENGTH: SensorEntityDescription(
68  key=OralBSensor.SIGNAL_STRENGTH,
69  device_class=SensorDeviceClass.SIGNAL_STRENGTH,
70  native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
71  state_class=SensorStateClass.MEASUREMENT,
72  entity_category=EntityCategory.DIAGNOSTIC,
73  entity_registry_enabled_default=False,
74  ),
75  OralBSensor.BATTERY_PERCENT: SensorEntityDescription(
76  key=OralBSensor.BATTERY_PERCENT,
77  device_class=SensorDeviceClass.BATTERY,
78  native_unit_of_measurement=PERCENTAGE,
79  state_class=SensorStateClass.MEASUREMENT,
80  entity_category=EntityCategory.DIAGNOSTIC,
81  ),
82 }
83 
84 
86  sensor_update: SensorUpdate,
87 ) -> PassiveBluetoothDataUpdate:
88  """Convert a sensor update to a bluetooth data update."""
90  devices={
91  device_id: sensor_device_info_to_hass_device_info(device_info)
92  for device_id, device_info in sensor_update.devices.items()
93  },
94  entity_descriptions={
95  device_key_to_bluetooth_entity_key(device_key): SENSOR_DESCRIPTIONS[
96  device_key.key
97  ]
98  for device_key in sensor_update.entity_descriptions
99  },
100  entity_data={
101  device_key_to_bluetooth_entity_key(device_key): sensor_values.native_value
102  for device_key, sensor_values in sensor_update.entity_values.items()
103  },
104  entity_names={},
105  )
106 
107 
109  hass: HomeAssistant,
110  entry: OralBConfigEntry,
111  async_add_entities: AddEntitiesCallback,
112 ) -> None:
113  """Set up the OralB BLE sensors."""
114  coordinator = entry.runtime_data
115  processor = PassiveBluetoothDataProcessor(sensor_update_to_bluetooth_data_update)
116  entry.async_on_unload(
117  processor.async_add_entities_listener(
118  OralBBluetoothSensorEntity, async_add_entities
119  )
120  )
121  entry.async_on_unload(
122  coordinator.async_register_processor(processor, SensorEntityDescription)
123  )
124 
125 
127  PassiveBluetoothProcessorEntity[
128  PassiveBluetoothDataProcessor[str | int | None, SensorUpdate]
129  ],
130  SensorEntity,
131 ):
132  """Representation of a OralB sensor."""
133 
134  @property
135  def native_value(self) -> str | int | None:
136  """Return the native value."""
137  return self.processor.entity_data.get(self.entity_key)
138 
139  @property
140  def available(self) -> bool:
141  """Return True if entity is available.
142 
143  The sensor is only created when the device is seen.
144 
145  Since these are sleepy devices which stop broadcasting
146  when not in use, we can't rely on the last update time
147  so once we have seen the device we always return True.
148  """
149  return True
150 
151  @property
152  def assumed_state(self) -> bool:
153  """Return True if the device is no longer broadcasting."""
154  return not self.processor.available
PassiveBluetoothEntityKey device_key_to_bluetooth_entity_key(DeviceKey device_key)
Definition: device.py:14
None async_setup_entry(HomeAssistant hass, OralBConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:112
PassiveBluetoothDataUpdate sensor_update_to_bluetooth_data_update(SensorUpdate sensor_update)
Definition: sensor.py:87
DeviceInfo sensor_device_info_to_hass_device_info(SensorDeviceInfo sensor_device_info)
Definition: sensor.py:20