Add alarms app (fix #83)
parent
d8c3b73334
commit
47205bfe61
18
apps.json
18
apps.json
|
|
@ -2,7 +2,7 @@
|
||||||
{ "id": "boot",
|
{ "id": "boot",
|
||||||
"name": "Bootloader",
|
"name": "Bootloader",
|
||||||
"icon": "bootloader.png",
|
"icon": "bootloader.png",
|
||||||
"version":"0.03",
|
"version":"0.04",
|
||||||
"description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings",
|
"description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings",
|
||||||
"tags": "tool,system",
|
"tags": "tool,system",
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
"sortorder" : -10
|
"sortorder" : -10
|
||||||
},
|
},
|
||||||
{ "id": "launch",
|
{ "id": "launch",
|
||||||
"name": "Launcher",
|
"name": "Default Launcher",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.01",
|
"version":"0.01",
|
||||||
"description": "This is needed by Bangle.js to display a menu allowing you to choose your own applications. You can replace this with a customised launcher.",
|
"description": "This is needed by Bangle.js to display a menu allowing you to choose your own applications. You can replace this with a customised launcher.",
|
||||||
|
|
@ -66,6 +66,20 @@
|
||||||
],
|
],
|
||||||
"sortorder" : -2
|
"sortorder" : -2
|
||||||
},
|
},
|
||||||
|
{ "id": "alarm",
|
||||||
|
"name": "Default Alarm",
|
||||||
|
"icon": "app.png",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "Set and respond to alarms",
|
||||||
|
"tags": "tool,alarm",
|
||||||
|
"storage": [
|
||||||
|
{"name":"+alarm","url":"app.json"},
|
||||||
|
{"name":"-alarm","url":"app.js"},
|
||||||
|
{"name":"@alarm","content":"[]"},
|
||||||
|
{"name":"*alarm","url":"app-icon.js","evaluate":true},
|
||||||
|
{"name":"=alarm","url":"widget.js"}
|
||||||
|
]
|
||||||
|
},
|
||||||
{ "id": "wclock",
|
{ "id": "wclock",
|
||||||
"name": "Word Clock",
|
"name": "Word Clock",
|
||||||
"icon": "clock-word.png",
|
"icon": "clock-word.png",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
0.01: New App!
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEwwkGswAhiMRCCAREAo4eHBIQLEAgwYHsIJDiwHB5gACBpIhHCoYZEGA4gFCw4ABGA4HEjgXJ4IXGAwcUB4VEmf//8zogICoJIFAodMBoNDCoIADmgJB4gXIFwXDCwoABngwFC4guB4k/CQXwh4EC+YMCC44iBp4qDC4n/+gNBC41sEIJCEC4v/GAPGC4dhXYRdFC4xhCCYIXCdQRdDC5HzegQXCsxGHC45IDCwQXCUgwXHJAIXGRogXJSIIXcOw4XIPAYXcBwv/mEDBAwXOgtQC65QGC5vzoEAJAx3Nmk/mEABIiPN+dDAQIwFC4zXGFwKRCGAjvMFwQECGAgXI4YuGGAUvAgU8C4/EFwwGCAgdMC4p4EFwobFOwoXDJAIoEAApGBC4xIEABJGHGAapEAAqNBFwwXD4heI+YuBC5BIBVQhdHIw4wD5inFS4IKCCxFmigNCokzCoMzogICoIWIsMRjgPCAA3BiMWC48RBQIXJEgMRFxAJCCw4lEC44IECooOIBAaBJKwhgIAH4ACA=="))
|
||||||
|
|
@ -0,0 +1,151 @@
|
||||||
|
Bangle.loadWidgets();
|
||||||
|
Bangle.drawWidgets();
|
||||||
|
|
||||||
|
var alarms = require("Storage").readJSON("@alarm")||[];
|
||||||
|
/*alarms = [
|
||||||
|
{ on : true,
|
||||||
|
hr : 6.5, // hours + minutes/60
|
||||||
|
msg : "Eat chocolate",
|
||||||
|
last : 0, // last day of the month we alarmed on - so we don't alarm twice in one day!
|
||||||
|
rp : true, // repeat
|
||||||
|
}
|
||||||
|
];*/
|
||||||
|
|
||||||
|
function formatTime(t) {
|
||||||
|
var hrs = 0|t;
|
||||||
|
var mins = 0|((t-hrs)*60);
|
||||||
|
return hrs+":"+("0"+mins).substr(-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentHr() {
|
||||||
|
var time = new Date();
|
||||||
|
return time.getHours()+(time.getMinutes()/60);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showMainMenu() {
|
||||||
|
const menu = {
|
||||||
|
'': { 'title': 'Alarms' },
|
||||||
|
'New Alarm': ()=>editAlarm(-1)
|
||||||
|
};
|
||||||
|
alarms.forEach((alarm,idx)=>{
|
||||||
|
txt = (alarm.on?"on ":"off ")+formatTime(alarm.hr);
|
||||||
|
if (alarm.rp) txt += " (repeat)";
|
||||||
|
menu[txt] = function() {
|
||||||
|
editAlarm(idx);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
menu['< Back'] = ()=>{load();};
|
||||||
|
return E.showMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
function editAlarm(alarmIndex) {
|
||||||
|
var newAlarm = alarmIndex<0;
|
||||||
|
var hrs = 12;
|
||||||
|
var mins = 0;
|
||||||
|
var en = true;
|
||||||
|
var repeat = true;
|
||||||
|
if (!newAlarm) {
|
||||||
|
var a = alarms[alarmIndex];
|
||||||
|
hrs = 0|a.hr;
|
||||||
|
mins = 0|((a.hr-hrs)*60);
|
||||||
|
en = a.on;
|
||||||
|
repeat = a.rp;
|
||||||
|
}
|
||||||
|
const menu = {
|
||||||
|
'': { 'title': 'Alarms' },
|
||||||
|
'Hours': {
|
||||||
|
value: hrs,
|
||||||
|
min: 0,
|
||||||
|
max: 23,
|
||||||
|
onchange: v=>hrs=v
|
||||||
|
},
|
||||||
|
'Minutes': {
|
||||||
|
value: mins,
|
||||||
|
min: 0,
|
||||||
|
max: 60,
|
||||||
|
onchange: v=>mins=v
|
||||||
|
},
|
||||||
|
'Enabled': {
|
||||||
|
value: en,
|
||||||
|
format: v=>v?"On":"Off",
|
||||||
|
onchange: v=>en=v
|
||||||
|
},
|
||||||
|
'Repeat': {
|
||||||
|
value: en,
|
||||||
|
format: v=>v?"Yes":"No",
|
||||||
|
onchange: v=>repeat=v
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function getAlarm() {
|
||||||
|
var hr = hrs+(mins/60);
|
||||||
|
var day = 0;
|
||||||
|
// If alarm is for tomorrow not today, set day
|
||||||
|
if (hr > getCurrentHr())
|
||||||
|
day = (new Date()).getDate();
|
||||||
|
// Save alarm
|
||||||
|
return {
|
||||||
|
on : en, hr : hr,
|
||||||
|
last : day, rp : repeat
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (newAlarm) {
|
||||||
|
menu["> New Alarm"] = function() {
|
||||||
|
alarms.push(getAlarm());
|
||||||
|
require("Storage").write("@alarm",JSON.stringify(alarms));
|
||||||
|
showMainMenu();
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
menu["> Save"] = function() {
|
||||||
|
alarms[alarmIndex] = getAlarm();
|
||||||
|
require("Storage").write("@alarm",JSON.stringify(alarms));
|
||||||
|
showMainMenu();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
menu['< Back'] = showMainMenu;
|
||||||
|
return E.showMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showAlarm(alarm) {
|
||||||
|
var msg = formatTime(alarm.hr);
|
||||||
|
var buzzCount = 10;
|
||||||
|
if (alarm.msg)
|
||||||
|
msg += "\n"+alarm.msg;
|
||||||
|
E.showPrompt(msg,{
|
||||||
|
title:"ALARM!",
|
||||||
|
buttons : {"Sleep":true,"Ok":false} // default is sleep so it'll come back in 10 mins
|
||||||
|
}).then(function(sleep) {
|
||||||
|
buzzCount = 0;
|
||||||
|
if (sleep) {
|
||||||
|
alarm.hr += 10/60; // 10 minutes
|
||||||
|
} else {
|
||||||
|
alarm.last = (new Date()).getDate();
|
||||||
|
if (!alarm.rp) alarm.on = false;
|
||||||
|
}
|
||||||
|
require("Storage").write("@alarm",JSON.stringify(alarms));
|
||||||
|
load();
|
||||||
|
});
|
||||||
|
function buzz() {
|
||||||
|
Bangle.buzz(100).then(()=>{
|
||||||
|
setTimeout(()=>{
|
||||||
|
Bangle.buzz(100).then(function() {
|
||||||
|
if (buzzCount--)
|
||||||
|
setTimeout(buzz, 3000);
|
||||||
|
});
|
||||||
|
},100);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
buzz();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for alarms
|
||||||
|
var day = (new Date()).getDate();
|
||||||
|
var hr = getCurrentHr();
|
||||||
|
var active = alarms.filter(a=>a.on&&(a.hr<hr)&&(a.last!=day));
|
||||||
|
if (active.length) {
|
||||||
|
// if there's an alarm, show it
|
||||||
|
active = active.sort((a,b)=>a.hr-b.hr);
|
||||||
|
showAlarm(active[0]);
|
||||||
|
} else {
|
||||||
|
// otherwise show the main menu
|
||||||
|
showMainMenu();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"name":"Alarms",
|
||||||
|
"icon":"*alarm",
|
||||||
|
"src":"-alarm"
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
|
|
@ -0,0 +1,17 @@
|
||||||
|
(() => {
|
||||||
|
var alarms = require('Storage').readJSON('@alarm')||[];
|
||||||
|
alarms = alarms.filter(alarm=>alarm.on);
|
||||||
|
if (!alarms.length) return;
|
||||||
|
delete alarms;
|
||||||
|
// add the width
|
||||||
|
var xpos = WIDGETPOS.tl;
|
||||||
|
WIDGETPOS.tl += 24;/* the widget width plus some extra pixel to keep distance to others */;
|
||||||
|
|
||||||
|
// draw your widget at xpos
|
||||||
|
|
||||||
|
// add the widget
|
||||||
|
WIDGETS["alarm"]={draw:function() {
|
||||||
|
g.setColor(-1);
|
||||||
|
g.drawImage(atob("GBgBAAAAAAAAABgADhhwDDwwGP8YGf+YMf+MM//MM//MA//AA//AA//AA//AA//AA//AB//gD//wD//wAAAAADwAABgAAAAAAAAA"),xpos,0);
|
||||||
|
}};
|
||||||
|
})()
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
0.02: Attempt to reset state of the interpreter better before loading an app
|
0.02: Attempt to reset state of the interpreter better before loading an app
|
||||||
0.03: Fix issue switching clockfaces via menu
|
0.03: Fix issue switching clockfaces via menu
|
||||||
|
0.04: Add alarm functionality
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,30 @@ Bangle.setLCDTimeout(s.timeout);
|
||||||
if (!s.timeout) Bangle.setLCDPower(1);
|
if (!s.timeout) Bangle.setLCDPower(1);
|
||||||
E.setTimeZone(s.timezone);
|
E.setTimeZone(s.timezone);
|
||||||
delete s;
|
delete s;
|
||||||
|
// check for alarms
|
||||||
|
function checkAlarm() {
|
||||||
|
var alarms = require('Storage').readJSON('@alarm')||[];
|
||||||
|
var time = new Date();
|
||||||
|
var active = alarms.filter(a=>a.on&&(a.last!=time.getDate()));
|
||||||
|
if (active.length) {
|
||||||
|
active = active.sort((a,b)=>a.hr-b.hr);
|
||||||
|
var hr = time.getHours()+(time.getMinutes()/60);
|
||||||
|
if (!require('Storage').read("-alarm")) {
|
||||||
|
console.log("No alarm app!");
|
||||||
|
require('Storage').write('@alarm',"[]")
|
||||||
|
} else {
|
||||||
|
if (active[0].hr < hr) {
|
||||||
|
// fire alarm now
|
||||||
|
load("-alarm");
|
||||||
|
} else {
|
||||||
|
// execute alarm at the correct time
|
||||||
|
setTimeout(function() {
|
||||||
|
load("-alarm");
|
||||||
|
},3600000*(active[0].hr-hr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// check to see if our clock is wrong - if it is use GPS time
|
// check to see if our clock is wrong - if it is use GPS time
|
||||||
if ((new Date()).getFullYear()==1970) {
|
if ((new Date()).getFullYear()==1970) {
|
||||||
console.log("Searching for GPS time");
|
console.log("Searching for GPS time");
|
||||||
|
|
@ -32,9 +56,12 @@ if ((new Date()).getFullYear()==1970) {
|
||||||
}
|
}
|
||||||
setTime(g.time.getTime()/1000);
|
setTime(g.time.getTime()/1000);
|
||||||
console.log("GPS time",g.time.toString());
|
console.log("GPS time",g.time.toString());
|
||||||
|
checkAlarm();
|
||||||
});
|
});
|
||||||
Bangle.setGPSPower(1);
|
Bangle.setGPSPower(1);
|
||||||
}
|
} else checkAlarm();
|
||||||
|
delete checkAlarm;
|
||||||
|
// Check for
|
||||||
// All of this is just shim for older Bangles
|
// All of this is just shim for older Bangles
|
||||||
if (!Bangle.loadWidgets) {
|
if (!Bangle.loadWidgets) {
|
||||||
Bangle.loadWidgets = function(){
|
Bangle.loadWidgets = function(){
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
Bangle.loadWidgets();
|
||||||
|
Bangle.drawWidgets();
|
||||||
|
|
||||||
const storage = require('Storage');
|
const storage = require('Storage');
|
||||||
let settings;
|
let settings;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
["boot","launch","mclock","setting","sbat","sbt"]
|
["boot","launch","mclock","setting","alarm","sbat","sbt"]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue