Esempio n. 1
0
async def test_loading_race_condition(hass):
    """Test only one storage load called when concurrent loading occurred ."""
    with tests.async_mock.patch(
            "homeassistant.helpers.entity_registry.EntityRegistry.async_load"
    ) as mock_load:
        results = await asyncio.gather(
            entity_registry.async_get_registry(hass),
            entity_registry.async_get_registry(hass),
        )

        mock_load.assert_called_once_with()
        assert results[0] == results[1]
async def test_loading_race_condition(hass):
    """Test only one storage load called when concurrent loading occurred ."""
    with asynctest.patch(
        'homeassistant.helpers.entity_registry.EntityRegistry.async_load',
    ) as mock_load:
        results = await asyncio.gather(
            entity_registry.async_get_registry(hass),
            entity_registry.async_get_registry(hass),
        )

        mock_load.assert_called_once_with()
        assert results[0] == results[1]
Esempio n. 3
0
def light_entities_for_group(group_name):
    """Find light entity IDs for the Philips Hue zone/room name.

    All configured Hue bridges are queried for the group. Pyscript must be configured to expose the
    "hass" global variable and allow all imports so that we can access the bridge configs and entity
    registry.

    :param group_name: The Hue zone/room name exactly as it appears in the Hue app (e.g. "Living room").
    :return: Set of light entity IDs for the group name or empty set if no matching group or entities are found.
    """
    entity_ids = set()

    # Load entity registry.
    entity_registry = er.async_get_registry(hass)
    # Find Hue bridge config(s).
    for config_entry in hass.config_entries.async_entries(domain="hue"):
        host, api_key = config_entry.data["host"], config_entry.data["api_key"]
        async with HueBridgeV2(host, api_key) as bridge:
            # Query Hue bridge for light services in the matching group(s), if any.
            for group in bridge.groups:
                if not hasattr(group, "metadata") or group.metadata.name != group_name:
                    continue

                lights_resolver = bridge.groups.room if group.type == ResourceTypes.ROOM else bridge.groups.zone
                light_ids = {light.id for light in lights_resolver.get_lights(group.id)}
                group_entity_ids = {
                    id
                    for id, entity in entity_registry.entities.items()
                    if entity.unique_id in light_ids and entity.platform == "hue"
                }
                log.debug(f"Found Hue group '{group_name}' on {host}; lights: {group_entity_ids}")
                entity_ids |= group_entity_ids
    return entity_ids
Esempio n. 4
0
async def async_extract_referenced_entity_ids(
        hass: HomeAssistantType,
        service_call: ha.ServiceCall,
        expand_group: bool = True) -> SelectedEntities:
    """Extract referenced entity IDs from a service call."""
    entity_ids = service_call.data.get(ATTR_ENTITY_ID)
    device_ids = service_call.data.get(ATTR_DEVICE_ID)
    area_ids = service_call.data.get(ATTR_AREA_ID)

    selects_entity_ids = entity_ids not in (None, ENTITY_MATCH_NONE)
    selects_device_ids = device_ids not in (None, ENTITY_MATCH_NONE)
    selects_area_ids = area_ids not in (None, ENTITY_MATCH_NONE)

    selected = SelectedEntities()

    if not selects_entity_ids and not selects_device_ids and not selects_area_ids:
        return selected

    if selects_entity_ids:
        assert entity_ids is not None

        # Entity ID attr can be a list or a string
        if isinstance(entity_ids, str):
            entity_ids = [entity_ids]

        if expand_group:
            entity_ids = hass.components.group.expand_entity_ids(entity_ids)

        selected.referenced.update(entity_ids)

    if not selects_device_ids and not selects_area_ids:
        return selected

    area_reg, dev_reg, ent_reg = cast(
        Tuple[area_registry.AreaRegistry, device_registry.DeviceRegistry,
              entity_registry.EntityRegistry, ],
        await asyncio.gather(
            area_registry.async_get_registry(hass),
            device_registry.async_get_registry(hass),
            entity_registry.async_get_registry(hass),
        ),
    )

    picked_devices = set()

    if selects_device_ids:
        if isinstance(device_ids, str):
            picked_devices = {device_ids}
        else:
            assert isinstance(device_ids, list)
            picked_devices = set(device_ids)

        for device_id in picked_devices:
            if device_id not in dev_reg.devices:
                selected.missing_devices.add(device_id)

    if selects_area_ids:
        assert area_ids is not None

        if isinstance(area_ids, str):
            area_lookup = {area_ids}
        else:
            area_lookup = set(area_ids)

        for area_id in area_lookup:
            if area_id not in area_reg.areas:
                selected.missing_areas.add(area_id)
                continue

        # Find entities tied to an area
        for entity_entry in ent_reg.entities.values():
            if entity_entry.area_id in area_lookup:
                selected.indirectly_referenced.add(entity_entry.entity_id)

        # Find devices for this area
        for device_entry in dev_reg.devices.values():
            if device_entry.area_id in area_lookup:
                picked_devices.add(device_entry.id)

    if not picked_devices:
        return selected

    for entity_entry in ent_reg.entities.values():
        if not entity_entry.area_id and entity_entry.device_id in picked_devices:
            selected.indirectly_referenced.add(entity_entry.entity_id)

    return selected
Esempio n. 5
0
 def _get_entry_id(self, entity_id: str):
     """ Resolve ConfigEntry.entry_id for entity_id """
     registry = asyncio.run_coroutine_threadsafe(
         er.async_get_registry(self._hass), self._hass.loop).result()
     return registry.async_get(entity_id).config_entry_id