mirror of https://github.com/espruino/BangleApps
Fixes, README and alarm lib
parent
0feebdb318
commit
9055cd7990
|
@ -14,3 +14,4 @@
|
|||
0.13: Alarm widget state now updates when setting/resetting an alarm
|
||||
0.14: Order of 'back' menu item
|
||||
0.15: Fix hour/minute wrapping code for new menu system
|
||||
0.16: Adding alarm library
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
Default Alarm & Timer
|
||||
======================
|
||||
|
||||
This provides an app, widget, library and tools for alarms and timers.
|
||||
|
||||
Other apps can use this to provide alarm functionality.
|
||||
|
||||
App
|
||||
---
|
||||
|
||||
The Alarm app allows you to add/modify any running timers.
|
||||
|
||||
|
||||
Internals / Library
|
||||
-------------------
|
||||
|
||||
Alarms are stored in an array in `alarm.json`, and take the form:
|
||||
|
||||
```
|
||||
{
|
||||
id : "mytimer", // optional ID for this alarm/timer, so apps can easily find *their* timers
|
||||
on : true, // is the alarm enabled?
|
||||
t : 23400000, // Time of day since midnight in ms
|
||||
msg : "Eat chocolate", // message to display
|
||||
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
|
||||
timer : 5*60*1000, // OPTIONAL - if set, this is a timer and it's the time in ms
|
||||
js : "load('myapp.js')" // OPTIONAL - a JS command to execute when the alarm activates (*instead* of loading 'alarm.js')
|
||||
// when this code is run, you're responsible for setting alarm.on=false (or removing the alarm)
|
||||
}
|
||||
```
|
||||
|
||||
The [`alarm` library](https://github.com/espruino/BangleApps/blob/master/apps/alarm/lib.js) contains
|
||||
a few helpful functions for getting/setting alarms, but is intentionally sparse so as not to
|
||||
use too much RAM.
|
||||
|
||||
It can be used as follows:
|
||||
|
||||
```
|
||||
// add/update an existing alarm
|
||||
require("alarm").setAlarm("mytimer", {
|
||||
msg : "Wake up",
|
||||
timer : 10*60*1000, // 10 Minutes
|
||||
});
|
||||
// Ensure the widget and alarm timer updates to schedule the new alarm properly
|
||||
require("alarm").reload();
|
||||
|
||||
// Get the time to the next alarm for us
|
||||
var timeToNext = require("alarm").getTimeToAlarm(require("alarm").getAlarm("mytimer"));
|
||||
// timeToNext===undefined if no alarm or alarm disabled
|
||||
|
||||
// delete an alarm
|
||||
require("alarm").setAlarm("mytimer", undefined);
|
||||
// reload after deleting...
|
||||
require("alarm").reload();
|
||||
|
||||
// Or add an alarm that runs your own code - in this case
|
||||
// loading the settings app. The alarm will not be removed/stopped
|
||||
// automatically.
|
||||
require("alarm").setAlarm("customrunner", {
|
||||
js : "load('setting.app.js')",
|
||||
timer : 1*60*1000, // 1 Minute
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
|
||||
If your app requires alarms, you can specify that the alarms app needs to
|
||||
be installed by adding `"dependencies": {"alarm":"app"},` to your metadata.
|
|
@ -3,13 +3,16 @@ Bangle.drawWidgets();
|
|||
|
||||
var alarms = require("Storage").readJSON("alarm.json",1)||[];
|
||||
/*alarms = [
|
||||
{ on : true,
|
||||
t : 23400000, // Time of day since midnight in ms
|
||||
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
|
||||
{
|
||||
id : "mytimer", // optional ID for this alarm/timer, so apps can easily find *their* timers
|
||||
on : true, // is the alarm enabled?
|
||||
t : 23400000, // Time of day since midnight in ms
|
||||
msg : "Eat chocolate", // message to display
|
||||
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
|
||||
timer : 5*60*1000, // OPTIONAL - if set, this is a timer and it's the time in ms
|
||||
js : "load('myapp.js')" // OPTIONAL - a JS command to execute when the alarm activates (*instead* of loading 'alarm.js')
|
||||
}
|
||||
];*/
|
||||
|
||||
|
@ -41,7 +44,7 @@ function getCurrentTime() {
|
|||
|
||||
function saveAndReload() {
|
||||
require("Storage").write("alarm.json",JSON.stringify(alarms));
|
||||
eval(require("Storage").read("alarm.boot.js"));
|
||||
require("alarm").reload();
|
||||
}
|
||||
|
||||
function showMainMenu() {
|
||||
|
@ -185,7 +188,7 @@ function editTimer(alarmIndex, alarm) {
|
|||
};
|
||||
menu[/*LANG*/"Save"] = function() {
|
||||
a.timer = encodeTime(t);
|
||||
a.hr = getCurrentTime() + a.timer;
|
||||
a.t = getCurrentTime() + a.timer;
|
||||
if (newAlarm) alarms.push(a);
|
||||
else alarms[alarmIndex] = a;
|
||||
saveAndReload();
|
||||
|
|
|
@ -20,10 +20,9 @@
|
|||
/* execute alarm at the correct time. We avoid execing immediately
|
||||
since this code will get called AGAIN when alarm.js is loaded. alarm.js
|
||||
will then clearInterval() to get rid of this call so it can proceed
|
||||
normally. */
|
||||
Bangle.ALARM = setTimeout(function() {
|
||||
load("alarm.js");
|
||||
},t);
|
||||
normally.
|
||||
If active[0].js is defined, just run that code as-is and not alarm.js */
|
||||
Bangle.ALARM = setTimeout(active[0].js||'load("alarm.js")',t);
|
||||
}
|
||||
} else { // check for new alarms at midnight (so day of week works)
|
||||
Bangle.ALARM = setTimeout(() => {
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
// Return an array of all alarms
|
||||
exports.getAlarms = function() {
|
||||
return require("Storage").readJSON("alarm.json",1)||[];
|
||||
};
|
||||
// Return an alarm object based on ID
|
||||
exports.getAlarm = function(id) {
|
||||
var alarms = require("Storage").readJSON("alarm.json",1)||[];
|
||||
return alarms.find(a=>a.id==id);
|
||||
};
|
||||
// Set an alarm object based on ID. Leave 'alarm' undefined to remove it
|
||||
exports.setAlarm = function(id, alarm) {
|
||||
var alarms = require("Storage").readJSON("alarm.json",1)||[];
|
||||
alarms = alarms.filter(a=>a.id!=id);
|
||||
if (alarm !== undefined) {
|
||||
alarm.id = id;
|
||||
if (alarm.dow===undefined) alarm.dow = 0b1111111;
|
||||
if (alarm.on!==false) alarm.on=true;
|
||||
if (alarm.timer) { // if it's a timer, set the start time as a time from *now*
|
||||
var time = new Date();
|
||||
var currentTime = (time.getHours()*3600000)+(time.getMinutes()*60000)+(time.getSeconds()*1000);
|
||||
alarm.t = currentTime + alarm.timer;
|
||||
}
|
||||
}
|
||||
alarms.push(alarm);
|
||||
require("Storage").writeJSON("alarm.json", alarms);
|
||||
};
|
||||
/// Get time until the given alarm (object). Return undefined if alarm not enabled, or if 86400000 or more, alarm could me *more* than a day in the future
|
||||
exports.getTimeToAlarm = function(alarm, time) {
|
||||
if (!alarm) return undefined;
|
||||
if (!time) time = new Date();
|
||||
var active = alarm.on && (alarm.dow>>time.getDay())&1;
|
||||
if (!active) return undefined;
|
||||
var currentTime = (time.getHours()*3600000)+(time.getMinutes()*60000)+(time.getSeconds()*1000);
|
||||
var t = alarm.t-currentTime;
|
||||
if (alarm.last == time.getDate() || t < -60000) t += 86400000;
|
||||
return t;
|
||||
};
|
||||
/// Force a reload of the current alarms and widget
|
||||
exports.reload = function() {
|
||||
eval(require("Storage").read("alarm.boot.js"));
|
||||
if (WIDGETS["alarm"]) {
|
||||
WIDGETS["alarm"].reload();
|
||||
Bangle.drawWidgets();
|
||||
}
|
||||
};
|
|
@ -2,17 +2,19 @@
|
|||
"id": "alarm",
|
||||
"name": "Default Alarm & Timer",
|
||||
"shortName": "Alarms",
|
||||
"version": "0.15",
|
||||
"version": "0.16",
|
||||
"description": "Set and respond to alarms and timers",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,alarm,widget",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name":"alarm.app.js","url":"app.js"},
|
||||
{"name":"alarm.boot.js","url":"boot.js"},
|
||||
{"name":"alarm.js","url":"alarm.js"},
|
||||
{"name":"alarm.img","url":"app-icon.js","evaluate":true},
|
||||
{"name":"alarm.wid.js","url":"widget.js"}
|
||||
{"name":"alarm.wid.js","url":"widget.js"},
|
||||
{"name":"alarm","url":"lib.js"}
|
||||
],
|
||||
"data": [{"name":"alarm.json"}]
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
WIDGETS["alarm"]={area:"tl",width:0,draw:function() {
|
||||
if (this.width) g.reset().drawImage(atob("GBgBAAAAAAAAABgADhhwDDwwGP8YGf+YMf+MM//MM//MA//AA//AA//AA//AA//AA//AB//gD//wD//wAAAAADwAABgAAAAAAAAA"),this.x,this.y);
|
||||
},reload:function() {
|
||||
// don't include library here as we're trying to use as little RAM as possible
|
||||
WIDGETS["alarm"].width = (require('Storage').readJSON('alarm.json',1)||[]).some(alarm=>alarm.on) ? 24 : 0;
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue