diff --git a/homeassistant/components/conversation/manifest.json b/homeassistant/components/conversation/manifest.json index 58170b37c6b..f308ae57647 100644 --- a/homeassistant/components/conversation/manifest.json +++ b/homeassistant/components/conversation/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/conversation", "integration_type": "system", "quality_scale": "internal", - "requirements": ["hassil==1.7.3", "home-assistant-intents==2024.7.3"] + "requirements": ["hassil==1.7.4", "home-assistant-intents==2024.7.10"] } diff --git a/homeassistant/components/intent/__init__.py b/homeassistant/components/intent/__init__.py index 9b09fa9167b..c933b94fdd4 100644 --- a/homeassistant/components/intent/__init__.py +++ b/homeassistant/components/intent/__init__.py @@ -2,6 +2,7 @@ from __future__ import annotations +from datetime import datetime import logging from typing import Any, Protocol @@ -120,6 +121,8 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: intent.async_register(hass, PauseTimerIntentHandler()) intent.async_register(hass, UnpauseTimerIntentHandler()) intent.async_register(hass, TimerStatusIntentHandler()) + intent.async_register(hass, GetCurrentDateIntentHandler()) + intent.async_register(hass, GetCurrentTimeIntentHandler()) return True @@ -370,6 +373,30 @@ class SetPositionIntentHandler(intent.DynamicServiceIntentHandler): raise intent.IntentHandleError(f"Domain not supported: {state.domain}") +class GetCurrentDateIntentHandler(intent.IntentHandler): + """Gets the current date.""" + + intent_type = intent.INTENT_GET_CURRENT_DATE + description = "Gets the current date" + + async def async_handle(self, intent_obj: intent.Intent) -> intent.IntentResponse: + response = intent_obj.create_response() + response.async_set_speech_slots({"date": datetime.now().date()}) + return response + + +class GetCurrentTimeIntentHandler(intent.IntentHandler): + """Gets the current time.""" + + intent_type = intent.INTENT_GET_CURRENT_TIME + description = "Gets the current time" + + async def async_handle(self, intent_obj: intent.Intent) -> intent.IntentResponse: + response = intent_obj.create_response() + response.async_set_speech_slots({"time": datetime.now().time()}) + return response + + async def _async_process_intent( hass: HomeAssistant, domain: str, platform: IntentPlatformProtocol ) -> None: diff --git a/homeassistant/helpers/intent.py b/homeassistant/helpers/intent.py index 1bf78ae3a29..eeb160934ff 100644 --- a/homeassistant/helpers/intent.py +++ b/homeassistant/helpers/intent.py @@ -54,6 +54,8 @@ INTENT_DECREASE_TIMER = "HassDecreaseTimer" INTENT_PAUSE_TIMER = "HassPauseTimer" INTENT_UNPAUSE_TIMER = "HassUnpauseTimer" INTENT_TIMER_STATUS = "HassTimerStatus" +INTENT_GET_CURRENT_DATE = "HassGetCurrentDate" +INTENT_GET_CURRENT_TIME = "HassGetCurrentTime" SLOT_SCHEMA = vol.Schema({}, extra=vol.ALLOW_EXTRA) diff --git a/homeassistant/helpers/llm.py b/homeassistant/helpers/llm.py index 506cadbf168..52d7271c196 100644 --- a/homeassistant/helpers/llm.py +++ b/homeassistant/helpers/llm.py @@ -277,6 +277,8 @@ class AssistAPI(API): intent.INTENT_GET_STATE, intent.INTENT_NEVERMIND, intent.INTENT_TOGGLE, + intent.INTENT_GET_CURRENT_DATE, + intent.INTENT_GET_CURRENT_TIME, } def __init__(self, hass: HomeAssistant) -> None: diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index cb153fc2a7c..22bd95f10d2 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -30,10 +30,10 @@ ha-av==10.1.1 ha-ffmpeg==3.2.0 habluetooth==3.1.3 hass-nabucasa==0.81.1 -hassil==1.7.3 +hassil==1.7.4 home-assistant-bluetooth==1.12.2 home-assistant-frontend==20240710.0 -home-assistant-intents==2024.7.3 +home-assistant-intents==2024.7.10 httpx==0.27.0 ifaddr==0.2.0 Jinja2==3.1.4 diff --git a/requirements_all.txt b/requirements_all.txt index 684a716d052..398508325ec 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1062,7 +1062,7 @@ hass-nabucasa==0.81.1 hass-splunk==0.1.1 # homeassistant.components.conversation -hassil==1.7.3 +hassil==1.7.4 # homeassistant.components.jewish_calendar hdate==0.10.9 @@ -1099,7 +1099,7 @@ holidays==0.52 home-assistant-frontend==20240710.0 # homeassistant.components.conversation -home-assistant-intents==2024.7.3 +home-assistant-intents==2024.7.10 # homeassistant.components.home_connect homeconnect==0.7.2 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 934b107118c..a71b2577321 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -876,7 +876,7 @@ habluetooth==3.1.3 hass-nabucasa==0.81.1 # homeassistant.components.conversation -hassil==1.7.3 +hassil==1.7.4 # homeassistant.components.jewish_calendar hdate==0.10.9 @@ -904,7 +904,7 @@ holidays==0.52 home-assistant-frontend==20240710.0 # homeassistant.components.conversation -home-assistant-intents==2024.7.3 +home-assistant-intents==2024.7.10 # homeassistant.components.home_connect homeconnect==0.7.2 diff --git a/tests/components/conversation/test_default_agent_intents.py b/tests/components/conversation/test_default_agent_intents.py index b1c4a6d51af..8be25136df4 100644 --- a/tests/components/conversation/test_default_agent_intents.py +++ b/tests/components/conversation/test_default_agent_intents.py @@ -1,7 +1,9 @@ """Test intents for the default agent.""" +from datetime import datetime from unittest.mock import patch +from freezegun import freeze_time import pytest from homeassistant.components import ( @@ -413,3 +415,28 @@ async def test_todo_add_item_fr( assert mock_handle.call_args.args intent_obj = mock_handle.call_args.args[0] assert intent_obj.slots.get("item", {}).get("value", "").strip() == "farine" + + +@freeze_time(datetime(year=2013, month=9, day=17, hour=1, minute=2)) +async def test_date_time( + hass: HomeAssistant, + init_components, +) -> None: + """Test the date and time intents.""" + result = await conversation.async_converse( + hass, "what is the date", None, Context(), None + ) + await hass.async_block_till_done() + + response = result.response + assert response.response_type == intent.IntentResponseType.ACTION_DONE + assert response.speech["plain"]["speech"] == "September 17th, 2013" + + result = await conversation.async_converse( + hass, "what time is it", None, Context(), None + ) + await hass.async_block_till_done() + + response = result.response + assert response.response_type == intent.IntentResponseType.ACTION_DONE + assert response.speech["plain"]["speech"] == "1:02 AM"