mirror of https://github.com/espruino/BangleApps
Pastel: added weather, change to queueDraw() update once per minute
parent
c0e7535ada
commit
200f9e19b5
|
@ -1,10 +1,22 @@
|
|||
var SunCalc = require("https://raw.githubusercontent.com/mourner/suncalc/master/suncalc.js");
|
||||
require("f_latosmall").add(Graphics);
|
||||
const storage = require('Storage');
|
||||
const locale = require("locale");
|
||||
const SETTINGS_FILE = "pastel.json";
|
||||
const LOCATION_FILE = "mylocation.json";
|
||||
let settings;
|
||||
let location;
|
||||
|
||||
// cloud, sun, partSun, snow, rain, storm, error
|
||||
// create 1 bit, max contrast, brightness set to 85
|
||||
var cloudIcon = require("heatshrink").decompress(atob("kEggIfcj+AAYM/8ADBuFwAYPAmADCCAMBwEf8ADBhFwg4aBnEPAYMYjAVBhgDDDoQDHCYc4jwDB+EP///FYIDBMTgA=="));
|
||||
var sunIcon = require("heatshrink").decompress(atob("kEggILIgOAAZkDAYPAgeBwPAgIFBBgPhw4TBp/yAYMcnADBnEcAYMwhgDBsEGgE/AYP8AYYLDCYgbDEYYrD8fHIwI7CIYZLDL54AHA=="));
|
||||
var sunPartIcon = require("heatshrink").decompress(atob("kEggIHEmADJjEwsEAjkw8EAh0B4EAg35wEAgP+CYMDwv8AYMDBAP2g8HgH+g0DBYMMgPwAYX8gOMEwMG3kAg8OvgSBjg2BgcYGQIcBAY5CBg0Av//HAM///4MYgNBEIMOCoUMDoUAnBwGkEA"));
|
||||
var snowIcon = require("heatshrink").decompress(atob("kEggITQj/AAYM98ADBsEwAYPAjADCj+AgOAj/gAYMIuEHwEAjEPAYQVChk4AYQhCAYcYBYQTDnEPgEB+EH///IAQACE4IAB8EICIPghwDB4EeBYNAjgDBg8EAYQYCg4bCgZuFA=="));
|
||||
var rainIcon = require("heatshrink").decompress(atob("kEggIPMh+AAYM/8ADBuFwAYPgmADB4EbAYOAj/ggOAhnwg4aBnAeCjEcCIMMjADCDoQDHjAPCnAXCuEP///8EDAYJECAAXBwkAgPDhwDBwUMgEEhkggEOjFgFgMQLYQAOA=="));
|
||||
var errIcon = require("heatshrink").decompress(atob("kEggILIgOAAYsD4ADBg/gAYMGsADBhkwAYsYjADCjgDBmEMAYNxxwDBsOGAYPBwYDEgOBwOAgYDB4EDHYPAgwDBsADDhgDBFIcwjAHBjE4AYMcmADBhhNCKIcG/4AGOw4A=="));
|
||||
|
||||
|
||||
function loadSettings() {
|
||||
settings = require("Storage").readJSON(SETTINGS_FILE,1)||{};
|
||||
settings.grid = settings.grid||false;
|
||||
|
@ -93,6 +105,50 @@ function prevInfo() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Choose weather icon to display based on condition.
|
||||
Based on function from the Bangle weather app so it should handle all of the conditions
|
||||
sent from gadget bridge.
|
||||
*/
|
||||
function chooseIcon(condition) {
|
||||
condition = condition.toLowerCase();
|
||||
if (condition.includes("thunderstorm")) return stormIcon;
|
||||
if (condition.includes("freezing")||condition.includes("snow")||
|
||||
condition.includes("sleet")) {
|
||||
return snowIcon;
|
||||
}
|
||||
if (condition.includes("drizzle")||
|
||||
condition.includes("shower")) {
|
||||
return rainIcon;
|
||||
}
|
||||
if (condition.includes("rain")) return rainIcon;
|
||||
if (condition.includes("clear")) return sunIcon;
|
||||
if (condition.includes("few clouds")) return partSunIcon;
|
||||
if (condition.includes("scattered clouds")) return cloudIcon;
|
||||
if (condition.includes("clouds")) return cloudIcon;
|
||||
if (condition.includes("mist") ||
|
||||
condition.includes("smoke") ||
|
||||
condition.includes("haze") ||
|
||||
condition.includes("sand") ||
|
||||
condition.includes("dust") ||
|
||||
condition.includes("fog") ||
|
||||
condition.includes("ash") ||
|
||||
condition.includes("squalls") ||
|
||||
condition.includes("tornado")) {
|
||||
return cloudIcon;
|
||||
}
|
||||
return cloudIcon;
|
||||
}
|
||||
|
||||
/**
|
||||
Get weather stored in json file by weather app.
|
||||
*/
|
||||
function getWeather() {
|
||||
let jsonWeather = storage.readJSON('weather.json');
|
||||
return jsonWeather;
|
||||
}
|
||||
|
||||
var mm_prev = "xx";
|
||||
|
||||
function draw() {
|
||||
|
@ -114,7 +170,25 @@ function draw() {
|
|||
var h = g.getHeight();
|
||||
var x = (g.getWidth()/2);
|
||||
var y = (g.getHeight()/3);
|
||||
|
||||
|
||||
var weatherJson = getWeather();
|
||||
var w_temp;
|
||||
var w_icon;
|
||||
var w_wind;
|
||||
|
||||
if (settings.weather && weatherJson && weatherJson.weather) {
|
||||
var currentWeather = weatherJson.weather;
|
||||
const temp = locale.temp(currentWeather.temp-273.15).match(/^(\D*\d*)(.*)$/);
|
||||
w_temp = temp[1] + " " + temp[2];
|
||||
w_icon = chooseIcon(currentWeather.txt);
|
||||
const wind = locale.speed(currentWeather.wind).match(/^(\D*\d*)(.*)$/);
|
||||
w_wind = wind[1] + " " + wind[2] + " " + (currentWeather.wrose||'').toUpperCase();
|
||||
} else {
|
||||
w_temp = "Err";
|
||||
w_wind = "???";
|
||||
w_icon = errIcon;
|
||||
}
|
||||
|
||||
g.reset();
|
||||
|
||||
if (process.env.HWVERSION == 1) {
|
||||
|
@ -139,6 +213,18 @@ function draw() {
|
|||
|
||||
g.setColor(g.theme.fg);
|
||||
|
||||
// draw weather line
|
||||
if (settings.weather) {
|
||||
g.drawImage(w_icon, (w/2) - 40, 24);
|
||||
g.setFontLatoSmall();
|
||||
g.setFontAlign(-1,0); // left aligned
|
||||
if (drawCount % 2 == 0)
|
||||
g.drawString(w_temp, (w/2) + 6, 24 + ((y - 24)/2));
|
||||
else
|
||||
g.drawString( (w_wind.split(' ').slice(0, 2).join(' ')), (w/2) + 6, 24 + ((y - 24)/2));
|
||||
// display first 2 words of the wind string eg '4 mph'
|
||||
}
|
||||
|
||||
if (settings.font == "Architect")
|
||||
g.setFontArchitect();
|
||||
else if (settings.font == "GochiHand")
|
||||
|
@ -161,36 +247,39 @@ function draw() {
|
|||
|
||||
// for the colon
|
||||
g.setFontAlign(0,-1); // centre aligned
|
||||
|
||||
if (d.getSeconds()&1) {
|
||||
g.drawString(":", x,y);
|
||||
} else {
|
||||
// on bangle 1, we are not using clearRect(), hide : by printing over it in reverse color
|
||||
if (process.env.HWVERSION == 1) {
|
||||
g.setColor(g.theme.bg);
|
||||
g.drawString(":", x,y);
|
||||
g.setColor(g.theme.fg);
|
||||
}
|
||||
}
|
||||
|
||||
g.drawString(":", x,y);
|
||||
g.setFontLatoSmall();
|
||||
g.setFontAlign(0, -1);
|
||||
g.drawString((infoData[infoMode].calc()), w/2, h - 24 - 24);
|
||||
|
||||
if (drawCount % 3600 == 0)
|
||||
// recalc sunrise / sunset every hour
|
||||
if (drawCount % 60 == 0)
|
||||
updateSunRiseSunSet(new Date(), location.lat, location.lon);
|
||||
drawCount++;
|
||||
queueDraw();
|
||||
}
|
||||
|
||||
// Only update when display turns on
|
||||
if (process.env.BOARD!="SMAQ3") // hack for Q3 which is always-on
|
||||
Bangle.on('lcdPower', function(on) {
|
||||
if (secondInterval)
|
||||
clearInterval(secondInterval);
|
||||
secondInterval = undefined;
|
||||
if (on)
|
||||
secondInterval = setInterval(draw, 1000);
|
||||
draw();
|
||||
// timeout used to update every minute
|
||||
var drawTimeout;
|
||||
|
||||
// schedule a draw for the next minute
|
||||
function queueDraw() {
|
||||
if (drawTimeout) clearTimeout(drawTimeout);
|
||||
drawTimeout = setTimeout(function() {
|
||||
drawTimeout = undefined;
|
||||
nextInfo();
|
||||
draw();
|
||||
}, 60000 - (Date.now() % 60000));
|
||||
}
|
||||
|
||||
// Stop updates when LCD is off, restart when on
|
||||
Bangle.on('lcdPower',on=>{
|
||||
if (on) {
|
||||
draw(); // draw immediately, queue redraw
|
||||
} else { // stop draw timer
|
||||
if (drawTimeout) clearTimeout(drawTimeout);
|
||||
drawTimeout = undefined;
|
||||
}
|
||||
});
|
||||
|
||||
Bangle.setUI("clockupdown", btn=> {
|
||||
|
@ -204,8 +293,6 @@ loadFonts();
|
|||
loadLocation();
|
||||
|
||||
g.clear();
|
||||
var secondInterval = setInterval(draw, 1000);
|
||||
draw();
|
||||
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
draw();
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
// initialize with default settings...
|
||||
let s = {
|
||||
'grid': false,
|
||||
'weather': false,
|
||||
'font': "Lato"
|
||||
}
|
||||
|
||||
|
@ -39,8 +40,16 @@
|
|||
value: s.grid,
|
||||
format: () => (s.grid ? 'Yes' : 'No'),
|
||||
onchange: () => {
|
||||
s.grid = !s.grid
|
||||
save()
|
||||
s.grid = !s.grid;
|
||||
save();
|
||||
},
|
||||
},
|
||||
'Show Weather': {
|
||||
value: s.weather,
|
||||
format: () => (s.weather ? 'Yes' : 'No'),
|
||||
onchange: () => {
|
||||
s.weather = !s.weather;
|
||||
save();
|
||||
},
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue