Example #1
0
async def async_from_config_dict(
    config: Dict[str, Any],
    hass: core.HomeAssistant,
    config_dir: Optional[str] = None,
    enable_log: bool = True,
    verbose: bool = False,
    skip_pip: bool = False,
    log_rotate_days: Any = None,
    log_file: Any = None,
    log_no_color: bool = False,
) -> Optional[core.HomeAssistant]:
    """Try to configure Home Assistant from a configuration dictionary.

    Dynamically loads required components and its dependencies.
    This method is a coroutine.
    """
    start = time()

    if enable_log:
        async_enable_logging(hass, verbose, log_rotate_days, log_file,
                             log_no_color)

    hass.config.skip_pip = skip_pip
    if skip_pip:
        _LOGGER.warning("Skipping pip installation of required modules. "
                        "This may cause issues")

    core_config = config.get(core.DOMAIN, {})
    api_password = config.get("http", {}).get("api_password")
    trusted_networks = config.get("http", {}).get("trusted_networks")

    try:
        await conf_util.async_process_ha_core_config(hass, core_config,
                                                     api_password,
                                                     trusted_networks)
    except vol.Invalid as config_err:
        conf_util.async_log_exception(config_err, "homeassistant", core_config,
                                      hass)
        return None
    except HomeAssistantError:
        _LOGGER.error("Home Assistant core failed to initialize. "
                      "Further initialization aborted")
        return None

    # Make a copy because we are mutating it.
    config = OrderedDict(config)

    # Merge packages
    await conf_util.merge_packages_config(
        hass, config, core_config.get(conf_util.CONF_PACKAGES, {}))

    hass.config_entries = config_entries.ConfigEntries(hass, config)
    await hass.config_entries.async_initialize()

    await _async_set_up_integrations(hass, config)

    stop = time()
    _LOGGER.info("Home Assistant initialized in %.2fs", stop - start)

    return hass
Example #2
0
async def async_validate_config(hass, config):
    """Validate config."""
    if DOMAIN not in config:
        return config

    config_sections = []

    for cfg in cv.ensure_list(config[DOMAIN]):
        try:
            cfg = CONFIG_SECTION_SCHEMA(cfg)
            cfg[CONF_TRIGGER] = await async_validate_trigger_config(
                hass, cfg[CONF_TRIGGER])
        except vol.Invalid as err:
            async_log_exception(err, DOMAIN, cfg, hass)
            continue

        if CONF_TRIGGER in cfg and CONF_SENSORS in cfg:
            cfg = _rewrite_legacy_to_modern_trigger_conf(cfg)

        config_sections.append(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] = config_sections

    return config
Example #3
0
async def _try_async_validate_config_item(hass, config, full_config=None):
    """Validate config item."""
    raw_config = None
    try:
        raw_config = dict(config)
    except ValueError:
        # Invalid config
        pass

    try:
        config = await async_validate_config_item(hass, config, full_config)
    except (
            vol.Invalid,
            HomeAssistantError,
            IntegrationNotFound,
            InvalidDeviceAutomationConfig,
    ) as ex:
        async_log_exception(ex, DOMAIN, full_config or config, hass)
        return None

    if isinstance(config, blueprint.BlueprintInputs):
        return config

    config = AutomationConfig(config)
    config.raw_config = raw_config
    return config
Example #4
0
async def async_load_users(path: str, hass: HomeAssistantType,
                           config: ConfigType, async_add_entities):
    """Load users from YAML configuration file.
    """
    user_schema = vol.Schema({
        vol.Required('user_name'): cv.string,
        vol.Optional('remote_id', default=''): cv.string,
        vol.Optional('local_id', default=''): cv.string,
    })
    result = []
    try:
        _LOGGER.debug("async_load_users(): reading config file %s", path)
        users = await hass.async_add_job(load_yaml_config_file, path)

        _LOGGER.debug(
            'async_load_users(): devices loaded from config file: %s', users)

    except HomeAssistantError as err:
        _LOGGER.error("async_load_users(): unable to load %s: %s", path,
                      str(err))
        return []
    except FileNotFoundError as err:
        _LOGGER.info("async_load_users(): file %s could not be found: %s",
                     path, str(err))
        return []

    for user_name, user in users.items():
        try:
            user = user_schema(user)
        except vol.Invalid as exp:
            _LOGGER.info("in except")
            async_log_exception(exp, user_name, users, hass)
        else:
            result.append(user)
    return result
Example #5
0
async def _try_async_validate_config_item(hass, config, full_config=None):
    """Validate config item."""
    try:
        config = await async_validate_config_item(hass, config, full_config)
    except (vol.Invalid, HomeAssistantError, IntegrationNotFound) as ex:
        async_log_exception(ex, DOMAIN, full_config or config, hass)
        return None

    return config
Example #6
0
async def async_load_config(path: str, hass: HomeAssistantType,
                            config: ConfigType, async_add_entities):
    """Load devices from YAML configuration file.
    This method is a coroutine.
    """
    dev_schema = vol.Schema({
        vol.Required('dev_id'):
        cv.string,
        vol.Optional(CONF_NAME, default=''):
        cv.string,
        vol.Optional(CONF_DEVICE_CLASS, default='motion'):
        DEVICE_CLASSES_SCHEMA
        #        vol.Optional(CONF_ICON, default=None): vol.Any(None, cv.icon),
        #        vol.Optional('track', default=False): cv.boolean,
        #        vol.Optional(CONF_MAC, default=None):
        #        vol.Any(None, vol.All(cv.string, vol.Upper)),
        #        vol.Optional(CONF_AWAY_HIDE, default=DEFAULT_AWAY_HIDE): cv.boolean,
        #        vol.Optional('gravatar', default=None): vol.Any(None, cv.string),
        #        vol.Optional('picture', default=None): vol.Any(None, cv.string),
        #        vol.Optional(CONF_CONSIDER_HOME, default=consider_home): vol.All(
        #            cv.time_period, cv.positive_timedelta),
    })
    result = []
    try:
        _LOGGER.debug("async_load_config(): reading config file %s", path)

        devices = await hass.async_add_job(load_yaml_config_file, path)

        _LOGGER.debug(
            'async_load_config(): devices loaded from config file: %s',
            devices)

    except HomeAssistantError as err:
        _LOGGER.error("async_load_config(): unable to load %s: %s", path,
                      str(err))
        return []
    except FileNotFoundError as err:
        _LOGGER.debug("async_load_config(): file %s could not be found: %s",
                      path, str(err))
        return []

    for dev_id, device in devices.items():
        # Deprecated option. We just ignore it to avoid breaking change
        #        device.pop('vendor', None)
        try:
            device = dev_schema(device)
            device['dev_id'] = cv.slugify(dev_id)
        except vol.Invalid as exp:
            async_log_exception(exp, dev_id, devices, hass)
        else:
            _LOGGER.debug('device: %s', device)
            dev = JablotronSensor(hass, **device)
            result.append(dev)
            """ Create sensors for each device in devices """
            #            device = JablotronSensor(hass, dev_id)
            async_add_entities([dev])
    return result
