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:
dontinelli 2024-08-30 17:03:24 +02:00 committed by GitHub
parent 1d05a917f9
commit 20f9b9e412
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 260 additions and 80 deletions

View file

@ -7,17 +7,17 @@ from homeassistant.const import Platform
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er from homeassistant.helpers import entity_registry as er
from .coordinator import SolarlogData from .coordinator import SolarLogCoordinator
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
PLATFORMS = [Platform.SENSOR] PLATFORMS = [Platform.SENSOR]
type SolarlogConfigEntry = ConfigEntry[SolarlogData] type SolarlogConfigEntry = ConfigEntry[SolarLogCoordinator]
async def async_setup_entry(hass: HomeAssistant, entry: SolarlogConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: SolarlogConfigEntry) -> bool:
"""Set up a config entry for solarlog.""" """Set up a config entry for solarlog."""
coordinator = SolarlogData(hass, entry) coordinator = SolarLogCoordinator(hass, entry)
await coordinator.async_config_entry_first_refresh() await coordinator.async_config_entry_first_refresh()
entry.runtime_data = coordinator entry.runtime_data = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

View file

@ -24,7 +24,7 @@ if TYPE_CHECKING:
from . import SolarlogConfigEntry from . import SolarlogConfigEntry
class SolarlogData(update_coordinator.DataUpdateCoordinator): class SolarLogCoordinator(update_coordinator.DataUpdateCoordinator):
"""Get and update the latest data.""" """Get and update the latest data."""
def __init__(self, hass: HomeAssistant, entry: SolarlogConfigEntry) -> None: def __init__(self, hass: HomeAssistant, entry: SolarlogConfigEntry) -> None:
@ -49,12 +49,19 @@ class SolarlogData(update_coordinator.DataUpdateCoordinator):
self.host, extended_data, hass.config.time_zone self.host, extended_data, hass.config.time_zone
) )
async def _async_setup(self) -> None:
"""Do initialization logic."""
if self.solarlog.extended_data:
device_list = await self.solarlog.client.get_device_list()
self.solarlog.set_enabled_devices({key: True for key in device_list})
async def _async_update_data(self): async def _async_update_data(self):
"""Update the data from the SolarLog device.""" """Update the data from the SolarLog device."""
_LOGGER.debug("Start data update") _LOGGER.debug("Start data update")
try: try:
data = await self.solarlog.update_data() data = await self.solarlog.update_data()
await self.solarlog.update_device_list()
except SolarLogConnectionError as err: except SolarLogConnectionError as err:
raise ConfigEntryNotReady(err) from err raise ConfigEntryNotReady(err) from err
except SolarLogUpdateError as err: except SolarLogUpdateError as err:

View file

@ -0,0 +1,71 @@
"""Entities for SolarLog integration."""
from __future__ import annotations
from homeassistant.components.sensor import SensorEntityDescription
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from homeassistant.util import slugify
from .const import DOMAIN
from .coordinator import SolarLogCoordinator
class SolarLogBaseEntity(CoordinatorEntity[SolarLogCoordinator]):
"""SolarLog base entity."""
_attr_has_entity_name = True
def __init__(
self,
coordinator: SolarLogCoordinator,
description: SensorEntityDescription,
) -> None:
"""Initialize the SolarLogCoordinator sensor."""
super().__init__(coordinator)
self.entity_description = description
class SolarLogCoordinatorEntity(SolarLogBaseEntity):
"""Base SolarLog Coordinator entity."""
def __init__(
self,
coordinator: SolarLogCoordinator,
description: SensorEntityDescription,
) -> None:
"""Initialize the SolarLogCoordinator sensor."""
super().__init__(coordinator, description)
self._attr_unique_id = f"{coordinator.unique_id}-{description.key}"
self._attr_device_info = DeviceInfo(
manufacturer="Solar-Log",
model="Controller",
identifiers={(DOMAIN, coordinator.unique_id)},
name=coordinator.name,
configuration_url=coordinator.host,
)
class SolarLogInverterEntity(SolarLogBaseEntity):
"""Base SolarLog inverter entity."""
def __init__(
self,
coordinator: SolarLogCoordinator,
description: SensorEntityDescription,
device_id: int,
) -> None:
"""Initialize the SolarLogInverter sensor."""
super().__init__(coordinator, description)
name = f"{coordinator.unique_id}-{slugify(coordinator.solarlog.device_name(device_id))}"
self._attr_unique_id = f"{name}-{description.key}"
self._attr_device_info = DeviceInfo(
manufacturer="Solar-Log",
model="Inverter",
identifiers={(DOMAIN, name)},
name=coordinator.solarlog.device_name(device_id),
via_device=(DOMAIN, coordinator.unique_id),
)
self.device_id = device_id

