diff --git a/homeassistant/components/almond/__init__.py b/homeassistant/components/almond/__init__.py index 07aea4f792e..3da49e51f21 100644 --- a/homeassistant/components/almond/__init__.py +++ b/homeassistant/components/almond/__init__.py @@ -294,7 +294,7 @@ class AlmondAgent(conversation.AbstractConversationAgent): context: Context, conversation_id: str | None = None, language: str | None = None, - ) -> conversation.ConversationResult | None: + ) -> conversation.ConversationResult: """Process a sentence.""" response = await self.api.async_converse_text(text, conversation_id) language = language or self.hass.config.language diff --git a/homeassistant/components/conversation/__init__.py b/homeassistant/components/conversation/__init__.py index 86bb5c2183c..ed06234707f 100644 --- a/homeassistant/components/conversation/__init__.py +++ b/homeassistant/components/conversation/__init__.py @@ -242,44 +242,5 @@ async def async_converse( if language is None: language = hass.config.language - result: ConversationResult | None = None - intent_response: intent.IntentResponse | None = None - - try: - result = await agent.async_process(text, context, conversation_id, language) - except intent.IntentHandleError as err: - # Match was successful, but target(s) were invalid - intent_response = intent.IntentResponse(language=language) - intent_response.async_set_error( - intent.IntentResponseErrorCode.NO_VALID_TARGETS, - str(err), - ) - except intent.IntentUnexpectedError as err: - # Match was successful, but an error occurred while handling intent - intent_response = intent.IntentResponse(language=language) - intent_response.async_set_error( - intent.IntentResponseErrorCode.FAILED_TO_HANDLE, - str(err), - ) - except intent.IntentError as err: - # Unknown error - intent_response = intent.IntentResponse(language=language) - intent_response.async_set_error( - intent.IntentResponseErrorCode.UNKNOWN, - str(err), - ) - - if result is None: - if intent_response is None: - # Match was not successful - intent_response = intent.IntentResponse(language=language) - intent_response.async_set_error( - intent.IntentResponseErrorCode.NO_INTENT_MATCH, - "Sorry, I didn't understand that", - ) - - result = ConversationResult( - response=intent_response, conversation_id=conversation_id - ) - + result = await agent.async_process(text, context, conversation_id, language) return result diff --git a/homeassistant/components/conversation/agent.py b/homeassistant/components/conversation/agent.py index 889412996aa..2d01a7a1e3e 100644 --- a/homeassistant/components/conversation/agent.py +++ b/homeassistant/components/conversation/agent.py @@ -47,7 +47,7 @@ class AbstractConversationAgent(ABC): context: Context, conversation_id: str | None = None, language: str | None = None, - ) -> ConversationResult | None: + ) -> ConversationResult: """Process a sentence.""" async def async_reload(self, language: str | None = None): diff --git a/homeassistant/components/conversation/default_agent.py b/homeassistant/components/conversation/default_agent.py index a8097645a6a..b33991c0540 100644 --- a/homeassistant/components/conversation/default_agent.py +++ b/homeassistant/components/conversation/default_agent.py @@ -8,31 +8,40 @@ from dataclasses import dataclass import logging from pathlib import Path import re -from typing import Any +from typing import IO, Any -from hassil.intents import Intents, SlotList, TextSlotList +from hassil.intents import Intents, ResponseType, SlotList, TextSlotList from hassil.recognize import recognize from hassil.util import merge_dict from home_assistant_intents import get_intents import yaml from homeassistant import core, setup -from homeassistant.helpers import area_registry, entity_registry, intent +from homeassistant.helpers import area_registry, entity_registry, intent, template +from homeassistant.helpers.json import json_loads from .agent import AbstractConversationAgent, ConversationResult from .const import DOMAIN _LOGGER = logging.getLogger(__name__) +_DEFAULT_ERROR_TEXT = "Sorry, I couldn't understand that" REGEX_TYPE = type(re.compile("")) +def json_load(fp: IO[str]) -> dict[str, Any]: + """Wrap json_loads for get_intents.""" + return json_loads(fp.read()) + + @dataclass class LanguageIntents: """Loaded intents for a language.""" intents: Intents intents_dict: dict[str, Any] + intent_responses: dict[str, Any] + error_responses: dict[str, Any] loaded_components: set[str] @@ -78,7 +87,7 @@ class DefaultAgent(AbstractConversationAgent): context: core.Context, conversation_id: str | None = None, language: str | None = None, - ) -> ConversationResult | None: + ) -> ConversationResult: """Process a sentence.""" language = language or self.hass.config.language lang_intents = self._lang_intents.get(language) @@ -93,7 +102,12 @@ class DefaultAgent(AbstractConversationAgent): if lang_intents is None: # No intents loaded _LOGGER.warning("No intents were loaded for language: %s", language) - return None + return _make_error_result( + language, + intent.IntentResponseErrorCode.NO_INTENT_MATCH, + _DEFAULT_ERROR_TEXT, + conversation_id, + ) slot_lists: dict[str, SlotList] = { "area": self._make_areas_list(), @@ -102,17 +116,65 @@ class DefaultAgent(AbstractConversationAgent): result = recognize(text, lang_intents.intents, slot_lists=slot_lists) if result is None: - return None + _LOGGER.debug("No intent was matched for '%s'", text) + return _make_error_result( + language, + intent.IntentResponseErrorCode.NO_INTENT_MATCH, + self._get_error_text(ResponseType.NO_INTENT, lang_intents), + conversation_id, + ) - intent_response = await intent.async_handle( - self.hass, - DOMAIN, - result.intent.name, - {entity.name: {"value": entity.value} for entity in result.entities_list}, - text, - context, - language, - ) + try: + intent_response = await intent.async_handle( + self.hass, + DOMAIN, + result.intent.name, + { + entity.name: {"value": entity.value} + for entity in result.entities_list + }, + text, + context, + language, + ) + except intent.IntentHandleError: + _LOGGER.exception("Intent handling error") + return _make_error_result( + language, + intent.IntentResponseErrorCode.FAILED_TO_HANDLE, + self._get_error_text(ResponseType.HANDLE_ERROR, lang_intents), + conversation_id, + ) + except intent.IntentUnexpectedError: + _LOGGER.exception("Unexpected intent error") + return _make_error_result( + language, + intent.IntentResponseErrorCode.UNKNOWN, + self._get_error_text(ResponseType.HANDLE_ERROR, lang_intents), + conversation_id, + ) + + if ( + (not intent_response.speech) + and (intent_response.intent is not None) + and (response_key := result.response) + ): + # Use response template, if available + response_str = lang_intents.intent_responses.get( + result.intent.name, {} + ).get(response_key) + if response_str: + response_template = template.Template(response_str, self.hass) + intent_response.async_set_speech( + response_template.async_render( + { + "slots": { + entity_name: entity_value.text or entity_value.value + for entity_name, entity_value in result.entities.items() + } + } + ) + ) return ConversationResult( response=intent_response, conversation_id=conversation_id @@ -168,7 +230,9 @@ class DefaultAgent(AbstractConversationAgent): # Check for intents for this component with the target language. # Try en-US, en, etc. for language_variation in _get_language_variations(language): - component_intents = get_intents(component, language_variation) + component_intents = get_intents( + component, language_variation, json_load=json_load + ) if component_intents: # Merge sentences into existing dictionary merge_dict(intents_dict, component_intents) @@ -230,11 +294,24 @@ class DefaultAgent(AbstractConversationAgent): # components with sentences are often being loaded. intents = Intents.from_dict(intents_dict) + # Load responses + responses_dict = intents_dict.get("responses", {}) + intent_responses = responses_dict.get("intents", {}) + error_responses = responses_dict.get("errors", {}) + if lang_intents is None: - lang_intents = LanguageIntents(intents, intents_dict, loaded_components) + lang_intents = LanguageIntents( + intents, + intents_dict, + intent_responses, + error_responses, + loaded_components, + ) self._lang_intents[language] = lang_intents else: lang_intents.intents = intents + lang_intents.intent_responses = intent_responses + lang_intents.error_responses = error_responses return lang_intents @@ -256,6 +333,9 @@ class DefaultAgent(AbstractConversationAgent): registry = entity_registry.async_get(self.hass) names = [] for state in states: + domain = state.entity_id.split(".", maxsplit=1)[0] + context = {"domain": domain} + entry = registry.async_get(state.entity_id) if entry is not None: if entry.entity_category: @@ -264,9 +344,30 @@ class DefaultAgent(AbstractConversationAgent): if entry.aliases: for alias in entry.aliases: - names.append((alias, state.entity_id)) + names.append((alias, state.entity_id, context)) # Default name - names.append((state.name, state.entity_id)) + names.append((state.name, state.entity_id, context)) return TextSlotList.from_tuples(names) + + def _get_error_text( + self, response_type: ResponseType, lang_intents: LanguageIntents + ) -> str: + """Get response error text by type.""" + response_key = response_type.value + response_str = lang_intents.error_responses.get(response_key) + return response_str or _DEFAULT_ERROR_TEXT + + +def _make_error_result( + language: str, + error_code: intent.IntentResponseErrorCode, + response_text: str, + conversation_id: str | None = None, +) -> ConversationResult: + """Create conversation result with error code and text.""" + response = intent.IntentResponse(language=language) + response.async_set_error(error_code, response_text) + + return ConversationResult(response, conversation_id) diff --git a/homeassistant/components/conversation/manifest.json b/homeassistant/components/conversation/manifest.json index b83dfe431d5..7dea0511f7f 100644 --- a/homeassistant/components/conversation/manifest.json +++ b/homeassistant/components/conversation/manifest.json @@ -2,7 +2,7 @@ "domain": "conversation", "name": "Conversation", "documentation": "https://www.home-assistant.io/integrations/conversation", - "requirements": ["hassil==0.2.3", "home-assistant-intents==0.0.1"], + "requirements": ["hassil==0.2.5", "home-assistant-intents==2022.1.23"], "dependencies": ["http"], "codeowners": ["@home-assistant/core"], "quality_scale": "internal", diff --git a/homeassistant/components/google_assistant_sdk/__init__.py b/homeassistant/components/google_assistant_sdk/__init__.py index 59c065ecbb6..c784ebb500e 100644 --- a/homeassistant/components/google_assistant_sdk/__init__.py +++ b/homeassistant/components/google_assistant_sdk/__init__.py @@ -131,7 +131,7 @@ class GoogleAssistantConversationAgent(conversation.AbstractConversationAgent): context: Context, conversation_id: str | None = None, language: str | None = None, - ) -> conversation.ConversationResult | None: + ) -> conversation.ConversationResult: """Process a sentence.""" if self.session: session = self.session diff --git a/homeassistant/components/intent/__init__.py b/homeassistant/components/intent/__init__.py index 9171f5b9fc0..874a9f1120c 100644 --- a/homeassistant/components/intent/__init__.py +++ b/homeassistant/components/intent/__init__.py @@ -31,21 +31,15 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: intent.async_register( hass, - OnOffIntentHandler( - intent.INTENT_TURN_ON, HA_DOMAIN, SERVICE_TURN_ON, "Turned {} on" - ), + OnOffIntentHandler(intent.INTENT_TURN_ON, HA_DOMAIN, SERVICE_TURN_ON), ) intent.async_register( hass, - OnOffIntentHandler( - intent.INTENT_TURN_OFF, HA_DOMAIN, SERVICE_TURN_OFF, "Turned {} off" - ), + OnOffIntentHandler(intent.INTENT_TURN_OFF, HA_DOMAIN, SERVICE_TURN_OFF), ) intent.async_register( hass, - intent.ServiceIntentHandler( - intent.INTENT_TOGGLE, HA_DOMAIN, SERVICE_TOGGLE, "Toggled {}" - ), + intent.ServiceIntentHandler(intent.INTENT_TOGGLE, HA_DOMAIN, SERVICE_TOGGLE), ) return True diff --git a/homeassistant/components/light/intent.py b/homeassistant/components/light/intent.py index 5ee60459128..7b75821ab43 100644 --- a/homeassistant/components/light/intent.py +++ b/homeassistant/components/light/intent.py @@ -47,7 +47,6 @@ class SetIntentHandler(intent.IntentHandler): """Handle the hass intent.""" hass = intent_obj.hass service_data: dict[str, Any] = {} - speech_parts: list[str] = [] slots = self.async_validate_slots(intent_obj.slots) name: str | None = slots.get("name", {}).get("value") @@ -92,13 +91,9 @@ class SetIntentHandler(intent.IntentHandler): if "color" in slots: service_data[ATTR_RGB_COLOR] = slots["color"]["value"] - # Use original passed in value of the color because we don't have - # human readable names for that internally. - speech_parts.append(f"the color {intent_obj.slots['color']['value']}") if "brightness" in slots: service_data[ATTR_BRIGHTNESS_PCT] = slots["brightness"]["value"] - speech_parts.append(f"{slots['brightness']['value']}% brightness") response = intent_obj.create_response() needs_brightness = ATTR_BRIGHTNESS_PCT in service_data @@ -116,9 +111,6 @@ class SetIntentHandler(intent.IntentHandler): id=area.id, ) ) - speech_name = area.name - else: - speech_name = states[0].name for state in states: target = intent.IntentResponseTarget( @@ -152,19 +144,4 @@ class SetIntentHandler(intent.IntentHandler): success_results=success_results, failed_results=failed_results ) - if not speech_parts: # No attributes changed - speech = f"Turned on {speech_name}" - else: - parts = [f"Changed {speech_name} to"] - for index, part in enumerate(speech_parts): - if index == 0: - parts.append(f" {part}") - elif index != len(speech_parts) - 1: - parts.append(f", {part}") - else: - parts.append(f" and {part}") - speech = "".join(parts) - - response.async_set_speech(speech) - return response diff --git a/homeassistant/helpers/intent.py b/homeassistant/helpers/intent.py index c1b0b9d3a3f..f7ee7008b68 100644 --- a/homeassistant/helpers/intent.py +++ b/homeassistant/helpers/intent.py @@ -286,7 +286,7 @@ class ServiceIntentHandler(IntentHandler): } def __init__( - self, intent_type: str, domain: str, service: str, speech: str + self, intent_type: str, domain: str, service: str, speech: str | None = None ) -> None: """Create Service Intent Handler.""" self.intent_type = intent_type @@ -382,7 +382,9 @@ class ServiceIntentHandler(IntentHandler): response.async_set_results( success_results=success_results, ) - response.async_set_speech(self.speech.format(speech_name)) + + if self.speech is not None: + response.async_set_speech(self.speech.format(speech_name)) return response diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 0c52660c341..33d61a9dfe6 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -21,10 +21,10 @@ cryptography==39.0.0 dbus-fast==1.84.0 fnvhash==0.1.0 hass-nabucasa==0.61.0 -hassil==0.2.3 +hassil==0.2.5 home-assistant-bluetooth==1.9.2 home-assistant-frontend==20230110.0 -home-assistant-intents==0.0.1 +home-assistant-intents==2022.1.23 httpx==0.23.2 ifaddr==0.1.7 janus==1.0.0 diff --git a/requirements_all.txt b/requirements_all.txt index b55350b60ae..8cfb6cd2445 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -877,7 +877,7 @@ hass-nabucasa==0.61.0 hass_splunk==0.1.1 # homeassistant.components.conversation -hassil==0.2.3 +hassil==0.2.5 # homeassistant.components.tasmota hatasmota==0.6.3 @@ -913,7 +913,7 @@ holidays==0.18.0 home-assistant-frontend==20230110.0 # homeassistant.components.conversation -home-assistant-intents==0.0.1 +home-assistant-intents==2022.1.23 # homeassistant.components.home_connect homeconnect==0.7.2 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 83e3325fa31..8b95c95f8c9 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -669,7 +669,7 @@ habitipy==0.2.0 hass-nabucasa==0.61.0 # homeassistant.components.conversation -hassil==0.2.3 +hassil==0.2.5 # homeassistant.components.tasmota hatasmota==0.6.3 @@ -696,7 +696,7 @@ holidays==0.18.0 home-assistant-frontend==20230110.0 # homeassistant.components.conversation -home-assistant-intents==0.0.1 +home-assistant-intents==2022.1.23 # homeassistant.components.home_connect homeconnect==0.7.2 diff --git a/tests/components/conversation/__init__.py b/tests/components/conversation/__init__.py index 9f842d4ff5f..998885ea218 100644 --- a/tests/components/conversation/__init__.py +++ b/tests/components/conversation/__init__.py @@ -20,7 +20,7 @@ class MockAgent(conversation.AbstractConversationAgent): context: Context, conversation_id: str | None = None, language: str | None = None, - ) -> conversation.ConversationResult | None: + ) -> conversation.ConversationResult: """Process some text.""" self.calls.append((text, context, conversation_id, language)) response = intent.IntentResponse(language=language) diff --git a/tests/components/conversation/test_init.py b/tests/components/conversation/test_init.py index 1d096b48463..f48ad4c0dfd 100644 --- a/tests/components/conversation/test_init.py +++ b/tests/components/conversation/test_init.py @@ -5,8 +5,9 @@ from unittest.mock import ANY, patch import pytest from homeassistant.components import conversation -from homeassistant.core import DOMAIN as HASS_DOMAIN -from homeassistant.helpers import intent +from homeassistant.components.cover import SERVICE_OPEN_COVER +from homeassistant.core import DOMAIN as HASS_DOMAIN, Context +from homeassistant.helpers import entity_registry, intent from homeassistant.setup import async_setup_component from tests.common import async_mock_service @@ -37,10 +38,15 @@ async def test_http_processing_intent( hass, init_components, hass_client, hass_admin_user ): """Test processing intent via HTTP API.""" - hass.states.async_set("light.kitchen", "on") + # Add an alias + entities = entity_registry.async_get(hass) + entities.async_get_or_create("light", "demo", "1234", suggested_object_id="kitchen") + entities.async_update_entity("light.kitchen", aliases={"my cool light"}) + hass.states.async_set("light.kitchen", "off") + client = await hass_client() resp = await client.post( - "/api/conversation/process", json={"text": "turn on kitchen"} + "/api/conversation/process", json={"text": "turn on my cool light"} ) assert resp.status == HTTPStatus.OK @@ -53,7 +59,7 @@ async def test_http_processing_intent( "speech": { "plain": { "extra_data": None, - "speech": "Turned kitchen on", + "speech": "Turned on my cool light", } }, "language": hass.config.language, @@ -120,7 +126,7 @@ async def test_http_api(hass, init_components, hass_client): assert data == { "response": { "card": {}, - "speech": {"plain": {"extra_data": None, "speech": "Turned kitchen on"}}, + "speech": {"plain": {"extra_data": None, "speech": "Turned on kitchen"}}, "language": hass.config.language, "response_type": "action_done", "data": { @@ -161,7 +167,7 @@ async def test_http_api_no_match(hass, init_components, hass_client): "card": {}, "speech": { "plain": { - "speech": "Sorry, I didn't understand that", + "speech": "Sorry, I couldn't understand that", "extra_data": None, }, }, @@ -178,11 +184,9 @@ async def test_http_api_handle_failure(hass, init_components, hass_client): hass.states.async_set("light.kitchen", "off") - # Raise an "unexpected" error during intent handling + # Raise an error during intent handling def async_handle_error(*args, **kwargs): - raise intent.IntentUnexpectedError( - "Unexpected error turning on the kitchen light" - ) + raise intent.IntentHandleError() with patch("homeassistant.helpers.intent.async_handle", new=async_handle_error): resp = await client.post( @@ -199,7 +203,7 @@ async def test_http_api_handle_failure(hass, init_components, hass_client): "speech": { "plain": { "extra_data": None, - "speech": "Unexpected error turning on the kitchen light", + "speech": "An unexpected error occurred while handling the intent", } }, "language": hass.config.language, @@ -211,6 +215,43 @@ async def test_http_api_handle_failure(hass, init_components, hass_client): } +async def test_http_api_unexpected_failure(hass, init_components, hass_client): + """Test the HTTP conversation API with an unexpected error during handling.""" + client = await hass_client() + + hass.states.async_set("light.kitchen", "off") + + # Raise an "unexpected" error during intent handling + def async_handle_error(*args, **kwargs): + raise intent.IntentUnexpectedError() + + with patch("homeassistant.helpers.intent.async_handle", new=async_handle_error): + resp = await client.post( + "/api/conversation/process", json={"text": "turn on the kitchen"} + ) + + assert resp.status == HTTPStatus.OK + data = await resp.json() + + assert data == { + "response": { + "response_type": "error", + "card": {}, + "speech": { + "plain": { + "extra_data": None, + "speech": "An unexpected error occurred while handling the intent", + } + }, + "language": hass.config.language, + "data": { + "code": "unknown", + }, + }, + "conversation_id": None, + } + + async def test_http_api_wrong_data(hass, init_components, hass_client): """Test the HTTP conversation API.""" client = await hass_client() @@ -302,7 +343,7 @@ async def test_ws_api(hass, hass_ws_client, payload): "speech": { "plain": { "extra_data": None, - "speech": "Sorry, I didn't understand that", + "speech": "Sorry, I couldn't understand that", } }, "language": payload.get("language", hass.config.language), @@ -484,3 +525,40 @@ async def test_language_region(hass, init_components): assert call.domain == HASS_DOMAIN assert call.service == "turn_on" assert call.data == {"entity_id": "light.kitchen"} + + +async def test_reload_on_new_component(hass): + """Test intents being reloaded when a new component is loaded.""" + language = hass.config.language + assert await async_setup_component(hass, "conversation", {}) + + # Load intents + agent = await conversation._get_agent(hass) + assert isinstance(agent, conversation.DefaultAgent) + await agent.async_prepare() + + lang_intents = agent._lang_intents.get(language) + assert lang_intents is not None + loaded_components = set(lang_intents.loaded_components) + + # Load another component + assert await async_setup_component(hass, "light", {}) + + # Intents should reload + await agent.async_prepare() + lang_intents = agent._lang_intents.get(language) + assert lang_intents is not None + + assert {"light"} == (lang_intents.loaded_components - loaded_components) + + +async def test_non_default_response(hass, init_components): + """Test intent response that is not the default.""" + hass.states.async_set("cover.front_door", "closed") + async_mock_service(hass, "cover", SERVICE_OPEN_COVER) + + agent = await conversation._get_agent(hass) + assert isinstance(agent, conversation.DefaultAgent) + + result = await agent.async_process("open the front door", Context()) + assert result.response.speech["plain"]["speech"] == "Opened front door" diff --git a/tests/components/intent/test_init.py b/tests/components/intent/test_init.py index 40bf79e1c45..beb17dc6b37 100644 --- a/tests/components/intent/test_init.py +++ b/tests/components/intent/test_init.py @@ -96,12 +96,11 @@ async def test_turn_on_intent(hass): hass.states.async_set("light.test_light", "off") calls = async_mock_service(hass, "light", SERVICE_TURN_ON) - response = await intent.async_handle( + await intent.async_handle( hass, "test", "HassTurnOn", {"name": {"value": "test light"}} ) await hass.async_block_till_done() - assert response.speech["plain"]["speech"] == "Turned test light on" assert len(calls) == 1 call = calls[0] assert call.domain == "light" @@ -118,12 +117,11 @@ async def test_turn_off_intent(hass): hass.states.async_set("light.test_light", "on") calls = async_mock_service(hass, "light", SERVICE_TURN_OFF) - response = await intent.async_handle( + await intent.async_handle( hass, "test", "HassTurnOff", {"name": {"value": "test light"}} ) await hass.async_block_till_done() - assert response.speech["plain"]["speech"] == "Turned test light off" assert len(calls) == 1 call = calls[0] assert call.domain == "light" @@ -140,12 +138,11 @@ async def test_toggle_intent(hass): hass.states.async_set("light.test_light", "off") calls = async_mock_service(hass, "light", SERVICE_TOGGLE) - response = await intent.async_handle( + await intent.async_handle( hass, "test", "HassToggle", {"name": {"value": "test light"}} ) await hass.async_block_till_done() - assert response.speech["plain"]["speech"] == "Toggled test light" assert len(calls) == 1 call = calls[0] assert call.domain == "light" @@ -167,12 +164,11 @@ async def test_turn_on_multiple_intent(hass): hass.states.async_set("light.test_lighter", "off") calls = async_mock_service(hass, "light", SERVICE_TURN_ON) - response = await intent.async_handle( + await intent.async_handle( hass, "test", "HassTurnOn", {"name": {"value": "test lights 2"}} ) await hass.async_block_till_done() - assert response.speech["plain"]["speech"] == "Turned test lights 2 on" assert len(calls) == 1 call = calls[0] assert call.domain == "light" diff --git a/tests/components/light/test_intent.py b/tests/components/light/test_intent.py index 9c665ded03b..57f90bb297c 100644 --- a/tests/components/light/test_intent.py +++ b/tests/components/light/test_intent.py @@ -16,7 +16,7 @@ async def test_intent_set_color(hass): calls = async_mock_service(hass, light.DOMAIN, light.SERVICE_TURN_ON) await intent.async_setup_intents(hass) - result = await async_handle( + await async_handle( hass, "test", intent.INTENT_SET, @@ -24,8 +24,6 @@ async def test_intent_set_color(hass): ) await hass.async_block_till_done() - assert result.speech["plain"]["speech"] == "Changed hello 2 to the color blue" - assert len(calls) == 1 call = calls[0] assert call.domain == light.DOMAIN @@ -62,7 +60,7 @@ async def test_intent_set_color_and_brightness(hass): calls = async_mock_service(hass, light.DOMAIN, light.SERVICE_TURN_ON) await intent.async_setup_intents(hass) - result = await async_handle( + await async_handle( hass, "test", intent.INTENT_SET, @@ -74,11 +72,6 @@ async def test_intent_set_color_and_brightness(hass): ) await hass.async_block_till_done() - assert ( - result.speech["plain"]["speech"] - == "Changed hello 2 to the color blue and 20% brightness" - ) - assert len(calls) == 1 call = calls[0] assert call.domain == light.DOMAIN