Example #7
0
async def async_from_config_dict(
        config: ConfigType,
        hass: core.HomeAssistant) -> Optional[core.HomeAssistant]:
    """Try to configure Home Assistant from a configuration dictionary.

    Dynamically loads required components and its dependencies.
    This method is a coroutine.
    """
    start = monotonic()

    hass.config_entries = config_entries.ConfigEntries(hass, config)
    await hass.config_entries.async_initialize()

    # Set up core.
    _LOGGER.debug("Setting up %s", CORE_INTEGRATIONS)

    if not all(await
               asyncio.gather(*(async_setup_component(hass, domain, config)
                                for domain in CORE_INTEGRATIONS))):
        _LOGGER.error("Home Assistant core failed to initialize. ")
        return None

    _LOGGER.debug("Home Assistant core initialized")

    core_config = config.get(core.DOMAIN, {})

    try:
        await conf_util.async_process_ha_core_config(hass, core_config)
    except vol.Invalid as config_err:
        conf_util.async_log_exception(config_err, "homeassistant", core_config,
                                      hass)
        return None
    except HomeAssistantError:
        _LOGGER.error("Home Assistant core failed to initialize. "
                      "Further initialization aborted")
        return None

    await _async_set_up_integrations(hass, config)

    stop = monotonic()
    _LOGGER.info("Home Assistant initialized in %.2fs", stop - start)

    if REQUIRED_NEXT_PYTHON_DATE and sys.version_info[:
                                                      3] < REQUIRED_NEXT_PYTHON_VER:
        msg = (
            "Support for the running Python version "
            f"{'.'.join(str(x) for x in sys.version_info[:3])} is deprecated and will "
            f"be removed in the first release after {REQUIRED_NEXT_PYTHON_DATE}. "
            "Please upgrade Python to "
            f"{'.'.join(str(x) for x in REQUIRED_NEXT_PYTHON_VER)} or "
            "higher.")
        _LOGGER.warning(msg)
        hass.components.persistent_notification.async_create(
            msg, "Python version", "python_version")

    return hass
Example #8
0
async def async_validate_config(hass, config):
    """Validate config."""
    if DOMAIN not in config:
        return config

    config_sections = []

    for cfg in cv.ensure_list(config[DOMAIN]):
        try:
            cfg = CONFIG_SECTION_SCHEMA(cfg)

            if CONF_TRIGGER in cfg:
                cfg[CONF_TRIGGER] = await async_validate_trigger_config(
                    hass, cfg[CONF_TRIGGER]
                )
        except vol.Invalid as err:
            async_log_exception(err, DOMAIN, cfg, hass)
            continue

        legacy_warn_printed = False

        for old_key, new_key, transform in (
            (
                CONF_SENSORS,
                SENSOR_DOMAIN,
                sensor_platform.rewrite_legacy_to_modern_conf,
            ),
            (
                CONF_BINARY_SENSORS,
                BINARY_SENSOR_DOMAIN,
                binary_sensor_platform.rewrite_legacy_to_modern_conf,
            ),
        ):
            if old_key not in cfg:
                continue

            if not legacy_warn_printed:
                legacy_warn_printed = True
                logging.getLogger(__name__).warning(
                    "The entity definition format under template: differs from the platform "
                    "configuration format. See "
                    "https://www.home-assistant.io/integrations/template#configuration-for-trigger-based-template-sensors"
                )

            definitions = list(cfg[new_key]) if new_key in cfg else []
            definitions.extend(transform(cfg[old_key]))
            cfg = {**cfg, new_key: definitions}

        config_sections.append(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] = config_sections

    return config
Example #9
0
    def async_validate_config(
        hass: HomeAssistant,
        config: list[ConfigType],
    ) -> list[ConfigType]:
        """Validate config."""
        validated_config = []
        for config_item in config:
            try:
                validated_config.append(schema(config_item))
            except vol.MultipleInvalid as err:
                async_log_exception(err, domain, config_item, hass)

        return validated_config
Example #10
0
async def _try_async_validate_config_item(hass,
                                          object_id,
                                          config,
                                          full_config=None):
    """Validate config item."""
    try:
        cv.slug(object_id)
        config = await async_validate_config_item(hass, config, full_config)
    except (vol.Invalid, HomeAssistantError) as ex:
        async_log_exception(ex, DOMAIN, full_config or config, hass)
        return None

    return config
Example #11
0
def async_load_config(path: str, hass: HomeAssistantType,
                      consider_home: timedelta):
    """Load devices from YAML configuration file.

    This method is a coroutine.
    """
    dev_schema = vol.Schema({
        vol.Required(CONF_NAME):
        cv.string,
        vol.Optional(CONF_ICON, default=None):
        vol.Any(None, cv.icon),
        vol.Optional('track', default=False):
        cv.boolean,
        vol.Optional(CONF_MAC, default=None):
        vol.Any(None, vol.All(cv.string, vol.Upper)),
        vol.Optional(CONF_AWAY_HIDE, default=DEFAULT_AWAY_HIDE):
        cv.boolean,
        vol.Optional('gravatar', default=None):
        vol.Any(None, cv.string),
        vol.Optional('picture', default=None):
        vol.Any(None, cv.string),
        vol.Optional(CONF_CONSIDER_HOME, default=consider_home):
        vol.All(cv.time_period, cv.positive_timedelta),
    })
    try:
        result = []
        try:
            devices = yield from hass.async_add_job(load_yaml_config_file,
                                                    path)
        except HomeAssistantError as err:
            _LOGGER.error("Unable to load %s: %s", path, str(err))
            return []

        for dev_id, device in devices.items():
            # Deprecated option. We just ignore it to avoid breaking change
            device.pop('vendor', None)
            try:
                device = dev_schema(device)
                device['dev_id'] = cv.slugify(dev_id)
            except vol.Invalid as exp:
                async_log_exception(exp, dev_id, devices, hass)
            else:
                result.append(Device(hass, **device))
        return result
    except (HomeAssistantError, FileNotFoundError):
        # When YAML file could not be loaded/did not contain a dict
        return []
Example #12
0
async def async_load_config(path: str, hass: HomeAssistant,
                            consider_home: timedelta) -> list[Device]:
    """Load devices from YAML configuration file.

    This method is a coroutine.
    """
    dev_schema = vol.Schema({
        vol.Required(CONF_NAME):
        cv.string,
        vol.Optional(CONF_ICON, default=None):
        vol.Any(None, cv.icon),
        vol.Optional("track", default=False):
        cv.boolean,
        vol.Optional(CONF_MAC, default=None):
        vol.Any(None, vol.All(cv.string, vol.Upper)),
        vol.Optional("gravatar", default=None):
        vol.Any(None, cv.string),
        vol.Optional("picture", default=None):
        vol.Any(None, cv.string),
        vol.Optional(CONF_CONSIDER_HOME, default=consider_home):
        vol.All(cv.time_period, cv.positive_timedelta),
    })
    result: list[Device] = []
    try:
        devices = await hass.async_add_executor_job(load_yaml_config_file,
                                                    path)
    except HomeAssistantError as err:
        LOGGER.error("Unable to load %s: %s", path, str(err))
        return []
    except FileNotFoundError:
        return []

    for dev_id, device in devices.items():
        # Deprecated option. We just ignore it to avoid breaking change
        device.pop("vendor", None)
        device.pop("hide_if_away", None)
        try:
            device = dev_schema(device)
            device["dev_id"] = cv.slugify(dev_id)
        except vol.Invalid as exp:
            async_log_exception(exp, dev_id, devices, hass)
        else:
            result.append(Device(hass, **device))
    return result
Example #13
0
async def async_from_config_dict(
        config: ConfigType,
        hass: core.HomeAssistant) -> Optional[core.HomeAssistant]:
    """Try to configure Home Assistant from a configuration dictionary.

    Dynamically loads required components and its dependencies.
    This method is a coroutine.
    """
    start = monotonic()

    hass.config_entries = config_entries.ConfigEntries(hass, config)
    await hass.config_entries.async_initialize()

    # Set up core.
    _LOGGER.debug("Setting up %s", CORE_INTEGRATIONS)

    if not all(await
               asyncio.gather(*(async_setup_component(hass, domain, config)
                                for domain in CORE_INTEGRATIONS))):
        _LOGGER.error("Home Assistant core failed to initialize. ")
        return None

    _LOGGER.debug("Home Assistant core initialized")

    core_config = config.get(core.DOMAIN, {})

    try:
        await conf_util.async_process_ha_core_config(hass, core_config)
    except vol.Invalid as config_err:
        conf_util.async_log_exception(config_err, "homeassistant", core_config,
                                      hass)
        return None
    except HomeAssistantError:
        _LOGGER.error("Home Assistant core failed to initialize. "
                      "Further initialization aborted")
        return None

    await _async_set_up_integrations(hass, config)

    stop = monotonic()
    _LOGGER.info("Home Assistant initialized in %.2fs", stop - start)

    return hass
