def test_find_config_file_prefers_yaml_over_conf(self): """ Test if find config prefers YAML over CONF if both exist. """ create_file(YAML_PATH) create_file(CONF_PATH) self.assertEqual(YAML_PATH, config_util.find_config_file(CONFIG_DIR))
def reload_themes(_): """Reload themes.""" path = find_config_file(hass.config.config_dir) new_themes = load_yaml_config_file(path)[DOMAIN].get(CONF_THEMES, {}) hass.data[DATA_THEMES] = new_themes if hass.data[DATA_DEFAULT_THEME] not in new_themes: hass.data[DATA_DEFAULT_THEME] = DEFAULT_THEME update_theme_and_fire_event()
def handle_reload_config(call): """Service handler for reloading core config.""" from homeassistant.exceptions import HomeAssistantError from homeassistant import config as conf_util try: path = conf_util.find_config_file(hass.config.config_dir) conf = conf_util.load_yaml_config_file(path) except HomeAssistantError as err: _LOGGER.error(err) return conf_util.process_ha_core_config(hass, conf.get(ha.DOMAIN) or {})
def prepare_reload(self): """Prepare reloading this entity component.""" try: path = conf_util.find_config_file(self.hass.config.config_dir) conf = conf_util.load_yaml_config_file(path) except HomeAssistantError as err: self.logger.error(err) return None conf = prepare_setup_component(self.hass, conf, self.domain) if conf is None: return None self.reset() return conf
def test_find_config_file_yaml(self): """Test if it finds a YAML config file.""" create_file(YAML_PATH) assert YAML_PATH == config_util.find_config_file(CONFIG_DIR)
def test_find_config_file_yaml(): """Test if it finds a YAML config file.""" create_file(YAML_PATH) assert YAML_PATH == config_util.find_config_file(CONFIG_DIR)
def check_ha_config_file(hass): """Check if Home Assistant configuration file is valid.""" config_dir = hass.config.config_dir result = HomeAssistantConfig() def _pack_error(package, component, config, message): """Handle errors from packages: _log_pkg_error.""" message = "Package {} setup failed. Component {} {}".format( package, component, message) domain = 'homeassistant.packages.{}.{}'.format(package, component) pack_config = core_config[CONF_PACKAGES].get(package, config) result.add_error(message, domain, pack_config) def _comp_error(ex, domain, config): """Handle errors from components: async_log_exception.""" result.add_error(_format_config_error(ex, domain, config), domain, config) # Load configuration.yaml try: config_path = find_config_file(config_dir) if not config_path: return result.add_error("File configuration.yaml not found.") config = load_yaml_config_file(config_path) except HomeAssistantError as err: return result.add_error("Error loading {}: {}".format( config_path, err)) finally: yaml.clear_secret_cache() # Extract and validate core [homeassistant] config try: core_config = config.pop(CONF_CORE, {}) core_config = CORE_CONFIG_SCHEMA(core_config) result[CONF_CORE] = core_config except vol.Invalid as err: result.add_error(err, CONF_CORE, core_config) core_config = {} # Merge packages merge_packages_config(hass, config, core_config.get(CONF_PACKAGES, {}), _pack_error) del core_config[CONF_PACKAGES] # Ensure we have no None values after merge for key, value in config.items(): if not value: config[key] = {} # Filter out repeating config sections components = set(key.split(' ')[0] for key in config.keys()) # Process and validate config for domain in components: component = loader.get_component(hass, domain) if not component: result.add_error("Component not found: {}".format(domain)) continue if hasattr(component, 'CONFIG_SCHEMA'): try: config = component.CONFIG_SCHEMA(config) result[domain] = config[domain] except vol.Invalid as ex: _comp_error(ex, domain, config) continue if not hasattr(component, 'PLATFORM_SCHEMA'): continue platforms = [] for p_name, p_config in config_per_platform(config, domain): # Validate component specific platform schema try: p_validated = component.PLATFORM_SCHEMA(p_config) except vol.Invalid as ex: _comp_error(ex, domain, config) continue # Not all platform components follow same pattern for platforms # So if p_name is None we are not going to validate platform # (the automation component is one of them) if p_name is None: platforms.append(p_validated) continue platform = loader.get_platform(hass, domain, p_name) if platform is None: result.add_error("Platform not found: {}.{}".format( domain, p_name)) continue # Validate platform specific schema if hasattr(platform, 'PLATFORM_SCHEMA'): try: p_validated = platform.PLATFORM_SCHEMA(p_validated) except vol.Invalid as ex: _comp_error(ex, '{}.{}'.format(domain, p_name), p_validated) continue platforms.append(p_validated) # Remove config for current component and add validated config back in. for filter_comp in extract_domain_configs(config, domain): del config[filter_comp] result[domain] = platforms return result
def check_ha_config_file(hass): """Check if Home Assistant configuration file is valid.""" config_dir = hass.config.config_dir result = HomeAssistantConfig() def _pack_error(package, component, config, message): """Handle errors from packages: _log_pkg_error.""" message = "Package {} setup failed. Component {} {}".format( package, component, message) domain = 'homeassistant.packages.{}.{}'.format(package, component) pack_config = core_config[CONF_PACKAGES].get(package, config) result.add_error(message, domain, pack_config) def _comp_error(ex, domain, config): """Handle errors from components: async_log_exception.""" result.add_error( _format_config_error(ex, domain, config), domain, config) # Load configuration.yaml try: config_path = find_config_file(config_dir) if not config_path: return result.add_error("File configuration.yaml not found.") config = load_yaml_config_file(config_path) except HomeAssistantError as err: return result.add_error( "Error loading {}: {}".format(config_path, err)) finally: yaml.clear_secret_cache() # Extract and validate core [homeassistant] config try: core_config = config.pop(CONF_CORE, {}) core_config = CORE_CONFIG_SCHEMA(core_config) result[CONF_CORE] = core_config except vol.Invalid as err: result.add_error(err, CONF_CORE, core_config) core_config = {} # Merge packages merge_packages_config( hass, config, core_config.get(CONF_PACKAGES, {}), _pack_error) core_config.pop(CONF_PACKAGES, None) # Filter out repeating config sections components = set(key.split(' ')[0] for key in config.keys()) # Process and validate config for domain in components: component = loader.get_component(hass, domain) if not component: result.add_error("Component not found: {}".format(domain)) continue if hasattr(component, 'CONFIG_SCHEMA'): try: config = component.CONFIG_SCHEMA(config) result[domain] = config[domain] except vol.Invalid as ex: _comp_error(ex, domain, config) continue if (not hasattr(component, 'PLATFORM_SCHEMA') and not hasattr(component, 'PLATFORM_SCHEMA_BASE')): continue platforms = [] for p_name, p_config in config_per_platform(config, domain): # Validate component specific platform schema try: if hasattr(component, 'PLATFORM_SCHEMA_BASE'): p_validated = \ component.PLATFORM_SCHEMA_BASE( # type: ignore p_config) else: p_validated = component.PLATFORM_SCHEMA( # type: ignore p_config) except vol.Invalid as ex: _comp_error(ex, domain, config) continue # Not all platform components follow same pattern for platforms # So if p_name is None we are not going to validate platform # (the automation component is one of them) if p_name is None: platforms.append(p_validated) continue platform = loader.get_platform(hass, domain, p_name) if platform is None: result.add_error( "Platform not found: {}.{}".format(domain, p_name)) continue # Validate platform specific schema if hasattr(platform, 'PLATFORM_SCHEMA'): try: p_validated = platform.PLATFORM_SCHEMA(p_validated) except vol.Invalid as ex: _comp_error( ex, '{}.{}'.format(domain, p_name), p_validated) continue platforms.append(p_validated) # Remove config for current component and add validated config back in. for filter_comp in extract_domain_configs(config, domain): del config[filter_comp] result[domain] = platforms return result
def test_find_config_file_yaml(self): """Test if it finds a YAML config file.""" create_file(YAML_PATH) self.assertEqual(YAML_PATH, config_util.find_config_file(CONFIG_DIR))
def test_find_config_file_conf(self): """ Test if it finds the old CONF config file. """ create_file(CONF_PATH) self.assertEqual(CONF_PATH, config_util.find_config_file(CONFIG_DIR))
def main(): global GROUP_CONFIG logging.basicConfig(level=logging.INFO) try: from colorlog import ColoredFormatter logging.getLogger().handlers[0].setFormatter( ColoredFormatter("%(log_color)s%(levelname)s %(message)s%(reset)s", datefmt="", reset=True, log_colors={ 'DEBUG': 'cyan', 'INFO': 'green', 'WARNING': 'yellow', 'ERROR': 'red', 'CRITICAL': 'red', })) except ImportError: pass parser = argparse.ArgumentParser( description="Check Home Assistant configuration.") parser.add_argument( '-c', '--config', default=get_default_config_dir(), help="Directory that contains the Home Assistant configuration") args = parser.parse_args() config_dir = os.path.join(os.getcwd(), args.config) hass = homeassistant.core.HomeAssistant() hass.config.config_dir = config_dir config_path = find_config_file(config_dir) config = load_yaml_config_file(config_path) GROUP_CONFIG = config['group'] name = config['homeassistant'].get('name', 'Home') lovelace = OrderedDict() lovelace['name'] = name views = lovelace['views'] = [] if 'default_view' in GROUP_CONFIG: views.append(convert_view(GROUP_CONFIG['default_view'], 'default_view')) for name, conf in GROUP_CONFIG.items(): if name == 'default_view': continue if not conf.get('view', False): continue views.append(convert_view(conf, name)) views.append({ 'name': "All Entities", 'tab_icon': "mdi:settings", 'cards': [{ 'type': 'entity-filter', 'filter': [{}], 'card_config': { 'title': 'All Entities' } }], }) lovelace_path = os.path.join(config_dir, 'ui-lovelace.yaml') if os.path.exists(lovelace_path): i = 0 while os.path.exists(lovelace_path + '.bkp.{}'.format(i)): i += 1 bkp_path = lovelace_path + '.bkp.{}'.format(i) shutil.move(lovelace_path, bkp_path) _LOGGER.error( "The lovelace configuration already exists under %s! " "I will move it to %s", lovelace_path, bkp_path) with open(lovelace_path, 'w', encoding='utf-8') as f: f.write(yaml.dump(lovelace) + '\n') _LOGGER.info("Successfully migrated lovelace configuration to %s", lovelace_path) return 0