Weather: Unify formatting and more modern style of javascript

master^2
Rengyr 2025-05-17 18:29:26 +02:00
parent bc375c512b
commit dcec8ead09
No known key found for this signature in database
5 changed files with 124 additions and 126 deletions

View File

@ -79,7 +79,7 @@ var layout = new Layout({type:"v", bgCol: g.theme.bg, c: [
]}, {lazy: true}); ]}, {lazy: true});
function formatDuration(millis) { function formatDuration(millis) {
let pluralize = (n, w) => n + " " + w + (n == 1 ? "" : "s"); let pluralize = (n, w) => `${n} ${w}${n === 1 ? "" : "s"}`;
if (millis < 60000) return /*LANG*/"< 1 minute"; if (millis < 60000) return /*LANG*/"< 1 minute";
if (millis < 3600000) return pluralize(Math.floor(millis/60000), /*LANG*/"minute"); if (millis < 3600000) return pluralize(Math.floor(millis/60000), /*LANG*/"minute");
if (millis < 86400000) return pluralize(Math.floor(millis/3600000), /*LANG*/"hour"); if (millis < 86400000) return pluralize(Math.floor(millis/3600000), /*LANG*/"hour");
@ -99,10 +99,10 @@ function draw() {
layout.feelslike.label = feelsLikeTemp[1]+feelsLikeTemp[2]; layout.feelslike.label = feelsLikeTemp[1]+feelsLikeTemp[2];
} }
layout.hum.label = current.hum+"%"; layout.hum.label = `${current.hum}%`;
const wind = locale.speed(current.wind).match(/^(\D*\d*)(.*)$/); const wind = locale.speed(current.wind).match(/^(\D*\d*)(.*)$/);
layout.wind.label = wind[1]; layout.wind.label = wind[1];
layout.windUnit.label = wind[2] + " " + (current.wrose||'').toUpperCase(); layout.windUnit.label = `${wind[2]} ${(current.wrose||'').toUpperCase()}`;
layout.cond.label = current.txt.charAt(0).toUpperCase()+(current.txt||'').slice(1); layout.cond.label = current.txt.charAt(0).toUpperCase()+(current.txt||'').slice(1);
layout.loc.label = current.loc; layout.loc.label = current.loc;
layout.updateTime.label = `${formatDuration(Date.now() - current.time)} ago`; // How to autotranslate this and similar? layout.updateTime.label = `${formatDuration(Date.now() - current.time)} ago`; // How to autotranslate this and similar?

View File

@ -1,5 +1,4 @@
(() => {
(function() {
var weather; var weather;
var weatherLib = require("weather"); var weatherLib = require("weather");
@ -8,9 +7,9 @@
if(weather){ if(weather){
weather.temp = require("locale").temp(weather.temp-273.15); weather.temp = require("locale").temp(weather.temp-273.15);
weather.feels = require("locale").temp(weather.feels-273.15); weather.feels = require("locale").temp(weather.feels-273.15);
weather.hum = weather.hum + "%"; weather.hum = `${weather.hum}%`;
weather.wind = require("locale").speed(weather.wind).match(/^(\D*\d*)(.*)$/); weather.wind = require("locale").speed(weather.wind).match(/^(\D*\d*)(.*)$/);
weather.wind = Math.round(weather.wind[1]) + "kph"; weather.wind = `${Math.round(weather.wind[1])}kph`;
} else { } else {
weather = { weather = {
temp: "?", temp: "?",

View File

@ -1,4 +1,4 @@
const storage = require('Storage'); const storage = require("Storage");
const B2 = process.env.HWVERSION === 2; const B2 = process.env.HWVERSION === 2;
let expiryTimeout; let expiryTimeout;
@ -15,7 +15,7 @@ function scheduleExpiry(json) {
} }
function update(weatherEvent) { function update(weatherEvent) {
let json = storage.readJSON('weather.json')||{}; let json = storage.readJSON("weather.json") || {};
if (weatherEvent) { if (weatherEvent) {
let weather = weatherEvent.clone(); let weather = weatherEvent.clone();
@ -27,17 +27,15 @@ function update(weatherEvent) {
while (deg < 0 || deg > 360) { while (deg < 0 || deg > 360) {
deg = (deg + 360) % 360; deg = (deg + 360) % 360;
} }
weather.wrose = ['n','ne','e','se','s','sw','w','nw','n'][Math.floor((deg+22.5)/45)]; weather.wrose = ["n", "ne", "e", "se", "s", "sw", "w", "nw", "n"][Math.floor((deg + 22.5) / 45)];
} }
json.weather = weather; json.weather = weather;
} } else {
else {
delete json.weather; delete json.weather;
} }
storage.write("weather.json", json);
storage.write('weather.json', json);
scheduleExpiry(json); scheduleExpiry(json);
exports.emit("update", json.weather); exports.emit("update", json.weather);
} }
@ -48,68 +46,68 @@ global.GB = (event) => {
if (_GB) setTimeout(_GB, 0, event); if (_GB) setTimeout(_GB, 0, event);
}; };
exports.get = function() { exports.get = () => {
return (storage.readJSON('weather.json')||{}).weather; return (storage.readJSON("weather.json") || {}).weather;
} };
scheduleExpiry(storage.readJSON('weather.json')||{}); scheduleExpiry(storage.readJSON("weather.json") || {});
function getPalette(monochrome, ovr) { function getPalette(monochrome, ovr) {
var palette; var palette;
if (monochrome) { if (monochrome) {
palette = { palette = {
sun: '#FFF', sun: "#FFF",
cloud: '#FFF', cloud: "#FFF",
bgCloud: '#FFF', bgCloud: "#FFF",
rain: '#FFF', rain: "#FFF",
lightning: '#FFF', lightning: "#FFF",
snow: '#FFF', snow: "#FFF",
mist: '#FFF', mist: "#FFF",
background: '#000' background: "#000",
}; };
} else { } else {
if (B2) { if (B2) {
if (ovr.theme.dark) { if (ovr.theme.dark) {
palette = { palette = {
sun: '#FF0', sun: "#FF0",
cloud: '#FFF', cloud: "#FFF",
bgCloud: '#777', // dithers on B2, but that's ok bgCloud: "#777", // dithers on B2, but that's ok
rain: '#0FF', rain: "#0FF",
lightning: '#FF0', lightning: "#FF0",
snow: '#FFF', snow: "#FFF",
mist: '#FFF' mist: "#FFF",
}; };
} else { } else {
palette = { palette = {
sun: '#FF0', sun: "#FF0",
cloud: '#777', // dithers on B2, but that's ok cloud: "#777", // dithers on B2, but that's ok
bgCloud: '#000', bgCloud: "#000",
rain: '#00F', rain: "#00F",
lightning: '#FF0', lightning: "#FF0",
snow: '#0FF', snow: "#0FF",
mist: '#0FF' mist: "#0FF",
}; };
} }
} else { } else {
if (ovr.theme.dark) { if (ovr.theme.dark) {
palette = { palette = {
sun: '#FE0', sun: "#FE0",
cloud: '#BBB', cloud: "#BBB",
bgCloud: '#777', bgCloud: "#777",
rain: '#0CF', rain: "#0CF",
lightning: '#FE0', lightning: "#FE0",
snow: '#FFF', snow: "#FFF",
mist: '#FFF' mist: "#FFF",
}; };
} else { } else {
palette = { palette = {
sun: '#FC0', sun: "#FC0",
cloud: '#000', cloud: "#000",
bgCloud: '#777', bgCloud: "#777",
rain: '#07F', rain: "#07F",
lightning: '#FC0', lightning: "#FC0",
snow: '#CCC', snow: "#CCC",
mist: '#CCC' mist: "#CCC",
}; };
} }
} }
@ -117,10 +115,10 @@ function getPalette(monochrome, ovr) {
return palette; return palette;
} }
exports.getColor = function(code) { exports.getColor = (code) => {
const codeGroup = Math.round(code / 100); const codeGroup = Math.round(code / 100);
const palette = getPalette(0, g); const palette = getPalette(0, g);
const cloud = g.blendColor(palette.cloud, palette.bgCloud, .5); //theme independent const cloud = g.blendColor(palette.cloud, palette.bgCloud, 0.5); //theme independent
switch (codeGroup) { switch (codeGroup) {
case 2: return g.blendColor(cloud, palette.lightning, .5); case 2: return g.blendColor(cloud, palette.lightning, .5);
case 3: return palette.rain; case 3: return palette.rain;
@ -144,7 +142,7 @@ exports.getColor = function(code) {
} }
default: return cloud; default: return cloud;
} }
} };
/** /**
* *
@ -158,7 +156,7 @@ exports.getColor = function(code) {
* @param ovr Graphics instance (or undefined for g) * @param ovr Graphics instance (or undefined for g)
* @param monochrome If true, produce a monochromatic icon * @param monochrome If true, produce a monochromatic icon
*/ */
exports.drawIcon = function(cond, x, y, r, ovr, monochrome) { exports.drawIcon = (cond, x, y, r, ovr, monochrome) => {
var palette; var palette;
if (!ovr) ovr = g; if (!ovr) ovr = g;
@ -336,7 +334,8 @@ exports.drawIcon = function(cond, x, y, r, ovr, monochrome) {
if (txt.includes("few clouds")) return drawFewClouds; if (txt.includes("few clouds")) return drawFewClouds;
if (txt.includes("scattered clouds")) return drawCloud; if (txt.includes("scattered clouds")) return drawCloud;
if (txt.includes("clouds")) return drawBrokenClouds; if (txt.includes("clouds")) return drawBrokenClouds;
if (txt.includes("mist") || if (
txt.includes("mist") ||
txt.includes("smoke") || txt.includes("smoke") ||
txt.includes("haze") || txt.includes("haze") ||
txt.includes("sand") || txt.includes("sand") ||
@ -344,14 +343,15 @@ exports.drawIcon = function(cond, x, y, r, ovr, monochrome) {
txt.includes("fog") || txt.includes("fog") ||
txt.includes("ash") || txt.includes("ash") ||
txt.includes("squalls") || txt.includes("squalls") ||
txt.includes("tornado")) { txt.includes("tornado")
) {
return drawMist; return drawMist;
} }
return drawUnknown; return drawUnknown;
} }
/* /*
* Choose weather icon to display based on weather conditition code * Choose weather icon to display based on weather condition code
* https://openweathermap.org/weather-conditions#Weather-Condition-Codes-2 * https://openweathermap.org/weather-conditions#Weather-Condition-Codes-2
*/ */
function chooseIconByCode(code) { function chooseIconByCode(code) {
@ -382,16 +382,15 @@ exports.drawIcon = function(cond, x, y, r, ovr, monochrome) {
} }
function chooseIcon(cond) { function chooseIcon(cond) {
if (typeof (cond)==="object") { if (typeof cond === "object") {
if ("code" in cond) return chooseIconByCode(cond.code); if ("code" in cond) return chooseIconByCode(cond.code);
if ("txt" in cond) return chooseIconByTxt(cond.txt); if ("txt" in cond) return chooseIconByTxt(cond.txt);
} else if (typeof (cond)==="number") { } else if (typeof cond === "number") {
return chooseIconByCode(cond.code); return chooseIconByCode(cond.code);
} else if (typeof (cond)==="string") { } else if (typeof cond === "string") {
return chooseIconByTxt(cond.txt); return chooseIconByTxt(cond.txt);
} }
return drawUnknown; return drawUnknown;
} }
chooseIcon(cond)(x, y, r); chooseIcon(cond)(x, y, r);
}; };

View File

@ -1,31 +1,31 @@
(function(back) { (back) => {
const storage = require('Storage'); const storage = require("Storage");
let settings = storage.readJSON('weather.json', 1) || {}; let settings = storage.readJSON("weather.json", 1) || {};
function save(key, value) { function save(key, value) {
settings[key] = value; settings[key] = value;
storage.write('weather.json', settings); storage.write("weather.json", settings);
} }
E.showMenu({ E.showMenu({
'': { 'title': 'Weather' }, "": { "title": "Weather" },
'Expiry': { "Expiry": {
value: "expiry" in settings ? settings["expiry"] : 2*3600000, value: "expiry" in settings ? settings.expiry : 2 * 3600000,
min: 0, min: 0,
max: 24 * 3600000, max: 24 * 3600000,
step: 15 * 60000, step: 15 * 60000,
format: x => { format: (x) => {
if (x == 0) return "none"; if (x === 0) return "none";
if (x < 3600000) return Math.floor(x/60000) + "m"; if (x < 3600000) return `${Math.floor(x / 60000)}m`;
if (x < 86400000) return Math.floor(x/36000)/100 + "h"; if (x < 86400000) return `${Math.floor(x / 36000) / 100}h`;
}, },
onchange: x => save('expiry', x), onchange: (x) => save("expiry", x),
}, },
'Hide Widget': { "Hide Widget": {
value: "hide" in settings ? settings.hide : false, value: "hide" in settings ? settings.hide : false,
onchange: () => { onchange: () => {
settings.hide = !settings.hide settings.hide = !settings.hide;
save('hide', settings.hide); save("hide", settings.hide);
}, },
}, },
'< Back': back, "< Back": back,
}); });
}) };

View File

@ -1,53 +1,53 @@
(() => { (() => {
const weather = require('weather'); const weather = require("weather");
var dirty = false; var dirty = false;
let settings; let settings;
function loadSettings() { function loadSettings() {
settings = require('Storage').readJSON('weather.json', 1) || {}; settings = require("Storage").readJSON("weather.json", 1) || {};
} }
function setting(key) { function setting(key) {
if (!settings) { loadSettings(); } if (!settings) { loadSettings(); }
const DEFAULTS = { const DEFAULTS = {
'expiry': 2*3600000, "expiry": 2*3600000,
'hide': false "hide": false
}; };
return (key in settings) ? settings[key] : DEFAULTS[key]; return (key in settings) ? settings[key] : DEFAULTS[key];
} }
weather.on("update", w => { weather.on("update", w => {
if (setting('hide')) return; if (setting("hide")) return;
if (w) { if (w) {
if (!WIDGETS["weather"].width) { if (!WIDGETS.weather.width) {
WIDGETS["weather"].width = 20; WIDGETS.weather.width = 20;
Bangle.drawWidgets(); Bangle.drawWidgets();
} else if (Bangle.isLCDOn()) { } else if (Bangle.isLCDOn()) {
WIDGETS["weather"].draw(); WIDGETS.weather.draw();
} else { } else {
dirty = true; dirty = true;
} }
} }
else { else {
WIDGETS["weather"].width = 0; WIDGETS.weather.width = 0;
Bangle.drawWidgets(); Bangle.drawWidgets();
} }
}); });
Bangle.on('lcdPower', on => { Bangle.on("lcdPower", on => {
if (on && dirty && !setting('hide')) { if (on && dirty && !setting("hide")) {
WIDGETS["weather"].draw(); WIDGETS.weather.draw();
dirty = false; dirty = false;
} }
}); });
WIDGETS["weather"] = { WIDGETS.weather = {
area: "tl", area: "tl",
width: weather.get() && !setting('hide') ? 20 : 0, width: weather.get() && !setting("hide") ? 20 : 0,
draw: function() { draw: function() {
if (setting('hide')) return; if (setting("hide")) return;
const w = weather.get(); const w = weather.get();
if (!w) return; if (!w) return;
g.reset(); g.reset();
@ -56,17 +56,17 @@
weather.drawIcon(w, this.x+10, this.y+8, 7.5); weather.drawIcon(w, this.x+10, this.y+8, 7.5);
} }
if (w.temp) { if (w.temp) {
let t = require('locale').temp(w.temp-273.15); // applies conversion let t = require("locale").temp(w.temp-273.15); // applies conversion
t = t.match(/[\d\-]*/)[0]; // but we have no room for units t = t.match(/[\d\-]*/)[0]; // but we have no room for units
g.reset(); g.reset();
g.setFontAlign(0, 1); // center horizontally at bottom of widget g.setFontAlign(0, 1); // center horizontally at bottom of widget
g.setFont('6x8', 1); g.setFont("6x8", 1);
g.drawString(t, this.x+10, this.y+24); g.drawString(t, this.x+10, this.y+24);
} }
}, },
reload:function() { reload:() => {
loadSettings(); loadSettings();
WIDGETS["weather"].redraw(); WIDGETS.weather.redraw();
}, },
}; };
})(); })();