Example #14
0
async def _try_async_validate_config_item(hass, object_id, config, full_config=None):
    """Validate config item."""
    raw_config = None
    with suppress(ValueError):  # Invalid config
        raw_config = dict(config)

    try:
        cv.slug(object_id)
        config = await async_validate_config_item(hass, config, full_config)
    except (vol.Invalid, HomeAssistantError) as ex:
        async_log_exception(ex, DOMAIN, full_config or config, hass)
        return None

    if isinstance(config, BlueprintInputs):
        return config

    config = ScriptConfig(config)
    config.raw_config = raw_config
    return config
Example #15
0
async def async_load_config(path: str, hass: HomeAssistantType,
                            consider_home: timedelta):
    """Load devices from YAML configuration file.

    This method is a coroutine.
    """
    dev_schema = vol.Schema({
        vol.Required(CONF_NAME): cv.string,
        vol.Optional(CONF_ICON, default=None): vol.Any(None, cv.icon),
        vol.Optional('track', default=False): cv.boolean,
        vol.Optional(CONF_MAC, default=None):
            vol.Any(None, vol.All(cv.string, vol.Upper)),
        vol.Optional(CONF_AWAY_HIDE, default=DEFAULT_AWAY_HIDE): cv.boolean,
        vol.Optional('gravatar', default=None): vol.Any(None, cv.string),
        vol.Optional('picture', default=None): vol.Any(None, cv.string),
        vol.Optional(CONF_CONSIDER_HOME, default=consider_home): vol.All(
            cv.time_period, cv.positive_timedelta),
    })
    try:
        result = []
        try:
            devices = await hass.async_add_job(
                load_yaml_config_file, path)
        except HomeAssistantError as err:
            _LOGGER.error("Unable to load %s: %s", path, str(err))
            return []

        for dev_id, device in devices.items():
            # Deprecated option. We just ignore it to avoid breaking change
            device.pop('vendor', None)
            try:
                device = dev_schema(device)
                device['dev_id'] = cv.slugify(dev_id)
            except vol.Invalid as exp:
                async_log_exception(exp, dev_id, devices, hass)
            else:
                result.append(Device(hass, **device))
        return result
    except (HomeAssistantError, FileNotFoundError):
        # When YAML file could not be loaded/did not contain a dict
        return []
Example #16
0
async def _try_async_validate_config_item(hass,
                                          object_id,
                                          config,
                                          full_config=None):
    """Validate config item."""
    raw_config = None
    try:
        raw_config = dict(config)
    except ValueError:
        # Invalid config
        pass

    try:
        cv.slug(object_id)
        config = await async_validate_config_item(hass, config, full_config)
    except (vol.Invalid, HomeAssistantError) as ex:
        async_log_exception(ex, DOMAIN, full_config or config, hass)
        return None

    config = ScriptConfig(config)
    config.raw_config = raw_config
    return config
Example #17
0
def async_load_config(path: str, hass: HomeAssistantType,
                      consider_home: timedelta):
    """Load devices from YAML configuration file.

    This method is a coroutine.
    """
    dev_schema = vol.Schema({
        vol.Required('name'): cv.string,
        vol.Optional('track', default=False): cv.boolean,
        vol.Optional('mac', default=None): vol.Any(None, vol.All(cv.string,
                                                                 vol.Upper)),
        vol.Optional(CONF_AWAY_HIDE, default=DEFAULT_AWAY_HIDE): cv.boolean,
        vol.Optional('gravatar', default=None): vol.Any(None, cv.string),
        vol.Optional('picture', default=None): vol.Any(None, cv.string),
        vol.Optional(CONF_CONSIDER_HOME, default=consider_home): vol.All(
            cv.time_period, cv.positive_timedelta),
        vol.Optional('vendor', default=None): vol.Any(None, cv.string),
    })
    try:
        result = []
        try:
            devices = yield from hass.loop.run_in_executor(
                None, load_yaml_config_file, path)
        except HomeAssistantError as err:
            _LOGGER.error('Unable to load %s: %s', path, str(err))
            return []

        for dev_id, device in devices.items():
            try:
                device = dev_schema(device)
                device['dev_id'] = cv.slugify(dev_id)
            except vol.Invalid as exp:
                async_log_exception(exp, dev_id, devices, hass)
            else:
                result.append(Device(hass, **device))
        return result
    except (HomeAssistantError, FileNotFoundError):
        # When YAML file could not be loaded/did not contain a dict
        return []
Example #18
0
async def async_validate_config(hass: HomeAssistant,
                                config: ConfigType) -> ConfigType:
    """Validate config."""
    if DOMAIN not in config:
        return config

    config_sections = []

    for cfg in cv.ensure_list(config[DOMAIN]):
        try:
            cfg = CONFIG_SECTION_SCHEMA(cfg)

        except vol.Invalid as err:
            async_log_exception(err, DOMAIN, cfg, hass)
            continue

        config_sections.append(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] = config_sections

    return config
Example #19
0
def async_from_config_dict(config: Dict[str, Any],
                           hass: core.HomeAssistant,
                           config_dir: Optional[str]=None,
                           enable_log: bool=True,
                           verbose: bool=False,
                           skip_pip: bool=False,
                           log_rotate_days: Any=None) \
                           -> Optional[core.HomeAssistant]:
    """Try to configure Home Assistant from a config dict.

    Dynamically loads required components and its dependencies.
    This method is a coroutine.
    """
    start = time()
    hass.async_track_tasks()

    core_config = config.get(core.DOMAIN, {})

    try:
        yield from conf_util.async_process_ha_core_config(hass, core_config)
    except vol.Invalid as ex:
        conf_util.async_log_exception(ex, 'homeassistant', core_config, hass)
        return None

    yield from hass.loop.run_in_executor(
        None, conf_util.process_ha_config_upgrade, hass)

    if enable_log:
        async_enable_logging(hass, verbose, log_rotate_days)

    hass.config.skip_pip = skip_pip
    if skip_pip:
        _LOGGER.warning('Skipping pip installation of required modules. '
                        'This may cause issues.')

    if not loader.PREPARED:
        yield from hass.loop.run_in_executor(None, loader.prepare, hass)

    # Merge packages
    conf_util.merge_packages_config(
        config, core_config.get(conf_util.CONF_PACKAGES, {}))

    # Make a copy because we are mutating it.
    # Use OrderedDict in case original one was one.
    # Convert values to dictionaries if they are None
    new_config = OrderedDict()
    for key, value in config.items():
        new_config[key] = value or {}
    config = new_config

    # Filter out the repeating and common config section [homeassistant]
    components = set(key.split(' ')[0] for key in config.keys()
                     if key != core.DOMAIN)

    # setup components
    # pylint: disable=not-an-iterable
    res = yield from core_components.async_setup(hass, config)
    if not res:
        _LOGGER.error('Home Assistant core failed to initialize. '
                      'Further initialization aborted.')
        return hass

    yield from persistent_notification.async_setup(hass, config)

    _LOGGER.info('Home Assistant core initialized')

    # stage 1
    for component in components:
        if component not in FIRST_INIT_COMPONENT:
            continue
        hass.async_add_job(async_setup_component(hass, component, config))

    yield from hass.async_block_till_done()

    # stage 2
    for component in components:
        if component in FIRST_INIT_COMPONENT:
            continue
        hass.async_add_job(async_setup_component(hass, component, config))

    yield from hass.async_stop_track_tasks()

    stop = time()
    _LOGGER.info('Home Assistant initialized in %ss', round(stop-start, 2))

    async_register_signal_handling(hass)
    return hass
