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");
|
var SunCalc = require("https://raw.githubusercontent.com/mourner/suncalc/master/suncalc.js");
|
||||||
require("f_latosmall").add(Graphics);
|
require("f_latosmall").add(Graphics);
|
||||||
|
const storage = require('Storage');
|
||||||
|
const locale = require("locale");
|
||||||
const SETTINGS_FILE = "pastel.json";
|
const SETTINGS_FILE = "pastel.json";
|
||||||
const LOCATION_FILE = "mylocation.json";
|
const LOCATION_FILE = "mylocation.json";
|
||||||
let settings;
|
let settings;
|
||||||
let location;
|
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() {
|
function loadSettings() {
|
||||||
settings = require("Storage").readJSON(SETTINGS_FILE,1)||{};
|
settings = require("Storage").readJSON(SETTINGS_FILE,1)||{};
|
||||||
settings.grid = settings.grid||false;
|
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";
|
var mm_prev = "xx";
|
||||||
|
|
||||||
function draw() {
|
function draw() {
|
||||||
|
@ -114,7 +170,25 @@ function draw() {
|
||||||
var h = g.getHeight();
|
var h = g.getHeight();
|
||||||
var x = (g.getWidth()/2);
|
var x = (g.getWidth()/2);
|
||||||
var y = (g.getHeight()/3);
|
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();
|
g.reset();
|
||||||
|
|
||||||
if (process.env.HWVERSION == 1) {
|
if (process.env.HWVERSION == 1) {
|
||||||
|
@ -139,6 +213,18 @@ function draw() {
|
||||||
|
|
||||||
g.setColor(g.theme.fg);
|
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")
|
if (settings.font == "Architect")
|
||||||
g.setFontArchitect();
|
g.setFontArchitect();
|
||||||
else if (settings.font == "GochiHand")
|
else if (settings.font == "GochiHand")
|
||||||
|
@ -161,36 +247,39 @@ function draw() {
|
||||||
|
|
||||||
// for the colon
|
// for the colon
|
||||||
g.setFontAlign(0,-1); // centre aligned
|
g.setFontAlign(0,-1); // centre aligned
|
||||||
|
g.drawString(":", x,y);
|
||||||
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.setFontLatoSmall();
|
g.setFontLatoSmall();
|
||||||
g.setFontAlign(0, -1);
|
g.setFontAlign(0, -1);
|
||||||
g.drawString((infoData[infoMode].calc()), w/2, h - 24 - 24);
|
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);
|
updateSunRiseSunSet(new Date(), location.lat, location.lon);
|
||||||
drawCount++;
|
drawCount++;
|
||||||
|
queueDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only update when display turns on
|
// timeout used to update every minute
|
||||||
if (process.env.BOARD!="SMAQ3") // hack for Q3 which is always-on
|
var drawTimeout;
|
||||||
Bangle.on('lcdPower', function(on) {
|
|
||||||
if (secondInterval)
|
// schedule a draw for the next minute
|
||||||
clearInterval(secondInterval);
|
function queueDraw() {
|
||||||
secondInterval = undefined;
|
if (drawTimeout) clearTimeout(drawTimeout);
|
||||||
if (on)
|
drawTimeout = setTimeout(function() {
|
||||||
secondInterval = setInterval(draw, 1000);
|
drawTimeout = undefined;
|
||||||
draw();
|
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=> {
|
Bangle.setUI("clockupdown", btn=> {
|
||||||
|
@ -204,8 +293,6 @@ loadFonts();
|
||||||
loadLocation();
|
loadLocation();
|
||||||
|
|
||||||
g.clear();
|
g.clear();
|
||||||
var secondInterval = setInterval(draw, 1000);
|
|
||||||
draw();
|
|
||||||
|
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
|
draw();
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
// initialize with default settings...
|
// initialize with default settings...
|
||||||
let s = {
|
let s = {
|
||||||
'grid': false,
|
'grid': false,
|
||||||
|
'weather': false,
|
||||||
'font': "Lato"
|
'font': "Lato"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,8 +40,16 @@
|
||||||
value: s.grid,
|
value: s.grid,
|
||||||
format: () => (s.grid ? 'Yes' : 'No'),
|
format: () => (s.grid ? 'Yes' : 'No'),
|
||||||
onchange: () => {
|
onchange: () => {
|
||||||
s.grid = !s.grid
|
s.grid = !s.grid;
|
||||||
save()
|
save();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'Show Weather': {
|
||||||
|
value: s.weather,
|
||||||
|
format: () => (s.weather ? 'Yes' : 'No'),
|
||||||
|
onchange: () => {
|
||||||
|
s.weather = !s.weather;
|
||||||
|
save();
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue