BangleApps/apps/pastel/pastel.app.js

289 lines
9.0 KiB
JavaScript
Raw Normal View History

var SunCalc = require("https://raw.githubusercontent.com/mourner/suncalc/master/suncalc.js");
2021-11-22 22:08:19 +00:00
require("f_latosmall").add(Graphics);
const storage = require('Storage');
const locale = require("locale");
2021-09-14 21:01:20 +00:00
const SETTINGS_FILE = "pastel.json";
const LOCATION_FILE = "mylocation.json";
2021-11-22 22:50:27 +00:00
let settings;
let location;
2021-09-14 21:01:20 +00:00
// 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=="));
2021-09-14 21:01:20 +00:00
function loadSettings() {
settings = require("Storage").readJSON(SETTINGS_FILE,1)||{};
settings.grid = settings.grid||false;
settings.font = settings.font||"Lato";
}
// requires the myLocation app
function loadLocation() {
location = require("Storage").readJSON(LOCATION_FILE,1)||{"lat":51.5072,"lon":0.1276,"location":"London"};
}
function extractTime(d){
var h = d.getHours(), m = d.getMinutes();
return(("0"+h).substr(-2) + ":" + ("0"+m).substr(-2));
}
var sunRise = "00:00";
var sunSet = "00:00";
var drawCount = 0;
function updateSunRiseSunSet(now, lat, lon, line){
// get today's sunlight times for lat/lon
var times = SunCalc.getTimes(new Date(), lat, lon);
// format sunrise time from the Date object
sunRise = extractTime(times.sunrise);
sunSet = extractTime(times.sunset);
}
2021-11-22 21:17:50 +00:00
function loadFonts() {
// load font files based on settings.font
if (settings.font == "Architect")
2021-11-22 22:50:27 +00:00
require("f_architect").add(Graphics);
2021-11-22 21:17:50 +00:00
else if (settings.font == "GochiHand")
require("f_gochihand").add(Graphics);
else if (settings.font == "CabinSketch")
require("f_cabin").add(Graphics);
else if (settings.font == "Orbitron")
require("f_orbitron").add(Graphics);
else if (settings.font == "Monoton")
require("f_monoton").add(Graphics);
else if (settings.font == "Elite")
require("f_elite").add(Graphics);
else
2021-11-22 22:08:19 +00:00
require("f_lato").add(Graphics);
2021-11-22 21:17:50 +00:00
}
2021-11-22 21:03:53 +00:00
2022-01-20 23:29:37 +00:00
function getSteps() {
try {
return Bangle.getHealthStatus("day").steps;
} catch (e) {
if (WIDGETS.wpedom !== undefined)
return WIDGETS.wpedom.getSteps();
else
return '???'
}
}
const infoData = {
ID_BLANK: { calc: () => '' },
ID_DATE: { calc: () => {var d = (new Date).toString().split(" "); return d[2] + ' ' + d[1] + ' ' + d[3];} },
ID_DAY: { calc: () => {var d = require("locale").dow(new Date).toLowerCase(); return d[0].toUpperCase() + d.substring(1);} },
ID_SR: { calc: () => 'Sunrise: ' + sunRise },
ID_SS: { calc: () => 'Sunset: ' + sunSet },
2022-01-20 23:29:37 +00:00
ID_STEP: { calc: () => 'Steps: ' + getSteps() },
ID_BATT: { calc: () => 'Battery: ' + E.getBattery() + '%' },
ID_MEM: { calc: () => {var val = process.memory(false); return 'Ram: ' + Math.round(val.usage*100/val.total) + '%';} },
ID_ID: { calc: () => {var val = NRF.getAddress().split(':'); return 'Id: ' + val[4] + val[5];} },
ID_FW: { calc: () => 'Fw: ' + process.env.VERSION }
};
const infoList = Object.keys(infoData).sort();
let infoMode = infoList[0];
function nextInfo() {
let idx = infoList.indexOf(infoMode);
if (idx > -1) {
if (idx === infoList.length - 1) infoMode = infoList[0];
else infoMode = infoList[idx + 1];
}
}
function prevInfo() {
let idx = infoList.indexOf(infoMode);
if (idx > -1) {
if (idx === 0) infoMode = infoList[infoList.length - 1];
else infoMode = infoList[idx - 1];
}
}
/**
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;
}
2021-09-13 19:26:53 +00:00
function draw() {
var d = new Date();
var da = d.toString().split(" ");
var time = da[4].substr(0,5);
var hh = da[4].substr(0,2);
var mm = da[4].substr(3,2);
var day = da[0];
var month_day = da[1] + " " + da[2];
// fix hh for 12hr clock
var h2 = "0" + parseInt(hh) % 12 || 12;
if (parseInt(hh) > 12)
hh = h2.substr(h2.length -2);
2021-09-13 19:26:53 +00:00
var w = g.getWidth();
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;
}
2021-09-13 19:26:53 +00:00
g.reset();
g.clearRect(0, 30, w, h - 24);
2021-09-13 19:26:53 +00:00
// draw a grid like graph paper
2021-09-14 21:01:20 +00:00
if (settings.grid && process.env.HWVERSION !=1) {
g.setColor("#0f0");
for (var gx=20; gx <= w; gx += 20)
g.drawLine(gx, 30, gx, h - 24);
for (var gy=30; gy <= h - 24; gy += 20)
g.drawLine(0, gy, w, gy);
}
g.setColor(g.theme.fg);
2021-09-13 19:26:53 +00:00
// 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'
}
2021-09-14 21:01:20 +00:00
if (settings.font == "Architect")
g.setFontArchitect();
else if (settings.font == "GochiHand")
g.setFontGochiHand();
else if (settings.font == "CabinSketch")
g.setFontCabinSketch();
2021-09-14 22:04:48 +00:00
else if (settings.font == "Orbitron")
g.setFontOrbitron();
else if (settings.font == "Monoton")
g.setFontMonoton();
else if (settings.font == "Elite")
g.setFontSpecialElite();
2021-09-14 21:01:20 +00:00
else
2021-11-22 22:50:27 +00:00
g.setFontLato();
2021-09-14 21:01:20 +00:00
2021-09-13 19:26:53 +00:00
g.setFontAlign(1,-1); // right aligned
g.drawString(hh, x - 6, y);
g.setFontAlign(-1,-1); // left aligned
g.drawString(mm, x + 6, y);
2021-09-13 19:26:53 +00:00
// for the colon
g.setFontAlign(0,-1); // centre aligned
g.drawString(":", x,y);
g.setFontLatoSmall();
g.setFontAlign(0, -1);
g.drawString((infoData[infoMode].calc()), w/2, h - 24 - 24);
// recalc sunrise / sunset every hour
if (drawCount % 60 == 0)
updateSunRiseSunSet(new Date(), location.lat, location.lon);
drawCount++;
queueDraw();
2021-09-13 19:26:53 +00:00
}
// 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;
prevInfo();
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;
}
2021-09-13 19:26:53 +00:00
});
Bangle.setUI("clockupdown", btn=> {
if (btn<0) prevInfo();
if (btn>0) nextInfo();
draw();
});
2021-11-22 21:17:50 +00:00
loadSettings();
loadFonts();
loadLocation();
g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
draw();