Example #20
0
def async_from_config_dict(config: Dict[str, Any],
                           hass: core.HomeAssistant,
                           config_dir: Optional[str]=None,
                           enable_log: bool=True,
                           verbose: bool=False,
                           skip_pip: bool=False,
                           log_rotate_days: Any=None,
                           log_file: Any=None) \
                           -> Optional[core.HomeAssistant]:
    """Try to configure Home Assistant from a configuration dictionary.

    Dynamically loads required components and its dependencies.
    This method is a coroutine.
    """
    start = time()

    if enable_log:
        async_enable_logging(hass, verbose, log_rotate_days, log_file)

    if sys.version_info[:2] < (3, 5):
        _LOGGER.warning(
            'Python 3.4 support has been deprecated and will be removed in '
            'the beginning of 2018. Please upgrade Python or your operating '
            'system. More info: https://home-assistant.io/blog/2017/10/06/'
            'deprecating-python-3.4-support/'
        )

    core_config = config.get(core.DOMAIN, {})

    try:
        yield from conf_util.async_process_ha_core_config(hass, core_config)
    except vol.Invalid as ex:
        conf_util.async_log_exception(ex, 'homeassistant', core_config, hass)
        return None

    yield from hass.async_add_job(conf_util.process_ha_config_upgrade, hass)

    hass.config.skip_pip = skip_pip
    if skip_pip:
        _LOGGER.warning("Skipping pip installation of required modules. "
                        "This may cause issues")

    if not loader.PREPARED:
        yield from hass.async_add_job(loader.prepare, hass)

    # Merge packages
    conf_util.merge_packages_config(
        config, core_config.get(conf_util.CONF_PACKAGES, {}))

    # Make a copy because we are mutating it.
    # Use OrderedDict in case original one was one.
    # Convert values to dictionaries if they are None
    new_config = OrderedDict()
    for key, value in config.items():
        new_config[key] = value or {}
    config = new_config

    # Filter out the repeating and common config section [homeassistant]
    components = set(key.split(' ')[0] for key in config.keys()
                     if key != core.DOMAIN)

    # setup components
    # pylint: disable=not-an-iterable
    res = yield from core_components.async_setup(hass, config)
    if not res:
        _LOGGER.error("Home Assistant core failed to initialize. "
                      "further initialization aborted")
        return hass

    yield from persistent_notification.async_setup(hass, config)

    _LOGGER.info("Home Assistant core initialized")

    # stage 1
    for component in components:
        if component not in FIRST_INIT_COMPONENT:
            continue
        hass.async_add_job(async_setup_component(hass, component, config))

    yield from hass.async_block_till_done()

    # stage 2
    for component in components:
        if component in FIRST_INIT_COMPONENT:
            continue
        hass.async_add_job(async_setup_component(hass, component, config))

    yield from hass.async_block_till_done()

    stop = time()
    _LOGGER.info("Home Assistant initialized in %.2fs", stop-start)

    async_register_signal_handling(hass)
    return hass
Example #21
0
async def async_from_config_dict(config: Dict[str, Any],
                                 hass: core.HomeAssistant,
                                 config_dir: Optional[str] = None,
                                 enable_log: bool = True,
                                 verbose: bool = False,
                                 skip_pip: bool = False,
                                 log_rotate_days: Any = None,
                                 log_file: Any = None,
                                 log_no_color: bool = False) \
                           -> Optional[core.HomeAssistant]:
    """Try to configure Home Assistant from a configuration dictionary.

    Dynamically loads required components and its dependencies.
    This method is a coroutine.
    """
    start = time()

    if enable_log:
        async_enable_logging(hass, verbose, log_rotate_days, log_file,
                             log_no_color)

    core_config = config.get(core.DOMAIN, {})
    has_api_password = bool((config.get('http') or {}).get('api_password'))
    has_trusted_networks = bool((config.get('http') or {})
                                .get('trusted_networks'))

    try:
        await conf_util.async_process_ha_core_config(
            hass, core_config, has_api_password, has_trusted_networks)
    except vol.Invalid as config_err:
        conf_util.async_log_exception(
            config_err, 'homeassistant', core_config, hass)
        return None
    except HomeAssistantError:
        _LOGGER.error("Home Assistant core failed to initialize. "
                      "Further initialization aborted")
        return None

    await hass.async_add_executor_job(
        conf_util.process_ha_config_upgrade, hass)

    hass.config.skip_pip = skip_pip
    if skip_pip:
        _LOGGER.warning("Skipping pip installation of required modules. "
                        "This may cause issues")

    # Make a copy because we are mutating it.
    config = OrderedDict(config)

    # Merge packages
    conf_util.merge_packages_config(
        hass, config, core_config.get(conf_util.CONF_PACKAGES, {}))

    hass.config_entries = config_entries.ConfigEntries(hass, config)
    await hass.config_entries.async_load()

    # Filter out the repeating and common config section [homeassistant]
    components = set(key.split(' ')[0] for key in config.keys()
                     if key != core.DOMAIN)
    components.update(hass.config_entries.async_domains())

    # Resolve all dependencies of all components.
    for component in list(components):
        try:
            components.update(loader.component_dependencies(hass, component))
        except loader.LoaderError:
            # Ignore it, or we'll break startup
            # It will be properly handled during setup.
            pass

    # setup components
    res = await core_components.async_setup(hass, config)
    if not res:
        _LOGGER.error("Home Assistant core failed to initialize. "
                      "Further initialization aborted")
        return hass

    await persistent_notification.async_setup(hass, config)

    _LOGGER.info("Home Assistant core initialized")

    # stage 1
    for component in components:
        if component not in FIRST_INIT_COMPONENT:
            continue
        hass.async_create_task(async_setup_component(hass, component, config))

    await hass.async_block_till_done()

    # stage 2
    for component in components:
        if component in FIRST_INIT_COMPONENT:
            continue
        hass.async_create_task(async_setup_component(hass, component, config))

    await hass.async_block_till_done()

    stop = time()
    _LOGGER.info("Home Assistant initialized in %.2fs", stop-start)

    # TEMP: warn users for invalid slugs
    # Remove after 0.94 or 1.0
    if cv.INVALID_SLUGS_FOUND or cv.INVALID_ENTITY_IDS_FOUND:
        msg = []

        if cv.INVALID_ENTITY_IDS_FOUND:
            msg.append(
                "Your configuration contains invalid entity ID references. "
                "Please find and update the following. "
                "This will become a breaking change."
            )
            msg.append('\n'.join('- {} -> {}'.format(*item)
                                 for item
                                 in cv.INVALID_ENTITY_IDS_FOUND.items()))

        if cv.INVALID_SLUGS_FOUND:
            msg.append(
                "Your configuration contains invalid slugs. "
                "Please find and update the following. "
                "This will become a breaking change."
            )
            msg.append('\n'.join('- {} -> {}'.format(*item)
                                 for item in cv.INVALID_SLUGS_FOUND.items()))

        hass.components.persistent_notification.async_create(
            '\n\n'.join(msg), "Config Warning", "config_warning"
        )

    # TEMP: warn users of invalid extra keys
    # Remove after 0.92
    if cv.INVALID_EXTRA_KEYS_FOUND:
        msg = []
        msg.append(
            "Your configuration contains extra keys "
            "that the platform does not support (but were silently "
            "accepted before 0.88). Please find and remove the following."
            "This will become a breaking change."
        )
        msg.append('\n'.join('- {}'.format(it)
                             for it in cv.INVALID_EXTRA_KEYS_FOUND))

        hass.components.persistent_notification.async_create(
            '\n\n'.join(msg), "Config Warning", "config_warning"
        )

    return hass
