From f177336025bf47334696186497563359984bcd59 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 9 Dec 2024 23:08:01 +0100 Subject: [PATCH] Add missing `last_reported_timestamp` to `LazyState` (#132761) followup to #132752 --- .../components/recorder/models/state.py | 8 ++++ tests/components/recorder/test_models.py | 37 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/homeassistant/components/recorder/models/state.py b/homeassistant/components/recorder/models/state.py index f5e49881b8f..fbf73e75025 100644 --- a/homeassistant/components/recorder/models/state.py +++ b/homeassistant/components/recorder/models/state.py @@ -111,6 +111,14 @@ class LazyState(State): assert ts is not None return ts + @cached_property + def last_reported_timestamp(self) -> float: # type: ignore[override] + """Last reported timestamp.""" + ts = self._last_reported_ts or self._last_updated_ts + if TYPE_CHECKING: + assert ts is not None + return ts + def as_dict(self) -> dict[str, Any]: # type: ignore[override] """Return a dict representation of the LazyState. diff --git a/tests/components/recorder/test_models.py b/tests/components/recorder/test_models.py index a0703f1f2c5..b2894883ff2 100644 --- a/tests/components/recorder/test_models.py +++ b/tests/components/recorder/test_models.py @@ -325,6 +325,7 @@ async def test_lazy_state_handles_different_last_updated_and_last_changed( state="off", attributes='{"shared":true}', last_updated_ts=now.timestamp(), + last_reported_ts=now.timestamp(), last_changed_ts=(now - timedelta(seconds=60)).timestamp(), ) lstate = LazyState( @@ -339,6 +340,7 @@ async def test_lazy_state_handles_different_last_updated_and_last_changed( } assert lstate.last_updated.timestamp() == row.last_updated_ts assert lstate.last_changed.timestamp() == row.last_changed_ts + assert lstate.last_reported.timestamp() == row.last_updated_ts assert lstate.as_dict() == { "attributes": {"shared": True}, "entity_id": "sensor.valid", @@ -348,6 +350,7 @@ async def test_lazy_state_handles_different_last_updated_and_last_changed( } assert lstate.last_changed_timestamp == row.last_changed_ts assert lstate.last_updated_timestamp == row.last_updated_ts + assert lstate.last_reported_timestamp == row.last_updated_ts async def test_lazy_state_handles_same_last_updated_and_last_changed( @@ -361,6 +364,7 @@ async def test_lazy_state_handles_same_last_updated_and_last_changed( attributes='{"shared":true}', last_updated_ts=now.timestamp(), last_changed_ts=now.timestamp(), + last_reported_ts=None, ) lstate = LazyState( row, {}, None, row.entity_id, row.state, row.last_updated_ts, False @@ -374,6 +378,7 @@ async def test_lazy_state_handles_same_last_updated_and_last_changed( } assert lstate.last_updated.timestamp() == row.last_updated_ts assert lstate.last_changed.timestamp() == row.last_changed_ts + assert lstate.last_reported.timestamp() == row.last_updated_ts assert lstate.as_dict() == { "attributes": {"shared": True}, "entity_id": "sensor.valid", @@ -383,3 +388,35 @@ async def test_lazy_state_handles_same_last_updated_and_last_changed( } assert lstate.last_changed_timestamp == row.last_changed_ts assert lstate.last_updated_timestamp == row.last_updated_ts + assert lstate.last_reported_timestamp == row.last_updated_ts + + +async def test_lazy_state_handles_different_last_reported( + caplog: pytest.LogCaptureFixture, +) -> None: + """Test that the LazyState handles last_reported different from last_updated.""" + now = datetime(2021, 6, 12, 3, 4, 1, 323, tzinfo=dt_util.UTC) + row = PropertyMock( + entity_id="sensor.valid", + state="off", + attributes='{"shared":true}', + last_updated_ts=(now - timedelta(seconds=60)).timestamp(), + last_reported_ts=now.timestamp(), + last_changed_ts=(now - timedelta(seconds=60)).timestamp(), + ) + lstate = LazyState( + row, {}, None, row.entity_id, row.state, row.last_updated_ts, False + ) + assert lstate.as_dict() == { + "attributes": {"shared": True}, + "entity_id": "sensor.valid", + "last_changed": "2021-06-12T03:03:01.000323+00:00", + "last_updated": "2021-06-12T03:03:01.000323+00:00", + "state": "off", + } + assert lstate.last_updated.timestamp() == row.last_updated_ts + assert lstate.last_changed.timestamp() == row.last_changed_ts + assert lstate.last_reported.timestamp() == row.last_reported_ts + assert lstate.last_changed_timestamp == row.last_changed_ts + assert lstate.last_updated_timestamp == row.last_updated_ts + assert lstate.last_reported_timestamp == row.last_reported_ts