Google Assistant SDK: support Korean and Japanese (#85419)

* Google Assistant SDK: support Korean and Japanese

* Fix Korean and Japanese broadcast commands
This commit is contained in:
tronikos 2023-01-08 17:16:00 -08:00 committed by GitHub
parent 7bdfa7b9ec
commit 05187d7bf4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 40 deletions

View File

@ -20,5 +20,7 @@ SUPPORTED_LANGUAGE_CODES: Final = [
"fr-CA", "fr-CA",
"fr-FR", "fr-FR",
"it-IT", "it-IT",
"ja-JP",
"ko-KR",
"pt-BR", "pt-BR",
] ]

View File

@ -22,6 +22,8 @@ DEFAULT_LANGUAGE_CODES = {
"es": "es-ES", "es": "es-ES",
"fr": "fr-FR", "fr": "fr-FR",
"it": "it-IT", "it": "it-IT",
"ja": "ja-JP",
"ko": "ko-KR",
"pt": "pt-BR", "pt": "pt-BR",
} }

View File

@ -13,12 +13,14 @@ from .helpers import async_send_text_commands, default_language_code
# https://support.google.com/assistant/answer/9071582?hl=en # https://support.google.com/assistant/answer/9071582?hl=en
LANG_TO_BROADCAST_COMMAND = { LANG_TO_BROADCAST_COMMAND = {
"en": ("broadcast", "broadcast to"), "en": ("broadcast {0}", "broadcast to {1} {0}"),
"de": ("Nachricht an alle", "Nachricht an alle an"), "de": ("Nachricht an alle {0}", "Nachricht an alle an {1} {0}"),
"es": ("Anuncia", "Anuncia en"), "es": ("Anuncia {0}", "Anuncia en {1} {0}"),
"fr": ("Diffuse", "Diffuse dans"), "fr": ("Diffuse {0}", "Diffuse dans {1} {0}"),
"it": ("Trasmetti", "Trasmetti in"), "it": ("Trasmetti {0}", "Trasmetti in {1} {0}"),
"pt": ("Transmite", "Transmite para"), "ja": ("{0}とほうそうして", "{0}{1}にブロードキャストして"),
"ko": ("{0} 라고 방송해 줘", "{0} 라고 {1}에 방송해 줘"),
"pt": ("Transmite {0}", "Transmite para {1} {0}"),
} }
@ -62,10 +64,10 @@ class BroadcastNotificationService(BaseNotificationService):
commands = [] commands = []
targets = kwargs.get(ATTR_TARGET) targets = kwargs.get(ATTR_TARGET)
if not targets: if not targets:
commands.append(f"{broadcast_commands(language_code)[0]} {message}") commands.append(broadcast_commands(language_code)[0].format(message))
else: else:
for target in targets: for target in targets:
commands.append( commands.append(
f"{broadcast_commands(language_code)[1]} {target} {message}" broadcast_commands(language_code)[1].format(message, target)
) )
await async_send_text_commands(commands, self.hass) await async_send_text_commands(commands, self.hass)

View File

