diff --git a/app/appointment.js b/app/appointment.js
index af91e67..f3f0767 100644
--- a/app/appointment.js
+++ b/app/appointment.js
@@ -1,14 +1,14 @@
import { inbox } from "file-transfer";
import { readFileSync } from "fs";
-import { dataFile, dataType } from "../common/constants";
+import { calendarFile, calendarType } from "../common/constants";
import { toEpochSec } from "../common/utils";
let data;
-let handleCalendarUpdatedCallback;
+let handleCallback;
export function initialize(callback) {
- handleCalendarUpdatedCallback = callback;
+ handleCallback = callback;
data = loadData();
inbox.addEventListener("newfile", fileHandler);
fileHandler();
@@ -43,14 +43,17 @@ function fileHandler() {
let fileName;
do {
fileName = inbox.nextFile();
- data = loadData();
- updatedData();
+ if (fileName === calendarFile) {
+ console.log('Load ' + fileName);
+ data = loadData();
+ updatedData();
+ }
} while (fileName);
}
function loadData() {
try {
- return readFileSync(`/private/data/${dataFile}`, dataType);
+ return readFileSync(`/private/data/${calendarFile}`, calendarType);
} catch (ex) {
console.error(`Appointment: loadData() failed. ${ex}`);
return;
@@ -66,7 +69,7 @@ function existsData() {
}
function updatedData() {
- if (typeof handleCalendarUpdatedCallback === "function" && existsData()) {
- handleCalendarUpdatedCallback();
+ if (typeof handleCallback === "function" && existsData()) {
+ handleCallback();
}
}
diff --git a/app/index.js b/app/index.js
index 27644cb..de6b5fa 100644
--- a/app/index.js
+++ b/app/index.js
@@ -4,8 +4,10 @@ import { battery } from "power";
import { display } from "display";
import { today } from 'user-activity';
import { me as device } from "device";
+import { units } from "user-settings";
import * as fs from "fs";
import * as appointment from "./appointment";
+import * as weather from "./weather";
import * as clock from "./clock";
import * as messaging from "messaging";
import { fromEpochSec, timeString } from "../common/utils";
@@ -19,10 +21,8 @@ const appointmentsLabel = document.getElementById("appointmentsLabel");
const batteryImage = document.getElementById("batteryImage");
const batteryLabel = document.getElementById("batteryLabel");
-const activityIcon = document.getElementById("activityIcon");
-const activityLabel = document.getElementById("activityLabel");
-
-//TODO: let activityIntervalID = 0;
+const infoIcon = document.getElementById("infoIcon");
+const infoLabel = document.getElementById("infoLabel");
const INVISIBLE = 0.0;
const VISIBLE = 0.8;
@@ -40,17 +40,22 @@ me.onunload = saveSettings;
// Load settings at startup
let settings = loadSettings();
-applySettings(settings.activity, settings.color);
+applySettings(settings.info, settings.color);
// Apply and store settings
-function applySettings(activity, color) {
- if (typeof activity !== 'undefined') {
- activityIcon.image = `${activity}.png`;
- settings.activity = activity;
+function applySettings(info, color) {
+ if (typeof info !== 'undefined') {
+ if (info === 'weather') {
+ renderWeather(weather.current());
+ }
+ else {
+ infoIcon.image = `${info}.png`;
+ settings.info = info;
+ }
}
if (typeof color !== 'undefined') {
hourLabel.style.fill = color;
- activityIcon.style.fill = color;
+ infoIcon.style.fill = color;
settings.color = color;
}
}
@@ -63,7 +68,7 @@ function loadSettings() {
catch (ex) {
// Default values
return {
- activity: "steps",
+ info: "steps",
color: "#2490DD"
};
}
@@ -76,11 +81,11 @@ function saveSettings() {
// Update settings
messaging.peerSocket.onmessage = (evt) => {
- if (evt.data.key === "activity") {
+ if (evt.data.key === "info") {
applySettings(evt.data.value, settings.color);
}
else if (evt.data.key === "color") {
- applySettings(settings.activity, evt.data.value);
+ applySettings(settings.info, evt.data.value);
}
renderAppointment();
}
@@ -103,6 +108,11 @@ appointment.initialize(() => {
renderAppointment();
});
+weather.initialize(data => {
+ // Update weather with new data
+ renderWeather(data);
+});
+
display.addEventListener("change", () => {
if (display.on) {
// Update appointment and battery on display on
@@ -110,15 +120,15 @@ display.addEventListener("change", () => {
renderBattery();
}
else {
- // Stop updating activity info
- hideActivity();
+ // Stop updating info
+ hideInfo();
}
});
// Hide event when touched
appointmentsLabel.addEventListener("mousedown", () => {
- showActivity();
- updateActivity();
+ showInfo();
+ updateInfo();
})
function renderAppointment() {
@@ -127,40 +137,48 @@ function renderAppointment() {
if (event) {
const date = fromEpochSec(event.startDate);
appointmentsLabel.text = timeString(date) + " " + event.title;
- hideActivity();
+ hideInfo();
}
else {
- showActivity();
- updateActivity();
+ showInfo();
+ updateInfo();
}
}
-function hideActivity() {
- activityIcon.style.opacity = INVISIBLE;
- activityLabel.style.opacity = INVISIBLE;
+function renderWeather(data) {
+ data = units.temperature === "F" ? toFahrenheit(data) : data;
+ infoLabel.text = `${data.temperature}\u00B0 ${data.unit}`;
+ infoIcon.image = `${data.icon}`;
+}
+
+function hideInfo() {
+ infoIcon.style.opacity = INVISIBLE;
+ infoLabel.style.opacity = INVISIBLE;
appointmentsLabel.style.opacity = VISIBLE;
- //TODO: clearInterval(activityIntervalID);
}
-function showActivity() {
- activityIcon.style.opacity = VISIBLE;
- activityLabel.style.opacity = VISIBLE;
+function showInfo() {
+ infoIcon.style.opacity = VISIBLE;
+ infoLabel.style.opacity = VISIBLE;
appointmentsLabel.style.opacity = INVISIBLE;
- //TODO: activityIntervalID = setInterval(updateActivity, 1500);
}
-function updateActivity() {
- if (settings.activity === 'distance') {
- activityLabel.text = today.adjusted.distance;
+function updateInfo() {
+ if (settings.info === 'distance') {
+ infoLabel.text = today.adjusted.distance;
+ }
+ else if (settings.info === 'floors') {
+ infoLabel.text = today.adjusted.elevationGain;
}
- else if (settings.activity === 'floors') {
- activityLabel.text = today.adjusted.elevationGain;
+ else if (settings.info === 'calories') {
+ infoLabel.text = today.adjusted.calories;
}
- else if (settings.activity === 'calories') {
- activityLabel.text = today.adjusted.calories;
+ else if (settings.info === 'weather') {
+ // TODO weather
+ console.log('updateInfo -> weather not implemented yet');
}
else {
- activityLabel.text = today.adjusted.steps;
+ infoLabel.text = today.adjusted.steps;
}
}
diff --git a/app/weather.js b/app/weather.js
new file mode 100644
index 0000000..e7352d4
--- /dev/null
+++ b/app/weather.js
@@ -0,0 +1,54 @@
+import { inbox } from "file-transfer";
+import { readFileSync } from "fs";
+
+import { weatherFile, weatherType } from "../common/constants";
+
+let data;
+let handleCallback;
+
+export function current() {
+ return data;
+}
+
+export function initialize(callback) {
+ handleCallback = callback;
+ data = loadData();
+ inbox.addEventListener("newfile", fileHandler);
+ fileHandler();
+ updatedData();
+}
+
+function fileHandler() {
+ let fileName;
+ do {
+ fileName = inbox.nextFile();
+ if (fileName === weatherFile) {
+ console.log('Load ' + fileName);
+ data = loadData();
+ updatedData();
+ }
+ } while (fileName);
+}
+
+function loadData() {
+ try {
+ return readFileSync(`/private/data/${weatherFile}`, weatherType);
+ } catch (ex) {
+ console.error(`loadData() failed. ${ex}`);
+ return;
+ }
+}
+
+function existsData() {
+ if (data === undefined) {
+ console.warn("No data found.");
+ return false;
+ }
+ return true;
+}
+
+function updatedData() {
+ if (typeof handleCallback === "function" && existsData()) {
+ handleCallback(data);
+ }
+}
diff --git a/common/constants.js b/common/constants.js
index bef9528..9d07bb3 100644
--- a/common/constants.js
+++ b/common/constants.js
@@ -1,5 +1,7 @@
-export const dataType = "cbor";
-export const dataFile = "appointments.cbor";
+export const calendarType = "cbor";
+export const calendarFile = "appointments.cbor";
export const settingsType = "cbor";
export const settingsFile = "settings.cbor";
+export const weatherType = "cbor";
+export const weatherFile = "weather.cbor";
export const millisecondsPerMinute = 1000 * 60;
diff --git a/common/utils.js b/common/utils.js
index a6bd3cb..a9dc262 100644
--- a/common/utils.js
+++ b/common/utils.js
@@ -9,6 +9,14 @@ export function zeroPad(i) {
return i;
}
+// Convert celcius to fahrenheit
+export function toFahrenheit(data) {
+ if (data.unit.toLowerCase() === "celsius") {
+ data.temperature = Math.round((data.temperature * 1.8) + 32.0);
+ data.unit = "Fahrenheit";
+ }
+ return data;
+}
// Return day as a string
export function dayString(day) {
if (day == 1) {
@@ -20,18 +28,6 @@ export function dayString(day) {
else if (day == 3) {
return "3rd"
}
- if (day == 21) {
- return "21st"
- }
- else if (day == 22) {
- return "22nd"
- }
- else if (day == 23) {
- return "23rd"
- }
- if (day == 31) {
- return "31st"
- }
return day.toString() + "th";
}
diff --git a/companion/index.js b/companion/index.js
index 3167783..4fc0814 100644
--- a/companion/index.js
+++ b/companion/index.js
@@ -3,16 +3,18 @@ import * as cbor from "cbor";
import { me as companion } from "companion";
import { outbox } from "file-transfer";
-import { toEpochSec } from "../common/utils";
-import { dataFile, millisecondsPerMinute } from "../common/constants";
+import { toEpochSec, findWeatherConditionIcon } from "../common/utils";
+import { calendarFile, weatherFile, millisecondsPerMinute } from "../common/constants";
import { settingsStorage } from "settings";
import * as messaging from "messaging";
+import { weather, WeatherCondition } from "weather";
+
// Update user settings
settingsStorage.onchange = function(evt) {
if (messaging.peerSocket.readyState === messaging.peerSocket.OPEN) {
- if (evt.key === "activity") {
+ if (evt.key === "info") {
let data = JSON.parse(evt.newValue);
messaging.peerSocket.send({
key: evt.key,
@@ -28,10 +30,39 @@ settingsStorage.onchange = function(evt) {
}
}
+// Set update interval and callback
companion.wakeInterval = 15 * millisecondsPerMinute;
-companion.addEventListener("wakeinterval", refreshEvents);
+companion.addEventListener("wakeinterval", refreshData);
+
+function refreshData() {
+ refreshEvents();
+ refreshWeather();
+}
-refreshEvents();
+refreshData();
+
+// Refresh weather data
+function refreshWeather() {
+ weather
+ .getWeatherData()
+ .then((data) => {
+ if (data.locations.length > 0) {
+ sendWeatherFile({
+ temperature: Math.floor(data.locations[0].currentWeather.temperature),
+ condition: data.locations[0].currentWeather.weatherCondition,
+ icon: findWeatherConditionIcon(data.locations[0].currentWeather.weatherCondition),
+ location: data.locations[0].name,
+ unit: data.temperatureUnit
+ });
+ }
+ else {
+ console.warn("No data for this location.")
+ }
+ })
+ .catch((ex) => {
+ console.error(ex);
+ });
+}
// Refresh calendar data
function refreshEvents() {
@@ -63,7 +94,7 @@ function refreshEvents() {
});
});
if (dataEvents && dataEvents.length > 0) {
- sendData(dataEvents);
+ sendCalendarFile(dataEvents);
}
})
.catch(error => {
@@ -74,8 +105,73 @@ function refreshEvents() {
}
// Send data
-function sendData(data) {
- outbox.enqueue(dataFile, cbor.encode(data)).catch(error => {
+function sendCalendarFile(data) {
+ outbox.enqueue(calendarFile, cbor.encode(data)).catch(error => {
console.warn(`Failed to enqueue data. Error: ${error}`);
});
}
+
+// Send data
+function sendWeatherFile(data) {
+ outbox.enqueue(weatherFile, cbor.encode(data)).catch(error => {
+ console.warn(`Failed to enqueue data. Error: ${error}`);
+ });
+}
+
+// Find the icon for a weather conditionCode
+function findWeatherConditionIcon(condition) {
+ switch (condition) {
+ case WeatherCondition.ClearNight:
+ case WeatherCondition.MostlyClearNight:
+ return 'weather-night.png';
+ case WeatherCondition.Cloudy:
+ return 'weather-cloudy.png';
+ case WeatherCondition.Cold:
+ return 'weather-snowflake-alert.png';
+ case WeatherCondition.Flurries:
+ return '';
+ case WeatherCondition.Fog:
+ return 'weather-fog.png';
+ case WeatherCondition.FreezingRain:
+ return 'weather-snowy-rainy.png';
+ case WeatherCondition.HazyMoonlight:
+ case WeatherCondition.HazySunshineDay:
+ return 'weather-hazy.png';
+ case WeatherCondition.Hot:
+ return 'weather-sunny-alert.png';
+ case WeatherCondition.Ice:
+ return 'weather-snowflake.png';
+ case WeatherCondition.IntermittentCloudsDay:
+ case WeatherCondition.MostlyCloudyDay:
+ return 'weather-partly-cloudy.png';
+ case WeatherCondition.IntermittentCloudsNight:
+ case WeatherCondition.MostlyCloudyNight:
+ return 'weather-night-partly-cloudy.png';
+ case WeatherCondition.MostlyCloudyWithFlurriesDay:
+ case WeatherCondition.MostlyCloudyWithFlurriesNight:
+ case WeatherCondition.MostlyCloudyWithShowersDay:
+ case WeatherCondition.MostlyCloudyWithShowersNight:
+ case WeatherCondition.MostlyCloudyWithSnowDay:
+ case WeatherCondition.MostlyCloudyWithSnowNight:
+ case WeatherCondition.MostlyCloudyWithThunderstormsDay:
+ case WeatherCondition.MostlyCloudyWithThunderstormsNight:
+ case WeatherCondition.MostlySunnyDay:
+ case WeatherCondition.Overcast:
+ case WeatherCondition.PartlyCloudyNight:
+ case WeatherCondition.PartlyCloudyWithShowersNight:
+ case WeatherCondition.PartlyCloudyWithThunderstormsNight:
+ case WeatherCondition.PartlySunnyDay:
+ case WeatherCondition.PartlySunnyWithFlurriesDay:
+ case WeatherCondition.PartlySunnyWithShowersDay:
+ case WeatherCondition.PartlySunnyWithThunderstormsDay:
+ case WeatherCondition.Rain:
+ case WeatherCondition.RainAndSnow:
+ case WeatherCondition.Showers:
+ case WeatherCondition.Sleet:
+ case WeatherCondition.Snow:
+ case WeatherCondition.SunnyDay:
+ case WeatherCondition.Thunderstorms:
+ case WeatherCondition.Windy:
+ return '';
+ }
+}
diff --git a/package.sdk4.json b/package.sdk4.json
index 900f7ff..2f3e9a9 100644
--- a/package.sdk4.json
+++ b/package.sdk4.json
@@ -22,7 +22,8 @@
"requestedPermissions": [
"access_calendar",
"run_background",
- "access_activity"
+ "access_activity",
+ "access_location"
],
"buildTargets": [
"higgs",
diff --git a/package.sdk5.json b/package.sdk5.json
index bff0e8b..db75052 100644
--- a/package.sdk5.json
+++ b/package.sdk5.json
@@ -22,7 +22,8 @@
"requestedPermissions": [
"access_calendar",
"run_background",
- "access_activity"
+ "access_activity",
+ "access_location"
],
"buildTargets": [
"atlas",
diff --git a/resources/index.gui b/resources/index.gui
index 0ebc4ae..bb5705a 100644
--- a/resources/index.gui
+++ b/resources/index.gui
@@ -5,6 +5,6 @@
-
-
+
+
\ No newline at end of file
diff --git a/resources/index.view b/resources/index.view
index d8c16d5..23abf1c 100644
--- a/resources/index.view
+++ b/resources/index.view
@@ -5,6 +5,6 @@
-
-
+
+
\ No newline at end of file
diff --git a/resources/weather-cloudy.png b/resources/weather-cloudy.png
index fc4d981..030c6fb 100644
--- a/resources/weather-cloudy.png
+++ b/resources/weather-cloudy.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:e81865ab3ea825cd79296a4263b8a92264206a0fcd26843f01a31dfbc5d23bd1
-size 508
+oid sha256:3c9e2755c876e3e96d73a776a4fa70c20ea986974785f105431b85d36055bd55
+size 504
diff --git a/resources/weather-fog.png b/resources/weather-fog.png
index d69d162..5ad1ab5 100644
--- a/resources/weather-fog.png
+++ b/resources/weather-fog.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:fdc224965ed93ba06ba9b186174d37c9119fce294a962e8c1cf2898b6334d1c2
-size 507
+oid sha256:538c9171aa0805d09564df41287a7121467702997811893c3cda880c49e3bf07
+size 503
diff --git a/resources/weather-hail.png b/resources/weather-hail.png
index f07ade0..a20ff2e 100644
--- a/resources/weather-hail.png
+++ b/resources/weather-hail.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:1d265831bdd9ec7765d38d8bc5414b238370113631d9ae3203b66444bfc5e70b
-size 573
+oid sha256:aa7035635fb26ba461ea3027afff8d16b058761b75d48d570953a192c5edb37e
+size 579
diff --git a/resources/weather-hazy.png b/resources/weather-hazy.png
index 8c81b0c..6bed5bc 100644
--- a/resources/weather-hazy.png
+++ b/resources/weather-hazy.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:0684656a337e38287a6de7e217e69dc6c337be89b36f86f6ae2fc6c9feaa8ef6
-size 524
+oid sha256:eeedf1728298de82d9cc313c0178df13dc941b60590f86c10b0e577781b9d498
+size 541
diff --git a/resources/weather-lightning-rainy.png b/resources/weather-lightning-rainy.png
index 1cedb38..9f517d0 100644
--- a/resources/weather-lightning-rainy.png
+++ b/resources/weather-lightning-rainy.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:92329333a35756196b9e49bdac78f6f511a47858cb5a4eab3c51028e79f0d9c8
-size 637
+oid sha256:d414cb2dbdcb305c566dc1cd2aa7ad685953d3079b541823ff4f194b9a5c2ed4
+size 646
diff --git a/resources/weather-lightning.png b/resources/weather-lightning.png
index d276d12..e7cbf18 100644
--- a/resources/weather-lightning.png
+++ b/resources/weather-lightning.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:c15f672af55c9f63f0df1b8390105eeb2cdc6cec0a11269c1749a372cb488c7f
-size 601
+oid sha256:ed8b1cef1b3ce3ce7152cb607e907547669a1de4ab070dbc9f95991d4ba814b4
+size 603
diff --git a/resources/weather-night-partly-cloudy.png b/resources/weather-night-partly-cloudy.png
index 6db275a..a2b7bfb 100644
--- a/resources/weather-night-partly-cloudy.png
+++ b/resources/weather-night-partly-cloudy.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:da2d0c45d3eb3ccc328ba17acf8f557b7f9402ad601f7402db2f0fd52168ac7d
-size 623
+oid sha256:e8749b0f865d6f83a22154c549948450a822b69fe444995e0c443c8bc9a6d106
+size 626
diff --git a/resources/weather-night.png b/resources/weather-night.png
index 01b5633..72ee7b9 100644
--- a/resources/weather-night.png
+++ b/resources/weather-night.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:7764ac9882520b8b9c84daf85d60d4ba17ff8045de1917d6fb9d29c6bcfca741
-size 697
+oid sha256:9929c78e152e34dce36a888ab6681a70d2a1f1985b2a7d969604ff931d31b68e
+size 720
diff --git a/resources/weather-partly-cloudy.png b/resources/weather-partly-cloudy.png
index 30b984a..3883d65 100644
--- a/resources/weather-partly-cloudy.png
+++ b/resources/weather-partly-cloudy.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:883d3757ea183e37ed651ac82bfd8b57cef447ac0bb21dfd6af91d36e165dd79
-size 657
+oid sha256:772ff2cd6ad69b284bb60653ef777184ea91cfc855306b62bb48598ff931a1c7
+size 661
diff --git a/resources/weather-partly-lightning.png b/resources/weather-partly-lightning.png
index c4cd0ea..fccc914 100644
--- a/resources/weather-partly-lightning.png
+++ b/resources/weather-partly-lightning.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:0335d4eeded612715c80e2077500408c0e85f9d5781e6ad01299350e9a31e4e2
-size 723
+oid sha256:cae95d4ae9f81686a49c4b058658bb1aab662fba6f553d85d4e81546b8d50b6c
+size 730
diff --git a/resources/weather-partly-rainy.png b/resources/weather-partly-rainy.png
index bc365ca..7d98664 100644
--- a/resources/weather-partly-rainy.png
+++ b/resources/weather-partly-rainy.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:d4fcfbeb8566bbe6636b01d75b32045d7b786fb771139130cfa98c8ef823c999
-size 715
+oid sha256:47cfbae4fb52fe71f32151ceff779a324509fcb31023319830897e89ef4f46f3
+size 716
diff --git a/resources/weather-partly-snowy-rainy.png b/resources/weather-partly-snowy-rainy.png
index 7923dfa..d9af03a 100644
--- a/resources/weather-partly-snowy-rainy.png
+++ b/resources/weather-partly-snowy-rainy.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:c499f838a4566a007ed9eafb99f78707036da7791caa8353705c0c4ec91ee147
-size 766
+oid sha256:dfdff5314e5f83572a5b09cd0accc5dbacc7aee980802d58165b576909a3ca44
+size 771
diff --git a/resources/weather-partly-snowy.png b/resources/weather-partly-snowy.png
index 890a6b9..14ef6a6 100644
--- a/resources/weather-partly-snowy.png
+++ b/resources/weather-partly-snowy.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:21fdc62165d99a127248a70bea26c4d916a609b76409f472f45f375f678d419c
-size 745
+oid sha256:31f56858abd3cb3ee86d8d12637dc9df46ecf7f4a0bc20b01edea9ccbe903166
+size 765
diff --git a/resources/weather-pouring.png b/resources/weather-pouring.png
new file mode 100644
index 0000000..d4f00c6
--- /dev/null
+++ b/resources/weather-pouring.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8751c8750cca8c97ca5d8457e19713edbac99940024b3eb1adf4e991048fb4b5
+size 652
diff --git a/resources/weather-rainy.png b/resources/weather-rainy.png
index c31083f..41ff49a 100644
--- a/resources/weather-rainy.png
+++ b/resources/weather-rainy.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:e65b71f8f2cd5fbea323630fc9f2e204b5b0d84c159b80433f993af4ed902d58
-size 651
+oid sha256:c1e3dff0af43c0d742c50ab472fc172db5b05ea68f68772b9e3a08d0baef8063
+size 645
diff --git a/resources/weather-snowflake-alert.png b/resources/weather-snowflake-alert.png
new file mode 100644
index 0000000..de81889
--- /dev/null
+++ b/resources/weather-snowflake-alert.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9fd12ec5a72a95791901895678f21adb1c9cc1c411f992b2096e565c0b47b009
+size 594
diff --git a/resources/weather-snowflake.png b/resources/weather-snowflake.png
new file mode 100644
index 0000000..71a2764
--- /dev/null
+++ b/resources/weather-snowflake.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b9075ed797974ef9eaea66bb1b4be63f3a56a015240b977e39a9e37a9a0864fc
+size 654
diff --git a/resources/weather-snowy-heavy.png b/resources/weather-snowy-heavy.png
new file mode 100644
index 0000000..64e58ee
--- /dev/null
+++ b/resources/weather-snowy-heavy.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5a6d2c0fa95bf0c9d13be9abaf8974d73ea97e33d907680f3b0b5fcf8c7f33cc
+size 692
diff --git a/resources/weather-snowy-rainy.png b/resources/weather-snowy-rainy.png
index e0b666f..fb990c5 100644
--- a/resources/weather-snowy-rainy.png
+++ b/resources/weather-snowy-rainy.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:5acf3a4f4458950e0b7884b157a38557320ab5d8347eb5c2819e35ccb9022360
-size 662
+oid sha256:3cfe0a1fee1cc679fde94ab1c71c8493960699d7c22d15591c5bcda8e114429b
+size 672
diff --git a/resources/weather-snowy.png b/resources/weather-snowy.png
index 682323d..35db0f0 100644
--- a/resources/weather-snowy.png
+++ b/resources/weather-snowy.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:c4882e792773f64941b4ffbbbcd99c56c78a47049c1e09a99d6924f4a4c0b518
-size 623
+oid sha256:e174f4d25d3bd8ea21be95ccb352357fda735e5795880a688104ce59e6b1f6bf
+size 637
diff --git a/resources/weather-storm.png b/resources/weather-storm.png
index f42c880..557af03 100644
--- a/resources/weather-storm.png
+++ b/resources/weather-storm.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:5ebe0c7a148122b4f50d5900a3d8ed2aa6d51e726d5cdc1abfb4e72690675d56
-size 406
+oid sha256:1738dce3f836cf8d4eafe5a7bf315f76b97a64c380894cdd2ca97fba3bebb715
+size 421
diff --git a/resources/weather-sunny-alert.png b/resources/weather-sunny-alert.png
new file mode 100644
index 0000000..21a9dae
--- /dev/null
+++ b/resources/weather-sunny-alert.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2b468d08d3a3aab87a45c9191ce394657c9605e240c076ad2b75676992880db4
+size 608
diff --git a/resources/weather-sunny.png b/resources/weather-sunny.png
index d680eec..f1556f5 100644
--- a/resources/weather-sunny.png
+++ b/resources/weather-sunny.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:bc3c5b340b593ba37323d65ae11265fe5cdb5251efe2c26f4e95d1523229290b
-size 632
+oid sha256:376ad1b8859496bd9eb76bec041584f26cb0999d0ae0e0f1a2f45f55ee30eb71
+size 656
diff --git a/resources/weather-windy.png b/resources/weather-windy.png
index 35fab4a..324351a 100644
--- a/resources/weather-windy.png
+++ b/resources/weather-windy.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:252682e6e9a345106d6b5a68ffd5d3ad152a8e0fc3ba37cd1aadc384a9e9d0cf
-size 464
+oid sha256:a050ebf4ea18ed05c44eaede683791d5bfd9d53267d0ab70c10e4d71e0807342
+size 530
diff --git a/settings/i18n/de-DE.po b/settings/i18n/de-DE.po
index 957f850..a337467 100644
--- a/settings/i18n/de-DE.po
+++ b/settings/i18n/de-DE.po
@@ -13,3 +13,6 @@ msgstr "Distanz"
msgid "floors"
msgstr "Etagen"
+
+msgid "weather"
+msgstr "Wetter"
diff --git a/settings/i18n/en-US.po b/settings/i18n/en-US.po
index 2e0e706..ad7a143 100644
--- a/settings/i18n/en-US.po
+++ b/settings/i18n/en-US.po
@@ -13,3 +13,6 @@ msgstr "Distance"
msgid "floors"
msgstr "Floors"
+
+msgid "weather"
+msgstr "Weather"
diff --git a/settings/i18n/ru-RU.po b/settings/i18n/ru-RU.po
index 5dbc05d..3ad5ebd 100644
--- a/settings/i18n/ru-RU.po
+++ b/settings/i18n/ru-RU.po
@@ -13,3 +13,6 @@ msgstr "Расстояние"
msgid "floors"
msgstr "Полы"
+
+msgid "weather"
+msgstr "Погода"
diff --git a/settings/index.jsx b/settings/index.jsx
index 691e4f5..d806895 100644
--- a/settings/index.jsx
+++ b/settings/index.jsx
@@ -2,22 +2,18 @@
import { gettext } from "i18n";
function settingsFunc(props) {
- let title = gettext("title");
- let steps = gettext("steps");
- let dist = gettext("dist");
- let floors = gettext("floors");
- let cal = gettext("cal");
return (