Ejemplo n.º 1
0
async def test_get_actions(
    hass: HomeAssistant,
    device_reg: device_registry.DeviceRegistry,
    entity_reg: entity_registry.EntityRegistry,
) -> None:
    """Test we get the expected actions from a button."""
    config_entry = MockConfigEntry(domain="test", data={})
    config_entry.add_to_hass(hass)
    device_entry = device_reg.async_get_or_create(
        config_entry_id=config_entry.entry_id,
        connections={(device_registry.CONNECTION_NETWORK_MAC,
                      "12:34:56:AB:CD:EF")},
    )
    entity_reg.async_get_or_create(DOMAIN,
                                   "test",
                                   "5678",
                                   device_id=device_entry.id)
    expected_actions = [{
        "domain": DOMAIN,
        "type": "press",
        "device_id": device_entry.id,
        "entity_id": "button.test_5678",
    }]
    actions = await async_get_device_automations(hass,
                                                 DeviceAutomationType.ACTION,
                                                 device_entry.id)
    assert_lists_same(actions, expected_actions)
async def test_get_conditions(
    hass: HomeAssistant,
    device_reg: device_registry.DeviceRegistry,
    entity_reg: entity_registry.EntityRegistry,
) -> None:
    """Test we get the expected conditions from a NEW_DOMAIN."""
    config_entry = MockConfigEntry(domain="test", data={})
    config_entry.add_to_hass(hass)
    device_entry = device_reg.async_get_or_create(
        config_entry_id=config_entry.entry_id,
        connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
    )
    entity_reg.async_get_or_create(DOMAIN, "test", "5678", device_id=device_entry.id)
    expected_conditions = [
        {
            "condition": "device",
            "domain": DOMAIN,
            "type": "is_off",
            "device_id": device_entry.id,
            "entity_id": f"{DOMAIN}.test_5678",
        },
        {
            "condition": "device",
            "domain": DOMAIN,
            "type": "is_on",
            "device_id": device_entry.id,
            "entity_id": f"{DOMAIN}.test_5678",
        },
    ]
    conditions = await async_get_device_automations(hass, "condition", device_entry.id)
    assert_lists_same(conditions, expected_conditions)
Ejemplo n.º 3
0
async def test_get_trigger_capabilities(hass: HomeAssistant,
                                        device_reg: DeviceRegistry,
                                        entity_reg: EntityRegistry) -> None:
    """Test we get the expected capabilities from a update trigger."""
    config_entry = MockConfigEntry(domain="test", data={})
    config_entry.add_to_hass(hass)
    device_entry = device_reg.async_get_or_create(
        config_entry_id=config_entry.entry_id,
        connections={(device_registry.CONNECTION_NETWORK_MAC,
                      "12:34:56:AB:CD:EF")},
    )
    entity_reg.async_get_or_create(DOMAIN,
                                   "test",
                                   "5678",
                                   device_id=device_entry.id)
    expected_capabilities = {
        "extra_fields": [{
            "name": "for",
            "optional": True,
            "type": "positive_time_period_dict"
        }]
    }
    triggers = await async_get_device_automations(hass,
                                                  DeviceAutomationType.TRIGGER,
                                                  device_entry.id)
    for trigger in triggers:
        capabilities = await async_get_device_automation_capabilities(
            hass, DeviceAutomationType.TRIGGER, trigger)
        assert capabilities == expected_capabilities
Ejemplo n.º 4
0
async def test_get_triggers(
    hass: HomeAssistant,
    device_reg: device_registry.DeviceRegistry,
    entity_reg: EntityRegistry,
) -> None:
    """Test we get the expected triggers from a button."""
    config_entry = MockConfigEntry(domain="test", data={})
    config_entry.add_to_hass(hass)
    device_entry = device_reg.async_get_or_create(
        config_entry_id=config_entry.entry_id,
        connections={(device_registry.CONNECTION_NETWORK_MAC,
                      "12:34:56:AB:CD:EF")},
    )
    entity_reg.async_get_or_create(DOMAIN,
                                   "test",
                                   "5678",
                                   device_id=device_entry.id)
    expected_triggers = [{
        "platform": "device",
        "domain": DOMAIN,
        "type": "pressed",
        "device_id": device_entry.id,
        "entity_id": f"{DOMAIN}.test_5678",
        "metadata": {
            "secondary": False
        },
    }]
    triggers = await async_get_device_automations(hass,
                                                  DeviceAutomationType.TRIGGER,
                                                  device_entry.id)
    assert_lists_same(triggers, expected_triggers)
Ejemplo n.º 5
0
async def test_dimmer_switch_unique_id_fix_original_entity_was_deleted(
        hass: HomeAssistant, entity_reg: EntityRegistry):
    """Test that roll out unique id entity id changed to the original unique id."""
    config_entry = MockConfigEntry(domain=DOMAIN,
                                   data={},
                                   unique_id=MAC_ADDRESS)
    config_entry.add_to_hass(hass)
    dimmer = _mocked_dimmer()
    rollout_unique_id = MAC_ADDRESS.replace(":", "").upper()
    original_unique_id = tplink.legacy_device_id(dimmer)
    rollout_dimmer_entity_reg = entity_reg.async_get_or_create(
        config_entry=config_entry,
        platform=DOMAIN,
        domain="light",
        unique_id=rollout_unique_id,
        original_name="Rollout dimmer",
    )

    with _patch_discovery(device=dimmer), _patch_single_discovery(
            device=dimmer):
        await setup.async_setup_component(hass, DOMAIN, {})
        await hass.async_block_till_done()

    migrated_dimmer_entity_reg = entity_reg.async_get_or_create(
        config_entry=config_entry,
        platform=DOMAIN,
        domain="light",
        unique_id=original_unique_id,
        original_name="Migrated dimmer",
    )
    assert migrated_dimmer_entity_reg.entity_id == rollout_dimmer_entity_reg.entity_id
Ejemplo n.º 6
0
def is_sensor_continuous(ent_reg: er.EntityRegistry, entity_id: str) -> bool:
    """Determine if a sensor is continuous by checking its state class.

    Sensors with a unit_of_measurement are also considered continuous, but are filtered
    already by the SQL query generated by _get_events
    """
    if not (entry := ent_reg.async_get(entity_id)):
        # Entity not registered, so can't have a state class
        return False
Ejemplo n.º 7
0
def check_and_enable_disabled_entities(
    entity_registry: EntityRegistry, expected_entities: MappingProxyType
) -> None:
    """Ensure that the expected_entities are correctly disabled."""
    for expected_entity in expected_entities:
        if expected_entity.get(ATTR_DEFAULT_DISABLED):
            entity_id = expected_entity[ATTR_ENTITY_ID]
            registry_entry = entity_registry.entities.get(entity_id)
            assert registry_entry.disabled
            assert registry_entry.disabled_by == "integration"
            entity_registry.async_update_entity(entity_id, **{"disabled_by": None})
async def test_migration_device_online_end_to_end_after_downgrade(
        hass: HomeAssistant, device_reg: DeviceRegistry,
        entity_reg: EntityRegistry):
    """Test migration from single config entry can happen again after a downgrade."""
    config_entry = MockConfigEntry(domain=DOMAIN, data={}, unique_id=DOMAIN)
    config_entry.add_to_hass(hass)

    already_migrated_config_entry = MockConfigEntry(
        domain=DOMAIN, data={CONF_HOST: IP_ADDRESS}, unique_id=MAC_ADDRESS)
    already_migrated_config_entry.add_to_hass(hass)
    device = device_reg.async_get_or_create(
        config_entry_id=config_entry.entry_id,
        connections={(dr.CONNECTION_NETWORK_MAC, MAC_ADDRESS)},
        name=ALIAS,
    )
    light_entity_reg = entity_reg.async_get_or_create(
        config_entry=config_entry,
        platform=DOMAIN,
        domain="light",
        unique_id=MAC_ADDRESS,
        original_name=ALIAS,
        device_id=device.id,
    )
    power_sensor_entity_reg = entity_reg.async_get_or_create(
        config_entry=config_entry,
        platform=DOMAIN,
        domain="sensor",
        unique_id=f"{MAC_ADDRESS}_sensor",
        original_name=ALIAS,
        device_id=device.id,
    )

    with _patch_discovery(), _patch_single_discovery():
        await setup.async_setup_component(hass, DOMAIN, {})
        await hass.async_block_till_done()

        assert device.config_entries == {config_entry.entry_id}
        assert light_entity_reg.config_entry_id == config_entry.entry_id
        assert power_sensor_entity_reg.config_entry_id == config_entry.entry_id
        assert er.async_entries_for_config_entry(entity_reg,
                                                 config_entry) == []

        hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
        await hass.async_block_till_done()

        legacy_entry = None
        for entry in hass.config_entries.async_entries(DOMAIN):
            if entry.unique_id == DOMAIN:
                legacy_entry = entry
                break

        assert legacy_entry is None
Ejemplo n.º 9
0
    async def _get_entity_and_device(self, ent_reg: EntityRegistry, dev_reg: DeviceRegistry) -> \
            tuple[RegistryEntry, DeviceEntry] | tuple[None, None]:
        """Fetch the entity and device entries."""
        entity_entry = ent_reg.async_get(self.entity_id)
        if not entity_entry:
            return None, None

        device_entry = dev_reg.devices.get(entity_entry.device_id)
        return entity_entry, device_entry
Ejemplo n.º 10
0
def _exclude_by_entity_registry(
    ent_reg: entity_registry.EntityRegistry,
    entity_id: str,
    include_entity_category: bool,
    include_hidden: bool,
) -> bool:
    """Filter out hidden entities and ones with entity category (unless specified)."""
    return bool(
        (entry := ent_reg.async_get(entity_id)) and
        ((not include_hidden and entry.hidden_by is not None) or
         (not include_entity_category and entry.entity_category is not None)))
Ejemplo n.º 11
0
async def test_get_triggers(hass: HomeAssistant, device_reg: DeviceRegistry,
                            entity_reg: EntityRegistry) -> None:
    """Test we get the expected triggers from a update entity."""
    config_entry = MockConfigEntry(domain="test", data={})
    config_entry.add_to_hass(hass)
    device_entry = device_reg.async_get_or_create(
        config_entry_id=config_entry.entry_id,
        connections={(device_registry.CONNECTION_NETWORK_MAC,
                      "12:34:56:AB:CD:EF")},
    )
    entity_reg.async_get_or_create(DOMAIN,
                                   "test",
                                   "5678",
                                   device_id=device_entry.id)
    expected_triggers = [
        {
            "platform": "device",
            "domain": DOMAIN,
            "type": "changed_states",
            "device_id": device_entry.id,
            "entity_id": f"{DOMAIN}.test_5678",
        },
        {
            "platform": "device",
            "domain": DOMAIN,
            "type": "turned_off",
            "device_id": device_entry.id,
            "entity_id": f"{DOMAIN}.test_5678",
        },
        {
            "platform": "device",
            "domain": DOMAIN,
            "type": "turned_on",
            "device_id": device_entry.id,
            "entity_id": f"{DOMAIN}.test_5678",
        },
    ]
    triggers = await async_get_device_automations(hass,
                                                  DeviceAutomationType.TRIGGER,
                                                  device_entry.id)
    assert triggers == expected_triggers
