mirror of
https://github.com/home-assistant/core.git
synced 2026-08-24 10:13:52 -05:00
Invalidate conversation slot-list cache on device registry changes (#179486)
This commit is contained in:
@@ -83,6 +83,7 @@ _LOGGER = logging.getLogger(__name__)
|
||||
|
||||
_DEFAULT_ERROR_TEXT = "Sorry, I couldn't understand that"
|
||||
_ENTITY_REGISTRY_UPDATE_FIELDS = ["aliases", "name", "original_name"]
|
||||
_DEVICE_REGISTRY_UPDATE_FIELDS = ["name", "name_by_user"]
|
||||
|
||||
_DEFAULT_EXPOSED_ATTRIBUTES = {"device_class"}
|
||||
|
||||
@@ -288,6 +289,15 @@ class DefaultAgent(ConversationEntity):
|
||||
field in event_data["changes"] for field in _ENTITY_REGISTRY_UPDATE_FIELDS
|
||||
)
|
||||
|
||||
@callback
|
||||
def _filter_device_registry_changes(
|
||||
self, event_data: dr.EventDeviceRegistryUpdatedData
|
||||
) -> bool:
|
||||
"""Filter device registry changed events."""
|
||||
return event_data["action"] == "update" and any(
|
||||
field in event_data["changes"] for field in _DEVICE_REGISTRY_UPDATE_FIELDS
|
||||
)
|
||||
|
||||
@callback
|
||||
def _filter_state_changes(self, event_data: EventStateChangedData) -> bool:
|
||||
"""Filter state changed events."""
|
||||
@@ -312,6 +322,11 @@ class DefaultAgent(ConversationEntity):
|
||||
self._async_clear_slot_list,
|
||||
event_filter=self._filter_entity_registry_changes,
|
||||
),
|
||||
self.hass.bus.async_listen(
|
||||
dr.EVENT_DEVICE_REGISTRY_UPDATED,
|
||||
self._async_clear_slot_list,
|
||||
event_filter=self._filter_device_registry_changes,
|
||||
),
|
||||
self.hass.bus.async_listen(
|
||||
EVENT_STATE_CHANGED,
|
||||
self._async_clear_slot_list,
|
||||
|
||||
@@ -492,6 +492,54 @@ async def test_duplicated_names_resolved_with_device_area(
|
||||
assert result.response.intent.slots.get("name", {}).get("text") == name
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_components")
|
||||
async def test_device_rename_refreshes_slot_list(
|
||||
hass: HomeAssistant,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test renaming a device makes the entity matchable by its new computed name."""
|
||||
config_entry = MockConfigEntry()
|
||||
config_entry.add_to_hass(hass)
|
||||
device = device_registry.async_get_or_create(
|
||||
config_entry_id=config_entry.entry_id,
|
||||
connections=set(),
|
||||
identifiers={("demo", "device-1")},
|
||||
name="Kitchen",
|
||||
)
|
||||
|
||||
light = entity_registry.async_get_or_create(
|
||||
"light",
|
||||
"demo",
|
||||
"1234",
|
||||
device_id=device.id,
|
||||
has_entity_name=True,
|
||||
original_name="Light",
|
||||
)
|
||||
hass.states.async_set(light.entity_id, "off")
|
||||
expose_entity(hass, light.entity_id, True)
|
||||
|
||||
# Populate the slot list cache: the current computed name matches.
|
||||
calls = async_mock_service(hass, "light", "turn_on")
|
||||
result = await conversation.async_converse(
|
||||
hass, "turn on Kitchen Light", None, Context(), None
|
||||
)
|
||||
assert result.response.response_type is intent.IntentResponseType.ACTION_DONE
|
||||
assert len(calls) == 1
|
||||
|
||||
# Renaming the device changes the light's computed name to "Bedroom Light".
|
||||
device_registry.async_update_device(device.id, name_by_user="Bedroom")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# The new name is now matchable.
|
||||
calls = async_mock_service(hass, "light", "turn_on")
|
||||
result = await conversation.async_converse(
|
||||
hass, "turn on Bedroom Light", None, Context(), None
|
||||
)
|
||||
assert result.response.response_type is intent.IntentResponseType.ACTION_DONE
|
||||
assert len(calls) == 1
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_components")
|
||||
async def test_trigger_sentences(hass: HomeAssistant) -> None:
|
||||
"""Test registering/unregistering/matching a few trigger sentences."""
|
||||
|
||||
Reference in New Issue
Block a user