Add inverter-devices to solarlog (#123205)
* Add inverter-devices * Minor code adjustments * Update manifest.json Seperate dependency upgrade to seperate PR * Update requirements_all.txt Seperate dependency upgrade to seperate PR * Update requirements_test_all.txt Seperate dependency upgrade to seperate PR * Update homeassistant/components/solarlog/sensor.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Split up base class, document SolarLogSensorEntityDescription * Split up sensor types * Update snapshot * Add all devices in config_flow * Remove options flow * Move devices in config_entry from options to data * Correct mock_config_entry * Minor adjustments * Remove enabled_devices from config * Remove obsolete test * Update snapshot * Delete obsolete code snips * Update homeassistant/components/solarlog/sensor.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Remove obsolete test in setting up sensors * Update homeassistant/components/solarlog/sensor.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update homeassistant/components/solarlog/entity.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update homeassistant/components/solarlog/config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Fix typing error --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
parent
1d05a917f9
commit
20f9b9e412
8 changed files with 260 additions and 80 deletions
|
@ -1,8 +1,11 @@
|
|||
"""Platform for solarlog sensors."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
|
@ -17,22 +20,22 @@ from homeassistant.const import (
|
|||
UnitOfPower,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from . import SolarlogConfigEntry, SolarlogData
|
||||
from .const import DOMAIN
|
||||
from . import SolarlogConfigEntry
|
||||
from .entity import SolarLogCoordinatorEntity, SolarLogInverterEntity
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SolarLogSensorEntityDescription(SensorEntityDescription):
|
||||
"""Describes Solarlog sensor entity."""
|
||||
|
||||
value: Callable[[float | int], float] | Callable[[datetime], datetime] | None = None
|
||||
value_fn: Callable[[float | int], float] | Callable[[datetime], datetime] = (
|
||||
lambda value: value
|
||||
)
|
||||
|
||||
|
||||
SENSOR_TYPES: tuple[SolarLogSensorEntityDescription, ...] = (
|
||||
SOLARLOG_SENSOR_TYPES: tuple[SolarLogSensorEntityDescription, ...] = (
|
||||
SolarLogSensorEntityDescription(
|
||||
key="last_updated",
|
||||
translation_key="last_update",
|
||||
|
@ -71,28 +74,28 @@ SENSOR_TYPES: tuple[SolarLogSensorEntityDescription, ...] = (
|
|||
translation_key="yield_day",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
value=lambda value: round(value / 1000, 3),
|
||||
value_fn=lambda value: round(value / 1000, 3),
|
||||
),
|
||||
SolarLogSensorEntityDescription(
|
||||
key="yield_yesterday",
|
||||
translation_key="yield_yesterday",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
value=lambda value: round(value / 1000, 3),
|
||||
value_fn=lambda value: round(value / 1000, 3),
|
||||
),
|
||||
SolarLogSensorEntityDescription(
|
||||
key="yield_month",
|
||||
translation_key="yield_month",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
value=lambda value: round(value / 1000, 3),
|
||||
value_fn=lambda value: round(value / 1000, 3),
|
||||
),
|
||||
SolarLogSensorEntityDescription(
|
||||
key="yield_year",
|
||||
translation_key="yield_year",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
value=lambda value: round(value / 1000, 3),
|
||||
value_fn=lambda value: round(value / 1000, 3),
|
||||
),
|
||||
SolarLogSensorEntityDescription(
|
||||
key="yield_total",
|
||||
|
@ -100,7 +103,7 @@ SENSOR_TYPES: tuple[SolarLogSensorEntityDescription, ...] = (
|
|||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL,
|
||||
value=lambda value: round(value / 1000, 3),
|
||||
value_fn=lambda value: round(value / 1000, 3),
|
||||
),
|
||||
SolarLogSensorEntityDescription(
|
||||
key="consumption_ac",
|
||||
|
@ -114,28 +117,28 @@ SENSOR_TYPES: tuple[SolarLogSensorEntityDescription, ...] = (
|
|||
translation_key="consumption_day",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
value=lambda value: round(value / 1000, 3),
|
||||
value_fn=lambda value: round(value / 1000, 3),
|
||||
),
|
||||
SolarLogSensorEntityDescription(
|
||||
key="consumption_yesterday",
|
||||
translation_key="consumption_yesterday",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
value=lambda value: round(value / 1000, 3),
|
||||
value_fn=lambda value: round(value / 1000, 3),
|
||||
),
|
||||
SolarLogSensorEntityDescription(
|
||||
key="consumption_month",
|
||||
translation_key="consumption_month",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
value=lambda value: round(value / 1000, 3),
|
||||
value_fn=lambda value: round(value / 1000, 3),
|
||||
),
|
||||
SolarLogSensorEntityDescription(
|
||||
key="consumption_year",
|
||||
translation_key="consumption_year",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
value=lambda value: round(value / 1000, 3),
|
||||
value_fn=lambda value: round(value / 1000, 3),
|
||||
),
|
||||
SolarLogSensorEntityDescription(
|
||||
key="consumption_total",
|
||||
|
@ -143,7 +146,7 @@ SENSOR_TYPES: tuple[SolarLogSensorEntityDescription, ...] = (
|
|||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL,
|
||||
value=lambda value: round(value / 1000, 3),
|
||||
value_fn=lambda value: round(value / 1000, 3),
|
||||
),
|
||||
SolarLogSensorEntityDescription(
|
||||
key="self_consumption_year",
|
||||
|
@ -171,7 +174,7 @@ SENSOR_TYPES: tuple[SolarLogSensorEntityDescription, ...] = (
|
|||
native_unit_of_measurement=PERCENTAGE,
|
||||
device_class=SensorDeviceClass.POWER_FACTOR,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value=lambda value: round(value * 100, 1),
|
||||
value_fn=lambda value: round(value * 100, 1),
|
||||
),
|
||||
SolarLogSensorEntityDescription(
|
||||
key="efficiency",
|
||||
|
@ -179,7 +182,7 @@ SENSOR_TYPES: tuple[SolarLogSensorEntityDescription, ...] = (
|
|||
native_unit_of_measurement=PERCENTAGE,
|
||||
device_class=SensorDeviceClass.POWER_FACTOR,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value=lambda value: round(value * 100, 1),
|
||||
value_fn=lambda value: round(value * 100, 1),
|
||||
),
|
||||
SolarLogSensorEntityDescription(
|
||||
key="power_available",
|
||||
|
@ -194,7 +197,24 @@ SENSOR_TYPES: tuple[SolarLogSensorEntityDescription, ...] = (
|
|||
native_unit_of_measurement=PERCENTAGE,
|
||||
device_class=SensorDeviceClass.POWER_FACTOR,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value=lambda value: round(value * 100, 1),
|
||||
value_fn=lambda value: round(value * 100, 1),
|
||||
),
|
||||
)
|
||||
|
||||
INVERTER_SENSOR_TYPES: tuple[SolarLogSensorEntityDescription, ...] = (
|
||||
SolarLogSensorEntityDescription(
|
||||
key="current_power",
|
||||
translation_key="current_power",
|
||||
native_unit_of_measurement=UnitOfPower.WATT,
|
||||
device_class=SensorDeviceClass.POWER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
SolarLogSensorEntityDescription(
|
||||
key="consumption_year",
|
||||
translation_key="consumption_year",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
value_fn=lambda value: round(value / 1000, 3),
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -206,39 +226,50 @@ async def async_setup_entry(
|
|||
) -> None:
|
||||
"""Add solarlog entry."""
|
||||
coordinator = entry.runtime_data
|
||||
async_add_entities(
|
||||
SolarlogSensor(coordinator, description) for description in SENSOR_TYPES
|
||||
)
|
||||
|
||||
# https://github.com/python/mypy/issues/14294
|
||||
|
||||
entities: list[SensorEntity] = [
|
||||
SolarLogCoordinatorSensor(coordinator, sensor)
|
||||
for sensor in SOLARLOG_SENSOR_TYPES
|
||||
]
|
||||
|
||||
device_data: dict[str, Any] = coordinator.data["devices"]
|
||||
|
||||
if not device_data:
|
||||
entities.extend(
|
||||
SolarLogInverterSensor(coordinator, sensor, int(device_id))
|
||||
for device_id in device_data
|
||||
for sensor in INVERTER_SENSOR_TYPES
|
||||
if sensor.key in device_data[device_id]
|
||||
)
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class SolarlogSensor(CoordinatorEntity[SolarlogData], SensorEntity):
|
||||
"""Representation of a Sensor."""
|
||||
|
||||
_attr_has_entity_name = True
|
||||
class SolarLogCoordinatorSensor(SolarLogCoordinatorEntity, SensorEntity):
|
||||
"""Represents a SolarLog sensor."""
|
||||
|
||||
entity_description: SolarLogSensorEntityDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: SolarlogData,
|
||||
description: SolarLogSensorEntityDescription,
|
||||
) -> None:
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(coordinator)
|
||||
self.entity_description = description
|
||||
self._attr_unique_id = f"{coordinator.unique_id}_{description.key}"
|
||||
self._attr_device_info = DeviceInfo(
|
||||
identifiers={(DOMAIN, coordinator.unique_id)},
|
||||
manufacturer="Solar-Log",
|
||||
name=coordinator.name,
|
||||
configuration_url=coordinator.host,
|
||||
)
|
||||
@property
|
||||
def native_value(self) -> float | datetime:
|
||||
"""Return the state for this sensor."""
|
||||
|
||||
val = self.coordinator.data[self.entity_description.key]
|
||||
return self.entity_description.value_fn(val)
|
||||
|
||||
|
||||
class SolarLogInverterSensor(SolarLogInverterEntity, SensorEntity):
|
||||
"""Represents a SolarLog inverter sensor."""
|
||||
|
||||
entity_description: SolarLogSensorEntityDescription
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
"""Return the native sensor value."""
|
||||
raw_attr = self.coordinator.data.get(self.entity_description.key)
|
||||
def native_value(self) -> float | datetime:
|
||||
"""Return the state for this sensor."""
|
||||
|
||||
if self.entity_description.value:
|
||||
return self.entity_description.value(raw_attr)
|
||||
return raw_attr
|
||||
val = self.coordinator.data["devices"][self.device_id][
|
||||
self.entity_description.key
|
||||
]
|
||||
return self.entity_description.value_fn(val)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue