Use EntityDescription - solaredge_local (#56434)

This commit is contained in:
Marc Mueller 2021-09-23 18:29:58 +02:00 committed by GitHub
parent 98d0c84468
commit 70f10338cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,6 +1,9 @@
"""Support for SolarEdge-local Monitoring API.""" """Support for SolarEdge-local Monitoring API."""
from __future__ import annotations
from contextlib import suppress from contextlib import suppress
from copy import deepcopy from copy import copy
from dataclasses import dataclass
from datetime import timedelta from datetime import timedelta
import logging import logging
import statistics import statistics
@ -9,7 +12,11 @@ from requests.exceptions import ConnectTimeout, HTTPError
from solaredge_local import SolarEdge from solaredge_local import SolarEdge
import voluptuous as vol import voluptuous as vol
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity from homeassistant.components.sensor import (
PLATFORM_SCHEMA,
SensorEntity,
SensorEntityDescription,
)
from homeassistant.const import ( from homeassistant.const import (
CONF_IP_ADDRESS, CONF_IP_ADDRESS,
CONF_NAME, CONF_NAME,
@ -41,122 +48,134 @@ INVERTER_MODES = (
"IDLE", "IDLE",
) )
# Supported sensor types:
# Key: ['json_key', 'name', unit, icon, attribute name] @dataclass
SENSOR_TYPES = { class SolarEdgeLocalSensorEntityDescription(SensorEntityDescription):
"current_AC_voltage": [ """Describes SolarEdge-local sensor entity."""
"gridvoltage",
"Grid Voltage", extra_attribute: str | None = None
ELECTRIC_POTENTIAL_VOLT,
"mdi:current-ac",
None, SENSOR_TYPES: tuple[SolarEdgeLocalSensorEntityDescription, ...] = (
None, SolarEdgeLocalSensorEntityDescription(
], key="gridvoltage",
"current_DC_voltage": [ name="Grid Voltage",
"dcvoltage", native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
"DC Voltage", icon="mdi:current-ac",
ELECTRIC_POTENTIAL_VOLT, ),
"mdi:current-dc", SolarEdgeLocalSensorEntityDescription(
None, key="dcvoltage",
None, name="DC Voltage",
], native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
"current_frequency": [ icon="mdi:current-dc",
"gridfrequency", ),
"Grid Frequency", SolarEdgeLocalSensorEntityDescription(
FREQUENCY_HERTZ, key="gridfrequency",
"mdi:current-ac", name="Grid Frequency",
None, native_unit_of_measurement=FREQUENCY_HERTZ,
None, icon="mdi:current-ac",
], ),
"current_power": [ SolarEdgeLocalSensorEntityDescription(
"currentPower", key="currentPower",
"Current Power", name="Current Power",
POWER_WATT, native_unit_of_measurement=POWER_WATT,
"mdi:solar-power", icon="mdi:solar-power",
None, ),
None, SolarEdgeLocalSensorEntityDescription(
], key="energyThisMonth",
"energy_this_month": [ name="Energy This Month",
"energyThisMonth", native_unit_of_measurement=ENERGY_WATT_HOUR,
"Energy This Month", icon="mdi:solar-power",
ENERGY_WATT_HOUR, ),
"mdi:solar-power", SolarEdgeLocalSensorEntityDescription(
None, key="energyThisYear",
None, name="Energy This Year",
], native_unit_of_measurement=ENERGY_WATT_HOUR,
"energy_this_year": [ icon="mdi:solar-power",
"energyThisYear", ),
"Energy This Year", SolarEdgeLocalSensorEntityDescription(
ENERGY_WATT_HOUR, key="energyToday",
"mdi:solar-power", name="Energy Today",
None, native_unit_of_measurement=ENERGY_WATT_HOUR,
None, icon="mdi:solar-power",
], ),
"energy_today": [ SolarEdgeLocalSensorEntityDescription(
"energyToday", key="energyTotal",
"Energy Today", name="Lifetime Energy",
ENERGY_WATT_HOUR, native_unit_of_measurement=ENERGY_WATT_HOUR,
"mdi:solar-power", icon="mdi:solar-power",
None, ),
None, SolarEdgeLocalSensorEntityDescription(
], key="optimizers",
"inverter_temperature": [ name="Optimizers Online",
"invertertemperature", native_unit_of_measurement="optimizers",
"Inverter Temperature", icon="mdi:solar-panel",
TEMP_CELSIUS, extra_attribute="optimizers_connected",
None, ),
"operating_mode", SolarEdgeLocalSensorEntityDescription(
DEVICE_CLASS_TEMPERATURE, key="optimizercurrent",
], name="Average Optimizer Current",
"lifetime_energy": [ native_unit_of_measurement=ELECTRIC_CURRENT_AMPERE,
"energyTotal", icon="mdi:solar-panel",
"Lifetime Energy", ),
ENERGY_WATT_HOUR, SolarEdgeLocalSensorEntityDescription(
"mdi:solar-power", key="optimizerpower",
None, name="Average Optimizer Power",
None, native_unit_of_measurement=POWER_WATT,
], icon="mdi:solar-panel",
"optimizer_connected": [ ),
"optimizers", SolarEdgeLocalSensorEntityDescription(
"Optimizers Online", key="optimizertemperature",
"optimizers", name="Average Optimizer Temperature",
"mdi:solar-panel", native_unit_of_measurement=TEMP_CELSIUS,
"optimizers_connected", icon="mdi:solar-panel",
None, device_class=DEVICE_CLASS_TEMPERATURE,
], ),
"optimizer_current": [ SolarEdgeLocalSensorEntityDescription(
"optimizercurrent", key="optimizervoltage",
"Average Optimizer Current", name="Average Optimizer Voltage",
ELECTRIC_CURRENT_AMPERE, native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
"mdi:solar-panel", icon="mdi:solar-panel",
None, ),
None, )
],
"optimizer_power": [ SENSOR_TYPE_INVERTER_TEMPERATURE = SolarEdgeLocalSensorEntityDescription(
"optimizerpower", key="invertertemperature",
"Average Optimizer Power", name="Inverter Temperature",
POWER_WATT, native_unit_of_measurement=TEMP_CELSIUS,
"mdi:solar-panel", extra_attribute="operating_mode",
None, device_class=DEVICE_CLASS_TEMPERATURE,
None, )
],
"optimizer_temperature": [ SENSOR_TYPES_ENERGY_IMPORT: tuple[SolarEdgeLocalSensorEntityDescription, ...] = (
"optimizertemperature", SolarEdgeLocalSensorEntityDescription(
"Average Optimizer Temperature", key="currentPowerimport",
TEMP_CELSIUS, name="current import Power",
"mdi:solar-panel", native_unit_of_measurement=POWER_WATT,
None, icon="mdi:arrow-collapse-down",
DEVICE_CLASS_TEMPERATURE, ),
], SolarEdgeLocalSensorEntityDescription(
"optimizer_voltage": [ key="totalEnergyimport",
"optimizervoltage", name="total import Energy",
"Average Optimizer Voltage", native_unit_of_measurement=ENERGY_WATT_HOUR,
ELECTRIC_POTENTIAL_VOLT, icon="mdi:counter",
"mdi:solar-panel", ),
None, )
None,
], SENSOR_TYPES_ENERGY_EXPORT: tuple[SolarEdgeLocalSensorEntityDescription, ...] = (
} SolarEdgeLocalSensorEntityDescription(
key="currentPowerexport",
name="current export Power",
native_unit_of_measurement=POWER_WATT,
icon="mdi:arrow-expand-up",
),
SolarEdgeLocalSensorEntityDescription(
key="totalEnergyexport",
name="total export Energy",
native_unit_of_measurement=ENERGY_WATT_HOUR,
icon="mdi:counter",
),
)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{ {
@ -188,133 +207,76 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
_LOGGER.error("Could not retrieve details from SolarEdge API") _LOGGER.error("Could not retrieve details from SolarEdge API")
return return
# Create solaredge data service which will retrieve and update the data.
data = SolarEdgeData(hass, api)
# Changing inverter temperature unit. # Changing inverter temperature unit.
sensors = deepcopy(SENSOR_TYPES) inverter_temp_description = copy(SENSOR_TYPE_INVERTER_TEMPERATURE)
if status.inverters.primary.temperature.units.farenheit: if status.inverters.primary.temperature.units.farenheit:
sensors["inverter_temperature"] = [ inverter_temp_description.native_unit_of_measurement = TEMP_FAHRENHEIT
"invertertemperature",
"Inverter Temperature", # Create entities
TEMP_FAHRENHEIT, entities = [
"mdi:thermometer", SolarEdgeSensor(platform_name, data, description)
"operating_mode", for description in (*SENSOR_TYPES, inverter_temp_description)
DEVICE_CLASS_TEMPERATURE,
] ]
try: try:
if status.metersList[0]: if status.metersList[0]:
sensors["import_current_power"] = [ entities.extend(
"currentPowerimport", [
"current import Power", SolarEdgeSensor(platform_name, data, description)
POWER_WATT, for description in SENSOR_TYPES_ENERGY_IMPORT
"mdi:arrow-collapse-down",
None,
None,
]
sensors["import_meter_reading"] = [
"totalEnergyimport",
"total import Energy",
ENERGY_WATT_HOUR,
"mdi:counter",
None,
None,
] ]
)
except IndexError: except IndexError:
_LOGGER.debug("Import meter sensors are not created") _LOGGER.debug("Import meter sensors are not created")
try: try:
if status.metersList[1]: if status.metersList[1]:
sensors["export_current_power"] = [ entities.extend(
"currentPowerexport", [
"current export Power", SolarEdgeSensor(platform_name, data, description)
POWER_WATT, for description in SENSOR_TYPES_ENERGY_EXPORT
"mdi:arrow-expand-up",
None,
None,
]
sensors["export_meter_reading"] = [
"totalEnergyexport",
"total export Energy",
ENERGY_WATT_HOUR,
"mdi:counter",
None,
None,
] ]
)
except IndexError: except IndexError:
_LOGGER.debug("Export meter sensors are not created") _LOGGER.debug("Export meter sensors are not created")
# Create solaredge data service which will retrieve and update the data.
data = SolarEdgeData(hass, api)
# Create a new sensor for each sensor type.
entities = []
for sensor_info in sensors.values():
sensor = SolarEdgeSensor(
platform_name,
data,
sensor_info[0],
sensor_info[1],
sensor_info[2],
sensor_info[3],
sensor_info[4],
sensor_info[5],
)
entities.append(sensor)
add_entities(entities, True) add_entities(entities, True)
class SolarEdgeSensor(SensorEntity): class SolarEdgeSensor(SensorEntity):
"""Representation of an SolarEdge Monitoring API sensor.""" """Representation of an SolarEdge Monitoring API sensor."""
entity_description: SolarEdgeLocalSensorEntityDescription
def __init__( def __init__(
self, platform_name, data, json_key, name, unit, icon, attr, device_class self,
platform_name,
data,
description: SolarEdgeLocalSensorEntityDescription,
): ):
"""Initialize the sensor.""" """Initialize the sensor."""
self.entity_description = description
self._platform_name = platform_name self._platform_name = platform_name
self._data = data self._data = data
self._state = None self._attr_name = f"{platform_name} ({description.name})"
self._json_key = json_key
self._name = name
self._unit_of_measurement = unit
self._icon = icon
self._attr = attr
self._attr_device_class = device_class
@property
def name(self):
"""Return the name."""
return f"{self._platform_name} ({self._name})"
@property
def native_unit_of_measurement(self):
"""Return the unit of measurement."""
return self._unit_of_measurement
@property @property
def extra_state_attributes(self): def extra_state_attributes(self):
"""Return the state attributes.""" """Return the state attributes."""
if self._attr: if extra_attr := self.entity_description.extra_attribute:
try: try:
return {self._attr: self._data.info[self._json_key]} return {extra_attr: self._data.info[self.entity_description.key]}
except KeyError: except KeyError:
pass
return None return None
return None
@property
def icon(self):
"""Return the sensor icon."""
return self._icon
@property
def native_value(self):
"""Return the state of the sensor."""
return self._state
def update(self): def update(self):
"""Get the latest data from the sensor and update the state.""" """Get the latest data from the sensor and update the state."""
self._data.update() self._data.update()
self._state = self._data.data[self._json_key] self._attr_native_value = self._data.data[self.entity_description.key]
class SolarEdgeData: class SolarEdgeData: