Fix last_reported_timestamp not being updated when last_reported is changed (#118341)
* Reduce number of calls to last_reported_timestamp When a state is created, last_update is always the same as last_reported, and we only update it later if it changes so we can pre-set the cached property to avoid it being run when the recorder accesses it later. * fix cache not being overridden * coverage
This commit is contained in:
parent
f3fa843b9d
commit
76aa504e36
2 changed files with 26 additions and 5 deletions
|
@ -1803,9 +1803,16 @@ class State:
|
|||
# The recorder or the websocket_api will always call the timestamps,
|
||||
# so we will set the timestamp values here to avoid the overhead of
|
||||
# the function call in the property we know will always be called.
|
||||
self.last_updated_timestamp = self.last_updated.timestamp()
|
||||
if self.last_changed == self.last_updated:
|
||||
self.__dict__["last_changed_timestamp"] = self.last_updated_timestamp
|
||||
last_updated = self.last_updated
|
||||
last_updated_timestamp = last_updated.timestamp()
|
||||
self.last_updated_timestamp = last_updated_timestamp
|
||||
if self.last_changed == last_updated:
|
||||
self.__dict__["last_changed_timestamp"] = last_updated_timestamp
|
||||
# If last_reported is the same as last_updated async_set will pass
|
||||
# the same datetime object for both values so we can use an identity
|
||||
# check here.
|
||||
if self.last_reported is last_updated:
|
||||
self.__dict__["last_reported_timestamp"] = last_updated_timestamp
|
||||
|
||||
@cached_property
|
||||
def name(self) -> str:
|
||||
|
@ -1822,8 +1829,6 @@ class State:
|
|||
@cached_property
|
||||
def last_reported_timestamp(self) -> float:
|
||||
"""Timestamp of last report."""
|
||||
if self.last_reported == self.last_updated:
|
||||
return self.last_updated_timestamp
|
||||
return self.last_reported.timestamp()
|
||||
|
||||
@cached_property
|
||||
|
@ -2282,6 +2287,7 @@ class StateMachine:
|
|||
# mypy does not understand this is only possible if old_state is not None
|
||||
old_last_reported = old_state.last_reported # type: ignore[union-attr]
|
||||
old_state.last_reported = now # type: ignore[union-attr]
|
||||
old_state.last_reported_timestamp = timestamp # type: ignore[union-attr]
|
||||
self._bus.async_fire_internal(
|
||||
EVENT_STATE_REPORTED,
|
||||
{
|
||||
|
|
|
@ -3524,3 +3524,18 @@ async def test_set_time_zone_deprecated(hass: HomeAssistant) -> None:
|
|||
),
|
||||
):
|
||||
await hass.config.set_time_zone("America/New_York")
|
||||
|
||||
|
||||
async def test_async_set_updates_last_reported(hass: HomeAssistant) -> None:
|
||||
"""Test async_set method updates last_reported AND last_reported_timestamp."""
|
||||
hass.states.async_set("light.bowl", "on", {})
|
||||
state = hass.states.get("light.bowl")
|
||||
last_reported = state.last_reported
|
||||
last_reported_timestamp = state.last_reported_timestamp
|
||||
|
||||
for _ in range(2):
|
||||
hass.states.async_set("light.bowl", "on", {})
|
||||
assert state.last_reported != last_reported
|
||||
assert state.last_reported_timestamp != last_reported_timestamp
|
||||
last_reported = state.last_reported
|
||||
last_reported_timestamp = state.last_reported_timestamp
|
||||
|
|
Loading…
Add table
Reference in a new issue