mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 18:57:06 +00:00
Convert States to dicts via as_dict only once (#41208)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
This commit is contained in:
parent
2f54bf29ba
commit
4798f37c6e
@ -65,7 +65,7 @@ class Events(Base): # type: ignore
|
|||||||
return Events(
|
return Events(
|
||||||
event_type=event.event_type,
|
event_type=event.event_type,
|
||||||
event_data=event_data or json.dumps(event.data, cls=JSONEncoder),
|
event_data=event_data or json.dumps(event.data, cls=JSONEncoder),
|
||||||
origin=str(event.origin),
|
origin=str(event.origin.value),
|
||||||
time_fired=event.time_fired,
|
time_fired=event.time_fired,
|
||||||
context_id=event.context.id,
|
context_id=event.context.id,
|
||||||
context_user_id=event.context.user_id,
|
context_user_id=event.context.user_id,
|
||||||
|
@ -21,6 +21,7 @@ from typing import (
|
|||||||
Any,
|
Any,
|
||||||
Awaitable,
|
Awaitable,
|
||||||
Callable,
|
Callable,
|
||||||
|
Collection,
|
||||||
Coroutine,
|
Coroutine,
|
||||||
Dict,
|
Dict,
|
||||||
Iterable,
|
Iterable,
|
||||||
@ -561,8 +562,8 @@ class Event:
|
|||||||
return {
|
return {
|
||||||
"event_type": self.event_type,
|
"event_type": self.event_type,
|
||||||
"data": dict(self.data),
|
"data": dict(self.data),
|
||||||
"origin": str(self.origin),
|
"origin": str(self.origin.value),
|
||||||
"time_fired": self.time_fired,
|
"time_fired": self.time_fired.isoformat(),
|
||||||
"context": self.context.as_dict(),
|
"context": self.context.as_dict(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,6 +627,7 @@ class EventBus:
|
|||||||
event_data: Optional[Dict] = None,
|
event_data: Optional[Dict] = None,
|
||||||
origin: EventOrigin = EventOrigin.local,
|
origin: EventOrigin = EventOrigin.local,
|
||||||
context: Optional[Context] = None,
|
context: Optional[Context] = None,
|
||||||
|
time_fired: Optional[datetime.datetime] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Fire an event.
|
"""Fire an event.
|
||||||
|
|
||||||
@ -638,7 +640,7 @@ class EventBus:
|
|||||||
if match_all_listeners is not None and event_type != EVENT_HOMEASSISTANT_CLOSE:
|
if match_all_listeners is not None and event_type != EVENT_HOMEASSISTANT_CLOSE:
|
||||||
listeners = match_all_listeners + listeners
|
listeners = match_all_listeners + listeners
|
||||||
|
|
||||||
event = Event(event_type, event_data, origin, None, context)
|
event = Event(event_type, event_data, origin, time_fired, context)
|
||||||
|
|
||||||
if event_type != EVENT_TIME_CHANGED:
|
if event_type != EVENT_TIME_CHANGED:
|
||||||
_LOGGER.debug("Bus:Handling %s", event)
|
_LOGGER.debug("Bus:Handling %s", event)
|
||||||
@ -771,6 +773,7 @@ class State:
|
|||||||
"context",
|
"context",
|
||||||
"domain",
|
"domain",
|
||||||
"object_id",
|
"object_id",
|
||||||
|
"_as_dict",
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@ -805,6 +808,7 @@ class State:
|
|||||||
self.last_changed = last_changed or self.last_updated
|
self.last_changed = last_changed or self.last_updated
|
||||||
self.context = context or Context()
|
self.context = context or Context()
|
||||||
self.domain, self.object_id = split_entity_id(self.entity_id)
|
self.domain, self.object_id = split_entity_id(self.entity_id)
|
||||||
|
self._as_dict: Optional[Dict[str, Collection[Any]]] = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
@ -821,14 +825,21 @@ class State:
|
|||||||
To be used for JSON serialization.
|
To be used for JSON serialization.
|
||||||
Ensures: state == State.from_dict(state.as_dict())
|
Ensures: state == State.from_dict(state.as_dict())
|
||||||
"""
|
"""
|
||||||
return {
|
if not self._as_dict:
|
||||||
|
last_changed_isoformat = self.last_changed.isoformat()
|
||||||
|
if self.last_changed == self.last_updated:
|
||||||
|
last_updated_isoformat = last_changed_isoformat
|
||||||
|
else:
|
||||||
|
last_updated_isoformat = self.last_updated.isoformat()
|
||||||
|
self._as_dict = {
|
||||||
"entity_id": self.entity_id,
|
"entity_id": self.entity_id,
|
||||||
"state": self.state,
|
"state": self.state,
|
||||||
"attributes": dict(self.attributes),
|
"attributes": dict(self.attributes),
|
||||||
"last_changed": self.last_changed,
|
"last_changed": last_changed_isoformat,
|
||||||
"last_updated": self.last_updated,
|
"last_updated": last_updated_isoformat,
|
||||||
"context": self.context.as_dict(),
|
"context": self.context.as_dict(),
|
||||||
}
|
}
|
||||||
|
return self._as_dict
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, json_dict: Dict) -> Any:
|
def from_dict(cls, json_dict: Dict) -> Any:
|
||||||
@ -1643,13 +1654,18 @@ def _async_create_timer(hass: HomeAssistant) -> None:
|
|||||||
"""Fire next time event."""
|
"""Fire next time event."""
|
||||||
now = dt_util.utcnow()
|
now = dt_util.utcnow()
|
||||||
|
|
||||||
hass.bus.async_fire(EVENT_TIME_CHANGED, {ATTR_NOW: now}, context=timer_context)
|
hass.bus.async_fire(
|
||||||
|
EVENT_TIME_CHANGED, {ATTR_NOW: now}, time_fired=now, context=timer_context
|
||||||
|
)
|
||||||
|
|
||||||
# If we are more than a second late, a tick was missed
|
# If we are more than a second late, a tick was missed
|
||||||
late = monotonic() - target
|
late = monotonic() - target
|
||||||
if late > 1:
|
if late > 1:
|
||||||
hass.bus.async_fire(
|
hass.bus.async_fire(
|
||||||
EVENT_TIMER_OUT_OF_SYNC, {ATTR_SECONDS: late}, context=timer_context
|
EVENT_TIMER_OUT_OF_SYNC,
|
||||||
|
{ATTR_SECONDS: late},
|
||||||
|
time_fired=now,
|
||||||
|
context=timer_context,
|
||||||
)
|
)
|
||||||
|
|
||||||
schedule_tick(now)
|
schedule_tick(now)
|
||||||
|
@ -201,10 +201,7 @@ async def test_get_states(hass, websocket_client):
|
|||||||
|
|
||||||
states = []
|
states = []
|
||||||
for state in hass.states.async_all():
|
for state in hass.states.async_all():
|
||||||
state = state.as_dict()
|
states.append(state.as_dict())
|
||||||
state["last_changed"] = state["last_changed"].isoformat()
|
|
||||||
state["last_updated"] = state["last_updated"].isoformat()
|
|
||||||
states.append(state)
|
|
||||||
|
|
||||||
assert msg["result"] == states
|
assert msg["result"] == states
|
||||||
|
|
||||||
|
@ -291,7 +291,7 @@ def test_event_repr():
|
|||||||
|
|
||||||
|
|
||||||
def test_event_as_dict():
|
def test_event_as_dict():
|
||||||
"""Test as Event as dictionary."""
|
"""Test an Event as dictionary."""
|
||||||
event_type = "some_type"
|
event_type = "some_type"
|
||||||
now = dt_util.utcnow()
|
now = dt_util.utcnow()
|
||||||
data = {"some": "attr"}
|
data = {"some": "attr"}
|
||||||
@ -301,7 +301,7 @@ def test_event_as_dict():
|
|||||||
"event_type": event_type,
|
"event_type": event_type,
|
||||||
"data": data,
|
"data": data,
|
||||||
"origin": "LOCAL",
|
"origin": "LOCAL",
|
||||||
"time_fired": now,
|
"time_fired": now.isoformat(),
|
||||||
"context": {
|
"context": {
|
||||||
"id": event.context.id,
|
"id": event.context.id,
|
||||||
"parent_id": None,
|
"parent_id": None,
|
||||||
@ -309,6 +309,36 @@ def test_event_as_dict():
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
assert event.as_dict() == expected
|
assert event.as_dict() == expected
|
||||||
|
# 2nd time to verify cache
|
||||||
|
assert event.as_dict() == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_state_as_dict():
|
||||||
|
"""Test a State as dictionary."""
|
||||||
|
last_time = datetime(1984, 12, 8, 12, 0, 0)
|
||||||
|
state = ha.State(
|
||||||
|
"happy.happy",
|
||||||
|
"on",
|
||||||
|
{"pig": "dog"},
|
||||||
|
last_updated=last_time,
|
||||||
|
last_changed=last_time,
|
||||||
|
)
|
||||||
|
expected = {
|
||||||
|
"context": {
|
||||||
|
"id": state.context.id,
|
||||||
|
"parent_id": None,
|
||||||
|
"user_id": state.context.user_id,
|
||||||
|
},
|
||||||
|
"entity_id": "happy.happy",
|
||||||
|
"attributes": {"pig": "dog"},
|
||||||
|
"last_changed": last_time.isoformat(),
|
||||||
|
"last_updated": last_time.isoformat(),
|
||||||
|
"state": "on",
|
||||||
|
}
|
||||||
|
assert state.as_dict() == expected
|
||||||
|
# 2nd time to verify cache
|
||||||
|
assert state.as_dict() == expected
|
||||||
|
assert state.as_dict() is state.as_dict()
|
||||||
|
|
||||||
|
|
||||||
class TestEventBus(unittest.TestCase):
|
class TestEventBus(unittest.TestCase):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user