diff --git a/homeassistant/components/google_assistant/helpers.py b/homeassistant/components/google_assistant/helpers.py index 48664bff395..00633422939 100644 --- a/homeassistant/components/google_assistant/helpers.py +++ b/homeassistant/components/google_assistant/helpers.py @@ -17,6 +17,7 @@ from homeassistant.const import ( STATE_UNAVAILABLE, ) from homeassistant.core import Context, HomeAssistant, State, callback +from homeassistant.helpers.area_registry import AreaEntry from homeassistant.helpers.event import async_call_later from homeassistant.helpers.network import get_url from homeassistant.helpers.storage import Store @@ -39,6 +40,29 @@ SYNC_DELAY = 15 _LOGGER = logging.getLogger(__name__) +async def _get_area(hass, entity_id) -> Optional[AreaEntry]: + """Calculate the area for a entity_id.""" + dev_reg, ent_reg, area_reg = await gather( + hass.helpers.device_registry.async_get_registry(), + hass.helpers.entity_registry.async_get_registry(), + hass.helpers.area_registry.async_get_registry(), + ) + + entity_entry = ent_reg.async_get(entity_id) + if not entity_entry: + return None + + if entity_entry.area_id: + area_id = entity_entry.area_id + else: + device_entry = dev_reg.devices.get(entity_entry.device_id) + if not (device_entry and device_entry.area_id): + return None + area_id = device_entry.area_id + + return area_reg.areas.get(area_id) + + class AbstractConfig(ABC): """Hold the configuration for Google Assistant.""" @@ -450,25 +474,10 @@ class GoogleEntity: room = entity_config.get(CONF_ROOM_HINT) if room: device["roomHint"] = room - return device - - dev_reg, ent_reg, area_reg = await gather( - self.hass.helpers.device_registry.async_get_registry(), - self.hass.helpers.entity_registry.async_get_registry(), - self.hass.helpers.area_registry.async_get_registry(), - ) - - entity_entry = ent_reg.async_get(state.entity_id) - if not (entity_entry and entity_entry.device_id): - return device - - device_entry = dev_reg.devices.get(entity_entry.device_id) - if not (device_entry and device_entry.area_id): - return device - - area_entry = area_reg.areas.get(device_entry.area_id) - if area_entry and area_entry.name: - device["roomHint"] = area_entry.name + else: + area = await _get_area(self.hass, state.entity_id) + if area and area.name: + device["roomHint"] = area.name return device diff --git a/tests/components/google_assistant/test_smart_home.py b/tests/components/google_assistant/test_smart_home.py index 27e62fafc73..ebe34c2aa95 100644 --- a/tests/components/google_assistant/test_smart_home.py +++ b/tests/components/google_assistant/test_smart_home.py @@ -152,7 +152,8 @@ async def test_sync_message(hass): # pylint: disable=redefined-outer-name -async def test_sync_in_area(hass, registries): +@pytest.mark.parametrize("area_on_device", [True, False]) +async def test_sync_in_area(area_on_device, hass, registries): """Test a sync message where room hint comes from area.""" area = registries.area.async_create("Living Room") @@ -160,10 +161,17 @@ async def test_sync_in_area(hass, registries): config_entry_id="1234", connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) - registries.device.async_update_device(device.id, area_id=area.id) + registries.device.async_update_device( + device.id, area_id=area.id if area_on_device else None + ) entity = registries.entity.async_get_or_create( - "light", "test", "1235", suggested_object_id="demo_light", device_id=device.id + "light", + "test", + "1235", + suggested_object_id="demo_light", + device_id=device.id, + area_id=area.id if not area_on_device else None, ) light = DemoLight(