add hardalarm

pull/614/head
jamespsteinberg@gmail.com 2020-12-25 21:41:09 +08:00
parent e339b9b523
commit 369d076745
8 changed files with 295 additions and 0 deletions

View File

@ -2490,5 +2490,23 @@
{"name":"HRV.app.js","url":"app.js"},
{"name":"HRV.img","url":"app-icon.js","evaluate":true}
]
},
{ "id": "hardalarm",
"name": "Hard Alarm",
"shortName":"HardAlarm",
"icon": "app.png",
"version":"0.01",
"description": "Count to the right number to turn off the alarm",
"tags": "tool,alarm,widget",
"storage": [
{"name":"hardalarm.app.js","url":"app.js"},
{"name":"hardalarm.boot.js","url":"boot.js"},
{"name":"hardalarm.js","url":"hardalarm.js"},
{"name":"hardalarm.img","url":"app-icon.js","evaluate":true},
{"name":"hardalarm.wid.js","url":"widget.js"}
],
"data": [
{"name":"alarm.json"}
]
}
]

1
apps/hardalarm/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.01: Add a number to match to turn off alarm

View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mEwwkE5gA/AF9cBZXFQYIOGBIUMC5PATgQJFqAIBgovMBwISDAYQ5HGBAAGFxQ/FgMzmcgJ5BIKgAXFIxYuBgMxCIMjmcQgECiBHLFwITBFYIvBiBLBmQwLqECCYMziICBmIeBD4IwKFwQAIGAJGJRQUhgIbDAocQJBHAgYlCOQIrDAoUwhhGIiZZBX4gFEAgIXICIMwX4gFFC45eDF5RgI4pZHAo0gC43AXoaPJC4J4GRwQAMSA4XfmKuBC6kQRYQXMO4YACXYYADO46nDIwcCiBIFU47XDBwcTkBQFa4/MH4sAkYxBBAoWGC4I/DmQ1BdwJPEC5CQEmAECGQKOKMA0gCYRgELxBICCYUyFQZgCJgIWI5lQYIxjCGYMFC5PFLAiKDFwRGJGATCFLoYuKGAYYGiAuMDAkiCoMiCx6SCAAq7IF48F4tQCoMFqAXP4AQF4B1MSAZXFMwIXPA41VC5wA/ADAA=="))

112
apps/hardalarm/app.js Normal file
View File

@ -0,0 +1,112 @@
Bangle.loadWidgets();
Bangle.drawWidgets();
var alarms = require("Storage").readJSON("hardalarm.json",1)||[];
/*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
as : false, // auto snooze
}
];*/
function formatTime(t) {
var hrs = 0|t;
var mins = Math.round((t-hrs)*60);
return hrs+":"+("0"+mins).substr(-2);
}
function getCurrentHr() {
var time = new Date();
return time.getHours()+(time.getMinutes()/60)+(time.getSeconds()/3600);
}
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;
var as = false;
if (!newAlarm) {
var a = alarms[alarmIndex];
hrs = 0|a.hr;
mins = Math.round((a.hr-hrs)*60);
en = a.on;
repeat = a.rp;
as = a.as;
}
const menu = {
'': { 'title': 'Alarms' },
'Hours': {
value: hrs,
onchange: function(v){if (v<0)v=23;if (v>23)v=0;hrs=v;this.value=v;} // no arrow fn -> preserve 'this'
},
'Minutes': {
value: mins,
onchange: function(v){if (v<0)v=59;if (v>59)v=0;mins=v;this.value=v;} // no arrow fn -> preserve 'this'
},
'Enabled': {
value: en,
format: v=>v?"On":"Off",
onchange: v=>en=v
},
'Repeat': {
value: en,
format: v=>v?"Yes":"No",
onchange: v=>repeat=v
},
'Auto snooze': {
value: as,
format: v=>v?"Yes":"No",
onchange: v=>as=v
}
};
function getAlarm() {
var hr = hrs+(mins/60);
var day = 0;
// If alarm is for tomorrow not today (eg, in the past), set day
if (hr < getCurrentHr())
day = (new Date()).getDate();
// Save alarm
return {
on : en, hr : hr,
last : day, rp : repeat, as: as
};
}
menu["> Save"] = function() {
if (newAlarm) alarms.push(getAlarm());
else alarms[alarmIndex] = getAlarm();
require("Storage").write("hardalarm.json",JSON.stringify(alarms));
showMainMenu();
};
if (!newAlarm) {
menu["> Delete"] = function() {
alarms.splice(alarmIndex,1);
require("Storage").write("hardalarm.json",JSON.stringify(alarms));
showMainMenu();
};
}
menu['< Back'] = showMainMenu;
return E.showMenu(menu);
}
showMainMenu();

BIN
apps/hardalarm/app.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

25
apps/hardalarm/boot.js Normal file
View File

@ -0,0 +1,25 @@
// check for alarms
(function() {
var alarms = require('Storage').readJSON('hardalarm.json',1)||[];
var time = new Date();
var active = alarms.filter(a=>a.on);
if (active.length) {
active = active.sort((a,b)=>(a.hr-b.hr)+(a.last-b.last)*24);
var hr = time.getHours()+(time.getMinutes()/60)+(time.getSeconds()/3600);
if (!require('Storage').read("hardalarm.js")) {
console.log("No alarm app!");
require('Storage').write('hardalarm.json',"[]");
} else {
var t = 3600000*(active[0].hr-hr);
if (active[0].last == time.getDate() || t < 0) t += 86400000;
if (t<1000) t=1000;
/* execute alarm at the correct time. We avoid execing immediately
since this code will get called AGAIN when hardalarm.js is loaded. alarm.js
will then clearInterval() to get rid of this call so it can proceed
normally. */
setTimeout(function() {
load("hardalarm.js");
},t);
}
}
})();

127
apps/hardalarm/hardalarm.js Normal file
View File

@ -0,0 +1,127 @@
// Chances are boot0.js got run already and scheduled *another*
// 'load(hardalarm.js)' - so let's remove it first!
clearInterval();
function formatTime(t) {
var hrs = 0|t;
var mins = Math.round((t-hrs)*60);
return hrs+":"+("0"+mins).substr(-2);
}
function getCurrentHr() {
var time = new Date();
return time.getHours()+(time.getMinutes()/60)+(time.getSeconds()/3600);
}
function getRandomInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}
function getRandomFromRange(lowerRangeMin, lowerRangeMax, higherRangeMin, higherRangeMax) {
var lowerRange = lowerRangeMax - lowerRangeMin;
var higherRange = higherRangeMax - higherRangeMin;
var fullRange = lowerRange + higherRange;
var randomNum = getRandomInt(fullRange);
if(randomNum <= (lowerRangeMax - lowerRangeMin)) {
return randomNum + lowerRangeMin;
} else {
return randomNum + (higherRangeMin - lowerRangeMax);
}
}
function showNumberPicker(currentGuess, randomNum) {
if(currentGuess == randomNum) {
E.showMessage("" + currentGuess + "\n PRESS ENTER", "Get to " + randomNum);
} else {
E.showMessage("" + currentGuess, "Get to " + randomNum);
}
}
function showPrompt(msg, buzzCount, alarm) {
E.showPrompt(msg,{
title:"STAY AWAKE!",
buttons : {"Sleep":0,"Stop":1} // default is sleep so it'll come back in 10 mins
}).then(function(choice) {
buzzCount = 0;
if (choice==0) {
if(alarm.ohr===undefined) alarm.ohr = alarm.hr;
alarm.hr += 10/60; // 10 minutes
require("Storage").write("hardalarm.json",JSON.stringify(alarms));
load();
} else if(choice==1) {
alarm.last = (new Date()).getDate();
if (alarm.ohr!==undefined) {
alarm.hr = alarm.ohr;
delete alarm.ohr;
}
if (!alarm.rp) alarm.on = false;
require("Storage").write("hardalarm.json",JSON.stringify(alarms));
load();
}
});
}
function showAlarm(alarm) {
var msg = formatTime(alarm.hr);
var buzzCount = 20;
if (alarm.msg)
msg += "\n"+alarm.msg;
var okClicked = false;
var currentGuess = 10;
var randomNum = getRandomFromRange(0, 7, 13, 20);
showNumberPicker(currentGuess, randomNum)
setWatch(o => {
if(!okClicked && currentGuess < 20) {
currentGuess = currentGuess + 1;
showNumberPicker(currentGuess, randomNum);
}
}, BTN1, {repeat: true, edge: 'rising'});
setWatch(o => {
if(currentGuess == randomNum) {
okClicked = true;
showPrompt(msg, buzzCount, alarm);
}
}, BTN2, {repeat: true, edge: 'rising'});
setWatch(o => {
if(!okClicked && currentGuess > 0) {
currentGuess = currentGuess - 1;
showNumberPicker(currentGuess, randomNum);
}
}, BTN3, {repeat: true, edge: 'rising'});
function buzz() {
Bangle.buzz(500).then(()=>{
setTimeout(()=>{
Bangle.buzz(500).then(function() {
setTimeout(()=>{
Bangle.buzz(2000).then(function() {
if (buzzCount--)
setTimeout(buzz, 2000);
else if(alarm.as) { // auto-snooze
buzzCount = 20;
setTimeout(buzz, 600000); // 10 minutes
}
});
},100);
});
},100);
});
}
buzz();
}
// Check for alarms
var day = (new Date()).getDate();
var hr = getCurrentHr()+10000; // get current time - 10s in future to ensure we alarm if we've started the app a tad early
var alarms = require("Storage").readJSON("hardalarm.json",1)||[];
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 just go back to default app
setTimeout(load, 100);
}

11
apps/hardalarm/widget.js Normal file
View File

@ -0,0 +1,11 @@
(() => {
var alarms = require('Storage').readJSON('hardalarm.json',1)||[];
alarms = alarms.filter(alarm=>alarm.on);
if (!alarms.length) return; // no alarms, no widget!
delete alarms;
// add the widget
WIDGETS["alarm"]={area:"tl",width:24,draw:function() {
g.setColor(-1);
g.drawImage(atob("GBgBAAAAAAAAABgADhhwDDwwGP8YGf+YMf+MM//MM//MA//AA//AA//AA//AA//AA//AB//gD//wD//wAAAAADwAABgAAAAAAAAA"),this.x,this.y);
}};
})()