Exemple #1
0
async def async_setup(opp: OpenPeerPower, config: dict):
    """Set up the ONVIF component."""
    # Import from yaml
    configs = {}
    for p_type, p_config in config_per_platform(config, "camera"):
        if p_type != DOMAIN:
            continue

        config = p_config.copy()
        if config[CONF_HOST] not in configs:
            configs[config[CONF_HOST]] = {
                CONF_HOST: config[CONF_HOST],
                CONF_NAME: config.get(CONF_NAME, DEFAULT_NAME),
                CONF_PASSWORD: config.get(CONF_PASSWORD, DEFAULT_PASSWORD),
                CONF_PORT: config.get(CONF_PORT, DEFAULT_PORT),
                CONF_USERNAME: config.get(CONF_USERNAME, DEFAULT_USERNAME),
            }

    for conf in configs.values():
        opp.async_create_task(
            opp.config_entries.flow.async_init(
                DOMAIN, context={"source": SOURCE_IMPORT}, data=conf
            )
        )

    return True
Exemple #2
0
async def async_validate_config(opp, config):
    """Validate config."""
    scripts = {}
    for _, p_config in config_per_platform(config, DOMAIN):
        for object_id, cfg in p_config.items():
            cfg = await _try_async_validate_config_item(opp, object_id, cfg, config)
            if cfg is not None:
                scripts[object_id] = cfg

    # Create a copy of the configuration with all config for current
    # component removed and add validated config back in.
    config = config_without_domain(config, DOMAIN)
    config[DOMAIN] = scripts

    return config
async def async_validate_config(opp, config):
    """Validate config."""
    automations = []
    validated_automations = await asyncio.gather(
        *(_try_async_validate_config_item(opp, p_config, config)
          for _, p_config in config_per_platform(config, DOMAIN)))
    for validated_automation in validated_automations:
        if validated_automation is not None:
            automations.append(validated_automation)

    # Create a copy of the configuration with all config for current
    # component removed and add validated config back in.
    config = config_without_domain(config, DOMAIN)
    config[DOMAIN] = automations

    return config
async def async_extract_config(opp, config):
    """Extract device tracker config and split between legacy and modern."""
    legacy = []

    for platform in await asyncio.gather(
            *(async_create_platform_type(opp, config, p_type, p_config)
              for p_type, p_config in config_per_platform(config, DOMAIN))):
        if platform is None:
            continue

        if platform.type == PLATFORM_TYPE_LEGACY:
            legacy.append(platform)
        else:
            raise ValueError("Unable to determine type for {}: {}".format(
                platform.name, platform.type))

    return legacy
Exemple #5
0
async def async_setup(opp: OpenPeerPower, config):
    """Set up STT."""
    providers = {}

    async def async_setup_platform(p_type, p_config=None, discovery_info=None):
        """Set up a TTS platform."""
        if p_config is None:
            p_config = {}

        platform = await async_prepare_setup_platform(opp, config, DOMAIN,
                                                      p_type)
        if platform is None:
            return

        try:
            provider = await platform.async_get_engine(opp, p_config,
                                                       discovery_info)
            if provider is None:
                _LOGGER.error("Error setting up platform %s", p_type)
                return

            provider.name = p_type
            provider.opp = opp

            providers[provider.name] = provider
        except Exception:  # pylint: disable=broad-except
            _LOGGER.exception("Error setting up platform: %s", p_type)
            return

    setup_tasks = [
        asyncio.create_task(async_setup_platform(p_type, p_config))
        for p_type, p_config in config_per_platform(config, DOMAIN)
    ]

    if setup_tasks:
        await asyncio.wait(setup_tasks)

    # Add discovery support
    async def async_platform_discovered(platform, info):
        """Handle for discovered platform."""
        await async_setup_platform(platform, discovery_info=info)

    discovery.async_listen_platform(opp, DOMAIN, async_platform_discovered)

    opp.http.register_view(SpeechToTextView(providers))
    return True
Exemple #6
0
def test_config_per_platform():
    """Test config per platform method."""
    config = OrderedDict([
        ("zone", {
            "platform": "hello"
        }),
        ("zoner", None),
        ("zone Hallo", [1, {
            "platform": "hello 2"
        }]),
        ("zone 100", None),
    ])

    assert [
        ("hello", config["zone"]),
        (None, 1),
        ("hello 2", config["zone Hallo"][1]),
    ] == list(helpers.config_per_platform(config, "zone"))
Exemple #7
0
async def async_extract_config(
        opp: OpenPeerPower, config: ConfigType) -> list[DeviceTrackerPlatform]:
    """Extract device tracker config and split between legacy and modern."""
    legacy: list[DeviceTrackerPlatform] = []

    for platform in await asyncio.gather(
            *(async_create_platform_type(opp, config, p_type, p_config)
              for p_type, p_config in config_per_platform(config, DOMAIN))):
        if platform is None:
            continue

        if platform.type == PLATFORM_TYPE_LEGACY:
            legacy.append(platform)
        else:
            raise ValueError(
                f"Unable to determine type for {platform.name}: {platform.type}"
            )

    return legacy
    async def reload_config(call):
        """Reload the scene config."""
        try:
            conf = await conf_util.async_opp_config_yaml(opp)
        except OpenPeerPowerError as err:
            _LOGGER.error(err)
            return

        integration = await async_get_integration(opp, SCENE_DOMAIN)

        conf = await conf_util.async_process_component_config(
            opp, conf, integration)

        if not conf or not platform:
            return

        await platform.async_reset()

        # Extract only the config for the Open Peer Power platform, ignore the rest.
        for p_type, p_config in config_per_platform(conf, SCENE_DOMAIN):
            if p_type != HA_DOMAIN:
                continue

            _process_scenes_config(opp, async_add_entities, p_config)
Exemple #9
0
async def async_setup(opp, config):
    """Set up the notify services."""
    opp.data.setdefault(NOTIFY_SERVICES, {})

    async def persistent_notification(service: ServiceCall) -> None:
        """Send notification via the built-in persistsent_notify integration."""
        payload = {}
        message = service.data[ATTR_MESSAGE]
        message.opp = opp
        payload[ATTR_MESSAGE] = message.async_render(parse_result=False)

        title = service.data.get(ATTR_TITLE)
        if title:
            title.opp = opp
            payload[ATTR_TITLE] = title.async_render(parse_result=False)

        await opp.services.async_call(
            pn.DOMAIN, pn.SERVICE_CREATE, payload, blocking=True
        )

    async def async_setup_platform(
        integration_name, p_config=None, discovery_info=None
    ):
        """Set up a notify platform."""
        if p_config is None:
            p_config = {}

        platform = await async_prepare_setup_platform(
            opp, config, DOMAIN, integration_name
        )

        if platform is None:
            _LOGGER.error("Unknown notification service specified")
            return

        full_name = f"{DOMAIN}.{integration_name}"
        _LOGGER.info("Setting up %s", full_name)
        with async_start_setup(opp, [full_name]):
            notify_service = None
            try:
                if hasattr(platform, "async_get_service"):
                    notify_service = await platform.async_get_service(
                        opp, p_config, discovery_info
                    )
                elif hasattr(platform, "get_service"):
                    notify_service = await opp.async_add_executor_job(
                        platform.get_service, opp, p_config, discovery_info
                    )
                else:
                    raise OpenPeerPowerError("Invalid notify platform.")

                if notify_service is None:
                    # Platforms can decide not to create a service based
                    # on discovery data.
                    if discovery_info is None:
                        _LOGGER.error(
                            "Failed to initialize notification service %s",
                            integration_name,
                        )
                    return

            except Exception:  # pylint: disable=broad-except
                _LOGGER.exception("Error setting up platform %s", integration_name)
                return

            if discovery_info is None:
                discovery_info = {}

            conf_name = p_config.get(CONF_NAME) or discovery_info.get(CONF_NAME)
            target_service_name_prefix = conf_name or integration_name
            service_name = slugify(conf_name or SERVICE_NOTIFY)

            await notify_service.async_setup(
                opp, service_name, target_service_name_prefix
            )
            await notify_service.async_register_services()

            opp.data[NOTIFY_SERVICES].setdefault(integration_name, []).append(
                notify_service
            )
            opp.config.components.add(f"{DOMAIN}.{integration_name}")

        return True

    opp.services.async_register(
        DOMAIN,
        SERVICE_PERSISTENT_NOTIFICATION,
        persistent_notification,
        schema=PERSISTENT_NOTIFICATION_SERVICE_SCHEMA,
    )

    setup_tasks = [
        asyncio.create_task(async_setup_platform(integration_name, p_config))
        for integration_name, p_config in config_per_platform(config, DOMAIN)
    ]

    if setup_tasks:
        await asyncio.wait(setup_tasks)

    async def async_platform_discovered(platform, info):
        """Handle for discovered platform."""
        await async_setup_platform(platform, discovery_info=info)

    discovery.async_listen_platform(opp, DOMAIN, async_platform_discovered)

    return True
Exemple #10
0
async def async_process_component_config(  # noqa: C901
        opp: OpenPeerPower, config: ConfigType,
        integration: Integration) -> ConfigType | None:
    """Check component configuration and return processed configuration.

    Returns None on error.

    This method must be run in the event loop.
    """
    domain = integration.domain
    try:
        component = integration.get_component()
    except LOAD_EXCEPTIONS as ex:
        _LOGGER.error("Unable to import %s: %s", domain, ex)
        return None

    # Check if the integration has a custom config validator
    config_validator = None
    try:
        config_validator = integration.get_platform("config")
    except ImportError as err:
        # Filter out import error of the config platform.
        # If the config platform contains bad imports, make sure
        # that still fails.
        if err.name != f"{integration.pkg_path}.config":
            _LOGGER.error("Error importing config platform %s: %s", domain,
                          err)
            return None

    if config_validator is not None and hasattr(config_validator,
                                                "async_validate_config"):
        try:
            return await config_validator.async_validate_config(  # type: ignore
                opp, config)
        except (vol.Invalid, OpenPeerPowerError) as ex:
            async_log_exception(ex, domain, config, opp,
                                integration.documentation)
            return None
        except Exception:  # pylint: disable=broad-except
            _LOGGER.exception("Unknown error calling %s config validator",
                              domain)
            return None

    # No custom config validator, proceed with schema validation
    if hasattr(component, "CONFIG_SCHEMA"):
        try:
            return component.CONFIG_SCHEMA(config)  # type: ignore
        except vol.Invalid as ex:
            async_log_exception(ex, domain, config, opp,
                                integration.documentation)
            return None
        except Exception:  # pylint: disable=broad-except
            _LOGGER.exception("Unknown error calling %s CONFIG_SCHEMA", domain)
            return None

    component_platform_schema = getattr(
        component, "PLATFORM_SCHEMA_BASE",
        getattr(component, "PLATFORM_SCHEMA", None))

    if component_platform_schema is None:
        return config

    platforms = []
    for p_name, p_config in config_per_platform(config, domain):
        # Validate component specific platform schema
        try:
            p_validated = component_platform_schema(p_config)
        except vol.Invalid as ex:
            async_log_exception(ex, domain, p_config, opp,
                                integration.documentation)
            continue
        except Exception:  # pylint: disable=broad-except
            _LOGGER.exception(
                "Unknown error validating %s platform config with %s component platform schema",
                p_name,
                domain,
            )
            continue

        # Not all platform components follow same pattern for platforms
        # So if p_name is None we are not going to validate platform
        # (the automation component is one of them)
        if p_name is None:
            platforms.append(p_validated)
            continue

        try:
            p_integration = await async_get_integration_with_requirements(
                opp, p_name)
        except (RequirementsNotFound, IntegrationNotFound) as ex:
            _LOGGER.error("Platform error: %s - %s", domain, ex)
            continue

        try:
            platform = p_integration.get_platform(domain)
        except LOAD_EXCEPTIONS:
            _LOGGER.exception("Platform error: %s", domain)
            continue

        # Validate platform specific schema
        if hasattr(platform, "PLATFORM_SCHEMA"):
            try:
                p_validated = platform.PLATFORM_SCHEMA(
                    p_config)  # type: ignore
            except vol.Invalid as ex:
                async_log_exception(
                    ex,
                    f"{domain}.{p_name}",
                    p_config,
                    opp,
                    p_integration.documentation,
                )
                continue
            except Exception:  # pylint: disable=broad-except
                _LOGGER.exception(
                    "Unknown error validating config for %s platform for %s component with PLATFORM_SCHEMA",
                    p_name,
                    domain,
                )
                continue

        platforms.append(p_validated)

    # Create a copy of the configuration with all config for current
    # component removed and add validated config back in.
    config = config_without_domain(config, domain)
    config[domain] = platforms

    return config
async def async_setup(opp, config):
    """Set up the notify services."""
    targets = {}

    async def async_setup_platform(p_type, p_config=None, discovery_info=None):
        """Set up a notify platform."""
        if p_config is None:
            p_config = {}

        platform = await async_prepare_setup_platform(opp, config, DOMAIN,
                                                      p_type)

        if platform is None:
            _LOGGER.error("Unknown notification service specified")
            return

        _LOGGER.info("Setting up %s.%s", DOMAIN, p_type)
        notify_service = None
        try:
            if hasattr(platform, "async_get_service"):
                notify_service = await platform.async_get_service(
                    opp, p_config, discovery_info)
            elif hasattr(platform, "get_service"):
                notify_service = await opp.async_add_job(
                    platform.get_service, opp, p_config, discovery_info)
            else:
                raise OpenPeerPowerError("Invalid notify platform.")

            if notify_service is None:
                # Platforms can decide not to create a service based
                # on discovery data.
                if discovery_info is None:
                    _LOGGER.error(
                        "Failed to initialize notification service %s", p_type)
                return

        except Exception:  # pylint: disable=broad-except
            _LOGGER.exception("Error setting up platform %s", p_type)
            return

        notify_service.opp = opp

        if discovery_info is None:
            discovery_info = {}

        async def async_notify_message(service):
            """Handle sending notification message service calls."""
            kwargs = {}
            message = service.data[ATTR_MESSAGE]
            title = service.data.get(ATTR_TITLE)

            if title:
                title.opp = opp
                kwargs[ATTR_TITLE] = title.async_render()

            if targets.get(service.service) is not None:
                kwargs[ATTR_TARGET] = [targets[service.service]]
            elif service.data.get(ATTR_TARGET) is not None:
                kwargs[ATTR_TARGET] = service.data.get(ATTR_TARGET)

            message.opp = opp
            kwargs[ATTR_MESSAGE] = message.async_render()
            kwargs[ATTR_DATA] = service.data.get(ATTR_DATA)

            await notify_service.async_send_message(**kwargs)

        if hasattr(notify_service, "targets"):
            platform_name = (p_config.get(CONF_NAME)
                             or discovery_info.get(CONF_NAME) or p_type)
            for name, target in notify_service.targets.items():
                target_name = slugify(f"{platform_name}_{name}")
                targets[target_name] = target
                opp.services.async_register(
                    DOMAIN,
                    target_name,
                    async_notify_message,
                    schema=NOTIFY_SERVICE_SCHEMA,
                )

        platform_name = (p_config.get(CONF_NAME)
                         or discovery_info.get(CONF_NAME) or SERVICE_NOTIFY)
        platform_name_slug = slugify(platform_name)

        opp.services.async_register(
            DOMAIN,
            platform_name_slug,
            async_notify_message,
            schema=NOTIFY_SERVICE_SCHEMA,
        )

        opp.config.components.add(f"{DOMAIN}.{p_type}")

        return True

    setup_tasks = [
        async_setup_platform(p_type, p_config)
        for p_type, p_config in config_per_platform(config, DOMAIN)
    ]

    if setup_tasks:
        await asyncio.wait(setup_tasks)

    async def async_platform_discovered(platform, info):
        """Handle for discovered platform."""
        await async_setup_platform(platform, discovery_info=info)

    discovery.async_listen_platform(opp, DOMAIN, async_platform_discovered)

    return True
Exemple #12
0
async def async_setup(opp, config):
    """Track states and offer events for mailboxes."""
    mailboxes = []
    opp.components.frontend.async_register_built_in_panel(
        "mailbox", "mailbox", "mdi:mailbox")
    opp.http.register_view(MailboxPlatformsView(mailboxes))
    opp.http.register_view(MailboxMessageView(mailboxes))
    opp.http.register_view(MailboxMediaView(mailboxes))
    opp.http.register_view(MailboxDeleteView(mailboxes))

    async def async_setup_platform(p_type, p_config=None, discovery_info=None):
        """Set up a mailbox platform."""
        if p_config is None:
            p_config = {}
        if discovery_info is None:
            discovery_info = {}

        platform = await async_prepare_setup_platform(opp, config, DOMAIN,
                                                      p_type)

        if platform is None:
            _LOGGER.error("Unknown mailbox platform specified")
            return

        _LOGGER.info("Setting up %s.%s", DOMAIN, p_type)
        mailbox = None
        try:
            if hasattr(platform, "async_get_handler"):
                mailbox = await platform.async_get_handler(
                    opp, p_config, discovery_info)
            elif hasattr(platform, "get_handler"):
                mailbox = await opp.async_add_executor_job(
                    platform.get_handler, opp, p_config, discovery_info)
            else:
                raise OpenPeerPowerError("Invalid mailbox platform.")

            if mailbox is None:
                _LOGGER.error("Failed to initialize mailbox platform %s",
                              p_type)
                return

        except Exception:  # pylint: disable=broad-except
            _LOGGER.exception("Error setting up platform %s", p_type)
            return

        mailboxes.append(mailbox)
        mailbox_entity = MailboxEntity(mailbox)
        component = EntityComponent(logging.getLogger(__name__), DOMAIN, opp,
                                    SCAN_INTERVAL)
        await component.async_add_entities([mailbox_entity])

    setup_tasks = [
        asyncio.create_task(async_setup_platform(p_type, p_config))
        for p_type, p_config in config_per_platform(config, DOMAIN)
    ]

    if setup_tasks:
        await asyncio.wait(setup_tasks)

    async def async_platform_discovered(platform, info):
        """Handle for discovered platform."""
        await async_setup_platform(platform, discovery_info=info)

    discovery.async_listen_platform(opp, DOMAIN, async_platform_discovered)

    return True
Exemple #13
0
async def async_setup(opp, config):
    """Set up TTS."""
    tts = SpeechManager(opp)

    try:
        conf = config[DOMAIN][0] if config.get(DOMAIN, []) else {}
        use_cache = conf.get(CONF_CACHE, DEFAULT_CACHE)
        cache_dir = conf.get(CONF_CACHE_DIR, DEFAULT_CACHE_DIR)
        time_memory = conf.get(CONF_TIME_MEMORY, DEFAULT_TIME_MEMORY)
        base_url = conf.get(CONF_BASE_URL)
        opp.data[BASE_URL_KEY] = base_url

        await tts.async_init_cache(use_cache, cache_dir, time_memory, base_url)
    except (OpenPeerPowerError, KeyError):
        _LOGGER.exception("Error on cache init")
        return False

    opp.http.register_view(TextToSpeechView(tts))
    opp.http.register_view(TextToSpeechUrlView(tts))

    # Load service descriptions from tts/services.yaml
    integration = await async_get_integration(opp, DOMAIN)
    services_yaml = integration.file_path / "services.yaml"
    services_dict = cast(
        dict, await opp.async_add_executor_job(load_yaml, str(services_yaml)))

    async def async_setup_platform(p_type, p_config=None, discovery_info=None):
        """Set up a TTS platform."""
        if p_config is None:
            p_config = {}

        platform = await async_prepare_setup_platform(opp, config, DOMAIN,
                                                      p_type)
        if platform is None:
            return

        try:
            if hasattr(platform, "async_get_engine"):
                provider = await platform.async_get_engine(
                    opp, p_config, discovery_info)
            else:
                provider = await opp.async_add_executor_job(
                    platform.get_engine, opp, p_config, discovery_info)

            if provider is None:
                _LOGGER.error("Error setting up platform %s", p_type)
                return

            tts.async_register_engine(p_type, provider, p_config)
        except Exception:  # pylint: disable=broad-except
            _LOGGER.exception("Error setting up platform: %s", p_type)
            return

        async def async_say_handle(service):
            """Service handle for say."""
            entity_ids = service.data[ATTR_ENTITY_ID]
            message = service.data.get(ATTR_MESSAGE)
            cache = service.data.get(ATTR_CACHE)
            language = service.data.get(ATTR_LANGUAGE)
            options = service.data.get(ATTR_OPTIONS)

            try:
                url = await tts.async_get_url_path(p_type,
                                                   message,
                                                   cache=cache,
                                                   language=language,
                                                   options=options)
            except OpenPeerPowerError as err:
                _LOGGER.error("Error on init TTS: %s", err)
                return

            base = tts.base_url or get_url(opp)
            url = base + url

            data = {
                ATTR_MEDIA_CONTENT_ID: url,
                ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_MUSIC,
                ATTR_ENTITY_ID: entity_ids,
            }

            await opp.services.async_call(
                DOMAIN_MP,
                SERVICE_PLAY_MEDIA,
                data,
                blocking=True,
                context=service.context,
            )

        service_name = p_config.get(CONF_SERVICE_NAME,
                                    f"{p_type}_{SERVICE_SAY}")
        opp.services.async_register(DOMAIN,
                                    service_name,
                                    async_say_handle,
                                    schema=SCHEMA_SERVICE_SAY)

        # Register the service description
        service_desc = {
            CONF_NAME: f"Say an TTS message with {p_type}",
            CONF_DESCRIPTION:
            f"Say something using text-to-speech on a media player with {p_type}.",
            CONF_FIELDS: services_dict[SERVICE_SAY][CONF_FIELDS],
        }
        async_set_service_schema(opp, DOMAIN, service_name, service_desc)

    setup_tasks = [
        asyncio.create_task(async_setup_platform(p_type, p_config))
        for p_type, p_config in config_per_platform(config, DOMAIN)
    ]

    if setup_tasks:
        await asyncio.wait(setup_tasks)

    async def async_platform_discovered(platform, info):
        """Handle for discovered platform."""
        await async_setup_platform(platform, discovery_info=info)

    discovery.async_listen_platform(opp, DOMAIN, async_platform_discovered)

    async def async_clear_cache_handle(service):
        """Handle clear cache service call."""
        await tts.async_clear_cache()

    opp.services.async_register(
        DOMAIN,
        SERVICE_CLEAR_CACHE,
        async_clear_cache_handle,
        schema=SCHEMA_SERVICE_CLEAR_CACHE,
    )

    return True