From 75f8ea48f42f4a1bee161b6991d521566512324f Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 11 May 2023 10:51:00 +0200 Subject: [PATCH] Add tts get engine ws command (#92336) Co-authored-by: Erik Montnemery --- homeassistant/components/tts/__init__.py | 42 +++++++++++++++++++++ tests/components/tts/test_init.py | 48 +++++++++++++++++++++++- 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/tts/__init__.py b/homeassistant/components/tts/__init__.py index a90a69edcdb..7a55fb9b77d 100644 --- a/homeassistant/components/tts/__init__.py +++ b/homeassistant/components/tts/__init__.py @@ -206,6 +206,7 @@ def async_get_text_to_speech_languages(hass: HomeAssistant) -> set[str]: async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up TTS.""" websocket_api.async_register_command(hass, websocket_list_engines) + websocket_api.async_register_command(hass, websocket_get_engine) websocket_api.async_register_command(hass, websocket_list_engine_voices) # Legacy config options @@ -969,6 +970,47 @@ def websocket_list_engines( ) +@websocket_api.websocket_command( + { + "type": "tts/engine/get", + vol.Required("engine_id"): str, + } +) +@callback +def websocket_get_engine( + hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict +) -> None: + """Get text to speech engine info.""" + component: EntityComponent[TextToSpeechEntity] = hass.data[DOMAIN] + manager: SpeechManager = hass.data[DATA_TTS_MANAGER] + + engine_id = msg["engine_id"] + provider_info: dict[str, Any] + + provider: TextToSpeechEntity | Provider | None = next( + (entity for entity in component.entities if entity.entity_id == engine_id), None + ) + if not provider: + provider = manager.providers.get(engine_id) + + if not provider: + connection.send_error( + msg["id"], + websocket_api.const.ERR_NOT_FOUND, + f"tts engine {engine_id} not found", + ) + return + + provider_info = { + "engine_id": engine_id, + "supported_languages": provider.supported_languages, + } + + connection.send_message( + websocket_api.result_message(msg["id"], {"provider": provider_info}) + ) + + @websocket_api.websocket_command( { "type": "tts/engine/voices", diff --git a/tests/components/tts/test_init.py b/tests/components/tts/test_init.py index cdb8fd9a413..b43687ba931 100644 --- a/tests/components/tts/test_init.py +++ b/tests/components/tts/test_init.py @@ -1623,7 +1623,7 @@ async def test_fetching_in_async( async def test_ws_list_engines( hass: HomeAssistant, hass_ws_client: WebSocketGenerator, setup: str, engine_id: str ) -> None: - """Test streaming audio and getting response.""" + """Test listing tts engines and supported languages.""" client = await hass_ws_client() await client.send_json_auto_id({"type": "tts/engine/list"}) @@ -1690,6 +1690,50 @@ async def test_ws_list_engines( } +@pytest.mark.parametrize( + ("setup", "engine_id"), + [ + ("mock_setup", "test"), + ("mock_config_entry_setup", "tts.test"), + ], + indirect=["setup"], +) +async def test_ws_get_engine( + hass: HomeAssistant, hass_ws_client: WebSocketGenerator, setup: str, engine_id: str +) -> None: + """Test getting an tts engine.""" + client = await hass_ws_client() + + await client.send_json_auto_id({"type": "tts/engine/get", "engine_id": engine_id}) + + msg = await client.receive_json() + assert msg["success"] + assert msg["result"] == { + "provider": { + "engine_id": engine_id, + "supported_languages": ["de_CH", "de_DE", "en_GB", "en_US"], + } + } + + +@pytest.mark.parametrize( + ("setup", "engine_id"), + [("mock_setup", "not_existing"), ("mock_config_entry_setup", "tts.not_existing")], + indirect=["setup"], +) +async def test_ws_get_engine_none_existing( + hass: HomeAssistant, hass_ws_client: WebSocketGenerator, setup: str, engine_id: str +) -> None: + """Test getting a non existing tts engine.""" + client = await hass_ws_client() + + await client.send_json_auto_id({"type": "tts/engine/get", "engine_id": engine_id}) + + msg = await client.receive_json() + assert not msg["success"] + assert msg["error"]["code"] == "not_found" + + @pytest.mark.parametrize( ("setup", "engine_id"), [ @@ -1701,7 +1745,7 @@ async def test_ws_list_engines( async def test_ws_list_voices( hass: HomeAssistant, hass_ws_client: WebSocketGenerator, setup: str, engine_id: str ) -> None: - """Test streaming audio and getting response.""" + """Test listing supported voices for a tts engine and language.""" client = await hass_ws_client() await client.send_json_auto_id(