Ejemplo n.º 1
0
def _async_process_trigger(hass, config, trigger_configs, name, action):
    """Set up the triggers.

    This method is a coroutine.
    """
    removes = []

    for conf in trigger_configs:
        platform = yield from async_prepare_setup_platform(
            hass, config, DOMAIN, conf.get(CONF_PLATFORM))

        if platform is None:
            return None

        remove = yield from platform.async_trigger(hass, conf, action)

        if not remove:
            _LOGGER.error("Error setting up trigger %s", name)
            continue

        _LOGGER.info("Initialized trigger %s", name)
        removes.append(remove)

    if not removes:
        return None

    def remove_triggers():
        """Remove attached triggers."""
        for remove in removes:
            remove()

    return remove_triggers
Ejemplo n.º 2
0
    def async_setup_platform(p_type, p_config=None, discovery_info=None):
        """Setup a telegram bot platform."""
        platform = yield from async_prepare_setup_platform(
            hass, config, DOMAIN, p_type)

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

        _LOGGER.info("Setting up1 %s.%s", DOMAIN, p_type)

        try:
            if hasattr(platform, 'async_setup_platform'):
                notify_service = yield from \
                    platform.async_setup_platform(hass, p_config,
                                                  discovery_info)
            elif hasattr(platform, 'setup_platform'):
                notify_service = yield from hass.loop.run_in_executor(
                    None, platform.setup_platform, hass, p_config,
                    discovery_info)
            else:
                raise HomeAssistantError("Invalid telegram bot platform.")

            if notify_service is None:
                _LOGGER.error("Failed to initialize telegram bot %s", p_type)
                return

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

        return True
Ejemplo n.º 3
0
    def _async_setup_platform(self, platform_type, platform_config,
                              discovery_info=None):
        """Set up a platform for this component.

        This method must be run in the event loop.
        """
        platform = yield from async_prepare_setup_platform(
            self.hass, self.config, self.domain, platform_type)

        if platform is None:
            return

        # Config > Platform > Component
        scan_interval = (platform_config.get(CONF_SCAN_INTERVAL) or
                         getattr(platform, 'SCAN_INTERVAL', None) or
                         self.scan_interval)
        entity_namespace = platform_config.get(CONF_ENTITY_NAMESPACE)

        key = (platform_type, scan_interval, entity_namespace)

        if key not in self._platforms:
            self._platforms[key] = EntityPlatform(
                self, platform_type, scan_interval, entity_namespace)
        entity_platform = self._platforms[key]

        self.logger.info("Setting up %s.%s", self.domain, platform_type)
        warn_task = self.hass.loop.call_later(
            SLOW_SETUP_WARNING, self.logger.warning,
            "Setup of platform %s is taking over %s seconds.", platform_type,
            SLOW_SETUP_WARNING)

        try:
            if getattr(platform, 'async_setup_platform', None):
                task = platform.async_setup_platform(
                    self.hass, platform_config,
                    entity_platform.async_schedule_add_entities, discovery_info
                )
            else:
                # This should not be replaced with hass.async_add_job because
                # we don't want to track this task in case it blocks startup.
                task = self.hass.loop.run_in_executor(
                    None, platform.setup_platform, self.hass, platform_config,
                    entity_platform.schedule_add_entities, discovery_info
                )
            yield from asyncio.wait_for(
                asyncio.shield(task, loop=self.hass.loop),
                SLOW_SETUP_MAX_WAIT, loop=self.hass.loop)
            yield from entity_platform.async_block_entities_done()
            self.hass.config.components.add(
                '{}.{}'.format(self.domain, platform_type))
        except asyncio.TimeoutError:
            self.logger.error(
                "Setup of platform %s is taking longer than %s seconds."
                " Startup will proceed without waiting any longer.",
                platform_type, SLOW_SETUP_MAX_WAIT)
        except Exception:  # pylint: disable=broad-except
            self.logger.exception(
                "Error while setting up platform %s", platform_type)
        finally:
            warn_task.cancel()