def async_from_config_dict(config: Dict[str, Any],
                           hass: core.HomeAssistant,
                           config_dir: Optional[str]=None,
                           enable_log: bool=True,
                           verbose: bool=False,
                           skip_pip: bool=False,
                           log_rotate_days: Any=None) \
                           -> Optional[core.HomeAssistant]:
    """Try to configure Home Assistant from a config dict.

    Dynamically loads required components and its dependencies.
    This method is a coroutine.
    """
    start = time()
    core_config = config.get(core.DOMAIN, {})

    try:
        yield from conf_util.async_process_ha_core_config(hass, core_config)
    except vol.Invalid as ex:
        conf_util.async_log_exception(ex, 'homeassistant', core_config, hass)
        return None

    yield from hass.async_add_job(conf_util.process_ha_config_upgrade, hass)

    if enable_log:
        async_enable_logging(hass, verbose, log_rotate_days)

    hass.config.skip_pip = skip_pip
    if skip_pip:
        _LOGGER.warning('Skipping pip installation of required modules. '
                        'This may cause issues.')

    if not loader.PREPARED:
        yield from hass.async_add_job(loader.prepare, hass)

    # Merge packages
    conf_util.merge_packages_config(
        config, core_config.get(conf_util.CONF_PACKAGES, {}))

    # Make a copy because we are mutating it.
    # Use OrderedDict in case original one was one.
    # Convert values to dictionaries if they are None
    new_config = OrderedDict()
    for key, value in config.items():
        new_config[key] = value or {}
    config = new_config

    # Filter out the repeating and common config section [homeassistant]
    components = set(
        key.split(' ')[0] for key in config.keys() if key != core.DOMAIN)

    # setup components
    # pylint: disable=not-an-iterable
    res = yield from core_components.async_setup(hass, config)
    if not res:
        _LOGGER.error('Home Assistant core failed to initialize. '
                      'Further initialization aborted.')
        return hass

    yield from persistent_notification.async_setup(hass, config)

    _LOGGER.info('Home Assistant core initialized')

    # stage 1
    for component in components:
        if component not in FIRST_INIT_COMPONENT:
            continue
        hass.async_add_job(async_setup_component(hass, component, config))

    yield from hass.async_block_till_done()

    # stage 2
    for component in components:
        if component in FIRST_INIT_COMPONENT:
            continue
        hass.async_add_job(async_setup_component(hass, component, config))

    yield from hass.async_block_till_done()

    stop = time()
    _LOGGER.info('Home Assistant initialized in %.2fs', stop - start)

    async_register_signal_handling(hass)
    return hass
Example #23
0
async def async_from_config_dict(config: Dict[str, Any],
                                 hass: core.HomeAssistant,
                                 config_dir: Optional[str] = None,
                                 enable_log: bool = True,
                                 verbose: bool = False,
                                 skip_pip: bool = False,
                                 log_rotate_days: Any = None,
                                 log_file: Any = None,
                                 log_no_color: bool = False) \
                           -> Optional[core.HomeAssistant]:
    """Try to configure Home Assistant from a configuration dictionary.

    Dynamically loads required components and its dependencies.
    This method is a coroutine.
    """
    start = time()

    if enable_log:
        async_enable_logging(hass, verbose, log_rotate_days, log_file,
                             log_no_color)

    hass.config.skip_pip = skip_pip
    if skip_pip:
        _LOGGER.warning("Skipping pip installation of required modules. "
                        "This may cause issues")

    core_config = config.get(core.DOMAIN, {})
    api_password = config.get('http', {}).get('api_password')
    trusted_networks = config.get('http', {}).get('trusted_networks')

    try:
        await conf_util.async_process_ha_core_config(hass, core_config,
                                                     api_password,
                                                     trusted_networks)
    except vol.Invalid as config_err:
        conf_util.async_log_exception(config_err, 'homeassistant', core_config,
                                      hass)
        return None
    except HomeAssistantError:
        _LOGGER.error("Home Assistant core failed to initialize. "
                      "Further initialization aborted")
        return None

    # Make a copy because we are mutating it.
    config = OrderedDict(config)

    # Merge packages
    await conf_util.merge_packages_config(
        hass, config, core_config.get(conf_util.CONF_PACKAGES, {}))

    hass.config_entries = config_entries.ConfigEntries(hass, config)
    await hass.config_entries.async_initialize()

    await _async_set_up_integrations(hass, config)

    stop = time()
    _LOGGER.info("Home Assistant initialized in %.2fs", stop - start)

    if sys.version_info[:3] < (3, 6, 0):
        hass.components.persistent_notification.async_create(
            "Python 3.5 support is deprecated and will "
            "be removed in the first release after August 1. Please "
            "upgrade Python.", "Python version", "python_version")

    # TEMP: warn users for invalid slugs
    # Remove after 0.94 or 1.0
    if cv.INVALID_SLUGS_FOUND or cv.INVALID_ENTITY_IDS_FOUND:
        msg = []

        if cv.INVALID_ENTITY_IDS_FOUND:
            msg.append(
                "Your configuration contains invalid entity ID references. "
                "Please find and update the following. "
                "This will become a breaking change.")
            msg.append('\n'.join(
                '- {} -> {}'.format(*item)
                for item in cv.INVALID_ENTITY_IDS_FOUND.items()))

        if cv.INVALID_SLUGS_FOUND:
            msg.append("Your configuration contains invalid slugs. "
                       "Please find and update the following. "
                       "This will become a breaking change.")
            msg.append('\n'.join('- {} -> {}'.format(*item)
                                 for item in cv.INVALID_SLUGS_FOUND.items()))

        hass.components.persistent_notification.async_create(
            '\n\n'.join(msg), "Config Warning", "config_warning")

    # TEMP: warn users of invalid extra keys
    # Remove after 0.92
    if cv.INVALID_EXTRA_KEYS_FOUND:
        msg = []
        msg.append(
            "Your configuration contains extra keys "
            "that the platform does not support (but were silently "
            "accepted before 0.88). Please find and remove the following."
            "This will become a breaking change.")
        msg.append('\n'.join('- {}'.format(it)
                             for it in cv.INVALID_EXTRA_KEYS_FOUND))

        hass.components.persistent_notification.async_create(
            '\n\n'.join(msg), "Config Warning", "config_warning")

    return hass
Example #24
0
async def async_from_config_dict(
        config: ConfigType,
        hass: core.HomeAssistant) -> core.HomeAssistant | None:
    """Try to configure Home Assistant from a configuration dictionary.

    Dynamically loads required components and its dependencies.
    This method is a coroutine.
    """
    start = monotonic()

    hass.config_entries = config_entries.ConfigEntries(hass, config)
    await hass.config_entries.async_initialize()

    # Set up core.
    _LOGGER.debug("Setting up %s", CORE_INTEGRATIONS)

    if not all(await
               asyncio.gather(*(async_setup_component(hass, domain, config)
                                for domain in CORE_INTEGRATIONS))):
        _LOGGER.error("Home Assistant core failed to initialize. ")
        return None

    _LOGGER.debug("Home Assistant core initialized")

    core_config = config.get(core.DOMAIN, {})

    try:
        await conf_util.async_process_ha_core_config(hass, core_config)
    except vol.Invalid as config_err:
        conf_util.async_log_exception(config_err, "homeassistant", core_config,
                                      hass)
        return None
    except HomeAssistantError:
        _LOGGER.error("Home Assistant core failed to initialize. "
                      "Further initialization aborted")
        return None

    await _async_set_up_integrations(hass, config)

    stop = monotonic()
    _LOGGER.info("Home Assistant initialized in %.2fs", stop - start)
    from homeassistant.components.ais_dom import ais_global

    ais_global.set_ais_android_id_dom_file_path(
        hass.config.config_dir + "/.dom/.ais_secure_android_id_dom")
    await ais_global.async_say_direct(
        hass,
        "Asystent domowy, inicjalizacja: %.2f sekundy. Trwa uruchamianie konfiguracji. Poczekaj..."
        % (stop - start),
    )

    if (REQUIRED_NEXT_PYTHON_HA_RELEASE
            and sys.version_info[:3] < REQUIRED_NEXT_PYTHON_VER):
        msg = (
            "Support for the running Python version "
            f"{'.'.join(str(x) for x in sys.version_info[:3])} is deprecated and will "
            f"be removed in Home Assistant {REQUIRED_NEXT_PYTHON_HA_RELEASE}. "
            "Please upgrade Python to "
            f"{'.'.join(str(x) for x in REQUIRED_NEXT_PYTHON_VER[:2])}.")
        _LOGGER.warning(msg)
        hass.components.persistent_notification.async_create(
            msg, "Python version", "python_version")

    return hass
