From 641754e0bb7b90180f64a731fcb30c9ec9eeca14 Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Tue, 14 May 2024 13:59:49 -0500 Subject: [PATCH] Pass device_id to intent handlers (#117442) --- .../components/conversation/default_agent.py | 1 + homeassistant/helpers/intent.py | 5 +++ .../conversation/test_default_agent.py | 32 +++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/homeassistant/components/conversation/default_agent.py b/homeassistant/components/conversation/default_agent.py index 7c0d2ec254f..c124ad96af8 100644 --- a/homeassistant/components/conversation/default_agent.py +++ b/homeassistant/components/conversation/default_agent.py @@ -358,6 +358,7 @@ class DefaultAgent(ConversationEntity): user_input.context, language, assistant=DOMAIN, + device_id=user_input.device_id, ) except intent.MatchFailedError as match_error: # Intent was valid, but no entities matched the constraints. diff --git a/homeassistant/helpers/intent.py b/homeassistant/helpers/intent.py index fd06314972d..4b835e2a65a 100644 --- a/homeassistant/helpers/intent.py +++ b/homeassistant/helpers/intent.py @@ -97,6 +97,7 @@ async def async_handle( context: Context | None = None, language: str | None = None, assistant: str | None = None, + device_id: str | None = None, ) -> IntentResponse: """Handle an intent.""" handler = hass.data.get(DATA_KEY, {}).get(intent_type) @@ -119,6 +120,7 @@ async def async_handle( context=context, language=language, assistant=assistant, + device_id=device_id, ) try: @@ -1116,6 +1118,7 @@ class Intent: "language", "category", "assistant", + "device_id", ] def __init__( @@ -1129,6 +1132,7 @@ class Intent: language: str, category: IntentCategory | None = None, assistant: str | None = None, + device_id: str | None = None, ) -> None: """Initialize an intent.""" self.hass = hass @@ -1140,6 +1144,7 @@ class Intent: self.language = language self.category = category self.assistant = assistant + self.device_id = device_id @callback def create_response(self) -> IntentResponse: diff --git a/tests/components/conversation/test_default_agent.py b/tests/components/conversation/test_default_agent.py index f100dc810fb..1ff3dd406c4 100644 --- a/tests/components/conversation/test_default_agent.py +++ b/tests/components/conversation/test_default_agent.py @@ -1090,3 +1090,35 @@ async def test_same_aliased_entities_in_different_areas( hass, "how many lights are on?", None, Context(), None ) assert result.response.response_type == intent.IntentResponseType.QUERY_ANSWER + + +async def test_device_id_in_handler(hass: HomeAssistant, init_components) -> None: + """Test that the default agent passes device_id to intent handler.""" + device_id = "test_device" + + # Reuse custom sentences in test config to trigger default agent. + class OrderBeerIntentHandler(intent.IntentHandler): + intent_type = "OrderBeer" + + def __init__(self) -> None: + super().__init__() + self.device_id: str | None = None + + async def async_handle( + self, intent_obj: intent.Intent + ) -> intent.IntentResponse: + self.device_id = intent_obj.device_id + return intent_obj.create_response() + + handler = OrderBeerIntentHandler() + intent.async_register(hass, handler) + + result = await conversation.async_converse( + hass, + "I'd like to order a stout please", + None, + Context(), + device_id=device_id, + ) + assert result.response.response_type == intent.IntentResponseType.ACTION_DONE + assert handler.device_id == device_id