Describe Google Assistant events (#49141)

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
Paulus Schoutsen 2021-04-13 09:31:01 -07:00 committed by GitHub
parent 926c2489f0
commit 05aeff5591
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 137 additions and 7 deletions

View File

@ -17,10 +17,10 @@ def async_describe_events(hass, async_describe_event):
if entity_id:
state = hass.states.get(entity_id)
name = state.name if state else entity_id
message = f"send command {data['request']['namespace']}/{data['request']['name']} for {name}"
message = f"sent command {data['request']['namespace']}/{data['request']['name']} for {name}"
else:
message = (
f"send command {data['request']['namespace']}/{data['request']['name']}"
f"sent command {data['request']['namespace']}/{data['request']['name']}"
)
return {"name": "Amazon Alexa", "message": message, "entity_id": entity_id}

View File

@ -5,10 +5,12 @@ import logging
from hass_nabucasa import Cloud, cloud_api
from hass_nabucasa.google_report_state import ErrorResponse
from homeassistant.components.google_assistant.const import DOMAIN as GOOGLE_DOMAIN
from homeassistant.components.google_assistant.helpers import AbstractConfig
from homeassistant.const import CLOUD_NEVER_EXPOSED_ENTITIES, HTTP_OK
from homeassistant.core import CoreState, split_entity_id
from homeassistant.helpers import entity_registry
from homeassistant.setup import async_setup_component
from .const import (
CONF_ENTITY_CONFIG,
@ -84,6 +86,9 @@ class CloudGoogleConfig(AbstractConfig):
"""Perform async initialization of config."""
await super().async_initialize()
if self.enabled and GOOGLE_DOMAIN not in self.hass.config.components:
await async_setup_component(self.hass, GOOGLE_DOMAIN, {})
# Remove old/wrong user agent ids
remove_agent_user_ids = []
for agent_user_id in self._store.agent_user_ids:
@ -164,6 +169,9 @@ class CloudGoogleConfig(AbstractConfig):
async def _async_prefs_updated(self, prefs):
"""Handle updated preferences."""
if self.enabled and GOOGLE_DOMAIN not in self.hass.config.components:
await async_setup_component(self.hass, GOOGLE_DOMAIN, {})
if self.should_report_state != self.is_reporting_state:
if self.should_report_state:
self.async_enable_report_state()

View File

@ -86,12 +86,17 @@ GOOGLE_ASSISTANT_SCHEMA = vol.All(
_check_report_state,
)
CONFIG_SCHEMA = vol.Schema({DOMAIN: GOOGLE_ASSISTANT_SCHEMA}, extra=vol.ALLOW_EXTRA)
CONFIG_SCHEMA = vol.Schema(
{vol.Optional(DOMAIN): GOOGLE_ASSISTANT_SCHEMA}, extra=vol.ALLOW_EXTRA
)
async def async_setup(hass: HomeAssistant, yaml_config: dict[str, Any]):
"""Activate Google Actions component."""
config = yaml_config.get(DOMAIN, {})
if DOMAIN not in yaml_config:
return True
config = yaml_config[DOMAIN]
google_config = GoogleConfig(hass, config)
await google_config.async_initialize()

View File

@ -0,0 +1,29 @@
"""Describe logbook events."""
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import callback
from .const import DOMAIN, EVENT_COMMAND_RECEIVED
COMMON_COMMAND_PREFIX = "action.devices.commands."
@callback
def async_describe_events(hass, async_describe_event):
"""Describe logbook events."""
@callback
def async_describe_logbook_event(event):
"""Describe a logbook event."""
entity_id = event.data[ATTR_ENTITY_ID]
state = hass.states.get(entity_id)
name = state.name if state else entity_id
command = event.data["execution"]["command"]
if command.startswith(COMMON_COMMAND_PREFIX):
command = command[len(COMMON_COMMAND_PREFIX) :]
message = f"sent command {command} for {name} (via {event.data['source']})"
return {"name": "Google Assistant", "message": message, "entity_id": entity_id}
async_describe_event(DOMAIN, EVENT_COMMAND_RECEIVED, async_describe_logbook_event)

View File

@ -51,19 +51,19 @@ async def test_humanify_alexa_event(hass):
event1, event2, event3 = results
assert event1["name"] == "Amazon Alexa"
assert event1["message"] == "send command Alexa.Discovery/Discover"
assert event1["message"] == "sent command Alexa.Discovery/Discover"
assert event1["entity_id"] is None
assert event2["name"] == "Amazon Alexa"
assert (
event2["message"]
== "send command Alexa.PowerController/TurnOn for Kitchen Light"
== "sent command Alexa.PowerController/TurnOn for Kitchen Light"
)
assert event2["entity_id"] == "light.kitchen"
assert event3["name"] == "Amazon Alexa"
assert (
event3["message"]
== "send command Alexa.PowerController/TurnOn for light.non_existing"
== "sent command Alexa.PowerController/TurnOn for light.non_existing"
)
assert event3["entity_id"] == "light.non_existing"

View File

@ -225,3 +225,19 @@ def test_enabled_requires_valid_sub(hass, mock_expired_cloud_login, cloud_prefs)
)
assert not config.enabled
async def test_setup_integration(hass, mock_conf, cloud_prefs):
"""Test that we set up the integration if used."""
mock_conf._cloud.subscription_expired = False
assert "google_assistant" not in hass.config.components
await mock_conf.async_initialize()
assert "google_assistant" in hass.config.components
hass.config.components.remove("google_assistant")
await cloud_prefs.async_update()
await hass.async_block_till_done()
assert "google_assistant" in hass.config.components

View File

@ -0,0 +1,72 @@
"""The tests for Google Assistant logbook."""
from homeassistant.components import logbook
from homeassistant.components.google_assistant.const import (
DOMAIN,
EVENT_COMMAND_RECEIVED,
SOURCE_CLOUD,
SOURCE_LOCAL,
)
from homeassistant.const import ATTR_ENTITY_ID, ATTR_FRIENDLY_NAME
from homeassistant.setup import async_setup_component
from tests.components.logbook.test_init import MockLazyEventPartialState
async def test_humanify_command_received(hass):
"""Test humanifying command event."""
hass.config.components.add("recorder")
hass.config.components.add("frontend")
hass.config.components.add("google_assistant")
assert await async_setup_component(hass, "logbook", {})
entity_attr_cache = logbook.EntityAttributeCache(hass)
hass.states.async_set(
"light.kitchen", "on", {ATTR_FRIENDLY_NAME: "The Kitchen Lights"}
)
events = list(
logbook.humanify(
hass,
[
MockLazyEventPartialState(
EVENT_COMMAND_RECEIVED,
{
"request_id": "abcd",
ATTR_ENTITY_ID: "light.kitchen",
"execution": {
"command": "action.devices.commands.OnOff",
"params": {"on": True},
},
"source": SOURCE_LOCAL,
},
),
MockLazyEventPartialState(
EVENT_COMMAND_RECEIVED,
{
"request_id": "abcd",
ATTR_ENTITY_ID: "light.non_existing",
"execution": {
"command": "action.devices.commands.OnOff",
"params": {"on": False},
},
"source": SOURCE_CLOUD,
},
),
],
entity_attr_cache,
{},
)
)
assert len(events) == 2
event1, event2 = events
assert event1["name"] == "Google Assistant"
assert event1["domain"] == DOMAIN
assert event1["message"] == "sent command OnOff for The Kitchen Lights (via local)"
assert event1["entity_id"] == "light.kitchen"
assert event2["name"] == "Google Assistant"
assert event2["domain"] == DOMAIN
assert event2["message"] == "sent command OnOff for light.non_existing (via cloud)"
assert event2["entity_id"] == "light.non_existing"