diff --git a/xtrn/wttr.in/wttr-lib.js b/xtrn/wttr.in/wttr-lib.js
index 0515c3ac552d5b9fbb6da1c5360ae4cb52e6dce6..c30a41518035e2a2b0251e4f36388eb79f5b0c4d 100644
--- a/xtrn/wttr.in/wttr-lib.js
+++ b/xtrn/wttr.in/wttr-lib.js
@@ -2,17 +2,35 @@ require('http.js', 'HTTPRequest');
 const locator = load({}, js.exec_dir + 'locator.js');
 const xterm = load({}, js.exec_dir + 'xterm-colors.js');
 
+function loadSettings() {
+	const settings = load({}, 'modopts.js', 'wttr.in') || {};
+	if (settings.base_url === undefined) {
+		settings.base_url = 'https://wttr.in/';
+	} else if (settings.base_url.search(/\/$/) < 0) {
+		settings.base_url += '/';
+	}
+	if (settings.units === undefined) settings.units = '';
+	if (settings.view === undefined) settings.view = 'AFn';
+	if (settings.cache_ttl === undefined) settings.cache_ttl = 3600;
+	if (settings.fallback_location === undefined) {
+		settings.fallback_location = '';
+	} else {
+		settings.fallback_location = settings.fallback_location.replace(/\s/g, '+');
+	}
+	return settings;
+}
+
 function uReplace(str) {
 	return str.replace(/\xE2\x9A\xA1/g, '\x01+\x01h\x01yZ \x01-'); // U+26A1 Lightning bolt
 }
 
-function getCacheName(qs, addr) {
-	const cfn = format('wttr.in_%s_%s.ans', qs, addr || '').replace(/[^0-9a-z\.]+/ig, '_');
+function getCacheName(url, addr) {
+	const cfn = format('wttr.in_%s%s.ans', url, addr || '').replace(/[^0-9a-z\.]+/ig, '_');
 	return system.temp_path + cfn;
 }
 
-function readCache(qs, addr, ttl) {
-	const cfn = getCacheName(qs, addr);
+function readCache(url, addr, ttl) {
+	const cfn = getCacheName(url, addr);
 	const f = new File(cfn);
 	if (!f.exists) return;
 	if (time() - file_date(cfn) > ttl) return;
@@ -22,30 +40,39 @@ function readCache(qs, addr, ttl) {
 	return cache;
 }
 
-function writeCache(qs, addr, ans) {
-	const cfn = getCacheName(qs, addr);
+function writeCache(url, addr, ans) {
+	const cfn = getCacheName(url, addr);
 	const f = new File(cfn);
 	if (!f.open('w')) return;
 	f.write(ans);
 	f.close();
 }
 
-function fetchWeather(qs, addr) {
+function fetchWeather(url, addr) {
 	const http = new HTTPRequest();
 	if (addr !== undefined) http.extra_headers = { 'X-Forwarded-For': addr };
-	const body = http.Get(qs);
+	const body = http.Get(url);
 	if (http.response_code !== 200) throw new Error('wttr.in response had status ' + http.response_code);
 	return body;
 }
 
-function getWeather(qs, ttl) {
-	const addr = locator.getAddress();
-	const cachedWeather = readCache(qs, addr, ttl);
+function getURL(settings, addr) {
+	var url = settings.base_url;
+	if (addr === undefined) url += settings.fallback_location;
+	url += '?' + settings.units + settings.view;
+	return url;
+}
+
+function getWeather() {
+	const settings = loadSettings();
+	const addr = locator.getAddress() || settings.fallback_ip;
+	const url = getURL(settings, addr);
+	const cachedWeather = readCache(url, addr, settings.cache_ttl);
 	if (cachedWeather !== undefined) return cachedWeather;
-	const weather = fetchWeather(qs, addr);
+	const weather = fetchWeather(url, addr);
 	const text = uReplace(weather);
 	const ansi = xterm.convertColors(text);
-	writeCache(qs, addr, ansi);
+	writeCache(url, addr, ansi);
 	return ansi;
 }