Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Support for SolarEdge Monitoring API."""
2 
3 from __future__ import annotations
4 
5 from dataclasses import dataclass
6 from typing import Any
7 
8 from aiosolaredge import SolarEdge
9 
11  SensorDeviceClass,
12  SensorEntity,
13  SensorEntityDescription,
14  SensorStateClass,
15 )
16 from homeassistant.const import PERCENTAGE, UnitOfEnergy, UnitOfPower
17 from homeassistant.core import HomeAssistant
18 from homeassistant.helpers.device_registry import DeviceInfo
19 from homeassistant.helpers.entity_platform import AddEntitiesCallback
21  CoordinatorEntity,
22  DataUpdateCoordinator,
23 )
24 
25 from .const import CONF_SITE_ID, DATA_API_CLIENT, DOMAIN
26 from .coordinator import (
27  SolarEdgeDataService,
28  SolarEdgeDetailsDataService,
29  SolarEdgeEnergyDetailsService,
30  SolarEdgeInventoryDataService,
31  SolarEdgeOverviewDataService,
32  SolarEdgePowerFlowDataService,
33 )
34 from .types import SolarEdgeConfigEntry
35 
36 
37 @dataclass(frozen=True, kw_only=True)
39  """Sensor entity description for SolarEdge."""
40 
41  json_key: str
42 
43 
44 SENSOR_TYPES = [
46  key="lifetime_energy",
47  json_key="lifeTimeData",
48  translation_key="lifetime_energy",
49  state_class=SensorStateClass.TOTAL,
50  native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
51  device_class=SensorDeviceClass.ENERGY,
52  ),
54  key="energy_this_year",
55  json_key="lastYearData",
56  translation_key="energy_this_year",
57  entity_registry_enabled_default=False,
58  native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
59  device_class=SensorDeviceClass.ENERGY,
60  ),
62  key="energy_this_month",
63  json_key="lastMonthData",
64  translation_key="energy_this_month",
65  entity_registry_enabled_default=False,
66  native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
67  device_class=SensorDeviceClass.ENERGY,
68  ),
70  key="energy_today",
71  json_key="lastDayData",
72  translation_key="energy_today",
73  entity_registry_enabled_default=False,
74  native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
75  device_class=SensorDeviceClass.ENERGY,
76  ),
78  key="current_power",
79  json_key="currentPower",
80  translation_key="current_power",
81  state_class=SensorStateClass.MEASUREMENT,
82  native_unit_of_measurement=UnitOfPower.WATT,
83  device_class=SensorDeviceClass.POWER,
84  ),
86  key="site_details",
87  json_key="status",
88  translation_key="site_details",
89  entity_registry_enabled_default=False,
90  ),
92  key="meters",
93  json_key="meters",
94  translation_key="meters",
95  entity_registry_enabled_default=False,
96  ),
98  key="sensors",
99  json_key="sensors",
100  translation_key="sensors",
101  entity_registry_enabled_default=False,
102  ),
104  key="gateways",
105  json_key="gateways",
106  translation_key="gateways",
107  entity_registry_enabled_default=False,
108  ),
110  key="batteries",
111  json_key="batteries",
112  translation_key="batteries",
113  entity_registry_enabled_default=False,
114  ),
116  key="inverters",
117  json_key="inverters",
118  translation_key="inverters",
119  entity_registry_enabled_default=False,
120  ),
122  key="power_consumption",
123  json_key="LOAD",
124  translation_key="power_consumption",
125  entity_registry_enabled_default=False,
126  ),
128  key="solar_power",
129  json_key="PV",
130  translation_key="solar_power",
131  entity_registry_enabled_default=False,
132  ),
134  key="grid_power",
135  json_key="GRID",
136  translation_key="grid_power",
137  entity_registry_enabled_default=False,
138  ),
140  key="storage_power",
141  json_key="STORAGE",
142  translation_key="storage_power",
143  entity_registry_enabled_default=False,
144  ),
146  key="purchased_energy",
147  json_key="Purchased",
148  translation_key="purchased_energy",
149  entity_registry_enabled_default=False,
150  state_class=SensorStateClass.TOTAL_INCREASING,
151  native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
152  device_class=SensorDeviceClass.ENERGY,
153  ),
155  key="production_energy",
156  json_key="Production",
157  translation_key="production_energy",
158  entity_registry_enabled_default=False,
159  state_class=SensorStateClass.TOTAL_INCREASING,
160  native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
161  device_class=SensorDeviceClass.ENERGY,
162  ),
164  key="consumption_energy",
165  json_key="Consumption",
166  translation_key="consumption_energy",
167  entity_registry_enabled_default=False,
168  state_class=SensorStateClass.TOTAL_INCREASING,
169  native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
170  device_class=SensorDeviceClass.ENERGY,
171  ),
173  key="selfconsumption_energy",
174  json_key="SelfConsumption",
175  translation_key="selfconsumption_energy",
176  entity_registry_enabled_default=False,
177  state_class=SensorStateClass.TOTAL_INCREASING,
178  native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
179  device_class=SensorDeviceClass.ENERGY,
180  ),
182  key="feedin_energy",
183  json_key="FeedIn",
184  translation_key="feedin_energy",
185  entity_registry_enabled_default=False,
186  state_class=SensorStateClass.TOTAL_INCREASING,
187  native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
188  device_class=SensorDeviceClass.ENERGY,
189  ),
191  key="storage_level",
192  json_key="STORAGE",
193  translation_key="storage_level",
194  entity_registry_enabled_default=False,
195  state_class=SensorStateClass.MEASUREMENT,
196  native_unit_of_measurement=PERCENTAGE,
197  ),
198 ]
199 
200 
202  hass: HomeAssistant,
203  entry: SolarEdgeConfigEntry,
204  async_add_entities: AddEntitiesCallback,
205 ) -> None:
206  """Add an solarEdge entry."""
207  # Add the needed sensors to hass
208  api = entry.runtime_data[DATA_API_CLIENT]
209  sensor_factory = SolarEdgeSensorFactory(hass, entry.data[CONF_SITE_ID], api)
210  for service in sensor_factory.all_services:
211  service.async_setup()
212  await service.coordinator.async_refresh()
213 
214  entities = []
215  for sensor_type in SENSOR_TYPES:
216  sensor = sensor_factory.create_sensor(sensor_type)
217  if sensor is not None:
218  entities.append(sensor)
219  async_add_entities(entities)
220 
221 
223  """Factory which creates sensors based on the sensor_key."""
224 
225  def __init__(self, hass: HomeAssistant, site_id: str, api: SolarEdge) -> None:
226  """Initialize the factory."""
227 
228  details = SolarEdgeDetailsDataService(hass, api, site_id)
229  overview = SolarEdgeOverviewDataService(hass, api, site_id)
230  inventory = SolarEdgeInventoryDataService(hass, api, site_id)
231  flow = SolarEdgePowerFlowDataService(hass, api, site_id)
232  energy = SolarEdgeEnergyDetailsService(hass, api, site_id)
233 
234  self.all_servicesall_services = (details, overview, inventory, flow, energy)
235 
236  self.services: dict[
237  str,
238  tuple[
239  type[SolarEdgeSensorEntity | SolarEdgeOverviewSensor],
240  SolarEdgeDataService,
241  ],
242  ] = {"site_details": (SolarEdgeDetailsSensor, details)}
243 
244  for key in (
245  "lifetime_energy",
246  "energy_this_year",
247  "energy_this_month",
248  "energy_today",
249  "current_power",
250  ):
251  self.services[key] = (SolarEdgeOverviewSensor, overview)
252 
253  for key in ("meters", "sensors", "gateways", "batteries", "inverters"):
254  self.services[key] = (SolarEdgeInventorySensor, inventory)
255 
256  for key in ("power_consumption", "solar_power", "grid_power", "storage_power"):
257  self.services[key] = (SolarEdgePowerFlowSensor, flow)
258 
259  for key in ("storage_level",):
260  self.services[key] = (SolarEdgeStorageLevelSensor, flow)
261 
262  for key in (
263  "purchased_energy",
264  "production_energy",
265  "feedin_energy",
266  "consumption_energy",
267  "selfconsumption_energy",
268  ):
269  self.services[key] = (SolarEdgeEnergyDetailsSensor, energy)
270 
272  self, sensor_type: SolarEdgeSensorEntityDescription
273  ) -> SolarEdgeSensorEntity:
274  """Create and return a sensor based on the sensor_key."""
275  sensor_class, service = self.services[sensor_type.key]
276 
277  return sensor_class(sensor_type, service)
278 
279 
281  CoordinatorEntity[DataUpdateCoordinator[None]], SensorEntity
282 ):
283  """Abstract class for a solaredge sensor."""
284 
285  _attr_has_entity_name = True
286 
287  entity_description: SolarEdgeSensorEntityDescription
288 
289  def __init__(
290  self,
291  description: SolarEdgeSensorEntityDescription,
292  data_service: SolarEdgeDataService,
293  ) -> None:
294  """Initialize the sensor."""
295  super().__init__(data_service.coordinator)
296  self.entity_descriptionentity_description = description
297  self.data_servicedata_service = data_service
298  self._attr_device_info_attr_device_info = DeviceInfo(
299  identifiers={(DOMAIN, data_service.site_id)}, manufacturer="SolarEdge"
300  )
301 
302  @property
303  def unique_id(self) -> str | None:
304  """Return a unique ID."""
305  if not self.data_servicedata_service.site_id:
306  return None
307  return f"{self.data_service.site_id}_{self.entity_description.key}"
308 
309 
311  """Representation of an SolarEdge Monitoring API overview sensor."""
312 
313  @property
314  def native_value(self) -> str | None:
315  """Return the state of the sensor."""
316  return self.data_servicedata_service.data.get(self.entity_descriptionentity_description.json_key)
317 
318 
320  """Representation of an SolarEdge Monitoring API details sensor."""
321 
322  @property
323  def extra_state_attributes(self) -> dict[str, Any]:
324  """Return the state attributes."""
325  return self.data_servicedata_service.attributes
326 
327  @property
328  def native_value(self) -> str | None:
329  """Return the state of the sensor."""
330  return self.data_servicedata_service.data.get(self.entity_descriptionentity_description.json_key)
331 
332  @property
333  def unique_id(self) -> str | None:
334  """Return a unique ID."""
335  if not self.data_servicedata_service.site_id:
336  return None
337  return str(self.data_servicedata_service.site_id)
338 
339 
341  """Representation of an SolarEdge Monitoring API inventory sensor."""
342 
343  @property
344  def extra_state_attributes(self) -> dict[str, Any] | None:
345  """Return the state attributes."""
346  return self.data_servicedata_service.attributes.get(self.entity_descriptionentity_description.json_key)
347 
348  @property
349  def native_value(self) -> str | None:
350  """Return the state of the sensor."""
351  return self.data_servicedata_service.data.get(self.entity_descriptionentity_description.json_key)
352 
353 
355  """Representation of an SolarEdge Monitoring API power flow sensor."""
356 
357  def __init__(
358  self,
359  sensor_type: SolarEdgeSensorEntityDescription,
360  data_service: SolarEdgeEnergyDetailsService,
361  ) -> None:
362  """Initialize the power flow sensor."""
363  super().__init__(sensor_type, data_service)
364 
365  self._attr_native_unit_of_measurement_attr_native_unit_of_measurement = data_service.unit
366 
367  @property
368  def extra_state_attributes(self) -> dict[str, Any] | None:
369  """Return the state attributes."""
370  return self.data_servicedata_service.attributes.get(self.entity_descriptionentity_description.json_key)
371 
372  @property
373  def native_value(self) -> str | None:
374  """Return the state of the sensor."""
375  return self.data_servicedata_service.data.get(self.entity_descriptionentity_description.json_key)
376 
377 
379  """Representation of an SolarEdge Monitoring API power flow sensor."""
380 
381  _attr_device_class = SensorDeviceClass.POWER
382 
383  def __init__(
384  self,
385  description: SolarEdgeSensorEntityDescription,
386  data_service: SolarEdgePowerFlowDataService,
387  ) -> None:
388  """Initialize the power flow sensor."""
389  super().__init__(description, data_service)
390 
391  self._attr_native_unit_of_measurement_attr_native_unit_of_measurement = data_service.unit
392 
393  @property
394  def extra_state_attributes(self) -> dict[str, Any] | None:
395  """Return the state attributes."""
396  return self.data_servicedata_service.attributes.get(self.entity_descriptionentity_description.json_key)
397 
398  @property
399  def native_value(self) -> str | None:
400  """Return the state of the sensor."""
401  return self.data_servicedata_service.data.get(self.entity_descriptionentity_description.json_key)
402 
403 
405  """Representation of an SolarEdge Monitoring API storage level sensor."""
406 
407  _attr_device_class = SensorDeviceClass.BATTERY
408 
409  @property
410  def native_value(self) -> str | None:
411  """Return the state of the sensor."""
412  attr = self.data_servicedata_service.attributes.get(self.entity_descriptionentity_description.json_key)
413  if attr and "soc" in attr:
414  return attr["soc"]
415  return None
None __init__(self, SolarEdgeSensorEntityDescription sensor_type, SolarEdgeEnergyDetailsService data_service)
Definition: sensor.py:361
None __init__(self, SolarEdgeSensorEntityDescription description, SolarEdgePowerFlowDataService data_service)
Definition: sensor.py:387
None __init__(self, SolarEdgeSensorEntityDescription description, SolarEdgeDataService data_service)
Definition: sensor.py:293
SolarEdgeSensorEntity create_sensor(self, SolarEdgeSensorEntityDescription sensor_type)
Definition: sensor.py:273
None __init__(self, HomeAssistant hass, str site_id, SolarEdge api)
Definition: sensor.py:225
None async_setup_entry(HomeAssistant hass, SolarEdgeConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:205