def create_default_config(config_dir, detect_location=True): """Create a default configuration file in given configuration directory. Return path to new config file if success, None if failed. This method needs to run in an executor. """ from homeassistant.components.config.group import ( CONFIG_PATH as GROUP_CONFIG_PATH) config_path = os.path.join(config_dir, YAML_CONFIG_FILE) version_path = os.path.join(config_dir, VERSION_FILE) group_yaml_path = os.path.join(config_dir, GROUP_CONFIG_PATH) info = {attr: default for attr, default, _, _ in DEFAULT_CORE_CONFIG} location_info = detect_location and loc_util.detect_location_info() if location_info: if location_info.use_metric: info[CONF_UNIT_SYSTEM] = CONF_UNIT_SYSTEM_METRIC else: info[CONF_UNIT_SYSTEM] = CONF_UNIT_SYSTEM_IMPERIAL for attr, default, prop, _ in DEFAULT_CORE_CONFIG: if prop is None: continue info[attr] = getattr(location_info, prop) or default if location_info.latitude and location_info.longitude: info[CONF_ELEVATION] = loc_util.elevation(location_info.latitude, location_info.longitude) # Writing files with YAML does not create the most human readable results # So we're hard coding a YAML template. try: with open(config_path, 'w') as config_file: config_file.write("homeassistant:\n") for attr, _, _, description in DEFAULT_CORE_CONFIG: if info[attr] is None: continue elif description: config_file.write(" # {}\n".format(description)) config_file.write(" {}: {}\n".format(attr, info[attr])) config_file.write(DEFAULT_CONFIG) with open(version_path, 'wt') as version_file: version_file.write(__version__) with open(group_yaml_path, 'w'): pass return config_path except IOError: print('Unable to create default configuration file', config_path) return None
def create_default_config(config_dir, detect_location=True): """Create a default configuration file in given configuration directory. Return path to new config file if success, None if failed. """ config_path = os.path.join(config_dir, YAML_CONFIG_FILE) version_path = os.path.join(config_dir, VERSION_FILE) info = {attr: default for attr, default, _, _ in DEFAULT_CONFIG} location_info = detect_location and loc_util.detect_location_info() if location_info: if location_info.use_fahrenheit: info[CONF_TEMPERATURE_UNIT] = 'F' for attr, default, prop, _ in DEFAULT_CONFIG: if prop is None: continue info[attr] = getattr(location_info, prop) or default if location_info.latitude and location_info.longitude: info[CONF_ELEVATION] = loc_util.elevation(location_info.latitude, location_info.longitude) # Writing files with YAML does not create the most human readable results # So we're hard coding a YAML template. try: with open(config_path, 'w') as config_file: config_file.write("homeassistant:\n") for attr, _, _, description in DEFAULT_CONFIG: if info[attr] is None: continue elif description: config_file.write(" # {}\n".format(description)) config_file.write(" {}: {}\n".format(attr, info[attr])) config_file.write("\n") for component, description in DEFAULT_COMPONENTS.items(): config_file.write("# {}\n".format(description)) config_file.write("{}\n\n".format(component)) with open(version_path, 'wt') as version_file: version_file.write(__version__) return config_path except IOError: print('Unable to create default configuration file', config_path) return None
def test_detect_location_info_ipapi(self, mock_req, mock_freegeoip): """Test detect location info using freegeoip.""" mock_req.get(location_util.IP_API, text=load_fixture('ip-api.com.json')) info = location_util.detect_location_info(_test_real=True) assert info is not None assert info.ip == '1.2.3.4' assert info.country_code == 'US' assert info.country_name == 'United States' assert info.region_code == 'CA' assert info.region_name == 'California' assert info.city == 'San Diego' assert info.zip_code == '92122' assert info.time_zone == 'America/Los_Angeles' assert info.latitude == 32.8594 assert info.longitude == -117.2073 assert info.use_fahrenheit
def create_default_config(config_dir, detect_location=True): """ Creates a default configuration file in given config dir. Returns path to new config file if success, None if failed. """ config_path = os.path.join(config_dir, YAML_CONFIG_FILE) info = {attr: default for attr, default, *_ in DEFAULT_CONFIG} location_info = detect_location and loc_util.detect_location_info() if location_info: if location_info.use_fahrenheit: info[CONF_TEMPERATURE_UNIT] = 'F' for attr, default, prop, _ in DEFAULT_CONFIG: if prop is None: continue info[attr] = getattr(location_info, prop) or default # Writing files with YAML does not create the most human readable results # So we're hard coding a YAML template. try: with open(config_path, 'w') as config_file: config_file.write("homeassistant:\n") for attr, _, _, description in DEFAULT_CONFIG: if info[attr] is None: continue elif description: config_file.write(" # {}\n".format(description)) config_file.write(" {}: {}\n".format(attr, info[attr])) config_file.write("\n") for component in DEFAULT_COMPONENTS: config_file.write("{}:\n\n".format(component)) return config_path except IOError: _LOGGER.exception( 'Unable to write default configuration file %s', config_path) return None
def test_detect_location_info_ipapi(self, m): """Test detect location info using ipapi.co.""" m.get( location_util.IPAPI, text=load_fixture('ipapi.co.json')) info = location_util.detect_location_info(_test_real=True) assert info is not None assert info.ip == '1.2.3.4' assert info.country_code == 'CH' assert info.country_name == 'Switzerland' assert info.region_code == 'BE' assert info.region_name == 'Bern' assert info.city == 'Bern' assert info.zip_code == '3000' assert info.time_zone == 'Europe/Zurich' assert info.latitude == 46.9480278 assert info.longitude == 7.4490812 assert info.use_metric
def create_default_config(config_dir, detect_location=True): """ Creates a default configuration file in given config dir. Returns path to new config file if success, None if failed. """ config_path = os.path.join(config_dir, YAML_CONFIG_FILE) info = {attr: default for attr, default, _, _ in DEFAULT_CONFIG} location_info = detect_location and loc_util.detect_location_info() if location_info: if location_info.use_fahrenheit: info[CONF_TEMPERATURE_UNIT] = 'F' for attr, default, prop, _ in DEFAULT_CONFIG: if prop is None: continue info[attr] = getattr(location_info, prop) or default # Writing files with YAML does not create the most human readable results # So we're hard coding a YAML template. try: with open(config_path, 'w') as config_file: config_file.write("homeassistant:\n") for attr, _, _, description in DEFAULT_CONFIG: if info[attr] is None: continue elif description: config_file.write(" # {}\n".format(description)) config_file.write(" {}: {}\n".format(attr, info[attr])) config_file.write("\n") for component, description in DEFAULT_COMPONENTS.items(): config_file.write("# {}\n".format(description)) config_file.write("{}:\n\n".format(component)) return config_path except IOError: print('Unable to create default configuration file', config_path) return None
def set_homeassistant_config(self): info = { attr: default for attr, default, _, _ in POLY_HOMEASSISTANT_CONFIG } location_info = True and loc_util.detect_location_info() # print(location_info) if location_info: if location_info.use_metric: info[CONF_UNIT_SYSTEM] = CONF_UNIT_SYSTEM_METRIC else: info[CONF_UNIT_SYSTEM] = CONF_UNIT_SYSTEM_IMPERIAL for attr, default, prop, _ in POLY_HOMEASSISTANT_CONFIG: if prop is None: continue info[attr] = getattr(location_info, prop) or default if location_info.latitude and location_info.longitude: info[CONF_ELEVATION] = loc_util.elevation( location_info.latitude, location_info.longitude) try: # write default config text with open(self._save_dir + 'configuration.yaml', 'wt') as config_file: config_file.write("homeassistant:\n") for attr, _, _, description in POLY_HOMEASSISTANT_CONFIG: if info[attr] is None: continue elif description: config_file.write(" # {}\n".format(description)) config_file.write(" {}: {}\n".format(attr, info[attr])) except IOError: _LOGGER.error("Unable to create default configuration file") finally: config_file.close()
def test_detect_location_info_both_queries_fail(self, mock_ipapi, mock_ip_api, mock_elevation): """Ensure we return None if both queries fail.""" info = location_util.detect_location_info(_test_real=True) assert info is None
def create_default_config(config_dir, detect_location=True): """Create a default configuration file in given configuration directory. Return path to new config file if success, None if failed. This method needs to run in an executor. """ from homeassistant.components.config.group import ( CONFIG_PATH as GROUP_CONFIG_PATH) from homeassistant.components.config.automation import ( CONFIG_PATH as AUTOMATION_CONFIG_PATH) from homeassistant.components.config.script import ( CONFIG_PATH as SCRIPT_CONFIG_PATH) from homeassistant.components.config.customize import ( CONFIG_PATH as CUSTOMIZE_CONFIG_PATH) config_path = os.path.join(config_dir, YAML_CONFIG_FILE) secret_path = os.path.join(config_dir, SECRET_YAML) version_path = os.path.join(config_dir, VERSION_FILE) group_yaml_path = os.path.join(config_dir, GROUP_CONFIG_PATH) automation_yaml_path = os.path.join(config_dir, AUTOMATION_CONFIG_PATH) script_yaml_path = os.path.join(config_dir, SCRIPT_CONFIG_PATH) customize_yaml_path = os.path.join(config_dir, CUSTOMIZE_CONFIG_PATH) info = {attr: default for attr, default, _, _ in DEFAULT_CORE_CONFIG} location_info = detect_location and loc_util.detect_location_info() if location_info: if location_info.use_metric: info[CONF_UNIT_SYSTEM] = CONF_UNIT_SYSTEM_METRIC else: info[CONF_UNIT_SYSTEM] = CONF_UNIT_SYSTEM_IMPERIAL for attr, default, prop, _ in DEFAULT_CORE_CONFIG: if prop is None: continue info[attr] = getattr(location_info, prop) or default if location_info.latitude and location_info.longitude: info[CONF_ELEVATION] = loc_util.elevation( location_info.latitude, location_info.longitude) # Writing files with YAML does not create the most human readable results # So we're hard coding a YAML template. try: with open(config_path, 'wt') as config_file: config_file.write("homeassistant:\n") for attr, _, _, description in DEFAULT_CORE_CONFIG: if info[attr] is None: continue elif description: config_file.write(" # {}\n".format(description)) config_file.write(" {}: {}\n".format(attr, info[attr])) config_file.write(DEFAULT_CONFIG) with open(secret_path, 'wt') as secret_file: secret_file.write(DEFAULT_SECRETS) with open(version_path, 'wt') as version_file: version_file.write(__version__) with open(group_yaml_path, 'wt'): pass with open(automation_yaml_path, 'wt') as fil: fil.write('[]') with open(script_yaml_path, 'wt'): pass with open(customize_yaml_path, 'wt'): pass return config_path except IOError: print("Unable to create default configuration file", config_path) return None
def process_ha_core_config(hass, config): """ Processes the [homeassistant] section from the config. """ hac = hass.config def set_time_zone(time_zone_str): """ Helper method to set time zone in HA. """ if time_zone_str is None: return time_zone = date_util.get_time_zone(time_zone_str) if time_zone: hac.time_zone = time_zone date_util.set_default_time_zone(time_zone) else: _LOGGER.error('Received invalid time zone %s', time_zone_str) for key, attr in ((CONF_LATITUDE, 'latitude'), (CONF_LONGITUDE, 'longitude'), (CONF_NAME, 'location_name')): if key in config: setattr(hac, attr, config[key]) set_time_zone(config.get(CONF_TIME_ZONE)) customize = config.get(CONF_CUSTOMIZE) if isinstance(customize, dict): for entity_id, attrs in config.get(CONF_CUSTOMIZE, {}).items(): if not isinstance(attrs, dict): continue Entity.overwrite_attribute(entity_id, attrs.keys(), attrs.values()) if CONF_TEMPERATURE_UNIT in config: unit = config[CONF_TEMPERATURE_UNIT] if unit == 'C': hac.temperature_unit = TEMP_CELCIUS elif unit == 'F': hac.temperature_unit = TEMP_FAHRENHEIT # If we miss some of the needed values, auto detect them if None not in ( hac.latitude, hac.longitude, hac.temperature_unit, hac.time_zone): return _LOGGER.info('Auto detecting location and temperature unit') info = loc_util.detect_location_info() if info is None: _LOGGER.error('Could not detect location information') return if hac.latitude is None and hac.longitude is None: hac.latitude = info.latitude hac.longitude = info.longitude if hac.temperature_unit is None: if info.use_fahrenheit: hac.temperature_unit = TEMP_FAHRENHEIT else: hac.temperature_unit = TEMP_CELCIUS if hac.location_name is None: hac.location_name = info.city if hac.time_zone is None: set_time_zone(info.time_zone)
def process_ha_core_config(hass, config): """ Processes the [homeassistant] section from the config. """ hac = hass.config def set_time_zone(time_zone_str): """ Helper method to set time zone in HA. """ if time_zone_str is None: return time_zone = date_util.get_time_zone(time_zone_str) if time_zone: hac.time_zone = time_zone date_util.set_default_time_zone(time_zone) else: _LOGGER.error('Received invalid time zone %s', time_zone_str) for key, attr in ((CONF_LATITUDE, 'latitude'), (CONF_LONGITUDE, 'longitude'), (CONF_NAME, 'location_name')): if key in config: setattr(hac, attr, config[key]) set_time_zone(config.get(CONF_TIME_ZONE)) customize = config.get(CONF_CUSTOMIZE) if isinstance(customize, dict): for entity_id, attrs in config.get(CONF_CUSTOMIZE, {}).items(): if not isinstance(attrs, dict): continue Entity.overwrite_attribute(entity_id, attrs.keys(), attrs.values()) if CONF_TEMPERATURE_UNIT in config: unit = config[CONF_TEMPERATURE_UNIT] if unit == 'C': hac.temperature_unit = TEMP_CELCIUS elif unit == 'F': hac.temperature_unit = TEMP_FAHRENHEIT # If we miss some of the needed values, auto detect them if None not in (hac.latitude, hac.longitude, hac.temperature_unit, hac.time_zone): return _LOGGER.info('Auto detecting location and temperature unit') info = loc_util.detect_location_info() if info is None: _LOGGER.error('Could not detect location information') return if hac.latitude is None and hac.longitude is None: hac.latitude = info.latitude hac.longitude = info.longitude if hac.temperature_unit is None: if info.use_fahrenheit: hac.temperature_unit = TEMP_FAHRENHEIT else: hac.temperature_unit = TEMP_CELCIUS if hac.location_name is None: hac.location_name = info.city if hac.time_zone is None: set_time_zone(info.time_zone)
def test_detect_location_info_both_queries_fail(self, mock_ipapi, mock_freegeoip, mock_elevation): """Ensure we return None if both queries fail.""" info = location_util.detect_location_info(_test_real=True) assert info is None
def process_ha_core_config(hass, config): """Process the [homeassistant] section from the config.""" # pylint: disable=too-many-branches config = CORE_CONFIG_SCHEMA(config) hac = hass.config def set_time_zone(time_zone_str): """Helper method to set time zone.""" if time_zone_str is None: return time_zone = date_util.get_time_zone(time_zone_str) if time_zone: hac.time_zone = time_zone date_util.set_default_time_zone(time_zone) else: _LOGGER.error('Received invalid time zone %s', time_zone_str) for key, attr in ((CONF_LATITUDE, 'latitude'), (CONF_LONGITUDE, 'longitude'), (CONF_NAME, 'location_name'), (CONF_ELEVATION, 'elevation')): if key in config: setattr(hac, attr, config[key]) if CONF_TIME_ZONE in config: set_time_zone(config.get(CONF_TIME_ZONE)) set_customize(config.get(CONF_CUSTOMIZE) or {}) if CONF_UNIT_SYSTEM in config: if config[CONF_UNIT_SYSTEM] == CONF_UNIT_SYSTEM_IMPERIAL: hac.units = IMPERIAL_SYSTEM else: hac.units = METRIC_SYSTEM elif CONF_TEMPERATURE_UNIT in config: unit = config[CONF_TEMPERATURE_UNIT] if unit == TEMP_CELSIUS: hac.units = METRIC_SYSTEM else: hac.units = IMPERIAL_SYSTEM _LOGGER.warning( "Found deprecated temperature unit in core config, " "expected unit system. Replace '%s: %s' with " "'%s: %s'", CONF_TEMPERATURE_UNIT, unit, CONF_UNIT_SYSTEM, hac.units.name) # Shortcut if no auto-detection necessary if None not in (hac.latitude, hac.longitude, hac.units, hac.time_zone, hac.elevation): return discovered = [] # If we miss some of the needed values, auto detect them if None in (hac.latitude, hac.longitude, hac.units, hac.time_zone): info = loc_util.detect_location_info() if info is None: _LOGGER.error('Could not detect location information') return if hac.latitude is None and hac.longitude is None: hac.latitude, hac.longitude = (info.latitude, info.longitude) discovered.append(('latitude', hac.latitude)) discovered.append(('longitude', hac.longitude)) if hac.units is None: hac.units = METRIC_SYSTEM if info.use_metric else IMPERIAL_SYSTEM discovered.append((CONF_UNIT_SYSTEM, hac.units.name)) if hac.location_name is None: hac.location_name = info.city discovered.append(('name', info.city)) if hac.time_zone is None: set_time_zone(info.time_zone) discovered.append(('time_zone', info.time_zone)) if hac.elevation is None and hac.latitude is not None and \ hac.longitude is not None: elevation = loc_util.elevation(hac.latitude, hac.longitude) hac.elevation = elevation discovered.append(('elevation', elevation)) if discovered: _LOGGER.warning( 'Incomplete core config. Auto detected %s', ', '.join('{}: {}'.format(key, val) for key, val in discovered))
def process_ha_core_config(hass, config): """Process the [homeassistant] section from the config.""" # pylint: disable=too-many-branches config = CORE_CONFIG_SCHEMA(config) hac = hass.config def set_time_zone(time_zone_str): """Helper method to set time zone.""" if time_zone_str is None: return time_zone = date_util.get_time_zone(time_zone_str) if time_zone: hac.time_zone = time_zone date_util.set_default_time_zone(time_zone) else: _LOGGER.error('Received invalid time zone %s', time_zone_str) for key, attr in ((CONF_LATITUDE, 'latitude'), (CONF_LONGITUDE, 'longitude'), (CONF_NAME, 'location_name'), (CONF_ELEVATION, 'elevation')): if key in config: setattr(hac, attr, config[key]) if CONF_TIME_ZONE in config: set_time_zone(config.get(CONF_TIME_ZONE)) set_customize(config.get(CONF_CUSTOMIZE) or {}) if CONF_UNIT_SYSTEM in config: if config[CONF_UNIT_SYSTEM] == CONF_UNIT_SYSTEM_IMPERIAL: hac.units = IMPERIAL_SYSTEM else: hac.units = METRIC_SYSTEM elif CONF_TEMPERATURE_UNIT in config: unit = config[CONF_TEMPERATURE_UNIT] if unit == TEMP_CELSIUS: hac.units = METRIC_SYSTEM else: hac.units = IMPERIAL_SYSTEM _LOGGER.warning("Found deprecated temperature unit in core config, " "expected unit system. Replace '%s: %s' with " "'%s: %s'", CONF_TEMPERATURE_UNIT, unit, CONF_UNIT_SYSTEM, hac.units.name) # Shortcut if no auto-detection necessary if None not in (hac.latitude, hac.longitude, hac.units, hac.time_zone, hac.elevation): return discovered = [] # If we miss some of the needed values, auto detect them if None in (hac.latitude, hac.longitude, hac.units, hac.time_zone): info = loc_util.detect_location_info() if info is None: _LOGGER.error('Could not detect location information') return if hac.latitude is None and hac.longitude is None: hac.latitude, hac.longitude = (info.latitude, info.longitude) discovered.append(('latitude', hac.latitude)) discovered.append(('longitude', hac.longitude)) if hac.units is None: hac.units = METRIC_SYSTEM if info.use_metric else IMPERIAL_SYSTEM discovered.append((CONF_UNIT_SYSTEM, hac.units.name)) if hac.location_name is None: hac.location_name = info.city discovered.append(('name', info.city)) if hac.time_zone is None: set_time_zone(info.time_zone) discovered.append(('time_zone', info.time_zone)) if hac.elevation is None and hac.latitude is not None and \ hac.longitude is not None: elevation = loc_util.elevation(hac.latitude, hac.longitude) hac.elevation = elevation discovered.append(('elevation', elevation)) if discovered: _LOGGER.warning( 'Incomplete core config. Auto detected %s', ', '.join('{}: {}'.format(key, val) for key, val in discovered))
def process_ha_core_config(hass, config): """Process the [homeassistant] section from the config.""" # pylint: disable=too-many-branches config = CORE_CONFIG_SCHEMA(config) hac = hass.config def set_time_zone(time_zone_str): """Helper method to set time zone.""" if time_zone_str is None: return time_zone = date_util.get_time_zone(time_zone_str) if time_zone: hac.time_zone = time_zone date_util.set_default_time_zone(time_zone) else: _LOGGER.error('Received invalid time zone %s', time_zone_str) for key, attr in ((CONF_LATITUDE, 'latitude'), (CONF_LONGITUDE, 'longitude'), (CONF_NAME, 'location_name'), (CONF_ELEVATION, 'elevation')): if key in config: setattr(hac, attr, config[key]) if CONF_TIME_ZONE in config: set_time_zone(config.get(CONF_TIME_ZONE)) set_customize(config.get(CONF_CUSTOMIZE) or {}) if CONF_TEMPERATURE_UNIT in config: hac.temperature_unit = config[CONF_TEMPERATURE_UNIT] # Shortcut if no auto-detection necessary if None not in (hac.latitude, hac.longitude, hac.temperature_unit, hac.time_zone, hac.elevation): return discovered = [] # If we miss some of the needed values, auto detect them if None in (hac.latitude, hac.longitude, hac.temperature_unit, hac.time_zone): info = loc_util.detect_location_info() if info is None: _LOGGER.error('Could not detect location information') return if hac.latitude is None and hac.longitude is None: hac.latitude = info.latitude hac.longitude = info.longitude discovered.append(('latitude', hac.latitude)) discovered.append(('longitude', hac.longitude)) if hac.temperature_unit is None: if info.use_fahrenheit: hac.temperature_unit = TEMP_FAHRENHEIT discovered.append(('temperature_unit', 'F')) else: hac.temperature_unit = TEMP_CELSIUS discovered.append(('temperature_unit', 'C')) if hac.location_name is None: hac.location_name = info.city discovered.append(('name', info.city)) if hac.time_zone is None: set_time_zone(info.time_zone) discovered.append(('time_zone', info.time_zone)) if hac.elevation is None and hac.latitude is not None and \ hac.longitude is not None: elevation = loc_util.elevation(hac.latitude, hac.longitude) hac.elevation = elevation discovered.append(('elevation', elevation)) if discovered: _LOGGER.warning( 'Incomplete core config. Auto detected %s', ', '.join('{}: {}'.format(key, val) for key, val in discovered))