mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 09:47:13 +00:00
Add state class support to SolarEdge (#52271)
This commit is contained in:
parent
f1303e02ff
commit
a93487f389
@ -2,7 +2,11 @@
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
from homeassistant.components.sensor import STATE_CLASS_MEASUREMENT
|
||||
from homeassistant.const import ENERGY_WATT_HOUR, PERCENTAGE, POWER_WATT
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .models import SolarEdgeSensor
|
||||
|
||||
DOMAIN = "solaredge"
|
||||
|
||||
@ -23,64 +27,153 @@ ENERGY_DETAILS_DELAY = timedelta(minutes=15)
|
||||
SCAN_INTERVAL = timedelta(minutes=15)
|
||||
|
||||
|
||||
# Supported overview sensor types:
|
||||
# Key: ['json_key', 'name', unit, icon, default]
|
||||
SENSOR_TYPES = {
|
||||
"lifetime_energy": [
|
||||
"lifeTimeData",
|
||||
"Lifetime energy",
|
||||
ENERGY_WATT_HOUR,
|
||||
"mdi:solar-power",
|
||||
False,
|
||||
],
|
||||
"energy_this_year": [
|
||||
"lastYearData",
|
||||
"Energy this year",
|
||||
ENERGY_WATT_HOUR,
|
||||
"mdi:solar-power",
|
||||
False,
|
||||
],
|
||||
"energy_this_month": [
|
||||
"lastMonthData",
|
||||
"Energy this month",
|
||||
ENERGY_WATT_HOUR,
|
||||
"mdi:solar-power",
|
||||
False,
|
||||
],
|
||||
"energy_today": [
|
||||
"lastDayData",
|
||||
"Energy today",
|
||||
ENERGY_WATT_HOUR,
|
||||
"mdi:solar-power",
|
||||
False,
|
||||
],
|
||||
"current_power": [
|
||||
"currentPower",
|
||||
"Current Power",
|
||||
POWER_WATT,
|
||||
"mdi:solar-power",
|
||||
True,
|
||||
],
|
||||
"site_details": [None, "Site details", None, None, False],
|
||||
"meters": ["meters", "Meters", None, None, False],
|
||||
"sensors": ["sensors", "Sensors", None, None, False],
|
||||
"gateways": ["gateways", "Gateways", None, None, False],
|
||||
"batteries": ["batteries", "Batteries", None, None, False],
|
||||
"inverters": ["inverters", "Inverters", None, None, False],
|
||||
"power_consumption": ["LOAD", "Power Consumption", None, "mdi:flash", False],
|
||||
"solar_power": ["PV", "Solar Power", None, "mdi:solar-power", False],
|
||||
"grid_power": ["GRID", "Grid Power", None, "mdi:power-plug", False],
|
||||
"storage_power": ["STORAGE", "Storage Power", None, "mdi:car-battery", False],
|
||||
"purchased_power": ["Purchased", "Imported Power", None, "mdi:flash", False],
|
||||
"production_power": ["Production", "Production Power", None, "mdi:flash", False],
|
||||
"consumption_power": ["Consumption", "Consumption Power", None, "mdi:flash", False],
|
||||
"selfconsumption_power": [
|
||||
"SelfConsumption",
|
||||
"SelfConsumption Power",
|
||||
None,
|
||||
"mdi:flash",
|
||||
False,
|
||||
],
|
||||
"feedin_power": ["FeedIn", "Exported Power", None, "mdi:flash", False],
|
||||
"storage_level": ["STORAGE", "Storage Level", PERCENTAGE, None, False],
|
||||
}
|
||||
# Supported overview sensors
|
||||
SENSOR_TYPES = [
|
||||
SolarEdgeSensor(
|
||||
key="lifetime_energy",
|
||||
json_key="lifeTimeData",
|
||||
name="Lifetime energy",
|
||||
icon="mdi:solar-power",
|
||||
last_reset=dt_util.utc_from_timestamp(0),
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=ENERGY_WATT_HOUR,
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="energy_this_year",
|
||||
json_key="lastYearData",
|
||||
name="Energy this year",
|
||||
entity_registry_enabled_default=False,
|
||||
icon="mdi:solar-power",
|
||||
unit_of_measurement=ENERGY_WATT_HOUR,
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="energy_this_month",
|
||||
json_key="lastMonthData",
|
||||
name="Energy this month",
|
||||
entity_registry_enabled_default=False,
|
||||
icon="mdi:solar-power",
|
||||
unit_of_measurement=ENERGY_WATT_HOUR,
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="energy_today",
|
||||
json_key="lastDayData",
|
||||
name="Energy today",
|
||||
entity_registry_enabled_default=False,
|
||||
icon="mdi:solar-power",
|
||||
unit_of_measurement=ENERGY_WATT_HOUR,
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="current_power",
|
||||
json_key="currentPower",
|
||||
name="Current Power",
|
||||
icon="mdi:solar-power",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=POWER_WATT,
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="site_details",
|
||||
name="Site details",
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="meters",
|
||||
json_key="meters",
|
||||
name="Meters",
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="sensors",
|
||||
json_key="sensors",
|
||||
name="Sensors",
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="gateways",
|
||||
json_key="gateways",
|
||||
name="Gateways",
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="batteries",
|
||||
json_key="batteries",
|
||||
name="Batteries",
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="inverters",
|
||||
json_key="inverters",
|
||||
name="Inverters",
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="power_consumption",
|
||||
json_key="LOAD",
|
||||
name="Power Consumption",
|
||||
entity_registry_enabled_default=False,
|
||||
icon="mdi:flash",
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="solar_power",
|
||||
json_key="PV",
|
||||
name="Solar Power",
|
||||
entity_registry_enabled_default=False,
|
||||
icon="mdi:solar-power",
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="grid_power",
|
||||
json_key="GRID",
|
||||
name="Grid Power",
|
||||
entity_registry_enabled_default=False,
|
||||
icon="mdi:power-plug",
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="storage_power",
|
||||
json_key="STORAGE",
|
||||
name="Storage Power",
|
||||
entity_registry_enabled_default=False,
|
||||
icon="mdi:car-battery",
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="purchased_power",
|
||||
json_key="Purchased",
|
||||
name="Imported Power",
|
||||
entity_registry_enabled_default=False,
|
||||
icon="mdi:flash",
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="production_power",
|
||||
json_key="Production",
|
||||
name="Production Power",
|
||||
entity_registry_enabled_default=False,
|
||||
icon="mdi:flash",
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="consumption_power",
|
||||
json_key="Consumption",
|
||||
name="Consumption Power",
|
||||
entity_registry_enabled_default=False,
|
||||
icon="mdi:flash",
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="selfconsumption_power",
|
||||
json_key="SelfConsumption",
|
||||
name="SelfConsumption Power",
|
||||
entity_registry_enabled_default=False,
|
||||
icon="mdi:flash",
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="feedin_power",
|
||||
json_key="FeedIn",
|
||||
name="Exported Power",
|
||||
entity_registry_enabled_default=False,
|
||||
icon="mdi:flash",
|
||||
),
|
||||
SolarEdgeSensor(
|
||||
key="storage_level",
|
||||
json_key="STORAGE",
|
||||
name="Storage Level",
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
),
|
||||
]
|
||||
|
21
homeassistant/components/solaredge/models.py
Normal file
21
homeassistant/components/solaredge/models.py
Normal file
@ -0,0 +1,21 @@
|
||||
"""Models for the SolarEdge integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class SolarEdgeSensor:
|
||||
"""Represents an SolarEdge Sensor."""
|
||||
|
||||
key: str
|
||||
name: str
|
||||
|
||||
json_key: str | None = None
|
||||
device_class: str | None = None
|
||||
entity_registry_enabled_default: bool = True
|
||||
icon: str | None = None
|
||||
last_reset: datetime | None = None
|
||||
state_class: str | None = None
|
||||
unit_of_measurement: str | None = None
|
@ -21,6 +21,7 @@ from .coordinator import (
|
||||
SolarEdgeOverviewDataService,
|
||||
SolarEdgePowerFlowDataService,
|
||||
)
|
||||
from .models import SolarEdgeSensor
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
@ -40,8 +41,8 @@ async def async_setup_entry(
|
||||
await service.coordinator.async_refresh()
|
||||
|
||||
entities = []
|
||||
for sensor_key in SENSOR_TYPES:
|
||||
sensor = sensor_factory.create_sensor(sensor_key)
|
||||
for sensor_type in SENSOR_TYPES:
|
||||
sensor = sensor_factory.create_sensor(sensor_type)
|
||||
if sensor is not None:
|
||||
entities.append(sensor)
|
||||
async_add_entities(entities)
|
||||
@ -98,48 +99,49 @@ class SolarEdgeSensorFactory:
|
||||
]:
|
||||
self.services[key] = (SolarEdgeEnergyDetailsSensor, energy)
|
||||
|
||||
def create_sensor(self, sensor_key: str) -> SolarEdgeSensor:
|
||||
def create_sensor(self, sensor_type: SolarEdgeSensor) -> SolarEdgeSensor:
|
||||
"""Create and return a sensor based on the sensor_key."""
|
||||
sensor_class, service = self.services[sensor_key]
|
||||
sensor_class, service = self.services[sensor_type.key]
|
||||
|
||||
return sensor_class(self.platform_name, sensor_key, service)
|
||||
return sensor_class(self.platform_name, sensor_type, service)
|
||||
|
||||
|
||||
class SolarEdgeSensor(CoordinatorEntity, SensorEntity):
|
||||
class SolarEdgeSensorEntity(CoordinatorEntity, SensorEntity):
|
||||
"""Abstract class for a solaredge sensor."""
|
||||
|
||||
def __init__(
|
||||
self, platform_name: str, sensor_key: str, data_service: SolarEdgeDataService
|
||||
self,
|
||||
platform_name: str,
|
||||
sensor_type: SolarEdgeSensor,
|
||||
data_service: SolarEdgeDataService,
|
||||
) -> None:
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(data_service.coordinator)
|
||||
self.platform_name = platform_name
|
||||
self.sensor_key = sensor_key
|
||||
self.sensor_type = sensor_type
|
||||
self.data_service = data_service
|
||||
|
||||
self._attr_unit_of_measurement = SENSOR_TYPES[sensor_key][2]
|
||||
self._attr_name = f"{platform_name} ({SENSOR_TYPES[sensor_key][1]})"
|
||||
self._attr_icon = SENSOR_TYPES[sensor_key][3]
|
||||
self._attr_device_class = sensor_type.device_class
|
||||
self._attr_entity_registry_enabled_default = (
|
||||
sensor_type.entity_registry_enabled_default
|
||||
)
|
||||
self._attr_icon = sensor_type.icon
|
||||
self._attr_last_reset = sensor_type.last_reset
|
||||
self._attr_name = f"{platform_name} ({sensor_type.name})"
|
||||
self._attr_state_class = sensor_type.state_class
|
||||
self._attr_unit_of_measurement = sensor_type.unit_of_measurement
|
||||
|
||||
|
||||
class SolarEdgeOverviewSensor(SolarEdgeSensor):
|
||||
class SolarEdgeOverviewSensor(SolarEdgeSensorEntity):
|
||||
"""Representation of an SolarEdge Monitoring API overview sensor."""
|
||||
|
||||
def __init__(
|
||||
self, platform_name: str, sensor_key: str, data_service: SolarEdgeDataService
|
||||
) -> None:
|
||||
"""Initialize the overview sensor."""
|
||||
super().__init__(platform_name, sensor_key, data_service)
|
||||
|
||||
self._json_key = SENSOR_TYPES[self.sensor_key][0]
|
||||
|
||||
@property
|
||||
def state(self) -> str | None:
|
||||
"""Return the state of the sensor."""
|
||||
return self.data_service.data.get(self._json_key)
|
||||
return self.data_service.data.get(self.sensor_type.json_key)
|
||||
|
||||
|
||||
class SolarEdgeDetailsSensor(SolarEdgeSensor):
|
||||
class SolarEdgeDetailsSensor(SolarEdgeSensorEntity):
|
||||
"""Representation of an SolarEdge Monitoring API details sensor."""
|
||||
|
||||
@property
|
||||
@ -153,89 +155,76 @@ class SolarEdgeDetailsSensor(SolarEdgeSensor):
|
||||
return self.data_service.data
|
||||
|
||||
|
||||
class SolarEdgeInventorySensor(SolarEdgeSensor):
|
||||
class SolarEdgeInventorySensor(SolarEdgeSensorEntity):
|
||||
"""Representation of an SolarEdge Monitoring API inventory sensor."""
|
||||
|
||||
def __init__(self, platform_name, sensor_key, data_service):
|
||||
"""Initialize the inventory sensor."""
|
||||
super().__init__(platform_name, sensor_key, data_service)
|
||||
|
||||
self._json_key = SENSOR_TYPES[self.sensor_key][0]
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Return the state attributes."""
|
||||
return self.data_service.attributes.get(self._json_key)
|
||||
return self.data_service.attributes.get(self.sensor_type.json_key)
|
||||
|
||||
@property
|
||||
def state(self) -> str | None:
|
||||
"""Return the state of the sensor."""
|
||||
return self.data_service.data.get(self._json_key)
|
||||
return self.data_service.data.get(self.sensor_type.json_key)
|
||||
|
||||
|
||||
class SolarEdgeEnergyDetailsSensor(SolarEdgeSensor):
|
||||
class SolarEdgeEnergyDetailsSensor(SolarEdgeSensorEntity):
|
||||
"""Representation of an SolarEdge Monitoring API power flow sensor."""
|
||||
|
||||
def __init__(self, platform_name, sensor_key, data_service):
|
||||
def __init__(self, platform_name, sensor_type, data_service):
|
||||
"""Initialize the power flow sensor."""
|
||||
super().__init__(platform_name, sensor_key, data_service)
|
||||
super().__init__(platform_name, sensor_type, data_service)
|
||||
|
||||
self._json_key = SENSOR_TYPES[self.sensor_key][0]
|
||||
self._attr_unit_of_measurement = data_service.unit
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Return the state attributes."""
|
||||
return self.data_service.attributes.get(self._json_key)
|
||||
return self.data_service.attributes.get(self.sensor_type.json_key)
|
||||
|
||||
@property
|
||||
def state(self) -> str | None:
|
||||
"""Return the state of the sensor."""
|
||||
return self.data_service.data.get(self._json_key)
|
||||
return self.data_service.data.get(self.sensor_type.json_key)
|
||||
|
||||
|
||||
class SolarEdgePowerFlowSensor(SolarEdgeSensor):
|
||||
class SolarEdgePowerFlowSensor(SolarEdgeSensorEntity):
|
||||
"""Representation of an SolarEdge Monitoring API power flow sensor."""
|
||||
|
||||
_attr_device_class = DEVICE_CLASS_POWER
|
||||
|
||||
def __init__(
|
||||
self, platform_name: str, sensor_key: str, data_service: SolarEdgeDataService
|
||||
self,
|
||||
platform_name: str,
|
||||
sensor_type: SolarEdgeSensor,
|
||||
data_service: SolarEdgeDataService,
|
||||
) -> None:
|
||||
"""Initialize the power flow sensor."""
|
||||
super().__init__(platform_name, sensor_key, data_service)
|
||||
super().__init__(platform_name, sensor_type, data_service)
|
||||
|
||||
self._json_key = SENSOR_TYPES[self.sensor_key][0]
|
||||
self._attr_unit_of_measurement = data_service.unit
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Return the state attributes."""
|
||||
return self.data_service.attributes.get(self._json_key)
|
||||
return self.data_service.attributes.get(self.sensor_type.json_key)
|
||||
|
||||
@property
|
||||
def state(self) -> str | None:
|
||||
"""Return the state of the sensor."""
|
||||
return self.data_service.data.get(self._json_key)
|
||||
return self.data_service.data.get(self.sensor_type.json_key)
|
||||
|
||||
|
||||
class SolarEdgeStorageLevelSensor(SolarEdgeSensor):
|
||||
class SolarEdgeStorageLevelSensor(SolarEdgeSensorEntity):
|
||||
"""Representation of an SolarEdge Monitoring API storage level sensor."""
|
||||
|
||||
_attr_device_class = DEVICE_CLASS_BATTERY
|
||||
|
||||
def __init__(
|
||||
self, platform_name: str, sensor_key: str, data_service: SolarEdgeDataService
|
||||
) -> None:
|
||||
"""Initialize the storage level sensor."""
|
||||
super().__init__(platform_name, sensor_key, data_service)
|
||||
|
||||
self._json_key = SENSOR_TYPES[self.sensor_key][0]
|
||||
|
||||
@property
|
||||
def state(self) -> str | None:
|
||||
"""Return the state of the sensor."""
|
||||
attr = self.data_service.attributes.get(self._json_key)
|
||||
attr = self.data_service.attributes.get(self.sensor_type.json_key)
|
||||
if attr and "soc" in attr:
|
||||
return attr["soc"]
|
||||
return None
|
||||
|
Loading…
x
Reference in New Issue
Block a user