From 0e4c32efe2b761ff376706ec0d56ba9b4573e7bc Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Wed, 1 Mar 2023 03:56:18 +0100 Subject: [PATCH] Adjust registry access in conversation (#88879) --- .../components/conversation/default_agent.py | 16 +-- .../conversation/test_default_agent.py | 46 ++++---- tests/components/conversation/test_init.py | 100 +++++++++++------- 3 files changed, 94 insertions(+), 68 deletions(-) diff --git a/homeassistant/components/conversation/default_agent.py b/homeassistant/components/conversation/default_agent.py index 78002b42f69..49569f66ac0 100644 --- a/homeassistant/components/conversation/default_agent.py +++ b/homeassistant/components/conversation/default_agent.py @@ -18,9 +18,9 @@ import yaml from homeassistant import core, setup from homeassistant.helpers import ( - area_registry, - device_registry, - entity_registry, + area_registry as ar, + device_registry as dr, + entity_registry as er, intent, template, translation, @@ -95,12 +95,12 @@ class DefaultAgent(AbstractConversationAgent): self._config_intents = config_intents self.hass.bus.async_listen( - area_registry.EVENT_AREA_REGISTRY_UPDATED, + ar.EVENT_AREA_REGISTRY_UPDATED, self._async_handle_area_registry_changed, run_immediately=True, ) self.hass.bus.async_listen( - entity_registry.EVENT_ENTITY_REGISTRY_UPDATED, + er.EVENT_ENTITY_REGISTRY_UPDATED, self._async_handle_entity_registry_changed, run_immediately=True, ) @@ -471,8 +471,8 @@ class DefaultAgent(AbstractConversationAgent): states = [ state for state in self.hass.states.async_all() if is_entity_exposed(state) ] - entities = entity_registry.async_get(self.hass) - devices = device_registry.async_get(self.hass) + entities = er.async_get(self.hass) + devices = dr.async_get(self.hass) # Gather exposed entity names entity_names = [] @@ -512,7 +512,7 @@ class DefaultAgent(AbstractConversationAgent): entity_names.append((state.name, state.name, context)) # Gather areas from exposed entities - areas = area_registry.async_get(self.hass) + areas = ar.async_get(self.hass) area_names = [] for area_id in area_ids_with_entities: area = areas.async_get_area(area_id) diff --git a/tests/components/conversation/test_default_agent.py b/tests/components/conversation/test_default_agent.py index 726ee4dc6e3..338d840c4a7 100644 --- a/tests/components/conversation/test_default_agent.py +++ b/tests/components/conversation/test_default_agent.py @@ -7,10 +7,10 @@ from homeassistant.components import conversation from homeassistant.const import ATTR_FRIENDLY_NAME from homeassistant.core import DOMAIN as HASS_DOMAIN, Context, HomeAssistant from homeassistant.helpers import ( - area_registry, - device_registry, + area_registry as ar, + device_registry as dr, entity, - entity_registry, + entity_registry as er, intent, ) from homeassistant.setup import async_setup_component @@ -29,19 +29,18 @@ async def init_components(hass): @pytest.mark.parametrize( "er_kwargs", [ - {"hidden_by": entity_registry.RegistryEntryHider.USER}, - {"hidden_by": entity_registry.RegistryEntryHider.INTEGRATION}, + {"hidden_by": er.RegistryEntryHider.USER}, + {"hidden_by": er.RegistryEntryHider.INTEGRATION}, {"entity_category": entity.EntityCategory.CONFIG}, {"entity_category": entity.EntityCategory.DIAGNOSTIC}, ], ) async def test_hidden_entities_skipped( - hass: HomeAssistant, init_components, er_kwargs + hass: HomeAssistant, init_components, er_kwargs, entity_registry: er.EntityRegistry ) -> None: """Test we skip hidden entities.""" - er = entity_registry.async_get(hass) - er.async_get_or_create( + entity_registry.async_get_or_create( "light", "demo", "1234", suggested_object_id="Test light", **er_kwargs ) hass.states.async_set("light.test_light", "off") @@ -71,27 +70,34 @@ async def test_exposed_domains(hass: HomeAssistant, init_components) -> None: assert result.response.error_code == intent.IntentResponseErrorCode.NO_INTENT_MATCH -async def test_exposed_areas(hass: HomeAssistant, init_components) -> None: +async def test_exposed_areas( + hass: HomeAssistant, + init_components, + area_registry: ar.AreaRegistry, + device_registry: dr.DeviceRegistry, + entity_registry: er.EntityRegistry, +) -> None: """Test that only expose areas with an exposed entity/device.""" - areas = area_registry.async_get(hass) - area_kitchen = areas.async_get_or_create("kitchen") - area_bedroom = areas.async_get_or_create("bedroom") + area_kitchen = area_registry.async_get_or_create("kitchen") + area_bedroom = area_registry.async_get_or_create("bedroom") - devices = device_registry.async_get(hass) - kitchen_device = devices.async_get_or_create( + kitchen_device = device_registry.async_get_or_create( config_entry_id="1234", connections=set(), identifiers={("demo", "id-1234")} ) - devices.async_update_device(kitchen_device.id, area_id=area_kitchen.id) + device_registry.async_update_device(kitchen_device.id, area_id=area_kitchen.id) - entities = entity_registry.async_get(hass) - kitchen_light = entities.async_get_or_create("light", "demo", "1234") - entities.async_update_entity(kitchen_light.entity_id, device_id=kitchen_device.id) + kitchen_light = entity_registry.async_get_or_create("light", "demo", "1234") + entity_registry.async_update_entity( + kitchen_light.entity_id, device_id=kitchen_device.id + ) hass.states.async_set( kitchen_light.entity_id, "on", attributes={ATTR_FRIENDLY_NAME: "kitchen light"} ) - bedroom_light = entities.async_get_or_create("light", "demo", "5678") - entities.async_update_entity(bedroom_light.entity_id, area_id=area_bedroom.id) + bedroom_light = entity_registry.async_get_or_create("light", "demo", "5678") + entity_registry.async_update_entity( + bedroom_light.entity_id, area_id=area_bedroom.id + ) hass.states.async_set( bedroom_light.entity_id, "on", attributes={ATTR_FRIENDLY_NAME: "bedroom light"} ) diff --git a/tests/components/conversation/test_init.py b/tests/components/conversation/test_init.py index f0f5698705e..55a345bd605 100644 --- a/tests/components/conversation/test_init.py +++ b/tests/components/conversation/test_init.py @@ -12,9 +12,9 @@ from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN from homeassistant.const import ATTR_FRIENDLY_NAME from homeassistant.core import Context, HomeAssistant from homeassistant.helpers import ( - area_registry, - device_registry, - entity_registry, + area_registry as ar, + device_registry as dr, + entity_registry as er, intent, ) from homeassistant.setup import async_setup_component @@ -53,12 +53,14 @@ async def test_http_processing_intent( hass_client: ClientSessionGenerator, hass_admin_user: MockUser, agent_id, + entity_registry: er.EntityRegistry, ) -> None: """Test processing intent via HTTP API.""" # Add an alias - entities = entity_registry.async_get(hass) - entities.async_get_or_create("light", "demo", "1234", suggested_object_id="kitchen") - entities.async_update_entity("light.kitchen", aliases={"my cool light"}) + entity_registry.async_get_or_create( + "light", "demo", "1234", suggested_object_id="kitchen" + ) + entity_registry.async_update_entity("light.kitchen", aliases={"my cool light"}) hass.states.async_set("light.kitchen", "off") calls = async_mock_service(hass, LIGHT_DOMAIN, "turn_on") @@ -101,12 +103,14 @@ async def test_http_processing_intent_target_ha_agent( hass_client: ClientSessionGenerator, hass_admin_user: MockUser, mock_agent, + entity_registry: er.EntityRegistry, ) -> None: """Test processing intent can be processed via HTTP API with picking agent.""" # Add an alias - entities = entity_registry.async_get(hass) - entities.async_get_or_create("light", "demo", "1234", suggested_object_id="kitchen") - entities.async_update_entity("light.kitchen", aliases={"my cool light"}) + entity_registry.async_get_or_create( + "light", "demo", "1234", suggested_object_id="kitchen" + ) + entity_registry.async_update_entity("light.kitchen", aliases={"my cool light"}) hass.states.async_set("light.kitchen", "off") calls = async_mock_service(hass, LIGHT_DOMAIN, "turn_on") @@ -148,15 +152,17 @@ async def test_http_processing_intent_entity_added( init_components, hass_client: ClientSessionGenerator, hass_admin_user: MockUser, + entity_registry: er.EntityRegistry, ) -> None: """Test processing intent via HTTP API with entities added later. We want to ensure that adding an entity later busts the cache so that the new entity is available as well as any aliases. """ - er = entity_registry.async_get(hass) - er.async_get_or_create("light", "demo", "1234", suggested_object_id="kitchen") - er.async_update_entity("light.kitchen", aliases={"my cool light"}) + entity_registry.async_get_or_create( + "light", "demo", "1234", suggested_object_id="kitchen" + ) + entity_registry.async_update_entity("light.kitchen", aliases={"my cool light"}) hass.states.async_set("light.kitchen", "off") calls = async_mock_service(hass, LIGHT_DOMAIN, "turn_on") @@ -192,7 +198,9 @@ async def test_http_processing_intent_entity_added( } # Add an alias - er.async_get_or_create("light", "demo", "5678", suggested_object_id="late") + entity_registry.async_get_or_create( + "light", "demo", "5678", suggested_object_id="late" + ) hass.states.async_set("light.late", "off", {"friendly_name": "friendly light"}) client = await hass_client() @@ -226,7 +234,7 @@ async def test_http_processing_intent_entity_added( } # Now add an alias - er.async_update_entity("light.late", aliases={"late added light"}) + entity_registry.async_update_entity("light.late", aliases={"late added light"}) client = await hass_client() resp = await client.post( @@ -259,7 +267,7 @@ async def test_http_processing_intent_entity_added( } # Now delete the entity - er.async_remove("light.late") + entity_registry.async_remove("light.late") client = await hass_client() resp = await client.post( @@ -786,23 +794,28 @@ async def test_non_default_response(hass: HomeAssistant, init_components) -> Non assert result.response.speech["plain"]["speech"] == "Opened" -async def test_turn_on_area(hass: HomeAssistant, init_components) -> None: +async def test_turn_on_area( + hass: HomeAssistant, + init_components, + area_registry: ar.AreaRegistry, + device_registry: dr.DeviceRegistry, + entity_registry: er.EntityRegistry, +) -> None: """Test turning on an area.""" - er = entity_registry.async_get(hass) - dr = device_registry.async_get(hass) - ar = area_registry.async_get(hass) entry = MockConfigEntry(domain="test") - device = dr.async_get_or_create( + device = device_registry.async_get_or_create( config_entry_id=entry.entry_id, - connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) - kitchen_area = ar.async_create("kitchen") - dr.async_update_device(device.id, area_id=kitchen_area.id) + kitchen_area = area_registry.async_create("kitchen") + device_registry.async_update_device(device.id, area_id=kitchen_area.id) - er.async_get_or_create("light", "demo", "1234", suggested_object_id="stove") - er.async_update_entity( + entity_registry.async_get_or_create( + "light", "demo", "1234", suggested_object_id="stove" + ) + entity_registry.async_update_entity( "light.stove", aliases={"my stove light"}, area_id=kitchen_area.id ) hass.states.async_set("light.stove", "off") @@ -822,9 +835,9 @@ async def test_turn_on_area(hass: HomeAssistant, init_components) -> None: assert call.service == "turn_on" assert call.data == {"entity_id": ["light.stove"]} - basement_area = ar.async_create("basement") - dr.async_update_device(device.id, area_id=basement_area.id) - er.async_update_entity("light.stove", area_id=basement_area.id) + basement_area = area_registry.async_create("basement") + device_registry.async_update_device(device.id, area_id=basement_area.id) + entity_registry.async_update_entity("light.stove", area_id=basement_area.id) calls.clear() # Test that the area is updated @@ -852,33 +865,40 @@ async def test_turn_on_area(hass: HomeAssistant, init_components) -> None: assert call.data == {"entity_id": ["light.stove"]} -async def test_light_area_same_name(hass: HomeAssistant, init_components) -> None: +async def test_light_area_same_name( + hass: HomeAssistant, + init_components, + area_registry: ar.AreaRegistry, + device_registry: dr.DeviceRegistry, + entity_registry: er.EntityRegistry, +) -> None: """Test turning on a light with the same name as an area.""" - entities = entity_registry.async_get(hass) - devices = device_registry.async_get(hass) - areas = area_registry.async_get(hass) entry = MockConfigEntry(domain="test") - device = devices.async_get_or_create( + device = device_registry.async_get_or_create( config_entry_id=entry.entry_id, - connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) - kitchen_area = areas.async_create("kitchen") - devices.async_update_device(device.id, area_id=kitchen_area.id) + kitchen_area = area_registry.async_create("kitchen") + device_registry.async_update_device(device.id, area_id=kitchen_area.id) - kitchen_light = entities.async_get_or_create( + kitchen_light = entity_registry.async_get_or_create( "light", "demo", "1234", original_name="kitchen light" ) - entities.async_update_entity(kitchen_light.entity_id, area_id=kitchen_area.id) + entity_registry.async_update_entity( + kitchen_light.entity_id, area_id=kitchen_area.id + ) hass.states.async_set( kitchen_light.entity_id, "off", attributes={ATTR_FRIENDLY_NAME: "kitchen light"} ) - ceiling_light = entities.async_get_or_create( + ceiling_light = entity_registry.async_get_or_create( "light", "demo", "5678", original_name="ceiling light" ) - entities.async_update_entity(ceiling_light.entity_id, area_id=kitchen_area.id) + entity_registry.async_update_entity( + ceiling_light.entity_id, area_id=kitchen_area.id + ) hass.states.async_set( ceiling_light.entity_id, "off", attributes={ATTR_FRIENDLY_NAME: "ceiling light"} )