Fix easyEnergy price period count sensor semantics (#181431)

This commit is contained in:
Klaas Schoute
2026-09-07 11:56:30 +02:00
committed by GitHub
parent 139de5c5fd
commit 31af4273aa
3 changed files with 69 additions and 17 deletions
@@ -12,13 +12,7 @@ from homeassistant.components.sensor import (
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.const import (
CURRENCY_EURO,
PERCENTAGE,
UnitOfEnergy,
UnitOfTime,
UnitOfVolume,
)
from homeassistant.const import CURRENCY_EURO, PERCENTAGE, UnitOfEnergy, UnitOfVolume
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
@@ -182,14 +176,12 @@ SENSORS: tuple[EasyEnergySensorEntityDescription, ...] = (
key="hours_priced_equal_or_lower",
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.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.return_periods_priced_equal_or_higher,
),
)
@@ -24,10 +24,10 @@
"name": "Time of highest price - today"
},
"hours_priced_equal_or_higher": {
"name": "Hours priced equal or higher than current - today"
"name": "Periods priced equal or higher than current - today"
},
"hours_priced_equal_or_lower": {
"name": "Hours priced equal or lower than current - today"
"name": "Periods priced equal or lower than current - today"
},
"lowest_price_time": {
"name": "Time of lowest price - today"
+66 -6
View File
@@ -1,8 +1,9 @@
"""Tests for the sensors provided by the easyEnergy integration."""
from datetime import timedelta
from unittest.mock import MagicMock
from easyenergy import EasyEnergyNoDataError
from easyenergy import EasyEnergyNoDataError, Electricity
import pytest
from homeassistant.components.easyenergy.const import DOMAIN
@@ -29,8 +30,9 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util
from tests.common import MockConfigEntry
from tests.common import MockConfigEntry, async_load_json_object_fixture
@pytest.mark.freeze_time("2026-04-19 13:00:00+00:00")
@@ -128,7 +130,7 @@ async def test_energy_usage_today(
assert not device_entry.model
assert not device_entry.sw_version
# Usage hours priced equal or lower sensor
# Usage periods priced equal or lower sensor
state = hass.states.get(
"sensor.easyenergy_today_energy_usage_hours_priced_equal_or_lower"
)
@@ -141,9 +143,10 @@ async def test_energy_usage_today(
entry.unique_id == f"{entry_id}_today_energy_usage_hours_priced_equal_or_lower"
)
assert state.state == "2"
assert ATTR_UNIT_OF_MEASUREMENT not in state.attributes
assert (
state.attributes.get(ATTR_FRIENDLY_NAME) == "Energy market price"
" - Usage Hours priced equal or lower than current - today"
" - Usage Periods priced equal or lower than current - today"
)
assert ATTR_DEVICE_CLASS not in state.attributes
@@ -243,7 +246,7 @@ async def test_energy_return_today(
assert not device_entry.model
assert not device_entry.sw_version
# Return hours priced equal or higher sensor
# Return periods priced equal or higher sensor
state = hass.states.get(
"sensor.easyenergy_today_energy_return_hours_priced_equal_or_higher"
)
@@ -257,9 +260,10 @@ async def test_energy_return_today(
== f"{entry_id}_today_energy_return_hours_priced_equal_or_higher"
)
assert state.state == "23"
assert ATTR_UNIT_OF_MEASUREMENT not in state.attributes
assert (
state.attributes.get(ATTR_FRIENDLY_NAME) == "Energy market price"
" - Return Hours priced equal or higher than current - today"
" - Return Periods priced equal or higher than current - today"
)
assert ATTR_DEVICE_CLASS not in state.attributes
@@ -321,3 +325,59 @@ async def test_no_gas_today(
state = hass.states.get("sensor.easyenergy_today_gas_current_hour_price")
assert state
assert state.state == STATE_UNKNOWN
@pytest.mark.freeze_time("2026-04-19 00:00:00+00:00")
@pytest.mark.parametrize(
("minutes", "granularity"),
[
pytest.param(60, "hour", id="hourly"),
pytest.param(15, "quarter", id="quarter-hourly"),
],
)
@pytest.mark.parametrize(
("sensor", "expected_state"),
[
pytest.param("usage_hours_priced_equal_or_lower", "3", id="usage"),
pytest.param("return_hours_priced_equal_or_higher", "2", id="return"),
],
)
async def test_price_period_counts(
hass: HomeAssistant,
mock_easyenergy: MagicMock,
mock_config_entry: MockConfigEntry,
minutes: int,
granularity: str,
sensor: str,
expected_state: str,
) -> None:
"""Test inclusive counts for distinct usage and return prices at any interval size."""
data = await async_load_json_object_fixture(hass, "today_energy.json", DOMAIN)
start = dt_util.utcnow()
interval = timedelta(minutes=minutes)
prices = [
{
**data["prices"][0],
"from": (start + index * interval).isoformat(),
"until": (start + (index + 1) * interval).isoformat(),
"granularity": granularity,
"priceIncVat": usage_price,
"invoicePrice": return_price,
}
for index, (usage_price, return_price) in enumerate(
[(0.2, 0.3), (-0.1, 0.1), (0.2, 0.3), (0.4, 0.2)]
)
]
mock_easyenergy.energy_prices.return_value = Electricity.from_dict(
prices, price_key="priceIncVat", return_price_key="invoicePrice"
)
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
state = hass.states.get(f"sensor.easyenergy_today_energy_{sensor}")
assert state
assert state.state == expected_state
assert ATTR_UNIT_OF_MEASUREMENT not in state.attributes
assert ATTR_DEVICE_CLASS not in state.attributes
assert ATTR_STATE_CLASS not in state.attributes