Ejemplo n.º 4
0
    def async_setup_platform(p_type, p_config=None, discovery_info=None):
        """Set up a telegram bot platform."""
        platform = yield from async_prepare_setup_platform(
            hass, config, DOMAIN, p_type)

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

        _LOGGER.info("Setting up %s.%s", DOMAIN, p_type)

        try:
            if hasattr(platform, 'async_setup_platform'):
                notify_service = yield from \
                    platform.async_setup_platform(hass, p_config,
                                                  discovery_info)
            elif hasattr(platform, 'setup_platform'):
                notify_service = yield from hass.loop.run_in_executor(
                    None, platform.setup_platform, hass, p_config,
                    discovery_info)
            else:
                raise HomeAssistantError("Invalid Telegram bot platform")

            if notify_service is None:
                _LOGGER.error(
                    "Failed to initialize Telegram bot %s", p_type)
                return

        except Exception:  # pylint: disable=broad-except
            _LOGGER.exception('Error setting up platform %s', p_type)
            return
Ejemplo n.º 5
0
    def async_setup_platform(p_type, p_config, disc_info=None):
        """Set up a TTS platform."""
        platform = yield from async_prepare_setup_platform(
            hass, config, DOMAIN, p_type)
        if platform is None:
            return

        try:
            if hasattr(platform, 'async_get_engine'):
                provider = yield from platform.async_get_engine(hass, p_config)
            else:
                provider = yield from hass.async_add_job(
                    platform.get_engine, hass, p_config)

            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

        @asyncio.coroutine
        def async_say_handle(service):
            """Service handle for say."""
            entity_ids = service.data.get(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 = yield from tts.async_get_url(p_type,
                                                   message,
                                                   cache=cache,
                                                   language=language,
                                                   options=options)
            except HomeAssistantError as err:
                _LOGGER.error("Error on init tts: %s", err)
                return

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

            if entity_ids:
                data[ATTR_ENTITY_ID] = entity_ids

            yield from hass.services.async_call(DOMAIN_MP,
                                                SERVICE_PLAY_MEDIA,
                                                data,
                                                blocking=True)

        hass.services.async_register(DOMAIN,
                                     "{}_{}".format(p_type, SERVICE_SAY),
                                     async_say_handle,
                                     descriptions.get(SERVICE_SAY),
                                     schema=SCHEMA_SERVICE_SAY)
Ejemplo n.º 6
0
def _async_process_trigger(hass, config, trigger_configs, name, action):
    """Setup the triggers.

    This method is a coroutine.
    """
    removes = []

    for conf in trigger_configs:
        platform = yield from async_prepare_setup_platform(
            hass, config, DOMAIN, conf.get(CONF_PLATFORM))

        if platform is None:
            return None

        remove = yield from platform.async_trigger(hass, conf, action)

        if not remove:
            _LOGGER.error("Error setting up trigger %s", name)
            continue

        _LOGGER.info("Initialized trigger %s", name)
        removes.append(remove)

    if not removes:
        return None

    def remove_triggers():
        """Remove attached triggers."""
        for remove in removes:
            remove()

    return remove_triggers
Ejemplo n.º 7
0
    def _async_setup_platform(self, platform_type, platform_config,
                              discovery_info=None):
        """Set up a platform for this component.

        This method must be run in the event loop.
        """
        platform = yield from async_prepare_setup_platform(
            self.hass, self.config, self.domain, platform_type)

        if platform is None:
            return

        # Config > Platform > Component
        scan_interval = (platform_config.get(CONF_SCAN_INTERVAL) or
                         getattr(platform, 'SCAN_INTERVAL', None) or
                         self.scan_interval)
        entity_namespace = platform_config.get(CONF_ENTITY_NAMESPACE)

        key = (platform_type, scan_interval, entity_namespace)

        if key not in self._platforms:
            self._platforms[key] = EntityPlatform(
                self, platform_type, scan_interval, entity_namespace)
        entity_platform = self._platforms[key]

        self.logger.info("Setting up %s.%s", self.domain, platform_type)
        warn_task = self.hass.loop.call_later(
            SLOW_SETUP_WARNING, self.logger.warning,
            "Setup of platform %s is taking over %s seconds.", platform_type,
            SLOW_SETUP_WARNING)

        try:
            if getattr(platform, 'async_setup_platform', None):
                task = platform.async_setup_platform(
                    self.hass, platform_config,
                    entity_platform.async_schedule_add_entities, discovery_info
                )
            else:
                task = self.hass.loop.run_in_executor(
                    None, platform.setup_platform, self.hass, platform_config,
                    entity_platform.schedule_add_entities, discovery_info
                )
            yield from asyncio.wait_for(
                asyncio.shield(task, loop=self.hass.loop),
                SLOW_SETUP_MAX_WAIT, loop=self.hass.loop)
            yield from entity_platform.async_block_entities_done()
            self.hass.config.components.add(
                '{}.{}'.format(self.domain, platform_type))
        except asyncio.TimeoutError:
            self.logger.error(
                "Setup of platform %s is taking longer than %s seconds."
                " Startup will proceed without waiting any longer.",
                platform_type, SLOW_SETUP_MAX_WAIT)
        except Exception:  # pylint: disable=broad-except
            self.logger.exception(
                "Error while setting up platform %s", platform_type)
        finally:
            warn_task.cancel()
Ejemplo n.º 8
0
    def async_setup_platform(p_type, p_config, disc_info=None):
        """Set up a TTS platform."""
        platform = yield from async_prepare_setup_platform(
            hass, config, DOMAIN, p_type)
        if platform is None:
            return

        try:
            if hasattr(platform, 'async_get_engine'):
                provider = yield from platform.async_get_engine(
                    hass, p_config)
            else:
                provider = yield from hass.async_add_job(
                    platform.get_engine, hass, p_config)

            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

        @asyncio.coroutine
        def async_say_handle(service):
            """Service handle for say."""
            entity_ids = service.data.get(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 = yield from tts.async_get_url(
                    p_type, message, cache=cache, language=language,
                    options=options
                )
            except HomeAssistantError as err:
                _LOGGER.error("Error on init tts: %s", err)
                return

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

            if entity_ids:
                data[ATTR_ENTITY_ID] = entity_ids

            yield from hass.services.async_call(
                DOMAIN_MP, SERVICE_PLAY_MEDIA, data, blocking=True)

        hass.services.async_register(
            DOMAIN, "{}_{}".format(p_type, SERVICE_SAY), async_say_handle,
            descriptions.get(SERVICE_SAY), schema=SCHEMA_SERVICE_SAY)
Ejemplo n.º 9
0
    def _async_setup_platform(self, platform_type, platform_config,
                              discovery_info=None):
        """Setup a platform for this component.

        This method must be run in the event loop.
        """
        platform = yield from async_prepare_setup_platform(
            self.hass, self.config, self.domain, platform_type)

        if platform is None:
            return

        # Config > Platform > Component
        scan_interval = (platform_config.get(CONF_SCAN_INTERVAL) or
                         getattr(platform, 'SCAN_INTERVAL', None) or
                         self.scan_interval)
        entity_namespace = platform_config.get(CONF_ENTITY_NAMESPACE)

        key = (platform_type, scan_interval, entity_namespace)

        if key not in self._platforms:
            self._platforms[key] = EntityPlatform(
                self, platform_type, scan_interval, entity_namespace)
        entity_platform = self._platforms[key]

        self.logger.info("Setting up %s.%s", self.domain, platform_type)
        warn_task = self.hass.loop.call_later(
            SLOW_SETUP_WARNING, self.logger.warning,
            'Setup of platform %s is taking over %s seconds.', platform_type,
            SLOW_SETUP_WARNING)

        try:
            if getattr(platform, 'async_setup_platform', None):
                yield from platform.async_setup_platform(
                    self.hass, platform_config,
                    entity_platform.async_schedule_add_entities, discovery_info
                )
            else:
                yield from self.hass.loop.run_in_executor(
                    None, platform.setup_platform, self.hass, platform_config,
                    entity_platform.schedule_add_entities, discovery_info
                )

            yield from entity_platform.async_block_entities_done()

            self.hass.config.components.add(
                '{}.{}'.format(self.domain, platform_type))
        except Exception:  # pylint: disable=broad-except
            self.logger.exception(
                'Error while setting up platform %s', platform_type)
        finally:
            warn_task.cancel()
Ejemplo n.º 10
0
    def setup_panel(panel_name):
        """Set up a panel."""
        panel = yield from async_prepare_setup_platform(
            hass, config, DOMAIN, panel_name)

        if not panel:
            return

        success = yield from panel.async_setup(hass)

        if success:
            key = '{}.{}'.format(DOMAIN, panel_name)
            hass.bus.async_fire(EVENT_COMPONENT_LOADED, {ATTR_COMPONENT: key})
            hass.config.components.add(key)
Ejemplo n.º 11
0
    def setup_panel(panel_name):
        """Setup a panel."""
        panel = yield from async_prepare_setup_platform(
            hass, config, DOMAIN, panel_name)

        if not panel:
            return

        success = yield from panel.async_setup(hass)

        if success:
            key = '{}.{}'.format(DOMAIN, panel_name)
            hass.bus.async_fire(EVENT_COMPONENT_LOADED, {ATTR_COMPONENT: key})
            hass.config.components.add(key)
Ejemplo n.º 12
0
def _async_setup_discovery(hass, config):
    """Try to start the discovery of MQTT devices.

    This method is a coroutine.
    """
    conf = config.get(DOMAIN, {})

    discovery = yield from async_prepare_setup_platform(
        hass, config, DOMAIN, 'discovery')

    if discovery is None:
        _LOGGER.error("Unable to load MQTT discovery")
        return None

    success = yield from discovery.async_start(
        hass, conf[CONF_DISCOVERY_PREFIX], config)

    return success
Ejemplo n.º 13
0
def _async_setup_server(hass, config):
    """Try to start embedded MQTT broker.

    This method is a coroutine.
    """
    conf = config.get(DOMAIN, {})

    server = yield from async_prepare_setup_platform(hass, config, DOMAIN,
                                                     'server')

    if server is None:
        _LOGGER.error("Unable to load embedded server")
        return None

    success, broker_config = \
        yield from server.async_start(hass, conf.get(CONF_EMBEDDED))

    return success and broker_config
Ejemplo n.º 14
0
def _async_setup_server(hass, config):
    """Try to start embedded MQTT broker.

    This method is a coroutine.
    """
    conf = config.get(DOMAIN, {})

    server = yield from async_prepare_setup_platform(
        hass, config, DOMAIN, 'server')

    if server is None:
        _LOGGER.error("Unable to load embedded server")
        return None

    success, broker_config = \
        yield from server.async_start(hass, conf.get(CONF_EMBEDDED))

    return success and broker_config
Ejemplo n.º 15
0
def _async_setup_discovery(hass, config):
    """Try to start the discovery of MQTT devices.

    This method is a coroutine.
    """
    conf = config.get(DOMAIN, {})

    discovery = yield from async_prepare_setup_platform(
        hass, config, DOMAIN, 'discovery')

    if discovery is None:
        _LOGGER.error("Unable to load MQTT discovery")
        return None

    success = yield from discovery.async_start(
        hass, conf[CONF_DISCOVERY_PREFIX], config)

    return success
Ejemplo n.º 16
0
    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 = yield from async_prepare_setup_platform(
            hass, 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 = yield from \
                    platform.async_get_handler(hass, p_config, discovery_info)
            elif hasattr(platform, 'get_handler'):
                mailbox = yield from hass.async_add_job(
                    platform.get_handler, hass, p_config, discovery_info)
            else:
                raise HomeAssistantError("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(hass, mailbox)
        component = EntityComponent(
            logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL)
        yield from component.async_add_entities([mailbox_entity])
Ejemplo n.º 17
0
    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 = yield from async_prepare_setup_platform(
            hass, 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 = yield from \
                    platform.async_get_handler(hass, p_config, discovery_info)
            elif hasattr(platform, 'get_handler'):
                mailbox = yield from hass.async_add_job(
                    platform.get_handler, hass, p_config, discovery_info)
            else:
                raise HomeAssistantError("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(hass, mailbox)
        component = EntityComponent(
            logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL)
        yield from component.async_add_entities([mailbox_entity])
Ejemplo n.º 18
0
    def _async_setup_platform(self,
                              platform_type,
                              platform_config,
                              discovery_info=None):
        """Set up a platform for this component."""
        platform = yield from async_prepare_setup_platform(
            self.hass, self.config, self.domain, platform_type)

        if platform is None:
            return

        # Config > Platform > Component
        scan_interval = (platform_config.get(CONF_SCAN_INTERVAL)
                         or getattr(platform, 'SCAN_INTERVAL', None)
                         or self.scan_interval)
        parallel_updates = getattr(
            platform, 'PARALLEL_UPDATES',
            int(not hasattr(platform, 'async_setup_platform')))

        entity_namespace = platform_config.get(CONF_ENTITY_NAMESPACE)

        key = (platform_type, scan_interval, entity_namespace)

        if key not in self._platforms:
            entity_platform = self._platforms[key] = EntityPlatform(
                hass=self.hass,
                logger=self.logger,
                domain=self.domain,
                platform_name=platform_type,
                scan_interval=scan_interval,
                parallel_updates=parallel_updates,
                entity_namespace=entity_namespace,
                async_entities_added_callback=self._async_update_group,
            )
        else:
            entity_platform = self._platforms[key]

        yield from entity_platform.async_setup(platform, platform_config,
                                               discovery_info)
Ejemplo n.º 19
0
    def async_setup_platform(p_type, p_config, disc_info=None):
        """Set up a device tracker platform."""
        platform = yield from async_prepare_setup_platform(
            hass, config, DOMAIN, p_type)
        if platform is None:
            return

        _LOGGER.info("Setting up %s.%s", DOMAIN, p_type)
        try:
            scanner = None
            setup = None
            if hasattr(platform, 'async_get_scanner'):
                scanner = yield from platform.async_get_scanner(
                    hass, {DOMAIN: p_config})
            elif hasattr(platform, 'get_scanner'):
                scanner = yield from hass.async_add_job(
                    platform.get_scanner, hass, {DOMAIN: p_config})
            elif hasattr(platform, 'async_setup_scanner'):
                setup = yield from platform.async_setup_scanner(
                    hass, p_config, tracker.async_see, disc_info)
            elif hasattr(platform, 'setup_scanner'):
                setup = yield from hass.async_add_job(platform.setup_scanner,
                                                      hass, p_config,
                                                      tracker.see, disc_info)
            else:
                raise HomeAssistantError("Invalid device_tracker platform.")

            if scanner:
                async_setup_scanner_platform(hass, p_config, scanner,
                                             tracker.async_see, p_type)
                return

            if not setup:
                _LOGGER.error("Error setting up platform %s", p_type)
                return

        except Exception:  # pylint: disable=broad-except
            _LOGGER.exception("Error setting up platform %s", p_type)
Ejemplo n.º 20
0
    def async_setup_platform(p_type, p_config, disc_info=None):
        """Set up a device tracker platform."""
        platform = yield from async_prepare_setup_platform(
            hass, config, DOMAIN, p_type)
        if platform is None:
            return

        _LOGGER.info("Setting up %s.%s", DOMAIN, p_type)
        try:
            scanner = None
            setup = None
            if hasattr(platform, 'async_get_scanner'):
                scanner = yield from platform.async_get_scanner(
                    hass, {DOMAIN: p_config})
            elif hasattr(platform, 'get_scanner'):
                scanner = yield from hass.async_add_job(
                    platform.get_scanner, hass, {DOMAIN: p_config})
            elif hasattr(platform, 'async_setup_scanner'):
                setup = yield from platform.async_setup_scanner(
                    hass, p_config, tracker.async_see, disc_info)
            elif hasattr(platform, 'setup_scanner'):
                setup = yield from hass.async_add_job(
                    platform.setup_scanner, hass, p_config, tracker.see,
                    disc_info)
            else:
                raise HomeAssistantError("Invalid device_tracker platform.")

            if scanner:
                async_setup_scanner_platform(
                    hass, p_config, scanner, tracker.async_see, p_type)
                return

            if not setup:
                _LOGGER.error("Error setting up platform %s", p_type)
                return

        except Exception:  # pylint: disable=broad-except
            _LOGGER.exception("Error setting up platform %s", p_type)
Ejemplo n.º 21
0
    def _async_setup_platform(self, platform_type, platform_config,
                              discovery_info=None):
        """Set up a platform for this component."""
        platform = yield from async_prepare_setup_platform(
            self.hass, self.config, self.domain, platform_type)

        if platform is None:
            return

        # Config > Platform > Component
        scan_interval = (
            platform_config.get(CONF_SCAN_INTERVAL) or
            getattr(platform, 'SCAN_INTERVAL', None) or self.scan_interval)
        parallel_updates = getattr(
            platform, 'PARALLEL_UPDATES',
            int(not hasattr(platform, 'async_setup_platform')))

        entity_namespace = platform_config.get(CONF_ENTITY_NAMESPACE)

        key = (platform_type, scan_interval, entity_namespace)

        if key not in self._platforms:
            entity_platform = self._platforms[key] = EntityPlatform(
                hass=self.hass,
                logger=self.logger,
                domain=self.domain,
                platform_name=platform_type,
                scan_interval=scan_interval,
                parallel_updates=parallel_updates,
                entity_namespace=entity_namespace,
                async_entities_added_callback=self._async_update_group,
            )
        else:
            entity_platform = self._platforms[key]

        yield from entity_platform.async_setup(
            platform, platform_config, discovery_info)
Ejemplo n.º 22
0
    def _async_setup_platform(self,
                              platform_type,
                              platform_config,
                              discovery_info=None,
                              tries=0):
        """Set up a platform for this component.

        This method must be run in the event loop.
        """
        platform = yield from async_prepare_setup_platform(
            self.hass, self.config, self.domain, platform_type)

        if platform is None:
            return

        # Config > Platform > Component
        scan_interval = (platform_config.get(CONF_SCAN_INTERVAL)
                         or getattr(platform, 'SCAN_INTERVAL', None)
                         or self.scan_interval)
        parallel_updates = getattr(
            platform, 'PARALLEL_UPDATES',
            int(not hasattr(platform, 'async_setup_platform')))

        entity_namespace = platform_config.get(CONF_ENTITY_NAMESPACE)

        key = (platform_type, scan_interval, entity_namespace)

        if key not in self._platforms:
            entity_platform = self._platforms[key] = EntityPlatform(
                self, platform_type, scan_interval, parallel_updates,
                entity_namespace)
        else:
            entity_platform = self._platforms[key]

        self.logger.info("Setting up %s.%s", self.domain, platform_type)
        warn_task = self.hass.loop.call_later(
            SLOW_SETUP_WARNING, self.logger.warning,
            "Setup of platform %s is taking over %s seconds.", platform_type,
            SLOW_SETUP_WARNING)

        try:
            if getattr(platform, 'async_setup_platform', None):
                task = platform.async_setup_platform(
                    self.hass, platform_config,
                    entity_platform.async_schedule_add_entities,
                    discovery_info)
            else:
                # This should not be replaced with hass.async_add_job because
                # we don't want to track this task in case it blocks startup.
                task = self.hass.loop.run_in_executor(
                    None, platform.setup_platform, self.hass, platform_config,
                    entity_platform.schedule_add_entities, discovery_info)
            yield from asyncio.wait_for(asyncio.shield(task,
                                                       loop=self.hass.loop),
                                        SLOW_SETUP_MAX_WAIT,
                                        loop=self.hass.loop)
            yield from entity_platform.async_block_entities_done()
            self.hass.config.components.add('{}.{}'.format(
                self.domain, platform_type))
        except PlatformNotReady:
            tries += 1
            wait_time = min(tries, 6) * 30
            self.logger.warning(
                'Platform %s not ready yet. Retrying in %d seconds.',
                platform_type, wait_time)
            async_track_point_in_time(
                self.hass,
                self._async_setup_platform(platform_type, platform_config,
                                           discovery_info, tries),
                dt_util.utcnow() + timedelta(seconds=wait_time))
        except asyncio.TimeoutError:
            self.logger.error(
                "Setup of platform %s is taking longer than %s seconds."
                " Startup will proceed without waiting any longer.",
                platform_type, SLOW_SETUP_MAX_WAIT)
        except Exception:  # pylint: disable=broad-except
            self.logger.exception("Error while setting up platform %s",
                                  platform_type)
        finally:
            warn_task.cancel()
Ejemplo n.º 23
0
    def async_setup_platform(p_type, p_config=None, discovery_info=None):
        """Set up a Telegram bot platform."""
        platform = yield from async_prepare_setup_platform(
            hass, config, DOMAIN, p_type)

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

        _LOGGER.info("Setting up %s.%s", DOMAIN, p_type)
        try:
            receiver_service = yield from \
                platform.async_setup_platform(hass, p_config, discovery_info)
            if receiver_service is None:
                _LOGGER.error("Failed to initialize Telegram bot %s", p_type)
                return

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

        notify_service = TelegramNotificationService(
            hass, p_config.get(CONF_API_KEY),
            p_config.get(CONF_ALLOWED_CHAT_IDS), p_config.get(ATTR_PARSER))

        @asyncio.coroutine
        def async_send_telegram_message(service):
            """Handle sending Telegram Bot message service calls."""
            def _render_template_attr(data, attribute):
                attribute_templ = data.get(attribute)
                if attribute_templ:
                    attribute_templ.hass = hass
                    data[attribute] = attribute_templ.async_render()

            msgtype = service.service
            kwargs = dict(service.data)
            _render_template_attr(kwargs, ATTR_MESSAGE)
            _render_template_attr(kwargs, ATTR_TITLE)
            _LOGGER.debug("NEW telegram_message %s: %s", msgtype, kwargs)

            if msgtype == SERVICE_SEND_MESSAGE:
                yield from hass.async_add_job(
                    partial(notify_service.send_message, **kwargs))
            elif msgtype == SERVICE_SEND_PHOTO:
                yield from hass.async_add_job(
                    partial(notify_service.send_file, True, **kwargs))
            elif msgtype == SERVICE_SEND_DOCUMENT:
                yield from hass.async_add_job(
                    partial(notify_service.send_file, False, **kwargs))
            elif msgtype == SERVICE_SEND_LOCATION:
                yield from hass.async_add_job(
                    partial(notify_service.send_location, **kwargs))
            elif msgtype == SERVICE_ANSWER_CALLBACK_QUERY:
                yield from hass.async_add_job(
                    partial(notify_service.answer_callback_query, **kwargs))
            else:
                yield from hass.async_add_job(
                    partial(notify_service.edit_message, msgtype, **kwargs))

        # Register notification services
        for service_notif, schema in SERVICE_MAP.items():
            hass.services.async_register(DOMAIN,
                                         service_notif,
                                         async_send_telegram_message,
                                         descriptions.get(service_notif),
                                         schema=schema)

        return True
Ejemplo n.º 24
0
def async_setup(hass, config):
    """Set up the Telegram bot component."""
    if not config[DOMAIN]:
        return False

    p_config = config[DOMAIN][0]

    p_type = p_config.get(CONF_PLATFORM)

    platform = yield from async_prepare_setup_platform(
        hass, config, DOMAIN, p_type)

    if platform is None:
        return

    _LOGGER.info("Setting up %s.%s", DOMAIN, p_type)
    try:
        receiver_service = yield from \
            platform.async_setup_platform(hass, p_config)
        if receiver_service is False:
            _LOGGER.error(
                "Failed to initialize Telegram bot %s", p_type)
            return False

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

    bot = initialize_bot(p_config)
    notify_service = TelegramNotificationService(
        hass,
        bot,
        p_config.get(CONF_ALLOWED_CHAT_IDS),
        p_config.get(ATTR_PARSER)
    )

    @asyncio.coroutine
    def async_send_telegram_message(service):
        """Handle sending Telegram Bot message service calls."""
        def _render_template_attr(data, attribute):
            attribute_templ = data.get(attribute)
            if attribute_templ:
                if any([isinstance(attribute_templ, vtype)
                        for vtype in [float, int, str]]):
                    data[attribute] = attribute_templ
                else:
                    attribute_templ.hass = hass
                    try:
                        data[attribute] = attribute_templ.async_render()
                    except TemplateError as exc:
                        _LOGGER.error(
                            "TemplateError in %s: %s -> %s",
                            attribute, attribute_templ.template, exc)
                        data[attribute] = attribute_templ.template

        msgtype = service.service
        kwargs = dict(service.data)
        for attribute in [ATTR_MESSAGE, ATTR_TITLE, ATTR_URL, ATTR_FILE,
                          ATTR_CAPTION, ATTR_LONGITUDE, ATTR_LATITUDE]:
            _render_template_attr(kwargs, attribute)
        _LOGGER.debug("New telegram message %s: %s", msgtype, kwargs)

        if msgtype == SERVICE_SEND_MESSAGE:
            yield from hass.async_add_job(
                partial(notify_service.send_message, **kwargs))
        elif msgtype in [SERVICE_SEND_PHOTO, SERVICE_SEND_STICKER,
                         SERVICE_SEND_VIDEO, SERVICE_SEND_DOCUMENT]:
            yield from hass.async_add_job(
                partial(notify_service.send_file, msgtype, **kwargs))
        elif msgtype == SERVICE_SEND_LOCATION:
            yield from hass.async_add_job(
                partial(notify_service.send_location, **kwargs))
        elif msgtype == SERVICE_ANSWER_CALLBACK_QUERY:
            yield from hass.async_add_job(
                partial(notify_service.answer_callback_query, **kwargs))
        elif msgtype == SERVICE_DELETE_MESSAGE:
            yield from hass.async_add_job(
                partial(notify_service.delete_message, **kwargs))
        else:
            yield from hass.async_add_job(
                partial(notify_service.edit_message, msgtype, **kwargs))

    # Register notification services
    for service_notif, schema in SERVICE_MAP.items():
        hass.services.async_register(
            DOMAIN, service_notif, async_send_telegram_message,
            schema=schema)

    return True
Ejemplo n.º 25
0
    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 = yield from async_prepare_setup_platform(
            hass, 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 = yield from \
                    platform.async_get_service(hass, p_config, discovery_info)
            elif hasattr(platform, 'get_service'):
                notify_service = yield from hass.async_add_job(
                    platform.get_service, hass, p_config, discovery_info)
            else:
                raise HomeAssistantError("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.hass = hass

        if discovery_info is None:
            discovery_info = {}

        @asyncio.coroutine
        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.hass = hass
                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.hass = hass
            kwargs[ATTR_MESSAGE] = message.async_render()
            kwargs[ATTR_DATA] = service.data.get(ATTR_DATA)

            yield from 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('{}_{}'.format(platform_name, name))
                targets[target_name] = target
                hass.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)

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

        hass.config.components.add('{}.{}'.format(DOMAIN, p_type))

        return True
def async_setup(hass, config):
    """Set up the Telegram bot component."""
    if not config[DOMAIN]:
        return False

    p_config = config[DOMAIN][0]

    p_type = p_config.get(CONF_PLATFORM)

    platform = yield from async_prepare_setup_platform(hass, config, DOMAIN,
                                                       p_type)

    if platform is None:
        return

    _LOGGER.info("Setting up %s.%s", DOMAIN, p_type)
    try:
        receiver_service = yield from \
            platform.async_setup_platform(hass, p_config)
        if receiver_service is False:
            _LOGGER.error("Failed to initialize Telegram bot %s", p_type)
            return False

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

    bot = initialize_bot(p_config)
    notify_service = TelegramNotificationService(
        hass, bot, p_config.get(CONF_ALLOWED_CHAT_IDS),
        p_config.get(ATTR_PARSER))

    @asyncio.coroutine
    def async_send_telegram_message(service):
        """Handle sending Telegram Bot message service calls."""
        def _render_template_attr(data, attribute):
            attribute_templ = data.get(attribute)
            if attribute_templ:
                if any([
                        isinstance(attribute_templ, vtype)
                        for vtype in [float, int, str]
                ]):
                    data[attribute] = attribute_templ
                else:
                    attribute_templ.hass = hass
                    try:
                        data[attribute] = attribute_templ.async_render()
                    except TemplateError as exc:
                        _LOGGER.error("TemplateError in %s: %s -> %s",
                                      attribute, attribute_templ.template, exc)
                        data[attribute] = attribute_templ.template

        msgtype = service.service
        kwargs = dict(service.data)
        for attribute in [
                ATTR_MESSAGE, ATTR_TITLE, ATTR_URL, ATTR_FILE, ATTR_CAPTION,
                ATTR_LONGITUDE, ATTR_LATITUDE
        ]:
            _render_template_attr(kwargs, attribute)
        _LOGGER.debug("New telegram message %s: %s", msgtype, kwargs)

        if msgtype == SERVICE_SEND_MESSAGE:
            yield from hass.async_add_job(
                partial(notify_service.send_message, **kwargs))
        elif msgtype in [
                SERVICE_SEND_PHOTO, SERVICE_SEND_STICKER, SERVICE_SEND_VIDEO,
                SERVICE_SEND_DOCUMENT
        ]:
            yield from hass.async_add_job(
                partial(notify_service.send_file, msgtype, **kwargs))
        elif msgtype == SERVICE_SEND_LOCATION:
            yield from hass.async_add_job(
                partial(notify_service.send_location, **kwargs))
        elif msgtype == SERVICE_ANSWER_CALLBACK_QUERY:
            yield from hass.async_add_job(
                partial(notify_service.answer_callback_query, **kwargs))
        elif msgtype == SERVICE_DELETE_MESSAGE:
            yield from hass.async_add_job(
                partial(notify_service.delete_message, **kwargs))
        else:
            yield from hass.async_add_job(
                partial(notify_service.edit_message, msgtype, **kwargs))

    # Register notification services
    for service_notif, schema in SERVICE_MAP.items():
        hass.services.async_register(DOMAIN,
                                     service_notif,
                                     async_send_telegram_message,
                                     schema=schema)

    return True