Always show the start and stop event in logbook (#71600)

This commit is contained in:
J. Nick Koston 2022-05-09 15:21:21 -05:00 committed by GitHub
parent 5430b51358
commit 2560d35f1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 124 deletions

View File

@ -5,7 +5,6 @@ from collections.abc import Callable, Generator, Iterable
from contextlib import suppress
from datetime import datetime as dt, timedelta
from http import HTTPStatus
from itertools import groupby
import json
import re
from typing import Any, cast
@ -338,51 +337,21 @@ def _humanify(
"""
external_events = hass.data.get(DOMAIN, {})
# Continuous sensors, will be excluded from the logbook
continuous_sensors = {}
# Group events in batches of GROUP_BY_MINUTES
for _, g_rows in groupby(
rows, lambda row: row.time_fired.minute // GROUP_BY_MINUTES # type: ignore[no-any-return]
):
rows_batch = list(g_rows)
# Group HA start/stop events
# Maps minute of event to 1: stop, 2: stop + start
start_stop_events = {}
continuous_sensors: dict[str, bool] = {}
# Process events
for row in rows_batch:
if row.event_type == EVENT_STATE_CHANGED:
entity_id = row.entity_id
if (
entity_id in continuous_sensors
or split_entity_id(entity_id)[0] != SENSOR_DOMAIN
):
continue
assert entity_id is not None
continuous_sensors[entity_id] = _is_sensor_continuous(hass, entity_id)
elif row.event_type == EVENT_HOMEASSISTANT_STOP:
if row.time_fired.minute in start_stop_events:
continue
start_stop_events[row.time_fired.minute] = 1
elif row.event_type == EVENT_HOMEASSISTANT_START:
if row.time_fired.minute not in start_stop_events:
continue
start_stop_events[row.time_fired.minute] = 2
# Yield entries
for row in rows_batch:
if row.event_type == EVENT_STATE_CHANGED:
for row in rows:
event_type = row.event_type
if event_type == EVENT_STATE_CHANGED:
entity_id = row.entity_id
assert entity_id is not None
if continuous_sensors.get(entity_id):
# Skip continuous sensors
if (
is_continuous := continuous_sensors.get(entity_id)
) is None and split_entity_id(entity_id)[0] == SENSOR_DOMAIN:
is_continuous = _is_sensor_continuous(hass, entity_id)
continuous_sensors[entity_id] = is_continuous
if is_continuous:
continue
data = {
@ -391,53 +360,36 @@ def _humanify(
"state": row.state,
"entity_id": entity_id,
}
if icon := _row_attributes_extract(row, ICON_JSON_EXTRACT):
data["icon"] = icon
if row.context_user_id:
data["context_user_id"] = row.context_user_id
context_augmenter.augment(data, entity_id, row)
yield data
elif row.event_type in external_events:
domain, describe_event = external_events[row.event_type]
elif event_type in external_events:
domain, describe_event = external_events[event_type]
data = describe_event(event_cache.get(row))
data["when"] = _row_time_fired_isoformat(row)
data["domain"] = domain
if row.context_user_id:
data["context_user_id"] = row.context_user_id
entity_id = data.get(ATTR_ENTITY_ID)
context_augmenter.augment(data, entity_id, row)
context_augmenter.augment(data, data.get(ATTR_ENTITY_ID), row)
yield data
elif row.event_type == EVENT_HOMEASSISTANT_START:
if start_stop_events.get(row.time_fired.minute) == 2:
continue
elif event_type == EVENT_HOMEASSISTANT_START:
yield {
"when": _row_time_fired_isoformat(row),
"name": "Home Assistant",
"message": "started",
"domain": HA_DOMAIN,
}
elif row.event_type == EVENT_HOMEASSISTANT_STOP:
if start_stop_events.get(row.time_fired.minute) == 2:
action = "restarted"
else:
action = "stopped"
elif event_type == EVENT_HOMEASSISTANT_STOP:
yield {
"when": _row_time_fired_isoformat(row),
"name": "Home Assistant",
"message": action,
"message": "stopped",
"domain": HA_DOMAIN,
}
elif row.event_type == EVENT_LOGBOOK_ENTRY:
elif event_type == EVENT_LOGBOOK_ENTRY:
event = event_cache.get(row)
event_data = event.data
domain = event_data.get(ATTR_DOMAIN)
@ -453,10 +405,6 @@ def _humanify(
"domain": domain,
"entity_id": entity_id,
}
if row.context_user_id:
data["context_user_id"] = row.context_user_id
context_augmenter.augment(data, entity_id, row)
yield data
@ -746,6 +694,9 @@ class ContextAugmenter:
def augment(self, data: dict[str, Any], entity_id: str | None, row: Row) -> None:
"""Augment data from the row and cache."""
if context_user_id := row.context_user_id:
data["context_user_id"] = context_user_id
if not (context_row := self.context_lookup.get(row.context_id)):
return

View File

@ -210,11 +210,8 @@ async def test_filter_sensor(hass_: ha.HomeAssistant, hass_client):
_assert_entry(entries[2], name="ble", entity_id=entity_id4, state="10")
def test_home_assistant_start_stop_grouped(hass_):
"""Test if HA start and stop events are grouped.
Events that are occurring in the same minute.
"""
def test_home_assistant_start_stop_not_grouped(hass_):
"""Test if HA start and stop events are no longer grouped."""
entries = mock_humanify(
hass_,
(
@ -223,10 +220,9 @@ def test_home_assistant_start_stop_grouped(hass_):
),
)
assert len(entries) == 1
assert_entry(
entries[0], name="Home Assistant", message="restarted", domain=ha.DOMAIN
)
assert len(entries) == 2
assert_entry(entries[0], name="Home Assistant", message="stopped", domain=ha.DOMAIN)
assert_entry(entries[1], name="Home Assistant", message="started", domain=ha.DOMAIN)
def test_home_assistant_start(hass_):