From 19be31d13acf5f2ef960b7d076454629b3187b67 Mon Sep 17 00:00:00 2001
From: Paulus Schoutsen <balloob@gmail.com>
Date: Mon, 20 Apr 2020 17:48:09 -0700
Subject: [PATCH] Migrate HomeKit to use describe_event for logbook support
 (#34485)

---
 homeassistant/components/homekit/__init__.py  | 25 +++++++
 .../components/homekit/manifest.json          |  5 +-
 homeassistant/components/logbook/__init__.py  | 29 -------
 tests/components/homekit/test_init.py         | 54 +++++++++++++
 tests/components/logbook/test_init.py         | 75 ++-----------------
 5 files changed, 87 insertions(+), 101 deletions(-)
 create mode 100644 tests/components/homekit/test_init.py

diff --git a/homeassistant/components/homekit/__init__.py b/homeassistant/components/homekit/__init__.py
index 3031dbddf0d..9cfbab0395f 100644
--- a/homeassistant/components/homekit/__init__.py
+++ b/homeassistant/components/homekit/__init__.py
@@ -11,6 +11,7 @@ from homeassistant.components.media_player import DEVICE_CLASS_TV
 from homeassistant.const import (
     ATTR_DEVICE_CLASS,
     ATTR_ENTITY_ID,
+    ATTR_SERVICE,
     ATTR_SUPPORTED_FEATURES,
     ATTR_UNIT_OF_MEASUREMENT,
     CONF_IP_ADDRESS,
@@ -26,6 +27,7 @@ from homeassistant.const import (
     TEMP_FAHRENHEIT,
     UNIT_PERCENTAGE,
 )
+from homeassistant.core import callback
 import homeassistant.helpers.config_validation as cv
 from homeassistant.helpers.entityfilter import FILTER_SCHEMA
 from homeassistant.util import get_local_ip
@@ -34,6 +36,8 @@ from homeassistant.util.decorator import Registry
 from .aidmanager import AccessoryAidStorage
 from .const import (
     AID_STORAGE,
+    ATTR_DISPLAY_NAME,
+    ATTR_VALUE,
     BRIDGE_NAME,
     CONF_ADVERTISE_IP,
     CONF_AUTO_START,
@@ -50,6 +54,7 @@ from .const import (
     DEVICE_CLASS_CO2,
     DEVICE_CLASS_PM25,
     DOMAIN,
+    EVENT_HOMEKIT_CHANGED,
     HOMEKIT_FILE,
     SERVICE_HOMEKIT_RESET_ACCESSORY,
     SERVICE_HOMEKIT_START,
@@ -169,6 +174,26 @@ async def async_setup(hass, config):
         schema=RESET_ACCESSORY_SERVICE_SCHEMA,
     )
 
+    @callback
+    def async_describe_logbook_event(event):
+        """Describe a logbook event."""
+        data = event.data
+        entity_id = data.get(ATTR_ENTITY_ID)
+        value = data.get(ATTR_VALUE)
+
+        value_msg = f" to {value}" if value else ""
+        message = f"send command {data[ATTR_SERVICE]}{value_msg} for {data[ATTR_DISPLAY_NAME]}"
+
+        return {
+            "name": "HomeKit",
+            "message": message,
+            "entity_id": entity_id,
+        }
+
+    hass.components.logbook.async_describe_event(
+        DOMAIN, EVENT_HOMEKIT_CHANGED, async_describe_logbook_event
+    )
+
     if auto_start:
         hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, homekit.start)
         return True
diff --git a/homeassistant/components/homekit/manifest.json b/homeassistant/components/homekit/manifest.json
index ca6ab7a00a5..7b1cc0ec827 100644
--- a/homeassistant/components/homekit/manifest.json
+++ b/homeassistant/components/homekit/manifest.json
@@ -2,6 +2,7 @@
   "domain": "homekit",
   "name": "HomeKit",
   "documentation": "https://www.home-assistant.io/integrations/homekit",
-  "requirements": ["HAP-python==2.8.2","fnvhash==0.1.0"],
-  "codeowners": ["@bdraco"]
+  "requirements": ["HAP-python==2.8.2", "fnvhash==0.1.0"],
+  "codeowners": ["@bdraco"],
+  "after_dependencies": ["logbook"]
 }
diff --git a/homeassistant/components/logbook/__init__.py b/homeassistant/components/logbook/__init__.py
index 9fad7e9752f..cd6a06720ae 100644
--- a/homeassistant/components/logbook/__init__.py
+++ b/homeassistant/components/logbook/__init__.py
@@ -8,12 +8,6 @@ from sqlalchemy.exc import SQLAlchemyError
 import voluptuous as vol
 
 from homeassistant.components import sun
-from homeassistant.components.homekit.const import (
-    ATTR_DISPLAY_NAME,
-    ATTR_VALUE,
-    DOMAIN as DOMAIN_HOMEKIT,
-    EVENT_HOMEKIT_CHANGED,
-)
 from homeassistant.components.http import HomeAssistantView
 from homeassistant.components.recorder.models import Events, States
 from homeassistant.components.recorder.util import (
@@ -26,7 +20,6 @@ from homeassistant.const import (
     ATTR_ENTITY_ID,
     ATTR_HIDDEN,
     ATTR_NAME,
-    ATTR_SERVICE,
     CONF_EXCLUDE,
     CONF_INCLUDE,
     EVENT_AUTOMATION_TRIGGERED,
@@ -89,7 +82,6 @@ ALL_EVENT_TYPES = [
     EVENT_LOGBOOK_ENTRY,
     EVENT_HOMEASSISTANT_START,
     EVENT_HOMEASSISTANT_STOP,
-    EVENT_HOMEKIT_CHANGED,
     EVENT_AUTOMATION_TRIGGERED,
     EVENT_SCRIPT_STARTED,
 ]
@@ -324,24 +316,6 @@ def humanify(hass, events):
                     "context_user_id": event.context.user_id,
                 }
 
-            elif event.event_type == EVENT_HOMEKIT_CHANGED:
-                data = event.data
-                entity_id = data.get(ATTR_ENTITY_ID)
-                value = data.get(ATTR_VALUE)
-
-                value_msg = f" to {value}" if value else ""
-                message = f"send command {data[ATTR_SERVICE]}{value_msg} for {data[ATTR_DISPLAY_NAME]}"
-
-                yield {
-                    "when": event.time_fired,
-                    "name": "HomeKit",
-                    "message": message,
-                    "domain": DOMAIN_HOMEKIT,
-                    "entity_id": entity_id,
-                    "context_id": event.context.id,
-                    "context_user_id": event.context.user_id,
-                }
-
             elif event.event_type == EVENT_AUTOMATION_TRIGGERED:
                 yield {
                     "when": event.time_fired,
@@ -498,9 +472,6 @@ def _keep_event(hass, event, entities_filter):
     elif event.event_type in hass.data.get(DOMAIN, {}):
         domain = hass.data[DOMAIN][event.event_type][0]
 
-    elif event.event_type == EVENT_HOMEKIT_CHANGED:
-        domain = DOMAIN_HOMEKIT
-
     if not entity_id and domain:
         entity_id = f"{domain}."
 
diff --git a/tests/components/homekit/test_init.py b/tests/components/homekit/test_init.py
new file mode 100644
index 00000000000..e01588305d5
--- /dev/null
+++ b/tests/components/homekit/test_init.py
@@ -0,0 +1,54 @@
+"""Test HomeKit initialization."""
+from asynctest import patch
+
+from homeassistant import core as ha
+from homeassistant.components import logbook
+from homeassistant.components.homekit.const import (
+    ATTR_DISPLAY_NAME,
+    ATTR_VALUE,
+    DOMAIN as DOMAIN_HOMEKIT,
+    EVENT_HOMEKIT_CHANGED,
+)
+from homeassistant.const import ATTR_ENTITY_ID, ATTR_SERVICE
+from homeassistant.setup import async_setup_component
+
+
+async def test_humanify_homekit_changed_event(hass, hk_driver):
+    """Test humanifying HomeKit changed event."""
+    with patch("homeassistant.components.homekit.HomeKit"):
+        assert await async_setup_component(hass, "homekit", {"homekit": {}})
+
+    event1, event2 = list(
+        logbook.humanify(
+            hass,
+            [
+                ha.Event(
+                    EVENT_HOMEKIT_CHANGED,
+                    {
+                        ATTR_ENTITY_ID: "lock.front_door",
+                        ATTR_DISPLAY_NAME: "Front Door",
+                        ATTR_SERVICE: "lock",
+                    },
+                ),
+                ha.Event(
+                    EVENT_HOMEKIT_CHANGED,
+                    {
+                        ATTR_ENTITY_ID: "cover.window",
+                        ATTR_DISPLAY_NAME: "Window",
+                        ATTR_SERVICE: "set_cover_position",
+                        ATTR_VALUE: 75,
+                    },
+                ),
+            ],
+        )
+    )
+
+    assert event1["name"] == "HomeKit"
+    assert event1["domain"] == DOMAIN_HOMEKIT
+    assert event1["message"] == "send command lock for Front Door"
+    assert event1["entity_id"] == "lock.front_door"
+
+    assert event2["name"] == "HomeKit"
+    assert event2["domain"] == DOMAIN_HOMEKIT
+    assert event2["message"] == "send command set_cover_position to 75 for Window"
+    assert event2["entity_id"] == "cover.window"
diff --git a/tests/components/logbook/test_init.py b/tests/components/logbook/test_init.py
index 2a6c08a668e..814e304f9f5 100644
--- a/tests/components/logbook/test_init.py
+++ b/tests/components/logbook/test_init.py
@@ -11,17 +11,10 @@ import voluptuous as vol
 
 from homeassistant.components import logbook, recorder, sun
 from homeassistant.components.alexa.smart_home import EVENT_ALEXA_SMART_HOME
-from homeassistant.components.homekit.const import (
-    ATTR_DISPLAY_NAME,
-    ATTR_VALUE,
-    DOMAIN as DOMAIN_HOMEKIT,
-    EVENT_HOMEKIT_CHANGED,
-)
 from homeassistant.const import (
     ATTR_ENTITY_ID,
     ATTR_HIDDEN,
     ATTR_NAME,
-    ATTR_SERVICE,
     EVENT_AUTOMATION_TRIGGERED,
     EVENT_HOMEASSISTANT_START,
     EVENT_HOMEASSISTANT_STOP,
@@ -287,9 +280,7 @@ class TestComponentLogbook(unittest.TestCase):
             {
                 ha.DOMAIN: {},
                 logbook.DOMAIN: {
-                    logbook.CONF_EXCLUDE: {
-                        logbook.CONF_DOMAINS: ["switch", "alexa", DOMAIN_HOMEKIT]
-                    }
+                    logbook.CONF_EXCLUDE: {logbook.CONF_DOMAINS: ["switch", "alexa"]}
                 },
             }
         )
@@ -299,7 +290,6 @@ class TestComponentLogbook(unittest.TestCase):
             for e in (
                 ha.Event(EVENT_HOMEASSISTANT_START),
                 ha.Event(EVENT_ALEXA_SMART_HOME),
-                ha.Event(EVENT_HOMEKIT_CHANGED),
                 eventA,
                 eventB,
             )
@@ -439,14 +429,6 @@ class TestComponentLogbook(unittest.TestCase):
             EVENT_ALEXA_SMART_HOME,
             {"request": {"namespace": "Alexa.Discovery", "name": "Discover"}},
         )
-        event_homekit = ha.Event(
-            EVENT_HOMEKIT_CHANGED,
-            {
-                ATTR_ENTITY_ID: "lock.front_door",
-                ATTR_DISPLAY_NAME: "Front Door",
-                ATTR_SERVICE: "lock",
-            },
-        )
 
         eventA = self.create_state_changed_event(pointA, entity_id, 10)
         eventB = self.create_state_changed_event(pointB, entity_id2, 20)
@@ -455,34 +437,25 @@ class TestComponentLogbook(unittest.TestCase):
             {
                 ha.DOMAIN: {},
                 logbook.DOMAIN: {
-                    logbook.CONF_INCLUDE: {
-                        logbook.CONF_DOMAINS: ["sensor", "alexa", DOMAIN_HOMEKIT]
-                    }
+                    logbook.CONF_INCLUDE: {logbook.CONF_DOMAINS: ["sensor", "alexa"]}
                 },
             }
         )
         entities_filter = logbook._generate_filter_from_config(config[logbook.DOMAIN])
         events = [
             e
-            for e in (
-                ha.Event(EVENT_HOMEASSISTANT_START),
-                event_alexa,
-                event_homekit,
-                eventA,
-                eventB,
-            )
+            for e in (ha.Event(EVENT_HOMEASSISTANT_START), event_alexa, eventA, eventB,)
             if logbook._keep_event(self.hass, e, entities_filter)
         ]
         entries = list(logbook.humanify(self.hass, events))
 
-        assert len(entries) == 4
+        assert len(entries) == 3
         self.assert_entry(
             entries[0], name="Home Assistant", message="started", domain=ha.DOMAIN
         )
         self.assert_entry(entries[1], name="Amazon Alexa", domain="alexa")
-        self.assert_entry(entries[2], name="HomeKit", domain=DOMAIN_HOMEKIT)
         self.assert_entry(
-            entries[3], pointB, "blu", domain="sensor", entity_id=entity_id2
+            entries[2], pointB, "blu", domain="sensor", entity_id=entity_id2
         )
 
     def test_include_exclude_events(self):
@@ -1362,44 +1335,6 @@ async def test_logbook_view_period_entity(hass, hass_client):
     assert json[0]["entity_id"] == entity_id_test
 
 
-async def test_humanify_homekit_changed_event(hass):
-    """Test humanifying HomeKit changed event."""
-    event1, event2 = list(
-        logbook.humanify(
-            hass,
-            [
-                ha.Event(
-                    EVENT_HOMEKIT_CHANGED,
-                    {
-                        ATTR_ENTITY_ID: "lock.front_door",
-                        ATTR_DISPLAY_NAME: "Front Door",
-                        ATTR_SERVICE: "lock",
-                    },
-                ),
-                ha.Event(
-                    EVENT_HOMEKIT_CHANGED,
-                    {
-                        ATTR_ENTITY_ID: "cover.window",
-                        ATTR_DISPLAY_NAME: "Window",
-                        ATTR_SERVICE: "set_cover_position",
-                        ATTR_VALUE: 75,
-                    },
-                ),
-            ],
-        )
-    )
-
-    assert event1["name"] == "HomeKit"
-    assert event1["domain"] == DOMAIN_HOMEKIT
-    assert event1["message"] == "send command lock for Front Door"
-    assert event1["entity_id"] == "lock.front_door"
-
-    assert event2["name"] == "HomeKit"
-    assert event2["domain"] == DOMAIN_HOMEKIT
-    assert event2["message"] == "send command set_cover_position to 75 for Window"
-    assert event2["entity_id"] == "cover.window"
-
-
 async def test_humanify_automation_triggered_event(hass):
     """Test humanifying Automation Trigger event."""
     event1, event2 = list(
-- 
GitLab