1
mirror of https://github.com/home-assistant/core synced 2024-08-28 03:36:46 +02:00
ha-core/homeassistant/components/sunweg/sensor.py
2023-12-18 10:03:40 -10:00

178 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,
)