Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Support for mill wifi-enabled home heaters."""
2 
3 from __future__ import annotations
4 
5 import mill
6 
8  SensorDeviceClass,
9  SensorEntity,
10  SensorEntityDescription,
11  SensorStateClass,
12 )
13 from homeassistant.config_entries import ConfigEntry
14 from homeassistant.const import (
15  CONCENTRATION_PARTS_PER_BILLION,
16  CONCENTRATION_PARTS_PER_MILLION,
17  CONF_IP_ADDRESS,
18  CONF_USERNAME,
19  PERCENTAGE,
20  EntityCategory,
21  UnitOfEnergy,
22  UnitOfPower,
23  UnitOfTemperature,
24 )
25 from homeassistant.core import HomeAssistant, callback
26 from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo
27 from homeassistant.helpers.entity_platform import AddEntitiesCallback
28 from homeassistant.helpers.update_coordinator import CoordinatorEntity
29 
30 from .const import (
31  BATTERY,
32  CLOUD,
33  CONNECTION_TYPE,
34  CONSUMPTION_TODAY,
35  CONSUMPTION_YEAR,
36  DOMAIN,
37  ECO2,
38  HUMIDITY,
39  LOCAL,
40  MANUFACTURER,
41  TEMPERATURE,
42  TVOC,
43 )
44 
45 HEATER_SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
47  key=CONSUMPTION_YEAR,
48  translation_key="year_consumption",
49  device_class=SensorDeviceClass.ENERGY,
50  native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
51  state_class=SensorStateClass.TOTAL_INCREASING,
52  ),
54  key=CONSUMPTION_TODAY,
55  translation_key="day_consumption",
56  device_class=SensorDeviceClass.ENERGY,
57  native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
58  state_class=SensorStateClass.TOTAL_INCREASING,
59  ),
61  key="current_power",
62  translation_key="current_power",
63  device_class=SensorDeviceClass.POWER,
64  native_unit_of_measurement=UnitOfPower.WATT,
65  state_class=SensorStateClass.MEASUREMENT,
66  ),
68  key="control_signal",
69  translation_key="control_signal",
70  native_unit_of_measurement=PERCENTAGE,
71  state_class=SensorStateClass.MEASUREMENT,
72  ),
73 )
74 
75 SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
77  key=TEMPERATURE,
78  device_class=SensorDeviceClass.TEMPERATURE,
79  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
80  state_class=SensorStateClass.MEASUREMENT,
81  ),
83  key=HUMIDITY,
84  device_class=SensorDeviceClass.HUMIDITY,
85  native_unit_of_measurement=PERCENTAGE,
86  state_class=SensorStateClass.MEASUREMENT,
87  ),
89  key=BATTERY,
90  device_class=SensorDeviceClass.BATTERY,
91  native_unit_of_measurement=PERCENTAGE,
92  state_class=SensorStateClass.MEASUREMENT,
93  entity_category=EntityCategory.DIAGNOSTIC,
94  ),
96  key=ECO2,
97  device_class=SensorDeviceClass.CO2,
98  native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
99  translation_key="estimated_co2",
100  state_class=SensorStateClass.MEASUREMENT,
101  ),
103  key=TVOC,
104  native_unit_of_measurement=CONCENTRATION_PARTS_PER_BILLION,
105  translation_key="tvoc",
106  state_class=SensorStateClass.MEASUREMENT,
107  ),
108 )
109 
110 LOCAL_SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
112  key="control_signal",
113  translation_key="control_signal",
114  native_unit_of_measurement=PERCENTAGE,
115  state_class=SensorStateClass.MEASUREMENT,
116  ),
118  key="current_power",
119  translation_key="current_power",
120  device_class=SensorDeviceClass.POWER,
121  native_unit_of_measurement=UnitOfPower.WATT,
122  state_class=SensorStateClass.MEASUREMENT,
123  ),
125  key="raw_ambient_temperature",
126  translation_key="uncalibrated_temperature",
127  device_class=SensorDeviceClass.TEMPERATURE,
128  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
129  state_class=SensorStateClass.MEASUREMENT,
130  entity_registry_enabled_default=False,
131  ),
132 )
133 
134 SOCKET_SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
136  key=HUMIDITY,
137  device_class=SensorDeviceClass.HUMIDITY,
138  native_unit_of_measurement=PERCENTAGE,
139  state_class=SensorStateClass.MEASUREMENT,
140  ),
141  *HEATER_SENSOR_TYPES,
142 )
143 
144 
146  hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
147 ) -> None:
148  """Set up the Mill sensor."""
149  if entry.data.get(CONNECTION_TYPE) == LOCAL:
150  mill_data_coordinator = hass.data[DOMAIN][LOCAL][entry.data[CONF_IP_ADDRESS]]
151 
154  mill_data_coordinator,
155  entity_description,
156  )
157  for entity_description in LOCAL_SENSOR_TYPES
158  )
159  return
160 
161  mill_data_coordinator = hass.data[DOMAIN][CLOUD][entry.data[CONF_USERNAME]]
162 
163  entities = [
164  MillSensor(
165  mill_data_coordinator,
166  entity_description,
167  mill_device,
168  )
169  for mill_device in mill_data_coordinator.data.values()
170  for entity_description in (
171  SOCKET_SENSOR_TYPES
172  if isinstance(mill_device, mill.Socket)
173  else HEATER_SENSOR_TYPES
174  if isinstance(mill_device, mill.Heater)
175  else SENSOR_TYPES
176  )
177  ]
178 
179  async_add_entities(entities)
180 
181 
183  """Representation of a Mill Sensor device."""
184 
185  _attr_has_entity_name = True
186 
187  def __init__(self, coordinator, entity_description, mill_device):
188  """Initialize the sensor."""
189  super().__init__(coordinator)
190 
191  self._id_id = mill_device.device_id
192  self.entity_descriptionentity_description = entity_description
193  self._available_available = False
194  self._attr_unique_id_attr_unique_id = f"{mill_device.device_id}_{entity_description.key}"
195  self._attr_device_info_attr_device_info = DeviceInfo(
196  identifiers={(DOMAIN, mill_device.device_id)},
197  name=mill_device.name,
198  manufacturer=MANUFACTURER,
199  model=mill_device.model,
200  )
201  self._update_attr_update_attr(mill_device)
202 
203  @callback
204  def _handle_coordinator_update(self) -> None:
205  """Handle updated data from the coordinator."""
206  self._update_attr_update_attr(self.coordinator.data[self._id_id])
207  self.async_write_ha_stateasync_write_ha_state()
208 
209  @property
210  def available(self) -> bool:
211  """Return True if entity is available."""
212  return super().available and self._available_available
213 
214  @callback
215  def _update_attr(self, device):
216  self._available_available = device.available
217  self._attr_native_value_attr_native_value = getattr(device, self.entity_descriptionentity_description.key)
218 
219 
221  """Representation of a Mill Sensor device."""
222 
223  _attr_has_entity_name = True
224 
225  def __init__(self, coordinator, entity_description):
226  """Initialize the sensor."""
227  super().__init__(coordinator)
228 
229  self.entity_descriptionentity_description = entity_description
230  if mac := coordinator.mill_data_connection.mac_address:
231  self._attr_unique_id_attr_unique_id = f"{mac}_{entity_description.key}"
232  self._attr_device_info_attr_device_info = DeviceInfo(
233  connections={(CONNECTION_NETWORK_MAC, mac)},
234  configuration_url=self.coordinator.mill_data_connection.url,
235  manufacturer=MANUFACTURER,
236  model="Generation 3",
237  name=coordinator.mill_data_connection.name,
238  sw_version=coordinator.mill_data_connection.version,
239  )
240 
241  @property
242  def native_value(self):
243  """Return the native value of the sensor."""
244  return self.coordinator.data[self.entity_descriptionentity_description.key]
def __init__(self, coordinator, entity_description)
Definition: sensor.py:225
def __init__(self, coordinator, entity_description, mill_device)
Definition: sensor.py:187
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:147