Ejemplo n.º 1
0
async def async_setup_entry(
    hass: HomeAssistant,
    config_entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up Cast from a config entry."""
    hass.data.setdefault(ADDED_CAST_DEVICES_KEY, set())

    # Import CEC IGNORE attributes
    pychromecast.IGNORE_CEC += config_entry.data.get(CONF_IGNORE_CEC) or []

    wanted_uuids = config_entry.data.get(CONF_UUID) or None

    @callback
    def async_cast_discovered(discover: ChromecastInfo) -> None:
        """Handle discovery of a new chromecast."""
        # If wanted_uuids is set, we're only accepting specific cast devices identified
        # by UUID
        if wanted_uuids is not None and str(discover.uuid) not in wanted_uuids:
            # UUID not matching, ignore.
            return

        cast_device = _async_create_cast_device(hass, discover)
        if cast_device is not None:
            async_add_entities([cast_device])

    async_dispatcher_connect(hass, SIGNAL_CAST_DISCOVERED,
                             async_cast_discovered)
    ChromeCastZeroconf.set_zeroconf(await zeroconf.async_get_instance(hass))
    hass.async_add_executor_job(setup_internal_discovery, hass, config_entry)
Ejemplo n.º 2
0
async def _async_get_custom_components(
    hass: HomeAssistant, ) -> dict[str, Integration]:
    """Return list of custom integrations."""
    if hass.config.safe_mode:
        return {}

    try:
        import custom_components  # pylint: disable=import-outside-toplevel
    except ImportError:
        return {}

    def get_sub_directories(paths: list[str]) -> list[pathlib.Path]:
        """Return all sub directories in a set of paths."""
        return [
            entry for path in paths for entry in pathlib.Path(path).iterdir()
            if entry.is_dir()
        ]

    dirs = await hass.async_add_executor_job(get_sub_directories,
                                             custom_components.__path__)

    integrations = await asyncio.gather(*(hass.async_add_executor_job(
        Integration.resolve_from_root, hass, custom_components, comp.name)
                                          for comp in dirs))

    return {
        integration.domain: integration
        for integration in integrations if integration is not None
    }
Ejemplo n.º 3
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
    """Set up a wemo config entry."""
    config = hass.data[DOMAIN].pop("config")

    # Keep track of WeMo device subscriptions for push updates
    registry = hass.data[DOMAIN]["registry"] = pywemo.SubscriptionRegistry()
    await hass.async_add_executor_job(registry.start)

    wemo_dispatcher = WemoDispatcher(entry)
    wemo_discovery = WemoDiscovery(hass, wemo_dispatcher)

    async def async_stop_wemo(event):
        """Shutdown Wemo subscriptions and subscription thread on exit."""
        _LOGGER.debug("Shutting down WeMo event subscriptions")
        await hass.async_add_executor_job(registry.stop)
        wemo_discovery.async_stop_discovery()

    hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, async_stop_wemo)

    static_conf = config.get(CONF_STATIC, [])
    if static_conf:
        _LOGGER.debug("Adding statically configured WeMo devices")
        for device in await asyncio.gather(*[
                hass.async_add_executor_job(validate_static_config, host, port)
                for host, port in static_conf
        ]):
            if device:
                wemo_dispatcher.async_add_unique_device(hass, device)

    if config.get(CONF_DISCOVERY, DEFAULT_DISCOVERY):
        await wemo_discovery.async_discover_and_schedule()

    return True
Ejemplo n.º 4
0
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Unload a config entry."""
    unload = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
    await asyncio.gather(
        *(hass.async_add_executor_job(gateway.websocket_disconnect)
          for gateway in hass.data[DOMAIN][entry.entry_id]["gateways"]))
    hass.data[DOMAIN][entry.entry_id]["listener"]()
    hass.data[DOMAIN].pop(entry.entry_id)
    return unload
Ejemplo n.º 5
0
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
    """Unload Withings config entry."""
    controller_data: ControllerData = get_controller_data(hass, config_entry)

    tasks: list[Awaitable] = [
        hass.config_entries.async_forward_entry_unload(config_entry, platform)
        for platform in get_configured_platforms(controller_data)
    ]
    tasks.append(hass.async_add_executor_job(controller_data.controller.stop))
    await asyncio.gather(*tasks)

    return True
Ejemplo n.º 6
0
async def async_get_component_strings(
    hass: HomeAssistant, language: str, components: set[str]
) -> dict[str, Any]:
    """Load translations."""
    domains = list({loaded.split(".")[-1] for loaded in components})
    integrations = dict(
        zip(
            domains,
            await gather_with_concurrency(
                MAX_LOAD_CONCURRENTLY,
                *(async_get_integration(hass, domain) for domain in domains),
            ),
        )
    )

    translations: dict[str, Any] = {}

    # Determine paths of missing components/platforms
    files_to_load = {}
    for loaded in components:
        parts = loaded.split(".")
        domain = parts[-1]
        integration = integrations[domain]

        path = component_translation_path(loaded, language, integration)
        # No translation available
        if path is None:
            translations[loaded] = {}
        else:
            files_to_load[loaded] = path

    if not files_to_load:
        return translations

    # Load files
    load_translations_job = hass.async_add_executor_job(
        load_translations_files, files_to_load
    )
    assert load_translations_job is not None
    loaded_translations = await load_translations_job

    # Translations that miss "title" will get integration put in.
    for loaded, loaded_translation in loaded_translations.items():
        if "." in loaded:
            continue

        if "title" not in loaded_translation:
            loaded_translation["title"] = integrations[loaded].name

    translations.update(loaded_translations)

    return translations
Ejemplo n.º 7
0
async def async_get_component_strings(hass: HomeAssistant, language: str,
                                      components: set[str]) -> dict[str, Any]:
    """Load translations."""
    domains = list({loaded.split(".")[-1] for loaded in components})

    integrations: dict[str, Integration] = {}
    ints_or_excs = await async_get_integrations(hass, domains)
    for domain, int_or_exc in ints_or_excs.items():
        if isinstance(int_or_exc, Exception):
            raise int_or_exc
        integrations[domain] = int_or_exc
    translations: dict[str, Any] = {}

    # Determine paths of missing components/platforms
    files_to_load = {}
    for loaded in components:
        parts = loaded.split(".")
        domain = parts[-1]
        integration = integrations[domain]

        path = component_translation_path(loaded, language, integration)
        # No translation available
        if path is None:
            translations[loaded] = {}
        else:
            files_to_load[loaded] = path

    if not files_to_load:
        return translations

    # Load files
    load_translations_job = hass.async_add_executor_job(
        load_translations_files, files_to_load)
    assert load_translations_job is not None
    loaded_translations = await load_translations_job

    # Translations that miss "title" will get integration put in.
    for loaded, loaded_translation in loaded_translations.items():
        if "." in loaded:
            continue

        if "title" not in loaded_translation:
            loaded_translation["title"] = integrations[loaded].name

    translations.update(loaded_translations)

    return translations
Ejemplo n.º 8
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
    """Set up HomeKit from a config entry."""
    _async_import_options_from_data_if_missing(hass, entry)

    conf = entry.data
    options = entry.options

    name = conf[CONF_NAME]
    port = conf[CONF_PORT]
    _LOGGER.debug("Begin setup HomeKit for %s", name)

    # If the previous instance hasn't cleaned up yet
    # we need to wait a bit
    if not await hass.async_add_executor_job(port_is_available, port):
        _LOGGER.warning("The local port %s is in use", port)
        raise ConfigEntryNotReady

    if CONF_ENTRY_INDEX in conf and conf[CONF_ENTRY_INDEX] == 0:
        _LOGGER.debug("Migrating legacy HomeKit data for %s", name)
        hass.async_add_executor_job(
            migrate_filesystem_state_data_for_primary_imported_entry_id,
            hass,
            entry.entry_id,
        )

    aid_storage = AccessoryAidStorage(hass, entry.entry_id)

    await aid_storage.async_initialize()
    # ip_address and advertise_ip are yaml only
    ip_address = conf.get(CONF_IP_ADDRESS)
    advertise_ip = conf.get(CONF_ADVERTISE_IP)

    entity_config = options.get(CONF_ENTITY_CONFIG, {}).copy()
    auto_start = options.get(CONF_AUTO_START, DEFAULT_AUTO_START)
    safe_mode = options.get(CONF_SAFE_MODE, DEFAULT_SAFE_MODE)
    entity_filter = FILTER_SCHEMA(options.get(CONF_FILTER, {}))

    homekit = HomeKit(
        hass,
        name,
        port,
        ip_address,
        entity_filter,
        entity_config,
        safe_mode,
        advertise_ip,
        entry.entry_id,
    )
    zeroconf_instance = await zeroconf.async_get_instance(hass)
    await hass.async_add_executor_job(homekit.setup, zeroconf_instance)

    undo_listener = entry.add_update_listener(_async_update_listener)

    hass.data[DOMAIN][entry.entry_id] = {
        AID_STORAGE: aid_storage,
        HOMEKIT: homekit,
        UNDO_UPDATE_LISTENER: undo_listener,
    }

    if hass.state == CoreState.running:
        await homekit.async_start()
    elif auto_start:
        hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED,
                                   homekit.async_start)

    return True
Ejemplo n.º 9
0
async def async_setup_entry(hass: HomeAssistant,
                            config_entry: ConfigEntry) -> bool:
    """Do setup of vera."""
    # Use options entered during initial config flow or provided from configuration.yml
    if config_entry.data.get(CONF_LIGHTS) or config_entry.data.get(
            CONF_EXCLUDE):
        hass.config_entries.async_update_entry(
            entry=config_entry,
            data=config_entry.data,
            options=new_options(
                config_entry.data.get(CONF_LIGHTS, []),
                config_entry.data.get(CONF_EXCLUDE, []),
            ),
        )

    base_url = config_entry.data[CONF_CONTROLLER]
    light_ids = config_entry.options.get(CONF_LIGHTS, [])
    exclude_ids = config_entry.options.get(CONF_EXCLUDE, [])

    # Initialize the Vera controller.
    controller = veraApi.VeraController(base_url)
    controller.start()

    hass.bus.async_listen_once(
        EVENT_HOMEASSISTANT_STOP,
        lambda event: hass.async_add_executor_job(controller.stop),
    )

    try:
        all_devices = await hass.async_add_executor_job(controller.get_devices)

        all_scenes = await hass.async_add_executor_job(controller.get_scenes)
    except RequestException:
        # There was a network related error connecting to the Vera controller.
        _LOGGER.exception("Error communicating with Vera API")
        return False

    # Exclude devices unwanted by user.
    devices = [
        device for device in all_devices if device.device_id not in exclude_ids
    ]

    vera_devices = defaultdict(list)
    for device in devices:
        device_type = map_vera_device(device, light_ids)
        if device_type is None:
            continue

        vera_devices[device_type].append(device)

    vera_scenes = []
    for scene in all_scenes:
        vera_scenes.append(scene)

    controller_data = ControllerData(controller=controller,
                                     devices=vera_devices,
                                     scenes=vera_scenes)

    hass.data[DOMAIN] = controller_data

    # Forward the config data to the necessary platforms.
    for platform in get_configured_platforms(controller_data):
        hass.async_create_task(
            hass.config_entries.async_forward_entry_setup(
                config_entry, platform))

    return True