mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
Add statistics import to Ista EcoTrend integration (#118788)
* Add statistics import to Ista EcoTrend integration * Use decorator for fixtures * define recorder as after_dependency * Increase test coverage * remember initial statistic_id * fix type checking
This commit is contained in:
parent
cb8a6af12d
commit
ea4443f79e
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"domain": "ista_ecotrend",
|
"domain": "ista_ecotrend",
|
||||||
"name": "ista EcoTrend",
|
"name": "ista EcoTrend",
|
||||||
|
"after_dependencies": ["recorder"],
|
||||||
"codeowners": ["@tr4nt0r"],
|
"codeowners": ["@tr4nt0r"],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/ista_ecotrend",
|
"documentation": "https://www.home-assistant.io/integrations/ista_ecotrend",
|
||||||
|
@ -2,10 +2,21 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
import datetime
|
||||||
from enum import StrEnum
|
from enum import StrEnum
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from homeassistant.components.recorder.models.statistics import (
|
||||||
|
StatisticData,
|
||||||
|
StatisticMetaData,
|
||||||
|
)
|
||||||
|
from homeassistant.components.recorder.statistics import (
|
||||||
|
async_add_external_statistics,
|
||||||
|
get_instance,
|
||||||
|
get_last_statistics,
|
||||||
|
)
|
||||||
from homeassistant.components.sensor import (
|
from homeassistant.components.sensor import (
|
||||||
SensorDeviceClass,
|
SensorDeviceClass,
|
||||||
SensorEntity,
|
SensorEntity,
|
||||||
@ -14,7 +25,11 @@ from homeassistant.components.sensor import (
|
|||||||
)
|
)
|
||||||
from homeassistant.const import UnitOfEnergy, UnitOfVolume
|
from homeassistant.const import UnitOfEnergy, UnitOfVolume
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
|
from homeassistant.helpers.device_registry import (
|
||||||
|
DeviceEntry,
|
||||||
|
DeviceEntryType,
|
||||||
|
DeviceInfo,
|
||||||
|
)
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.typing import StateType
|
from homeassistant.helpers.typing import StateType
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
@ -22,7 +37,7 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
|||||||
from . import IstaConfigEntry
|
from . import IstaConfigEntry
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
from .coordinator import IstaCoordinator
|
from .coordinator import IstaCoordinator
|
||||||
from .util import IstaConsumptionType, IstaValueType, get_native_value
|
from .util import IstaConsumptionType, IstaValueType, get_native_value, get_statistics
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -155,6 +170,7 @@ class IstaSensor(CoordinatorEntity[IstaCoordinator], SensorEntity):
|
|||||||
|
|
||||||
entity_description: IstaSensorEntityDescription
|
entity_description: IstaSensorEntityDescription
|
||||||
_attr_has_entity_name = True
|
_attr_has_entity_name = True
|
||||||
|
device_entry: DeviceEntry
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -186,3 +202,81 @@ class IstaSensor(CoordinatorEntity[IstaCoordinator], SensorEntity):
|
|||||||
consumption_type=self.entity_description.consumption_type,
|
consumption_type=self.entity_description.consumption_type,
|
||||||
value_type=self.entity_description.value_type,
|
value_type=self.entity_description.value_type,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def async_added_to_hass(self) -> None:
|
||||||
|
"""When added to hass."""
|
||||||
|
# perform initial statistics import when sensor is added, otherwise it would take
|
||||||
|
# 1 day when _handle_coordinator_update is triggered for the first time.
|
||||||
|
await self.update_statistics()
|
||||||
|
await super().async_added_to_hass()
|
||||||
|
|
||||||
|
def _handle_coordinator_update(self) -> None:
|
||||||
|
"""Handle coordinator update."""
|
||||||
|
asyncio.run_coroutine_threadsafe(self.update_statistics(), self.hass.loop)
|
||||||
|
|
||||||
|
async def update_statistics(self) -> None:
|
||||||
|
"""Import ista EcoTrend historical statistics."""
|
||||||
|
|
||||||
|
# Remember the statistic_id that was initially created
|
||||||
|
# in case the entity gets renamed, because we cannot
|
||||||
|
# change the statistic_id
|
||||||
|
name = self.coordinator.config_entry.options.get(
|
||||||
|
f"lts_{self.entity_description.key}_{self.consumption_unit}"
|
||||||
|
)
|
||||||
|
if not name:
|
||||||
|
name = self.entity_id.removeprefix("sensor.")
|
||||||
|
self.hass.config_entries.async_update_entry(
|
||||||
|
entry=self.coordinator.config_entry,
|
||||||
|
options={
|
||||||
|
**self.coordinator.config_entry.options,
|
||||||
|
f"lts_{self.entity_description.key}_{self.consumption_unit}": name,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
statistic_id = f"{DOMAIN}:{name}"
|
||||||
|
statistics_sum = 0.0
|
||||||
|
statistics_since = None
|
||||||
|
|
||||||
|
last_stats = await get_instance(self.hass).async_add_executor_job(
|
||||||
|
get_last_statistics,
|
||||||
|
self.hass,
|
||||||
|
1,
|
||||||
|
statistic_id,
|
||||||
|
False,
|
||||||
|
{"sum"},
|
||||||
|
)
|
||||||
|
|
||||||
|
_LOGGER.debug("Last statistics: %s", last_stats)
|
||||||
|
|
||||||
|
if last_stats:
|
||||||
|
statistics_sum = last_stats[statistic_id][0].get("sum") or 0.0
|
||||||
|
statistics_since = datetime.datetime.fromtimestamp(
|
||||||
|
last_stats[statistic_id][0].get("end") or 0, tz=datetime.UTC
|
||||||
|
) + datetime.timedelta(days=1)
|
||||||
|
|
||||||
|
if monthly_consumptions := get_statistics(
|
||||||
|
self.coordinator.data[self.consumption_unit],
|
||||||
|
self.entity_description.consumption_type,
|
||||||
|
self.entity_description.value_type,
|
||||||
|
):
|
||||||
|
statistics: list[StatisticData] = [
|
||||||
|
{
|
||||||
|
"start": consumptions["date"],
|
||||||
|
"state": consumptions["value"],
|
||||||
|
"sum": (statistics_sum := statistics_sum + consumptions["value"]),
|
||||||
|
}
|
||||||
|
for consumptions in monthly_consumptions
|
||||||
|
if statistics_since is None or consumptions["date"] > statistics_since
|
||||||
|
]
|
||||||
|
|
||||||
|
metadata: StatisticMetaData = {
|
||||||
|
"has_mean": False,
|
||||||
|
"has_sum": True,
|
||||||
|
"name": f"{self.device_entry.name} {self.name}",
|
||||||
|
"source": DOMAIN,
|
||||||
|
"statistic_id": statistic_id,
|
||||||
|
"unit_of_measurement": self.entity_description.native_unit_of_measurement,
|
||||||
|
}
|
||||||
|
if statistics:
|
||||||
|
_LOGGER.debug("Insert statistics: %s %s", metadata, statistics)
|
||||||
|
async_add_external_statistics(self.hass, metadata, statistics)
|
||||||
|
@ -166,3 +166,52 @@ def get_consumption_data(obj_uuid: str | None = None) -> dict[str, Any]:
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def extend_statistics(obj_uuid: str | None = None) -> dict[str, Any]:
|
||||||
|
"""Extend statistics data with new values."""
|
||||||
|
stats = get_consumption_data(obj_uuid)
|
||||||
|
|
||||||
|
stats["costs"].insert(
|
||||||
|
0,
|
||||||
|
{
|
||||||
|
"date": {"month": 6, "year": 2024},
|
||||||
|
"costsByEnergyType": [
|
||||||
|
{
|
||||||
|
"type": "heating",
|
||||||
|
"value": 9000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "warmwater",
|
||||||
|
"value": 9000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "water",
|
||||||
|
"value": 9000,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
stats["consumptions"].insert(
|
||||||
|
0,
|
||||||
|
{
|
||||||
|
"date": {"month": 6, "year": 2024},
|
||||||
|
"readings": [
|
||||||
|
{
|
||||||
|
"type": "heating",
|
||||||
|
"value": "9000",
|
||||||
|
"additionalValue": "9000,0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "warmwater",
|
||||||
|
"value": "9999,0",
|
||||||
|
"additionalValue": "90000,0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "water",
|
||||||
|
"value": "9000,0",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return stats
|
||||||
|
609
tests/components/ista_ecotrend/snapshots/test_statistics.ambr
Normal file
609
tests/components/ista_ecotrend/snapshots/test_statistics.ambr
Normal file
@ -0,0 +1,609 @@
|
|||||||
|
# serializer version: 1
|
||||||
|
# name: test_statistics_import[ista_ecotrend:bahnhofsstr_1a_heating_2months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 104.0,
|
||||||
|
'sum': 104.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 35.0,
|
||||||
|
'sum': 139.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:bahnhofsstr_1a_heating_3months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 104.0,
|
||||||
|
'sum': 104.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 35.0,
|
||||||
|
'sum': 139.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1719817200.0,
|
||||||
|
'start': 1717225200.0,
|
||||||
|
'state': 9000.0,
|
||||||
|
'sum': 9139.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:bahnhofsstr_1a_heating_cost_2months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 62.0,
|
||||||
|
'sum': 62.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 21.0,
|
||||||
|
'sum': 83.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:bahnhofsstr_1a_heating_cost_3months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 62.0,
|
||||||
|
'sum': 62.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 21.0,
|
||||||
|
'sum': 83.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1719817200.0,
|
||||||
|
'start': 1717225200.0,
|
||||||
|
'state': 9000.0,
|
||||||
|
'sum': 9083.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:bahnhofsstr_1a_heating_energy_2months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 113.0,
|
||||||
|
'sum': 113.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 38.0,
|
||||||
|
'sum': 151.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:bahnhofsstr_1a_heating_energy_3months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 113.0,
|
||||||
|
'sum': 113.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 38.0,
|
||||||
|
'sum': 151.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1719817200.0,
|
||||||
|
'start': 1717225200.0,
|
||||||
|
'state': 9000.0,
|
||||||
|
'sum': 9151.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:bahnhofsstr_1a_hot_water_2months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 1.1,
|
||||||
|
'sum': 1.1,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 1.0,
|
||||||
|
'sum': 2.1,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:bahnhofsstr_1a_hot_water_3months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 1.1,
|
||||||
|
'sum': 1.1,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 1.0,
|
||||||
|
'sum': 2.1,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1719817200.0,
|
||||||
|
'start': 1717225200.0,
|
||||||
|
'state': 9999.0,
|
||||||
|
'sum': 10001.1,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:bahnhofsstr_1a_hot_water_cost_2months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 7.0,
|
||||||
|
'sum': 7.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 7.0,
|
||||||
|
'sum': 14.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:bahnhofsstr_1a_hot_water_cost_3months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 7.0,
|
||||||
|
'sum': 7.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 7.0,
|
||||||
|
'sum': 14.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1719817200.0,
|
||||||
|
'start': 1717225200.0,
|
||||||
|
'state': 9000.0,
|
||||||
|
'sum': 9014.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:bahnhofsstr_1a_hot_water_energy_2months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 61.1,
|
||||||
|
'sum': 61.1,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 57.0,
|
||||||
|
'sum': 118.1,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:bahnhofsstr_1a_hot_water_energy_3months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 61.1,
|
||||||
|
'sum': 61.1,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 57.0,
|
||||||
|
'sum': 118.1,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1719817200.0,
|
||||||
|
'start': 1717225200.0,
|
||||||
|
'state': 90000.0,
|
||||||
|
'sum': 90118.1,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:bahnhofsstr_1a_water_2months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 6.8,
|
||||||
|
'sum': 6.8,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 5.0,
|
||||||
|
'sum': 11.8,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:bahnhofsstr_1a_water_3months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 6.8,
|
||||||
|
'sum': 6.8,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 5.0,
|
||||||
|
'sum': 11.8,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1719817200.0,
|
||||||
|
'start': 1717225200.0,
|
||||||
|
'state': 9000.0,
|
||||||
|
'sum': 9011.8,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:bahnhofsstr_1a_water_cost_2months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 2.0,
|
||||||
|
'sum': 2.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 3.0,
|
||||||
|
'sum': 5.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:bahnhofsstr_1a_water_cost_3months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 2.0,
|
||||||
|
'sum': 2.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 3.0,
|
||||||
|
'sum': 5.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1719817200.0,
|
||||||
|
'start': 1717225200.0,
|
||||||
|
'state': 9000.0,
|
||||||
|
'sum': 9005.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:luxemburger_str_1_heating_2months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 104.0,
|
||||||
|
'sum': 104.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 35.0,
|
||||||
|
'sum': 139.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:luxemburger_str_1_heating_3months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 104.0,
|
||||||
|
'sum': 104.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 35.0,
|
||||||
|
'sum': 139.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1719817200.0,
|
||||||
|
'start': 1717225200.0,
|
||||||
|
'state': 9000.0,
|
||||||
|
'sum': 9139.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:luxemburger_str_1_heating_cost_2months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 62.0,
|
||||||
|
'sum': 62.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 21.0,
|
||||||
|
'sum': 83.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:luxemburger_str_1_heating_cost_3months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 62.0,
|
||||||
|
'sum': 62.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 21.0,
|
||||||
|
'sum': 83.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1719817200.0,
|
||||||
|
'start': 1717225200.0,
|
||||||
|
'state': 9000.0,
|
||||||
|
'sum': 9083.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:luxemburger_str_1_heating_energy_2months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 113.0,
|
||||||
|
'sum': 113.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 38.0,
|
||||||
|
'sum': 151.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:luxemburger_str_1_heating_energy_3months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 113.0,
|
||||||
|
'sum': 113.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 38.0,
|
||||||
|
'sum': 151.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1719817200.0,
|
||||||
|
'start': 1717225200.0,
|
||||||
|
'state': 9000.0,
|
||||||
|
'sum': 9151.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:luxemburger_str_1_hot_water_2months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 1.1,
|
||||||
|
'sum': 1.1,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 1.0,
|
||||||
|
'sum': 2.1,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:luxemburger_str_1_hot_water_3months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 1.1,
|
||||||
|
'sum': 1.1,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 1.0,
|
||||||
|
'sum': 2.1,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1719817200.0,
|
||||||
|
'start': 1717225200.0,
|
||||||
|
'state': 9999.0,
|
||||||
|
'sum': 10001.1,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:luxemburger_str_1_hot_water_cost_2months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 7.0,
|
||||||
|
'sum': 7.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 7.0,
|
||||||
|
'sum': 14.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:luxemburger_str_1_hot_water_cost_3months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 7.0,
|
||||||
|
'sum': 7.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 7.0,
|
||||||
|
'sum': 14.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1719817200.0,
|
||||||
|
'start': 1717225200.0,
|
||||||
|
'state': 9000.0,
|
||||||
|
'sum': 9014.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:luxemburger_str_1_hot_water_energy_2months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 61.1,
|
||||||
|
'sum': 61.1,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 57.0,
|
||||||
|
'sum': 118.1,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:luxemburger_str_1_hot_water_energy_3months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 61.1,
|
||||||
|
'sum': 61.1,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 57.0,
|
||||||
|
'sum': 118.1,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1719817200.0,
|
||||||
|
'start': 1717225200.0,
|
||||||
|
'state': 90000.0,
|
||||||
|
'sum': 90118.1,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:luxemburger_str_1_water_2months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 6.8,
|
||||||
|
'sum': 6.8,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 5.0,
|
||||||
|
'sum': 11.8,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:luxemburger_str_1_water_3months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 6.8,
|
||||||
|
'sum': 6.8,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 5.0,
|
||||||
|
'sum': 11.8,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1719817200.0,
|
||||||
|
'start': 1717225200.0,
|
||||||
|
'state': 9000.0,
|
||||||
|
'sum': 9011.8,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:luxemburger_str_1_water_cost_2months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 2.0,
|
||||||
|
'sum': 2.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 3.0,
|
||||||
|
'sum': 5.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
||||||
|
# name: test_statistics_import[ista_ecotrend:luxemburger_str_1_water_cost_3months]
|
||||||
|
list([
|
||||||
|
dict({
|
||||||
|
'end': 1714546800.0,
|
||||||
|
'start': 1711954800.0,
|
||||||
|
'state': 2.0,
|
||||||
|
'sum': 2.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1717225200.0,
|
||||||
|
'start': 1714546800.0,
|
||||||
|
'state': 3.0,
|
||||||
|
'sum': 5.0,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'end': 1719817200.0,
|
||||||
|
'start': 1717225200.0,
|
||||||
|
'state': 9000.0,
|
||||||
|
'sum': 9005.0,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
# ---
|
82
tests/components/ista_ecotrend/test_statistics.py
Normal file
82
tests/components/ista_ecotrend/test_statistics.py
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
"""Tests for the ista EcoTrend Statistics import."""
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
|
import pytest
|
||||||
|
from syrupy.assertion import SnapshotAssertion
|
||||||
|
|
||||||
|
from homeassistant.components.recorder.statistics import statistics_during_period
|
||||||
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
|
||||||
|
from .conftest import extend_statistics
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
from tests.components.recorder.common import async_wait_recording_done
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("recorder_mock", "entity_registry_enabled_by_default")
|
||||||
|
async def test_statistics_import(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
ista_config_entry: MockConfigEntry,
|
||||||
|
entity_registry: er.EntityRegistry,
|
||||||
|
mock_ista: MagicMock,
|
||||||
|
snapshot: SnapshotAssertion,
|
||||||
|
freezer: FrozenDateTimeFactory,
|
||||||
|
) -> None:
|
||||||
|
"""Test setup of ista EcoTrend sensor platform."""
|
||||||
|
|
||||||
|
ista_config_entry.add_to_hass(hass)
|
||||||
|
await hass.config_entries.async_setup(ista_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert ista_config_entry.state is ConfigEntryState.LOADED
|
||||||
|
entities = er.async_entries_for_config_entry(
|
||||||
|
entity_registry, ista_config_entry.entry_id
|
||||||
|
)
|
||||||
|
await async_wait_recording_done(hass)
|
||||||
|
|
||||||
|
# Test that consumption statistics for 2 months have been added
|
||||||
|
for entity in entities:
|
||||||
|
statistic_id = f"ista_ecotrend:{entity.entity_id.removeprefix("sensor.")}"
|
||||||
|
stats = await hass.async_add_executor_job(
|
||||||
|
statistics_during_period,
|
||||||
|
hass,
|
||||||
|
datetime.datetime.fromtimestamp(0, tz=datetime.UTC),
|
||||||
|
None,
|
||||||
|
{statistic_id},
|
||||||
|
"month",
|
||||||
|
None,
|
||||||
|
{"state", "sum"},
|
||||||
|
)
|
||||||
|
assert stats[statistic_id] == snapshot(name=f"{statistic_id}_2months")
|
||||||
|
assert len(stats[statistic_id]) == 2
|
||||||
|
|
||||||
|
# Add another monthly consumption and forward
|
||||||
|
# 1 day and test if the new values have been
|
||||||
|
# appended to the statistics
|
||||||
|
mock_ista.get_consumption_data = extend_statistics
|
||||||
|
|
||||||
|
freezer.tick(datetime.timedelta(days=1))
|
||||||
|
await async_wait_recording_done(hass)
|
||||||
|
freezer.tick(datetime.timedelta(days=1))
|
||||||
|
await async_wait_recording_done(hass)
|
||||||
|
|
||||||
|
for entity in entities:
|
||||||
|
statistic_id = f"ista_ecotrend:{entity.entity_id.removeprefix("sensor.")}"
|
||||||
|
stats = await hass.async_add_executor_job(
|
||||||
|
statistics_during_period,
|
||||||
|
hass,
|
||||||
|
datetime.datetime.fromtimestamp(0, tz=datetime.UTC),
|
||||||
|
None,
|
||||||
|
{statistic_id},
|
||||||
|
"month",
|
||||||
|
None,
|
||||||
|
{"state", "sum"},
|
||||||
|
)
|
||||||
|
assert stats[statistic_id] == snapshot(name=f"{statistic_id}_3months")
|
||||||
|
|
||||||
|
assert len(stats[statistic_id]) == 3
|
Loading…
x
Reference in New Issue
Block a user