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