Google Assistant SDK: Allow responses for send_text_command (#95966)
google_assistant_sdk.send_text_command response
This commit is contained in:
parent
79991c32dc
commit
bdaa2285fc
3 changed files with 47 additions and 12 deletions
|
@ -1,6 +1,8 @@
|
|||
"""Support for Google Assistant SDK."""
|
||||
from __future__ import annotations
|
||||
|
||||
import dataclasses
|
||||
|
||||
import aiohttp
|
||||
from gassist_text import TextAssistant
|
||||
from google.oauth2.credentials import Credentials
|
||||
|
@ -9,7 +11,12 @@ import voluptuous as vol
|
|||
from homeassistant.components import conversation
|
||||
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
|
||||
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_NAME, Platform
|
||||
from homeassistant.core import HomeAssistant, ServiceCall
|
||||
from homeassistant.core import (
|
||||
HomeAssistant,
|
||||
ServiceCall,
|
||||
ServiceResponse,
|
||||
SupportsResponse,
|
||||
)
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||
from homeassistant.helpers import config_validation as cv, discovery, intent
|
||||
from homeassistant.helpers.config_entry_oauth2_flow import (
|
||||
|
@ -101,19 +108,30 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
async def async_setup_service(hass: HomeAssistant) -> None:
|
||||
"""Add the services for Google Assistant SDK."""
|
||||
|
||||
async def send_text_command(call: ServiceCall) -> None:
|
||||
async def send_text_command(call: ServiceCall) -> ServiceResponse:
|
||||
"""Send a text command to Google Assistant SDK."""
|
||||
commands: list[str] = call.data[SERVICE_SEND_TEXT_COMMAND_FIELD_COMMAND]
|
||||
media_players: list[str] | None = call.data.get(
|
||||
SERVICE_SEND_TEXT_COMMAND_FIELD_MEDIA_PLAYER
|
||||
)
|
||||
await async_send_text_commands(hass, commands, media_players)
|
||||
command_response_list = await async_send_text_commands(
|
||||
hass, commands, media_players
|
||||
)
|
||||
if call.return_response:
|
||||
return {
|
||||
"responses": [
|
||||
dataclasses.asdict(command_response)
|
||||
for command_response in command_response_list
|
||||
]
|
||||
}
|
||||
return None
|
||||
|
||||
hass.services.async_register(
|
||||
DOMAIN,
|
||||
SERVICE_SEND_TEXT_COMMAND,
|
||||
send_text_command,
|
||||
schema=SERVICE_SEND_TEXT_COMMAND_SCHEMA,
|
||||
supports_response=SupportsResponse.OPTIONAL,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Helper classes for Google Assistant SDK integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from http import HTTPStatus
|
||||
import logging
|
||||
from typing import Any
|
||||
|
@ -48,9 +49,16 @@ DEFAULT_LANGUAGE_CODES = {
|
|||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommandResponse:
|
||||
"""Response from a single command to Google Assistant Service."""
|
||||
|
||||
text: str
|
||||
|
||||
|
||||
async def async_send_text_commands(
|
||||
hass: HomeAssistant, commands: list[str], media_players: list[str] | None = None
|
||||
) -> None:
|
||||
) -> list[CommandResponse]:
|
||||
"""Send text commands to Google Assistant Service."""
|
||||
# There can only be 1 entry (config_flow has single_instance_allowed)
|
||||
entry: ConfigEntry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
|
@ -68,6 +76,7 @@ async def async_send_text_commands(
|
|||
with TextAssistant(
|
||||
credentials, language_code, audio_out=bool(media_players)
|
||||
) as assistant:
|
||||
command_response_list = []
|
||||
for command in commands:
|
||||
resp = assistant.assist(command)
|
||||
text_response = resp[0]
|
||||
|
@ -91,6 +100,8 @@ async def async_send_text_commands(
|
|||
},
|
||||
blocking=True,
|
||||
)
|
||||
command_response_list.append(CommandResponse(text_response))
|
||||
return command_response_list
|
||||
|
||||
|
||||
def default_language_code(hass: HomeAssistant):
|
||||
|
|
|
@ -162,20 +162,26 @@ async def test_send_text_commands(
|
|||
|
||||
command1 = "open the garage door"
|
||||
command2 = "1234"
|
||||
command1_response = "what's the PIN?"
|
||||
command2_response = "opened the garage door"
|
||||
with patch(
|
||||
"homeassistant.components.google_assistant_sdk.helpers.TextAssistant"
|
||||
) as mock_text_assistant:
|
||||
await hass.services.async_call(
|
||||
"homeassistant.components.google_assistant_sdk.helpers.TextAssistant.assist",
|
||||
side_effect=[
|
||||
(command1_response, None, None),
|
||||
(command2_response, None, None),
|
||||
],
|
||||
) as mock_assist_call:
|
||||
response = await hass.services.async_call(
|
||||
DOMAIN,
|
||||
"send_text_command",
|
||||
{"command": [command1, command2]},
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
mock_text_assistant.assert_called_once_with(
|
||||
ExpectedCredentials(), "en-US", audio_out=False
|
||||
)
|
||||
mock_text_assistant.assert_has_calls([call().__enter__().assist(command1)])
|
||||
mock_text_assistant.assert_has_calls([call().__enter__().assist(command2)])
|
||||
assert response == {
|
||||
"responses": [{"text": command1_response}, {"text": command2_response}]
|
||||
}
|
||||
mock_assist_call.assert_has_calls([call(command1), call(command2)])
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue