Add additional context data to logbook events (#71721)

This commit is contained in:
J. Nick Koston 2022-05-12 20:21:14 -04:00 committed by GitHub
parent 1d9fb4bca8
commit 24a0007785
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 254 additions and 124 deletions

View file

@ -15,7 +15,7 @@ def async_describe_events(hass: HomeAssistant, async_describe_event): # type: i
def async_describe_logbook_event(event: LazyEventPartialState): # type: ignore[no-untyped-def]
"""Describe a logbook event."""
data = event.data
message = "has been triggered"
message = "triggered"
if ATTR_SOURCE in data:
message = f"{message} by {data[ATTR_SOURCE]}"

View file

@ -136,7 +136,7 @@ def async_describe_events(
return {
"name": f"{deconz_alarm_event.device.name}",
"message": f"fired event '{data}'.",
"message": f"fired event '{data}'",
}
@callback
@ -158,26 +158,26 @@ def async_describe_events(
if not data:
return {
"name": f"{deconz_event.device.name}",
"message": "fired an unknown event.",
"message": "fired an unknown event",
}
# No device event match
if not action:
return {
"name": f"{deconz_event.device.name}",
"message": f"fired event '{data}'.",
"message": f"fired event '{data}'",
}
# Gesture event
if not interface:
return {
"name": f"{deconz_event.device.name}",
"message": f"fired event '{ACTIONS[action]}'.",
"message": f"fired event '{ACTIONS[action]}'",
}
return {
"name": f"{deconz_event.device.name}",
"message": f"'{ACTIONS[action]}' event for '{INTERFACES[interface]}' was fired.",
"message": f"'{ACTIONS[action]}' event for '{INTERFACES[interface]}' was fired",
}
async_describe_event(

View file

@ -17,7 +17,7 @@ def async_describe_events(hass, async_describe_event):
return {
"name": "Doorbird",
"message": f"Event {event.event_type} was fired.",
"message": f"Event {event.event_type} was fired",
"entity_id": hass.data[DOMAIN][DOOR_STATION_EVENT_ENTITY_IDS].get(
doorbird_event, event.data.get(ATTR_ENTITY_ID)
),

View file

@ -0,0 +1,39 @@
"""Describe homeassistant logbook events."""
from __future__ import annotations
from collections.abc import Callable
from homeassistant.components.logbook import (
LOGBOOK_ENTRY_ICON,
LOGBOOK_ENTRY_MESSAGE,
LOGBOOK_ENTRY_NAME,
)
from homeassistant.const import EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP
from homeassistant.core import Event, HomeAssistant, callback
from . import DOMAIN
EVENT_TO_NAME = {
EVENT_HOMEASSISTANT_STOP: "stopped",
EVENT_HOMEASSISTANT_START: "started",
}
@callback
def async_describe_events(
hass: HomeAssistant,
async_describe_event: Callable[[str, str, Callable[[Event], dict[str, str]]], None],
) -> None:
"""Describe logbook events."""
@callback
def async_describe_hass_event(event: Event) -> dict[str, str]:
"""Describe homeassisant logbook event."""
return {
LOGBOOK_ENTRY_NAME: "Home Assistant",
LOGBOOK_ENTRY_MESSAGE: EVENT_TO_NAME[event.event_type],
LOGBOOK_ENTRY_ICON: "mdi:home-assistant",
}
async_describe_event(DOMAIN, EVENT_HOMEASSISTANT_STOP, async_describe_hass_event)
async_describe_event(DOMAIN, EVENT_HOMEASSISTANT_START, async_describe_hass_event)

View file

@ -37,13 +37,10 @@ from homeassistant.const import (
ATTR_NAME,
ATTR_SERVICE,
EVENT_CALL_SERVICE,
EVENT_HOMEASSISTANT_START,
EVENT_HOMEASSISTANT_STOP,
EVENT_LOGBOOK_ENTRY,
EVENT_STATE_CHANGED,
)
from homeassistant.core import (
DOMAIN as HA_DOMAIN,
Context,
Event,
HomeAssistant,
@ -70,7 +67,6 @@ from .queries import statement_for_request
_LOGGER = logging.getLogger(__name__)
FRIENDLY_NAME_JSON_EXTRACT = re.compile('"friendly_name": ?"([^"]+)"')
ENTITY_ID_JSON_EXTRACT = re.compile('"entity_id": ?"([^"]+)"')
DOMAIN_JSON_EXTRACT = re.compile('"domain": ?"([^"]+)"')
@ -79,19 +75,28 @@ ATTR_MESSAGE = "message"
DOMAIN = "logbook"
HA_DOMAIN_ENTITY_ID = f"{HA_DOMAIN}._"
CONFIG_SCHEMA = vol.Schema(
{DOMAIN: INCLUDE_EXCLUDE_BASE_FILTER_SCHEMA}, extra=vol.ALLOW_EXTRA
)
HOMEASSISTANT_EVENTS = {EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP}
CONTEXT_USER_ID = "context_user_id"
CONTEXT_ENTITY_ID = "context_entity_id"
CONTEXT_ENTITY_ID_NAME = "context_entity_id_name"
CONTEXT_EVENT_TYPE = "context_event_type"
CONTEXT_DOMAIN = "context_domain"
CONTEXT_SERVICE = "context_service"
CONTEXT_NAME = "context_name"
CONTEXT_MESSAGE = "context_message"
ALL_EVENT_TYPES_EXCEPT_STATE_CHANGED = (
EVENT_LOGBOOK_ENTRY,
EVENT_CALL_SERVICE,
*HOMEASSISTANT_EVENTS,
)
LOGBOOK_ENTRY_DOMAIN = "domain"
LOGBOOK_ENTRY_ENTITY_ID = "entity_id"
LOGBOOK_ENTRY_ICON = "icon"
LOGBOOK_ENTRY_MESSAGE = "message"
LOGBOOK_ENTRY_NAME = "name"
LOGBOOK_ENTRY_STATE = "state"
LOGBOOK_ENTRY_WHEN = "when"
ALL_EVENT_TYPES_EXCEPT_STATE_CHANGED = {EVENT_LOGBOOK_ENTRY, EVENT_CALL_SERVICE}
SCRIPT_AUTOMATION_EVENTS = {EVENT_AUTOMATION_TRIGGERED, EVENT_SCRIPT_STARTED}
@ -133,12 +138,12 @@ def async_log_entry(
context: Context | None = None,
) -> None:
"""Add an entry to the logbook."""
data = {ATTR_NAME: name, ATTR_MESSAGE: message}
data = {LOGBOOK_ENTRY_NAME: name, LOGBOOK_ENTRY_MESSAGE: message}
if domain is not None:
data[ATTR_DOMAIN] = domain
data[LOGBOOK_ENTRY_DOMAIN] = domain
if entity_id is not None:
data[ATTR_ENTITY_ID] = entity_id
data[LOGBOOK_ENTRY_ENTITY_ID] = entity_id
hass.bus.async_fire(EVENT_LOGBOOK_ENTRY, data, context=context)
@ -162,7 +167,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
message.hass = hass
message = message.async_render(parse_result=False)
async_log_entry(hass, name, message, domain, entity_id)
async_log_entry(hass, name, message, domain, entity_id, service.context)
frontend.async_register_built_in_panel(
hass, "logbook", "logbook", "hass:format-list-bulleted-type"
@ -375,13 +380,13 @@ def _humanify(
continue
data = {
"when": format_time(row),
"name": entity_name_cache.get(entity_id, row),
"state": row.state,
"entity_id": entity_id,
LOGBOOK_ENTRY_WHEN: format_time(row),
LOGBOOK_ENTRY_NAME: entity_name_cache.get(entity_id, row),
LOGBOOK_ENTRY_STATE: row.state,
LOGBOOK_ENTRY_ENTITY_ID: entity_id,
}
if icon := _row_attributes_extract(row, ICON_JSON_EXTRACT):
data["icon"] = icon
data[LOGBOOK_ENTRY_ICON] = icon
context_augmenter.augment(data, entity_id, row)
yield data
@ -389,26 +394,11 @@ def _humanify(
elif event_type in external_events:
domain, describe_event = external_events[event_type]
data = describe_event(event_cache.get(row))
data["when"] = format_time(row)
data["domain"] = domain
data[LOGBOOK_ENTRY_WHEN] = format_time(row)
data[LOGBOOK_ENTRY_DOMAIN] = domain
context_augmenter.augment(data, data.get(ATTR_ENTITY_ID), row)
yield data
elif event_type == EVENT_HOMEASSISTANT_START:
yield {
"when": format_time(row),
"name": "Home Assistant",
"message": "started",
"domain": HA_DOMAIN,
}
elif event_type == EVENT_HOMEASSISTANT_STOP:
yield {
"when": format_time(row),
"name": "Home Assistant",
"message": "stopped",
"domain": HA_DOMAIN,
}
elif event_type == EVENT_LOGBOOK_ENTRY:
event = event_cache.get(row)
event_data = event.data
@ -419,11 +409,11 @@ def _humanify(
domain = split_entity_id(str(entity_id))[0]
data = {
"when": format_time(row),
"name": event_data.get(ATTR_NAME),
"message": event_data.get(ATTR_MESSAGE),
"domain": domain,
"entity_id": entity_id,
LOGBOOK_ENTRY_WHEN: format_time(row),
LOGBOOK_ENTRY_NAME: event_data.get(ATTR_NAME),
LOGBOOK_ENTRY_MESSAGE: event_data.get(ATTR_MESSAGE),
LOGBOOK_ENTRY_DOMAIN: domain,
LOGBOOK_ENTRY_ENTITY_ID: entity_id,
}
context_augmenter.augment(data, entity_id, row)
yield data
@ -505,9 +495,6 @@ def _keep_row(
row: Row,
entities_filter: EntityFilter | Callable[[str], bool] | None = None,
) -> bool:
if event_type in HOMEASSISTANT_EVENTS:
return entities_filter is None or entities_filter(HA_DOMAIN_ENTITY_ID)
if entity_id := _row_event_data_extract(row, ENTITY_ID_JSON_EXTRACT):
return entities_filter is None or entities_filter(entity_id)
@ -544,7 +531,7 @@ 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
data[CONTEXT_USER_ID] = context_user_id
if not (context_row := self.context_lookup.get(row.context_id)):
return
@ -567,43 +554,40 @@ class ContextAugmenter:
# State change
if context_entity_id := context_row.entity_id:
data["context_entity_id"] = context_entity_id
data["context_entity_id_name"] = self.entity_name_cache.get(
data[CONTEXT_ENTITY_ID] = context_entity_id
data[CONTEXT_ENTITY_ID_NAME] = self.entity_name_cache.get(
context_entity_id, context_row
)
data["context_event_type"] = event_type
data[CONTEXT_EVENT_TYPE] = event_type
return
# Call service
if event_type == EVENT_CALL_SERVICE:
event = self.event_cache.get(context_row)
event_data = event.data
data["context_domain"] = event_data.get(ATTR_DOMAIN)
data["context_service"] = event_data.get(ATTR_SERVICE)
data["context_event_type"] = event_type
data[CONTEXT_DOMAIN] = event_data.get(ATTR_DOMAIN)
data[CONTEXT_SERVICE] = event_data.get(ATTR_SERVICE)
data[CONTEXT_EVENT_TYPE] = event_type
return
if not entity_id:
if event_type not in self.external_events:
return
attr_entity_id = _row_event_data_extract(context_row, ENTITY_ID_JSON_EXTRACT)
if attr_entity_id is None or (
event_type in SCRIPT_AUTOMATION_EVENTS and attr_entity_id == entity_id
):
domain, describe_event = self.external_events[event_type]
data[CONTEXT_EVENT_TYPE] = event_type
data[CONTEXT_DOMAIN] = domain
event = self.event_cache.get(context_row)
described = describe_event(event)
if name := described.get(ATTR_NAME):
data[CONTEXT_NAME] = name
if message := described.get(ATTR_MESSAGE):
data[CONTEXT_MESSAGE] = message
if not (attr_entity_id := described.get(ATTR_ENTITY_ID)):
return
data["context_entity_id"] = attr_entity_id
data["context_entity_id_name"] = self.entity_name_cache.get(
data[CONTEXT_ENTITY_ID] = attr_entity_id
data[CONTEXT_ENTITY_ID_NAME] = self.entity_name_cache.get(
attr_entity_id, context_row
)
data["context_event_type"] = event_type
if event_type in self.external_events:
domain, describe_event = self.external_events[event_type]
data["context_domain"] = domain
event = self.event_cache.get(context_row)
if name := describe_event(event).get(ATTR_NAME):
data["context_name"] = name
def _is_sensor_continuous(
@ -627,11 +611,14 @@ def _is_sensor_continuous(
def _rows_match(row: Row, other_row: Row) -> bool:
"""Check of rows match by using the same method as Events __hash__."""
return bool(
row.event_type == other_row.event_type
and row.context_id == other_row.context_id
and row.time_fired == other_row.time_fired
)
if (
(state_id := row.state_id) is not None
and state_id == other_row.state_id
or (event_id := row.event_id) is not None
and event_id == other_row.event_id
):
return True
return False
def _row_event_data_extract(row: Row, extractor: re.Pattern) -> str | None:

View file

@ -33,6 +33,7 @@ UNIT_OF_MEASUREMENT_JSON_LIKE = f"%{UNIT_OF_MEASUREMENT_JSON}%"
EVENT_COLUMNS = (
Events.event_id.label("event_id"),
Events.event_type.label("event_type"),
Events.event_data.label("event_data"),
Events.time_fired.label("time_fired"),
@ -42,6 +43,7 @@ EVENT_COLUMNS = (
)
STATE_COLUMNS = (
States.state_id.label("state_id"),
States.state.label("state"),
States.entity_id.label("entity_id"),
States.attributes.label("attributes"),
@ -49,6 +51,7 @@ STATE_COLUMNS = (
)
EMPTY_STATE_COLUMNS = (
literal(value=None, type_=sqlalchemy.String).label("state_id"),
literal(value=None, type_=sqlalchemy.String).label("state"),
literal(value=None, type_=sqlalchemy.String).label("entity_id"),
literal(value=None, type_=sqlalchemy.Text).label("attributes"),
@ -294,6 +297,7 @@ def _select_states(start_day: dt, end_day: dt) -> Select:
old_state = aliased(States, name="old_state")
return (
select(
literal(value=None, type_=sqlalchemy.Text).label("event_id"),
literal(value=EVENT_STATE_CHANGED, type_=sqlalchemy.String).label(
"event_type"
),

View file

@ -49,7 +49,7 @@ def async_describe_events(
return {
"name": "Shelly",
"message": f"'{click_type}' click event for {input_name} Input was fired.",
"message": f"'{click_type}' click event for {input_name} Input was fired",
}
async_describe_event(DOMAIN, EVENT_SHELLY_CLICK, async_describe_shelly_click_event)

View file

@ -1243,12 +1243,12 @@ async def test_logbook_humanify_automation_triggered_event(hass):
assert event1["name"] == "Hello Automation"
assert event1["domain"] == "automation"
assert event1["message"] == "has been triggered"
assert event1["message"] == "triggered"
assert event1["entity_id"] == "automation.hello"
assert event2["name"] == "Bye Automation"
assert event2["domain"] == "automation"
assert event2["message"] == "has been triggered by source of trigger"
assert event2["message"] == "triggered by source of trigger"
assert event2["entity_id"] == "automation.bye"

View file

@ -37,13 +37,13 @@ async def test_humanify_automation_trigger_event(hass):
)
assert event1["name"] == "Bla"
assert event1["message"] == "has been triggered by state change of input_boolean.yo"
assert event1["message"] == "triggered by state change of input_boolean.yo"
assert event1["source"] == "state change of input_boolean.yo"
assert event1["context_id"] == context.id
assert event1["entity_id"] == "automation.bla"
assert event2["name"] == "Bla"
assert event2["message"] == "has been triggered"
assert event2["message"] == "triggered"
assert event2["source"] is None
assert event2["context_id"] == context.id
assert event2["entity_id"] == "automation.bla"

View file

@ -85,7 +85,7 @@ async def test_humanifying_deconz_alarm_event(hass, aioclient_mock):
assert events[0]["name"] == "Keypad"
assert events[0]["domain"] == "deconz"
assert events[0]["message"] == "fired event 'armed_away'."
assert events[0]["message"] == "fired event 'armed_away'"
async def test_humanifying_deconz_event(hass, aioclient_mock):
@ -214,20 +214,20 @@ async def test_humanifying_deconz_event(hass, aioclient_mock):
assert events[0]["name"] == "Switch 1"
assert events[0]["domain"] == "deconz"
assert events[0]["message"] == "fired event '2000'."
assert events[0]["message"] == "fired event '2000'"
assert events[1]["name"] == "Hue remote"
assert events[1]["domain"] == "deconz"
assert events[1]["message"] == "'Long press' event for 'Dim up' was fired."
assert events[1]["message"] == "'Long press' event for 'Dim up' was fired"
assert events[2]["name"] == "Xiaomi cube"
assert events[2]["domain"] == "deconz"
assert events[2]["message"] == "fired event 'Shake'."
assert events[2]["message"] == "fired event 'Shake'"
assert events[3]["name"] == "Xiaomi cube"
assert events[3]["domain"] == "deconz"
assert events[3]["message"] == "fired event 'unsupported_gesture'."
assert events[3]["message"] == "fired event 'unsupported_gesture'"
assert events[4]["name"] == "Faulty event"
assert events[4]["domain"] == "deconz"
assert events[4]["message"] == "fired an unknown event."
assert events[4]["message"] == "fired an unknown event"

View file

@ -1,5 +1,6 @@
"""The tests for the logbook component."""
# pylint: disable=protected-access,invalid-name
import asyncio
import collections
from datetime import datetime, timedelta
from http import HTTPStatus
@ -208,8 +209,10 @@ 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_not_grouped(hass_):
async def test_home_assistant_start_stop_not_grouped(hass_):
"""Test if HA start and stop events are no longer grouped."""
await async_setup_component(hass_, "homeassistant", {})
await hass_.async_block_till_done()
entries = mock_humanify(
hass_,
(
@ -223,8 +226,10 @@ def test_home_assistant_start_stop_not_grouped(hass_):
assert_entry(entries[1], name="Home Assistant", message="started", domain=ha.DOMAIN)
def test_home_assistant_start(hass_):
async def test_home_assistant_start(hass_):
"""Test if HA start is not filtered or converted into a restart."""
await async_setup_component(hass_, "homeassistant", {})
await hass_.async_block_till_done()
entity_id = "switch.bla"
pointA = dt_util.utcnow()
@ -604,9 +609,12 @@ async def test_logbook_view_end_time_entity(hass, hass_client, recorder_mock):
async def test_logbook_entity_filter_with_automations(hass, hass_client, recorder_mock):
"""Test the logbook view with end_time and entity with automations and scripts."""
await async_setup_component(hass, "logbook", {})
await async_setup_component(hass, "automation", {})
await async_setup_component(hass, "script", {})
await asyncio.gather(
*[
async_setup_component(hass, comp, {})
for comp in ("homeassistant", "logbook", "automation", "script")
]
)
await async_recorder_block_till_done(hass)
@ -749,7 +757,12 @@ async def test_filter_continuous_sensor_values(
async def test_exclude_new_entities(hass, hass_client, recorder_mock, set_utc):
"""Test if events are excluded on first update."""
await async_setup_component(hass, "logbook", {})
await asyncio.gather(
*[
async_setup_component(hass, comp, {})
for comp in ("homeassistant", "logbook")
]
)
await async_recorder_block_till_done(hass)
entity_id = "climate.bla"
@ -781,7 +794,12 @@ async def test_exclude_new_entities(hass, hass_client, recorder_mock, set_utc):
async def test_exclude_removed_entities(hass, hass_client, recorder_mock, set_utc):
"""Test if events are excluded on last update."""
await async_setup_component(hass, "logbook", {})
await asyncio.gather(
*[
async_setup_component(hass, comp, {})
for comp in ("homeassistant", "logbook")
]
)
await async_recorder_block_till_done(hass)
entity_id = "climate.bla"
@ -820,7 +838,12 @@ async def test_exclude_removed_entities(hass, hass_client, recorder_mock, set_ut
async def test_exclude_attribute_changes(hass, hass_client, recorder_mock, set_utc):
"""Test if events of attribute changes are filtered."""
await async_setup_component(hass, "logbook", {})
await asyncio.gather(
*[
async_setup_component(hass, comp, {})
for comp in ("homeassistant", "logbook")
]
)
await async_recorder_block_till_done(hass)
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
@ -855,9 +878,12 @@ async def test_exclude_attribute_changes(hass, hass_client, recorder_mock, set_u
async def test_logbook_entity_context_id(hass, recorder_mock, hass_client):
"""Test the logbook view with end_time and entity with automations and scripts."""
await async_setup_component(hass, "logbook", {})
await async_setup_component(hass, "automation", {})
await async_setup_component(hass, "script", {})
await asyncio.gather(
*[
async_setup_component(hass, comp, {})
for comp in ("homeassistant", "logbook", "automation", "script")
]
)
await async_recorder_block_till_done(hass)
@ -1004,9 +1030,12 @@ async def test_logbook_context_id_automation_script_started_manually(
hass, recorder_mock, hass_client
):
"""Test the logbook populates context_ids for scripts and automations started manually."""
await async_setup_component(hass, "logbook", {})
await async_setup_component(hass, "automation", {})
await async_setup_component(hass, "script", {})
await asyncio.gather(
*[
async_setup_component(hass, comp, {})
for comp in ("homeassistant", "logbook", "automation", "script")
]
)
await async_recorder_block_till_done(hass)
@ -1032,6 +1061,19 @@ async def test_logbook_context_id_automation_script_started_manually(
)
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
script_2_context = ha.Context(
id="1234",
user_id="b400facee45711eaa9308bfd3d19e474",
)
hass.bus.async_fire(
EVENT_SCRIPT_STARTED,
{ATTR_NAME: "Mock script"},
context=script_2_context,
)
hass.states.async_set("switch.new", STATE_ON, context=script_2_context)
hass.states.async_set("switch.new", STATE_OFF, context=script_2_context)
await hass.async_block_till_done()
await async_wait_recording_done(hass)
@ -1061,12 +1103,28 @@ async def test_logbook_context_id_automation_script_started_manually(
assert json_dict[2]["domain"] == "homeassistant"
assert json_dict[3]["entity_id"] is None
assert json_dict[3]["name"] == "Mock script"
assert "context_entity_id" not in json_dict[1]
assert json_dict[3]["context_user_id"] == "b400facee45711eaa9308bfd3d19e474"
assert json_dict[3]["context_id"] == "1234"
assert json_dict[4]["entity_id"] == "switch.new"
assert json_dict[4]["state"] == "off"
assert "context_entity_id" not in json_dict[1]
assert json_dict[4]["context_user_id"] == "b400facee45711eaa9308bfd3d19e474"
assert json_dict[4]["context_event_type"] == "script_started"
assert json_dict[4]["context_domain"] == "script"
async def test_logbook_entity_context_parent_id(hass, hass_client, recorder_mock):
"""Test the logbook view links events via context parent_id."""
await async_setup_component(hass, "logbook", {})
await async_setup_component(hass, "automation", {})
await async_setup_component(hass, "script", {})
await asyncio.gather(
*[
async_setup_component(hass, comp, {})
for comp in ("homeassistant", "logbook", "automation", "script")
]
)
await async_recorder_block_till_done(hass)
@ -1240,7 +1298,13 @@ async def test_logbook_entity_context_parent_id(hass, hass_client, recorder_mock
async def test_logbook_context_from_template(hass, hass_client, recorder_mock):
"""Test the logbook view with end_time and entity with automations and scripts."""
await async_setup_component(hass, "logbook", {})
await asyncio.gather(
*[
async_setup_component(hass, comp, {})
for comp in ("homeassistant", "logbook")
]
)
assert await async_setup_component(
hass,
"switch",
@ -1637,7 +1701,13 @@ async def test_logbook_invalid_entity(hass, hass_client, recorder_mock):
async def test_icon_and_state(hass, hass_client, recorder_mock):
"""Test to ensure state and custom icons are returned."""
await async_setup_component(hass, "logbook", {})
await asyncio.gather(
*[
async_setup_component(hass, comp, {})
for comp in ("homeassistant", "logbook")
]
)
await async_recorder_block_till_done(hass)
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
@ -1705,6 +1775,7 @@ async def test_exclude_events_domain(hass, hass_client, recorder_mock):
entity_id = "switch.bla"
entity_id2 = "sensor.blu"
await async_setup_component(hass, "homeassistant", {})
config = logbook.CONFIG_SCHEMA(
{
ha.DOMAIN: {},
@ -1750,7 +1821,10 @@ async def test_exclude_events_domain_glob(hass, hass_client, recorder_mock):
},
}
)
await async_setup_component(hass, "logbook", config)
await asyncio.gather(
async_setup_component(hass, "homeassistant", {}),
async_setup_component(hass, "logbook", config),
)
await async_recorder_block_till_done(hass)
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
@ -1789,7 +1863,10 @@ async def test_include_events_entity(hass, hass_client, recorder_mock):
},
}
)
await async_setup_component(hass, "logbook", config)
await asyncio.gather(
async_setup_component(hass, "homeassistant", {}),
async_setup_component(hass, "logbook", config),
)
await async_recorder_block_till_done(hass)
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
@ -1821,7 +1898,10 @@ async def test_exclude_events_entity(hass, hass_client, recorder_mock):
logbook.DOMAIN: {CONF_EXCLUDE: {CONF_ENTITIES: [entity_id]}},
}
)
await async_setup_component(hass, "logbook", config)
await asyncio.gather(
async_setup_component(hass, "homeassistant", {}),
async_setup_component(hass, "logbook", config),
)
await async_recorder_block_till_done(hass)
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
@ -1854,7 +1934,10 @@ async def test_include_events_domain(hass, hass_client, recorder_mock):
},
}
)
await async_setup_component(hass, "logbook", config)
await asyncio.gather(
async_setup_component(hass, "homeassistant", {}),
async_setup_component(hass, "logbook", config),
)
await async_recorder_block_till_done(hass)
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
@ -1897,7 +1980,10 @@ async def test_include_events_domain_glob(hass, hass_client, recorder_mock):
},
}
)
await async_setup_component(hass, "logbook", config)
await asyncio.gather(
async_setup_component(hass, "homeassistant", {}),
async_setup_component(hass, "logbook", config),
)
await async_recorder_block_till_done(hass)
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
@ -1948,7 +2034,10 @@ async def test_include_exclude_events(hass, hass_client, recorder_mock):
},
}
)
await async_setup_component(hass, "logbook", config)
await asyncio.gather(
async_setup_component(hass, "homeassistant", {}),
async_setup_component(hass, "logbook", config),
)
await async_recorder_block_till_done(hass)
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
@ -2004,7 +2093,10 @@ async def test_include_exclude_events_with_glob_filters(
},
}
)
await async_setup_component(hass, "logbook", config)
await asyncio.gather(
async_setup_component(hass, "homeassistant", {}),
async_setup_component(hass, "logbook", config),
)
await async_recorder_block_till_done(hass)
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
@ -2047,7 +2139,10 @@ async def test_empty_config(hass, hass_client, recorder_mock):
logbook.DOMAIN: {},
}
)
await async_setup_component(hass, "logbook", config)
await asyncio.gather(
async_setup_component(hass, "homeassistant", {}),
async_setup_component(hass, "logbook", config),
)
await async_recorder_block_till_done(hass)
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
@ -2141,7 +2236,12 @@ def _assert_entry(
async def test_get_events(hass, hass_ws_client, recorder_mock):
"""Test logbook get_events."""
now = dt_util.utcnow()
await async_setup_component(hass, "logbook", {})
await asyncio.gather(
*[
async_setup_component(hass, comp, {})
for comp in ("homeassistant", "logbook")
]
)
await async_recorder_block_till_done(hass)
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)

View file

@ -46,14 +46,14 @@ async def test_humanify_shelly_click_event_block_device(hass, coap_wrapper):
assert event1["domain"] == DOMAIN
assert (
event1["message"]
== "'single' click event for Test name channel 1 Input was fired."
== "'single' click event for Test name channel 1 Input was fired"
)
assert event2["name"] == "Shelly"
assert event2["domain"] == DOMAIN
assert (
event2["message"]
== "'long' click event for shellyswitch25-12345678 channel 2 Input was fired."
== "'long' click event for shellyswitch25-12345678 channel 2 Input was fired"
)
@ -91,12 +91,12 @@ async def test_humanify_shelly_click_event_rpc_device(hass, rpc_wrapper):
assert event1["domain"] == DOMAIN
assert (
event1["message"]
== "'single_push' click event for test switch_0 Input was fired."
== "'single_push' click event for test switch_0 Input was fired"
)
assert event2["name"] == "Shelly"
assert event2["domain"] == DOMAIN
assert (
event2["message"]
== "'btn_down' click event for shellypro4pm-12345678 channel 2 Input was fired."
== "'btn_down' click event for shellypro4pm-12345678 channel 2 Input was fired"
)