179 lines
5.6 KiB
Python
179 lines
5.6 KiB
Python
"""Read status of SunWEG inverters."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from types import MappingProxyType
|
|
from typing import Any
|
|
|
|
from sunweg.api import APIHelper
|
|
from sunweg.device import Inverter
|
|
from sunweg.plant import Plant
|
|
|
|
from homeassistant.components.sensor import SensorEntity
|
|
from homeassistant.config_entries import ConfigEntry
|
|
from homeassistant.const import CONF_NAME
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.device_registry import DeviceInfo
|
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
|
|
from . import SunWEGData
|
|
from .const import CONF_PLANT_ID, DEFAULT_PLANT_ID, DOMAIN, DeviceType
|
|
from .sensor_types.inverter import INVERTER_SENSOR_TYPES
|
|
from .sensor_types.phase import PHASE_SENSOR_TYPES
|
|
from .sensor_types.sensor_entity_description import SunWEGSensorEntityDescription
|
|
from .sensor_types.string import STRING_SENSOR_TYPES
|
|
from .sensor_types.total import TOTAL_SENSOR_TYPES
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
def get_device_list(
|
|
api: APIHelper, config: MappingProxyType[str, Any]
|
|
) -> tuple[list[Inverter], int]:
|
|
"""Retrieve the device list for the selected plant."""
|
|
plant_id = int(config[CONF_PLANT_ID])
|
|
|
|
if plant_id == DEFAULT_PLANT_ID:
|
|
plant_info: list[Plant] = api.listPlants()
|
|
plant_id = plant_info[0].id
|
|
|
|
devices: list[Inverter] = []
|
|
# Get a list of devices for specified plant to add sensors for.
|
|
for inverter in api.plant(plant_id).inverters:
|
|
api.complete_inverter(inverter)
|
|
devices.append(inverter)
|
|
return (devices, plant_id)
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
config_entry: ConfigEntry,
|
|
async_add_entities: AddEntitiesCallback,
|
|
) -> None:
|
|
"""Set up the SunWEG sensor."""
|
|
name = config_entry.data[CONF_NAME]
|
|
|
|
probe: SunWEGData = hass.data[DOMAIN][config_entry.entry_id]
|
|
|
|
devices, plant_id = await hass.async_add_executor_job(
|
|
get_device_list, probe.api, config_entry.data
|
|
)
|
|
|
|
entities = [
|
|
SunWEGInverter(
|
|
probe,
|
|
name=f"{name} Total",
|
|
unique_id=f"{plant_id}-{description.key}",
|
|
description=description,
|
|
device_type=DeviceType.TOTAL,
|
|
)
|
|
for description in TOTAL_SENSOR_TYPES
|
|
]
|
|
|
|
# Add sensors for each device in the specified plant.
|
|
entities.extend(
|
|
[
|
|
SunWEGInverter(
|
|
probe,
|
|
name=f"{device.name}",
|
|
unique_id=f"{device.sn}-{description.key}",
|
|
description=description,
|
|
device_type=DeviceType.INVERTER,
|
|
inverter_id=device.id,
|
|
)
|
|
for device in devices
|
|
for description in INVERTER_SENSOR_TYPES
|
|
]
|
|
)
|
|
|
|
entities.extend(
|
|
[
|
|
SunWEGInverter(
|
|
probe,
|
|
name=f"{device.name} {phase.name}",
|
|
unique_id=f"{device.sn}-{phase.name}-{description.key}",
|
|
description=description,
|
|
inverter_id=device.id,
|
|
device_type=DeviceType.PHASE,
|
|
deep_name=phase.name,
|
|
)
|
|
for device in devices
|
|
for phase in device.phases
|
|
for description in PHASE_SENSOR_TYPES
|
|
]
|
|
)
|
|
|
|
entities.extend(
|
|
[
|
|
SunWEGInverter(
|
|
probe,
|
|
name=f"{device.name} {string.name}",
|
|
unique_id=f"{device.sn}-{string.name}-{description.key}",
|
|
description=description,
|
|
inverter_id=device.id,
|
|
device_type=DeviceType.STRING,
|
|
deep_name=string.name,
|
|
)
|
|
for device in devices
|
|
for mppt in device.mppts
|
|
for string in mppt.strings
|
|
for description in STRING_SENSOR_TYPES
|
|
]
|
|
)
|
|
|
|
async_add_entities(entities, True)
|
|
|
|
|
|
class SunWEGInverter(SensorEntity):
|
|
"""Representation of a SunWEG Sensor."""
|
|
|
|
entity_description: SunWEGSensorEntityDescription
|
|
|
|
def __init__(
|
|
self,
|
|
probe: SunWEGData,
|
|
name: str,
|
|
unique_id: str,
|
|
description: SunWEGSensorEntityDescription,
|
|
device_type: DeviceType,
|
|
inverter_id: int = 0,
|
|
deep_name: str | None = None,
|
|
) -> None:
|
|
"""Initialize a sensor."""
|
|
self.probe = probe
|
|
self.entity_description = description
|
|
self.device_type = device_type
|
|
self.inverter_id = inverter_id
|
|
self.deep_name = deep_name
|
|
|
|
self._attr_name = f"{name} {description.name}"
|
|
self._attr_unique_id = unique_id
|
|
self._attr_icon = (
|
|
description.icon if description.icon is not None else "mdi:solar-power"
|
|
)
|
|
|
|
self._attr_device_info = DeviceInfo(
|
|
identifiers={(DOMAIN, str(probe.plant_id))},
|
|
manufacturer="SunWEG",
|
|
name=name,
|
|
)
|
|
|
|
def update(self) -> None:
|
|
"""Get the latest data from the Sun WEG API and updates the state."""
|
|
self.probe.update()
|
|
(
|
|
self._attr_native_value,
|
|
self._attr_native_unit_of_measurement,
|
|
) = self.probe.get_data(
|
|
api_variable_key=self.entity_description.api_variable_key,
|
|
api_variable_unit=self.entity_description.api_variable_unit,
|
|
deep_name=self.deep_name,
|
|
device_type=self.device_type,
|
|
inverter_id=self.inverter_id,
|
|
name=self.entity_description.name,
|
|
native_unit_of_measurement=self.native_unit_of_measurement,
|
|
never_resets=self.entity_description.never_resets,
|
|
previous_value_drop_threshold=self.entity_description.previous_value_drop_threshold,
|
|
)
|