move away the legacy code

This commit is contained in:
J. Nick Koston
2023-04-10 12:53:52 -10:00
parent bc724a45cc
commit 8ef60088f9
3 changed files with 137 additions and 11 deletions

View File

@@ -24,13 +24,16 @@ from ... import recorder
from ..db_schema import RecorderRuns, StateAttributes, States from ..db_schema import RecorderRuns, StateAttributes, States
from ..filters import Filters from ..filters import Filters
from ..models import ( from ..models import (
LazyState,
process_datetime_to_timestamp, process_datetime_to_timestamp,
process_timestamp, process_timestamp,
process_timestamp_to_utc_isoformat, process_timestamp_to_utc_isoformat,
row_to_compressed_state,
) )
from ..models.legacy import LazyStatePreSchema31, row_to_compressed_state_pre_schema_31 from ..models.legacy import (
LegacyLazyState,
LegacyLazyStatePreSchema31,
legacy_row_to_compressed_state,
legacy_row_to_compressed_state_pre_schema_31,
)
from ..util import execute_stmt_lambda_element, session_scope from ..util import execute_stmt_lambda_element, session_scope
from .common import _schema_version from .common import _schema_version
from .const import ( from .const import (
@@ -713,17 +716,17 @@ def _sorted_states_to_dict(
] ]
if compressed_state_format: if compressed_state_format:
if schema_version >= 31: if schema_version >= 31:
state_class = row_to_compressed_state state_class = legacy_row_to_compressed_state
else: else:
state_class = row_to_compressed_state_pre_schema_31 state_class = legacy_row_to_compressed_state_pre_schema_31
_process_timestamp = process_datetime_to_timestamp _process_timestamp = process_datetime_to_timestamp
attr_time = COMPRESSED_STATE_LAST_UPDATED attr_time = COMPRESSED_STATE_LAST_UPDATED
attr_state = COMPRESSED_STATE_STATE attr_state = COMPRESSED_STATE_STATE
else: else:
if schema_version >= 31: if schema_version >= 31:
state_class = LazyState state_class = LegacyLazyState
else: else:
state_class = LazyStatePreSchema31 state_class = LegacyLazyStatePreSchema31
_process_timestamp = process_timestamp_to_utc_isoformat _process_timestamp = process_timestamp_to_utc_isoformat
attr_time = LAST_CHANGED_KEY attr_time = LAST_CHANGED_KEY
attr_state = STATE_KEY attr_state = STATE_KEY

View File

@@ -13,6 +13,7 @@ from homeassistant.const import (
COMPRESSED_STATE_STATE, COMPRESSED_STATE_STATE,
) )
from homeassistant.core import Context, State from homeassistant.core import Context, State
import homeassistant.util.dt as dt_util
from .state_attributes import decode_attributes_from_row from .state_attributes import decode_attributes_from_row
from .time import ( from .time import (
@@ -24,7 +25,7 @@ from .time import (
# pylint: disable=invalid-name # pylint: disable=invalid-name
class LazyStatePreSchema31(State): class LegacyLazyStatePreSchema31(State):
"""A lazy version of core State before schema 31.""" """A lazy version of core State before schema 31."""
__slots__ = [ __slots__ = [
@@ -138,7 +139,7 @@ class LazyStatePreSchema31(State):
} }
def row_to_compressed_state_pre_schema_31( def legacy_row_to_compressed_state_pre_schema_31(
row: Row, row: Row,
attr_cache: dict[str, dict[str, Any]], attr_cache: dict[str, dict[str, Any]],
start_time: datetime | None, start_time: datetime | None,
@@ -162,3 +163,125 @@ def row_to_compressed_state_pre_schema_31(
row_changed_changed row_changed_changed
) )
return comp_state return comp_state
class LegacyLazyState(State):
"""A lazy version of core State after schema 31."""
__slots__ = [
"_row",
"_attributes",
"_last_changed_ts",
"_last_updated_ts",
"_context",
"attr_cache",
]
def __init__( # pylint: disable=super-init-not-called
self,
row: Row,
attr_cache: dict[str, dict[str, Any]],
start_time: datetime | None,
entity_id: str | None = None,
) -> None:
"""Init the lazy state."""
self._row = row
self.entity_id = entity_id or self._row.entity_id
self.state = self._row.state or ""
self._attributes: dict[str, Any] | None = None
self._last_updated_ts: float | None = self._row.last_updated_ts or (
dt_util.utc_to_timestamp(start_time) if start_time else None
)
self._last_changed_ts: float | None = (
self._row.last_changed_ts or self._last_updated_ts
)
self._context: Context | None = None
self.attr_cache = attr_cache
@property # type: ignore[override]
def attributes(self) -> dict[str, Any]:
"""State attributes."""
if self._attributes is None:
self._attributes = decode_attributes_from_row(self._row, self.attr_cache)
return self._attributes
@attributes.setter
def attributes(self, value: dict[str, Any]) -> None:
"""Set attributes."""
self._attributes = value
@property
def context(self) -> Context:
"""State context."""
if self._context is None:
self._context = Context(id=None)
return self._context
@context.setter
def context(self, value: Context) -> None:
"""Set context."""
self._context = value
@property
def last_changed(self) -> datetime:
"""Last changed datetime."""
assert self._last_changed_ts is not None
return dt_util.utc_from_timestamp(self._last_changed_ts)
@last_changed.setter
def last_changed(self, value: datetime) -> None:
"""Set last changed datetime."""
self._last_changed_ts = process_timestamp(value).timestamp()
@property
def last_updated(self) -> datetime:
"""Last updated datetime."""
assert self._last_updated_ts is not None
return dt_util.utc_from_timestamp(self._last_updated_ts)
@last_updated.setter
def last_updated(self, value: datetime) -> None:
"""Set last updated datetime."""
self._last_updated_ts = process_timestamp(value).timestamp()
def as_dict(self) -> dict[str, Any]: # type: ignore[override]
"""Return a dict representation of the LazyState.
Async friendly.
To be used for JSON serialization.
"""
last_updated_isoformat = self.last_updated.isoformat()
if self._last_changed_ts == self._last_updated_ts:
last_changed_isoformat = last_updated_isoformat
else:
last_changed_isoformat = self.last_changed.isoformat()
return {
"entity_id": self.entity_id,
"state": self.state,
"attributes": self._attributes or self.attributes,
"last_changed": last_changed_isoformat,
"last_updated": last_updated_isoformat,
}
def legacy_row_to_compressed_state(
row: Row,
attr_cache: dict[str, dict[str, Any]],
start_time: datetime | None,
entity_id: str | None = None,
) -> dict[str, Any]:
"""Convert a database row to a compressed state schema 31 and later."""
comp_state = {
COMPRESSED_STATE_STATE: row.state,
COMPRESSED_STATE_ATTRIBUTES: decode_attributes_from_row(row, attr_cache),
}
if start_time:
comp_state[COMPRESSED_STATE_LAST_UPDATED] = dt_util.utc_to_timestamp(start_time)
else:
row_last_updated_ts: float = row.last_updated_ts
comp_state[COMPRESSED_STATE_LAST_UPDATED] = row_last_updated_ts
if (
row_changed_changed_ts := row.last_changed_ts
) and row_last_updated_ts != row_changed_changed_ts:
comp_state[COMPRESSED_STATE_LAST_CHANGED] = row_changed_changed_ts
return comp_state

View File

@@ -24,7 +24,7 @@ from homeassistant.components.recorder.db_schema import (
from homeassistant.components.recorder.filters import Filters from homeassistant.components.recorder.filters import Filters
from homeassistant.components.recorder.history import legacy from homeassistant.components.recorder.history import legacy
from homeassistant.components.recorder.models import LazyState, process_timestamp from homeassistant.components.recorder.models import LazyState, process_timestamp
from homeassistant.components.recorder.models.legacy import LazyStatePreSchema31 from homeassistant.components.recorder.models.legacy import LegacyLazyStatePreSchema31
from homeassistant.components.recorder.util import session_scope from homeassistant.components.recorder.util import session_scope
import homeassistant.core as ha import homeassistant.core as ha
from homeassistant.core import HomeAssistant, State from homeassistant.core import HomeAssistant, State
@@ -56,7 +56,7 @@ async def _async_get_states(
def _get_states_with_session(): def _get_states_with_session():
if get_instance(hass).schema_version < 31: if get_instance(hass).schema_version < 31:
klass = LazyStatePreSchema31 klass = LegacyLazyStatePreSchema31
else: else:
klass = LazyState klass = LazyState
with session_scope(hass=hass, read_only=True) as session: with session_scope(hass=hass, read_only=True) as session: