Small speed up to writing entity state (#121043)

pull/114854/head
J. Nick Koston 2024-07-03 10:16:41 -07:00 committed by GitHub
parent 44c89e6c3b
commit 48172b0426
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 42 additions and 15 deletions

View File

@ -2243,16 +2243,45 @@ class StateMachine:
This method must be run in the event loop.
"""
new_state = str(new_state)
attributes = attributes or {}
old_state = self._states_data.get(entity_id)
if old_state is None:
# If the state is missing, try to convert the entity_id to lowercase
# and try again.
entity_id = entity_id.lower()
old_state = self._states_data.get(entity_id)
self.async_set_internal(
entity_id.lower(),
str(new_state),
attributes or {},
force_update,
context,
state_info,
timestamp or time.time(),
)
if old_state is None:
@callback
def async_set_internal(
self,
entity_id: str,
new_state: str,
attributes: Mapping[str, Any] | None,
force_update: bool,
context: Context | None,
state_info: StateInfo | None,
timestamp: float,
) -> None:
"""Set the state of an entity, add entity if it does not exist.
This method is intended to only be used by core internally
and should not be considered a stable API. We will make
breaking changes to this function in the future and it
should not be used in integrations.
This method must be run in the event loop.
"""
# Most cases the key will be in the dict
# so we optimize for the happy path as
# python 3.11+ has near zero overhead for
# try when it does not raise an exception.
old_state: State | None
try:
old_state = self._states_data[entity_id]
except KeyError:
old_state = None
same_state = False
same_attr = False
last_changed = None
@ -2272,10 +2301,11 @@ class StateMachine:
# timestamp implementation:
# https://github.com/python/cpython/blob/c90a862cdcf55dc1753c6466e5fa4a467a13ae24/Modules/_datetimemodule.c#L6387
# https://github.com/python/cpython/blob/c90a862cdcf55dc1753c6466e5fa4a467a13ae24/Modules/_datetimemodule.c#L6323
if timestamp is None:
timestamp = time.time()
now = dt_util.utc_from_timestamp(timestamp)
if context is None:
context = Context(id=ulid_at_time(timestamp))
if same_state and same_attr:
# 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]
@ -2294,9 +2324,6 @@ class StateMachine:
)
return
if context is None:
context = Context(id=ulid_at_time(timestamp))
if same_attr:
if TYPE_CHECKING:
assert old_state is not None

View File

@ -1202,7 +1202,7 @@ class Entity(
self._context_set = None
try:
hass.states.async_set(
hass.states.async_set_internal(
entity_id,
state,
attr,