mirror of
https://github.com/home-assistant/core.git
synced 2026-08-28 02:24:46 -05:00
Update easyEnergy integration to v3.0.0 (#169162)
This commit is contained in:
@@ -6,6 +6,7 @@ from datetime import timedelta
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .coordinator import EasyEnergyConfigEntry, EasyEnergyData
|
||||
|
||||
@@ -23,9 +24,7 @@ def get_gas_price(data: EasyEnergyData, hours: int) -> float | None:
|
||||
"""
|
||||
if not data.gas_today:
|
||||
return None
|
||||
return data.gas_today.price_at_time(
|
||||
data.gas_today.utcnow() + timedelta(hours=hours)
|
||||
)
|
||||
return data.gas_today.price_at_time(dt_util.utcnow() + timedelta(hours=hours))
|
||||
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
@@ -40,21 +39,21 @@ async def async_get_config_entry_diagnostics(
|
||||
"title": entry.title,
|
||||
},
|
||||
"energy_usage": {
|
||||
"current_hour_price": energy_today.current_usage_price,
|
||||
"current_hour_price": energy_today.current_price,
|
||||
"next_hour_price": energy_today.price_at_time(
|
||||
energy_today.utcnow() + timedelta(hours=1)
|
||||
dt_util.utcnow() + timedelta(hours=1)
|
||||
),
|
||||
"average_price": energy_today.average_usage_price,
|
||||
"max_price": energy_today.extreme_usage_prices[1],
|
||||
"min_price": energy_today.extreme_usage_prices[0],
|
||||
"highest_price_time": energy_today.highest_usage_price_time,
|
||||
"lowest_price_time": energy_today.lowest_usage_price_time,
|
||||
"percentage_of_max": energy_today.pct_of_max_usage,
|
||||
"average_price": energy_today.average_price,
|
||||
"max_price": energy_today.extreme_prices[1],
|
||||
"min_price": energy_today.extreme_prices[0],
|
||||
"highest_price_time": energy_today.highest_price_time,
|
||||
"lowest_price_time": energy_today.lowest_price_time,
|
||||
"percentage_of_max": energy_today.pct_of_max,
|
||||
},
|
||||
"energy_return": {
|
||||
"current_hour_price": energy_today.current_return_price,
|
||||
"next_hour_price": energy_today.price_at_time(
|
||||
energy_today.utcnow() + timedelta(hours=1), "return"
|
||||
"next_hour_price": energy_today.return_price_at_time(
|
||||
dt_util.utcnow() + timedelta(hours=1)
|
||||
),
|
||||
"average_price": energy_today.average_return_price,
|
||||
"max_price": energy_today.extreme_return_prices[1],
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/easyenergy",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"requirements": ["easyenergy==2.2.0"],
|
||||
"requirements": ["easyenergy==3.0.0"],
|
||||
"single_config_entry": true
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .const import DOMAIN, SERVICE_TYPE_DEVICE_NAMES
|
||||
from .coordinator import (
|
||||
@@ -63,7 +64,7 @@ SENSORS: tuple[EasyEnergySensorEntityDescription, ...] = (
|
||||
service_type="today_energy_usage",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=f"{CURRENCY_EURO}/{UnitOfEnergy.KILO_WATT_HOUR}",
|
||||
value_fn=lambda data: data.energy_today.current_usage_price,
|
||||
value_fn=lambda data: data.energy_today.current_price,
|
||||
),
|
||||
EasyEnergySensorEntityDescription(
|
||||
key="next_hour_price",
|
||||
@@ -71,7 +72,7 @@ SENSORS: tuple[EasyEnergySensorEntityDescription, ...] = (
|
||||
service_type="today_energy_usage",
|
||||
native_unit_of_measurement=f"{CURRENCY_EURO}/{UnitOfEnergy.KILO_WATT_HOUR}",
|
||||
value_fn=lambda data: data.energy_today.price_at_time(
|
||||
data.energy_today.utcnow() + timedelta(hours=1)
|
||||
dt_util.utcnow() + timedelta(hours=1)
|
||||
),
|
||||
),
|
||||
EasyEnergySensorEntityDescription(
|
||||
@@ -79,42 +80,42 @@ SENSORS: tuple[EasyEnergySensorEntityDescription, ...] = (
|
||||
translation_key="average_price",
|
||||
service_type="today_energy_usage",
|
||||
native_unit_of_measurement=f"{CURRENCY_EURO}/{UnitOfEnergy.KILO_WATT_HOUR}",
|
||||
value_fn=lambda data: data.energy_today.average_usage_price,
|
||||
value_fn=lambda data: data.energy_today.average_price,
|
||||
),
|
||||
EasyEnergySensorEntityDescription(
|
||||
key="max_price",
|
||||
translation_key="max_price",
|
||||
service_type="today_energy_usage",
|
||||
native_unit_of_measurement=f"{CURRENCY_EURO}/{UnitOfEnergy.KILO_WATT_HOUR}",
|
||||
value_fn=lambda data: data.energy_today.extreme_usage_prices[1],
|
||||
value_fn=lambda data: data.energy_today.extreme_prices[1],
|
||||
),
|
||||
EasyEnergySensorEntityDescription(
|
||||
key="min_price",
|
||||
translation_key="min_price",
|
||||
service_type="today_energy_usage",
|
||||
native_unit_of_measurement=f"{CURRENCY_EURO}/{UnitOfEnergy.KILO_WATT_HOUR}",
|
||||
value_fn=lambda data: data.energy_today.extreme_usage_prices[0],
|
||||
value_fn=lambda data: data.energy_today.extreme_prices[0],
|
||||
),
|
||||
EasyEnergySensorEntityDescription(
|
||||
key="highest_price_time",
|
||||
translation_key="highest_price_time",
|
||||
service_type="today_energy_usage",
|
||||
device_class=SensorDeviceClass.TIMESTAMP,
|
||||
value_fn=lambda data: data.energy_today.highest_usage_price_time,
|
||||
value_fn=lambda data: data.energy_today.highest_price_time,
|
||||
),
|
||||
EasyEnergySensorEntityDescription(
|
||||
key="lowest_price_time",
|
||||
translation_key="lowest_price_time",
|
||||
service_type="today_energy_usage",
|
||||
device_class=SensorDeviceClass.TIMESTAMP,
|
||||
value_fn=lambda data: data.energy_today.lowest_usage_price_time,
|
||||
value_fn=lambda data: data.energy_today.lowest_price_time,
|
||||
),
|
||||
EasyEnergySensorEntityDescription(
|
||||
key="percentage_of_max",
|
||||
translation_key="percentage_of_max",
|
||||
service_type="today_energy_usage",
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
value_fn=lambda data: data.energy_today.pct_of_max_usage,
|
||||
value_fn=lambda data: data.energy_today.pct_of_max,
|
||||
),
|
||||
EasyEnergySensorEntityDescription(
|
||||
key="current_hour_price",
|
||||
@@ -129,8 +130,8 @@ SENSORS: tuple[EasyEnergySensorEntityDescription, ...] = (
|
||||
translation_key="next_hour_price",
|
||||
service_type="today_energy_return",
|
||||
native_unit_of_measurement=f"{CURRENCY_EURO}/{UnitOfEnergy.KILO_WATT_HOUR}",
|
||||
value_fn=lambda data: data.energy_today.price_at_time(
|
||||
data.energy_today.utcnow() + timedelta(hours=1), "return"
|
||||
value_fn=lambda data: data.energy_today.return_price_at_time(
|
||||
dt_util.utcnow() + timedelta(hours=1)
|
||||
),
|
||||
),
|
||||
EasyEnergySensorEntityDescription(
|
||||
@@ -180,14 +181,14 @@ SENSORS: tuple[EasyEnergySensorEntityDescription, ...] = (
|
||||
translation_key="hours_priced_equal_or_lower",
|
||||
service_type="today_energy_usage",
|
||||
native_unit_of_measurement=UnitOfTime.HOURS,
|
||||
value_fn=lambda data: data.energy_today.hours_priced_equal_or_lower_usage,
|
||||
value_fn=lambda data: data.energy_today.periods_priced_equal_or_lower,
|
||||
),
|
||||
EasyEnergySensorEntityDescription(
|
||||
key="hours_priced_equal_or_higher",
|
||||
translation_key="hours_priced_equal_or_higher",
|
||||
service_type="today_energy_return",
|
||||
native_unit_of_measurement=UnitOfTime.HOURS,
|
||||
value_fn=lambda data: data.energy_today.hours_priced_equal_or_higher_return,
|
||||
value_fn=lambda data: data.energy_today.return_periods_priced_equal_or_higher,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -205,9 +206,7 @@ def get_gas_price(data: EasyEnergyData, hours: int) -> float | None:
|
||||
"""
|
||||
if data.gas_today is None:
|
||||
return None
|
||||
return data.gas_today.price_at_time(
|
||||
data.gas_today.utcnow() + timedelta(hours=hours)
|
||||
)
|
||||
return data.gas_today.price_at_time(dt_util.utcnow() + timedelta(hours=hours))
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import date, datetime
|
||||
from datetime import date, datetime, timedelta
|
||||
from enum import StrEnum
|
||||
from functools import partial
|
||||
from typing import Final
|
||||
|
||||
from easyenergy import Electricity, Gas, VatOption
|
||||
from easyenergy import Electricity, Gas, PriceInterval, VatOption
|
||||
from easyenergy.const import MARKET_TIMEZONE
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.core import (
|
||||
@@ -32,18 +33,22 @@ ATTR_INCL_VAT: Final = "incl_vat"
|
||||
GAS_SERVICE_NAME: Final = "get_gas_prices"
|
||||
ENERGY_USAGE_SERVICE_NAME: Final = "get_energy_usage_prices"
|
||||
ENERGY_RETURN_SERVICE_NAME: Final = "get_energy_return_prices"
|
||||
BASE_SERVICE_SCHEMA: Final = {
|
||||
vol.Required(ATTR_CONFIG_ENTRY): selector.ConfigEntrySelector(
|
||||
{
|
||||
"integration": DOMAIN,
|
||||
}
|
||||
),
|
||||
vol.Optional(ATTR_START): str,
|
||||
vol.Optional(ATTR_END): str,
|
||||
}
|
||||
SERVICE_SCHEMA: Final = vol.Schema(
|
||||
{
|
||||
vol.Required(ATTR_CONFIG_ENTRY): selector.ConfigEntrySelector(
|
||||
{
|
||||
"integration": DOMAIN,
|
||||
}
|
||||
),
|
||||
**BASE_SERVICE_SCHEMA,
|
||||
vol.Required(ATTR_INCL_VAT): bool,
|
||||
vol.Optional(ATTR_START): str,
|
||||
vol.Optional(ATTR_END): str,
|
||||
}
|
||||
)
|
||||
RETURN_SERVICE_SCHEMA: Final = vol.Schema(BASE_SERVICE_SCHEMA)
|
||||
|
||||
|
||||
class PriceType(StrEnum):
|
||||
@@ -54,22 +59,47 @@ class PriceType(StrEnum):
|
||||
GAS = "gas"
|
||||
|
||||
|
||||
def __get_date(date_input: str | None) -> date | datetime:
|
||||
"""Get date."""
|
||||
def __get_date(
|
||||
date_input: str | None,
|
||||
) -> tuple[date, datetime | None]:
|
||||
"""Get date for the API and optional datetime for response filtering."""
|
||||
if not date_input:
|
||||
return dt_util.now().date()
|
||||
return dt_util.now().date(), None
|
||||
|
||||
if value := dt_util.parse_datetime(date_input):
|
||||
return value
|
||||
if date_value := dt_util.parse_date(date_input):
|
||||
return date_value, None
|
||||
|
||||
raise ServiceValidationError(
|
||||
"Invalid datetime provided.",
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="invalid_date",
|
||||
translation_placeholders={
|
||||
"date": date_input,
|
||||
},
|
||||
)
|
||||
if not (datetime_value := dt_util.parse_datetime(date_input)):
|
||||
raise ServiceValidationError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="invalid_date",
|
||||
translation_placeholders={
|
||||
"date": date_input,
|
||||
},
|
||||
)
|
||||
|
||||
datetime_utc = dt_util.as_utc(datetime_value)
|
||||
return datetime_utc.astimezone(MARKET_TIMEZONE).date(), datetime_utc
|
||||
|
||||
|
||||
def __filter_prices(
|
||||
prices: list[dict[str, float | datetime]],
|
||||
intervals: tuple[PriceInterval, ...],
|
||||
start: datetime,
|
||||
end: datetime,
|
||||
) -> list[dict[str, float | datetime]]:
|
||||
"""Filter prices to the requested datetime range."""
|
||||
included_timestamps = {
|
||||
interval.starts_at
|
||||
for interval in intervals
|
||||
if interval.ends_at > start and interval.starts_at < end
|
||||
}
|
||||
|
||||
return [
|
||||
timestamp_price
|
||||
for timestamp_price in prices
|
||||
if timestamp_price["timestamp"] in included_timestamps
|
||||
]
|
||||
|
||||
|
||||
def __serialize_prices(prices: list[dict[str, float | datetime]]) -> ServiceResponse:
|
||||
@@ -101,8 +131,8 @@ async def __get_prices(
|
||||
"""Get prices from easyEnergy."""
|
||||
coordinator = __get_coordinator(call)
|
||||
|
||||
start = __get_date(call.data.get(ATTR_START))
|
||||
end = __get_date(call.data.get(ATTR_END))
|
||||
start_date, start_datetime = __get_date(call.data.get(ATTR_START))
|
||||
end_date, end_datetime = __get_date(call.data.get(ATTR_END))
|
||||
|
||||
vat = VatOption.INCLUDE
|
||||
if call.data.get(ATTR_INCL_VAT) is False:
|
||||
@@ -112,20 +142,38 @@ async def __get_prices(
|
||||
|
||||
if price_type == PriceType.GAS:
|
||||
data = await coordinator.easyenergy.gas_prices(
|
||||
start_date=start,
|
||||
end_date=end,
|
||||
start_date=start_date,
|
||||
end_date=end_date,
|
||||
vat=vat,
|
||||
)
|
||||
prices = data.timestamp_prices
|
||||
else:
|
||||
data = await coordinator.easyenergy.energy_prices(
|
||||
start_date=start_date,
|
||||
end_date=end_date,
|
||||
vat=vat,
|
||||
)
|
||||
return __serialize_prices(data.timestamp_prices)
|
||||
data = await coordinator.easyenergy.energy_prices(
|
||||
start_date=start,
|
||||
end_date=end,
|
||||
vat=vat,
|
||||
)
|
||||
|
||||
if price_type == PriceType.ENERGY_USAGE:
|
||||
return __serialize_prices(data.timestamp_usage_prices)
|
||||
return __serialize_prices(data.timestamp_return_prices)
|
||||
if price_type == PriceType.ENERGY_USAGE:
|
||||
prices = data.timestamp_prices
|
||||
else:
|
||||
prices = data.timestamp_return_prices
|
||||
|
||||
if start_datetime or end_datetime:
|
||||
filter_start = start_datetime or dt_util.as_utc(
|
||||
dt_util.start_of_local_day(start_date)
|
||||
)
|
||||
filter_end = end_datetime or dt_util.as_utc(
|
||||
dt_util.start_of_local_day(end_date + timedelta(days=1))
|
||||
)
|
||||
prices = __filter_prices(
|
||||
prices,
|
||||
data.intervals,
|
||||
filter_start,
|
||||
filter_end,
|
||||
)
|
||||
|
||||
return __serialize_prices(prices)
|
||||
|
||||
|
||||
@callback
|
||||
@@ -150,6 +198,6 @@ def async_setup_services(hass: HomeAssistant) -> None:
|
||||
DOMAIN,
|
||||
ENERGY_RETURN_SERVICE_NAME,
|
||||
partial(__get_prices, price_type=PriceType.ENERGY_RETURN),
|
||||
schema=SERVICE_SCHEMA,
|
||||
schema=RETURN_SERVICE_SCHEMA,
|
||||
supports_response=SupportsResponse.ONLY,
|
||||
)
|
||||
|
||||
Generated
+1
-1
@@ -859,7 +859,7 @@ eagle100==0.1.1
|
||||
earn-e-p1==0.1.0
|
||||
|
||||
# homeassistant.components.easyenergy
|
||||
easyenergy==2.2.0
|
||||
easyenergy==3.0.0
|
||||
|
||||
# homeassistant.components.ebusd
|
||||
ebusdpy==0.0.17
|
||||
|
||||
Generated
+1
-1
@@ -768,7 +768,7 @@ eagle100==0.1.1
|
||||
earn-e-p1==0.1.0
|
||||
|
||||
# homeassistant.components.easyenergy
|
||||
easyenergy==2.2.0
|
||||
easyenergy==3.0.0
|
||||
|
||||
# homeassistant.components.egauge
|
||||
egauge-async==0.4.0
|
||||
|
||||
@@ -9,7 +9,7 @@ import pytest
|
||||
from homeassistant.components.easyenergy.const import DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry, async_load_json_array_fixture
|
||||
from tests.common import MockConfigEntry, async_load_json_object_fixture
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -39,11 +39,18 @@ async def mock_easyenergy(hass: HomeAssistant) -> AsyncGenerator[MagicMock]:
|
||||
"homeassistant.components.easyenergy.coordinator.EasyEnergy", autospec=True
|
||||
) as easyenergy_mock:
|
||||
client = easyenergy_mock.return_value
|
||||
client.energy_prices.return_value = Electricity.from_dict(
|
||||
await async_load_json_array_fixture(hass, "today_energy.json", DOMAIN)
|
||||
energy_data = await async_load_json_object_fixture(
|
||||
hass, "today_energy.json", DOMAIN
|
||||
)
|
||||
client.energy_prices.return_value = Electricity.from_dict(
|
||||
energy_data["prices"],
|
||||
price_key="priceIncVat",
|
||||
return_price_key="priceIncVat",
|
||||
)
|
||||
gas_data = await async_load_json_object_fixture(hass, "today_gas.json", DOMAIN)
|
||||
client.gas_prices.return_value = Gas.from_dict(
|
||||
await async_load_json_array_fixture(hass, "today_gas.json", DOMAIN)
|
||||
gas_data["prices"],
|
||||
price_key="priceIncVat",
|
||||
)
|
||||
yield client
|
||||
|
||||
|
||||
@@ -1,146 +1,317 @@
|
||||
[
|
||||
{
|
||||
"Timestamp": "2023-01-18T23:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.1349513,
|
||||
"TariffReturn": 0.11153
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T00:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.1294458,
|
||||
"TariffReturn": 0.10698
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T01:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.1270137,
|
||||
"TariffReturn": 0.10497
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T02:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.1230812,
|
||||
"TariffReturn": 0.10172
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T03:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.1297483,
|
||||
"TariffReturn": 0.10723
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T04:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.1386902,
|
||||
"TariffReturn": 0.11462
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T05:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.1439174,
|
||||
"TariffReturn": 0.11894
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T06:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.193479,
|
||||
"TariffReturn": 0.1599
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T07:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.19844,
|
||||
"TariffReturn": 0.164
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T08:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.2077449,
|
||||
"TariffReturn": 0.17169
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T09:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.16819,
|
||||
"TariffReturn": 0.139
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T10:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.1649835,
|
||||
"TariffReturn": 0.13635
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T11:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.156816,
|
||||
"TariffReturn": 0.1296
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T12:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.1873927,
|
||||
"TariffReturn": 0.15487
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T13:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.1941929,
|
||||
"TariffReturn": 0.16049
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T14:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.2129116,
|
||||
"TariffReturn": 0.17596
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T15:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.2254109,
|
||||
"TariffReturn": 0.18629
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T16:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.2467674,
|
||||
"TariffReturn": 0.20394
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T17:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.2390597,
|
||||
"TariffReturn": 0.19757
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T18:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.2074303,
|
||||
"TariffReturn": 0.17143
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T19:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.1815,
|
||||
"TariffReturn": 0.15
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T20:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.1795761,
|
||||
"TariffReturn": 0.14841
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T21:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.1807014,
|
||||
"TariffReturn": 0.14934
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T22:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.16819,
|
||||
"TariffReturn": 0.139
|
||||
}
|
||||
]
|
||||
{
|
||||
"providedAt": "2026-04-19T22:16:44.4866876Z",
|
||||
"prices": [
|
||||
{
|
||||
"from": "2026-04-19T00:00:00.0000000",
|
||||
"until": "2026-04-19T01:00:00.0000000",
|
||||
"price": 0.11549,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.13975,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.27238,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T01:00:00.0000000",
|
||||
"until": "2026-04-19T02:00:00.0000000",
|
||||
"price": 0.10522,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.12732,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.25995,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T02:00:00.0000000",
|
||||
"until": "2026-04-19T03:00:00.0000000",
|
||||
"price": 0.1092,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.13213,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.26476,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T03:00:00.0000000",
|
||||
"until": "2026-04-19T04:00:00.0000000",
|
||||
"price": 0.10325,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.12493,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.25756,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T04:00:00.0000000",
|
||||
"until": "2026-04-19T05:00:00.0000000",
|
||||
"price": 0.10346,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.12519,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.25782,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T05:00:00.0000000",
|
||||
"until": "2026-04-19T06:00:00.0000000",
|
||||
"price": 0.09795,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.11852,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.25115,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T06:00:00.0000000",
|
||||
"until": "2026-04-19T07:00:00.0000000",
|
||||
"price": 0.10071,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.12186,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.25449,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T07:00:00.0000000",
|
||||
"until": "2026-04-19T08:00:00.0000000",
|
||||
"price": 0.09793,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.1185,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.25113,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T08:00:00.0000000",
|
||||
"until": "2026-04-19T09:00:00.0000000",
|
||||
"price": 0.09725,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.11768,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.25031,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T09:00:00.0000000",
|
||||
"until": "2026-04-19T10:00:00.0000000",
|
||||
"price": 0.08766,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.10607,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.2387,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T10:00:00.0000000",
|
||||
"until": "2026-04-19T11:00:00.0000000",
|
||||
"price": 0.06132,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.07419,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.20682,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T11:00:00.0000000",
|
||||
"until": "2026-04-19T12:00:00.0000000",
|
||||
"price": 0.02832,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.03426,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.16689,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T12:00:00.0000000",
|
||||
"until": "2026-04-19T13:00:00.0000000",
|
||||
"price": 0.00806,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.00975,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.14238,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T13:00:00.0000000",
|
||||
"until": "2026-04-19T14:00:00.0000000",
|
||||
"price": -0.00085,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": -0.00085,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.13178,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T14:00:00.0000000",
|
||||
"until": "2026-04-19T15:00:00.0000000",
|
||||
"price": -0.003,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": -0.003,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.12963,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T15:00:00.0000000",
|
||||
"until": "2026-04-19T16:00:00.0000000",
|
||||
"price": -0.00226,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": -0.00226,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.13037,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T16:00:00.0000000",
|
||||
"until": "2026-04-19T17:00:00.0000000",
|
||||
"price": 0.01348,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.01631,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.14894,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T17:00:00.0000000",
|
||||
"until": "2026-04-19T18:00:00.0000000",
|
||||
"price": 0.06533,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.07905,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.21168,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T18:00:00.0000000",
|
||||
"until": "2026-04-19T19:00:00.0000000",
|
||||
"price": 0.10385,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.12566,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.25829,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T19:00:00.0000000",
|
||||
"until": "2026-04-19T20:00:00.0000000",
|
||||
"price": 0.11681,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.14134,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.27397,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T20:00:00.0000000",
|
||||
"until": "2026-04-19T21:00:00.0000000",
|
||||
"price": 0.12464,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.15082,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.28345,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T21:00:00.0000000",
|
||||
"until": "2026-04-19T22:00:00.0000000",
|
||||
"price": 0.12214,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.14779,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.28042,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T22:00:00.0000000",
|
||||
"until": "2026-04-19T23:00:00.0000000",
|
||||
"price": 0.11906,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.14407,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.2767,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-19T23:00:00.0000000",
|
||||
"until": "2026-04-20T00:00:00.0000000",
|
||||
"price": 0.1113,
|
||||
"unit": "kWh",
|
||||
"priceIncVat": 0.13467,
|
||||
"energyTax": 0.11085,
|
||||
"purchasePrice": 0.02178,
|
||||
"invoicePrice": 0.2673,
|
||||
"average": 0.0786,
|
||||
"averageInc": 0.09516,
|
||||
"granularity": "hour"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,146 +1,31 @@
|
||||
[
|
||||
{
|
||||
"Timestamp": "2023-01-19T05:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T06:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T07:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T08:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T09:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T10:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T11:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T12:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T13:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T14:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T15:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T16:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T17:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T18:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T19:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T20:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T21:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T22:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-19T23:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-20T00:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-20T01:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-20T02:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-20T03:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
},
|
||||
{
|
||||
"Timestamp": "2023-01-20T04:00:00+00:00",
|
||||
"SupplierId": 0,
|
||||
"TariffUsage": 0.7252982,
|
||||
"TariffReturn": 0.7252982
|
||||
}
|
||||
]
|
||||
{
|
||||
"providedAt": "2026-04-19T22:16:43.4740091Z",
|
||||
"prices": [
|
||||
{
|
||||
"from": "2026-04-19T00:00:00.0000000",
|
||||
"until": "2026-04-20T00:00:00.0000000",
|
||||
"price": 0.50983,
|
||||
"unit": "m3",
|
||||
"priceIncVat": 0.6169,
|
||||
"energyTax": 0.7268,
|
||||
"purchasePrice": 0.079,
|
||||
"invoicePrice": 1.4227,
|
||||
"average": 0.49402,
|
||||
"averageInc": 0.59776,
|
||||
"granularity": "day"
|
||||
},
|
||||
{
|
||||
"from": "2026-04-20T00:00:00.0000000",
|
||||
"until": "2026-04-21T00:00:00.0000000",
|
||||
"price": 0.4782,
|
||||
"unit": "m3",
|
||||
"priceIncVat": 0.57862,
|
||||
"energyTax": 0.7268,
|
||||
"purchasePrice": 0.079,
|
||||
"invoicePrice": 1.38442,
|
||||
"average": 0.49402,
|
||||
"averageInc": 0.59776,
|
||||
"granularity": "day"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,55 +2,55 @@
|
||||
# name: test_diagnostics
|
||||
dict({
|
||||
'energy_return': dict({
|
||||
'average_price': 0.14599,
|
||||
'current_hour_price': 0.18629,
|
||||
'highest_price_time': '2023-01-19T16:00:00+00:00',
|
||||
'lowest_price_time': '2023-01-19T02:00:00+00:00',
|
||||
'max_price': 0.20394,
|
||||
'min_price': 0.10172,
|
||||
'next_hour_price': 0.20394,
|
||||
'percentage_of_max': 91.35,
|
||||
'average_price': 0.09516,
|
||||
'current_hour_price': -0.00226,
|
||||
'highest_price_time': '2026-04-19T18:00:00+00:00',
|
||||
'lowest_price_time': '2026-04-19T12:00:00+00:00',
|
||||
'max_price': 0.15082,
|
||||
'min_price': -0.003,
|
||||
'next_hour_price': 0.01631,
|
||||
'percentage_of_max': -1.5,
|
||||
}),
|
||||
'energy_usage': dict({
|
||||
'average_price': 0.17665,
|
||||
'current_hour_price': 0.22541,
|
||||
'highest_price_time': '2023-01-19T16:00:00+00:00',
|
||||
'lowest_price_time': '2023-01-19T02:00:00+00:00',
|
||||
'max_price': 0.24677,
|
||||
'min_price': 0.12308,
|
||||
'next_hour_price': 0.24677,
|
||||
'percentage_of_max': 91.34,
|
||||
'average_price': 0.09516,
|
||||
'current_hour_price': -0.00226,
|
||||
'highest_price_time': '2026-04-19T18:00:00+00:00',
|
||||
'lowest_price_time': '2026-04-19T12:00:00+00:00',
|
||||
'max_price': 0.15082,
|
||||
'min_price': -0.003,
|
||||
'next_hour_price': 0.01631,
|
||||
'percentage_of_max': -1.5,
|
||||
}),
|
||||
'entry': dict({
|
||||
'title': 'energy',
|
||||
}),
|
||||
'gas': dict({
|
||||
'current_hour_price': 0.7253,
|
||||
'next_hour_price': 0.7253,
|
||||
'current_hour_price': 0.6169,
|
||||
'next_hour_price': 0.6169,
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
# name: test_diagnostics_no_gas_today
|
||||
dict({
|
||||
'energy_return': dict({
|
||||
'average_price': 0.14599,
|
||||
'current_hour_price': 0.18629,
|
||||
'highest_price_time': '2023-01-19T16:00:00+00:00',
|
||||
'lowest_price_time': '2023-01-19T02:00:00+00:00',
|
||||
'max_price': 0.20394,
|
||||
'min_price': 0.10172,
|
||||
'next_hour_price': 0.20394,
|
||||
'percentage_of_max': 91.35,
|
||||
'average_price': 0.09516,
|
||||
'current_hour_price': -0.00226,
|
||||
'highest_price_time': '2026-04-19T18:00:00+00:00',
|
||||
'lowest_price_time': '2026-04-19T12:00:00+00:00',
|
||||
'max_price': 0.15082,
|
||||
'min_price': -0.003,
|
||||
'next_hour_price': 0.01631,
|
||||
'percentage_of_max': -1.5,
|
||||
}),
|
||||
'energy_usage': dict({
|
||||
'average_price': 0.17665,
|
||||
'current_hour_price': 0.22541,
|
||||
'highest_price_time': '2023-01-19T16:00:00+00:00',
|
||||
'lowest_price_time': '2023-01-19T02:00:00+00:00',
|
||||
'max_price': 0.24677,
|
||||
'min_price': 0.12308,
|
||||
'next_hour_price': 0.24677,
|
||||
'percentage_of_max': 91.34,
|
||||
'average_price': 0.09516,
|
||||
'current_hour_price': -0.00226,
|
||||
'highest_price_time': '2026-04-19T18:00:00+00:00',
|
||||
'lowest_price_time': '2026-04-19T12:00:00+00:00',
|
||||
'max_price': 0.15082,
|
||||
'min_price': -0.003,
|
||||
'next_hour_price': 0.01631,
|
||||
'percentage_of_max': -1.5,
|
||||
}),
|
||||
'entry': dict({
|
||||
'title': 'energy',
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,7 +19,7 @@ from tests.components.diagnostics import get_diagnostics_for_config_entry
|
||||
from tests.typing import ClientSessionGenerator
|
||||
|
||||
|
||||
@pytest.mark.freeze_time("2023-01-19 15:00:00")
|
||||
@pytest.mark.freeze_time("2026-04-19 13:00:00+00:00")
|
||||
async def test_diagnostics(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
@@ -33,7 +33,7 @@ async def test_diagnostics(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.freeze_time("2023-01-19 15:00:00")
|
||||
@pytest.mark.freeze_time("2026-04-19 13:00:00+00:00")
|
||||
async def test_diagnostics_no_gas_today(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
|
||||
@@ -33,7 +33,7 @@ from homeassistant.setup import async_setup_component
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
@pytest.mark.freeze_time("2023-01-19 15:00:00")
|
||||
@pytest.mark.freeze_time("2026-04-19 13:00:00+00:00")
|
||||
async def test_energy_usage_today(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
@@ -51,7 +51,7 @@ async def test_energy_usage_today(
|
||||
assert entry
|
||||
assert state
|
||||
assert entry.unique_id == f"{entry_id}_today_energy_usage_current_hour_price"
|
||||
assert state.state == "0.22541"
|
||||
assert state.state == "-0.00226"
|
||||
assert (
|
||||
state.attributes.get(ATTR_FRIENDLY_NAME)
|
||||
== "Energy market price - Usage Current hour"
|
||||
@@ -72,7 +72,7 @@ async def test_energy_usage_today(
|
||||
assert entry
|
||||
assert state
|
||||
assert entry.unique_id == f"{entry_id}_today_energy_usage_average_price"
|
||||
assert state.state == "0.17665"
|
||||
assert state.state == "0.09516"
|
||||
assert (
|
||||
state.attributes.get(ATTR_FRIENDLY_NAME)
|
||||
== "Energy market price - Usage Average - today"
|
||||
@@ -90,7 +90,7 @@ async def test_energy_usage_today(
|
||||
assert entry
|
||||
assert state
|
||||
assert entry.unique_id == f"{entry_id}_today_energy_usage_max_price"
|
||||
assert state.state == "0.24677"
|
||||
assert state.state == "0.15082"
|
||||
assert (
|
||||
state.attributes.get(ATTR_FRIENDLY_NAME)
|
||||
== "Energy market price - Usage Highest price - today"
|
||||
@@ -110,7 +110,7 @@ async def test_energy_usage_today(
|
||||
assert entry
|
||||
assert state
|
||||
assert entry.unique_id == f"{entry_id}_today_energy_usage_highest_price_time"
|
||||
assert state.state == "2023-01-19T16:00:00+00:00"
|
||||
assert state.state == "2026-04-19T18:00:00+00:00"
|
||||
assert (
|
||||
state.attributes.get(ATTR_FRIENDLY_NAME)
|
||||
== "Energy market price - Usage Time of highest price - today"
|
||||
@@ -140,7 +140,7 @@ async def test_energy_usage_today(
|
||||
assert (
|
||||
entry.unique_id == f"{entry_id}_today_energy_usage_hours_priced_equal_or_lower"
|
||||
)
|
||||
assert state.state == "21"
|
||||
assert state.state == "2"
|
||||
assert (
|
||||
state.attributes.get(ATTR_FRIENDLY_NAME)
|
||||
== "Energy market price - Usage Hours priced equal or lower than current - today"
|
||||
@@ -148,7 +148,7 @@ async def test_energy_usage_today(
|
||||
assert ATTR_DEVICE_CLASS not in state.attributes
|
||||
|
||||
|
||||
@pytest.mark.freeze_time("2023-01-19 15:00:00")
|
||||
@pytest.mark.freeze_time("2026-04-19 13:00:00+00:00")
|
||||
async def test_energy_return_today(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
@@ -166,7 +166,7 @@ async def test_energy_return_today(
|
||||
assert entry
|
||||
assert state
|
||||
assert entry.unique_id == f"{entry_id}_today_energy_return_current_hour_price"
|
||||
assert state.state == "0.18629"
|
||||
assert state.state == "-0.00226"
|
||||
assert (
|
||||
state.attributes.get(ATTR_FRIENDLY_NAME)
|
||||
== "Energy market price - Return Current hour"
|
||||
@@ -187,7 +187,7 @@ async def test_energy_return_today(
|
||||
assert entry
|
||||
assert state
|
||||
assert entry.unique_id == f"{entry_id}_today_energy_return_average_price"
|
||||
assert state.state == "0.14599"
|
||||
assert state.state == "0.09516"
|
||||
assert (
|
||||
state.attributes.get(ATTR_FRIENDLY_NAME)
|
||||
== "Energy market price - Return Average - today"
|
||||
@@ -205,7 +205,7 @@ async def test_energy_return_today(
|
||||
assert entry
|
||||
assert state
|
||||
assert entry.unique_id == f"{entry_id}_today_energy_return_max_price"
|
||||
assert state.state == "0.20394"
|
||||
assert state.state == "0.15082"
|
||||
assert (
|
||||
state.attributes.get(ATTR_FRIENDLY_NAME)
|
||||
== "Energy market price - Return Highest price - today"
|
||||
@@ -225,7 +225,7 @@ async def test_energy_return_today(
|
||||
assert entry
|
||||
assert state
|
||||
assert entry.unique_id == f"{entry_id}_today_energy_return_highest_price_time"
|
||||
assert state.state == "2023-01-19T16:00:00+00:00"
|
||||
assert state.state == "2026-04-19T18:00:00+00:00"
|
||||
assert (
|
||||
state.attributes.get(ATTR_FRIENDLY_NAME)
|
||||
== "Energy market price - Return Time of highest price - today"
|
||||
@@ -256,7 +256,7 @@ async def test_energy_return_today(
|
||||
entry.unique_id
|
||||
== f"{entry_id}_today_energy_return_hours_priced_equal_or_higher"
|
||||
)
|
||||
assert state.state == "3"
|
||||
assert state.state == "23"
|
||||
assert (
|
||||
state.attributes.get(ATTR_FRIENDLY_NAME)
|
||||
== "Energy market price - Return Hours priced equal or higher than current - today"
|
||||
@@ -264,7 +264,7 @@ async def test_energy_return_today(
|
||||
assert ATTR_DEVICE_CLASS not in state.attributes
|
||||
|
||||
|
||||
@pytest.mark.freeze_time("2023-01-19 10:00:00")
|
||||
@pytest.mark.freeze_time("2026-04-19 10:00:00+00:00")
|
||||
async def test_gas_today(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
@@ -280,7 +280,7 @@ async def test_gas_today(
|
||||
assert entry
|
||||
assert state
|
||||
assert entry.unique_id == f"{entry_id}_today_gas_current_hour_price"
|
||||
assert state.state == "0.7253"
|
||||
assert state.state == "0.6169"
|
||||
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Gas market price Current hour"
|
||||
assert (
|
||||
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
|
||||
@@ -301,7 +301,7 @@ async def test_gas_today(
|
||||
assert not device_entry.sw_version
|
||||
|
||||
|
||||
@pytest.mark.freeze_time("2023-01-19 15:00:00")
|
||||
@pytest.mark.freeze_time("2026-04-19 13:00:00+00:00")
|
||||
async def test_no_gas_today(
|
||||
hass: HomeAssistant, mock_easyenergy: MagicMock, init_integration: MockConfigEntry
|
||||
) -> None:
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
"""Tests for the services provided by the easyEnergy integration."""
|
||||
|
||||
from datetime import date
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from easyenergy import VatOption
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
import voluptuous as vol
|
||||
@@ -37,8 +41,8 @@ async def test_has_services(
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("incl_vat", [{"incl_vat": False}, {"incl_vat": True}])
|
||||
@pytest.mark.parametrize("start", [{"start": "2023-01-01 00:00:00"}, {}])
|
||||
@pytest.mark.parametrize("end", [{"end": "2023-01-01 00:00:00"}, {}])
|
||||
@pytest.mark.parametrize("start", [{"start": "2023-01-01"}, {}])
|
||||
@pytest.mark.parametrize("end", [{"end": "2023-01-01"}, {}])
|
||||
async def test_service(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
@@ -48,8 +52,10 @@ async def test_service(
|
||||
start: dict[str, str],
|
||||
end: dict[str, str],
|
||||
) -> None:
|
||||
"""Test the EnergyZero Service."""
|
||||
"""Test the easyEnergy service."""
|
||||
entry = {ATTR_CONFIG_ENTRY: mock_config_entry.entry_id}
|
||||
if service == ENERGY_RETURN_SERVICE_NAME:
|
||||
incl_vat = {}
|
||||
|
||||
data = entry | incl_vat | start | end
|
||||
|
||||
@@ -62,6 +68,75 @@ async def test_service(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_integration")
|
||||
@pytest.mark.parametrize(
|
||||
("service", "expected_prices"),
|
||||
[
|
||||
(
|
||||
GAS_SERVICE_NAME,
|
||||
[
|
||||
{"timestamp": "2026-04-18 22:00:00+00:00", "price": 0.6169},
|
||||
],
|
||||
),
|
||||
(
|
||||
ENERGY_USAGE_SERVICE_NAME,
|
||||
[
|
||||
{"timestamp": "2026-04-19 00:00:00+00:00", "price": 0.13213},
|
||||
{"timestamp": "2026-04-19 01:00:00+00:00", "price": 0.12493},
|
||||
{"timestamp": "2026-04-19 02:00:00+00:00", "price": 0.12519},
|
||||
],
|
||||
),
|
||||
(
|
||||
ENERGY_RETURN_SERVICE_NAME,
|
||||
[
|
||||
{"timestamp": "2026-04-19 00:00:00+00:00", "price": 0.13213},
|
||||
{"timestamp": "2026-04-19 01:00:00+00:00", "price": 0.12493},
|
||||
{"timestamp": "2026-04-19 02:00:00+00:00", "price": 0.12519},
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_service_filters_datetime_range(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_easyenergy: MagicMock,
|
||||
service: str,
|
||||
expected_prices: list[dict[str, str | float]],
|
||||
) -> None:
|
||||
"""Test easyEnergy services filter returned day data to a datetime range."""
|
||||
service_data: dict[str, str | bool] = {
|
||||
ATTR_CONFIG_ENTRY: mock_config_entry.entry_id,
|
||||
"start": "2026-04-19 02:00:00+02:00",
|
||||
"end": "2026-04-19 05:00:00+02:00",
|
||||
}
|
||||
if service != ENERGY_RETURN_SERVICE_NAME:
|
||||
service_data["incl_vat"] = True
|
||||
|
||||
mock_easyenergy.reset_mock()
|
||||
|
||||
response = await hass.services.async_call(
|
||||
DOMAIN,
|
||||
service,
|
||||
service_data,
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
|
||||
assert response == {"prices": expected_prices}
|
||||
|
||||
expected_call = {
|
||||
"start_date": date(2026, 4, 19),
|
||||
"end_date": date(2026, 4, 19),
|
||||
"vat": VatOption.INCLUDE,
|
||||
}
|
||||
if service == GAS_SERVICE_NAME:
|
||||
mock_easyenergy.gas_prices.assert_called_once_with(**expected_call)
|
||||
mock_easyenergy.energy_prices.assert_not_called()
|
||||
else:
|
||||
mock_easyenergy.energy_prices.assert_called_once_with(**expected_call)
|
||||
mock_easyenergy.gas_prices.assert_not_called()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def config_entry_data(
|
||||
mock_config_entry: MockConfigEntry, request: pytest.FixtureRequest
|
||||
@@ -83,65 +158,22 @@ def config_entry_data(
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("config_entry_data", "service_data", "error", "error_message"),
|
||||
("config_entry_data", "service_data", "error_message"),
|
||||
[
|
||||
({}, {}, vol.er.Error, "required key not provided .+"),
|
||||
(
|
||||
{"config_entry": True},
|
||||
{},
|
||||
vol.er.Error,
|
||||
"required key not provided .+",
|
||||
),
|
||||
(
|
||||
{},
|
||||
{"incl_vat": True},
|
||||
vol.er.Error,
|
||||
"required key not provided .+",
|
||||
),
|
||||
(
|
||||
{"config_entry": True},
|
||||
{"incl_vat": "incorrect vat"},
|
||||
vol.er.Error,
|
||||
"expected bool for dictionary value .+",
|
||||
),
|
||||
(
|
||||
{"config_entry": "incorrect entry"},
|
||||
{"incl_vat": True},
|
||||
ServiceValidationError,
|
||||
"config entry with ID incorrect entry was not found",
|
||||
),
|
||||
(
|
||||
{"config_entry": True},
|
||||
{
|
||||
"incl_vat": True,
|
||||
"start": "incorrect date",
|
||||
},
|
||||
ServiceValidationError,
|
||||
"Invalid datetime provided.",
|
||||
),
|
||||
(
|
||||
{"config_entry": True},
|
||||
{
|
||||
"incl_vat": True,
|
||||
"end": "incorrect date",
|
||||
},
|
||||
ServiceValidationError,
|
||||
"Invalid datetime provided.",
|
||||
),
|
||||
({}, {}, "required key not provided .+"),
|
||||
],
|
||||
indirect=["config_entry_data"],
|
||||
)
|
||||
async def test_service_validation(
|
||||
async def test_service_schema_validation(
|
||||
hass: HomeAssistant,
|
||||
service: str,
|
||||
config_entry_data: dict[str, str],
|
||||
service_data: dict[str, str | bool],
|
||||
error: type[Exception],
|
||||
error_message: str,
|
||||
) -> None:
|
||||
"""Test the easyEnergy Service."""
|
||||
"""Test easyEnergy service schema validation."""
|
||||
|
||||
with pytest.raises(error, match=error_message):
|
||||
with pytest.raises(vol.er.Error, match=error_message):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
service,
|
||||
@@ -149,3 +181,122 @@ async def test_service_validation(
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_integration")
|
||||
@pytest.mark.parametrize("service", [GAS_SERVICE_NAME, ENERGY_USAGE_SERVICE_NAME])
|
||||
@pytest.mark.parametrize(
|
||||
("service_data", "error_message"),
|
||||
[
|
||||
({}, "required key not provided .+"),
|
||||
({"incl_vat": "incorrect vat"}, "expected bool for dictionary value .+"),
|
||||
],
|
||||
)
|
||||
async def test_service_schema_validation_vat(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
service: str,
|
||||
service_data: dict[str, str | bool],
|
||||
error_message: str,
|
||||
) -> None:
|
||||
"""Test easyEnergy service schema validation for VAT."""
|
||||
|
||||
with pytest.raises(vol.er.Error, match=error_message):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
service,
|
||||
{ATTR_CONFIG_ENTRY: mock_config_entry.entry_id} | service_data,
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_integration")
|
||||
async def test_service_schema_validation_return_vat(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test return prices do not accept VAT selection."""
|
||||
|
||||
with pytest.raises(vol.er.Error, match="extra keys not allowed .+"):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
ENERGY_RETURN_SERVICE_NAME,
|
||||
{ATTR_CONFIG_ENTRY: mock_config_entry.entry_id, "incl_vat": True},
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_integration")
|
||||
@pytest.mark.parametrize(
|
||||
"service",
|
||||
[
|
||||
GAS_SERVICE_NAME,
|
||||
ENERGY_USAGE_SERVICE_NAME,
|
||||
ENERGY_RETURN_SERVICE_NAME,
|
||||
],
|
||||
)
|
||||
async def test_service_validation_config_entry_not_found(
|
||||
hass: HomeAssistant,
|
||||
service: str,
|
||||
) -> None:
|
||||
"""Test config entry validation for easyEnergy services."""
|
||||
service_data: dict[str, str | bool] = {ATTR_CONFIG_ENTRY: "incorrect entry"}
|
||||
if service != ENERGY_RETURN_SERVICE_NAME:
|
||||
service_data["incl_vat"] = True
|
||||
|
||||
with pytest.raises(ServiceValidationError) as err:
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
service,
|
||||
service_data,
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
|
||||
assert err.value.translation_key == "service_config_entry_not_found"
|
||||
assert err.value.translation_placeholders == {
|
||||
"domain": DOMAIN,
|
||||
"entry_id": "incorrect entry",
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_integration")
|
||||
@pytest.mark.parametrize(
|
||||
"service",
|
||||
[
|
||||
GAS_SERVICE_NAME,
|
||||
ENERGY_USAGE_SERVICE_NAME,
|
||||
ENERGY_RETURN_SERVICE_NAME,
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("date_field", ["start", "end"])
|
||||
@pytest.mark.parametrize("date_value", ["incorrect date"])
|
||||
async def test_service_validation_invalid_date(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
service: str,
|
||||
date_field: str,
|
||||
date_value: str,
|
||||
) -> None:
|
||||
"""Test invalid date validation for easyEnergy services."""
|
||||
service_data: dict[str, str | bool] = {
|
||||
ATTR_CONFIG_ENTRY: mock_config_entry.entry_id,
|
||||
date_field: date_value,
|
||||
}
|
||||
if service != ENERGY_RETURN_SERVICE_NAME:
|
||||
service_data["incl_vat"] = True
|
||||
|
||||
with pytest.raises(ServiceValidationError) as err:
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
service,
|
||||
service_data,
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
|
||||
assert str(err.value) == f"Invalid date provided. Got {date_value}"
|
||||
assert err.value.translation_key == "invalid_date"
|
||||
assert err.value.translation_placeholders == {"date": date_value}
|
||||
|
||||
Reference in New Issue
Block a user