mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 04:37:06 +00:00
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:
parent
80ffac48a3
commit
c612a92cfb
@ -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]]
|
||||
|
@ -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 ""
|
||||
|
@ -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):
|
||||
|
@ -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"
|
||||
|
@ -1 +1,5 @@
|
||||
"""Tests for the history component."""
|
||||
|
||||
import pytest
|
||||
|
||||
pytest.register_assert_rewrite("tests.components.recorder.common")
|
||||
|
@ -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):
|
||||
|
@ -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):
|
||||
|
@ -1 +1,5 @@
|
||||
"""Tests for Recorder component."""
|
||||
|
||||
import pytest
|
||||
|
||||
pytest.register_assert_rewrite("tests.components.recorder.common")
|
||||
|
@ -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]
|
||||
)
|
||||
|
@ -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
|
||||
|
@ -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]]]:
|
||||
|
@ -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):
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -1 +1,4 @@
|
||||
"""The tests for Sensor platforms."""
|
||||
import pytest
|
||||
|
||||
pytest.register_assert_rewrite("tests.components.recorder.common")
|
||||
|
@ -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
|
||||
|
@ -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():
|
||||
|
Loading…
x
Reference in New Issue
Block a user