async def async_from_config_dict(config: Dict[str, Any],
                                 hass: core.HomeAssistant,
                                 config_dir: Optional[str] = None,
                                 enable_log: bool = True,
                                 verbose: bool = False,
                                 skip_pip: bool = False,
                                 log_rotate_days: Any = None,
                                 log_file: Any = None,
                                 log_no_color: bool = False) \
                           -> Optional[core.HomeAssistant]:
    """Try to configure Home Assistant from a configuration dictionary.

    Dynamically loads required components and its dependencies.
    This method is a coroutine.
    """
    start = time()

    if enable_log:
        async_enable_logging(hass, verbose, log_rotate_days, log_file,
                             log_no_color)

    hass.config.skip_pip = skip_pip
    if skip_pip:
        _LOGGER.warning("Skipping pip installation of required modules. "
                        "This may cause issues")

    core_config = config.get(core.DOMAIN, {})
    api_password = config.get('http', {}).get('api_password')
    trusted_networks = config.get('http', {}).get('trusted_networks')

    try:
        await conf_util.async_process_ha_core_config(
            hass, core_config, api_password, trusted_networks)
    except vol.Invalid as config_err:
        conf_util.async_log_exception(
            config_err, 'homeassistant', core_config, hass)
        return None
    except HomeAssistantError:
        _LOGGER.error("Home Assistant core failed to initialize. "
                      "Further initialization aborted")
        return None

    # Make a copy because we are mutating it.
    config = OrderedDict(config)

    # Merge packages
    await conf_util.merge_packages_config(
        hass, config, core_config.get(conf_util.CONF_PACKAGES, {}))

    hass.config_entries = config_entries.ConfigEntries(hass, config)
    await hass.config_entries.async_initialize()

    await _async_set_up_integrations(hass, config)

    stop = time()
    _LOGGER.info("Home Assistant initialized in %.2fs", stop-start)

    # TEMP: warn users for invalid slugs
    # Remove after 0.94 or 1.0
    if cv.INVALID_SLUGS_FOUND or cv.INVALID_ENTITY_IDS_FOUND:
        msg = []

        if cv.INVALID_ENTITY_IDS_FOUND:
            msg.append(
                "Your configuration contains invalid entity ID references. "
                "Please find and update the following. "
                "This will become a breaking change."
            )
            msg.append('\n'.join('- {} -> {}'.format(*item)
                                 for item
                                 in cv.INVALID_ENTITY_IDS_FOUND.items()))

        if cv.INVALID_SLUGS_FOUND:
            msg.append(
                "Your configuration contains invalid slugs. "
                "Please find and update the following. "
                "This will become a breaking change."
            )
            msg.append('\n'.join('- {} -> {}'.format(*item)
                                 for item in cv.INVALID_SLUGS_FOUND.items()))

        hass.components.persistent_notification.async_create(
            '\n\n'.join(msg), "Config Warning", "config_warning"
        )

    # TEMP: warn users of invalid extra keys
    # Remove after 0.92
    if cv.INVALID_EXTRA_KEYS_FOUND:
        msg = []
        msg.append(
            "Your configuration contains extra keys "
            "that the platform does not support (but were silently "
            "accepted before 0.88). Please find and remove the following."
            "This will become a breaking change."
        )
        msg.append('\n'.join('- {}'.format(it)
                             for it in cv.INVALID_EXTRA_KEYS_FOUND))

        hass.components.persistent_notification.async_create(
            '\n\n'.join(msg), "Config Warning", "config_warning"
        )

    return hass