Ejemplo n.º 12
0
async def test_migration_device_online_end_to_end(hass: HomeAssistant,
                                                  device_reg: DeviceRegistry,
                                                  entity_reg: EntityRegistry):
    """Test migration from single config entry."""
    config_entry = MockConfigEntry(domain=DOMAIN,
                                   title="LEGACY",
                                   data={},
                                   unique_id=DOMAIN)
    config_entry.add_to_hass(hass)
    device = device_reg.async_get_or_create(
        config_entry_id=config_entry.entry_id,
        identifiers={(DOMAIN, SERIAL)},
        connections={(dr.CONNECTION_NETWORK_MAC, MAC_ADDRESS)},
        name=LABEL,
    )
    light_entity_reg = entity_reg.async_get_or_create(
        config_entry=config_entry,
        platform=DOMAIN,
        domain="light",
        unique_id=dr.format_mac(SERIAL),
        original_name=LABEL,
        device_id=device.id,
    )

    with _patch_discovery(), _patch_config_flow_try_connect(), _patch_device():
        await setup.async_setup_component(hass, DOMAIN, {})
        await hass.async_block_till_done()

        migrated_entry = None
        for entry in hass.config_entries.async_entries(DOMAIN):
            if entry.unique_id == DOMAIN:
                migrated_entry = entry
                break

        assert migrated_entry is not None

        assert device.config_entries == {migrated_entry.entry_id}
        assert light_entity_reg.config_entry_id == migrated_entry.entry_id
        assert er.async_entries_for_config_entry(entity_reg,
                                                 config_entry) == []

        hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
        await hass.async_block_till_done()
        async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=20))
        await hass.async_block_till_done()

        legacy_entry = None
        for entry in hass.config_entries.async_entries(DOMAIN):
            if entry.unique_id == DOMAIN:
                legacy_entry = entry
                break

        assert legacy_entry is None
Ejemplo n.º 13
0
def async_migrate_entity(
    ent_reg: EntityRegistry, platform: str, old_unique_id: str, new_unique_id: str
) -> None:
    """Check if entity with old unique ID exists, and if so migrate it to new ID."""
    if entity_id := ent_reg.async_get_entity_id(platform, DOMAIN, old_unique_id):
        _LOGGER.debug(
            "Migrating entity %s from old unique ID '%s' to new unique ID '%s'",
            entity_id,
            old_unique_id,
            new_unique_id,
        )
        try:
            ent_reg.async_update_entity(
                entity_id,
                new_unique_id=new_unique_id,
            )
        except ValueError:
            _LOGGER.debug(
                (
                    "Entity %s can't be migrated because the unique ID is taken; "
                    "Cleaning it up since it is likely no longer valid"
                ),
                entity_id,
            )
            ent_reg.async_remove(entity_id)
Ejemplo n.º 14
0
    async def code_slots_changed(
        ent_reg: EntityRegistry,
        platform: entity_platform.EntityPlatform,
        config_entry: ConfigEntry,
        old_slots: List[int],
        new_slots: List[int],
    ):
        """Handle code slots changed."""
        slots_to_add = list(set(new_slots) - set(old_slots))
        slots_to_remove = list(set(old_slots) - set(new_slots))
        for slot in slots_to_remove:
            sensor_name = slugify(
                f"{config_entry.data[CONF_LOCK_NAME]}_code_slot_{slot}"
            )
            entity_id = f"sensor.{sensor_name}"
            if ent_reg.async_get(entity_id):
                await platform.async_remove_entity(entity_id)
                ent_reg.async_remove(entity_id)

        async_add_entities(
            [CodesSensor(hass, entry, x) for x in slots_to_add],
            True,
        )
Ejemplo n.º 15
0
def async_migrate_old_entity(
    hass: HomeAssistant,
    ent_reg: EntityRegistry,
    registered_unique_ids: set[str],
    platform: str,
    device: DeviceEntry,
    unique_id: str,
) -> None:
    """Migrate existing entity if current one can't be found and an old one exists."""
    # If we can find an existing entity with this unique ID, there's nothing to migrate
    if ent_reg.async_get_entity_id(platform, DOMAIN, unique_id):
        return

    value_id = ValueID.from_unique_id(unique_id)

    # Look for existing entities in the registry that could be the same value but on
    # a different endpoint
    existing_entity_entries: list[RegistryEntry] = []
    for entry in async_entries_for_device(ent_reg, device.id):
        # If entity is not in the domain for this discovery info or entity has already
        # been processed, skip it
        if entry.domain != platform or entry.unique_id in registered_unique_ids:
            continue

        try:
            old_ent_value_id = ValueID.from_unique_id(entry.unique_id)
        # Skip non value ID based unique ID's (e.g. node status sensor)
        except IndexError:
            continue

        if value_id.is_same_value_different_endpoints(old_ent_value_id):
            existing_entity_entries.append(entry)
            # We can return early if we get more than one result
            if len(existing_entity_entries) > 1:
                return

    # If we couldn't find any results, return early
    if not existing_entity_entries:
        return

    entry = existing_entity_entries[0]
    state = hass.states.get(entry.entity_id)

    if not state or state.state == STATE_UNAVAILABLE:
        async_migrate_unique_id(ent_reg, platform, entry.unique_id, unique_id)
async def test_migration_device_online_end_to_end_ignores_other_devices(
        hass: HomeAssistant, device_reg: DeviceRegistry,
        entity_reg: EntityRegistry):
    """Test migration from single config entry."""
    config_entry = MockConfigEntry(domain=DOMAIN, data={}, unique_id=DOMAIN)
    config_entry.add_to_hass(hass)

    other_domain_config_entry = MockConfigEntry(domain="other_domain",
                                                data={},
                                                unique_id="other_domain")
    other_domain_config_entry.add_to_hass(hass)
    device = device_reg.async_get_or_create(
        config_entry_id=config_entry.entry_id,
        connections={(dr.CONNECTION_NETWORK_MAC, MAC_ADDRESS)},
        name=ALIAS,
    )
    other_device = device_reg.async_get_or_create(
        config_entry_id=other_domain_config_entry.entry_id,
        connections={(dr.CONNECTION_NETWORK_MAC, "556655665566")},
        name=ALIAS,
    )
    light_entity_reg = entity_reg.async_get_or_create(
        config_entry=config_entry,
        platform=DOMAIN,
        domain="light",
        unique_id=MAC_ADDRESS,
        original_name=ALIAS,
        device_id=device.id,
    )
    power_sensor_entity_reg = entity_reg.async_get_or_create(
        config_entry=config_entry,
        platform=DOMAIN,
        domain="sensor",
        unique_id=f"{MAC_ADDRESS}_sensor",
        original_name=ALIAS,
        device_id=device.id,
    )
    ignored_entity_reg = entity_reg.async_get_or_create(
        config_entry=other_domain_config_entry,
        platform=DOMAIN,
        domain="sensor",
        unique_id="00:00:00:00:00:00_sensor",
        original_name=ALIAS,
        device_id=device.id,
    )
    garbage_entity_reg = entity_reg.async_get_or_create(
        config_entry=config_entry,
        platform=DOMAIN,
        domain="sensor",
        unique_id="garbage",
        original_name=ALIAS,
        device_id=other_device.id,
    )

    with _patch_discovery(), _patch_single_discovery():
        await setup.async_setup_component(hass, DOMAIN, {})
        await hass.async_block_till_done()

        migrated_entry = None
        for entry in hass.config_entries.async_entries(DOMAIN):
            if entry.unique_id == DOMAIN:
                migrated_entry = entry
                break

        assert migrated_entry is not None

        assert device.config_entries == {migrated_entry.entry_id}
        assert light_entity_reg.config_entry_id == migrated_entry.entry_id
        assert power_sensor_entity_reg.config_entry_id == migrated_entry.entry_id
        assert ignored_entity_reg.config_entry_id == other_domain_config_entry.entry_id
        assert garbage_entity_reg.config_entry_id == config_entry.entry_id

        assert er.async_entries_for_config_entry(entity_reg,
                                                 config_entry) == []

        hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
        await hass.async_block_till_done()

        legacy_entry = None
        for entry in hass.config_entries.async_entries(DOMAIN):
            if entry.unique_id == DOMAIN:
                legacy_entry = entry
                break

        assert legacy_entry is not None
Ejemplo n.º 17
0
    async def devices_serialize(self, entity_reg: EntityRegistry,
                                dev_reg: DeviceRegistry):
        """Serialize entity for a devices response.

        https://yandex.ru/dev/dialogs/alice/doc/smart-home/reference/get-devices-docpage/
        """
        state = self.state

        # When a state is unavailable, the attributes that describe
        # capabilities will be stripped. For example, a light entity will miss
        # the min/max mireds. Therefore they will be excluded from a sync.
        if state.state == STATE_UNAVAILABLE:
            return None

        entity_config = self.config.entity_config.get(state.entity_id, {})
        name = (entity_config.get(CONF_NAME) or state.name).strip()
        domain = state.domain
        device_class = state.attributes.get(ATTR_DEVICE_CLASS)

        # If an empty string
        if not name:
            return None

        capabilities = self.capabilities()
        properties = self.properties()

        # Found no supported capabilities for this entity
        if not capabilities and not properties:
            return None

        device_type = get_yandex_type(domain, device_class)

        entry = entity_reg.async_get(state.entity_id)
        device = dev_reg.async_get(getattr(entry, 'device_id', ""))

        manufacturer = state.entity_id + ' | ' + getattr(
            device, "manufacturer", "Yandex Smart Home")
        model = getattr(device, "model", "")

        device_info = {'manufacturer': manufacturer, 'model': model}

        device = {
            'id': state.entity_id,
            'name': name,
            'type': device_type,
            'capabilities': [],
            'properties': [],
            'device_info': device_info,
        }

        for cpb in capabilities:
            description = cpb.description()
            if description not in device['capabilities']:
                device['capabilities'].append(description)

        for ppt in properties:
            description = ppt.description()
            if description not in device['properties']:
                device['properties'].append(description)

        override_type = entity_config.get(CONF_TYPE)
        if override_type:
            device['type'] = override_type

        room = entity_config.get(CONF_ROOM)
        if room:
            device['room'] = 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['room'] = area_entry.name

        return device
Ejemplo n.º 18
0
async def test_migration_device_online_end_to_end_ignores_other_devices(
        hass: HomeAssistant, device_reg: DeviceRegistry,
        entity_reg: EntityRegistry):
    """Test migration from single config entry."""
    legacy_config_entry = MockConfigEntry(domain=DOMAIN,
                                          title="LEGACY",
                                          data={},
                                          unique_id=DOMAIN)
    legacy_config_entry.add_to_hass(hass)

    other_domain_config_entry = MockConfigEntry(domain="other_domain",
                                                data={},
                                                unique_id="other_domain")
    other_domain_config_entry.add_to_hass(hass)
    device = device_reg.async_get_or_create(
        config_entry_id=legacy_config_entry.entry_id,
        identifiers={(DOMAIN, SERIAL)},
        connections={(dr.CONNECTION_NETWORK_MAC, MAC_ADDRESS)},
        name=LABEL,
    )
    other_device = device_reg.async_get_or_create(
        config_entry_id=other_domain_config_entry.entry_id,
        connections={(dr.CONNECTION_NETWORK_MAC, "556655665566")},
        name=LABEL,
    )
    light_entity_reg = entity_reg.async_get_or_create(
        config_entry=legacy_config_entry,
        platform=DOMAIN,
        domain="light",
        unique_id=SERIAL,
        original_name=LABEL,
        device_id=device.id,
    )
    ignored_entity_reg = entity_reg.async_get_or_create(
        config_entry=other_domain_config_entry,
        platform=DOMAIN,
        domain="sensor",
        unique_id="00:00:00:00:00:00_sensor",
        original_name=LABEL,
        device_id=device.id,
    )
    garbage_entity_reg = entity_reg.async_get_or_create(
        config_entry=legacy_config_entry,
        platform=DOMAIN,
        domain="sensor",
        unique_id="garbage",
        original_name=LABEL,
        device_id=other_device.id,
    )

    with _patch_discovery(), _patch_config_flow_try_connect(), _patch_device():
        await setup.async_setup_component(hass, DOMAIN, {})
        await hass.async_block_till_done()
        hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
        await hass.async_block_till_done()
        async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=20))
        await hass.async_block_till_done()

        new_entry = None
        legacy_entry = None
        for entry in hass.config_entries.async_entries(DOMAIN):
            if entry.unique_id == DOMAIN:
                legacy_entry = entry
            else:
                new_entry = entry

        assert new_entry is not None
        assert legacy_entry is None

        assert device.config_entries == {legacy_config_entry.entry_id}
        assert light_entity_reg.config_entry_id == legacy_config_entry.entry_id
        assert ignored_entity_reg.config_entry_id == other_domain_config_entry.entry_id
        assert garbage_entity_reg.config_entry_id == legacy_config_entry.entry_id

        assert er.async_entries_for_config_entry(entity_reg,
                                                 legacy_config_entry) == []
        assert dr.async_entries_for_config_entry(device_reg,
                                                 legacy_config_entry) == []
Ejemplo n.º 19
0
async def test_discovery_is_more_frequent_during_migration(
        hass: HomeAssistant, device_reg: DeviceRegistry,
        entity_reg: EntityRegistry):
    """Test that discovery is more frequent during migration."""
    config_entry = MockConfigEntry(domain=DOMAIN,
                                   title="LEGACY",
                                   data={},
                                   unique_id=DOMAIN)
    config_entry.add_to_hass(hass)
    device = device_reg.async_get_or_create(
        config_entry_id=config_entry.entry_id,
        identifiers={(DOMAIN, SERIAL)},
        connections={(dr.CONNECTION_NETWORK_MAC, MAC_ADDRESS)},
        name=LABEL,
    )
    entity_reg.async_get_or_create(
        config_entry=config_entry,
        platform=DOMAIN,
        domain="light",
        unique_id=dr.format_mac(SERIAL),
        original_name=LABEL,
        device_id=device.id,
    )

    bulb = _mocked_bulb()
    start_calls = 0

    class MockLifxDiscovery:
        """Mock lifx discovery."""
        def __init__(self, *args, **kwargs):
            """Init discovery."""
            self.bulb = bulb
            self.lights = {}

        def start(self):
            """Mock start."""
            nonlocal start_calls
            start_calls += 1
            # Discover the bulb so we can complete migration
            # and verify we switch back to normal discovery
            # interval
            if start_calls == 4:
                self.lights = {self.bulb.mac_addr: self.bulb}

        def cleanup(self):
            """Mock cleanup."""

    with _patch_device(device=bulb), _patch_config_flow_try_connect(
            device=bulb), patch.object(discovery, "DEFAULT_TIMEOUT", 0), patch(
                "homeassistant.components.lifx.discovery.LifxDiscovery",
                MockLifxDiscovery):
        await async_setup_component(hass, lifx.DOMAIN, {lifx.DOMAIN: {}})
        await hass.async_block_till_done()
        assert start_calls == 0

        hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
        await hass.async_block_till_done()
        assert start_calls == 1

        async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=5))
        await hass.async_block_till_done()
        assert start_calls == 3

        async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=10))
        await hass.async_block_till_done()
        assert start_calls == 4

        async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=15))
        await hass.async_block_till_done()
        assert start_calls == 5