Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Sensor platform for Acaia."""
2 
3 from collections.abc import Callable
4 from dataclasses import dataclass
5 
6 from aioacaia.acaiascale import AcaiaDeviceState, AcaiaScale
7 from aioacaia.const import UnitMass as AcaiaUnitOfMass
8 
10  RestoreSensor,
11  SensorDeviceClass,
12  SensorEntity,
13  SensorEntityDescription,
14  SensorExtraStoredData,
15  SensorStateClass,
16 )
17 from homeassistant.const import PERCENTAGE, UnitOfMass, UnitOfVolumeFlowRate
18 from homeassistant.core import HomeAssistant, callback
19 from homeassistant.helpers.entity_platform import AddEntitiesCallback
20 
21 from .coordinator import AcaiaConfigEntry
22 from .entity import AcaiaEntity
23 
24 
25 @dataclass(kw_only=True, frozen=True)
27  """Description for Acaia sensor entities."""
28 
29  value_fn: Callable[[AcaiaScale], int | float | None]
30 
31 
32 @dataclass(kw_only=True, frozen=True)
34  """Description for Acaia sensor entities with dynamic units."""
35 
36  unit_fn: Callable[[AcaiaDeviceState], str] | None = None
37 
38 
39 SENSORS: tuple[AcaiaSensorEntityDescription, ...] = (
41  key="weight",
42  device_class=SensorDeviceClass.WEIGHT,
43  native_unit_of_measurement=UnitOfMass.GRAMS,
44  state_class=SensorStateClass.MEASUREMENT,
45  unit_fn=lambda data: (
46  UnitOfMass.OUNCES
47  if data.units == AcaiaUnitOfMass.OUNCES
48  else UnitOfMass.GRAMS
49  ),
50  value_fn=lambda scale: scale.weight,
51  ),
53  key="flow_rate",
54  device_class=SensorDeviceClass.VOLUME_FLOW_RATE,
55  native_unit_of_measurement=UnitOfVolumeFlowRate.MILLILITERS_PER_SECOND,
56  suggested_display_precision=1,
57  state_class=SensorStateClass.MEASUREMENT,
58  value_fn=lambda scale: scale.flow_rate,
59  ),
60 )
61 RESTORE_SENSORS: tuple[AcaiaSensorEntityDescription, ...] = (
63  key="battery",
64  device_class=SensorDeviceClass.BATTERY,
65  native_unit_of_measurement=PERCENTAGE,
66  state_class=SensorStateClass.MEASUREMENT,
67  value_fn=lambda scale: (
68  scale.device_state.battery_level if scale.device_state else None
69  ),
70  ),
71 )
72 
73 
75  hass: HomeAssistant,
76  entry: AcaiaConfigEntry,
77  async_add_entities: AddEntitiesCallback,
78 ) -> None:
79  """Set up sensors."""
80 
81  coordinator = entry.runtime_data
82  entities: list[SensorEntity] = [
83  AcaiaSensor(coordinator, entity_description) for entity_description in SENSORS
84  ]
85  entities.extend(
86  AcaiaRestoreSensor(coordinator, entity_description)
87  for entity_description in RESTORE_SENSORS
88  )
89  async_add_entities(entities)
90 
91 
93  """Representation of an Acaia sensor."""
94 
95  entity_description: AcaiaDynamicUnitSensorEntityDescription
96 
97  @property
98  def native_unit_of_measurement(self) -> str | None:
99  """Return the unit of measurement of this entity."""
100  if (
101  self._scale_scale_scale.device_state is not None
102  and self.entity_descriptionentity_description.unit_fn is not None
103  ):
104  return self.entity_descriptionentity_description.unit_fn(self._scale_scale_scale.device_state)
105  return self.entity_descriptionentity_description.native_unit_of_measurement
106 
107  @property
108  def native_value(self) -> int | float | None:
109  """Return the state of the entity."""
110  return self.entity_descriptionentity_description.value_fn(self._scale_scale_scale)
111 
112 
114  """Representation of an Acaia sensor with restore capabilities."""
115 
116  entity_description: AcaiaSensorEntityDescription
117  _restored_data: SensorExtraStoredData | None = None
118 
119  async def async_added_to_hass(self) -> None:
120  """Handle entity which will be added."""
121  await super().async_added_to_hass()
122 
123  self._restored_data_restored_data = await self.async_get_last_sensor_dataasync_get_last_sensor_data()
124  if self._restored_data_restored_data is not None:
125  self._attr_native_value_attr_native_value = self._restored_data_restored_data.native_value
126  self._attr_native_unit_of_measurement_attr_native_unit_of_measurement = (
127  self._restored_data_restored_data.native_unit_of_measurement
128  )
129 
130  if self._scale_scale_scale.device_state is not None:
131  self._attr_native_value_attr_native_value = self.entity_descriptionentity_description.value_fn(self._scale_scale_scale)
132 
133  @callback
134  def _handle_coordinator_update(self) -> None:
135  """Handle updated data from the coordinator."""
136  if self._scale_scale_scale.device_state is not None:
137  self._attr_native_value_attr_native_value = self.entity_descriptionentity_description.value_fn(self._scale_scale_scale)
138  self._async_write_ha_state_async_write_ha_state()
139 
140  @property
141  def available(self) -> bool:
142  """Return True if entity is available."""
143  return super().available or self._restored_data_restored_data is not None
SensorExtraStoredData|None async_get_last_sensor_data(self)
Definition: __init__.py:934
None async_setup_entry(HomeAssistant hass, AcaiaConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:78