Use python defaults for comparing State, LazyState, and Event objects (#86856)

* Speed up comparing State and Event objects

Use default python implementation for State and Event __hash__ and __eq__

The default implementation compared based on the id() of the object
which is effectively what we want here anyways. These overrides are
left over from the days when these used to be attrs objects

By avoiding implementing these ourselves all of the equality checks
can happen in native code

* tweak

* adjust tests

* write out some more

* fix test to not compare objects

* more test fixes

* more test fixes

* correct stats tests

* fix more tests

* fix more tests

* update sensor recorder tests
This commit is contained in:
J. Nick Koston 2023-01-29 08:31:43 -10:00 committed by GitHub
parent 80ffac48a3
commit c612a92cfb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 389 additions and 174 deletions

View File

@ -233,15 +233,6 @@ class LazyStatePreSchema31(State):
"last_updated": last_updated_isoformat,
}
def __eq__(self, other: Any) -> bool:
"""Return the comparison."""
return (
other.__class__ in [self.__class__, State]
and self.entity_id == other.entity_id
and self.state == other.state
and self.attributes == other.attributes
)
class LazyState(State):
"""A lazy version of core State after schema 31."""
@ -341,15 +332,6 @@ class LazyState(State):
"last_updated": last_updated_isoformat,
}
def __eq__(self, other: Any) -> bool:
"""Return the comparison."""
return (
other.__class__ in [self.__class__, State]
and self.entity_id == other.entity_id
and self.state == other.state
and self.attributes == other.attributes
)
def decode_attributes_from_row(
row: Row, attr_cache: dict[str, dict[str, Any]]

View File

@ -813,11 +813,6 @@ class Event:
id=ulid_util.ulid(dt_util.utc_to_timestamp(self.time_fired))
)
def __hash__(self) -> int:
"""Make hashable."""
# The only event type that shares context are the TIME_CHANGED
return hash((self.event_type, self.context.id, self.time_fired))
def as_dict(self) -> dict[str, Any]:
"""Create a dict representation of this Event.
@ -841,17 +836,6 @@ class Event:
return f"<Event {self.event_type}[{str(self.origin)[0]}]>"
def __eq__(self, other: Any) -> bool:
"""Return the comparison."""
return ( # type: ignore[no-any-return]
self.__class__ == other.__class__
and self.event_type == other.event_type
and self.data == other.data
and self.origin == other.origin
and self.time_fired == other.time_fired
and self.context == other.context
)
class _FilterableJob(NamedTuple):
"""Event listener job to be executed with optional filter."""
@ -1156,13 +1140,6 @@ class State:
self._as_dict: ReadOnlyDict[str, Collection[Any]] | None = None
self._as_compressed_state: dict[str, Any] | None = None
def __hash__(self) -> int:
"""Make the state hashable.
State objects are effectively immutable.
"""
return hash((id(self), self.last_updated))
@property
def name(self) -> str:
"""Name of this state."""
@ -1274,16 +1251,6 @@ class State:
self.context.user_id, self.context.parent_id, self.context.id
)
def __eq__(self, other: Any) -> bool:
"""Return the comparison of the state."""
return ( # type: ignore[no-any-return]
self.__class__ == other.__class__
and self.entity_id == other.entity_id
and self.state == other.state
and self.attributes == other.attributes
and self.context == other.context
)
def __repr__(self) -> str:
"""Return the representation of the states."""
attrs = f"; {util.repr_helper(self.attributes)}" if self.attributes else ""

View File

@ -30,8 +30,9 @@ async def test_api_list_state_entities(hass, mock_api_client):
assert resp.status == HTTPStatus.OK
json = await resp.json()
remote_data = [ha.State.from_dict(item) for item in json]
assert remote_data == hass.states.async_all()
remote_data = [ha.State.from_dict(item).as_dict() for item in json]
local_data = [state.as_dict() for state in hass.states.async_all()]
assert remote_data == local_data
async def test_api_get_state(hass, mock_api_client):

View File

@ -1,7 +1,7 @@
"""The tests for reproduction of state."""
from asyncio import Future
from unittest.mock import patch
from unittest.mock import ANY, patch
from homeassistant.components.group.reproduce_state import async_reproduce_states
from homeassistant.core import Context, State
@ -43,11 +43,12 @@ async def test_reproduce_group(hass):
fun.assert_called_once_with(
hass,
[
clone_state(state, "light.test1"),
clone_state(state, "light.test2"),
clone_state(state, "switch.test1"),
],
ANY,
context=context,
reproduce_options=None,
)
entities = fun.call_args[0][1]
assert entities[0].entity_id == "light.test1"
assert entities[1].entity_id == "light.test2"
assert entities[2].entity_id == "switch.test1"

View File

@ -1 +1,5 @@
"""Tests for the history component."""
import pytest
pytest.register_assert_rewrite("tests.components.recorder.common")

View File

@ -23,6 +23,10 @@ from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util
from tests.components.recorder.common import (
assert_dict_of_states_equal_without_context_and_last_changed,
assert_multiple_states_equal_without_context,
assert_multiple_states_equal_without_context_and_last_changed,
assert_states_equal_without_context,
async_wait_recording_done,
wait_recording_done,
)
@ -53,7 +57,7 @@ def test_get_significant_states(hass_history):
hass = hass_history
zero, four, states = record_states(hass)
hist = get_significant_states(hass, zero, four, filters=history.Filters())
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_minimal_response(hass_history):
@ -95,7 +99,30 @@ def test_get_significant_states_minimal_response(hass_history):
"last_changed": orig_last_changed,
"state": orig_state,
}
assert states == hist
assert len(hist) == len(states)
assert_states_equal_without_context(
states["media_player.test"][0], hist["media_player.test"][0]
)
assert states["media_player.test"][1] == hist["media_player.test"][1]
assert states["media_player.test"][2] == hist["media_player.test"][2]
assert_multiple_states_equal_without_context(
states["media_player.test2"], hist["media_player.test2"]
)
assert_states_equal_without_context(
states["media_player.test3"][0], hist["media_player.test3"][0]
)
assert states["media_player.test3"][1] == hist["media_player.test3"][1]
assert_multiple_states_equal_without_context(
states["script.can_cancel_this_one"], hist["script.can_cancel_this_one"]
)
assert_multiple_states_equal_without_context_and_last_changed(
states["thermostat.test"], hist["thermostat.test"]
)
assert_multiple_states_equal_without_context_and_last_changed(
states["thermostat.test2"], hist["thermostat.test2"]
)
def test_get_significant_states_with_initial(hass_history):
@ -123,7 +150,7 @@ def test_get_significant_states_with_initial(hass_history):
filters=history.Filters(),
include_start_time_state=True,
)
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_without_initial(hass_history):
@ -150,7 +177,7 @@ def test_get_significant_states_without_initial(hass_history):
filters=history.Filters(),
include_start_time_state=False,
)
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_entity_id(hass_history):
@ -166,7 +193,7 @@ def test_get_significant_states_entity_id(hass_history):
hist = get_significant_states(
hass, zero, four, ["media_player.test"], filters=history.Filters()
)
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_multiple_entity_ids(hass_history):
@ -185,7 +212,7 @@ def test_get_significant_states_multiple_entity_ids(hass_history):
["media_player.test", "thermostat.test"],
filters=history.Filters(),
)
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_exclude_domain(hass_history):
@ -490,14 +517,22 @@ def test_get_significant_states_only(hass_history):
hist = get_significant_states(hass, start, significant_changes_only=True)
assert len(hist[entity_id]) == 2
assert states[0] not in hist[entity_id]
assert states[1] in hist[entity_id]
assert states[2] in hist[entity_id]
assert not any(
state.last_updated == states[0].last_updated for state in hist[entity_id]
)
assert any(
state.last_updated == states[1].last_updated for state in hist[entity_id]
)
assert any(
state.last_updated == states[2].last_updated for state in hist[entity_id]
)
hist = get_significant_states(hass, start, significant_changes_only=False)
assert len(hist[entity_id]) == 3
assert states == hist[entity_id]
assert_multiple_states_equal_without_context_and_last_changed(
states, hist[entity_id]
)
def check_significant_states(hass, zero, four, states, config):
@ -513,7 +548,7 @@ def check_significant_states(hass, zero, four, states, config):
filters.included_domains = include.get(CONF_DOMAINS, [])
hist = get_significant_states(hass, zero, four, filters=filters)
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def record_states(hass):

View File

@ -24,6 +24,10 @@ from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util
from tests.components.recorder.common import (
assert_dict_of_states_equal_without_context_and_last_changed,
assert_multiple_states_equal_without_context,
assert_multiple_states_equal_without_context_and_last_changed,
assert_states_equal_without_context,
async_recorder_block_till_done,
async_wait_recording_done,
wait_recording_done,
@ -91,7 +95,7 @@ def test_get_significant_states(hass_history):
hass = hass_history
zero, four, states = record_states(hass)
hist = get_significant_states(hass, zero, four, filters=history.Filters())
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_minimal_response(hass_history):
@ -133,7 +137,31 @@ def test_get_significant_states_minimal_response(hass_history):
"last_changed": orig_last_changed,
"state": orig_state,
}
assert states == hist
assert len(hist) == len(states)
assert_states_equal_without_context(
states["media_player.test"][0], hist["media_player.test"][0]
)
assert states["media_player.test"][1] == hist["media_player.test"][1]
assert states["media_player.test"][2] == hist["media_player.test"][2]
assert_multiple_states_equal_without_context(
states["media_player.test2"], hist["media_player.test2"]
)
assert_states_equal_without_context(
states["media_player.test3"][0], hist["media_player.test3"][0]
)
assert states["media_player.test3"][1] == hist["media_player.test3"][1]
assert_multiple_states_equal_without_context(
states["script.can_cancel_this_one"], hist["script.can_cancel_this_one"]
)
assert_multiple_states_equal_without_context_and_last_changed(
states["thermostat.test"], hist["thermostat.test"]
)
assert_multiple_states_equal_without_context_and_last_changed(
states["thermostat.test2"], hist["thermostat.test2"]
)
def test_get_significant_states_with_initial(hass_history):
@ -153,6 +181,7 @@ def test_get_significant_states_with_initial(hass_history):
for state in states[entity_id]:
if state.last_changed == one:
state.last_changed = one_and_half
state.last_updated = one_and_half
hist = get_significant_states(
hass,
@ -161,7 +190,7 @@ def test_get_significant_states_with_initial(hass_history):
filters=history.Filters(),
include_start_time_state=True,
)
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_without_initial(hass_history):
@ -188,7 +217,7 @@ def test_get_significant_states_without_initial(hass_history):
filters=history.Filters(),
include_start_time_state=False,
)
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_entity_id(hass_history):
@ -204,7 +233,7 @@ def test_get_significant_states_entity_id(hass_history):
hist = get_significant_states(
hass, zero, four, ["media_player.test"], filters=history.Filters()
)
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_multiple_entity_ids(hass_history):
@ -223,7 +252,7 @@ def test_get_significant_states_multiple_entity_ids(hass_history):
["media_player.test", "thermostat.test"],
filters=history.Filters(),
)
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_exclude_domain(hass_history):
@ -528,14 +557,22 @@ def test_get_significant_states_only(hass_history):
hist = get_significant_states(hass, start, significant_changes_only=True)
assert len(hist[entity_id]) == 2
assert states[0] not in hist[entity_id]
assert states[1] in hist[entity_id]
assert states[2] in hist[entity_id]
assert not any(
state.last_updated == states[0].last_updated for state in hist[entity_id]
)
assert any(
state.last_updated == states[1].last_updated for state in hist[entity_id]
)
assert any(
state.last_updated == states[2].last_updated for state in hist[entity_id]
)
hist = get_significant_states(hass, start, significant_changes_only=False)
assert len(hist[entity_id]) == 3
assert states == hist[entity_id]
assert_multiple_states_equal_without_context_and_last_changed(
states, hist[entity_id]
)
def check_significant_states(hass, zero, four, states, config):
@ -551,7 +588,7 @@ def check_significant_states(hass, zero, four, states, config):
filters.included_domains = include.get(CONF_DOMAINS, [])
hist = get_significant_states(hass, zero, four, filters=filters)
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def record_states(hass):

View File

@ -1 +1,5 @@
"""Tests for Recorder component."""
import pytest
pytest.register_assert_rewrite("tests.components.recorder.common")

View File

@ -2,6 +2,7 @@
from __future__ import annotations
import asyncio
from collections.abc import Iterable
from dataclasses import dataclass
from datetime import datetime
import time
@ -16,7 +17,7 @@ from homeassistant.components.recorder import get_instance, statistics
from homeassistant.components.recorder.core import Recorder
from homeassistant.components.recorder.db_schema import RecorderRuns
from homeassistant.components.recorder.tasks import RecorderTask, StatisticsTask
from homeassistant.core import HomeAssistant
from homeassistant.core import Event, HomeAssistant, State
from homeassistant.util import dt as dt_util
from . import db_schema_0
@ -155,3 +156,68 @@ def statistics_during_period(
return statistics.statistics_during_period(
hass, start_time, end_time, statistic_ids, period, units, types
)
def assert_states_equal_without_context(state: State, other: State) -> None:
"""Assert that two states are equal, ignoring context."""
assert_states_equal_without_context_and_last_changed(state, other)
assert state.last_changed == other.last_changed
def assert_states_equal_without_context_and_last_changed(
state: State, other: State
) -> None:
"""Assert that two states are equal, ignoring context and last_changed."""
assert state.state == other.state
assert state.attributes == other.attributes
assert state.last_updated == other.last_updated
def assert_multiple_states_equal_without_context_and_last_changed(
states: Iterable[State], others: Iterable[State]
) -> None:
"""Assert that multiple states are equal, ignoring context and last_changed."""
states_list = list(states)
others_list = list(others)
assert len(states_list) == len(others_list)
for i, state in enumerate(states_list):
assert_states_equal_without_context_and_last_changed(state, others_list[i])
def assert_multiple_states_equal_without_context(
states: Iterable[State], others: Iterable[State]
) -> None:
"""Assert that multiple states are equal, ignoring context."""
states_list = list(states)
others_list = list(others)
assert len(states_list) == len(others_list)
for i, state in enumerate(states_list):
assert_states_equal_without_context(state, others_list[i])
def assert_events_equal_without_context(event: Event, other: Event) -> None:
"""Assert that two events are equal, ignoring context."""
assert event.data == other.data
assert event.event_type == other.event_type
assert event.origin == other.origin
assert event.time_fired == other.time_fired
def assert_dict_of_states_equal_without_context(
states: dict[str, list[State]], others: dict[str, list[State]]
) -> None:
"""Assert that two dicts of states are equal, ignoring context."""
assert len(states) == len(others)
for entity_id, state in states.items():
assert_multiple_states_equal_without_context(state, others[entity_id])
def assert_dict_of_states_equal_without_context_and_last_changed(
states: dict[str, list[State]], others: dict[str, list[State]]
) -> None:
"""Assert that two dicts of states are equal, ignoring context and last_changed."""
assert len(states) == len(others)
for entity_id, state in states.items():
assert_multiple_states_equal_without_context_and_last_changed(
state, others[entity_id]
)

View File

@ -30,6 +30,10 @@ from homeassistant.helpers.json import JSONEncoder
import homeassistant.util.dt as dt_util
from .common import (
assert_dict_of_states_equal_without_context_and_last_changed,
assert_multiple_states_equal_without_context,
assert_multiple_states_equal_without_context_and_last_changed,
assert_states_equal_without_context,
async_recorder_block_till_done,
async_wait_recording_done,
wait_recording_done,
@ -250,7 +254,7 @@ def test_state_changes_during_period(hass_recorder, attributes, no_attributes, l
hass, start, end, entity_id, no_attributes, limit=limit
)
assert states[:limit] == hist[entity_id]
assert_multiple_states_equal_without_context(states[:limit], hist[entity_id])
def test_state_changes_during_period_descending(hass_recorder):
@ -303,12 +307,14 @@ def test_state_changes_during_period_descending(hass_recorder):
hist = history.state_changes_during_period(
hass, start, end, entity_id, no_attributes=False, descending=False
)
assert states == hist[entity_id]
assert_multiple_states_equal_without_context(states, hist[entity_id])
hist = history.state_changes_during_period(
hass, start, end, entity_id, no_attributes=False, descending=True
)
assert states == list(reversed(list(hist[entity_id])))
assert_multiple_states_equal_without_context(
states, list(reversed(list(hist[entity_id])))
)
def test_get_last_state_changes(hass_recorder):
@ -344,7 +350,7 @@ def test_get_last_state_changes(hass_recorder):
hist = history.get_last_state_changes(hass, 2, entity_id)
assert states == hist[entity_id]
assert_multiple_states_equal_without_context(states, hist[entity_id])
def test_ensure_state_can_be_copied(hass_recorder):
@ -377,8 +383,8 @@ def test_ensure_state_can_be_copied(hass_recorder):
hist = history.get_last_state_changes(hass, 2, entity_id)
assert copy(hist[entity_id][0]) == hist[entity_id][0]
assert copy(hist[entity_id][1]) == hist[entity_id][1]
assert_states_equal_without_context(copy(hist[entity_id][0]), hist[entity_id][0])
assert_states_equal_without_context(copy(hist[entity_id][1]), hist[entity_id][1])
def test_get_significant_states(hass_recorder):
@ -391,7 +397,7 @@ def test_get_significant_states(hass_recorder):
hass = hass_recorder()
zero, four, states = record_states(hass)
hist = history.get_significant_states(hass, zero, four)
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_minimal_response(hass_recorder):
@ -431,7 +437,31 @@ def test_get_significant_states_minimal_response(hass_recorder):
"last_changed": orig_last_changed,
"state": orig_state,
}
assert states == hist
assert len(hist) == len(states)
assert_states_equal_without_context(
states["media_player.test"][0], hist["media_player.test"][0]
)
assert states["media_player.test"][1] == hist["media_player.test"][1]
assert states["media_player.test"][2] == hist["media_player.test"][2]
assert_multiple_states_equal_without_context(
states["media_player.test2"], hist["media_player.test2"]
)
assert_states_equal_without_context(
states["media_player.test3"][0], hist["media_player.test3"][0]
)
assert states["media_player.test3"][1] == hist["media_player.test3"][1]
assert_multiple_states_equal_without_context(
states["script.can_cancel_this_one"], hist["script.can_cancel_this_one"]
)
assert_multiple_states_equal_without_context_and_last_changed(
states["thermostat.test"], hist["thermostat.test"]
)
assert_multiple_states_equal_without_context_and_last_changed(
states["thermostat.test2"], hist["thermostat.test2"]
)
@pytest.mark.parametrize("time_zone", ["Europe/Berlin", "US/Hawaii", "UTC"])
@ -460,7 +490,7 @@ def test_get_significant_states_with_initial(time_zone, hass_recorder):
four,
include_start_time_state=True,
)
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_without_initial(hass_recorder):
@ -486,7 +516,7 @@ def test_get_significant_states_without_initial(hass_recorder):
four,
include_start_time_state=False,
)
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_entity_id(hass_recorder):
@ -500,17 +530,13 @@ def test_get_significant_states_entity_id(hass_recorder):
del states["script.can_cancel_this_one"]
hist = history.get_significant_states(hass, zero, four, ["media_player.test"])
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_multiple_entity_ids(hass_recorder):
"""Test that only significant states are returned for one entity."""
hass = hass_recorder()
zero, four, states = record_states(hass)
del states["media_player.test2"]
del states["media_player.test3"]
del states["thermostat.test2"]
del states["script.can_cancel_this_one"]
hist = history.get_significant_states(
hass,
@ -518,7 +544,13 @@ def test_get_significant_states_multiple_entity_ids(hass_recorder):
four,
["media_player.test", "thermostat.test"],
)
assert states == hist
assert_multiple_states_equal_without_context_and_last_changed(
states["media_player.test"], hist["media_player.test"]
)
assert_multiple_states_equal_without_context_and_last_changed(
states["thermostat.test"], hist["thermostat.test"]
)
def test_get_significant_states_are_ordered(hass_recorder):
@ -583,14 +615,22 @@ def test_get_significant_states_only(hass_recorder):
hist = history.get_significant_states(hass, start, significant_changes_only=True)
assert len(hist[entity_id]) == 2
assert states[0] not in hist[entity_id]
assert states[1] in hist[entity_id]
assert states[2] in hist[entity_id]
assert not any(
state.last_updated == states[0].last_updated for state in hist[entity_id]
)
assert any(
state.last_updated == states[1].last_updated for state in hist[entity_id]
)
assert any(
state.last_updated == states[2].last_updated for state in hist[entity_id]
)
hist = history.get_significant_states(hass, start, significant_changes_only=False)
assert len(hist[entity_id]) == 3
assert states == hist[entity_id]
assert_multiple_states_equal_without_context_and_last_changed(
states, hist[entity_id]
)
async def test_get_significant_states_only_minimal_response(recorder_mock, hass):
@ -885,8 +925,8 @@ async def test_get_full_significant_states_handles_empty_last_changed(
states = await recorder.get_instance(hass).async_add_executor_job(_get_entries)
sensor_one_states: list[State] = states["sensor.one"]
assert sensor_one_states[0] == state0
assert sensor_one_states[1] == state1
assert_states_equal_without_context(sensor_one_states[0], state0)
assert_states_equal_without_context(sensor_one_states[1], state1)
assert sensor_one_states[0].last_changed == sensor_one_states[1].last_changed
assert sensor_one_states[0].last_updated != sensor_one_states[1].last_updated
@ -908,8 +948,8 @@ async def test_get_full_significant_states_handles_empty_last_changed(
native_sensor_one_states = await recorder.get_instance(hass).async_add_executor_job(
_fetch_native_states
)
assert native_sensor_one_states[0] == state0
assert native_sensor_one_states[1] == state1
assert_states_equal_without_context(native_sensor_one_states[0], state0)
assert_states_equal_without_context(native_sensor_one_states[1], state1)
assert (
native_sensor_one_states[0].last_changed
== native_sensor_one_states[1].last_changed
@ -1004,7 +1044,7 @@ async def test_get_full_significant_states_past_year_2038(
states = await recorder.get_instance(hass).async_add_executor_job(_get_entries)
sensor_one_states: list[State] = states["sensor.one"]
assert sensor_one_states[0] == state0
assert sensor_one_states[1] == state1
assert_states_equal_without_context(sensor_one_states[0], state0)
assert_states_equal_without_context(sensor_one_states[1], state1)
assert sensor_one_states[0].last_changed == past_2038_time
assert sensor_one_states[0].last_updated == past_2038_time

View File

@ -21,7 +21,13 @@ from homeassistant.core import State
from homeassistant.helpers.json import JSONEncoder
import homeassistant.util.dt as dt_util
from .common import wait_recording_done
from .common import (
assert_dict_of_states_equal_without_context_and_last_changed,
assert_multiple_states_equal_without_context,
assert_multiple_states_equal_without_context_and_last_changed,
assert_states_equal_without_context,
wait_recording_done,
)
CREATE_ENGINE_TARGET = "homeassistant.components.recorder.core.create_engine"
SCHEMA_MODULE = "tests.components.recorder.db_schema_30"
@ -175,7 +181,7 @@ def test_state_changes_during_period(hass_recorder, attributes, no_attributes, l
hass, start, end, entity_id, no_attributes, limit=limit
)
assert states[:limit] == hist[entity_id]
assert_multiple_states_equal_without_context(states[:limit], hist[entity_id])
def test_state_changes_during_period_descending(hass_recorder):
@ -228,12 +234,14 @@ def test_state_changes_during_period_descending(hass_recorder):
hist = history.state_changes_during_period(
hass, start, end, entity_id, no_attributes=False, descending=False
)
assert states == hist[entity_id]
assert_multiple_states_equal_without_context(states, hist[entity_id])
hist = history.state_changes_during_period(
hass, start, end, entity_id, no_attributes=False, descending=True
)
assert states == list(reversed(list(hist[entity_id])))
assert_multiple_states_equal_without_context(
states, list(reversed(list(hist[entity_id])))
)
def test_get_last_state_changes(hass_recorder):
@ -269,7 +277,7 @@ def test_get_last_state_changes(hass_recorder):
hist = history.get_last_state_changes(hass, 2, entity_id)
assert states == hist[entity_id]
assert_multiple_states_equal_without_context(states, hist[entity_id])
def test_ensure_state_can_be_copied(hass_recorder):
@ -302,8 +310,8 @@ def test_ensure_state_can_be_copied(hass_recorder):
hist = history.get_last_state_changes(hass, 2, entity_id)
assert copy(hist[entity_id][0]) == hist[entity_id][0]
assert copy(hist[entity_id][1]) == hist[entity_id][1]
assert_states_equal_without_context(copy(hist[entity_id][0]), hist[entity_id][0])
assert_states_equal_without_context(copy(hist[entity_id][1]), hist[entity_id][1])
def test_get_significant_states(hass_recorder):
@ -316,7 +324,7 @@ def test_get_significant_states(hass_recorder):
hass = hass_recorder()
zero, four, states = record_states(hass)
hist = history.get_significant_states(hass, zero, four)
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_minimal_response(hass_recorder):
@ -355,7 +363,31 @@ def test_get_significant_states_minimal_response(hass_recorder):
"last_changed": orig_last_changed,
"state": orig_state,
}
assert states == hist
assert len(hist) == len(states)
assert_states_equal_without_context(
states["media_player.test"][0], hist["media_player.test"][0]
)
assert states["media_player.test"][1] == hist["media_player.test"][1]
assert states["media_player.test"][2] == hist["media_player.test"][2]
assert_multiple_states_equal_without_context(
states["media_player.test2"], hist["media_player.test2"]
)
assert_states_equal_without_context(
states["media_player.test3"][0], hist["media_player.test3"][0]
)
assert states["media_player.test3"][1] == hist["media_player.test3"][1]
assert_multiple_states_equal_without_context(
states["script.can_cancel_this_one"], hist["script.can_cancel_this_one"]
)
assert_multiple_states_equal_without_context_and_last_changed(
states["thermostat.test"], hist["thermostat.test"]
)
assert_multiple_states_equal_without_context_and_last_changed(
states["thermostat.test2"], hist["thermostat.test2"]
)
def test_get_significant_states_with_initial(hass_recorder):
@ -375,6 +407,7 @@ def test_get_significant_states_with_initial(hass_recorder):
for state in states[entity_id]:
if state.last_changed == one:
state.last_changed = one_and_half
state.last_updated = one_and_half
hist = history.get_significant_states(
hass,
@ -382,7 +415,7 @@ def test_get_significant_states_with_initial(hass_recorder):
four,
include_start_time_state=True,
)
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_without_initial(hass_recorder):
@ -408,7 +441,7 @@ def test_get_significant_states_without_initial(hass_recorder):
four,
include_start_time_state=False,
)
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_entity_id(hass_recorder):
@ -422,7 +455,7 @@ def test_get_significant_states_entity_id(hass_recorder):
del states["script.can_cancel_this_one"]
hist = history.get_significant_states(hass, zero, four, ["media_player.test"])
assert states == hist
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
def test_get_significant_states_multiple_entity_ids(hass_recorder):
@ -440,7 +473,12 @@ def test_get_significant_states_multiple_entity_ids(hass_recorder):
four,
["media_player.test", "thermostat.test"],
)
assert states == hist
assert_multiple_states_equal_without_context_and_last_changed(
states["media_player.test"], hist["media_player.test"]
)
assert_multiple_states_equal_without_context_and_last_changed(
states["thermostat.test"], hist["thermostat.test"]
)
def test_get_significant_states_are_ordered(hass_recorder):
@ -505,14 +543,22 @@ def test_get_significant_states_only(hass_recorder):
hist = history.get_significant_states(hass, start, significant_changes_only=True)
assert len(hist[entity_id]) == 2
assert states[0] not in hist[entity_id]
assert states[1] in hist[entity_id]
assert states[2] in hist[entity_id]
assert not any(
state.last_updated == states[0].last_updated for state in hist[entity_id]
)
assert any(
state.last_updated == states[1].last_updated for state in hist[entity_id]
)
assert any(
state.last_updated == states[2].last_updated for state in hist[entity_id]
)
hist = history.get_significant_states(hass, start, significant_changes_only=False)
assert len(hist[entity_id]) == 3
assert states == hist[entity_id]
assert_multiple_states_equal_without_context_and_last_changed(
states, hist[entity_id]
)
def record_states(hass) -> tuple[datetime, datetime, dict[str, list[State]]]:

View File

@ -221,7 +221,7 @@ async def test_saving_state(recorder_mock, hass: HomeAssistant):
assert len(db_states) == 1
assert db_states[0].event_id is None
assert state == _state_with_context(hass, entity_id)
assert state.as_dict() == _state_with_context(hass, entity_id).as_dict()
@pytest.mark.parametrize(
@ -257,7 +257,7 @@ async def test_saving_state_with_nul(
expected = _state_with_context(hass, entity_id)
expected.attributes = expected_attributes
assert state == expected
assert state.as_dict() == expected.as_dict()
async def test_saving_many_states(
@ -547,7 +547,7 @@ def test_saving_state_include_domains(hass_recorder):
hass = hass_recorder({"include": {"domains": "test2"}})
states = _add_entities(hass, ["test.recorder", "test2.recorder"])
assert len(states) == 1
assert _state_with_context(hass, "test2.recorder") == states[0]
assert _state_with_context(hass, "test2.recorder").as_dict() == states[0].as_dict()
def test_saving_state_include_domains_globs(hass_recorder):
@ -559,8 +559,11 @@ def test_saving_state_include_domains_globs(hass_recorder):
hass, ["test.recorder", "test2.recorder", "test3.included_entity"]
)
assert len(states) == 2
assert _state_with_context(hass, "test2.recorder") == states[0]
assert _state_with_context(hass, "test3.included_entity") == states[1]
assert _state_with_context(hass, "test2.recorder").as_dict() == states[0].as_dict()
assert (
_state_with_context(hass, "test3.included_entity").as_dict()
== states[1].as_dict()
)
def test_saving_state_incl_entities(hass_recorder):
@ -568,7 +571,7 @@ def test_saving_state_incl_entities(hass_recorder):
hass = hass_recorder({"include": {"entities": "test2.recorder"}})
states = _add_entities(hass, ["test.recorder", "test2.recorder"])
assert len(states) == 1
assert _state_with_context(hass, "test2.recorder") == states[0]
assert _state_with_context(hass, "test2.recorder").as_dict() == states[0].as_dict()
def test_saving_event_exclude_event_type(hass_recorder):
@ -597,7 +600,7 @@ def test_saving_state_exclude_domains(hass_recorder):
hass = hass_recorder({"exclude": {"domains": "test"}})
states = _add_entities(hass, ["test.recorder", "test2.recorder"])
assert len(states) == 1
assert _state_with_context(hass, "test2.recorder") == states[0]
assert _state_with_context(hass, "test2.recorder").as_dict() == states[0].as_dict()
def test_saving_state_exclude_domains_globs(hass_recorder):
@ -609,7 +612,7 @@ def test_saving_state_exclude_domains_globs(hass_recorder):
hass, ["test.recorder", "test2.recorder", "test2.excluded_entity"]
)
assert len(states) == 1
assert _state_with_context(hass, "test2.recorder") == states[0]
assert _state_with_context(hass, "test2.recorder").as_dict() == states[0].as_dict()
def test_saving_state_exclude_entities(hass_recorder):
@ -617,7 +620,7 @@ def test_saving_state_exclude_entities(hass_recorder):
hass = hass_recorder({"exclude": {"entities": "test.recorder"}})
states = _add_entities(hass, ["test.recorder", "test2.recorder"])
assert len(states) == 1
assert _state_with_context(hass, "test2.recorder") == states[0]
assert _state_with_context(hass, "test2.recorder").as_dict() == states[0].as_dict()
def test_saving_state_exclude_domain_include_entity(hass_recorder):
@ -650,7 +653,7 @@ def test_saving_state_include_domain_exclude_entity(hass_recorder):
)
states = _add_entities(hass, ["test.recorder", "test2.recorder", "test.ok"])
assert len(states) == 1
assert _state_with_context(hass, "test.ok") == states[0]
assert _state_with_context(hass, "test.ok").as_dict() == states[0].as_dict()
assert _state_with_context(hass, "test.ok").state == "state2"
@ -666,7 +669,7 @@ def test_saving_state_include_domain_glob_exclude_entity(hass_recorder):
hass, ["test.recorder", "test2.recorder", "test.ok", "test2.included_entity"]
)
assert len(states) == 1
assert _state_with_context(hass, "test.ok") == states[0]
assert _state_with_context(hass, "test.ok").as_dict() == states[0].as_dict()
assert _state_with_context(hass, "test.ok").state == "state2"
@ -1314,7 +1317,10 @@ def test_service_disable_states_not_recording(hass, hass_recorder):
db_states = list(session.query(States))
assert len(db_states) == 1
assert db_states[0].event_id is None
assert db_states[0].to_native() == _state_with_context(hass, "test.two")
assert (
db_states[0].to_native().as_dict()
== _state_with_context(hass, "test.two").as_dict()
)
def test_service_disable_run_information_recorded(tmpdir):

View File

@ -32,7 +32,7 @@ def test_from_event_to_db_event():
event = ha.Event("test_event", {"some_data": 15})
db_event = Events.from_event(event)
db_event.event_data = EventData.from_event(event).shared_data
assert event == db_event.to_native()
assert event.as_dict() == db_event.to_native().as_dict()
def test_from_event_to_db_state():
@ -43,7 +43,7 @@ def test_from_event_to_db_state():
{"entity_id": "sensor.temperature", "old_state": None, "new_state": state},
context=state.context,
)
assert state == States.from_event(event).to_native()
assert state.as_dict() == States.from_event(event).to_native().as_dict()
def test_from_event_to_db_state_attributes():
@ -293,11 +293,11 @@ async def test_event_to_db_model():
db_event = Events.from_event(event)
db_event.event_data = EventData.from_event(event).shared_data
native = db_event.to_native()
assert native == event
assert native.as_dict() == event.as_dict()
native = Events.from_event(event).to_native()
event.data = {}
assert native == event
assert native.as_dict() == event.as_dict()
async def test_lazy_state_handles_include_json(caplog):

View File

@ -37,6 +37,7 @@ from homeassistant.setup import setup_component
import homeassistant.util.dt as dt_util
from .common import (
assert_dict_of_states_equal_without_context_and_last_changed,
async_wait_recording_done,
do_adhoc_statistics,
statistics_during_period,
@ -55,7 +56,7 @@ def test_compile_hourly_statistics(hass_recorder):
setup_component(hass, "sensor", {})
zero, four, states = record_states(hass)
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
# Should not fail if there is nothing there yet
stats = get_latest_short_term_statistics(
@ -316,7 +317,7 @@ def test_rename_entity(hass_recorder):
zero, four, states = record_states(hass)
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
for kwargs in ({}, {"statistic_ids": ["sensor.test1"]}):
stats = statistics_during_period(hass, zero, period="5minute", **kwargs)
@ -382,7 +383,7 @@ def test_rename_entity_collision(hass_recorder, caplog):
zero, four, states = record_states(hass)
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
for kwargs in ({}, {"statistic_ids": ["sensor.test1"]}):
stats = statistics_during_period(hass, zero, period="5minute", **kwargs)
@ -447,7 +448,7 @@ def test_statistics_duplicated(hass_recorder, caplog):
setup_component(hass, "sensor", {})
zero, four, states = record_states(hass)
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
wait_recording_done(hass)
assert "Compiling statistics for" not in caplog.text

View File

@ -1 +1,4 @@
"""The tests for Sensor platforms."""
import pytest
pytest.register_assert_rewrite("tests.components.recorder.common")

View File

@ -34,6 +34,8 @@ from homeassistant.util.unit_system import METRIC_SYSTEM, US_CUSTOMARY_SYSTEM
from tests.common import async_fire_time_changed
from tests.components.recorder.common import (
assert_dict_of_states_equal_without_context_and_last_changed,
assert_multiple_states_equal_without_context_and_last_changed,
async_recorder_block_till_done,
async_wait_recording_done,
do_adhoc_statistics,
@ -139,7 +141,7 @@ def test_compile_hourly_statistics(
}
four, states = record_states(hass, zero, "sensor.test1", attributes)
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
do_adhoc_statistics(hass, start=zero)
wait_recording_done(hass)
@ -201,7 +203,7 @@ def test_compile_hourly_statistics_purged_state_changes(
}
four, states = record_states(hass, zero, "sensor.test1", attributes)
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
mean = min = max = float(hist["sensor.test1"][-1].state)
@ -282,7 +284,7 @@ def test_compile_hourly_statistics_wrong_unit(hass_recorder, caplog, attributes)
states = {**states, **_states}
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
do_adhoc_statistics(hass, start=zero)
wait_recording_done(hass)
@ -474,7 +476,9 @@ async def test_compile_hourly_sum_statistics_amount(
hist = history.get_significant_states(
hass, period0 - timedelta.resolution, eight + timedelta.resolution
)
assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"]
assert_multiple_states_equal_without_context_and_last_changed(
dict(states)["sensor.test1"], dict(hist)["sensor.test1"]
)
do_adhoc_statistics(hass, start=period0)
await async_wait_recording_done(hass)
@ -667,7 +671,9 @@ def test_compile_hourly_sum_statistics_amount_reset_every_state_change(
two + timedelta.resolution,
significant_changes_only=False,
)
assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"]
assert_multiple_states_equal_without_context_and_last_changed(
dict(states)["sensor.test1"], dict(hist)["sensor.test1"]
)
do_adhoc_statistics(hass, start=zero)
do_adhoc_statistics(hass, start=zero + timedelta(minutes=5))
@ -765,7 +771,9 @@ def test_compile_hourly_sum_statistics_amount_invalid_last_reset(
one + timedelta.resolution,
significant_changes_only=False,
)
assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"]
assert_multiple_states_equal_without_context_and_last_changed(
dict(states)["sensor.test1"], dict(hist)["sensor.test1"]
)
do_adhoc_statistics(hass, start=zero)
wait_recording_done(hass)
@ -849,7 +857,9 @@ def test_compile_hourly_sum_statistics_nan_inf_state(
one + timedelta.resolution,
significant_changes_only=False,
)
assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"]
assert_multiple_states_equal_without_context_and_last_changed(
dict(states)["sensor.test1"], dict(hist)["sensor.test1"]
)
do_adhoc_statistics(hass, start=zero)
wait_recording_done(hass)
@ -978,7 +988,9 @@ def test_compile_hourly_sum_statistics_negative_state(
one + timedelta.resolution,
significant_changes_only=False,
)
assert dict(states)[entity_id] == dict(hist)[entity_id]
assert_multiple_states_equal_without_context_and_last_changed(
dict(states)[entity_id], dict(hist)[entity_id]
)
do_adhoc_statistics(hass, start=zero)
wait_recording_done(hass)
@ -1060,7 +1072,9 @@ def test_compile_hourly_sum_statistics_total_no_reset(
hist = history.get_significant_states(
hass, period0 - timedelta.resolution, eight + timedelta.resolution
)
assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"]
assert_multiple_states_equal_without_context_and_last_changed(
dict(states)["sensor.test1"], dict(hist)["sensor.test1"]
)
do_adhoc_statistics(hass, start=period0)
wait_recording_done(hass)
@ -1160,7 +1174,9 @@ def test_compile_hourly_sum_statistics_total_increasing(
hist = history.get_significant_states(
hass, period0 - timedelta.resolution, eight + timedelta.resolution
)
assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"]
assert_multiple_states_equal_without_context_and_last_changed(
dict(states)["sensor.test1"], dict(hist)["sensor.test1"]
)
do_adhoc_statistics(hass, start=period0)
wait_recording_done(hass)
@ -1258,7 +1274,9 @@ def test_compile_hourly_sum_statistics_total_increasing_small_dip(
hist = history.get_significant_states(
hass, period0 - timedelta.resolution, eight + timedelta.resolution
)
assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"]
assert_multiple_states_equal_without_context_and_last_changed(
dict(states)["sensor.test1"], dict(hist)["sensor.test1"]
)
do_adhoc_statistics(hass, start=period0)
wait_recording_done(hass)
@ -1363,7 +1381,9 @@ def test_compile_hourly_energy_statistics_unsupported(hass_recorder, caplog):
hist = history.get_significant_states(
hass, period0 - timedelta.resolution, eight + timedelta.resolution
)
assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"]
assert_multiple_states_equal_without_context_and_last_changed(
dict(states)["sensor.test1"], dict(hist)["sensor.test1"]
)
do_adhoc_statistics(hass, start=period0)
wait_recording_done(hass)
@ -1453,7 +1473,9 @@ def test_compile_hourly_energy_statistics_multiple(hass_recorder, caplog):
hist = history.get_significant_states(
hass, period0 - timedelta.resolution, eight + timedelta.resolution
)
assert dict(states)["sensor.test1"] == dict(hist)["sensor.test1"]
assert_multiple_states_equal_without_context_and_last_changed(
dict(states)["sensor.test1"], dict(hist)["sensor.test1"]
)
do_adhoc_statistics(hass, start=period0)
wait_recording_done(hass)
@ -1635,7 +1657,7 @@ def test_compile_hourly_statistics_unchanged(
}
four, states = record_states(hass, zero, "sensor.test1", attributes)
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
do_adhoc_statistics(hass, start=four)
wait_recording_done(hass)
@ -1667,7 +1689,7 @@ def test_compile_hourly_statistics_partially_unavailable(hass_recorder, caplog):
hass, zero, "sensor.test1", TEMPERATURE_SENSOR_ATTRIBUTES
)
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
do_adhoc_statistics(hass, start=zero)
wait_recording_done(hass)
@ -1736,7 +1758,7 @@ def test_compile_hourly_statistics_unavailable(
_, _states = record_states(hass, zero, "sensor.test2", attributes)
states = {**states, **_states}
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
do_adhoc_statistics(hass, start=four)
wait_recording_done(hass)
@ -1944,7 +1966,7 @@ def test_compile_hourly_statistics_changing_units_1(
)
states["sensor.test1"] += _states["sensor.test1"]
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
do_adhoc_statistics(hass, start=zero)
wait_recording_done(hass)
@ -2054,7 +2076,7 @@ def test_compile_hourly_statistics_changing_units_2(
)
states["sensor.test1"] += _states["sensor.test1"]
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
do_adhoc_statistics(hass, start=zero + timedelta(seconds=30 * 5))
wait_recording_done(hass)
@ -2122,7 +2144,7 @@ def test_compile_hourly_statistics_changing_units_3(
)
states["sensor.test1"] += _states["sensor.test1"]
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
do_adhoc_statistics(hass, start=zero)
wait_recording_done(hass)
@ -2270,7 +2292,7 @@ def test_compile_hourly_statistics_convert_units_1(
)
states["sensor.test1"] += _states["sensor.test1"]
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
do_adhoc_statistics(hass, start=zero + timedelta(minutes=10))
wait_recording_done(hass)
assert "The unit of sensor.test1 is changing" not in caplog.text
@ -2362,7 +2384,7 @@ def test_compile_hourly_statistics_equivalent_units_1(
)
states["sensor.test1"] += _states["sensor.test1"]
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
do_adhoc_statistics(hass, start=zero)
wait_recording_done(hass)
@ -2476,7 +2498,7 @@ def test_compile_hourly_statistics_equivalent_units_2(
)
states["sensor.test1"] += _states["sensor.test1"]
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
do_adhoc_statistics(hass, start=zero + timedelta(seconds=30 * 5))
wait_recording_done(hass)
@ -2591,7 +2613,7 @@ def test_compile_hourly_statistics_changing_device_class_1(
)
states["sensor.test1"] += _states["sensor.test1"]
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
# Run statistics again, additional statistics is generated
do_adhoc_statistics(hass, start=zero + timedelta(minutes=10))
@ -2646,7 +2668,7 @@ def test_compile_hourly_statistics_changing_device_class_1(
)
states["sensor.test1"] += _states["sensor.test1"]
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
# Run statistics again, additional statistics is generated
do_adhoc_statistics(hass, start=zero + timedelta(minutes=20))
@ -2781,7 +2803,7 @@ def test_compile_hourly_statistics_changing_device_class_2(
)
states["sensor.test1"] += _states["sensor.test1"]
hist = history.get_significant_states(hass, zero, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
# Run statistics again, additional statistics is generated
do_adhoc_statistics(hass, start=zero + timedelta(minutes=10))
@ -2897,7 +2919,7 @@ def test_compile_hourly_statistics_changing_state_class(
four, _states = record_states(hass, period1, "sensor.test1", attributes_2)
states["sensor.test1"] += _states["sensor.test1"]
hist = history.get_significant_states(hass, period0, four)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
do_adhoc_statistics(hass, start=period1)
wait_recording_done(hass)
@ -3083,7 +3105,7 @@ def test_compile_statistics_hourly_daily_monthly_summary(hass_recorder, caplog):
hist = history.get_significant_states(
hass, zero - timedelta.resolution, four, significant_changes_only=False
)
assert dict(states) == dict(hist)
assert_dict_of_states_equal_without_context_and_last_changed(states, hist)
wait_recording_done(hass)
# Generate 5-minute statistics for two hours

View File

@ -331,7 +331,7 @@ def test_event_eq():
ha.Event("some_type", data, time_fired=now, context=context) for _ in range(2)
)
assert event1 == event2
assert event1.as_dict() == event2.as_dict()
def test_event_repr():
@ -685,7 +685,7 @@ def test_state_name_if_friendly_name_attr():
def test_state_dict_conversion():
"""Test conversion of dict."""
state = ha.State("domain.hello", "world", {"some": "attr"})
assert state == ha.State.from_dict(state.as_dict())
assert state.as_dict() == ha.State.from_dict(state.as_dict()).as_dict()
def test_state_dict_conversion_with_wrong_data():