diff --git a/homeassistant/components/bthome/logbook.py b/homeassistant/components/bthome/logbook.py new file mode 100644 index 00000000000..703ad671799 --- /dev/null +++ b/homeassistant/components/bthome/logbook.py @@ -0,0 +1,43 @@ +"""Describe bthome logbook events.""" +from __future__ import annotations + +from collections.abc import Callable +from typing import TYPE_CHECKING, cast + +from homeassistant.components.logbook import LOGBOOK_ENTRY_MESSAGE, LOGBOOK_ENTRY_NAME +from homeassistant.core import Event, HomeAssistant, callback +from homeassistant.helpers.device_registry import async_get + +from .const import ( + BTHOME_BLE_EVENT, + DOMAIN, + BTHomeBleEvent, +) + + +@callback +def async_describe_events( + hass: HomeAssistant, + async_describe_event: Callable[[str, str, Callable[[Event], dict[str, str]]], None], +) -> None: + """Describe logbook events.""" + dr = async_get(hass) + + @callback + def async_describe_bthome_event(event: Event) -> dict[str, str]: + """Describe bthome logbook event.""" + data = event.data + if TYPE_CHECKING: + data = cast(BTHomeBleEvent, data) # type: ignore[assignment] + device = dr.async_get(data["device_id"]) + name = device and device.name or f'BTHome {data["address"]}' + if properties := data["event_properties"]: + message = f"{data['event_class']} {data['event_type']}: {properties}" + else: + message = f"{data['event_class']} {data['event_type']}" + return { + LOGBOOK_ENTRY_NAME: name, + LOGBOOK_ENTRY_MESSAGE: message, + } + + async_describe_event(DOMAIN, BTHOME_BLE_EVENT, async_describe_bthome_event) diff --git a/tests/components/bthome/test_logbook.py b/tests/components/bthome/test_logbook.py new file mode 100644 index 00000000000..f68197f9fe5 --- /dev/null +++ b/tests/components/bthome/test_logbook.py @@ -0,0 +1,64 @@ +"""The tests for bthome logbook.""" +from homeassistant.components.bthome.const import ( + BTHOME_BLE_EVENT, + DOMAIN, + BTHomeBleEvent, +) +from homeassistant.core import HomeAssistant +from homeassistant.setup import async_setup_component + +from tests.common import MockConfigEntry +from tests.components.logbook.common import MockRow, mock_humanify + + +async def test_humanify_bthome_event(hass: HomeAssistant) -> None: + """Test humanifying bthome button presses.""" + hass.config.components.add("recorder") + assert await async_setup_component(hass, "logbook", {}) + config_entry = MockConfigEntry( + domain=DOMAIN, + unique_id="A4:C1:38:8D:18:B2", + ) + config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + (event1, event2) = mock_humanify( + hass, + [ + MockRow( + BTHOME_BLE_EVENT, + dict( + BTHomeBleEvent( + device_id=None, + address="A4:C1:38:8D:18:B2", + event_class="button", + event_type="long_press", + event_properties={ + "any": "thing", + }, + ) + ), + ), + MockRow( + BTHOME_BLE_EVENT, + dict( + BTHomeBleEvent( + device_id=None, + address="A4:C1:38:8D:18:B2", + event_class="button", + event_type="press", + event_properties=None, + ) + ), + ), + ], + ) + + assert event1["name"] == "BTHome A4:C1:38:8D:18:B2" + assert event1["domain"] == DOMAIN + assert event1["message"] == "button long_press: {'any': 'thing'}" + + assert event2["name"] == "BTHome A4:C1:38:8D:18:B2" + assert event2["domain"] == DOMAIN + assert event2["message"] == "button press"