Migrate HomeKit to use describe_event for logbook support (#34485)

This commit is contained in:
Paulus Schoutsen 2020-04-20 17:48:09 -07:00 committed by GitHub
parent 95357dfc55
commit 19be31d13a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 87 additions and 101 deletions

View file

@ -11,6 +11,7 @@ from homeassistant.components.media_player import DEVICE_CLASS_TV
from homeassistant.const import ( from homeassistant.const import (
ATTR_DEVICE_CLASS, ATTR_DEVICE_CLASS,
ATTR_ENTITY_ID, ATTR_ENTITY_ID,
ATTR_SERVICE,
ATTR_SUPPORTED_FEATURES, ATTR_SUPPORTED_FEATURES,
ATTR_UNIT_OF_MEASUREMENT, ATTR_UNIT_OF_MEASUREMENT,
CONF_IP_ADDRESS, CONF_IP_ADDRESS,
@ -26,6 +27,7 @@ from homeassistant.const import (
TEMP_FAHRENHEIT, TEMP_FAHRENHEIT,
UNIT_PERCENTAGE, UNIT_PERCENTAGE,
) )
from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entityfilter import FILTER_SCHEMA from homeassistant.helpers.entityfilter import FILTER_SCHEMA
from homeassistant.util import get_local_ip from homeassistant.util import get_local_ip
@ -34,6 +36,8 @@ from homeassistant.util.decorator import Registry
from .aidmanager import AccessoryAidStorage from .aidmanager import AccessoryAidStorage
from .const import ( from .const import (
AID_STORAGE, AID_STORAGE,
ATTR_DISPLAY_NAME,
ATTR_VALUE,
BRIDGE_NAME, BRIDGE_NAME,
CONF_ADVERTISE_IP, CONF_ADVERTISE_IP,
CONF_AUTO_START, CONF_AUTO_START,
@ -50,6 +54,7 @@ from .const import (
DEVICE_CLASS_CO2, DEVICE_CLASS_CO2,
DEVICE_CLASS_PM25, DEVICE_CLASS_PM25,
DOMAIN, DOMAIN,
EVENT_HOMEKIT_CHANGED,
HOMEKIT_FILE, HOMEKIT_FILE,
SERVICE_HOMEKIT_RESET_ACCESSORY, SERVICE_HOMEKIT_RESET_ACCESSORY,
SERVICE_HOMEKIT_START, SERVICE_HOMEKIT_START,
@ -169,6 +174,26 @@ async def async_setup(hass, config):
schema=RESET_ACCESSORY_SERVICE_SCHEMA, 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: if auto_start:
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, homekit.start) hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, homekit.start)
return True return True

View file

@ -2,6 +2,7 @@
"domain": "homekit", "domain": "homekit",
"name": "HomeKit", "name": "HomeKit",
"documentation": "https://www.home-assistant.io/integrations/homekit", "documentation": "https://www.home-assistant.io/integrations/homekit",
"requirements": ["HAP-python==2.8.2","fnvhash==0.1.0"], "requirements": ["HAP-python==2.8.2", "fnvhash==0.1.0"],
"codeowners": ["@bdraco"] "codeowners": ["@bdraco"],
"after_dependencies": ["logbook"]
} }

View file

@ -8,12 +8,6 @@ from sqlalchemy.exc import SQLAlchemyError
import voluptuous as vol import voluptuous as vol
from homeassistant.components import sun 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.http import HomeAssistantView
from homeassistant.components.recorder.models import Events, States from homeassistant.components.recorder.models import Events, States
from homeassistant.components.recorder.util import ( from homeassistant.components.recorder.util import (
@ -26,7 +20,6 @@ from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_ENTITY_ID,
ATTR_HIDDEN, ATTR_HIDDEN,
ATTR_NAME, ATTR_NAME,
ATTR_SERVICE,
CONF_EXCLUDE, CONF_EXCLUDE,
CONF_INCLUDE, CONF_INCLUDE,
EVENT_AUTOMATION_TRIGGERED, EVENT_AUTOMATION_TRIGGERED,
@ -89,7 +82,6 @@ ALL_EVENT_TYPES = [
EVENT_LOGBOOK_ENTRY, EVENT_LOGBOOK_ENTRY,
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_START,
EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_STOP,
EVENT_HOMEKIT_CHANGED,
EVENT_AUTOMATION_TRIGGERED, EVENT_AUTOMATION_TRIGGERED,
EVENT_SCRIPT_STARTED, EVENT_SCRIPT_STARTED,
] ]
@ -324,24 +316,6 @@ def humanify(hass, events):
"context_user_id": event.context.user_id, "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: elif event.event_type == EVENT_AUTOMATION_TRIGGERED:
yield { yield {
"when": event.time_fired, "when": event.time_fired,
@ -498,9 +472,6 @@ def _keep_event(hass, event, entities_filter):
elif event.event_type in hass.data.get(DOMAIN, {}): elif event.event_type in hass.data.get(DOMAIN, {}):
domain = hass.data[DOMAIN][event.event_type][0] domain = hass.data[DOMAIN][event.event_type][0]
elif event.event_type == EVENT_HOMEKIT_CHANGED:
domain = DOMAIN_HOMEKIT
if not entity_id and domain: if not entity_id and domain:
entity_id = f"{domain}." entity_id = f"{domain}."

View file

@ -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"

View file

@ -11,17 +11,10 @@ import voluptuous as vol
from homeassistant.components import logbook, recorder, sun from homeassistant.components import logbook, recorder, sun
from homeassistant.components.alexa.smart_home import EVENT_ALEXA_SMART_HOME 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 ( from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_ENTITY_ID,
ATTR_HIDDEN, ATTR_HIDDEN,
ATTR_NAME, ATTR_NAME,
ATTR_SERVICE,
EVENT_AUTOMATION_TRIGGERED, EVENT_AUTOMATION_TRIGGERED,
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_START,
EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_STOP,
@ -287,9 +280,7 @@ class TestComponentLogbook(unittest.TestCase):
{ {
ha.DOMAIN: {}, ha.DOMAIN: {},
logbook.DOMAIN: { logbook.DOMAIN: {
logbook.CONF_EXCLUDE: { logbook.CONF_EXCLUDE: {logbook.CONF_DOMAINS: ["switch", "alexa"]}
logbook.CONF_DOMAINS: ["switch", "alexa", DOMAIN_HOMEKIT]
}
}, },
} }
) )
@ -299,7 +290,6 @@ class TestComponentLogbook(unittest.TestCase):
for e in ( for e in (
ha.Event(EVENT_HOMEASSISTANT_START), ha.Event(EVENT_HOMEASSISTANT_START),
ha.Event(EVENT_ALEXA_SMART_HOME), ha.Event(EVENT_ALEXA_SMART_HOME),
ha.Event(EVENT_HOMEKIT_CHANGED),
eventA, eventA,
eventB, eventB,
) )
@ -439,14 +429,6 @@ class TestComponentLogbook(unittest.TestCase):
EVENT_ALEXA_SMART_HOME, EVENT_ALEXA_SMART_HOME,
{"request": {"namespace": "Alexa.Discovery", "name": "Discover"}}, {"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) eventA = self.create_state_changed_event(pointA, entity_id, 10)
eventB = self.create_state_changed_event(pointB, entity_id2, 20) eventB = self.create_state_changed_event(pointB, entity_id2, 20)
@ -455,34 +437,25 @@ class TestComponentLogbook(unittest.TestCase):
{ {
ha.DOMAIN: {}, ha.DOMAIN: {},
logbook.DOMAIN: { logbook.DOMAIN: {
logbook.CONF_INCLUDE: { logbook.CONF_INCLUDE: {logbook.CONF_DOMAINS: ["sensor", "alexa"]}
logbook.CONF_DOMAINS: ["sensor", "alexa", DOMAIN_HOMEKIT]
}
}, },
} }
) )
entities_filter = logbook._generate_filter_from_config(config[logbook.DOMAIN]) entities_filter = logbook._generate_filter_from_config(config[logbook.DOMAIN])
events = [ events = [
e e
for e in ( for e in (ha.Event(EVENT_HOMEASSISTANT_START), event_alexa, eventA, eventB,)
ha.Event(EVENT_HOMEASSISTANT_START),
event_alexa,
event_homekit,
eventA,
eventB,
)
if logbook._keep_event(self.hass, e, entities_filter) if logbook._keep_event(self.hass, e, entities_filter)
] ]
entries = list(logbook.humanify(self.hass, events)) entries = list(logbook.humanify(self.hass, events))
assert len(entries) == 4 assert len(entries) == 3
self.assert_entry( self.assert_entry(
entries[0], name="Home Assistant", message="started", domain=ha.DOMAIN entries[0], name="Home Assistant", message="started", domain=ha.DOMAIN
) )
self.assert_entry(entries[1], name="Amazon Alexa", domain="alexa") self.assert_entry(entries[1], name="Amazon Alexa", domain="alexa")
self.assert_entry(entries[2], name="HomeKit", domain=DOMAIN_HOMEKIT)
self.assert_entry( 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): 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 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): async def test_humanify_automation_triggered_event(hass):
"""Test humanifying Automation Trigger event.""" """Test humanifying Automation Trigger event."""
event1, event2 = list( event1, event2 = list(