Add excluded domains to broadcast intent (#137566)

This commit is contained in:
Michael Hansen 2025-02-06 10:53:55 -06:00 committed by Franck Nijhof
parent 42b6f83e7c
commit a033e4c88d
No known key found for this signature in database
GPG Key ID: D62583BA8AB11CA3
2 changed files with 66 additions and 26 deletions

View File

@ -1,5 +1,7 @@
"""Assist Satellite intents."""
from typing import Final
import voluptuous as vol
from homeassistant.core import HomeAssistant
@ -7,6 +9,8 @@ from homeassistant.helpers import entity_registry as er, intent
from .const import DOMAIN, AssistSatelliteEntityFeature
EXCLUDED_DOMAINS: Final[set[str]] = {"voip"}
async def async_setup_intents(hass: HomeAssistant) -> None:
"""Set up the intents."""
@ -30,19 +34,36 @@ class BroadcastIntentHandler(intent.IntentHandler):
ent_reg = er.async_get(hass)
# Find all assist satellite entities that are not the one invoking the intent
entities = {
entity: entry
for entity in hass.states.async_entity_ids(DOMAIN)
if (entry := ent_reg.async_get(entity))
and entry.supported_features & AssistSatelliteEntityFeature.ANNOUNCE
}
entities: dict[str, er.RegistryEntry] = {}
for entity in hass.states.async_entity_ids(DOMAIN):
entry = ent_reg.async_get(entity)
if (
(entry is None)
or (
# Supports announce
not (
entry.supported_features & AssistSatelliteEntityFeature.ANNOUNCE
)
)
# Not the invoking device
or (intent_obj.device_id and (entry.device_id == intent_obj.device_id))
):
# Skip satellite
continue
if intent_obj.device_id:
entities = {
entity: entry
for entity, entry in entities.items()
if entry.device_id != intent_obj.device_id
}
# Check domain of config entry against excluded domains
if (
entry.config_entry_id
and (
config_entry := hass.config_entries.async_get_entry(
entry.config_entry_id
)
)
and (config_entry.domain in EXCLUDED_DOMAINS)
):
continue
entities[entity] = entry
await hass.services.async_call(
DOMAIN,
@ -54,7 +75,6 @@ class BroadcastIntentHandler(intent.IntentHandler):
)
response = intent_obj.create_response()
response.async_set_speech("Done")
response.response_type = intent.IntentResponseType.ACTION_DONE
response.async_set_results(
success_results=[

View File

@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers import intent
from .conftest import MockAssistSatellite
from .conftest import TEST_DOMAIN, MockAssistSatellite
@pytest.fixture
@ -65,12 +65,7 @@ async def test_broadcast_intent(
},
"language": "en",
"response_type": "action_done",
"speech": {
"plain": {
"extra_data": None,
"speech": "Done",
}
},
"speech": {}, # response comes from intents
}
assert len(entity.announcements) == 1
assert len(entity2.announcements) == 1
@ -99,12 +94,37 @@ async def test_broadcast_intent(
},
"language": "en",
"response_type": "action_done",
"speech": {
"plain": {
"extra_data": None,
"speech": "Done",
}
},
"speech": {}, # response comes from intents
}
assert len(entity.announcements) == 1
assert len(entity2.announcements) == 2
async def test_broadcast_intent_excluded_domains(
hass: HomeAssistant,
init_components: ConfigEntry,
entity: MockAssistSatellite,
entity2: MockAssistSatellite,
mock_tts: None,
) -> None:
"""Test that the broadcast intent filters out entities in excluded domains."""
# Exclude the "test" domain
with patch(
"homeassistant.components.assist_satellite.intent.EXCLUDED_DOMAINS",
new={TEST_DOMAIN},
):
result = await intent.async_handle(
hass, "test", intent.INTENT_BROADCAST, {"message": {"value": "Hello"}}
)
assert result.as_dict() == {
"card": {},
"data": {
"failed": [],
"success": [], # no satellites
"targets": [],
},
"language": "en",
"response_type": "action_done",
"speech": {},
}