Example #26
0
def async_setup(hass: HomeAssistantType, config: ConfigType):
    """Setup device tracker."""
    yaml_path = hass.config.path(YAML_DEVICES)

    try:
        conf = config.get(DOMAIN, [])
    except vol.Invalid as ex:
        async_log_exception(ex, DOMAIN, config, hass)
        return False
    else:
        conf = conf[0] if len(conf) > 0 else {}
        consider_home = conf.get(CONF_CONSIDER_HOME, DEFAULT_CONSIDER_HOME)
        track_new = conf.get(CONF_TRACK_NEW, DEFAULT_TRACK_NEW)

    devices = yield from async_load_config(yaml_path, hass, consider_home)
    tracker = DeviceTracker(hass, consider_home, track_new, devices)

    @asyncio.coroutine
    def async_setup_platform(p_type, p_config, disc_info=None):
        """Setup 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.loop.run_in_executor(
                    None, 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.loop.run_in_executor(
                    None, 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)

    setup_tasks = [async_setup_platform(p_type, p_config) for p_type, p_config
                   in config_per_platform(config, DOMAIN)]
    if setup_tasks:
        yield from asyncio.wait(setup_tasks, loop=hass.loop)

    yield from tracker.async_setup_group()

    @callback
    def async_device_tracker_discovered(service, info):
        """Called when a device tracker platform is discovered."""
        hass.async_add_job(
            async_setup_platform(DISCOVERY_PLATFORMS[service], {}, info))

    discovery.async_listen(
        hass, DISCOVERY_PLATFORMS.keys(), async_device_tracker_discovered)

    @asyncio.coroutine
    def async_platform_discovered(platform, info):
        """Callback to load a platform."""
        yield from async_setup_platform(platform, {}, disc_info=info)

    discovery.async_listen_platform(hass, DOMAIN, async_platform_discovered)

    # Clean up stale devices
    async_track_utc_time_change(
        hass, tracker.async_update_stale, second=range(0, 60, 5))

    @asyncio.coroutine
    def async_see_service(call):
        """Service to see a device."""
        args = {key: value for key, value in call.data.items() if key in
                (ATTR_MAC, ATTR_DEV_ID, ATTR_HOST_NAME, ATTR_LOCATION_NAME,
                 ATTR_GPS, ATTR_GPS_ACCURACY, ATTR_BATTERY, ATTR_ATTRIBUTES)}
        yield from tracker.async_see(**args)

    descriptions = yield from hass.loop.run_in_executor(
        None, load_yaml_config_file,
        os.path.join(os.path.dirname(__file__), 'services.yaml')
    )
    hass.services.async_register(
        DOMAIN, SERVICE_SEE, async_see_service, descriptions.get(SERVICE_SEE))

    # restore
    yield from tracker.async_setup_tracked_device()
    return True
Example #27
0
async def async_from_config_dict(config: Dict[str, Any],
                                 hass: core.HomeAssistant,
                                 config_dir: Optional[str] = None,
                                 enable_log: bool = True,
                                 verbose: bool = False,
                                 skip_pip: bool = False,
                                 log_rotate_days: Any = None,
                                 log_file: Any = None,
                                 log_no_color: bool = False) \
                           -> Optional[core.HomeAssistant]:
    """Try to configure Home Assistant from a configuration dictionary.

    Dynamically loads required components and its dependencies.
    This method is a coroutine.
    """
    start = time()

    if enable_log:
        async_enable_logging(hass, verbose, log_rotate_days, log_file,
                             log_no_color)

    core_config = config.get(core.DOMAIN, {})

    try:
        await conf_util.async_process_ha_core_config(hass, core_config)
    except vol.Invalid as ex:
        conf_util.async_log_exception(ex, 'homeassistant', core_config, hass)
        return None

    await hass.async_add_executor_job(
        conf_util.process_ha_config_upgrade, hass)

    hass.config.skip_pip = skip_pip
    if skip_pip:
        _LOGGER.warning("Skipping pip installation of required modules. "
                        "This may cause issues")

    # Make a copy because we are mutating it.
    config = OrderedDict(config)

    # Merge packages
    conf_util.merge_packages_config(
        hass, config, core_config.get(conf_util.CONF_PACKAGES, {}))

    # Ensure we have no None values after merge
    for key, value in config.items():
        if not value:
            config[key] = {}

    hass.config_entries = config_entries.ConfigEntries(hass, config)
    await hass.config_entries.async_load()

    # Filter out the repeating and common config section [homeassistant]
    components = set(key.split(' ')[0] for key in config.keys()
                     if key != core.DOMAIN)
    components.update(hass.config_entries.async_domains())

    # setup components
    res = await core_components.async_setup(hass, config)
    if not res:
        _LOGGER.error("Home Assistant core failed to initialize. "
                      "further initialization aborted")
        return hass

    await persistent_notification.async_setup(hass, config)

    _LOGGER.info("Home Assistant core initialized")

    # stage 1
    for component in components:
        if component not in FIRST_INIT_COMPONENT:
            continue
        hass.async_create_task(async_setup_component(hass, component, config))

    await hass.async_block_till_done()

    # stage 2
    for component in components:
        if component in FIRST_INIT_COMPONENT:
            continue
        hass.async_create_task(async_setup_component(hass, component, config))

    await hass.async_block_till_done()

    stop = time()
    _LOGGER.info("Home Assistant initialized in %.2fs", stop-start)

    async_register_signal_handling(hass)
    return hass
Example #28
0
async def async_from_config_dict(
    config: Dict[str, Any],
    hass: core.HomeAssistant,
    config_dir: Optional[str] = None,
    enable_log: bool = True,
    verbose: bool = False,
    skip_pip: bool = False,
    log_rotate_days: Any = None,
    log_file: Any = None,
    log_no_color: bool = False,
) -> Optional[core.HomeAssistant]:
    """Try to configure Home Assistant from a configuration dictionary.

    Dynamically loads required components and its dependencies.
    This method is a coroutine.
    """
    start = time()

    if enable_log:
        async_enable_logging(hass, verbose, log_rotate_days, log_file,
                             log_no_color)

    hass.config.skip_pip = skip_pip
    if skip_pip:
        _LOGGER.warning(
            "Skipping pip installation of required modules. This may cause issues"
        )

    core_config = config.get(core.DOMAIN, {})

    try:
        await conf_util.async_process_ha_core_config(hass, core_config)
    except vol.Invalid as config_err:
        conf_util.async_log_exception(config_err, "homeassistant", core_config,
                                      hass)
        return None
    except HomeAssistantError:
        _LOGGER.error("Home Assistant core failed to initialize. "
                      "Further initialization aborted")
        return None

    # Make a copy because we are mutating it.
    config = OrderedDict(config)

    # Merge packages
    await conf_util.merge_packages_config(
        hass, config, core_config.get(conf_util.CONF_PACKAGES, {}))

    hass.config_entries = config_entries.ConfigEntries(hass, config)
    await hass.config_entries.async_initialize()

    await _async_set_up_integrations(hass, config)

    stop = time()
    _LOGGER.info("Home Assistant initialized in %.2fs", stop - start)

    if REQUIRED_NEXT_PYTHON_DATE and sys.version_info[:
                                                      3] < REQUIRED_NEXT_PYTHON_VER:
        msg = (
            "Support for the running Python version "
            f"{'.'.join(str(x) for x in sys.version_info[:3])} is deprecated and will "
            f"be removed in the first release after {REQUIRED_NEXT_PYTHON_DATE}. "
            "Please upgrade Python to "
            f"{'.'.join(str(x) for x in REQUIRED_NEXT_PYTHON_VER)} or "
            "higher.")
        _LOGGER.warning(msg)
        hass.components.persistent_notification.async_create(
            msg, "Python version", "python_version")

    return hass
Example #29
0
def async_setup(hass: HomeAssistantType, config: ConfigType):
    """Setup device tracker."""
    yaml_path = hass.config.path(YAML_DEVICES)

    try:
        conf = config.get(DOMAIN, [])
    except vol.Invalid as ex:
        async_log_exception(ex, DOMAIN, config, hass)
        return False
    else:
        conf = conf[0] if len(conf) > 0 else {}
        consider_home = conf.get(CONF_CONSIDER_HOME, DEFAULT_CONSIDER_HOME)
        track_new = conf.get(CONF_TRACK_NEW, DEFAULT_TRACK_NEW)

    devices = yield from async_load_config(yaml_path, hass, consider_home)
    tracker = DeviceTracker(hass, consider_home, track_new, devices)

    @asyncio.coroutine
    def async_setup_platform(p_type, p_config, disc_info=None):
        """Setup 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.loop.run_in_executor(
                    None, 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.loop.run_in_executor(
                    None, 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)

    setup_tasks = [
        async_setup_platform(p_type, p_config)
        for p_type, p_config in config_per_platform(config, DOMAIN)
    ]
    if setup_tasks:
        yield from asyncio.wait(setup_tasks, loop=hass.loop)

    yield from tracker.async_setup_group()

    @callback
    def async_device_tracker_discovered(service, info):
        """Called when a device tracker platform is discovered."""
        hass.async_add_job(
            async_setup_platform(DISCOVERY_PLATFORMS[service], {}, info))

    discovery.async_listen(hass, DISCOVERY_PLATFORMS.keys(),
                           async_device_tracker_discovered)

    @asyncio.coroutine
    def async_platform_discovered(platform, info):
        """Callback to load a platform."""
        yield from async_setup_platform(platform, {}, disc_info=info)

    discovery.async_listen_platform(hass, DOMAIN, async_platform_discovered)

    # Clean up stale devices
    async_track_utc_time_change(hass,
                                tracker.async_update_stale,
                                second=range(0, 60, 5))

    @asyncio.coroutine
    def async_see_service(call):
        """Service to see a device."""
        args = {
            key: value
            for key, value in call.data.items()
            if key in (ATTR_MAC, ATTR_DEV_ID, ATTR_HOST_NAME,
                       ATTR_LOCATION_NAME, ATTR_GPS, ATTR_GPS_ACCURACY,
                       ATTR_BATTERY, ATTR_ATTRIBUTES)
        }
        yield from tracker.async_see(**args)

    descriptions = yield from hass.loop.run_in_executor(
        None, load_yaml_config_file,
        os.path.join(os.path.dirname(__file__), 'services.yaml'))
    hass.services.async_register(DOMAIN, SERVICE_SEE, async_see_service,
                                 descriptions.get(SERVICE_SEE))

    # restore
    yield from tracker.async_setup_tracked_device()
    return True
Example #30
0
async def async_from_config_dict(config: Dict[str, Any],
                                 hass: core.HomeAssistant,
                                 config_dir: Optional[str] = None,
                                 enable_log: bool = True,
                                 verbose: bool = False,
                                 skip_pip: bool = False,
                                 log_rotate_days: Any = None,
                                 log_file: Any = None,
                                 log_no_color: bool = False) \
                           -> Optional[core.HomeAssistant]:
    """Try to configure Home Assistant from a configuration dictionary.

    Dynamically loads required components and its dependencies.
    This method is a coroutine.
    """
    start = time()

    if enable_log:
        async_enable_logging(hass, verbose, log_rotate_days, log_file,
                             log_no_color)

    hass.config.skip_pip = skip_pip
    if skip_pip:
        _LOGGER.warning("Skipping pip installation of required modules. "
                        "This may cause issues")

    core_config = config.get(core.DOMAIN, {})
    api_password = config.get('http', {}).get('api_password')
    trusted_networks = config.get('http', {}).get('trusted_networks')

    try:
        await conf_util.async_process_ha_core_config(hass, core_config,
                                                     api_password,
                                                     trusted_networks)
    except vol.Invalid as config_err:
        conf_util.async_log_exception(config_err, 'homeassistant', core_config,
                                      hass)
        return None
    except HomeAssistantError:
        _LOGGER.error("Home Assistant core failed to initialize. "
                      "Further initialization aborted")
        return None

    # Make a copy because we are mutating it.
    config = OrderedDict(config)

    # Merge packages
    await conf_util.merge_packages_config(
        hass, config, core_config.get(conf_util.CONF_PACKAGES, {}))

    hass.config_entries = config_entries.ConfigEntries(hass, config)
    await hass.config_entries.async_initialize()

    await _async_set_up_integrations(hass, config)

    stop = time()
    _LOGGER.info("Home Assistant initialized in %.2fs", stop - start)

    if sys.version_info[:3] < (3, 6, 0):
        hass.components.persistent_notification.async_create(
            "Python 3.5 support is deprecated and will "
            "be removed in the first release after August 1. Please "
            "upgrade Python.", "Python version", "python_version")

    return hass
Example #31
0
def async_from_config_dict(config: Dict[str, Any],
                           hass: core.HomeAssistant,
                           config_dir: Optional[str] = None,
                           enable_log: bool = True,
                           verbose: bool = False,
                           skip_pip: bool = False,
                           log_rotate_days: Any = None,
                           log_file: Any = None) \
                           -> Optional[core.HomeAssistant]:
    """Try to configure Home Assistant from a configuration dictionary.

    Dynamically loads required components and its dependencies.
    This method is a coroutine.
    """
    start = time()

    if enable_log:
        async_enable_logging(hass, verbose, log_rotate_days, log_file)

    if sys.version_info[:2] < (3, 5):
        _LOGGER.warning(
            'Python 3.4 support has been deprecated and will be removed in '
            'the beginning of 2018. Please upgrade Python or your operating '
            'system. More info: https://home-assistant.io/blog/2017/10/06/'
            'deprecating-python-3.4-support/'
        )

    core_config = config.get(core.DOMAIN, {})

    try:
        yield from conf_util.async_process_ha_core_config(hass, core_config)
    except vol.Invalid as ex:
        conf_util.async_log_exception(ex, 'homeassistant', core_config, hass)
        return None

    yield from hass.async_add_job(conf_util.process_ha_config_upgrade, hass)

    hass.config.skip_pip = skip_pip
    if skip_pip:
        _LOGGER.warning("Skipping pip installation of required modules. "
                        "This may cause issues")

    if not loader.PREPARED:
        yield from hass.async_add_job(loader.prepare, hass)

    # Make a copy because we are mutating it.
    new_config = OrderedDict()
    for key, value in config.items():
        new_config[key] = value or {}
    config = new_config

    # Merge packages
    conf_util.merge_packages_config(
        config, core_config.get(conf_util.CONF_PACKAGES, {}))

    hass.config_entries = config_entries.ConfigEntries(hass, config)
    yield from hass.config_entries.async_load()

    # Filter out the repeating and common config section [homeassistant]
    components = set(key.split(' ')[0] for key in config.keys()
                     if key != core.DOMAIN)
    components.update(hass.config_entries.async_domains())

    # setup components
    # pylint: disable=not-an-iterable
    res = yield from core_components.async_setup(hass, config)
    if not res:
        _LOGGER.error("Home Assistant core failed to initialize. "
                      "further initialization aborted")
        return hass

    yield from persistent_notification.async_setup(hass, config)

    _LOGGER.info("Home Assistant core initialized")

    # stage 1
    for component in components:
        if component not in FIRST_INIT_COMPONENT:
            continue
        hass.async_add_job(async_setup_component(hass, component, config))

    yield from hass.async_block_till_done()

    # stage 2
    for component in components:
        if component in FIRST_INIT_COMPONENT:
            continue
        hass.async_add_job(async_setup_component(hass, component, config))

    yield from hass.async_block_till_done()

    stop = time()
    _LOGGER.info("Home Assistant initialized in %.2fs", stop-start)

    async_register_signal_handling(hass)
    return hass
Example #32
0
async def async_from_config_dict(config: Dict[str, Any],
                                 hass: core.HomeAssistant,
                                 config_dir: Optional[str] = None,
                                 enable_log: bool = True,
                                 verbose: bool = False,
                                 skip_pip: bool = False,
                                 log_rotate_days: Any = None,
                                 log_file: Any = None,
                                 log_no_color: bool = False) \
                           -> Optional[core.HomeAssistant]:
    """Try to configure Home Assistant from a configuration dictionary.

    Dynamically loads required components and its dependencies.
    This method is a coroutine.
    """
    start = time()

    if enable_log:
        async_enable_logging(hass, verbose, log_rotate_days, log_file,
                             log_no_color)

    core_config = config.get(core.DOMAIN, {})
    has_api_password = bool((config.get('http') or {}).get('api_password'))
    has_trusted_networks = bool((config.get('http')
                                 or {}).get('trusted_networks'))

    try:
        await conf_util.async_process_ha_core_config(hass, core_config,
                                                     has_api_password,
                                                     has_trusted_networks)
    except vol.Invalid as config_err:
        conf_util.async_log_exception(config_err, 'homeassistant', core_config,
                                      hass)
        return None
    except HomeAssistantError:
        _LOGGER.error("Home Assistant core failed to initialize. "
                      "Further initialization aborted")
        return None

    await hass.async_add_executor_job(conf_util.process_ha_config_upgrade,
                                      hass)

    hass.config.skip_pip = skip_pip
    if skip_pip:
        _LOGGER.warning("Skipping pip installation of required modules. "
                        "This may cause issues")

    # Make a copy because we are mutating it.
    config = OrderedDict(config)

    # Merge packages
    conf_util.merge_packages_config(
        hass, config, core_config.get(conf_util.CONF_PACKAGES, {}))

    # Ensure we have no None values after merge
    for key, value in config.items():
        if not value:
            config[key] = {}

    hass.config_entries = config_entries.ConfigEntries(hass, config)
    await hass.config_entries.async_load()

    # Filter out the repeating and common config section [homeassistant]
    components = set(
        key.split(' ')[0] for key in config.keys() if key != core.DOMAIN)
    components.update(hass.config_entries.async_domains())

    # setup components
    res = await core_components.async_setup(hass, config)
    if not res:
        _LOGGER.error("Home Assistant core failed to initialize. "
                      "Further initialization aborted")
        return hass

    await persistent_notification.async_setup(hass, config)

    _LOGGER.info("Home Assistant core initialized")

    # stage 1
    for component in components:
        if component not in FIRST_INIT_COMPONENT:
            continue
        hass.async_create_task(async_setup_component(hass, component, config))

    await hass.async_block_till_done()

    # stage 2
    for component in components:
        if component in FIRST_INIT_COMPONENT:
            continue
        hass.async_create_task(async_setup_component(hass, component, config))

    await hass.async_block_till_done()

    stop = time()
    _LOGGER.info("Home Assistant initialized in %.2fs", stop - start)

    return hass