Populate hourly statistics in srp_energy (#167371)

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Signed-off-by: Branden Cash <203336+ammmze@users.noreply.github.com>
This commit is contained in:
Branden Cash
2026-06-22 23:51:33 +02:00
committed by GitHub
co-authored by Joost Lekkerkerker
parent 158595464a
commit c519b7ba07
11 changed files with 1455 additions and 99 deletions
+147 -61
View File
@@ -32,65 +32,151 @@ TEST_CONFIG_CABIN: Final[dict[str, str]] = {
}
MOCK_USAGE = [
("7/31/2022", "00:00 AM", "2022-07-31T00:00:00", "1.2", "0.19"),
("7/31/2022", "01:00 AM", "2022-07-31T01:00:00", "1.3", "0.20"),
("7/31/2022", "02:00 AM", "2022-07-31T02:00:00", "1.1", "0.17"),
("7/31/2022", "03:00 AM", "2022-07-31T03:00:00", "1.2", "0.18"),
("7/31/2022", "04:00 AM", "2022-07-31T04:00:00", "0.8", "0.13"),
("7/31/2022", "05:00 AM", "2022-07-31T05:00:00", "0.9", "0.14"),
("7/31/2022", "06:00 AM", "2022-07-31T06:00:00", "1.6", "0.24"),
("7/31/2022", "07:00 AM", "2022-07-31T07:00:00", "3.7", "0.53"),
("7/31/2022", "08:00 AM", "2022-07-31T08:00:00", "1.0", "0.16"),
("7/31/2022", "09:00 AM", "2022-07-31T09:00:00", "0.7", "0.12"),
("7/31/2022", "10:00 AM", "2022-07-31T10:00:00", "1.9", "0.28"),
("7/31/2022", "11:00 AM", "2022-07-31T11:00:00", "4.3", "0.61"),
("7/31/2022", "12:00 PM", "2022-07-31T12:00:00", "2.0", "0.29"),
("7/31/2022", "01:00 PM", "2022-07-31T13:00:00", "3.9", "0.55"),
("7/31/2022", "02:00 PM", "2022-07-31T14:00:00", "5.3", "0.75"),
("7/31/2022", "03:00 PM", "2022-07-31T15:00:00", "5.0", "0.70"),
("7/31/2022", "04:00 PM", "2022-07-31T16:00:00", "2.2", "0.31"),
("7/31/2022", "05:00 PM", "2022-07-31T17:00:00", "2.6", "0.37"),
("7/31/2022", "06:00 PM", "2022-07-31T18:00:00", "4.5", "0.64"),
("7/31/2022", "07:00 PM", "2022-07-31T19:00:00", "2.5", "0.35"),
("7/31/2022", "08:00 PM", "2022-07-31T20:00:00", "2.9", "0.42"),
("7/31/2022", "09:00 PM", "2022-07-31T21:00:00", "2.2", "0.32"),
("7/31/2022", "10:00 PM", "2022-07-31T22:00:00", "2.1", "0.30"),
("7/31/2022", "11:00 PM", "2022-07-31T23:00:00", "2.0", "0.28"),
("8/01/2022", "00:00 AM", "2022-08-01T00:00:00", "1.8", "0.26"),
("8/01/2022", "01:00 AM", "2022-08-01T01:00:00", "1.7", "0.26"),
("8/01/2022", "02:00 AM", "2022-08-01T02:00:00", "1.7", "0.26"),
("8/01/2022", "03:00 AM", "2022-08-01T03:00:00", "0.8", "0.14"),
("8/01/2022", "04:00 AM", "2022-08-01T04:00:00", "1.2", "0.19"),
("8/01/2022", "05:00 AM", "2022-08-01T05:00:00", "1.6", "0.23"),
("8/01/2022", "06:00 AM", "2022-08-01T06:00:00", "1.2", "0.18"),
("8/01/2022", "07:00 AM", "2022-08-01T07:00:00", "3.1", "0.44"),
("8/01/2022", "08:00 AM", "2022-08-01T08:00:00", "2.5", "0.35"),
("8/01/2022", "09:00 AM", "2022-08-01T09:00:00", "3.3", "0.47"),
("8/01/2022", "10:00 AM", "2022-08-01T10:00:00", "2.6", "0.37"),
("8/01/2022", "11:00 AM", "2022-08-01T11:00:00", "0.8", "0.13"),
("8/01/2022", "12:00 PM", "2022-08-01T12:00:00", "0.6", "0.11"),
("8/01/2022", "01:00 PM", "2022-08-01T13:00:00", "6.4", "0.9"),
("8/01/2022", "02:00 PM", "2022-08-01T14:00:00", "3.6", "0.52"),
("8/01/2022", "03:00 PM", "2022-08-01T15:00:00", "5.5", "0.79"),
("8/01/2022", "04:00 PM", "2022-08-01T16:00:00", "3", "0.43"),
("8/01/2022", "05:00 PM", "2022-08-01T17:00:00", "5", "0.71"),
("8/01/2022", "06:00 PM", "2022-08-01T18:00:00", "4.4", "0.63"),
("8/01/2022", "07:00 PM", "2022-08-01T19:00:00", "3.8", "0.54"),
("8/01/2022", "08:00 PM", "2022-08-01T20:00:00", "3.6", "0.51"),
("8/01/2022", "09:00 PM", "2022-08-01T21:00:00", "2.9", "0.4"),
("8/01/2022", "10:00 PM", "2022-08-01T22:00:00", "3.4", "0.49"),
("8/01/2022", "11:00 PM", "2022-08-01T23:00:00", "2.9", "0.41"),
("8/02/2022", "00:00 AM", "2022-08-02T00:00:00", "2", "0.3"),
("8/02/2022", "01:00 AM", "2022-08-02T01:00:00", "2", "0.29"),
("8/02/2022", "02:00 AM", "2022-08-02T02:00:00", "1.9", "0.28"),
("8/02/2022", "03:00 AM", "2022-08-02T03:00:00", "1.8", "0.27"),
("8/02/2022", "04:00 AM", "2022-08-02T04:00:00", "1.8", "0.26"),
("8/02/2022", "05:00 AM", "2022-08-02T05:00:00", "1.6", "0.23"),
("8/02/2022", "06:00 AM", "2022-08-02T06:00:00", "0.8", "0.14"),
("8/02/2022", "07:00 AM", "2022-08-02T07:00:00", "4", "0.56"),
("8/02/2022", "08:00 AM", "2022-08-02T08:00:00", "2.4", "0.34"),
("8/02/2022", "09:00 AM", "2022-08-02T09:00:00", "4.1", "0.58"),
("8/02/2022", "10:00 AM", "2022-08-02T10:00:00", "2.6", "0.37"),
("8/02/2022", "11:00 AM", "2022-08-02T11:00:00", "0.5", "0.1"),
("8/02/2022", "00:00 AM", "2022-08-02T12:00:00", "1", "0.16"),
("7/31/2022", "00:00 AM", "2022-07-31T00:00:00", 1.2, 0.19),
("7/31/2022", "01:00 AM", "2022-07-31T01:00:00", 1.3, 0.20),
("7/31/2022", "02:00 AM", "2022-07-31T02:00:00", 1.1, 0.17),
("7/31/2022", "03:00 AM", "2022-07-31T03:00:00", 1.2, 0.18),
("7/31/2022", "04:00 AM", "2022-07-31T04:00:00", 0.8, 0.13),
("7/31/2022", "05:00 AM", "2022-07-31T05:00:00", 0.9, 0.14),
("7/31/2022", "06:00 AM", "2022-07-31T06:00:00", 1.6, 0.24),
("7/31/2022", "07:00 AM", "2022-07-31T07:00:00", 3.7, 0.53),
("7/31/2022", "08:00 AM", "2022-07-31T08:00:00", 1.0, 0.16),
("7/31/2022", "09:00 AM", "2022-07-31T09:00:00", 0.7, 0.12),
("7/31/2022", "10:00 AM", "2022-07-31T10:00:00", 1.9, 0.28),
("7/31/2022", "11:00 AM", "2022-07-31T11:00:00", 4.3, 0.61),
("7/31/2022", "12:00 PM", "2022-07-31T12:00:00", 2.0, 0.29),
("7/31/2022", "01:00 PM", "2022-07-31T13:00:00", 3.9, 0.55),
("7/31/2022", "02:00 PM", "2022-07-31T14:00:00", 5.3, 0.75),
("7/31/2022", "03:00 PM", "2022-07-31T15:00:00", 5.0, 0.70),
("7/31/2022", "04:00 PM", "2022-07-31T16:00:00", 2.2, 0.31),
("7/31/2022", "05:00 PM", "2022-07-31T17:00:00", 2.6, 0.37),
("7/31/2022", "06:00 PM", "2022-07-31T18:00:00", 4.5, 0.64),
("7/31/2022", "07:00 PM", "2022-07-31T19:00:00", 2.5, 0.35),
("7/31/2022", "08:00 PM", "2022-07-31T20:00:00", 2.9, 0.42),
("7/31/2022", "09:00 PM", "2022-07-31T21:00:00", 2.2, 0.32),
("7/31/2022", "10:00 PM", "2022-07-31T22:00:00", 2.1, 0.30),
("7/31/2022", "11:00 PM", "2022-07-31T23:00:00", 2.0, 0.28),
("8/01/2022", "00:00 AM", "2022-08-01T00:00:00", 1.8, 0.26),
("8/01/2022", "01:00 AM", "2022-08-01T01:00:00", 1.7, 0.26),
("8/01/2022", "02:00 AM", "2022-08-01T02:00:00", 1.7, 0.26),
("8/01/2022", "03:00 AM", "2022-08-01T03:00:00", 0.8, 0.14),
("8/01/2022", "04:00 AM", "2022-08-01T04:00:00", 1.2, 0.19),
("8/01/2022", "05:00 AM", "2022-08-01T05:00:00", 1.6, 0.23),
("8/01/2022", "06:00 AM", "2022-08-01T06:00:00", 1.2, 0.18),
("8/01/2022", "07:00 AM", "2022-08-01T07:00:00", 3.1, 0.44),
("8/01/2022", "08:00 AM", "2022-08-01T08:00:00", 2.5, 0.35),
("8/01/2022", "09:00 AM", "2022-08-01T09:00:00", 3.3, 0.47),
("8/01/2022", "10:00 AM", "2022-08-01T10:00:00", 2.6, 0.37),
("8/01/2022", "11:00 AM", "2022-08-01T11:00:00", 0.8, 0.13),
("8/01/2022", "12:00 PM", "2022-08-01T12:00:00", 0.6, 0.11),
("8/01/2022", "01:00 PM", "2022-08-01T13:00:00", 6.4, 0.9),
("8/01/2022", "02:00 PM", "2022-08-01T14:00:00", 3.6, 0.52),
("8/01/2022", "03:00 PM", "2022-08-01T15:00:00", 5.5, 0.79),
("8/01/2022", "04:00 PM", "2022-08-01T16:00:00", 3.0, 0.43),
("8/01/2022", "05:00 PM", "2022-08-01T17:00:00", 5.0, 0.71),
("8/01/2022", "06:00 PM", "2022-08-01T18:00:00", 4.4, 0.63),
("8/01/2022", "07:00 PM", "2022-08-01T19:00:00", 3.8, 0.54),
("8/01/2022", "08:00 PM", "2022-08-01T20:00:00", 3.6, 0.51),
("8/01/2022", "09:00 PM", "2022-08-01T21:00:00", 2.9, 0.4),
("8/01/2022", "10:00 PM", "2022-08-01T22:00:00", 3.4, 0.49),
("8/01/2022", "11:00 PM", "2022-08-01T23:00:00", 2.9, 0.41),
("8/02/2022", "00:00 AM", "2022-08-02T00:00:00", 2.0, 0.3),
("8/02/2022", "01:00 AM", "2022-08-02T01:00:00", 2.0, 0.29),
("8/02/2022", "02:00 AM", "2022-08-02T02:00:00", 1.9, 0.28),
("8/02/2022", "03:00 AM", "2022-08-02T03:00:00", 1.8, 0.27),
("8/02/2022", "04:00 AM", "2022-08-02T04:00:00", 1.8, 0.26),
("8/02/2022", "05:00 AM", "2022-08-02T05:00:00", 1.6, 0.23),
("8/02/2022", "06:00 AM", "2022-08-02T06:00:00", 0.8, 0.14),
("8/02/2022", "07:00 AM", "2022-08-02T07:00:00", 4.0, 0.56),
("8/02/2022", "08:00 AM", "2022-08-02T08:00:00", 2.4, 0.34),
("8/02/2022", "09:00 AM", "2022-08-02T09:00:00", 4.1, 0.58),
("8/02/2022", "10:00 AM", "2022-08-02T10:00:00", 2.6, 0.37),
("8/02/2022", "11:00 AM", "2022-08-02T11:00:00", 0.5, 0.1),
("8/02/2022", "12:00 PM", "2022-08-02T12:00:00", 1.0, 0.16),
]
# Majority of the day the latest data we can see is yesterdays data
MOCK_USAGE_DAY_AUG_1_HOUR_5 = [
("7/31/2022", "00:00 AM", "2022-07-31T00:00:00", 1.2, 0.19),
("7/31/2022", "01:00 AM", "2022-07-31T01:00:00", 1.3, 0.20),
("7/31/2022", "02:00 AM", "2022-07-31T02:00:00", 1.1, 0.17),
("7/31/2022", "03:00 AM", "2022-07-31T03:00:00", 1.2, 0.18),
("7/31/2022", "04:00 AM", "2022-07-31T04:00:00", 0.8, 0.13),
("7/31/2022", "05:00 AM", "2022-07-31T05:00:00", 0.9, 0.14),
("7/31/2022", "06:00 AM", "2022-07-31T06:00:00", 1.6, 0.24),
("7/31/2022", "07:00 AM", "2022-07-31T07:00:00", 3.7, 0.53),
("7/31/2022", "08:00 AM", "2022-07-31T08:00:00", 1.0, 0.16),
("7/31/2022", "09:00 AM", "2022-07-31T09:00:00", 0.7, 0.12),
("7/31/2022", "10:00 AM", "2022-07-31T10:00:00", 1.9, 0.28),
("7/31/2022", "11:00 AM", "2022-07-31T11:00:00", 4.3, 0.61),
("7/31/2022", "12:00 PM", "2022-07-31T12:00:00", 2.0, 0.29),
("7/31/2022", "01:00 PM", "2022-07-31T13:00:00", 3.9, 0.55),
("7/31/2022", "02:00 PM", "2022-07-31T14:00:00", 5.3, 0.75),
("7/31/2022", "03:00 PM", "2022-07-31T15:00:00", 5.0, 0.70),
("7/31/2022", "04:00 PM", "2022-07-31T16:00:00", 2.2, 0.31),
("7/31/2022", "05:00 PM", "2022-07-31T17:00:00", 2.6, 0.37),
("7/31/2022", "06:00 PM", "2022-07-31T18:00:00", 4.5, 0.64),
("7/31/2022", "07:00 PM", "2022-07-31T19:00:00", 2.5, 0.35),
("7/31/2022", "08:00 PM", "2022-07-31T20:00:00", 2.9, 0.42),
("7/31/2022", "09:00 PM", "2022-07-31T21:00:00", 2.2, 0.32),
("7/31/2022", "10:00 PM", "2022-07-31T22:00:00", 2.1, 0.30),
("7/31/2022", "11:00 PM", "2022-07-31T23:00:00", 2.0, 0.28),
]
# At midnight the next day, we get yesterday's data BUT the last few hours
# incomplete.
MOCK_USAGE_DAY_AUG_2_HOUR_0 = [
# everything from aug 1
*MOCK_USAGE_DAY_AUG_1_HOUR_5,
("8/01/2022", "00:00 AM", "2022-08-01T00:00:00", 1.8, 0.26),
("8/01/2022", "01:00 AM", "2022-08-01T01:00:00", 1.7, 0.26),
("8/01/2022", "02:00 AM", "2022-08-01T02:00:00", 1.7, 0.26),
("8/01/2022", "03:00 AM", "2022-08-01T03:00:00", 0.8, 0.14),
("8/01/2022", "04:00 AM", "2022-08-01T04:00:00", 1.2, 0.19),
("8/01/2022", "05:00 AM", "2022-08-01T05:00:00", 1.6, 0.23),
("8/01/2022", "06:00 AM", "2022-08-01T06:00:00", 1.2, 0.18),
("8/01/2022", "07:00 AM", "2022-08-01T07:00:00", 3.1, 0.44),
("8/01/2022", "08:00 AM", "2022-08-01T08:00:00", 2.5, 0.35),
("8/01/2022", "09:00 AM", "2022-08-01T09:00:00", 3.3, 0.47),
("8/01/2022", "10:00 AM", "2022-08-01T10:00:00", 2.6, 0.37),
("8/01/2022", "11:00 AM", "2022-08-01T11:00:00", 0.8, 0.13),
("8/01/2022", "12:00 PM", "2022-08-01T12:00:00", 0.6, 0.11),
("8/01/2022", "01:00 PM", "2022-08-01T13:00:00", 6.4, 0.9),
("8/01/2022", "02:00 PM", "2022-08-01T14:00:00", 3.6, 0.52),
("8/01/2022", "03:00 PM", "2022-08-01T15:00:00", 5.5, 0.79),
("8/01/2022", "04:00 PM", "2022-08-01T16:00:00", 3.0, 0.43),
("8/01/2022", "05:00 PM", "2022-08-01T17:00:00", 5.0, 0.71),
("8/01/2022", "06:00 PM", "2022-08-01T18:00:00", 4.4, 0.63),
("8/01/2022", "07:00 PM", "2022-08-01T19:00:00", 1.9, 0.27),
("8/01/2022", "08:00 PM", "2022-08-01T20:00:00", 0.0, 0.0),
("8/01/2022", "09:00 PM", "2022-08-01T21:00:00", 0.0, 0.0),
("8/01/2022", "10:00 PM", "2022-08-01T22:00:00", 0.0, 0.0),
("8/01/2022", "11:00 PM", "2022-08-01T23:00:00", 0.0, 0.0),
]
# Around an hour after midnight, we get more of yesterdays data BUT the last
# record typically only accounts for part of the last hour, so it will get
# updated again.
MOCK_USAGE_DAY_AUG_2_HOUR_1 = [
# everything from hour 0 except the last 5 entries, replaced by the updated values below
*MOCK_USAGE_DAY_AUG_2_HOUR_0[:-5],
("8/01/2022", "07:00 PM", "2022-08-01T19:00:00", 3.8, 0.54),
("8/01/2022", "08:00 PM", "2022-08-01T20:00:00", 3.6, 0.51),
("8/01/2022", "09:00 PM", "2022-08-01T21:00:00", 2.9, 0.4),
("8/01/2022", "10:00 PM", "2022-08-01T22:00:00", 3.4, 0.49),
("8/01/2022", "11:00 PM", "2022-08-01T23:00:00", 1.4, 0.2),
]
# Finally around 5 AM, we get the finalized data
MOCK_USAGE_DAY_AUG_2_HOUR_5 = [
# everything from hour 1 except the last 1 entry, replaced by the updated values below
*MOCK_USAGE_DAY_AUG_2_HOUR_1[:-1],
("8/01/2022", "11:00 PM", "2022-08-01T23:00:00", 2.9, 0.41),
]
MOCK_USAGE_AT_TIMES = [
("2022-08-01T05:00:00-07:00", MOCK_USAGE_DAY_AUG_1_HOUR_5),
("2022-08-02T00:00:00-07:00", MOCK_USAGE_DAY_AUG_2_HOUR_0),
("2022-08-02T01:00:00-07:00", MOCK_USAGE_DAY_AUG_2_HOUR_1),
("2022-08-02T05:00:00-07:00", MOCK_USAGE_DAY_AUG_2_HOUR_5),
]
+37 -6
View File
@@ -7,17 +7,21 @@ from unittest.mock import MagicMock, patch
from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components.recorder import Recorder
from homeassistant.components.srp_energy.const import DOMAIN, PHOENIX_TIME_ZONE
from homeassistant.components.srp_energy.coordinator import HourlyUsageTuple
from homeassistant.const import CONF_ID
from homeassistant.core import HomeAssistant
from homeassistant.util import dt as dt_util
from . import MOCK_USAGE, TEST_CONFIG_HOME
from . import MOCK_USAGE_AT_TIMES, TEST_CONFIG_HOME
from tests.common import MockConfigEntry
PHOENIX_ZONE_INFO = dt_util.get_time_zone(PHOENIX_TIME_ZONE)
@pytest.fixture(name="setup_hass_config", autouse=True)
@pytest.fixture(name="setup_hass_config")
async def fixture_setup_hass_config(hass: HomeAssistant) -> None:
"""Set up things to be run when tests are started."""
hass.config.latitude = 33.27
@@ -34,17 +38,43 @@ def fixture_hass_tz_info(hass: HomeAssistant, setup_hass_config) -> dt.tzinfo |
@pytest.fixture(name="test_date")
def fixture_test_date(hass: HomeAssistant, hass_tz_info) -> dt.datetime | None:
"""Return test datetime for the hass timezone."""
return dt.datetime(2022, 8, 2, 0, 0, 0, 0, tzinfo=hass_tz_info)
# Default to run in the middle of the day on aug 2
return dt.datetime(2022, 8, 2, 12, 0, 0, 0, tzinfo=hass_tz_info)
@pytest.fixture(name="mock_config_entry")
def fixture_mock_config_entry() -> MockConfigEntry:
def fixture_mock_config_entry(hass: HomeAssistant) -> MockConfigEntry:
"""Return the default mocked config entry."""
return MockConfigEntry(
domain=DOMAIN, data=TEST_CONFIG_HOME, unique_id=TEST_CONFIG_HOME[CONF_ID]
)
def _mock_usage(
start_date: dt.datetime, end_date: dt.datetime, is_tou: bool
) -> list[HourlyUsageTuple]:
now = dt_util.now(PHOENIX_ZONE_INFO).replace(minute=0, second=0, microsecond=0)
data = MOCK_USAGE_AT_TIMES[-1][1]
start_date = start_date.replace(
hour=0, minute=0, second=0, microsecond=0, tzinfo=PHOENIX_ZONE_INFO
)
end_date = end_date.replace(
hour=23, minute=59, second=59, microsecond=999999, tzinfo=PHOENIX_ZONE_INFO
)
for key, value in reversed(MOCK_USAGE_AT_TIMES):
if now >= dt_util.parse_datetime(key).replace(tzinfo=PHOENIX_ZONE_INFO):
data = value
break
def is_in_range(ts: str) -> bool:
item_time = dt_util.parse_datetime(ts).replace(tzinfo=PHOENIX_ZONE_INFO)
after_start = item_time >= start_date
before_end = item_time <= end_date
return after_start and before_end
return [item for item in data if is_in_range(item[2])]
@pytest.fixture(name="mock_srp_energy")
def fixture_mock_srp_energy() -> Generator[MagicMock]:
"""Return a mocked SrpEnergyClient client."""
@@ -53,7 +83,7 @@ def fixture_mock_srp_energy() -> Generator[MagicMock]:
) as srp_energy_mock:
client = srp_energy_mock.return_value
client.validate.return_value = True
client.usage.return_value = MOCK_USAGE
client.usage.side_effect = _mock_usage
yield client
@@ -65,12 +95,13 @@ def fixture_mock_srp_energy_config_flow() -> Generator[MagicMock]:
) as srp_energy_mock:
client = srp_energy_mock.return_value
client.validate.return_value = True
client.usage.return_value = MOCK_USAGE
client.usage.side_effect = _mock_usage
yield client
@pytest.fixture
async def init_integration(
recorder_mock: Recorder,
hass: HomeAssistant,
freezer: FrozenDateTimeFactory,
test_date: dt.datetime,
@@ -0,0 +1,677 @@
# serializer version: 1
# name: test_coordinator_first_run
defaultdict({
'srp_energy:123456789_energy_consumption': list([
dict({
'end': 1659254400.0,
'start': 1659250800.0,
'state': 1.2,
'sum': 1.2,
}),
dict({
'end': 1659258000.0,
'start': 1659254400.0,
'state': 1.3,
'sum': 2.5,
}),
dict({
'end': 1659261600.0,
'start': 1659258000.0,
'state': 1.1,
'sum': 3.6,
}),
dict({
'end': 1659265200.0,
'start': 1659261600.0,
'state': 1.2,
'sum': 4.8,
}),
dict({
'end': 1659268800.0,
'start': 1659265200.0,
'state': 0.8,
'sum': 5.6,
}),
dict({
'end': 1659272400.0,
'start': 1659268800.0,
'state': 0.9,
'sum': 6.5,
}),
dict({
'end': 1659276000.0,
'start': 1659272400.0,
'state': 1.6,
'sum': 8.1,
}),
dict({
'end': 1659279600.0,
'start': 1659276000.0,
'state': 3.7,
'sum': 11.8,
}),
dict({
'end': 1659283200.0,
'start': 1659279600.0,
'state': 1.0,
'sum': 12.8,
}),
dict({
'end': 1659286800.0,
'start': 1659283200.0,
'state': 0.7,
'sum': 13.5,
}),
dict({
'end': 1659290400.0,
'start': 1659286800.0,
'state': 1.9,
'sum': 15.4,
}),
dict({
'end': 1659294000.0,
'start': 1659290400.0,
'state': 4.3,
'sum': 19.7,
}),
dict({
'end': 1659297600.0,
'start': 1659294000.0,
'state': 2.0,
'sum': 21.7,
}),
dict({
'end': 1659301200.0,
'start': 1659297600.0,
'state': 3.9,
'sum': 25.599999999999998,
}),
dict({
'end': 1659304800.0,
'start': 1659301200.0,
'state': 5.3,
'sum': 30.9,
}),
dict({
'end': 1659308400.0,
'start': 1659304800.0,
'state': 5.0,
'sum': 35.9,
}),
dict({
'end': 1659312000.0,
'start': 1659308400.0,
'state': 2.2,
'sum': 38.1,
}),
dict({
'end': 1659315600.0,
'start': 1659312000.0,
'state': 2.6,
'sum': 40.7,
}),
dict({
'end': 1659319200.0,
'start': 1659315600.0,
'state': 4.5,
'sum': 45.2,
}),
dict({
'end': 1659322800.0,
'start': 1659319200.0,
'state': 2.5,
'sum': 47.7,
}),
dict({
'end': 1659326400.0,
'start': 1659322800.0,
'state': 2.9,
'sum': 50.6,
}),
dict({
'end': 1659330000.0,
'start': 1659326400.0,
'state': 2.2,
'sum': 52.800000000000004,
}),
dict({
'end': 1659333600.0,
'start': 1659330000.0,
'state': 2.1,
'sum': 54.900000000000006,
}),
dict({
'end': 1659337200.0,
'start': 1659333600.0,
'state': 2.0,
'sum': 56.900000000000006,
}),
dict({
'end': 1659340800.0,
'start': 1659337200.0,
'state': 1.8,
'sum': 58.7,
}),
dict({
'end': 1659344400.0,
'start': 1659340800.0,
'state': 1.7,
'sum': 60.400000000000006,
}),
dict({
'end': 1659348000.0,
'start': 1659344400.0,
'state': 1.7,
'sum': 62.10000000000001,
}),
dict({
'end': 1659351600.0,
'start': 1659348000.0,
'state': 0.8,
'sum': 62.900000000000006,
}),
dict({
'end': 1659355200.0,
'start': 1659351600.0,
'state': 1.2,
'sum': 64.10000000000001,
}),
dict({
'end': 1659358800.0,
'start': 1659355200.0,
'state': 1.6,
'sum': 65.7,
}),
dict({
'end': 1659362400.0,
'start': 1659358800.0,
'state': 1.2,
'sum': 66.9,
}),
dict({
'end': 1659366000.0,
'start': 1659362400.0,
'state': 3.1,
'sum': 70.0,
}),
dict({
'end': 1659369600.0,
'start': 1659366000.0,
'state': 2.5,
'sum': 72.5,
}),
dict({
'end': 1659373200.0,
'start': 1659369600.0,
'state': 3.3,
'sum': 75.8,
}),
dict({
'end': 1659376800.0,
'start': 1659373200.0,
'state': 2.6,
'sum': 78.39999999999999,
}),
dict({
'end': 1659380400.0,
'start': 1659376800.0,
'state': 0.8,
'sum': 79.19999999999999,
}),
dict({
'end': 1659384000.0,
'start': 1659380400.0,
'state': 0.6,
'sum': 79.79999999999998,
}),
dict({
'end': 1659387600.0,
'start': 1659384000.0,
'state': 6.4,
'sum': 86.19999999999999,
}),
dict({
'end': 1659391200.0,
'start': 1659387600.0,
'state': 3.6,
'sum': 89.79999999999998,
}),
dict({
'end': 1659394800.0,
'start': 1659391200.0,
'state': 5.5,
'sum': 95.29999999999998,
}),
dict({
'end': 1659398400.0,
'start': 1659394800.0,
'state': 3.0,
'sum': 98.29999999999998,
}),
dict({
'end': 1659402000.0,
'start': 1659398400.0,
'state': 5.0,
'sum': 103.29999999999998,
}),
dict({
'end': 1659405600.0,
'start': 1659402000.0,
'state': 4.4,
'sum': 107.69999999999999,
}),
dict({
'end': 1659409200.0,
'start': 1659405600.0,
'state': 3.8,
'sum': 111.49999999999999,
}),
dict({
'end': 1659412800.0,
'start': 1659409200.0,
'state': 3.6,
'sum': 115.09999999999998,
}),
dict({
'end': 1659416400.0,
'start': 1659412800.0,
'state': 2.9,
'sum': 117.99999999999999,
}),
dict({
'end': 1659420000.0,
'start': 1659416400.0,
'state': 3.4,
'sum': 121.39999999999999,
}),
dict({
'end': 1659423600.0,
'start': 1659420000.0,
'state': 2.9,
'sum': 124.3,
}),
]),
'srp_energy:123456789_energy_cost': list([
dict({
'end': 1659254400.0,
'start': 1659250800.0,
'state': 0.19,
'sum': 0.19,
}),
dict({
'end': 1659258000.0,
'start': 1659254400.0,
'state': 0.2,
'sum': 0.39,
}),
dict({
'end': 1659261600.0,
'start': 1659258000.0,
'state': 0.17,
'sum': 0.56,
}),
dict({
'end': 1659265200.0,
'start': 1659261600.0,
'state': 0.18,
'sum': 0.74,
}),
dict({
'end': 1659268800.0,
'start': 1659265200.0,
'state': 0.13,
'sum': 0.87,
}),
dict({
'end': 1659272400.0,
'start': 1659268800.0,
'state': 0.14,
'sum': 1.01,
}),
dict({
'end': 1659276000.0,
'start': 1659272400.0,
'state': 0.24,
'sum': 1.25,
}),
dict({
'end': 1659279600.0,
'start': 1659276000.0,
'state': 0.53,
'sum': 1.78,
}),
dict({
'end': 1659283200.0,
'start': 1659279600.0,
'state': 0.16,
'sum': 1.94,
}),
dict({
'end': 1659286800.0,
'start': 1659283200.0,
'state': 0.12,
'sum': 2.06,
}),
dict({
'end': 1659290400.0,
'start': 1659286800.0,
'state': 0.28,
'sum': 2.34,
}),
dict({
'end': 1659294000.0,
'start': 1659290400.0,
'state': 0.61,
'sum': 2.9499999999999997,
}),
dict({
'end': 1659297600.0,
'start': 1659294000.0,
'state': 0.29,
'sum': 3.2399999999999998,
}),
dict({
'end': 1659301200.0,
'start': 1659297600.0,
'state': 0.55,
'sum': 3.79,
}),
dict({
'end': 1659304800.0,
'start': 1659301200.0,
'state': 0.75,
'sum': 4.54,
}),
dict({
'end': 1659308400.0,
'start': 1659304800.0,
'state': 0.7,
'sum': 5.24,
}),
dict({
'end': 1659312000.0,
'start': 1659308400.0,
'state': 0.31,
'sum': 5.55,
}),
dict({
'end': 1659315600.0,
'start': 1659312000.0,
'state': 0.37,
'sum': 5.92,
}),
dict({
'end': 1659319200.0,
'start': 1659315600.0,
'state': 0.64,
'sum': 6.56,
}),
dict({
'end': 1659322800.0,
'start': 1659319200.0,
'state': 0.35,
'sum': 6.909999999999999,
}),
dict({
'end': 1659326400.0,
'start': 1659322800.0,
'state': 0.42,
'sum': 7.329999999999999,
}),
dict({
'end': 1659330000.0,
'start': 1659326400.0,
'state': 0.32,
'sum': 7.6499999999999995,
}),
dict({
'end': 1659333600.0,
'start': 1659330000.0,
'state': 0.3,
'sum': 7.949999999999999,
}),
dict({
'end': 1659337200.0,
'start': 1659333600.0,
'state': 0.28,
'sum': 8.229999999999999,
}),
dict({
'end': 1659340800.0,
'start': 1659337200.0,
'state': 0.26,
'sum': 8.489999999999998,
}),
dict({
'end': 1659344400.0,
'start': 1659340800.0,
'state': 0.26,
'sum': 8.749999999999998,
}),
dict({
'end': 1659348000.0,
'start': 1659344400.0,
'state': 0.26,
'sum': 9.009999999999998,
}),
dict({
'end': 1659351600.0,
'start': 1659348000.0,
'state': 0.14,
'sum': 9.149999999999999,
}),
dict({
'end': 1659355200.0,
'start': 1659351600.0,
'state': 0.19,
'sum': 9.339999999999998,
}),
dict({
'end': 1659358800.0,
'start': 1659355200.0,
'state': 0.23,
'sum': 9.569999999999999,
}),
dict({
'end': 1659362400.0,
'start': 1659358800.0,
'state': 0.18,
'sum': 9.749999999999998,
}),
dict({
'end': 1659366000.0,
'start': 1659362400.0,
'state': 0.44,
'sum': 10.189999999999998,
}),
dict({
'end': 1659369600.0,
'start': 1659366000.0,
'state': 0.35,
'sum': 10.539999999999997,
}),
dict({
'end': 1659373200.0,
'start': 1659369600.0,
'state': 0.47,
'sum': 11.009999999999998,
}),
dict({
'end': 1659376800.0,
'start': 1659373200.0,
'state': 0.37,
'sum': 11.379999999999997,
}),
dict({
'end': 1659380400.0,
'start': 1659376800.0,
'state': 0.13,
'sum': 11.509999999999998,
}),
dict({
'end': 1659384000.0,
'start': 1659380400.0,
'state': 0.11,
'sum': 11.619999999999997,
}),
dict({
'end': 1659387600.0,
'start': 1659384000.0,
'state': 0.9,
'sum': 12.519999999999998,
}),
dict({
'end': 1659391200.0,
'start': 1659387600.0,
'state': 0.52,
'sum': 13.039999999999997,
}),
dict({
'end': 1659394800.0,
'start': 1659391200.0,
'state': 0.79,
'sum': 13.829999999999998,
}),
dict({
'end': 1659398400.0,
'start': 1659394800.0,
'state': 0.43,
'sum': 14.259999999999998,
}),
dict({
'end': 1659402000.0,
'start': 1659398400.0,
'state': 0.71,
'sum': 14.969999999999999,
}),
dict({
'end': 1659405600.0,
'start': 1659402000.0,
'state': 0.63,
'sum': 15.6,
}),
dict({
'end': 1659409200.0,
'start': 1659405600.0,
'state': 0.54,
'sum': 16.14,
}),
dict({
'end': 1659412800.0,
'start': 1659409200.0,
'state': 0.51,
'sum': 16.650000000000002,
}),
dict({
'end': 1659416400.0,
'start': 1659412800.0,
'state': 0.4,
'sum': 17.05,
}),
dict({
'end': 1659420000.0,
'start': 1659416400.0,
'state': 0.49,
'sum': 17.54,
}),
dict({
'end': 1659423600.0,
'start': 1659420000.0,
'state': 0.41,
'sum': 17.95,
}),
]),
})
# ---
# name: test_coordinator_subsequent_run
defaultdict({
'srp_energy:123456789_energy_consumption': list([
dict({
'end': 1659315600.0,
'start': 1659312000.0,
'state': 2.6,
'sum': 2.6,
}),
dict({
'end': 1659319200.0,
'start': 1659315600.0,
'state': 4.5,
'sum': 7.1,
}),
dict({
'end': 1659322800.0,
'start': 1659319200.0,
'state': 2.5,
'sum': 9.6,
}),
dict({
'end': 1659326400.0,
'start': 1659322800.0,
'state': 2.9,
'sum': 12.5,
}),
dict({
'end': 1659330000.0,
'start': 1659326400.0,
'state': 2.2,
'sum': 14.7,
}),
dict({
'end': 1659333600.0,
'start': 1659330000.0,
'state': 2.1,
'sum': 16.8,
}),
dict({
'end': 1659337200.0,
'start': 1659333600.0,
'state': 2.0,
'sum': 18.8,
}),
]),
'srp_energy:123456789_energy_cost': list([
dict({
'end': 1659315600.0,
'start': 1659312000.0,
'state': 0.37,
'sum': 0.37,
}),
dict({
'end': 1659319200.0,
'start': 1659315600.0,
'state': 0.64,
'sum': 1.01,
}),
dict({
'end': 1659322800.0,
'start': 1659319200.0,
'state': 0.35,
'sum': 1.3599999999999999,
}),
dict({
'end': 1659326400.0,
'start': 1659322800.0,
'state': 0.42,
'sum': 1.7799999999999998,
}),
dict({
'end': 1659330000.0,
'start': 1659326400.0,
'state': 0.32,
'sum': 2.0999999999999996,
}),
dict({
'end': 1659333600.0,
'start': 1659330000.0,
'state': 0.3,
'sum': 2.3999999999999995,
}),
dict({
'end': 1659337200.0,
'start': 1659333600.0,
'state': 0.28,
'sum': 2.6799999999999997,
}),
]),
})
# ---
@@ -4,6 +4,7 @@ from unittest.mock import MagicMock, patch
import pytest
from homeassistant.components.recorder import Recorder
from homeassistant.components.srp_energy.const import CONF_IS_TOU, DOMAIN
from homeassistant.config_entries import SOURCE_USER, ConfigEntryState
from homeassistant.const import (
@@ -33,7 +34,7 @@ from tests.common import MockConfigEntry
@pytest.mark.usefixtures("mock_srp_energy_config_flow")
async def test_show_form(
hass: HomeAssistant, capsys: pytest.CaptureFixture[str]
recorder_mock: Recorder, hass: HomeAssistant, capsys: pytest.CaptureFixture[str]
) -> None:
"""Test show configuration form."""
result = await hass.config_entries.flow.async_init(
@@ -69,6 +70,7 @@ async def test_show_form(
async def test_form_invalid_account(
recorder_mock: Recorder,
hass: HomeAssistant,
mock_srp_energy_config_flow: MagicMock,
) -> None:
@@ -88,6 +90,7 @@ async def test_form_invalid_account(
async def test_form_invalid_auth(
recorder_mock: Recorder,
hass: HomeAssistant,
mock_srp_energy_config_flow: MagicMock,
) -> None:
@@ -107,6 +110,7 @@ async def test_form_invalid_auth(
async def test_form_unknown_error(
recorder_mock: Recorder,
hass: HomeAssistant,
mock_srp_energy_config_flow: MagicMock,
) -> None:
@@ -126,7 +130,7 @@ async def test_form_unknown_error(
async def test_flow_entry_already_configured(
hass: HomeAssistant, init_integration: MockConfigEntry
recorder_mock: Recorder, hass: HomeAssistant, init_integration: MockConfigEntry
) -> None:
"""Test user input for config_entry that already exists."""
# Verify mock config setup from fixture
@@ -150,7 +154,7 @@ async def test_flow_entry_already_configured(
async def test_flow_multiple_configs(
hass: HomeAssistant, init_integration: MockConfigEntry
recorder_mock: Recorder, hass: HomeAssistant, init_integration: MockConfigEntry
) -> None:
"""Test multiple config entries."""
# Verify mock config setup from fixture
@@ -183,7 +187,7 @@ async def test_flow_multiple_configs(
async def test_reconfigure(
hass: HomeAssistant, init_integration: MockConfigEntry
recorder_mock: Recorder, hass: HomeAssistant, init_integration: MockConfigEntry
) -> None:
"""Test reconfiguring an existing entry."""
@@ -216,6 +220,7 @@ async def test_reconfigure(
@pytest.mark.usefixtures("mock_setup_entry")
async def test_reconfigure_error(
recorder_mock: Recorder,
hass: HomeAssistant,
init_integration: MockConfigEntry,
mock_srp_energy_config_flow: MagicMock,
@@ -262,6 +267,7 @@ async def test_reconfigure_error(
@pytest.mark.usefixtures("mock_setup_entry")
async def test_reconfigure_unknown_error(
recorder_mock: Recorder,
hass: HomeAssistant,
init_integration: MockConfigEntry,
mock_srp_energy_config_flow: MagicMock,
@@ -0,0 +1,227 @@
"""Tests for Srp Energy component coordinator."""
from datetime import datetime as dt
from unittest.mock import MagicMock
from freezegun.api import freeze_time
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.recorder import Recorder
from homeassistant.components.recorder.statistics import (
StatisticsRow,
statistics_during_period,
)
from homeassistant.components.srp_energy import SRPEnergyDataUpdateCoordinator
from homeassistant.core import HomeAssistant
from homeassistant.util import dt as dt_util
from .conftest import PHOENIX_ZONE_INFO
from tests.common import MockConfigEntry
from tests.components.recorder.common import async_wait_recording_done
@freeze_time("2022-08-02T12:00:00-07:00")
async def test_coordinator_first_run(
recorder_mock: Recorder,
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_srp_energy: MagicMock,
snapshot: SnapshotAssertion,
) -> None:
"""Test the coordinator on its first run with no existing statistics.
Should import multiple days of statistics.
"""
coordinator = SRPEnergyDataUpdateCoordinator(
hass, mock_config_entry, mock_srp_energy
)
await coordinator._async_update_data()
await async_wait_recording_done(hass)
# Check stats for electric account '123456789'
stats = await get_stats(hass)
assert stats == snapshot
async def test_coordinator_subsequent_run(
recorder_mock: Recorder,
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_srp_energy: MagicMock,
snapshot: SnapshotAssertion,
) -> None:
"""Test the coordinator correctly updates statistics on subsequent runs."""
coordinator = SRPEnergyDataUpdateCoordinator(
hass, mock_config_entry, mock_srp_energy
)
mock_srp_energy.usage.side_effect = None
mock_srp_energy.usage.return_value = [
("7/31/2022", "05:00 PM", "2022-07-31T17:00:00", 2.6, 0.37),
("7/31/2022", "06:00 PM", "2022-07-31T18:00:00", 4.5, 0.64),
("7/31/2022", "07:00 PM", "2022-07-31T19:00:00", 2.2, 0.32),
("7/31/2022", "08:00 PM", "2022-07-31T20:00:00", 0.0, 0.0),
("7/31/2022", "09:00 PM", "2022-07-31T21:00:00", 0.0, 0.0),
("7/31/2022", "10:00 PM", "2022-07-31T22:00:00", 0.0, 0.0),
("7/31/2022", "11:00 PM", "2022-07-31T23:00:00", 0.0, 0.0),
]
# Run aug 2nd at midnight to import through aug 1
# BUT tends to be missing last few hours
with freeze_time("2022-08-02T00:00:00-07:00"):
await coordinator._async_update_data()
await async_wait_recording_done(hass)
stats = await get_stats(hass)
last_consumption = stats["srp_energy:123456789_energy_consumption"][-1]
assert_stat(last_consumption, "2022-07-31T19:00:00-07:00", 2.2, 9.3)
last_cost = stats["srp_energy:123456789_energy_cost"][-1]
assert_stat(last_cost, "2022-07-31T19:00:00-07:00", 0.32, 1.33)
mock_srp_energy.usage.return_value = [
("7/31/2022", "05:00 PM", "2022-07-31T17:00:00", 2.6, 0.37),
("7/31/2022", "06:00 PM", "2022-07-31T18:00:00", 4.5, 0.64),
("7/31/2022", "07:00 PM", "2022-07-31T19:00:00", 2.5, 0.35), # was 2.2 / 0.32
("7/31/2022", "08:00 PM", "2022-07-31T20:00:00", 2.9, 0.42), # was 0 / 0
("7/31/2022", "09:00 PM", "2022-07-31T21:00:00", 2.2, 0.32), # was 0 / 0
("7/31/2022", "10:00 PM", "2022-07-31T22:00:00", 2.1, 0.30), # was 0 / 0
("7/31/2022", "11:00 PM", "2022-07-31T23:00:00", 2.0, 0.28), # was 0 / 0
]
# Run aug 2nd at 5am to get the updated data for aug 1
with freeze_time("2022-08-02T05:00:00-07:00"):
await coordinator._async_update_data()
await async_wait_recording_done(hass)
stats = await get_stats(hass)
last_consumption = stats["srp_energy:123456789_energy_consumption"][-1]
assert_stat(last_consumption, "2022-07-31T23:00:00-07:00", 2.0, 18.8)
last_cost = stats["srp_energy:123456789_energy_cost"][-1]
assert_stat(last_cost, "2022-07-31T23:00:00-07:00", 0.28, 2.68)
assert stats == snapshot
def assert_stat(
stat: StatisticsRow, expected_start: str, expected_state: float, expected_sum: float
) -> None:
"""Helper function to assert a single statistics row."""
assert (
dt.fromtimestamp(stat["start"], PHOENIX_ZONE_INFO).isoformat() == expected_start
)
assert round(stat["state"], 2) == expected_state
assert round(stat["sum"], 2) == expected_sum
async def test_coordinator_statistics_gap(
recorder_mock: Recorder,
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_srp_energy: MagicMock,
) -> None:
"""Test coordinator handles a gap between stored stats and SRP's available data.
When SRP's 30-day API window rolls past the period covered by stored statistics,
statistics_during_period finds nothing at hourly_usage[0].start_time. The else
branch should fall back to the last known running sums and continue the totals
from there rather than restarting from zero.
"""
coordinator = SRPEnergyDataUpdateCoordinator(
hass, mock_config_entry, mock_srp_energy
)
# First run: establish two stat entries so get_last_statistics returns 2 records.
mock_srp_energy.usage.side_effect = None
mock_srp_energy.usage.return_value = [
("7/31/2022", "05:00 PM", "2022-07-31T17:00:00", 2.0, 0.20),
("7/31/2022", "06:00 PM", "2022-07-31T18:00:00", 3.0, 0.30),
]
with freeze_time("2022-08-01T12:00:00-07:00"):
await coordinator._async_update_data()
await async_wait_recording_done(hass)
stats = await get_stats(hass)
assert_stat(
stats["srp_energy:123456789_energy_consumption"][-1],
"2022-07-31T18:00:00-07:00",
3.0,
5.0,
)
assert_stat(
stats["srp_energy:123456789_energy_cost"][-1],
"2022-07-31T18:00:00-07:00",
0.30,
0.50,
)
# Second run: SRP's API window has advanced so it only returns data starting
# AFTER the most recent stored stat (18:00). statistics_during_period will find
# nothing at 20:00 or later, triggering the else branch.
mock_srp_energy.usage.return_value = [
("7/31/2022", "08:00 PM", "2022-07-31T20:00:00", 4.0, 0.40),
("7/31/2022", "09:00 PM", "2022-07-31T21:00:00", 5.0, 0.50),
]
with freeze_time("2022-09-01T12:00:00-07:00"):
await coordinator._async_update_data()
await async_wait_recording_done(hass)
stats = await get_stats(hass)
# Sums must continue from the last stored values (5.0 kWh / $0.50), not restart.
assert_stat(
stats["srp_energy:123456789_energy_consumption"][-2],
"2022-07-31T20:00:00-07:00",
4.0,
9.0,
)
assert_stat(
stats["srp_energy:123456789_energy_consumption"][-1],
"2022-07-31T21:00:00-07:00",
5.0,
14.0,
)
assert_stat(
stats["srp_energy:123456789_energy_cost"][-2],
"2022-07-31T20:00:00-07:00",
0.40,
0.90,
)
assert_stat(
stats["srp_energy:123456789_energy_cost"][-1],
"2022-07-31T21:00:00-07:00",
0.50,
1.40,
)
async def test_coordinator_subsequent_run_no_energy_data(
recorder_mock: Recorder,
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_srp_energy: MagicMock,
) -> None:
"""Test the coordinator handles no recent usage/cost data."""
coordinator = SRPEnergyDataUpdateCoordinator(
hass, mock_config_entry, mock_srp_energy
)
await coordinator._async_update_data()
await async_wait_recording_done(hass)
async def get_stats(hass: HomeAssistant) -> dict[str, list[StatisticsRow]]:
"""Helper function to get the latest statistics."""
return await hass.async_add_executor_job(
statistics_during_period,
hass,
dt_util.utc_from_timestamp(0),
None,
{
"srp_energy:123456789_energy_consumption",
"srp_energy:123456789_energy_cost",
},
"hour",
None,
{"state", "sum"},
)
+7 -2
View File
@@ -1,15 +1,20 @@
"""Tests for Srp Energy component Init."""
from homeassistant.components.recorder import Recorder
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
async def test_setup_entry(hass: HomeAssistant, init_integration) -> None:
async def test_setup_entry(
recorder_mock: Recorder, hass: HomeAssistant, init_integration
) -> None:
"""Test setup entry."""
assert init_integration.state is ConfigEntryState.LOADED
async def test_unload_entry(hass: HomeAssistant, init_integration) -> None:
async def test_unload_entry(
recorder_mock: Recorder, hass: HomeAssistant, init_integration
) -> None:
"""Test being able to unload an entry."""
assert init_integration.state is ConfigEntryState.LOADED
+10 -3
View File
@@ -4,6 +4,7 @@ from unittest.mock import patch
from requests.models import HTTPError
from homeassistant.components.recorder import Recorder
from homeassistant.components.sensor import SensorDeviceClass, SensorStateClass
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import (
@@ -17,7 +18,9 @@ from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
async def test_loading_sensors(hass: HomeAssistant, init_integration) -> None:
async def test_loading_sensors(
recorder_mock: Recorder, hass: HomeAssistant, init_integration
) -> None:
"""Test the srp energy sensors."""
# Validate the Config Entry was initialized
assert init_integration.state is ConfigEntryState.LOADED
@@ -26,10 +29,12 @@ async def test_loading_sensors(hass: HomeAssistant, init_integration) -> None:
assert len(hass.states.async_all()) == 1
async def test_srp_entity(hass: HomeAssistant, init_integration) -> None:
async def test_srp_entity(
recorder_mock: Recorder, hass: HomeAssistant, init_integration
) -> None:
"""Test the SrpEntity."""
usage_state = hass.states.get("sensor.srp_energy_mock_title_energy_usage")
assert usage_state.state == "150.8"
assert usage_state.state == "67.4"
# Validate attributions
assert (
@@ -45,6 +50,7 @@ async def test_srp_entity(hass: HomeAssistant, init_integration) -> None:
async def test_srp_entity_update_failed(
recorder_mock: Recorder,
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
) -> None:
@@ -66,6 +72,7 @@ async def test_srp_entity_update_failed(
async def test_srp_entity_timeout(
recorder_mock: Recorder,
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
) -> None: