diff --git a/homeassistant/components/recorder/__init__.py b/homeassistant/components/recorder/__init__.py index c8feb3fbe9b..fb58ea5b1d0 100644 --- a/homeassistant/components/recorder/__init__.py +++ b/homeassistant/components/recorder/__init__.py @@ -1154,61 +1154,61 @@ class Recorder(threading.Thread): return self.event_session.add(dbevent) - if event.event_type == EVENT_STATE_CHANGED: - try: - dbstate = States.from_event(event) - shared_attrs = StateAttributes.shared_attrs_from_event( - event, self._exclude_attributes_by_domain - ) - except (TypeError, ValueError) as ex: - _LOGGER.warning( - "State is not JSON serializable: %s: %s", - event.data.get("new_state"), - ex, - ) - return + if event.event_type != EVENT_STATE_CHANGED: + return - dbstate.attributes = None - # Matching attributes found in the pending commit - if pending_attributes := self._pending_state_attributes.get(shared_attrs): - dbstate.state_attributes = pending_attributes - # Matching attributes id found in the cache - elif attributes_id := self._state_attributes_ids.get(shared_attrs): - dbstate.attributes_id = attributes_id - else: - attr_hash = StateAttributes.hash_shared_attrs(shared_attrs) - # Matching attributes found in the database - if ( - attributes := self.event_session.query( - StateAttributes.attributes_id - ) - .filter(StateAttributes.hash == attr_hash) - .filter(StateAttributes.shared_attrs == shared_attrs) - .first() - ): - dbstate.attributes_id = attributes[0] - self._state_attributes_ids[shared_attrs] = attributes[0] - # No matching attributes found, save them in the DB - else: - dbstate_attributes = StateAttributes( - shared_attrs=shared_attrs, hash=attr_hash - ) - dbstate.state_attributes = dbstate_attributes - self._pending_state_attributes[shared_attrs] = dbstate_attributes - self.event_session.add(dbstate_attributes) + try: + dbstate = States.from_event(event) + shared_attrs = StateAttributes.shared_attrs_from_event( + event, self._exclude_attributes_by_domain + ) + except (TypeError, ValueError) as ex: + _LOGGER.warning( + "State is not JSON serializable: %s: %s", + event.data.get("new_state"), + ex, + ) + return - if old_state := self._old_states.pop(dbstate.entity_id, None): - if old_state.state_id: - dbstate.old_state_id = old_state.state_id - else: - dbstate.old_state = old_state - if event.data.get("new_state"): - self._old_states[dbstate.entity_id] = dbstate - self._pending_expunge.append(dbstate) + dbstate.attributes = None + # Matching attributes found in the pending commit + if pending_attributes := self._pending_state_attributes.get(shared_attrs): + dbstate.state_attributes = pending_attributes + # Matching attributes id found in the cache + elif attributes_id := self._state_attributes_ids.get(shared_attrs): + dbstate.attributes_id = attributes_id + else: + attr_hash = StateAttributes.hash_shared_attrs(shared_attrs) + # Matching attributes found in the database + if ( + attributes := self.event_session.query(StateAttributes.attributes_id) + .filter(StateAttributes.hash == attr_hash) + .filter(StateAttributes.shared_attrs == shared_attrs) + .first() + ): + dbstate.attributes_id = attributes[0] + self._state_attributes_ids[shared_attrs] = attributes[0] + # No matching attributes found, save them in the DB else: - dbstate.state = None - dbstate.event = dbevent - self.event_session.add(dbstate) + dbstate_attributes = StateAttributes( + shared_attrs=shared_attrs, hash=attr_hash + ) + dbstate.state_attributes = dbstate_attributes + self._pending_state_attributes[shared_attrs] = dbstate_attributes + self.event_session.add(dbstate_attributes) + + if old_state := self._old_states.pop(dbstate.entity_id, None): + if old_state.state_id: + dbstate.old_state_id = old_state.state_id + else: + dbstate.old_state = old_state + if event.data.get("new_state"): + self._old_states[dbstate.entity_id] = dbstate + self._pending_expunge.append(dbstate) + else: + dbstate.state = None + dbstate.event = dbevent + self.event_session.add(dbstate) def _handle_database_error(self, err: Exception) -> bool: """Handle a database error that may result in moving away the corrupt db."""