mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
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
@ -1,6 +1,8 @@
|
|||||||
"""Support for Google Assistant SDK."""
|
"""Support for Google Assistant SDK."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import dataclasses
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from gassist_text import TextAssistant
|
from gassist_text import TextAssistant
|
||||||
from google.oauth2.credentials import Credentials
|
from google.oauth2.credentials import Credentials
|
||||||
@ -9,7 +11,12 @@ import voluptuous as vol
|
|||||||
from homeassistant.components import conversation
|
from homeassistant.components import conversation
|
||||||
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
|
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
|
||||||
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_NAME, Platform
|
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.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||||
from homeassistant.helpers import config_validation as cv, discovery, intent
|
from homeassistant.helpers import config_validation as cv, discovery, intent
|
||||||
from homeassistant.helpers.config_entry_oauth2_flow import (
|
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:
|
async def async_setup_service(hass: HomeAssistant) -> None:
|
||||||
"""Add the services for Google Assistant SDK."""
|
"""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."""
|
"""Send a text command to Google Assistant SDK."""
|
||||||
commands: list[str] = call.data[SERVICE_SEND_TEXT_COMMAND_FIELD_COMMAND]
|
commands: list[str] = call.data[SERVICE_SEND_TEXT_COMMAND_FIELD_COMMAND]
|
||||||
media_players: list[str] | None = call.data.get(
|
media_players: list[str] | None = call.data.get(
|
||||||
SERVICE_SEND_TEXT_COMMAND_FIELD_MEDIA_PLAYER
|
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(
|
hass.services.async_register(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
SERVICE_SEND_TEXT_COMMAND,
|
SERVICE_SEND_TEXT_COMMAND,
|
||||||
send_text_command,
|
send_text_command,
|
||||||
schema=SERVICE_SEND_TEXT_COMMAND_SCHEMA,
|
schema=SERVICE_SEND_TEXT_COMMAND_SCHEMA,
|
||||||
|
supports_response=SupportsResponse.OPTIONAL,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"""Helper classes for Google Assistant SDK integration."""
|
"""Helper classes for Google Assistant SDK integration."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
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(
|
async def async_send_text_commands(
|
||||||
hass: HomeAssistant, commands: list[str], media_players: list[str] | None = None
|
hass: HomeAssistant, commands: list[str], media_players: list[str] | None = None
|
||||||
) -> None:
|
) -> list[CommandResponse]:
|
||||||
"""Send text commands to Google Assistant Service."""
|
"""Send text commands to Google Assistant Service."""
|
||||||
# There can only be 1 entry (config_flow has single_instance_allowed)
|
# There can only be 1 entry (config_flow has single_instance_allowed)
|
||||||
entry: ConfigEntry = hass.config_entries.async_entries(DOMAIN)[0]
|
entry: ConfigEntry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||||
@ -68,6 +76,7 @@ async def async_send_text_commands(
|
|||||||
with TextAssistant(
|
with TextAssistant(
|
||||||
credentials, language_code, audio_out=bool(media_players)
|
credentials, language_code, audio_out=bool(media_players)
|
||||||
) as assistant:
|
) as assistant:
|
||||||
|
command_response_list = []
|
||||||
for command in commands:
|
for command in commands:
|
||||||
resp = assistant.assist(command)
|
resp = assistant.assist(command)
|
||||||
text_response = resp[0]
|
text_response = resp[0]
|
||||||
@ -91,6 +100,8 @@ async def async_send_text_commands(
|
|||||||
},
|
},
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
|
command_response_list.append(CommandResponse(text_response))
|
||||||
|
return command_response_list
|
||||||
|
|
||||||
|
|
||||||
def default_language_code(hass: HomeAssistant):
|
def default_language_code(hass: HomeAssistant):
|
||||||
|
@ -162,20 +162,26 @@ async def test_send_text_commands(
|
|||||||
|
|
||||||
command1 = "open the garage door"
|
command1 = "open the garage door"
|
||||||
command2 = "1234"
|
command2 = "1234"
|
||||||
|
command1_response = "what's the PIN?"
|
||||||
|
command2_response = "opened the garage door"
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.google_assistant_sdk.helpers.TextAssistant"
|
"homeassistant.components.google_assistant_sdk.helpers.TextAssistant.assist",
|
||||||
) as mock_text_assistant:
|
side_effect=[
|
||||||
await hass.services.async_call(
|
(command1_response, None, None),
|
||||||
|
(command2_response, None, None),
|
||||||
|
],
|
||||||
|
) as mock_assist_call:
|
||||||
|
response = await hass.services.async_call(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
"send_text_command",
|
"send_text_command",
|
||||||
{"command": [command1, command2]},
|
{"command": [command1, command2]},
|
||||||
blocking=True,
|
blocking=True,
|
||||||
|
return_response=True,
|
||||||
)
|
)
|
||||||
mock_text_assistant.assert_called_once_with(
|
assert response == {
|
||||||
ExpectedCredentials(), "en-US", audio_out=False
|
"responses": [{"text": command1_response}, {"text": command2_response}]
|
||||||
)
|
}
|
||||||
mock_text_assistant.assert_has_calls([call().__enter__().assist(command1)])
|
mock_assist_call.assert_has_calls([call(command1), call(command2)])
|
||||||
mock_text_assistant.assert_has_calls([call().__enter__().assist(command2)])
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user