From b42ac8b48f7ea5c91fd11293dc53456f31323cc0 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Mon, 9 Aug 2021 23:53:39 +0200 Subject: [PATCH] Use EntityDescription - growatt_server (#54316) --- .../components/growatt_server/sensor.py | 1149 +++++++++-------- 1 file changed, 633 insertions(+), 516 deletions(-) diff --git a/homeassistant/components/growatt_server/sensor.py b/homeassistant/components/growatt_server/sensor.py index 530842fab7b..6eb225e7535 100644 --- a/homeassistant/components/growatt_server/sensor.py +++ b/homeassistant/components/growatt_server/sensor.py @@ -1,4 +1,7 @@ """Read status of growatt inverters.""" +from __future__ import annotations + +from dataclasses import dataclass import datetime import json import logging @@ -6,7 +9,7 @@ import re import growattServer -from homeassistant.components.sensor import SensorEntity +from homeassistant.components.sensor import SensorEntity, SensorEntityDescription from homeassistant.const import ( CONF_NAME, CONF_PASSWORD, @@ -37,514 +40,643 @@ _LOGGER = logging.getLogger(__name__) SCAN_INTERVAL = datetime.timedelta(minutes=1) -# Sensor type order is: Sensor name, Unit of measurement, api data name, additional options -TOTAL_SENSOR_TYPES = { - "total_money_today": ("Total money today", CURRENCY_EURO, "plantMoneyText", {}), - "total_money_total": ("Money lifetime", CURRENCY_EURO, "totalMoneyText", {}), - "total_energy_today": ( - "Energy Today", - ENERGY_KILO_WATT_HOUR, - "todayEnergy", - {"device_class": DEVICE_CLASS_ENERGY}, - ), - "total_output_power": ( - "Output Power", - POWER_WATT, - "invTodayPpv", - {"device_class": DEVICE_CLASS_POWER}, - ), - "total_energy_output": ( - "Lifetime energy output", - ENERGY_KILO_WATT_HOUR, - "totalEnergy", - {"device_class": DEVICE_CLASS_ENERGY}, - ), - "total_maximum_output": ( - "Maximum power", - POWER_WATT, - "nominalPower", - {"device_class": DEVICE_CLASS_POWER}, - ), -} -INVERTER_SENSOR_TYPES = { - "inverter_energy_today": ( - "Energy today", - ENERGY_KILO_WATT_HOUR, - "powerToday", - {"round": 1, "device_class": DEVICE_CLASS_ENERGY}, - ), - "inverter_energy_total": ( - "Lifetime energy output", - ENERGY_KILO_WATT_HOUR, - "powerTotal", - {"round": 1, "device_class": DEVICE_CLASS_ENERGY}, - ), - "inverter_voltage_input_1": ( - "Input 1 voltage", - ELECTRIC_POTENTIAL_VOLT, - "vpv1", - {"round": 2, "device_class": DEVICE_CLASS_VOLTAGE}, - ), - "inverter_amperage_input_1": ( - "Input 1 Amperage", - ELECTRIC_CURRENT_AMPERE, - "ipv1", - {"round": 1, "device_class": DEVICE_CLASS_CURRENT}, - ), - "inverter_wattage_input_1": ( - "Input 1 Wattage", - POWER_WATT, - "ppv1", - {"device_class": DEVICE_CLASS_POWER, "round": 1}, - ), - "inverter_voltage_input_2": ( - "Input 2 voltage", - ELECTRIC_POTENTIAL_VOLT, - "vpv2", - {"round": 1, "device_class": DEVICE_CLASS_VOLTAGE}, - ), - "inverter_amperage_input_2": ( - "Input 2 Amperage", - ELECTRIC_CURRENT_AMPERE, - "ipv2", - {"round": 1, "device_class": DEVICE_CLASS_CURRENT}, - ), - "inverter_wattage_input_2": ( - "Input 2 Wattage", - POWER_WATT, - "ppv2", - {"device_class": DEVICE_CLASS_POWER, "round": 1}, - ), - "inverter_voltage_input_3": ( - "Input 3 voltage", - ELECTRIC_POTENTIAL_VOLT, - "vpv3", - {"round": 1, "device_class": DEVICE_CLASS_VOLTAGE}, - ), - "inverter_amperage_input_3": ( - "Input 3 Amperage", - ELECTRIC_CURRENT_AMPERE, - "ipv3", - {"round": 1, "device_class": DEVICE_CLASS_CURRENT}, - ), - "inverter_wattage_input_3": ( - "Input 3 Wattage", - POWER_WATT, - "ppv3", - {"device_class": DEVICE_CLASS_POWER, "round": 1}, - ), - "inverter_internal_wattage": ( - "Internal wattage", - POWER_WATT, - "ppv", - {"device_class": DEVICE_CLASS_POWER, "round": 1}, - ), - "inverter_reactive_voltage": ( - "Reactive voltage", - ELECTRIC_POTENTIAL_VOLT, - "vacr", - {"round": 1, "device_class": DEVICE_CLASS_VOLTAGE}, - ), - "inverter_inverter_reactive_amperage": ( - "Reactive amperage", - ELECTRIC_CURRENT_AMPERE, - "iacr", - {"round": 1, "device_class": DEVICE_CLASS_CURRENT}, - ), - "inverter_frequency": ("AC frequency", FREQUENCY_HERTZ, "fac", {"round": 1}), - "inverter_current_wattage": ( - "Output power", - POWER_WATT, - "pac", - {"device_class": DEVICE_CLASS_POWER, "round": 1}, - ), - "inverter_current_reactive_wattage": ( - "Reactive wattage", - POWER_WATT, - "pacr", - {"device_class": DEVICE_CLASS_POWER, "round": 1}, - ), - "inverter_ipm_temperature": ( - "Intelligent Power Management temperature", - TEMP_CELSIUS, - "ipmTemperature", - {"device_class": DEVICE_CLASS_TEMPERATURE, "round": 1}, - ), - "inverter_temperature": ( - "Temperature", - TEMP_CELSIUS, - "temperature", - {"device_class": DEVICE_CLASS_TEMPERATURE, "round": 1}, - ), -} +@dataclass +class GrowattRequiredKeysMixin: + """Mixin for required keys.""" -STORAGE_SENSOR_TYPES = { - "storage_storage_production_today": ( - "Storage production today", - ENERGY_KILO_WATT_HOUR, - "eBatDisChargeToday", - {"device_class": DEVICE_CLASS_ENERGY}, - ), - "storage_storage_production_lifetime": ( - "Lifetime Storage production", - ENERGY_KILO_WATT_HOUR, - "eBatDisChargeTotal", - {"device_class": DEVICE_CLASS_ENERGY}, - ), - "storage_grid_discharge_today": ( - "Grid discharged today", - ENERGY_KILO_WATT_HOUR, - "eacDisChargeToday", - {"device_class": DEVICE_CLASS_ENERGY}, - ), - "storage_load_consumption_today": ( - "Load consumption today", - ENERGY_KILO_WATT_HOUR, - "eopDischrToday", - {"device_class": DEVICE_CLASS_ENERGY}, - ), - "storage_load_consumption_lifetime": ( - "Lifetime load consumption", - ENERGY_KILO_WATT_HOUR, - "eopDischrTotal", - {"device_class": DEVICE_CLASS_ENERGY}, - ), - "storage_grid_charged_today": ( - "Grid charged today", - ENERGY_KILO_WATT_HOUR, - "eacChargeToday", - {"device_class": DEVICE_CLASS_ENERGY}, - ), - "storage_charge_storage_lifetime": ( - "Lifetime storaged charged", - ENERGY_KILO_WATT_HOUR, - "eChargeTotal", - {"device_class": DEVICE_CLASS_ENERGY}, - ), - "storage_solar_production": ( - "Solar power production", - POWER_WATT, - "ppv", - {"device_class": DEVICE_CLASS_POWER}, - ), - "storage_battery_percentage": ( - "Battery percentage", - PERCENTAGE, - "capacity", - {"device_class": DEVICE_CLASS_BATTERY}, - ), - "storage_power_flow": ( - "Storage charging/ discharging(-ve)", - POWER_WATT, - "pCharge", - {"device_class": DEVICE_CLASS_POWER}, - ), - "storage_load_consumption_solar_storage": ( - "Load consumption(Solar + Storage)", - "VA", - "rateVA", - {}, - ), - "storage_charge_today": ( - "Charge today", - ENERGY_KILO_WATT_HOUR, - "eChargeToday", - {"device_class": DEVICE_CLASS_ENERGY}, - ), - "storage_import_from_grid": ( - "Import from grid", - POWER_WATT, - "pAcInPut", - {"device_class": DEVICE_CLASS_POWER}, - ), - "storage_import_from_grid_today": ( - "Import from grid today", - ENERGY_KILO_WATT_HOUR, - "eToUserToday", - {"device_class": DEVICE_CLASS_ENERGY}, - ), - "storage_import_from_grid_total": ( - "Import from grid total", - ENERGY_KILO_WATT_HOUR, - "eToUserTotal", - {"device_class": DEVICE_CLASS_ENERGY}, - ), - "storage_load_consumption": ( - "Load consumption", - POWER_WATT, - "outPutPower", - {"device_class": DEVICE_CLASS_POWER}, - ), - "storage_grid_voltage": ( - "AC input voltage", - ELECTRIC_POTENTIAL_VOLT, - "vGrid", - {"round": 2, "device_class": DEVICE_CLASS_VOLTAGE}, - ), - "storage_pv_charging_voltage": ( - "PV charging voltage", - ELECTRIC_POTENTIAL_VOLT, - "vpv", - {"round": 2, "device_class": DEVICE_CLASS_VOLTAGE}, - ), - "storage_ac_input_frequency_out": ( - "AC input frequency", - FREQUENCY_HERTZ, - "freqOutPut", - {"round": 2}, - ), - "storage_output_voltage": ( - "Output voltage", - ELECTRIC_POTENTIAL_VOLT, - "outPutVolt", - {"round": 2, "device_class": DEVICE_CLASS_VOLTAGE}, - ), - "storage_ac_output_frequency": ( - "Ac output frequency", - FREQUENCY_HERTZ, - "freqGrid", - {"round": 2}, - ), - "storage_current_PV": ( - "Solar charge current", - ELECTRIC_CURRENT_AMPERE, - "iAcCharge", - {"round": 2, "device_class": DEVICE_CLASS_CURRENT}, - ), - "storage_current_1": ( - "Solar current to storage", - ELECTRIC_CURRENT_AMPERE, - "iChargePV1", - {"round": 2, "device_class": DEVICE_CLASS_CURRENT}, - ), - "storage_grid_amperage_input": ( - "Grid charge current", - ELECTRIC_CURRENT_AMPERE, - "chgCurr", - {"round": 2, "device_class": DEVICE_CLASS_CURRENT}, - ), - "storage_grid_out_current": ( - "Grid out current", - ELECTRIC_CURRENT_AMPERE, - "outPutCurrent", - {"round": 2, "device_class": DEVICE_CLASS_CURRENT}, - ), - "storage_battery_voltage": ( - "Battery voltage", - ELECTRIC_POTENTIAL_VOLT, - "vBat", - {"round": 2, "device_class": DEVICE_CLASS_VOLTAGE}, - ), - "storage_load_percentage": ( - "Load percentage", - PERCENTAGE, - "loadPercent", - {"device_class": DEVICE_CLASS_BATTERY, "round": 2}, - ), -} + api_key: str -MIX_SENSOR_TYPES = { + +@dataclass +class GrowattSensorEntityDescription(SensorEntityDescription, GrowattRequiredKeysMixin): + """Describes Growatt sensor entity.""" + + precision: int | None = None + + +TOTAL_SENSOR_TYPES: tuple[GrowattSensorEntityDescription, ...] = ( + GrowattSensorEntityDescription( + key="total_money_today", + name="Total money today", + api_key="plantMoneyText", + unit_of_measurement=CURRENCY_EURO, + ), + GrowattSensorEntityDescription( + key="total_money_total", + name="Money lifetime", + api_key="totalMoneyText", + unit_of_measurement=CURRENCY_EURO, + ), + GrowattSensorEntityDescription( + key="total_energy_today", + name="Energy Today", + api_key="todayEnergy", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, + ), + GrowattSensorEntityDescription( + key="total_output_power", + name="Output Power", + api_key="invTodayPpv", + unit_of_measurement=POWER_WATT, + device_class=DEVICE_CLASS_POWER, + ), + GrowattSensorEntityDescription( + key="total_energy_output", + name="Lifetime energy output", + api_key="totalEnergy", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, + ), + GrowattSensorEntityDescription( + key="total_maximum_output", + name="Maximum power", + api_key="nominalPower", + unit_of_measurement=POWER_WATT, + device_class=DEVICE_CLASS_POWER, + ), +) + +INVERTER_SENSOR_TYPES: tuple[GrowattSensorEntityDescription, ...] = ( + GrowattSensorEntityDescription( + key="inverter_energy_today", + name="Energy today", + api_key="powerToday", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, + precision=1, + ), + GrowattSensorEntityDescription( + key="inverter_energy_total", + name="Lifetime energy output", + api_key="powerTotal", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, + precision=1, + ), + GrowattSensorEntityDescription( + key="inverter_voltage_input_1", + name="Input 1 voltage", + api_key="vpv1", + unit_of_measurement=ELECTRIC_POTENTIAL_VOLT, + device_class=DEVICE_CLASS_VOLTAGE, + precision=2, + ), + GrowattSensorEntityDescription( + key="inverter_amperage_input_1", + name="Input 1 Amperage", + api_key="ipv1", + unit_of_measurement=ELECTRIC_CURRENT_AMPERE, + device_class=DEVICE_CLASS_CURRENT, + precision=1, + ), + GrowattSensorEntityDescription( + key="inverter_wattage_input_1", + name="Input 1 Wattage", + api_key="ppv1", + unit_of_measurement=POWER_WATT, + device_class=DEVICE_CLASS_POWER, + precision=1, + ), + GrowattSensorEntityDescription( + key="inverter_voltage_input_2", + name="Input 2 voltage", + api_key="vpv2", + unit_of_measurement=ELECTRIC_POTENTIAL_VOLT, + device_class=DEVICE_CLASS_VOLTAGE, + precision=1, + ), + GrowattSensorEntityDescription( + key="inverter_amperage_input_2", + name="Input 2 Amperage", + api_key="ipv2", + unit_of_measurement=ELECTRIC_CURRENT_AMPERE, + device_class=DEVICE_CLASS_CURRENT, + precision=1, + ), + GrowattSensorEntityDescription( + key="inverter_wattage_input_2", + name="Input 2 Wattage", + api_key="ppv2", + unit_of_measurement=POWER_WATT, + device_class=DEVICE_CLASS_POWER, + precision=1, + ), + GrowattSensorEntityDescription( + key="inverter_voltage_input_3", + name="Input 3 voltage", + api_key="vpv3", + unit_of_measurement=ELECTRIC_POTENTIAL_VOLT, + device_class=DEVICE_CLASS_VOLTAGE, + precision=1, + ), + GrowattSensorEntityDescription( + key="inverter_amperage_input_3", + name="Input 3 Amperage", + api_key="ipv3", + unit_of_measurement=ELECTRIC_CURRENT_AMPERE, + device_class=DEVICE_CLASS_CURRENT, + precision=1, + ), + GrowattSensorEntityDescription( + key="inverter_wattage_input_3", + name="Input 3 Wattage", + api_key="ppv3", + unit_of_measurement=POWER_WATT, + device_class=DEVICE_CLASS_POWER, + precision=1, + ), + GrowattSensorEntityDescription( + key="inverter_internal_wattage", + name="Internal wattage", + api_key="ppv", + unit_of_measurement=POWER_WATT, + device_class=DEVICE_CLASS_POWER, + precision=1, + ), + GrowattSensorEntityDescription( + key="inverter_reactive_voltage", + name="Reactive voltage", + api_key="vacr", + unit_of_measurement=ELECTRIC_POTENTIAL_VOLT, + device_class=DEVICE_CLASS_VOLTAGE, + precision=1, + ), + GrowattSensorEntityDescription( + key="inverter_inverter_reactive_amperage", + name="Reactive amperage", + api_key="iacr", + unit_of_measurement=ELECTRIC_CURRENT_AMPERE, + device_class=DEVICE_CLASS_CURRENT, + precision=1, + ), + GrowattSensorEntityDescription( + key="inverter_frequency", + name="AC frequency", + api_key="fac", + unit_of_measurement=FREQUENCY_HERTZ, + precision=1, + ), + GrowattSensorEntityDescription( + key="inverter_current_wattage", + name="Output power", + api_key="pac", + unit_of_measurement=POWER_WATT, + device_class=DEVICE_CLASS_POWER, + precision=1, + ), + GrowattSensorEntityDescription( + key="inverter_current_reactive_wattage", + name="Reactive wattage", + api_key="pacr", + unit_of_measurement=POWER_WATT, + device_class=DEVICE_CLASS_POWER, + precision=1, + ), + GrowattSensorEntityDescription( + key="inverter_ipm_temperature", + name="Intelligent Power Management temperature", + api_key="ipmTemperature", + unit_of_measurement=TEMP_CELSIUS, + device_class=DEVICE_CLASS_TEMPERATURE, + precision=1, + ), + GrowattSensorEntityDescription( + key="inverter_temperature", + name="Temperature", + api_key="temperature", + unit_of_measurement=TEMP_CELSIUS, + device_class=DEVICE_CLASS_TEMPERATURE, + precision=1, + ), +) + +STORAGE_SENSOR_TYPES: tuple[GrowattSensorEntityDescription, ...] = ( + GrowattSensorEntityDescription( + key="storage_storage_production_today", + name="Storage production today", + api_key="eBatDisChargeToday", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, + ), + GrowattSensorEntityDescription( + key="storage_storage_production_lifetime", + name="Lifetime Storage production", + api_key="eBatDisChargeTotal", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, + ), + GrowattSensorEntityDescription( + key="storage_grid_discharge_today", + name="Grid discharged today", + api_key="eacDisChargeToday", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, + ), + GrowattSensorEntityDescription( + key="storage_load_consumption_today", + name="Load consumption today", + api_key="eopDischrToday", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, + ), + GrowattSensorEntityDescription( + key="storage_load_consumption_lifetime", + name="Lifetime load consumption", + api_key="eopDischrTotal", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, + ), + GrowattSensorEntityDescription( + key="storage_grid_charged_today", + name="Grid charged today", + api_key="eacChargeToday", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, + ), + GrowattSensorEntityDescription( + key="storage_charge_storage_lifetime", + name="Lifetime storaged charged", + api_key="eChargeTotal", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, + ), + GrowattSensorEntityDescription( + key="storage_solar_production", + name="Solar power production", + api_key="ppv", + unit_of_measurement=POWER_WATT, + device_class=DEVICE_CLASS_POWER, + ), + GrowattSensorEntityDescription( + key="storage_battery_percentage", + name="Battery percentage", + api_key="capacity", + unit_of_measurement=PERCENTAGE, + device_class=DEVICE_CLASS_BATTERY, + ), + GrowattSensorEntityDescription( + key="storage_power_flow", + name="Storage charging/ discharging(-ve)", + api_key="pCharge", + unit_of_measurement=POWER_WATT, + device_class=DEVICE_CLASS_POWER, + ), + GrowattSensorEntityDescription( + key="storage_load_consumption_solar_storage", + name="Load consumption(Solar + Storage)", + api_key="rateVA", + unit_of_measurement="VA", + ), + GrowattSensorEntityDescription( + key="storage_charge_today", + name="Charge today", + api_key="eChargeToday", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, + ), + GrowattSensorEntityDescription( + key="storage_import_from_grid", + name="Import from grid", + api_key="pAcInPut", + unit_of_measurement=POWER_WATT, + device_class=DEVICE_CLASS_POWER, + ), + GrowattSensorEntityDescription( + key="storage_import_from_grid_today", + name="Import from grid today", + api_key="eToUserToday", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, + ), + GrowattSensorEntityDescription( + key="storage_import_from_grid_total", + name="Import from grid total", + api_key="eToUserTotal", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, + ), + GrowattSensorEntityDescription( + key="storage_load_consumption", + name="Load consumption", + api_key="outPutPower", + unit_of_measurement=POWER_WATT, + device_class=DEVICE_CLASS_POWER, + ), + GrowattSensorEntityDescription( + key="storage_grid_voltage", + name="AC input voltage", + api_key="vGrid", + unit_of_measurement=ELECTRIC_POTENTIAL_VOLT, + device_class=DEVICE_CLASS_VOLTAGE, + precision=2, + ), + GrowattSensorEntityDescription( + key="storage_pv_charging_voltage", + name="PV charging voltage", + api_key="vpv", + unit_of_measurement=ELECTRIC_POTENTIAL_VOLT, + device_class=DEVICE_CLASS_VOLTAGE, + precision=2, + ), + GrowattSensorEntityDescription( + key="storage_ac_input_frequency_out", + name="AC input frequency", + api_key="freqOutPut", + unit_of_measurement=FREQUENCY_HERTZ, + precision=2, + ), + GrowattSensorEntityDescription( + key="storage_output_voltage", + name="Output voltage", + api_key="outPutVolt", + unit_of_measurement=ELECTRIC_POTENTIAL_VOLT, + device_class=DEVICE_CLASS_VOLTAGE, + precision=2, + ), + GrowattSensorEntityDescription( + key="storage_ac_output_frequency", + name="Ac output frequency", + api_key="freqGrid", + unit_of_measurement=FREQUENCY_HERTZ, + precision=2, + ), + GrowattSensorEntityDescription( + key="storage_current_PV", + name="Solar charge current", + api_key="iAcCharge", + unit_of_measurement=ELECTRIC_CURRENT_AMPERE, + device_class=DEVICE_CLASS_CURRENT, + precision=2, + ), + GrowattSensorEntityDescription( + key="storage_current_1", + name="Solar current to storage", + api_key="iChargePV1", + unit_of_measurement=ELECTRIC_CURRENT_AMPERE, + device_class=DEVICE_CLASS_CURRENT, + precision=2, + ), + GrowattSensorEntityDescription( + key="storage_grid_amperage_input", + name="Grid charge current", + api_key="chgCurr", + unit_of_measurement=ELECTRIC_CURRENT_AMPERE, + device_class=DEVICE_CLASS_CURRENT, + precision=2, + ), + GrowattSensorEntityDescription( + key="storage_grid_out_current", + name="Grid out current", + api_key="outPutCurrent", + unit_of_measurement=ELECTRIC_CURRENT_AMPERE, + device_class=DEVICE_CLASS_CURRENT, + precision=2, + ), + GrowattSensorEntityDescription( + key="storage_battery_voltage", + name="Battery voltage", + api_key="vBat", + unit_of_measurement=ELECTRIC_POTENTIAL_VOLT, + device_class=DEVICE_CLASS_VOLTAGE, + precision=2, + ), + GrowattSensorEntityDescription( + key="storage_load_percentage", + name="Load percentage", + api_key="loadPercent", + unit_of_measurement=PERCENTAGE, + device_class=DEVICE_CLASS_BATTERY, + precision=2, + ), +) + +MIX_SENSOR_TYPES: tuple[GrowattSensorEntityDescription, ...] = ( # Values from 'mix_info' API call - "mix_statement_of_charge": ( - "Statement of charge", - PERCENTAGE, - "capacity", - {"device_class": DEVICE_CLASS_BATTERY}, + GrowattSensorEntityDescription( + key="mix_statement_of_charge", + name="Statement of charge", + api_key="capacity", + unit_of_measurement=PERCENTAGE, + device_class=DEVICE_CLASS_BATTERY, ), - "mix_battery_charge_today": ( - "Battery charged today", - ENERGY_KILO_WATT_HOUR, - "eBatChargeToday", - {"device_class": DEVICE_CLASS_ENERGY}, + GrowattSensorEntityDescription( + key="mix_battery_charge_today", + name="Battery charged today", + api_key="eBatChargeToday", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, ), - "mix_battery_charge_lifetime": ( - "Lifetime battery charged", - ENERGY_KILO_WATT_HOUR, - "eBatChargeTotal", - {"device_class": DEVICE_CLASS_ENERGY}, + GrowattSensorEntityDescription( + key="mix_battery_charge_lifetime", + name="Lifetime battery charged", + api_key="eBatChargeTotal", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, ), - "mix_battery_discharge_today": ( - "Battery discharged today", - ENERGY_KILO_WATT_HOUR, - "eBatDisChargeToday", - {"device_class": DEVICE_CLASS_ENERGY}, + GrowattSensorEntityDescription( + key="mix_battery_discharge_today", + name="Battery discharged today", + api_key="eBatDisChargeToday", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, ), - "mix_battery_discharge_lifetime": ( - "Lifetime battery discharged", - ENERGY_KILO_WATT_HOUR, - "eBatDisChargeTotal", - {"device_class": DEVICE_CLASS_ENERGY}, + GrowattSensorEntityDescription( + key="mix_battery_discharge_lifetime", + name="Lifetime battery discharged", + api_key="eBatDisChargeTotal", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, ), - "mix_solar_generation_today": ( - "Solar energy today", - ENERGY_KILO_WATT_HOUR, - "epvToday", - {"device_class": DEVICE_CLASS_ENERGY}, + GrowattSensorEntityDescription( + key="mix_solar_generation_today", + name="Solar energy today", + api_key="epvToday", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, ), - "mix_solar_generation_lifetime": ( - "Lifetime solar energy", - ENERGY_KILO_WATT_HOUR, - "epvTotal", - {"device_class": DEVICE_CLASS_ENERGY}, + GrowattSensorEntityDescription( + key="mix_solar_generation_lifetime", + name="Lifetime solar energy", + api_key="epvTotal", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, ), - "mix_battery_discharge_w": ( - "Battery discharging W", - POWER_WATT, - "pDischarge1", - {"device_class": DEVICE_CLASS_POWER}, + GrowattSensorEntityDescription( + key="mix_battery_discharge_w", + name="Battery discharging W", + api_key="pDischarge1", + unit_of_measurement=POWER_WATT, + device_class=DEVICE_CLASS_POWER, ), - "mix_battery_voltage": ( - "Battery voltage", - ELECTRIC_POTENTIAL_VOLT, - "vbat", - {"device_class": DEVICE_CLASS_VOLTAGE}, + GrowattSensorEntityDescription( + key="mix_battery_voltage", + name="Battery voltage", + api_key="vbat", + unit_of_measurement=ELECTRIC_POTENTIAL_VOLT, + device_class=DEVICE_CLASS_VOLTAGE, ), - "mix_pv1_voltage": ( - "PV1 voltage", - ELECTRIC_POTENTIAL_VOLT, - "vpv1", - {"device_class": DEVICE_CLASS_VOLTAGE}, + GrowattSensorEntityDescription( + key="mix_pv1_voltage", + name="PV1 voltage", + api_key="vpv1", + unit_of_measurement=ELECTRIC_POTENTIAL_VOLT, + device_class=DEVICE_CLASS_VOLTAGE, ), - "mix_pv2_voltage": ( - "PV2 voltage", - ELECTRIC_POTENTIAL_VOLT, - "vpv2", - {"device_class": DEVICE_CLASS_VOLTAGE}, + GrowattSensorEntityDescription( + key="mix_pv2_voltage", + name="PV2 voltage", + api_key="vpv2", + unit_of_measurement=ELECTRIC_POTENTIAL_VOLT, + device_class=DEVICE_CLASS_VOLTAGE, ), # Values from 'mix_totals' API call - "mix_load_consumption_today": ( - "Load consumption today", - ENERGY_KILO_WATT_HOUR, - "elocalLoadToday", - {"device_class": DEVICE_CLASS_ENERGY}, + GrowattSensorEntityDescription( + key="mix_load_consumption_today", + name="Load consumption today", + api_key="elocalLoadToday", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, ), - "mix_load_consumption_lifetime": ( - "Lifetime load consumption", - ENERGY_KILO_WATT_HOUR, - "elocalLoadTotal", - {"device_class": DEVICE_CLASS_ENERGY}, + GrowattSensorEntityDescription( + key="mix_load_consumption_lifetime", + name="Lifetime load consumption", + api_key="elocalLoadTotal", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, ), - "mix_export_to_grid_today": ( - "Export to grid today", - ENERGY_KILO_WATT_HOUR, - "etoGridToday", - {"device_class": DEVICE_CLASS_ENERGY}, + GrowattSensorEntityDescription( + key="mix_export_to_grid_today", + name="Export to grid today", + api_key="etoGridToday", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, ), - "mix_export_to_grid_lifetime": ( - "Lifetime export to grid", - ENERGY_KILO_WATT_HOUR, - "etogridTotal", - {"device_class": DEVICE_CLASS_ENERGY}, + GrowattSensorEntityDescription( + key="mix_export_to_grid_lifetime", + name="Lifetime export to grid", + api_key="etogridTotal", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, ), # Values from 'mix_system_status' API call - "mix_battery_charge": ( - "Battery charging", - POWER_KILO_WATT, - "chargePower", - {"device_class": DEVICE_CLASS_POWER}, + GrowattSensorEntityDescription( + key="mix_battery_charge", + name="Battery charging", + api_key="chargePower", + unit_of_measurement=POWER_KILO_WATT, + device_class=DEVICE_CLASS_POWER, ), - "mix_load_consumption": ( - "Load consumption", - POWER_KILO_WATT, - "pLocalLoad", - {"device_class": DEVICE_CLASS_POWER}, + GrowattSensorEntityDescription( + key="mix_load_consumption", + name="Load consumption", + api_key="pLocalLoad", + unit_of_measurement=POWER_KILO_WATT, + device_class=DEVICE_CLASS_POWER, ), - "mix_wattage_pv_1": ( - "PV1 Wattage", - POWER_KILO_WATT, - "pPv1", - {"device_class": DEVICE_CLASS_POWER}, + GrowattSensorEntityDescription( + key="mix_wattage_pv_1", + name="PV1 Wattage", + api_key="pPv1", + unit_of_measurement=POWER_KILO_WATT, + device_class=DEVICE_CLASS_POWER, ), - "mix_wattage_pv_2": ( - "PV2 Wattage", - POWER_KILO_WATT, - "pPv2", - {"device_class": DEVICE_CLASS_POWER}, + GrowattSensorEntityDescription( + key="mix_wattage_pv_2", + name="PV2 Wattage", + api_key="pPv2", + unit_of_measurement=POWER_KILO_WATT, + device_class=DEVICE_CLASS_POWER, ), - "mix_wattage_pv_all": ( - "All PV Wattage", - POWER_KILO_WATT, - "ppv", - {"device_class": DEVICE_CLASS_POWER}, + GrowattSensorEntityDescription( + key="mix_wattage_pv_all", + name="All PV Wattage", + api_key="ppv", + unit_of_measurement=POWER_KILO_WATT, + device_class=DEVICE_CLASS_POWER, ), - "mix_export_to_grid": ( - "Export to grid", - POWER_KILO_WATT, - "pactogrid", - {"device_class": DEVICE_CLASS_POWER}, + GrowattSensorEntityDescription( + key="mix_export_to_grid", + name="Export to grid", + api_key="pactogrid", + unit_of_measurement=POWER_KILO_WATT, + device_class=DEVICE_CLASS_POWER, ), - "mix_import_from_grid": ( - "Import from grid", - POWER_KILO_WATT, - "pactouser", - {"device_class": DEVICE_CLASS_POWER}, + GrowattSensorEntityDescription( + key="mix_import_from_grid", + name="Import from grid", + api_key="pactouser", + unit_of_measurement=POWER_KILO_WATT, + device_class=DEVICE_CLASS_POWER, ), - "mix_battery_discharge_kw": ( - "Battery discharging kW", - POWER_KILO_WATT, - "pdisCharge1", - {"device_class": DEVICE_CLASS_POWER}, + GrowattSensorEntityDescription( + key="mix_battery_discharge_kw", + name="Battery discharging kW", + api_key="pdisCharge1", + unit_of_measurement=POWER_KILO_WATT, + device_class=DEVICE_CLASS_POWER, ), - "mix_grid_voltage": ( - "Grid voltage", - ELECTRIC_POTENTIAL_VOLT, - "vAc1", - {"device_class": DEVICE_CLASS_VOLTAGE}, + GrowattSensorEntityDescription( + key="mix_grid_voltage", + name="Grid voltage", + api_key="vAc1", + unit_of_measurement=ELECTRIC_POTENTIAL_VOLT, + device_class=DEVICE_CLASS_VOLTAGE, ), # Values from 'mix_detail' API call - "mix_system_production_today": ( - "System production today (self-consumption + export)", - ENERGY_KILO_WATT_HOUR, - "eCharge", - {"device_class": DEVICE_CLASS_ENERGY}, + GrowattSensorEntityDescription( + key="mix_system_production_today", + name="System production today (self-consumption + export)", + api_key="eCharge", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, ), - "mix_load_consumption_solar_today": ( - "Load consumption today (solar)", - ENERGY_KILO_WATT_HOUR, - "eChargeToday", - {"device_class": DEVICE_CLASS_ENERGY}, + GrowattSensorEntityDescription( + key="mix_load_consumption_solar_today", + name="Load consumption today (solar)", + api_key="eChargeToday", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, ), - "mix_self_consumption_today": ( - "Self consumption today (solar + battery)", - ENERGY_KILO_WATT_HOUR, - "eChargeToday1", - {"device_class": DEVICE_CLASS_ENERGY}, + GrowattSensorEntityDescription( + key="mix_self_consumption_today", + name="Self consumption today (solar + battery)", + api_key="eChargeToday1", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, ), - "mix_load_consumption_battery_today": ( - "Load consumption today (battery)", - ENERGY_KILO_WATT_HOUR, - "echarge1", - {"device_class": DEVICE_CLASS_ENERGY}, + GrowattSensorEntityDescription( + key="mix_load_consumption_battery_today", + name="Load consumption today (battery)", + api_key="echarge1", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, ), - "mix_import_from_grid_today": ( - "Import from grid today (load)", - ENERGY_KILO_WATT_HOUR, - "etouser", - {"device_class": DEVICE_CLASS_ENERGY}, + GrowattSensorEntityDescription( + key="mix_import_from_grid_today", + name="Import from grid today (load)", + api_key="etouser", + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, ), # This sensor is manually created using the most recent X-Axis value from the chartData - "mix_last_update": ( - "Last Data Update", - None, - "lastdataupdate", - {"device_class": DEVICE_CLASS_TIMESTAMP}, + GrowattSensorEntityDescription( + key="mix_last_update", + name="Last Data Update", + api_key="lastdataupdate", + unit_of_measurement=None, + device_class=DEVICE_CLASS_TIMESTAMP, ), # Values from 'dashboard_data' API call - "mix_import_from_grid_today_combined": ( - "Import from grid today (load + charging)", - ENERGY_KILO_WATT_HOUR, - "etouser_combined", # This id is not present in the raw API data, it is added by the sensor - {"device_class": DEVICE_CLASS_ENERGY}, + GrowattSensorEntityDescription( + key="mix_import_from_grid_today_combined", + name="Import from grid today (load + charging)", + api_key="etouser_combined", # This id is not present in the raw API data, it is added by the sensor + unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, ), -} - -SENSOR_TYPES = { - **TOTAL_SENSOR_TYPES, - **INVERTER_SENSOR_TYPES, - **STORAGE_SENSOR_TYPES, - **MIX_SENSOR_TYPES, -} +) def get_device_list(api, config): @@ -579,42 +711,48 @@ async def async_setup_entry(hass, config_entry, async_add_entities): devices, plant_id = await hass.async_add_executor_job(get_device_list, api, config) - entities = [] probe = GrowattData(api, username, password, plant_id, "total") - for sensor in TOTAL_SENSOR_TYPES: - entities.append( - GrowattInverter(probe, f"{name} Total", sensor, f"{plant_id}-{sensor}") + entities = [ + GrowattInverter( + probe, + name=f"{name} Total", + unique_id=f"{plant_id}-{description.key}", + description=description, ) + for description in TOTAL_SENSOR_TYPES + ] # Add sensors for each device in the specified plant. for device in devices: probe = GrowattData( api, username, password, device["deviceSn"], device["deviceType"] ) - sensors = [] + sensor_descriptions = () if device["deviceType"] == "inverter": - sensors = INVERTER_SENSOR_TYPES + sensor_descriptions = INVERTER_SENSOR_TYPES elif device["deviceType"] == "storage": probe.plant_id = plant_id - sensors = STORAGE_SENSOR_TYPES + sensor_descriptions = STORAGE_SENSOR_TYPES elif device["deviceType"] == "mix": probe.plant_id = plant_id - sensors = MIX_SENSOR_TYPES + sensor_descriptions = MIX_SENSOR_TYPES else: _LOGGER.debug( "Device type %s was found but is not supported right now", device["deviceType"], ) - for sensor in sensors: - entities.append( + entities.extend( + [ GrowattInverter( probe, - f"{device['deviceAilas']}", - sensor, - f"{device['deviceSn']}-{sensor}", + name=f"{device['deviceAilas']}", + unique_id=f"{device['deviceSn']}-{description.key}", + description=description, ) - ) + for description in sensor_descriptions + ] + ) async_add_entities(entities, True) @@ -622,48 +760,27 @@ async def async_setup_entry(hass, config_entry, async_add_entities): class GrowattInverter(SensorEntity): """Representation of a Growatt Sensor.""" - def __init__(self, probe, name, sensor, unique_id): + entity_description: GrowattSensorEntityDescription + + def __init__( + self, probe, name, unique_id, description: GrowattSensorEntityDescription + ): """Initialize a PVOutput sensor.""" - self.sensor = sensor self.probe = probe - self._name = name - self._state = None - self._unique_id = unique_id + self.entity_description = description - @property - def name(self): - """Return the name of the sensor.""" - return f"{self._name} {SENSOR_TYPES[self.sensor][0]}" - - @property - def unique_id(self): - """Return the unique id of the sensor.""" - return self._unique_id - - @property - def icon(self): - """Return the icon of the sensor.""" - return "mdi:solar-power" + self._attr_name = f"{name} {description.name}" + self._attr_unique_id = unique_id + self._attr_icon = "mdi:solar-power" @property def state(self): """Return the state of the sensor.""" - result = self.probe.get_data(SENSOR_TYPES[self.sensor][2]) - round_to = SENSOR_TYPES[self.sensor][3].get("round") - if round_to is not None: - result = round(result, round_to) + result = self.probe.get_data(self.entity_description.api_key) + if self.entity_description.precision is not None: + result = round(result, self.entity_description.precision) return result - @property - def device_class(self): - """Return the device class of the sensor.""" - return SENSOR_TYPES[self.sensor][3].get("device_class") - - @property - def unit_of_measurement(self): - """Return the unit of measurement of this entity, if any.""" - return SENSOR_TYPES[self.sensor][1] - def update(self): """Get the latest data from the Growat API and updates the state.""" self.probe.update()