Remove "device_id" slot from timers (#117460)

Remove "device_id" slot
This commit is contained in:
Michael Hansen 2024-05-14 14:48:24 -05:00 committed by GitHub
parent 6322821b65
commit d441a62aa6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 47 additions and 87 deletions

View File

@ -335,18 +335,13 @@ class DefaultAgent(ConversationEntity):
assert lang_intents is not None
# Slot values to pass to the intent
slots: dict[str, Any] = {}
# Automatically add device id
if user_input.device_id is not None:
slots["device_id"] = user_input.device_id
# Add entities from match
for entity in result.entities_list:
slots[entity.name] = {
slots: dict[str, Any] = {
entity.name: {
"value": entity.value,
"text": entity.text or entity.value,
}
for entity in result.entities_list
}
try:
intent_response = await intent.async_handle(

View File

@ -408,7 +408,9 @@ def async_register_timer_handler(
# -----------------------------------------------------------------------------
def _find_timer(hass: HomeAssistant, slots: dict[str, Any]) -> TimerInfo:
def _find_timer(
hass: HomeAssistant, slots: dict[str, Any], device_id: str | None
) -> TimerInfo:
"""Match a single timer with constraints or raise an error."""
timer_manager: TimerManager = hass.data[TIMER_DATA]
matching_timers: list[TimerInfo] = list(timer_manager.timers.values())
@ -463,10 +465,7 @@ def _find_timer(hass: HomeAssistant, slots: dict[str, Any]) -> TimerInfo:
return matching_timers[0]
# Use device id
device_id: str | None = None
if matching_timers and ("device_id" in slots):
device_id = slots["device_id"]["value"]
assert device_id is not None
if matching_timers and device_id:
matching_device_timers = [
t for t in matching_timers if (t.device_id == device_id)
]
@ -513,7 +512,9 @@ def _find_timer(hass: HomeAssistant, slots: dict[str, Any]) -> TimerInfo:
raise TimerNotFoundError
def _find_timers(hass: HomeAssistant, slots: dict[str, Any]) -> list[TimerInfo]:
def _find_timers(
hass: HomeAssistant, slots: dict[str, Any], device_id: str | None
) -> list[TimerInfo]:
"""Match multiple timers with constraints or raise an error."""
timer_manager: TimerManager = hass.data[TIMER_DATA]
matching_timers: list[TimerInfo] = list(timer_manager.timers.values())
@ -559,12 +560,11 @@ def _find_timers(hass: HomeAssistant, slots: dict[str, Any]) -> list[TimerInfo]:
# No matches
return matching_timers
if "device_id" not in slots:
if not device_id:
# Can't re-order based on area/floor
return matching_timers
# Use device id to order remaining timers
device_id: str = slots["device_id"]["value"]
device_registry = dr.async_get(hass)
device = device_registry.async_get(device_id)
if (device is None) or (device.area_id is None):
@ -612,7 +612,6 @@ class StartTimerIntentHandler(intent.IntentHandler):
slot_schema = {
vol.Required(vol.Any("hours", "minutes", "seconds")): cv.positive_int,
vol.Optional("name"): cv.string,
vol.Optional("device_id"): cv.string,
}
async def async_handle(self, intent_obj: intent.Intent) -> intent.IntentResponse:
@ -621,10 +620,6 @@ class StartTimerIntentHandler(intent.IntentHandler):
timer_manager: TimerManager = hass.data[TIMER_DATA]
slots = self.async_validate_slots(intent_obj.slots)
device_id: str | None = None
if "device_id" in slots:
device_id = slots["device_id"]["value"]
name: str | None = None
if "name" in slots:
name = slots["name"]["value"]
@ -646,7 +641,7 @@ class StartTimerIntentHandler(intent.IntentHandler):
minutes,
seconds,
language=intent_obj.language,
device_id=device_id,
device_id=intent_obj.device_id,
name=name,
)
@ -660,7 +655,6 @@ class CancelTimerIntentHandler(intent.IntentHandler):
slot_schema = {
vol.Any("start_hours", "start_minutes", "start_seconds"): cv.positive_int,
vol.Optional("name"): cv.string,
vol.Optional("device_id"): cv.string,
}
async def async_handle(self, intent_obj: intent.Intent) -> intent.IntentResponse:
@ -669,7 +663,7 @@ class CancelTimerIntentHandler(intent.IntentHandler):
timer_manager: TimerManager = hass.data[TIMER_DATA]
slots = self.async_validate_slots(intent_obj.slots)
timer = _find_timer(hass, slots)
timer = _find_timer(hass, slots, intent_obj.device_id)
timer_manager.cancel_timer(timer.id)
return intent_obj.create_response()
@ -683,7 +677,6 @@ class IncreaseTimerIntentHandler(intent.IntentHandler):
vol.Any("hours", "minutes", "seconds"): cv.positive_int,
vol.Any("start_hours", "start_minutes", "start_seconds"): cv.positive_int,
vol.Optional("name"): cv.string,
vol.Optional("device_id"): cv.string,
}
async def async_handle(self, intent_obj: intent.Intent) -> intent.IntentResponse:
@ -693,7 +686,7 @@ class IncreaseTimerIntentHandler(intent.IntentHandler):
slots = self.async_validate_slots(intent_obj.slots)
total_seconds = _get_total_seconds(slots)
timer = _find_timer(hass, slots)
timer = _find_timer(hass, slots, intent_obj.device_id)
timer_manager.add_time(timer.id, total_seconds)
return intent_obj.create_response()
@ -707,7 +700,6 @@ class DecreaseTimerIntentHandler(intent.IntentHandler):
vol.Required(vol.Any("hours", "minutes", "seconds")): cv.positive_int,
vol.Any("start_hours", "start_minutes", "start_seconds"): cv.positive_int,
vol.Optional("name"): cv.string,
vol.Optional("device_id"): cv.string,
}
async def async_handle(self, intent_obj: intent.Intent) -> intent.IntentResponse:
@ -717,7 +709,7 @@ class DecreaseTimerIntentHandler(intent.IntentHandler):
slots = self.async_validate_slots(intent_obj.slots)
total_seconds = _get_total_seconds(slots)
timer = _find_timer(hass, slots)
timer = _find_timer(hass, slots, intent_obj.device_id)
timer_manager.remove_time(timer.id, total_seconds)
return intent_obj.create_response()
@ -730,7 +722,6 @@ class PauseTimerIntentHandler(intent.IntentHandler):
slot_schema = {
vol.Any("start_hours", "start_minutes", "start_seconds"): cv.positive_int,
vol.Optional("name"): cv.string,
vol.Optional("device_id"): cv.string,
}
async def async_handle(self, intent_obj: intent.Intent) -> intent.IntentResponse:
@ -739,7 +730,7 @@ class PauseTimerIntentHandler(intent.IntentHandler):
timer_manager: TimerManager = hass.data[TIMER_DATA]
slots = self.async_validate_slots(intent_obj.slots)
timer = _find_timer(hass, slots)
timer = _find_timer(hass, slots, intent_obj.device_id)
timer_manager.pause_timer(timer.id)
return intent_obj.create_response()
@ -752,7 +743,6 @@ class UnpauseTimerIntentHandler(intent.IntentHandler):
slot_schema = {
vol.Any("start_hours", "start_minutes", "start_seconds"): cv.positive_int,
vol.Optional("name"): cv.string,
vol.Optional("device_id"): cv.string,
}
async def async_handle(self, intent_obj: intent.Intent) -> intent.IntentResponse:
@ -761,7 +751,7 @@ class UnpauseTimerIntentHandler(intent.IntentHandler):
timer_manager: TimerManager = hass.data[TIMER_DATA]
slots = self.async_validate_slots(intent_obj.slots)
timer = _find_timer(hass, slots)
timer = _find_timer(hass, slots, intent_obj.device_id)
timer_manager.unpause_timer(timer.id)
return intent_obj.create_response()
@ -774,7 +764,6 @@ class TimerStatusIntentHandler(intent.IntentHandler):
slot_schema = {
vol.Any("start_hours", "start_minutes", "start_seconds"): cv.positive_int,
vol.Optional("name"): cv.string,
vol.Optional("device_id"): cv.string,
}
async def async_handle(self, intent_obj: intent.Intent) -> intent.IntentResponse:
@ -783,7 +772,7 @@ class TimerStatusIntentHandler(intent.IntentHandler):
slots = self.async_validate_slots(intent_obj.slots)
statuses: list[dict[str, Any]] = []
for timer in _find_timers(hass, slots):
for timer in _find_timers(hass, slots, intent_obj.device_id):
total_seconds = timer.seconds_left
minutes, seconds = divmod(total_seconds, 60)

View File

@ -65,9 +65,9 @@ async def test_start_finish_timer(hass: HomeAssistant, init_components) -> None:
intent.INTENT_START_TIMER,
{
"name": {"value": timer_name},
"device_id": {"value": device_id},
"seconds": {"value": 0},
},
device_id=device_id,
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
@ -118,11 +118,11 @@ async def test_cancel_timer(hass: HomeAssistant, init_components) -> None:
"test",
intent.INTENT_START_TIMER,
{
"device_id": {"value": device_id},
"hours": {"value": 1},
"minutes": {"value": 2},
"seconds": {"value": 3},
},
device_id=device_id,
)
async with asyncio.timeout(1):
@ -154,12 +154,12 @@ async def test_cancel_timer(hass: HomeAssistant, init_components) -> None:
"test",
intent.INTENT_START_TIMER,
{
"device_id": {"value": device_id},
"name": {"value": timer_name},
"hours": {"value": 1},
"minutes": {"value": 2},
"seconds": {"value": 3},
},
device_id=device_id,
)
async with asyncio.timeout(1):
@ -225,12 +225,12 @@ async def test_increase_timer(hass: HomeAssistant, init_components) -> None:
"test",
intent.INTENT_START_TIMER,
{
"device_id": {"value": device_id},
"name": {"value": timer_name},
"hours": {"value": 1},
"minutes": {"value": 2},
"seconds": {"value": 3},
},
device_id=device_id,
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
@ -244,7 +244,6 @@ async def test_increase_timer(hass: HomeAssistant, init_components) -> None:
"test",
intent.INTENT_INCREASE_TIMER,
{
"device_id": {"value": device_id},
"start_hours": {"value": 1},
"start_minutes": {"value": 2},
"start_seconds": {"value": 3},
@ -252,6 +251,7 @@ async def test_increase_timer(hass: HomeAssistant, init_components) -> None:
"minutes": {"value": 5},
"seconds": {"value": 30},
},
device_id=device_id,
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
@ -321,12 +321,12 @@ async def test_decrease_timer(hass: HomeAssistant, init_components) -> None:
"test",
intent.INTENT_START_TIMER,
{
"device_id": {"value": device_id},
"name": {"value": timer_name},
"hours": {"value": 1},
"minutes": {"value": 2},
"seconds": {"value": 3},
},
device_id=device_id,
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
@ -340,12 +340,12 @@ async def test_decrease_timer(hass: HomeAssistant, init_components) -> None:
"test",
intent.INTENT_DECREASE_TIMER,
{
"device_id": {"value": device_id},
"start_hours": {"value": 1},
"start_minutes": {"value": 2},
"start_seconds": {"value": 3},
"seconds": {"value": 30},
},
device_id=device_id,
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
@ -535,7 +535,8 @@ async def test_disambiguation(
hass,
"test",
intent.INTENT_START_TIMER,
{"device_id": {"value": device_alice_study.id}, "minutes": {"value": 3}},
{"minutes": {"value": 3}},
device_id=device_alice_study.id,
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
@ -544,16 +545,14 @@ async def test_disambiguation(
hass,
"test",
intent.INTENT_START_TIMER,
{"device_id": {"value": device_bob_kitchen_1.id}, "minutes": {"value": 3}},
{"minutes": {"value": 3}},
device_id=device_bob_kitchen_1.id,
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
# Alice should hear her timer listed first
result = await intent.async_handle(
hass,
"test",
intent.INTENT_TIMER_STATUS,
{"device_id": {"value": device_alice_study.id}},
hass, "test", intent.INTENT_TIMER_STATUS, {}, device_id=device_alice_study.id
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
timers = result.speech_slots.get("timers", [])
@ -563,10 +562,7 @@ async def test_disambiguation(
# Bob should hear his timer listed first
result = await intent.async_handle(
hass,
"test",
intent.INTENT_TIMER_STATUS,
{"device_id": {"value": device_bob_kitchen_1.id}},
hass, "test", intent.INTENT_TIMER_STATUS, {}, device_id=device_bob_kitchen_1.id
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
timers = result.speech_slots.get("timers", [])
@ -589,10 +585,7 @@ async def test_disambiguation(
# Alice: cancel my timer
result = await intent.async_handle(
hass,
"test",
intent.INTENT_CANCEL_TIMER,
{"device_id": {"value": device_alice_study.id}},
hass, "test", intent.INTENT_CANCEL_TIMER, {}, device_id=device_alice_study.id
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
@ -606,10 +599,7 @@ async def test_disambiguation(
# Cancel Bob's timer
result = await intent.async_handle(
hass,
"test",
intent.INTENT_CANCEL_TIMER,
{"device_id": {"value": device_bob_kitchen_1.id}},
hass, "test", intent.INTENT_CANCEL_TIMER, {}, device_id=device_bob_kitchen_1.id
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
@ -645,7 +635,8 @@ async def test_disambiguation(
hass,
"test",
intent.INTENT_START_TIMER,
{"device_id": {"value": device_alice_study.id}, "minutes": {"value": 3}},
{"minutes": {"value": 3}},
device_id=device_alice_study.id,
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
@ -654,10 +645,8 @@ async def test_disambiguation(
hass,
"test",
intent.INTENT_START_TIMER,
{
"device_id": {"value": device_alice_bedroom.id},
"minutes": {"value": 3},
},
{"minutes": {"value": 3}},
device_id=device_alice_bedroom.id,
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
@ -666,7 +655,8 @@ async def test_disambiguation(
hass,
"test",
intent.INTENT_START_TIMER,
{"device_id": {"value": device_bob_kitchen_1.id}, "minutes": {"value": 3}},
{"minutes": {"value": 3}},
device_id=device_bob_kitchen_1.id,
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
@ -675,17 +665,15 @@ async def test_disambiguation(
hass,
"test",
intent.INTENT_START_TIMER,
{"device_id": {"value": device_bob_living_room.id}, "minutes": {"value": 3}},
{"minutes": {"value": 3}},
device_id=device_bob_living_room.id,
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
# Alice should hear the timer in her area first, then on her floor, then
# elsewhere.
result = await intent.async_handle(
hass,
"test",
intent.INTENT_TIMER_STATUS,
{"device_id": {"value": device_alice_study.id}},
hass, "test", intent.INTENT_TIMER_STATUS, {}, device_id=device_alice_study.id
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
timers = result.speech_slots.get("timers", [])
@ -699,10 +687,7 @@ async def test_disambiguation(
cancelled_event.clear()
timer_info = None
result = await intent.async_handle(
hass,
"test",
intent.INTENT_CANCEL_TIMER,
{"device_id": {"value": device_alice_study.id}},
hass, "test", intent.INTENT_CANCEL_TIMER, {}, device_id=device_alice_study.id
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
@ -727,10 +712,7 @@ async def test_disambiguation(
cancelled_event.clear()
timer_info = None
result = await intent.async_handle(
hass,
"test",
intent.INTENT_CANCEL_TIMER,
{"device_id": {"value": device_alice_study.id}},
hass, "test", intent.INTENT_CANCEL_TIMER, {}, device_id=device_alice_study.id
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
@ -756,10 +738,7 @@ async def test_disambiguation(
cancelled_event.clear()
timer_info = None
result = await intent.async_handle(
hass,
"test",
intent.INTENT_CANCEL_TIMER,
{"device_id": {"value": device_bob_kitchen_2.id}},
hass, "test", intent.INTENT_CANCEL_TIMER, {}, device_id=device_bob_kitchen_2.id
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE
@ -774,10 +753,7 @@ async def test_disambiguation(
cancelled_event.clear()
timer_info = None
result = await intent.async_handle(
hass,
"test",
intent.INTENT_CANCEL_TIMER,
{"device_id": {"value": device_bob_kitchen_2.id}},
hass, "test", intent.INTENT_CANCEL_TIMER, {}, device_id=device_bob_kitchen_2.id
)
assert result.response_type == intent.IntentResponseType.ACTION_DONE