Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Support for Lektrico charging station sensors."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Callable
6 from dataclasses import dataclass
7 from typing import Any
8 
9 from lektricowifi import Device
10 
12  SensorDeviceClass,
13  SensorEntity,
14  SensorEntityDescription,
15  SensorStateClass,
16 )
17 from homeassistant.const import (
18  ATTR_SERIAL_NUMBER,
19  CONF_TYPE,
20  PERCENTAGE,
21  UnitOfElectricCurrent,
22  UnitOfElectricPotential,
23  UnitOfEnergy,
24  UnitOfPower,
25  UnitOfTemperature,
26  UnitOfTime,
27 )
28 from homeassistant.core import HomeAssistant
29 from homeassistant.exceptions import IntegrationError
30 from homeassistant.helpers.entity_platform import AddEntitiesCallback
31 from homeassistant.helpers.typing import StateType
32 
33 from . import LektricoConfigEntry, LektricoDeviceDataUpdateCoordinator
34 from .entity import LektricoEntity
35 
36 
37 @dataclass(frozen=True, kw_only=True)
39  """A class that describes the Lektrico sensor entities."""
40 
41  value_fn: Callable[[dict[str, Any]], StateType]
42 
43 
44 LIMIT_REASON_OPTIONS = [
45  "no_limit",
46  "installation_current",
47  "user_limit",
48  "dynamic_limit",
49  "schedule",
50  "em_offline",
51  "em",
52  "ocpp",
53  "overtemperature",
54  "switching_phases",
55  "1p_charging_disabled",
56 ]
57 
58 
59 SENSORS_FOR_CHARGERS: tuple[LektricoSensorEntityDescription, ...] = (
61  key="state",
62  device_class=SensorDeviceClass.ENUM,
63  options=[
64  "available",
65  "charging",
66  "connected",
67  "error",
68  "locked",
69  "need_auth",
70  "paused",
71  "paused_by_scheduler",
72  "updating_firmware",
73  ],
74  translation_key="state",
75  value_fn=lambda data: str(data["charger_state"]),
76  ),
78  key="charging_time",
79  translation_key="charging_time",
80  device_class=SensorDeviceClass.DURATION,
81  native_unit_of_measurement=UnitOfTime.SECONDS,
82  value_fn=lambda data: int(data["charging_time"]),
83  ),
85  key="power",
86  device_class=SensorDeviceClass.POWER,
87  state_class=SensorStateClass.MEASUREMENT,
88  native_unit_of_measurement=UnitOfPower.WATT,
89  suggested_unit_of_measurement=UnitOfPower.KILO_WATT,
90  value_fn=lambda data: float(data["instant_power"]),
91  ),
93  key="energy",
94  device_class=SensorDeviceClass.ENERGY,
95  native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
96  value_fn=lambda data: float(data["session_energy"]) / 1000,
97  ),
99  key="temperature",
100  device_class=SensorDeviceClass.TEMPERATURE,
101  state_class=SensorStateClass.MEASUREMENT,
102  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
103  value_fn=lambda data: float(data["temperature"]),
104  ),
106  key="lifetime_energy",
107  translation_key="lifetime_energy",
108  state_class=SensorStateClass.TOTAL_INCREASING,
109  device_class=SensorDeviceClass.ENERGY,
110  native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
111  value_fn=lambda data: int(data["total_charged_energy"]),
112  ),
114  key="installation_current",
115  translation_key="installation_current",
116  device_class=SensorDeviceClass.CURRENT,
117  native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
118  value_fn=lambda data: int(data["install_current"]),
119  ),
121  key="limit_reason",
122  translation_key="limit_reason",
123  device_class=SensorDeviceClass.ENUM,
124  options=LIMIT_REASON_OPTIONS,
125  value_fn=lambda data: (
126  str(data["current_limit_reason"])
127  if str(data["current_limit_reason"]) in LIMIT_REASON_OPTIONS
128  else None
129  ),
130  ),
131 )
132 
133 SENSORS_FOR_LB_DEVICES: tuple[LektricoSensorEntityDescription, ...] = (
135  key="breaker_current",
136  translation_key="breaker_current",
137  device_class=SensorDeviceClass.CURRENT,
138  state_class=SensorStateClass.MEASUREMENT,
139  native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
140  value_fn=lambda data: int(data["breaker_curent"]),
141  ),
142 )
143 
144 SENSORS_FOR_1_PHASE: tuple[LektricoSensorEntityDescription, ...] = (
146  key="voltage",
147  device_class=SensorDeviceClass.VOLTAGE,
148  native_unit_of_measurement=UnitOfElectricPotential.VOLT,
149  value_fn=lambda data: float(data["voltage_l1"]),
150  ),
152  key="current",
153  device_class=SensorDeviceClass.CURRENT,
154  state_class=SensorStateClass.MEASUREMENT,
155  native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
156  value_fn=lambda data: float(data["current_l1"]),
157  ),
158 )
159 
160 SENSORS_FOR_3_PHASE: tuple[LektricoSensorEntityDescription, ...] = (
162  key="voltage_l1",
163  translation_key="voltage_l1",
164  device_class=SensorDeviceClass.VOLTAGE,
165  native_unit_of_measurement=UnitOfElectricPotential.VOLT,
166  value_fn=lambda data: float(data["voltage_l1"]),
167  ),
169  key="voltage_l2",
170  translation_key="voltage_l2",
171  device_class=SensorDeviceClass.VOLTAGE,
172  native_unit_of_measurement=UnitOfElectricPotential.VOLT,
173  value_fn=lambda data: float(data["voltage_l2"]),
174  ),
176  key="voltage_l3",
177  translation_key="voltage_l3",
178  device_class=SensorDeviceClass.VOLTAGE,
179  native_unit_of_measurement=UnitOfElectricPotential.VOLT,
180  value_fn=lambda data: float(data["voltage_l3"]),
181  ),
183  key="current_l1",
184  translation_key="current_l1",
185  device_class=SensorDeviceClass.CURRENT,
186  state_class=SensorStateClass.MEASUREMENT,
187  native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
188  value_fn=lambda data: float(data["current_l1"]),
189  ),
191  key="current_l2",
192  translation_key="current_l2",
193  device_class=SensorDeviceClass.CURRENT,
194  state_class=SensorStateClass.MEASUREMENT,
195  native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
196  value_fn=lambda data: float(data["current_l2"]),
197  ),
199  key="current_l3",
200  translation_key="current_l3",
201  device_class=SensorDeviceClass.CURRENT,
202  state_class=SensorStateClass.MEASUREMENT,
203  native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
204  value_fn=lambda data: float(data["current_l3"]),
205  ),
206 )
207 
208 
209 SENSORS_FOR_LB_1_PHASE: tuple[LektricoSensorEntityDescription, ...] = (
211  key="power",
212  device_class=SensorDeviceClass.POWER,
213  state_class=SensorStateClass.MEASUREMENT,
214  native_unit_of_measurement=UnitOfPower.WATT,
215  suggested_unit_of_measurement=UnitOfPower.KILO_WATT,
216  value_fn=lambda data: float(data["power_l1"]),
217  ),
219  key="pf",
220  device_class=SensorDeviceClass.POWER_FACTOR,
221  state_class=SensorStateClass.MEASUREMENT,
222  native_unit_of_measurement=PERCENTAGE,
223  value_fn=lambda data: float(data["power_factor_l1"]) * 100,
224  ),
225 )
226 
227 
228 SENSORS_FOR_LB_3_PHASE: tuple[LektricoSensorEntityDescription, ...] = (
230  key="power_l1",
231  translation_key="power_l1",
232  device_class=SensorDeviceClass.POWER,
233  state_class=SensorStateClass.MEASUREMENT,
234  native_unit_of_measurement=UnitOfPower.WATT,
235  suggested_unit_of_measurement=UnitOfPower.KILO_WATT,
236  value_fn=lambda data: float(data["power_l1"]),
237  ),
239  key="power_l2",
240  translation_key="power_l2",
241  device_class=SensorDeviceClass.POWER,
242  state_class=SensorStateClass.MEASUREMENT,
243  native_unit_of_measurement=UnitOfPower.WATT,
244  suggested_unit_of_measurement=UnitOfPower.KILO_WATT,
245  value_fn=lambda data: float(data["power_l2"]),
246  ),
248  key="power_l3",
249  translation_key="power_l3",
250  device_class=SensorDeviceClass.POWER,
251  state_class=SensorStateClass.MEASUREMENT,
252  native_unit_of_measurement=UnitOfPower.WATT,
253  suggested_unit_of_measurement=UnitOfPower.KILO_WATT,
254  value_fn=lambda data: float(data["power_l3"]),
255  ),
257  key="pf_l1",
258  translation_key="pf_l1",
259  device_class=SensorDeviceClass.POWER_FACTOR,
260  state_class=SensorStateClass.MEASUREMENT,
261  native_unit_of_measurement=PERCENTAGE,
262  value_fn=lambda data: float(data["power_factor_l1"]) * 100,
263  ),
265  key="pf_l2",
266  translation_key="pf_l2",
267  device_class=SensorDeviceClass.POWER_FACTOR,
268  state_class=SensorStateClass.MEASUREMENT,
269  native_unit_of_measurement=PERCENTAGE,
270  value_fn=lambda data: float(data["power_factor_l2"]) * 100,
271  ),
273  key="pf_l3",
274  translation_key="pf_l3",
275  device_class=SensorDeviceClass.POWER_FACTOR,
276  state_class=SensorStateClass.MEASUREMENT,
277  native_unit_of_measurement=PERCENTAGE,
278  value_fn=lambda data: float(data["power_factor_l3"]) * 100,
279  ),
280 )
281 
282 
284  hass: HomeAssistant,
285  entry: LektricoConfigEntry,
286  async_add_entities: AddEntitiesCallback,
287 ) -> None:
288  """Set up Lektrico charger based on a config entry."""
289  coordinator = entry.runtime_data
290 
291  sensors_to_be_used: tuple[LektricoSensorEntityDescription, ...]
292  if coordinator.device_type == Device.TYPE_1P7K:
293  sensors_to_be_used = SENSORS_FOR_CHARGERS + SENSORS_FOR_1_PHASE
294  elif coordinator.device_type == Device.TYPE_3P22K:
295  sensors_to_be_used = SENSORS_FOR_CHARGERS + SENSORS_FOR_3_PHASE
296  elif coordinator.device_type == Device.TYPE_EM:
297  sensors_to_be_used = (
298  SENSORS_FOR_LB_DEVICES + SENSORS_FOR_1_PHASE + SENSORS_FOR_LB_1_PHASE
299  )
300  elif coordinator.device_type == Device.TYPE_3EM:
301  sensors_to_be_used = (
302  SENSORS_FOR_LB_DEVICES + SENSORS_FOR_3_PHASE + SENSORS_FOR_LB_3_PHASE
303  )
304  else:
305  raise IntegrationError
306 
309  description,
310  coordinator,
311  f"{entry.data[CONF_TYPE]}_{entry.data[ATTR_SERIAL_NUMBER]}",
312  )
313  for description in sensors_to_be_used
314  )
315 
316 
318  """The entity class for Lektrico charging stations sensors."""
319 
320  entity_description: LektricoSensorEntityDescription
321 
322  def __init__(
323  self,
324  description: LektricoSensorEntityDescription,
325  coordinator: LektricoDeviceDataUpdateCoordinator,
326  device_name: str,
327  ) -> None:
328  """Initialize Lektrico charger."""
329  super().__init__(coordinator, device_name)
330  self.entity_descriptionentity_description = description
331  self._attr_unique_id_attr_unique_id = f"{coordinator.serial_number}_{description.key}"
332 
333  @property
334  def native_value(self) -> StateType:
335  """Return the state of the sensor."""
336  return self.entity_descriptionentity_description.value_fn(self.coordinator.data)
None __init__(self, LektricoSensorEntityDescription description, LektricoDeviceDataUpdateCoordinator coordinator, str device_name)
Definition: sensor.py:327
None async_setup_entry(HomeAssistant hass, LektricoConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:287