View file

@ -1,8 +1,11 @@
"""Platform for solarlog sensors.""" """Platform for solarlog sensors."""
from __future__ import annotations
from collections.abc import Callable from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime from datetime import datetime
from typing import Any
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
SensorDeviceClass, SensorDeviceClass,
@ -17,22 +20,22 @@ from homeassistant.const import (
UnitOfPower, UnitOfPower,
) )
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import SolarlogConfigEntry, SolarlogData from . import SolarlogConfigEntry
from .const import DOMAIN from .entity import SolarLogCoordinatorEntity, SolarLogInverterEntity
@dataclass(frozen=True) @dataclass(frozen=True)
class SolarLogSensorEntityDescription(SensorEntityDescription): class SolarLogSensorEntityDescription(SensorEntityDescription):
"""Describes Solarlog sensor entity.""" """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( SolarLogSensorEntityDescription(
key="last_updated", key="last_updated",
translation_key="last_update", translation_key="last_update",
@ -71,28 +74,28 @@ SENSOR_TYPES: tuple[SolarLogSensorEntityDescription, ...] = (
translation_key="yield_day", translation_key="yield_day",
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY, device_class=SensorDeviceClass.ENERGY,
value=lambda value: round(value / 1000, 3), value_fn=lambda value: round(value / 1000, 3),
), ),
SolarLogSensorEntityDescription( SolarLogSensorEntityDescription(
key="yield_yesterday", key="yield_yesterday",
translation_key="yield_yesterday", translation_key="yield_yesterday",
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY, device_class=SensorDeviceClass.ENERGY,
value=lambda value: round(value / 1000, 3), value_fn=lambda value: round(value / 1000, 3),
), ),
SolarLogSensorEntityDescription( SolarLogSensorEntityDescription(
key="yield_month", key="yield_month",
translation_key="yield_month", translation_key="yield_month",
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY, device_class=SensorDeviceClass.ENERGY,
value=lambda value: round(value / 1000, 3), value_fn=lambda value: round(value / 1000, 3),
), ),
SolarLogSensorEntityDescription( SolarLogSensorEntityDescription(
key="yield_year", key="yield_year",
translation_key="yield_year", translation_key="yield_year",
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY, device_class=SensorDeviceClass.ENERGY,
value=lambda value: round(value / 1000, 3), value_fn=lambda value: round(value / 1000, 3),
), ),
SolarLogSensorEntityDescription( SolarLogSensorEntityDescription(
key="yield_total", key="yield_total",
@ -100,7 +103,7 @@ SENSOR_TYPES: tuple[SolarLogSensorEntityDescription, ...] = (
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY, device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL, state_class=SensorStateClass.TOTAL,
value=lambda value: round(value / 1000, 3), value_fn=lambda value: round(value / 1000, 3),
), ),
SolarLogSensorEntityDescription( SolarLogSensorEntityDescription(
key="consumption_ac", key="consumption_ac",
@ -114,28 +117,28 @@ SENSOR_TYPES: tuple[SolarLogSensorEntityDescription, ...] = (
translation_key="consumption_day", translation_key="consumption_day",
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY, device_class=SensorDeviceClass.ENERGY,
value=lambda value: round(value / 1000, 3), value_fn=lambda value: round(value / 1000, 3),
), ),
SolarLogSensorEntityDescription( SolarLogSensorEntityDescription(
key="consumption_yesterday", key="consumption_yesterday",
translation_key="consumption_yesterday", translation_key="consumption_yesterday",
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY, device_class=SensorDeviceClass.ENERGY,
value=lambda value: round(value / 1000, 3), value_fn=lambda value: round(value / 1000, 3),
), ),
SolarLogSensorEntityDescription( SolarLogSensorEntityDescription(
key="consumption_month", key="consumption_month",
translation_key="consumption_month", translation_key="consumption_month",
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY, device_class=SensorDeviceClass.ENERGY,
value=lambda value: round(value / 1000, 3), value_fn=lambda value: round(value / 1000, 3),
), ),
SolarLogSensorEntityDescription( SolarLogSensorEntityDescription(
key="consumption_year", key="consumption_year",
translation_key="consumption_year", translation_key="consumption_year",
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY, device_class=SensorDeviceClass.ENERGY,
value=lambda value: round(value / 1000, 3), value_fn=lambda value: round(value / 1000, 3),
), ),
SolarLogSensorEntityDescription( SolarLogSensorEntityDescription(
key="consumption_total", key="consumption_total",
@ -143,7 +146,7 @@ SENSOR_TYPES: tuple[SolarLogSensorEntityDescription, ...] = (
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY, device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL, state_class=SensorStateClass.TOTAL,
value=lambda value: round(value / 1000, 3), value_fn=lambda value: round(value / 1000, 3),
), ),
SolarLogSensorEntityDescription( SolarLogSensorEntityDescription(
key="self_consumption_year", key="self_consumption_year",
@ -171,7 +174,7 @@ SENSOR_TYPES: tuple[SolarLogSensorEntityDescription, ...] = (
native_unit_of_measurement=PERCENTAGE, native_unit_of_measurement=PERCENTAGE,
device_class=SensorDeviceClass.POWER_FACTOR, device_class=SensorDeviceClass.POWER_FACTOR,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
value=lambda value: round(value * 100, 1), value_fn=lambda value: round(value * 100, 1),
), ),
SolarLogSensorEntityDescription( SolarLogSensorEntityDescription(
key="efficiency", key="efficiency",
@ -179,7 +182,7 @@ SENSOR_TYPES: tuple[SolarLogSensorEntityDescription, ...] = (
native_unit_of_measurement=PERCENTAGE, native_unit_of_measurement=PERCENTAGE,
device_class=SensorDeviceClass.POWER_FACTOR, device_class=SensorDeviceClass.POWER_FACTOR,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
value=lambda value: round(value * 100, 1), value_fn=lambda value: round(value * 100, 1),
), ),
SolarLogSensorEntityDescription( SolarLogSensorEntityDescription(
key="power_available", key="power_available",
@ -194,7 +197,24 @@ SENSOR_TYPES: tuple[SolarLogSensorEntityDescription, ...] = (
native_unit_of_measurement=PERCENTAGE, native_unit_of_measurement=PERCENTAGE,
device_class=SensorDeviceClass.POWER_FACTOR, device_class=SensorDeviceClass.POWER_FACTOR,
state_class=SensorStateClass.MEASUREMENT, 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: ) -> None:
"""Add solarlog entry.""" """Add solarlog entry."""
coordinator = entry.runtime_data 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): class SolarLogCoordinatorSensor(SolarLogCoordinatorEntity, SensorEntity):
"""Representation of a Sensor.""" """Represents a SolarLog sensor."""
_attr_has_entity_name = True
entity_description: SolarLogSensorEntityDescription entity_description: SolarLogSensorEntityDescription
def __init__( @property
self, def native_value(self) -> float | datetime:
coordinator: SolarlogData, """Return the state for this sensor."""
description: SolarLogSensorEntityDescription,
) -> None: val = self.coordinator.data[self.entity_description.key]
"""Initialize the sensor.""" return self.entity_description.value_fn(val)
super().__init__(coordinator)
self.entity_description = description
self._attr_unique_id = f"{coordinator.unique_id}_{description.key}" class SolarLogInverterSensor(SolarLogInverterEntity, SensorEntity):
self._attr_device_info = DeviceInfo( """Represents a SolarLog inverter sensor."""
identifiers={(DOMAIN, coordinator.unique_id)},
manufacturer="Solar-Log", entity_description: SolarLogSensorEntityDescription
name=coordinator.name,
configuration_url=coordinator.host,
)
@property @property
def native_value(self): def native_value(self) -> float | datetime:
"""Return the native sensor value.""" """Return the state for this sensor."""
raw_attr = self.coordinator.data.get(self.entity_description.key)
if self.entity_description.value: val = self.coordinator.data["devices"][self.device_id][
return self.entity_description.value(raw_attr) self.entity_description.key
return raw_attr ]
return self.entity_description.value_fn(val)

View file

@ -1,6 +1,7 @@
"""Test helpers.""" """Test helpers."""
from collections.abc import Generator from collections.abc import Generator
from datetime import UTC, datetime
from unittest.mock import AsyncMock, patch from unittest.mock import AsyncMock, patch
import pytest import pytest
@ -35,9 +36,27 @@ def mock_solarlog_connector():
mock_solarlog_api = AsyncMock() mock_solarlog_api = AsyncMock()
mock_solarlog_api.test_connection = AsyncMock(return_value=True) mock_solarlog_api.test_connection = AsyncMock(return_value=True)
mock_solarlog_api.update_data.return_value = load_json_object_fixture(
"solarlog_data.json", SOLARLOG_DOMAIN data = {
) "devices": {
0: {"consumption_total": 354687, "current_power": 5},
}
}
data |= load_json_object_fixture("solarlog_data.json", SOLARLOG_DOMAIN)
data["last_updated"] = datetime.fromisoformat(data["last_updated"]).astimezone(UTC)
mock_solarlog_api.update_data.return_value = data
mock_solarlog_api.device_list.return_value = {
0: {"name": "Inverter 1"},
1: {"name": "Inverter 2"},
}
mock_solarlog_api.device_name = {0: "Inverter 1", 1: "Inverter 2"}.get
mock_solarlog_api.client.get_device_list.return_value = {
0: {"name": "Inverter 1"},
1: {"name": "Inverter 2"},
}
mock_solarlog_api.client.close = AsyncMock(return_value=None)
with ( with (
patch( patch(
"homeassistant.components.solarlog.coordinator.SolarLogConnector", "homeassistant.components.solarlog.coordinator.SolarLogConnector",

View file

@ -20,5 +20,6 @@
"efficiency": 0.9804, "efficiency": 0.9804,
"usage": 0.5487, "usage": 0.5487,
"power_available": 45.13, "power_available": 45.13,
"capacity": 0.85 "capacity": 0.85,
"last_updated": "2024-08-01T15:20:45"
} }

View file

@ -1,4 +1,55 @@
# serializer version: 1 # serializer version: 1
# name: test_all_entities[sensor.inverter_1_power-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.inverter_1_power',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.POWER: 'power'>,
'original_icon': None,
'original_name': 'Power',
'platform': 'solarlog',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'current_power',
'unique_id': 'ce5f5431554d101905d31797e1232da8-inverter_1-current_power',
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
})
# ---
# name: test_all_entities[sensor.inverter_1_power-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'power',
'friendly_name': 'Inverter 1 Power',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
}),
'context': <ANY>,
'entity_id': 'sensor.inverter_1_power',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '5',
})
# ---
# name: test_all_entities[sensor.solarlog_alternator_loss-entry] # name: test_all_entities[sensor.solarlog_alternator_loss-entry]
EntityRegistryEntrySnapshot({ EntityRegistryEntrySnapshot({
'aliases': set({ 'aliases': set({
@ -30,7 +81,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'alternator_loss', 'translation_key': 'alternator_loss',
'unique_id': 'ce5f5431554d101905d31797e1232da8_alternator_loss', 'unique_id': 'ce5f5431554d101905d31797e1232da8-alternator_loss',
'unit_of_measurement': <UnitOfPower.WATT: 'W'>, 'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
}) })
# --- # ---
@ -81,7 +132,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'capacity', 'translation_key': 'capacity',
'unique_id': 'ce5f5431554d101905d31797e1232da8_capacity', 'unique_id': 'ce5f5431554d101905d31797e1232da8-capacity',
'unit_of_measurement': '%', 'unit_of_measurement': '%',
}) })
# --- # ---
@ -132,7 +183,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'consumption_ac', 'translation_key': 'consumption_ac',
'unique_id': 'ce5f5431554d101905d31797e1232da8_consumption_ac', 'unique_id': 'ce5f5431554d101905d31797e1232da8-consumption_ac',
'unit_of_measurement': <UnitOfPower.WATT: 'W'>, 'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
}) })
# --- # ---
@ -181,7 +232,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'consumption_day', 'translation_key': 'consumption_day',
'unique_id': 'ce5f5431554d101905d31797e1232da8_consumption_day', 'unique_id': 'ce5f5431554d101905d31797e1232da8-consumption_day',
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>, 'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}) })
# --- # ---
@ -229,7 +280,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'consumption_month', 'translation_key': 'consumption_month',
'unique_id': 'ce5f5431554d101905d31797e1232da8_consumption_month', 'unique_id': 'ce5f5431554d101905d31797e1232da8-consumption_month',
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>, 'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}) })
# --- # ---
@ -279,7 +330,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'consumption_total', 'translation_key': 'consumption_total',
'unique_id': 'ce5f5431554d101905d31797e1232da8_consumption_total', 'unique_id': 'ce5f5431554d101905d31797e1232da8-consumption_total',
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>, 'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}) })
# --- # ---
@ -328,7 +379,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'consumption_year', 'translation_key': 'consumption_year',
'unique_id': 'ce5f5431554d101905d31797e1232da8_consumption_year', 'unique_id': 'ce5f5431554d101905d31797e1232da8-consumption_year',
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>, 'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}) })
# --- # ---
@ -376,7 +427,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'consumption_yesterday', 'translation_key': 'consumption_yesterday',
'unique_id': 'ce5f5431554d101905d31797e1232da8_consumption_yesterday', 'unique_id': 'ce5f5431554d101905d31797e1232da8-consumption_yesterday',
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>, 'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}) })
# --- # ---
@ -426,7 +477,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'efficiency', 'translation_key': 'efficiency',
'unique_id': 'ce5f5431554d101905d31797e1232da8_efficiency', 'unique_id': 'ce5f5431554d101905d31797e1232da8-efficiency',
'unit_of_measurement': '%', 'unit_of_measurement': '%',
}) })
# --- # ---
@ -475,7 +526,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'total_power', 'translation_key': 'total_power',
'unique_id': 'ce5f5431554d101905d31797e1232da8_total_power', 'unique_id': 'ce5f5431554d101905d31797e1232da8-total_power',
'unit_of_measurement': <UnitOfPower.WATT: 'W'>, 'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
}) })
# --- # ---
@ -523,7 +574,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'last_update', 'translation_key': 'last_update',
'unique_id': 'ce5f5431554d101905d31797e1232da8_last_updated', 'unique_id': 'ce5f5431554d101905d31797e1232da8-last_updated',
'unit_of_measurement': None, 'unit_of_measurement': None,
}) })
# --- # ---
@ -538,7 +589,7 @@
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,
'state': 'unknown', 'state': '2024-08-01T15:20:45+00:00',
}) })
# --- # ---
# name: test_all_entities[sensor.solarlog_power_ac-entry] # name: test_all_entities[sensor.solarlog_power_ac-entry]
@ -572,7 +623,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'power_ac', 'translation_key': 'power_ac',
'unique_id': 'ce5f5431554d101905d31797e1232da8_power_ac', 'unique_id': 'ce5f5431554d101905d31797e1232da8-power_ac',
'unit_of_measurement': <UnitOfPower.WATT: 'W'>, 'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
}) })
# --- # ---
@ -623,7 +674,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'power_available', 'translation_key': 'power_available',
'unique_id': 'ce5f5431554d101905d31797e1232da8_power_available', 'unique_id': 'ce5f5431554d101905d31797e1232da8-power_available',
'unit_of_measurement': <UnitOfPower.WATT: 'W'>, 'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
}) })
# --- # ---
@ -674,7 +725,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'power_dc', 'translation_key': 'power_dc',
'unique_id': 'ce5f5431554d101905d31797e1232da8_power_dc', 'unique_id': 'ce5f5431554d101905d31797e1232da8-power_dc',
'unit_of_measurement': <UnitOfPower.WATT: 'W'>, 'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
}) })
# --- # ---
@ -725,7 +776,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'self_consumption_year', 'translation_key': 'self_consumption_year',
'unique_id': 'ce5f5431554d101905d31797e1232da8_self_consumption_year', 'unique_id': 'ce5f5431554d101905d31797e1232da8-self_consumption_year',
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>, 'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}) })
# --- # ---
@ -776,7 +827,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'usage', 'translation_key': 'usage',
'unique_id': 'ce5f5431554d101905d31797e1232da8_usage', 'unique_id': 'ce5f5431554d101905d31797e1232da8-usage',
'unit_of_measurement': '%', 'unit_of_measurement': '%',
}) })
# --- # ---
@ -827,7 +878,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'voltage_ac', 'translation_key': 'voltage_ac',
'unique_id': 'ce5f5431554d101905d31797e1232da8_voltage_ac', 'unique_id': 'ce5f5431554d101905d31797e1232da8-voltage_ac',
'unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>, 'unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>,
}) })
# --- # ---
@ -878,7 +929,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'voltage_dc', 'translation_key': 'voltage_dc',
'unique_id': 'ce5f5431554d101905d31797e1232da8_voltage_dc', 'unique_id': 'ce5f5431554d101905d31797e1232da8-voltage_dc',
'unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>, 'unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>,
}) })
# --- # ---
@ -927,7 +978,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'yield_day', 'translation_key': 'yield_day',
'unique_id': 'ce5f5431554d101905d31797e1232da8_yield_day', 'unique_id': 'ce5f5431554d101905d31797e1232da8-yield_day',
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>, 'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}) })
# --- # ---
@ -975,7 +1026,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'yield_month', 'translation_key': 'yield_month',
'unique_id': 'ce5f5431554d101905d31797e1232da8_yield_month', 'unique_id': 'ce5f5431554d101905d31797e1232da8-yield_month',
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>, 'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}) })
# --- # ---
@ -1025,7 +1076,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'yield_total', 'translation_key': 'yield_total',
'unique_id': 'ce5f5431554d101905d31797e1232da8_yield_total', 'unique_id': 'ce5f5431554d101905d31797e1232da8-yield_total',
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>, 'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}) })
# --- # ---
@ -1074,7 +1125,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'yield_year', 'translation_key': 'yield_year',
'unique_id': 'ce5f5431554d101905d31797e1232da8_yield_year', 'unique_id': 'ce5f5431554d101905d31797e1232da8-yield_year',
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>, 'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}) })
# --- # ---
@ -1122,7 +1173,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'yield_yesterday', 'translation_key': 'yield_yesterday',
'unique_id': 'ce5f5431554d101905d31797e1232da8_yield_yesterday', 'unique_id': 'ce5f5431554d101905d31797e1232da8-yield_yesterday',
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>, 'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}) })
# --- # ---

View file

@ -67,7 +67,7 @@ async def test_user(
# tests with all provided # tests with all provided
result = await hass.config_entries.flow.async_configure( result = await hass.config_entries.flow.async_configure(
result["flow_id"], {CONF_HOST: HOST, CONF_NAME: NAME, "extended_data": False} result["flow_id"], {CONF_HOST: HOST, CONF_NAME: NAME, "extended_data": True}
) )
await hass.async_block_till_done() await hass.async_block_till_done()