@ -1,6 +1,8 @@
"""Tests for the Google Assistant notify.""" """Tests for the Google Assistant notify."""
from unittest.mock import call, patch from unittest.mock import call, patch
import pytest
from homeassistant.components import notify from homeassistant.components import notify
from homeassistant.components.google_assistant_sdk import DOMAIN from homeassistant.components.google_assistant_sdk import DOMAIN
from homeassistant.components.google_assistant_sdk.const import SUPPORTED_LANGUAGE_CODES from homeassistant.components.google_assistant_sdk.const import SUPPORTED_LANGUAGE_CODES
@ -10,14 +12,29 @@ from homeassistant.core import HomeAssistant
from .conftest import ComponentSetup, ExpectedCredentials from .conftest import ComponentSetup, ExpectedCredentials
@pytest.mark.parametrize(
"language_code,message,expected_command",
[
("en-US", "Dinner is served", "broadcast Dinner is served"),
("es-ES", "La cena está en la mesa", "Anuncia La cena está en la mesa"),
("ko-KR", "저녁 식사가 준비됐어요", "저녁 식사가 준비됐어요 라고 방송해 줘"),
("ja-JP", "晩ご飯できたよ", "晩ご飯できたよとほうそうして"),
],
ids=["english", "spanish", "korean", "japanese"],
)
async def test_broadcast_no_targets( async def test_broadcast_no_targets(
hass: HomeAssistant, setup_integration: ComponentSetup hass: HomeAssistant,
setup_integration: ComponentSetup,
language_code: str,
message: str,
expected_command: str,
) -> None: ) -> None:
"""Test broadcast to all.""" """Test broadcast to all."""
await setup_integration() await setup_integration()
message = "time for dinner" entry = hass.config_entries.async_entries(DOMAIN)[0]
expected_command = "broadcast time for dinner" entry.options = {"language_code": language_code}
with patch( with patch(
"homeassistant.components.google_assistant_sdk.helpers.TextAssistant" "homeassistant.components.google_assistant_sdk.helpers.TextAssistant"
) as mock_text_assistant: ) as mock_text_assistant:
@ -27,19 +44,44 @@ async def test_broadcast_no_targets(
{notify.ATTR_MESSAGE: message}, {notify.ATTR_MESSAGE: message},
) )
await hass.async_block_till_done() await hass.async_block_till_done()
mock_text_assistant.assert_called_once_with(ExpectedCredentials(), "en-US") mock_text_assistant.assert_called_once_with(ExpectedCredentials(), language_code)
mock_text_assistant.assert_has_calls([call().__enter__().assist(expected_command)]) mock_text_assistant.assert_has_calls([call().__enter__().assist(expected_command)])
@pytest.mark.parametrize(
"language_code,message,target,expected_command",
[
(
"en-US",
"it's time for homework",
"living room",
"broadcast to living room it's time for homework",
),
(
"es-ES",
"Es hora de hacer los deberes",
"el salón",
"Anuncia en el salón Es hora de hacer los deberes",
),
("ko-KR", "숙제할 시간이야", "거실", "숙제할 시간이야 라고 거실에 방송해 줘"),
("ja-JP", "宿題の時間だよ", "リビング", "宿題の時間だよとリビングにブロードキャストして"),
],
ids=["english", "spanish", "korean", "japanese"],
)
async def test_broadcast_one_target( async def test_broadcast_one_target(
hass: HomeAssistant, setup_integration: ComponentSetup hass: HomeAssistant,
setup_integration: ComponentSetup,
language_code: str,
message: str,
target: str,
expected_command: str,
) -> None: ) -> None:
"""Test broadcast to one target.""" """Test broadcast to one target."""
await setup_integration() await setup_integration()
message = "time for dinner" entry = hass.config_entries.async_entries(DOMAIN)[0]
target = "basement" entry.options = {"language_code": language_code}
expected_command = "broadcast to basement time for dinner"
with patch( with patch(
"homeassistant.components.google_assistant_sdk.helpers.TextAssistant.assist", "homeassistant.components.google_assistant_sdk.helpers.TextAssistant.assist",
return_value=["text_response", None], return_value=["text_response", None],
@ -98,30 +140,6 @@ async def test_broadcast_empty_message(
mock_assist_call.assert_not_called() mock_assist_call.assert_not_called()
async def test_broadcast_spanish(
hass: HomeAssistant, setup_integration: ComponentSetup
) -> None:
"""Test broadcast in Spanish."""
await setup_integration()
entry = hass.config_entries.async_entries(DOMAIN)[0]
entry.options = {"language_code": "es-ES"}
message = "comida"
expected_command = "Anuncia comida"
with patch(
"homeassistant.components.google_assistant_sdk.helpers.TextAssistant"
) as mock_text_assistant:
await hass.services.async_call(
notify.DOMAIN,
DOMAIN,
{notify.ATTR_MESSAGE: message},
)
await hass.async_block_till_done()
mock_text_assistant.assert_called_once_with(ExpectedCredentials(), "es-ES")
mock_text_assistant.assert_has_calls([call().__enter__().assist(expected_command)])
def test_broadcast_language_mapping( def test_broadcast_language_mapping(
hass: HomeAssistant, setup_integration: ComponentSetup hass: HomeAssistant, setup_integration: ComponentSetup
) -> None: ) -> None:
@ -131,4 +149,8 @@ def test_broadcast_language_mapping(
assert cmds assert cmds
assert len(cmds) == 2 assert len(cmds) == 2
assert cmds[0] assert cmds[0]
assert "{0}" in cmds[0]
assert "{1}" not in cmds[0]
assert cmds[1] assert cmds[1]
assert "{0}" in cmds[1]
assert "{1}" in cmds[1]