Merge branch 'master' of https://github.com/espruino/BangleApps into compass
# Conflicts: # apps/compass/compass.jsmaster
commit
3cdd0f7820
37
apps.json
37
apps.json
|
|
@ -137,7 +137,7 @@
|
||||||
"name": "Default Alarm",
|
"name": "Default Alarm",
|
||||||
"shortName":"Alarms",
|
"shortName":"Alarms",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.07",
|
"version":"0.08",
|
||||||
"description": "Set and respond to alarms",
|
"description": "Set and respond to alarms",
|
||||||
"tags": "tool,alarm,widget",
|
"tags": "tool,alarm,widget",
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -280,7 +280,7 @@
|
||||||
{ "id": "gpstime",
|
{ "id": "gpstime",
|
||||||
"name": "GPS Time",
|
"name": "GPS Time",
|
||||||
"icon": "gpstime.png",
|
"icon": "gpstime.png",
|
||||||
"version":"0.03",
|
"version":"0.04",
|
||||||
"description": "Update the Bangle.js's clock based on the time from the GPS receiver",
|
"description": "Update the Bangle.js's clock based on the time from the GPS receiver",
|
||||||
"tags": "tool,gps",
|
"tags": "tool,gps",
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -303,7 +303,7 @@
|
||||||
{ "id": "speedo",
|
{ "id": "speedo",
|
||||||
"name": "Speedo",
|
"name": "Speedo",
|
||||||
"icon": "speedo.png",
|
"icon": "speedo.png",
|
||||||
"version":"0.03",
|
"version":"0.04",
|
||||||
"description": "Show the current speed according to the GPS",
|
"description": "Show the current speed according to the GPS",
|
||||||
"tags": "tool,outdoors,gps",
|
"tags": "tool,outdoors,gps",
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -888,7 +888,7 @@
|
||||||
{ "id": "berlinc",
|
{ "id": "berlinc",
|
||||||
"name": "Berlin Clock",
|
"name": "Berlin Clock",
|
||||||
"icon": "berlin-clock.png",
|
"icon": "berlin-clock.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "Berlin Clock (see https://en.wikipedia.org/wiki/Mengenlehreuhr)",
|
"description": "Berlin Clock (see https://en.wikipedia.org/wiki/Mengenlehreuhr)",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
|
|
@ -1727,7 +1727,7 @@
|
||||||
{ "id": "rndmclk",
|
{ "id": "rndmclk",
|
||||||
"name": "Random Clock Loader",
|
"name": "Random Clock Loader",
|
||||||
"icon": "rndmclk.png",
|
"icon": "rndmclk.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "Load a different clock whenever the LCD is switched on.",
|
"description": "Load a different clock whenever the LCD is switched on.",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"tags": "widget,clock",
|
"tags": "widget,clock",
|
||||||
|
|
@ -1774,5 +1774,32 @@
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"widviz.wid.js","url":"widget.js"}
|
{"name":"widviz.wid.js","url":"widget.js"}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{ "id": "binclock",
|
||||||
|
"name": "Binary Clock",
|
||||||
|
"shortName":"Binary Clock",
|
||||||
|
"icon": "app.png",
|
||||||
|
"version":"0.02",
|
||||||
|
"description": "A binary clock with hours and minutes. BTN1 toggles a digital clock.",
|
||||||
|
"tags": "clock,binary",
|
||||||
|
"type": "clock",
|
||||||
|
"storage": [
|
||||||
|
{"name":"binclock.app.js","url":"app.js"},
|
||||||
|
{"name":"binclock.img","url":"app-icon.js","evaluate":true}
|
||||||
|
]
|
||||||
|
} ,
|
||||||
|
{
|
||||||
|
"id": "pizzatimer",
|
||||||
|
"name": "Pizza Timer",
|
||||||
|
"shortName":"Pizza Timer",
|
||||||
|
"icon": "pizza.png",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "A timer app for when you cook Pizza. Some say it can also time other things",
|
||||||
|
"tags": "timer,tool,pizza",
|
||||||
|
"readme": "README.md",
|
||||||
|
"storage": [
|
||||||
|
{"name":"pizzatimer.app.js","url":"app.js"},
|
||||||
|
{"name":"pizzatimer.img","url":"app-icon.js","evaluate":true}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,159 @@
|
||||||
|
{
|
||||||
|
"env": {
|
||||||
|
// TODO: "espruino": false
|
||||||
|
// TODO: "banglejs": false
|
||||||
|
},
|
||||||
|
"extends": "eslint:recommended",
|
||||||
|
"globals": {
|
||||||
|
// Methods and Fields at https://banglejs.com/reference
|
||||||
|
"Array": "readonly",
|
||||||
|
"ArrayBuffer": "readonly",
|
||||||
|
"ArrayBufferView": "readonly",
|
||||||
|
"Bangle": "readonly",
|
||||||
|
"BluetoothDevice": "readonly",
|
||||||
|
"BluetoothRemoteGATTCharacteristic": "readonly",
|
||||||
|
"BluetoothRemoteGATTServer": "readonly",
|
||||||
|
"BluetoothRemoteGATTService": "readonly",
|
||||||
|
"Boolean": "readonly",
|
||||||
|
"console": "readonly",
|
||||||
|
"DataView": "readonly",
|
||||||
|
"Date": "readonly",
|
||||||
|
"E": "readonly",
|
||||||
|
"Error": "readonly",
|
||||||
|
"Flash": "readonly",
|
||||||
|
"Float32Array": "readonly",
|
||||||
|
"Float64Array": "readonly",
|
||||||
|
"fs": "readonly",
|
||||||
|
"Function": "readonly",
|
||||||
|
"Graphics": "readonly",
|
||||||
|
"heatshrink": "readonly",
|
||||||
|
"I2C": "readonly",
|
||||||
|
"Int16Array": "readonly",
|
||||||
|
"Int32Array": "readonly",
|
||||||
|
"Int8Array": "readonly",
|
||||||
|
"InternalError": "readonly",
|
||||||
|
"JSON": "readonly",
|
||||||
|
"Math": "readonly",
|
||||||
|
"Modules": "readonly",
|
||||||
|
"NRF": "readonly",
|
||||||
|
"Number": "readonly",
|
||||||
|
"Object": "readonly",
|
||||||
|
"OneWire": "readonly",
|
||||||
|
"Pin": "readonly",
|
||||||
|
"process": "readonly",
|
||||||
|
"Promise": "readonly",
|
||||||
|
"ReferenceError": "readonly",
|
||||||
|
"RegExp": "readonly",
|
||||||
|
"Serial": "readonly",
|
||||||
|
"SPI": "readonly",
|
||||||
|
"Storage": "readonly",
|
||||||
|
"StorageFile": "readonly",
|
||||||
|
"String": "readonly",
|
||||||
|
"SyntaxError": "readonly",
|
||||||
|
"tensorflow": "readonly",
|
||||||
|
"TFMicroInterpreter": "readonly",
|
||||||
|
"TypeError": "readonly",
|
||||||
|
"Uint16Array": "readonly",
|
||||||
|
"Uint24Array": "readonly",
|
||||||
|
"Uint32Array": "readonly",
|
||||||
|
"Uint8Array": "readonly",
|
||||||
|
"Uint8ClampedArray": "readonly",
|
||||||
|
"Waveform": "readonly",
|
||||||
|
// Methods and Fields at https://banglejs.com/reference
|
||||||
|
"analogRead": "readonly",
|
||||||
|
"analogWrite": "readonly",
|
||||||
|
"arguments": "readonly",
|
||||||
|
"atob": "readonly",
|
||||||
|
"Bluetooth": "readonly",
|
||||||
|
"BTN": "readonly",
|
||||||
|
"BTN1": "readonly",
|
||||||
|
"BTN2": "readonly",
|
||||||
|
"BTN3": "readonly",
|
||||||
|
"BTN4": "readonly",
|
||||||
|
"BTN5": "readonly",
|
||||||
|
"btoa": "readonly",
|
||||||
|
"changeInterval": "readonly",
|
||||||
|
"clearInterval": "readonly",
|
||||||
|
"clearTimeout": "readonly",
|
||||||
|
"clearWatch": "readonly",
|
||||||
|
"decodeURIComponent": "readonly",
|
||||||
|
"digitalPulse": "readonly",
|
||||||
|
"digitalRead": "readonly",
|
||||||
|
"digitalWrite": "readonly",
|
||||||
|
"dump": "readonly",
|
||||||
|
"echo": "readonly",
|
||||||
|
"edit": "readonly",
|
||||||
|
"encodeURIComponent": "readonly",
|
||||||
|
"eval": "readonly",
|
||||||
|
"getPinMode": "readonly",
|
||||||
|
"getSerial": "readonly",
|
||||||
|
"getTime": "readonly",
|
||||||
|
"global": "readonly",
|
||||||
|
"HIGH": "readonly",
|
||||||
|
"I2C1": "readonly",
|
||||||
|
"Infinity": "readonly",
|
||||||
|
"isFinite": "readonly",
|
||||||
|
"isNaN": "readonly",
|
||||||
|
"LED": "readonly",
|
||||||
|
"LED1": "readonly",
|
||||||
|
"LED2": "readonly",
|
||||||
|
"load": "readonly",
|
||||||
|
"LoopbackA": "readonly",
|
||||||
|
"LoopbackB": "readonly",
|
||||||
|
"LOW": "readonly",
|
||||||
|
"NaN": "readonly",
|
||||||
|
"parseFloat": "readonly",
|
||||||
|
"parseInt": "readonly",
|
||||||
|
"peek16": "readonly",
|
||||||
|
"peek32": "readonly",
|
||||||
|
"peek8": "readonly",
|
||||||
|
"pinMode": "readonly",
|
||||||
|
"poke16": "readonly",
|
||||||
|
"poke32": "readonly",
|
||||||
|
"poke8": "readonly",
|
||||||
|
"print": "readonly",
|
||||||
|
"require": "readonly",
|
||||||
|
"reset": "readonly",
|
||||||
|
"save": "readonly",
|
||||||
|
"Serial1": "readonly",
|
||||||
|
"setBusyIndicator": "readonly",
|
||||||
|
"setInterval": "readonly",
|
||||||
|
"setSleepIndicator": "readonly",
|
||||||
|
"setTime": "readonly",
|
||||||
|
"setTimeout": "readonly",
|
||||||
|
"setWatch": "readonly",
|
||||||
|
"shiftOut": "readonly",
|
||||||
|
"SPI1": "readonly",
|
||||||
|
"Terminal": "readonly",
|
||||||
|
"trace": "readonly",
|
||||||
|
"VIBRATE": "readonly",
|
||||||
|
// Aliases and not defined at https://banglejs.com/reference
|
||||||
|
"g": "readonly",
|
||||||
|
"WIDGETS": "readonly"
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 11
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"indent": [
|
||||||
|
"warn",
|
||||||
|
2,
|
||||||
|
{
|
||||||
|
"SwitchCase": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"no-case-declarations": "off",
|
||||||
|
"no-constant-condition": "off",
|
||||||
|
"no-delete-var": "off",
|
||||||
|
"no-empty": "off",
|
||||||
|
"no-global-assign": "off",
|
||||||
|
"no-inner-declarations": "off",
|
||||||
|
"no-octal": "off",
|
||||||
|
"no-prototype-builtins": "off",
|
||||||
|
"no-redeclare": "off",
|
||||||
|
// TODO: "no-undef": "warn",
|
||||||
|
"no-undef": "off",
|
||||||
|
"no-unused-vars": "off",
|
||||||
|
"no-useless-escape": "off"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,19 +1,19 @@
|
||||||
(() => {
|
(() => {
|
||||||
|
|
||||||
//Graph module, as long as modules are not added by the app loader
|
//Graph module, as long as modules are not added by the app loader
|
||||||
Modules.addCached("graph",function(){exports.drawAxes=function(b,c,a){function h(a){return e+m*(a-t)/x}function l(a){return f+g-g*(a-n)/u}var k=a.padx||0,d=a.pady||0,t=-k,w=c.length+k-1,n=(void 0!==a.miny?a.miny:a.miny=c.reduce(function(a,b){return Math.min(a,b)},c[0]))-d;c=(void 0!==a.maxy?a.maxy:a.maxy=c.reduce(function(a,b){return Math.max(a,b)},c[0]))+d;a.gridy&&(d=a.gridy,n=d*Math.floor(n/d),c=d*Math.ceil(c/d));var e=a.x||0,f=a.y||0,m=a.width||b.getWidth()-(e+1),g=a.height||b.getHeight()-(f+1);a.axes&&(null!==a.ylabel&&
|
Modules.addCached("graph",function(){exports.drawAxes=function(b,c,a){function h(a){return e+m*(a-t)/x}function l(a){return f+g-g*(a-n)/u}var k=a.padx||0,d=a.pady||0,t=-k,w=c.length+k-1,n=(void 0!==a.miny?a.miny:a.miny=c.reduce(function(a,b){return Math.min(a,b)},c[0]))-d;c=(void 0!==a.maxy?a.maxy:a.maxy=c.reduce(function(a,b){return Math.max(a,b)},c[0]))+d;a.gridy&&(d=a.gridy,n=d*Math.floor(n/d),c=d*Math.ceil(c/d));var e=a.x||0,f=a.y||0,m=a.width||b.getWidth()-(e+1),g=a.height||b.getHeight()-(f+1);a.axes&&(null!==a.ylabel&&
|
||||||
(e+=6,m-=6),null!==a.xlabel&&(g-=6));a.title&&(f+=6,g-=6);a.axes&&(b.drawLine(e,f,e,f+g),b.drawLine(e,f+g,e+m,f+g));a.title&&(b.setFontAlign(0,-1),b.drawString(a.title,e+m/2,f-6));var x=w-t,u=c-n;u||(u=1);if(a.gridx){b.setFontAlign(0,-1,0);var v=a.gridx;for(d=Math.ceil((t+k)/v)*v;d<=w-k;d+=v){var r=h(d),p=a.xlabel?a.xlabel(d):d;b.setPixel(r,f+g-1);var q=b.stringWidth(p)/2;null!==a.xlabel&&r>q&&b.getWidth()>r+q&&b.drawString(p,r,f+g+2)}}if(a.gridy)for(b.setFontAlign(0,0,1),d=n;d<=c;d+=a.gridy)k=l(d),
|
(e+=6,m-=6),null!==a.xlabel&&(g-=6));a.title&&(f+=6,g-=6);a.axes&&(b.drawLine(e,f,e,f+g),b.drawLine(e,f+g,e+m,f+g));a.title&&(b.setFontAlign(0,-1),b.drawString(a.title,e+m/2,f-6));var x=w-t,u=c-n;u||(u=1);if(a.gridx){b.setFontAlign(0,-1,0);var v=a.gridx;for(d=Math.ceil((t+k)/v)*v;d<=w-k;d+=v){var r=h(d),p=a.xlabel?a.xlabel(d):d;b.setPixel(r,f+g-1);var q=b.stringWidth(p)/2;null!==a.xlabel&&r>q&&b.getWidth()>r+q&&b.drawString(p,r,f+g+2)}}if(a.gridy)for(b.setFontAlign(0,0,1),d=n;d<=c;d+=a.gridy)k=l(d),
|
||||||
p=a.ylabel?a.ylabel(d):d,b.setPixel(e+1,k),q=b.stringWidth(p)/2,null!==a.ylabel&&k>q&&b.getHeight()>k+q&&b.drawString(p,e-5,k+1);b.setFontAlign(-1,-1,0);return{x:e,y:f,w:m,h:g,getx:h,gety:l}};exports.drawLine=function(b,c,a){a=a||{};a=exports.drawAxes(b,c,a);var h=!0,l;for(l in c)h?b.moveTo(a.getx(l),a.gety(c[l])):b.lineTo(a.getx(l),a.gety(c[l])),h=!1;return a};exports.drawBar=function(b,c,a){a=a||{};a.padx=1;a=exports.drawAxes(b,c,a);for(var h in c)b.fillRect(a.getx(h-.5)+1,a.gety(c[h]),a.getx(h+
|
p=a.ylabel?a.ylabel(d):d,b.setPixel(e+1,k),q=b.stringWidth(p)/2,null!==a.ylabel&&k>q&&b.getHeight()>k+q&&b.drawString(p,e-5,k+1);b.setFontAlign(-1,-1,0);return{x:e,y:f,w:m,h:g,getx:h,gety:l}};exports.drawLine=function(b,c,a){a=a||{};a=exports.drawAxes(b,c,a);var h=!0,l;for(l in c)h?b.moveTo(a.getx(l),a.gety(c[l])):b.lineTo(a.getx(l),a.gety(c[l])),h=!1;return a};exports.drawBar=function(b,c,a){a=a||{};a.padx=1;a=exports.drawAxes(b,c,a);for(var h in c)b.fillRect(a.getx(h-.5)+1,a.gety(c[h]),a.getx(h+
|
||||||
.5)-1,a.gety(0));return a}});
|
.5)-1,a.gety(0));return a}});
|
||||||
|
|
||||||
const storage = require("Storage");
|
const storage = require("Storage");
|
||||||
const SETTINGS_FILE = 'activepedom.settings.json';
|
const SETTINGS_FILE = 'activepedom.settings.json';
|
||||||
var history = 86400000; // 28800000=8h 43200000=12h //86400000=24h
|
var history = 86400000; // 28800000=8h 43200000=12h //86400000=24h
|
||||||
|
|
||||||
//return setting
|
//return setting
|
||||||
function setting(key) {
|
function setting(key) {
|
||||||
//define default settings
|
//define default settings
|
||||||
const DEFAULTS = {
|
const DEFAULTS = {
|
||||||
'cMaxTime' : 1100,
|
'cMaxTime' : 1100,
|
||||||
'cMinTime' : 240,
|
'cMinTime' : 240,
|
||||||
'stepThreshold' : 30,
|
'stepThreshold' : 30,
|
||||||
|
|
@ -21,13 +21,13 @@ const DEFAULTS = {
|
||||||
'stepSensitivity' : 80,
|
'stepSensitivity' : 80,
|
||||||
'stepGoal' : 10000,
|
'stepGoal' : 10000,
|
||||||
'stepLength' : 75,
|
'stepLength' : 75,
|
||||||
};
|
};
|
||||||
if (!settings) { loadSettings(); }
|
if (!settings) { loadSettings(); }
|
||||||
return (key in settings) ? settings[key] : DEFAULTS[key];
|
return (key in settings) ? settings[key] : DEFAULTS[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
//Convert ms to time
|
//Convert ms to time
|
||||||
function getTime(t) {
|
function getTime(t) {
|
||||||
date = new Date(t);
|
date = new Date(t);
|
||||||
offset = date.getTimezoneOffset() / 60;
|
offset = date.getTimezoneOffset() / 60;
|
||||||
//var milliseconds = parseInt((t % 1000) / 100),
|
//var milliseconds = parseInt((t % 1000) / 100),
|
||||||
|
|
@ -39,9 +39,9 @@ function getTime(t) {
|
||||||
minutes = (minutes < 10) ? "0" + minutes : minutes;
|
minutes = (minutes < 10) ? "0" + minutes : minutes;
|
||||||
seconds = (seconds < 10) ? "0" + seconds : seconds;
|
seconds = (seconds < 10) ? "0" + seconds : seconds;
|
||||||
return hours + ":" + minutes + ":" + seconds;
|
return hours + ":" + minutes + ":" + seconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDate(t) {
|
function getDate(t) {
|
||||||
date = new Date(t*1);
|
date = new Date(t*1);
|
||||||
year = date.getFullYear();
|
year = date.getFullYear();
|
||||||
month = date.getMonth()+1; //month is zero-based
|
month = date.getMonth()+1; //month is zero-based
|
||||||
|
|
@ -49,10 +49,10 @@ function getDate(t) {
|
||||||
month = (month < 10) ? "0" + month : month;
|
month = (month < 10) ? "0" + month : month;
|
||||||
day = (day < 10) ? "0" + day : day;
|
day = (day < 10) ? "0" + day : day;
|
||||||
return year + "-" + month + "-" + day;
|
return year + "-" + month + "-" + day;
|
||||||
}
|
}
|
||||||
|
|
||||||
//columns: 0=time, 1=stepsCounted, 2=active, 3=stepsTooShort, 4=stepsTooLong, 5=stepsOutsideTime
|
//columns: 0=time, 1=stepsCounted, 2=active, 3=stepsTooShort, 4=stepsTooLong, 5=stepsOutsideTime
|
||||||
function getArrayFromCSV(file, column) {
|
function getArrayFromCSV(file, column) {
|
||||||
i = 0;
|
i = 0;
|
||||||
array = [];
|
array = [];
|
||||||
now = new Date();
|
now = new Date();
|
||||||
|
|
@ -67,9 +67,9 @@ function getArrayFromCSV(file, column) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawGraph() {
|
function drawGraph() {
|
||||||
//times
|
//times
|
||||||
// actives = getArrayFromCSV(csvFile, 2);
|
// actives = getArrayFromCSV(csvFile, 2);
|
||||||
// shorts = getArrayFromCSV(csvFile, 3);
|
// shorts = getArrayFromCSV(csvFile, 3);
|
||||||
|
|
@ -115,16 +115,16 @@ function drawGraph() {
|
||||||
allDataFile = undefined;
|
allDataFile = undefined;
|
||||||
csvFile = undefined;
|
csvFile = undefined;
|
||||||
times = undefined;
|
times = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawMenu () {
|
function drawMenu () {
|
||||||
g.clear();
|
g.clear();
|
||||||
g.setFont("6x8", 1);
|
g.setFont("6x8", 1);
|
||||||
g.drawString("BTN1:Timespan | BTN2:Draw", 20, 10);
|
g.drawString("BTN1:Timespan | BTN2:Draw", 20, 10);
|
||||||
g.drawString("Timespan: " + history/1000/60/60 + " hours", 20, 20);
|
g.drawString("Timespan: " + history/1000/60/60 + " hours", 20, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
setWatch(function() { //BTN1
|
setWatch(function() { //BTN1
|
||||||
switch(history) {
|
switch(history) {
|
||||||
case 3600000 : //1h
|
case 3600000 : //1h
|
||||||
history = 14400000; //4h
|
history = 14400000; //4h
|
||||||
|
|
@ -137,29 +137,29 @@ setWatch(function() { //BTN1
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
drawMenu();
|
drawMenu();
|
||||||
}, BTN1, {edge:"rising", debounce:50, repeat:true});
|
}, BTN1, {edge:"rising", debounce:50, repeat:true});
|
||||||
|
|
||||||
setWatch(function() { //BTN2
|
setWatch(function() { //BTN2
|
||||||
g.setFont("6x8", 2);
|
g.setFont("6x8", 2);
|
||||||
g.drawString ("Drawing...",30,60);
|
g.drawString ("Drawing...",30,60);
|
||||||
drawGraph();
|
drawGraph();
|
||||||
}, BTN2, {edge:"rising", debounce:50, repeat:true});
|
}, BTN2, {edge:"rising", debounce:50, repeat:true});
|
||||||
|
|
||||||
setWatch(function() { //BTN3
|
setWatch(function() { //BTN3
|
||||||
}, BTN3, {edge:"rising", debounce:50, repeat:true});
|
}, BTN3, {edge:"rising", debounce:50, repeat:true});
|
||||||
|
|
||||||
setWatch(function() { //BTN4
|
setWatch(function() { //BTN4
|
||||||
}, BTN4, {edge:"rising", debounce:50, repeat:true});
|
}, BTN4, {edge:"rising", debounce:50, repeat:true});
|
||||||
|
|
||||||
setWatch(function() { //BTN5
|
setWatch(function() { //BTN5
|
||||||
}, BTN5, {edge:"rising", debounce:50, repeat:true});
|
}, BTN5, {edge:"rising", debounce:50, repeat:true});
|
||||||
|
|
||||||
//load settings
|
//load settings
|
||||||
let settings;
|
let settings;
|
||||||
function loadSettings() {
|
function loadSettings() {
|
||||||
settings = storage.readJSON(SETTINGS_FILE, 1) || {};
|
settings = storage.readJSON(SETTINGS_FILE, 1) || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
drawMenu();
|
drawMenu();
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
@ -5,3 +5,4 @@
|
||||||
0.05: Add alarm.boot.js and move code from the bootloader
|
0.05: Add alarm.boot.js and move code from the bootloader
|
||||||
0.06: Change 'New Alarm' to 'Save', allow Deletion of Alarms
|
0.06: Change 'New Alarm' to 'Save', allow Deletion of Alarms
|
||||||
0.07: Don't overwrite existing settings on app update
|
0.07: Don't overwrite existing settings on app update
|
||||||
|
0.08: Make alarm scheduling more reliable
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,16 @@
|
||||||
(function() {
|
(function() {
|
||||||
var alarms = require('Storage').readJSON('alarm.json',1)||[];
|
var alarms = require('Storage').readJSON('alarm.json',1)||[];
|
||||||
var time = new Date();
|
var time = new Date();
|
||||||
var active = alarms.filter(a=>a.on&&(a.last!=time.getDate()));
|
var active = alarms.filter(a=>a.on);
|
||||||
if (active.length) {
|
if (active.length) {
|
||||||
active = active.sort((a,b)=>a.hr-b.hr);
|
active = active.sort((a,b)=>(a.hr-b.hr)+(a.last-b.last)*24);
|
||||||
var hr = time.getHours()+(time.getMinutes()/60)+(time.getSeconds()/3600);
|
var hr = time.getHours()+(time.getMinutes()/60)+(time.getSeconds()/3600);
|
||||||
if (!require('Storage').read("alarm.js")) {
|
if (!require('Storage').read("alarm.js")) {
|
||||||
console.log("No alarm app!");
|
console.log("No alarm app!");
|
||||||
require('Storage').write('alarm.json',"[]")
|
require('Storage').write('alarm.json',"[]");
|
||||||
} else {
|
} else {
|
||||||
var t = 3600000*(active[0].hr-hr);
|
var t = 3600000*(active[0].hr-hr);
|
||||||
|
if (active[0].last == time.getDate() || t < 0) t += 86400000;
|
||||||
if (t<1000) t=1000;
|
if (t<1000) t=1000;
|
||||||
/* execute alarm at the correct time. We avoid execing immediately
|
/* execute alarm at the correct time. We avoid execing immediately
|
||||||
since this code will get called AGAIN when alarm.js is loaded. alarm.js
|
since this code will get called AGAIN when alarm.js is loaded. alarm.js
|
||||||
|
|
@ -21,4 +22,4 @@
|
||||||
},t);
|
},t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})()
|
})();
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@
|
||||||
|
|
||||||
(function () { 'use strict';
|
(function () { 'use strict';
|
||||||
|
|
||||||
// shortcuts for easier to read formulas
|
// shortcuts for easier to read formulas
|
||||||
|
|
||||||
var PI = Math.PI,
|
var PI = Math.PI,
|
||||||
sin = Math.sin,
|
sin = Math.sin,
|
||||||
cos = Math.cos,
|
cos = Math.cos,
|
||||||
tan = Math.tan,
|
tan = Math.tan,
|
||||||
|
|
@ -17,54 +17,54 @@ var PI = Math.PI,
|
||||||
acos = Math.acos,
|
acos = Math.acos,
|
||||||
rad = PI / 180;
|
rad = PI / 180;
|
||||||
|
|
||||||
// sun calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas
|
// sun calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas
|
||||||
|
|
||||||
|
|
||||||
// date/time constants and conversions
|
// date/time constants and conversions
|
||||||
|
|
||||||
var dayMs = 1000 * 60 * 60 * 24,
|
var dayMs = 1000 * 60 * 60 * 24,
|
||||||
J1970 = 2440588,
|
J1970 = 2440588,
|
||||||
J2000 = 2451545;
|
J2000 = 2451545;
|
||||||
|
|
||||||
function toJulian(date) { return date.valueOf() / dayMs - 0.5 + J1970; }
|
function toJulian(date) { return date.valueOf() / dayMs - 0.5 + J1970; }
|
||||||
function fromJulian(j) { return (j + 0.5 - J1970) * dayMs; }
|
function fromJulian(j) { return (j + 0.5 - J1970) * dayMs; }
|
||||||
function toDays(date) { return toJulian(date) - J2000; }
|
function toDays(date) { return toJulian(date) - J2000; }
|
||||||
|
|
||||||
|
|
||||||
// general calculations for position
|
// general calculations for position
|
||||||
|
|
||||||
var e = rad * 23.4397; // obliquity of the Earth
|
var e = rad * 23.4397; // obliquity of the Earth
|
||||||
|
|
||||||
function rightAscension(l, b) { return atan(sin(l) * cos(e) - tan(b) * sin(e), cos(l)); }
|
function rightAscension(l, b) { return atan(sin(l) * cos(e) - tan(b) * sin(e), cos(l)); }
|
||||||
function declination(l, b) { return asin(sin(b) * cos(e) + cos(b) * sin(e) * sin(l)); }
|
function declination(l, b) { return asin(sin(b) * cos(e) + cos(b) * sin(e) * sin(l)); }
|
||||||
|
|
||||||
function azimuth(H, phi, dec) { return atan(sin(H), cos(H) * sin(phi) - tan(dec) * cos(phi)); }
|
function azimuth(H, phi, dec) { return atan(sin(H), cos(H) * sin(phi) - tan(dec) * cos(phi)); }
|
||||||
function altitude(H, phi, dec) { return asin(sin(phi) * sin(dec) + cos(phi) * cos(dec) * cos(H)); }
|
function altitude(H, phi, dec) { return asin(sin(phi) * sin(dec) + cos(phi) * cos(dec) * cos(H)); }
|
||||||
|
|
||||||
function siderealTime(d, lw) { return rad * (280.16 + 360.9856235 * d) - lw; }
|
function siderealTime(d, lw) { return rad * (280.16 + 360.9856235 * d) - lw; }
|
||||||
|
|
||||||
function astroRefraction(h) {
|
function astroRefraction(h) {
|
||||||
if (h < 0) // the following formula works for positive altitudes only.
|
if (h < 0) // the following formula works for positive altitudes only.
|
||||||
h = 0; // if h = -0.08901179 a div/0 would occur.
|
h = 0; // if h = -0.08901179 a div/0 would occur.
|
||||||
|
|
||||||
// formula 16.4 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
|
// formula 16.4 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
|
||||||
// 1.02 / tan(h + 10.26 / (h + 5.10)) h in degrees, result in arc minutes -> converted to rad:
|
// 1.02 / tan(h + 10.26 / (h + 5.10)) h in degrees, result in arc minutes -> converted to rad:
|
||||||
return 0.0002967 / Math.tan(h + 0.00312536 / (h + 0.08901179));
|
return 0.0002967 / Math.tan(h + 0.00312536 / (h + 0.08901179));
|
||||||
}
|
}
|
||||||
|
|
||||||
// general sun calculations
|
// general sun calculations
|
||||||
|
|
||||||
function solarMeanAnomaly(d) { return rad * (357.5291 + 0.98560028 * d); }
|
function solarMeanAnomaly(d) { return rad * (357.5291 + 0.98560028 * d); }
|
||||||
|
|
||||||
function eclipticLongitude(M) {
|
function eclipticLongitude(M) {
|
||||||
|
|
||||||
var C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center
|
var C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center
|
||||||
P = rad * 102.9372; // perihelion of the Earth
|
P = rad * 102.9372; // perihelion of the Earth
|
||||||
|
|
||||||
return M + C + P + PI;
|
return M + C + P + PI;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sunCoords(d) {
|
function sunCoords(d) {
|
||||||
|
|
||||||
var M = solarMeanAnomaly(d),
|
var M = solarMeanAnomaly(d),
|
||||||
L = eclipticLongitude(M);
|
L = eclipticLongitude(M);
|
||||||
|
|
@ -73,15 +73,15 @@ function sunCoords(d) {
|
||||||
dec: declination(L, 0),
|
dec: declination(L, 0),
|
||||||
ra: rightAscension(L, 0)
|
ra: rightAscension(L, 0)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var SunCalc = {};
|
var SunCalc = {};
|
||||||
|
|
||||||
|
|
||||||
// calculates sun position for a given date and latitude/longitude
|
// calculates sun position for a given date and latitude/longitude
|
||||||
|
|
||||||
SunCalc.getPosition = function (date, lat, lng) {
|
SunCalc.getPosition = function (date, lat, lng) {
|
||||||
|
|
||||||
var lw = rad * -lng,
|
var lw = rad * -lng,
|
||||||
phi = rad * lat,
|
phi = rad * lat,
|
||||||
|
|
@ -94,52 +94,52 @@ SunCalc.getPosition = function (date, lat, lng) {
|
||||||
azimuth: azimuth(H, phi, c.dec),
|
azimuth: azimuth(H, phi, c.dec),
|
||||||
altitude: altitude(H, phi, c.dec)
|
altitude: altitude(H, phi, c.dec)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// sun times configuration (angle, morning name, evening name)
|
// sun times configuration (angle, morning name, evening name)
|
||||||
|
|
||||||
var times = SunCalc.times = [
|
var times = SunCalc.times = [
|
||||||
[-0.833, 'sunrise', 'sunset' ],
|
[-0.833, 'sunrise', 'sunset' ],
|
||||||
[ -0.3, 'sunriseEnd', 'sunsetStart' ],
|
[ -0.3, 'sunriseEnd', 'sunsetStart' ],
|
||||||
[ -6, 'dawn', 'dusk' ],
|
[ -6, 'dawn', 'dusk' ],
|
||||||
[ -12, 'nauticalDawn', 'nauticalDusk'],
|
[ -12, 'nauticalDawn', 'nauticalDusk'],
|
||||||
[ -18, 'nightEnd', 'night' ],
|
[ -18, 'nightEnd', 'night' ],
|
||||||
[ 6, 'goldenHourEnd', 'goldenHour' ]
|
[ 6, 'goldenHourEnd', 'goldenHour' ]
|
||||||
];
|
];
|
||||||
|
|
||||||
// adds a custom time to the times config
|
// adds a custom time to the times config
|
||||||
|
|
||||||
SunCalc.addTime = function (angle, riseName, setName) {
|
SunCalc.addTime = function (angle, riseName, setName) {
|
||||||
times.push([angle, riseName, setName]);
|
times.push([angle, riseName, setName]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// calculations for sun times
|
// calculations for sun times
|
||||||
|
|
||||||
var J0 = 0.0009;
|
var J0 = 0.0009;
|
||||||
|
|
||||||
function julianCycle(d, lw) { return Math.round(d - J0 - lw / (2 * PI)); }
|
function julianCycle(d, lw) { return Math.round(d - J0 - lw / (2 * PI)); }
|
||||||
|
|
||||||
function approxTransit(Ht, lw, n) { return J0 + (Ht + lw) / (2 * PI) + n; }
|
function approxTransit(Ht, lw, n) { return J0 + (Ht + lw) / (2 * PI) + n; }
|
||||||
function solarTransitJ(ds, M, L) { return J2000 + ds + 0.0053 * sin(M) - 0.0069 * sin(2 * L); }
|
function solarTransitJ(ds, M, L) { return J2000 + ds + 0.0053 * sin(M) - 0.0069 * sin(2 * L); }
|
||||||
|
|
||||||
function hourAngle(h, phi, d) { return acos((sin(h) - sin(phi) * sin(d)) / (cos(phi) * cos(d))); }
|
function hourAngle(h, phi, d) { return acos((sin(h) - sin(phi) * sin(d)) / (cos(phi) * cos(d))); }
|
||||||
function observerAngle(height) { return -2.076 * Math.sqrt(height) / 60; }
|
function observerAngle(height) { return -2.076 * Math.sqrt(height) / 60; }
|
||||||
|
|
||||||
// returns set time for the given sun altitude
|
// returns set time for the given sun altitude
|
||||||
function getSetJ(h, lw, phi, dec, n, M, L) {
|
function getSetJ(h, lw, phi, dec, n, M, L) {
|
||||||
|
|
||||||
var w = hourAngle(h, phi, dec),
|
var w = hourAngle(h, phi, dec),
|
||||||
a = approxTransit(w, lw, n);
|
a = approxTransit(w, lw, n);
|
||||||
return solarTransitJ(a, M, L);
|
return solarTransitJ(a, M, L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// calculates sun times for a given date, latitude/longitude, and, optionally,
|
// calculates sun times for a given date, latitude/longitude, and, optionally,
|
||||||
// the observer height (in meters) relative to the horizon
|
// the observer height (in meters) relative to the horizon
|
||||||
|
|
||||||
SunCalc.getTimes = function (date, lat, lng, height) {
|
SunCalc.getTimes = function (date, lat, lng, height) {
|
||||||
|
|
||||||
height = height || 0;
|
height = height || 0;
|
||||||
|
|
||||||
|
|
@ -178,12 +178,12 @@ SunCalc.getTimes = function (date, lat, lng, height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// moon calculations, based on http://aa.quae.nl/en/reken/hemelpositie.html formulas
|
// moon calculations, based on http://aa.quae.nl/en/reken/hemelpositie.html formulas
|
||||||
|
|
||||||
function moonCoords(d) { // geocentric ecliptic coordinates of the moon
|
function moonCoords(d) { // geocentric ecliptic coordinates of the moon
|
||||||
|
|
||||||
var L = rad * (218.316 + 13.176396 * d), // ecliptic longitude
|
var L = rad * (218.316 + 13.176396 * d), // ecliptic longitude
|
||||||
M = rad * (134.963 + 13.064993 * d), // mean anomaly
|
M = rad * (134.963 + 13.064993 * d), // mean anomaly
|
||||||
|
|
@ -198,9 +198,9 @@ function moonCoords(d) { // geocentric ecliptic coordinates of the moon
|
||||||
dec: declination(l, b),
|
dec: declination(l, b),
|
||||||
dist: dt
|
dist: dt
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
SunCalc.getMoonPosition = function (date, lat, lng) {
|
SunCalc.getMoonPosition = function (date, lat, lng) {
|
||||||
|
|
||||||
var lw = rad * -lng,
|
var lw = rad * -lng,
|
||||||
phi = rad * lat,
|
phi = rad * lat,
|
||||||
|
|
@ -220,16 +220,16 @@ SunCalc.getMoonPosition = function (date, lat, lng) {
|
||||||
distance: c.dist,
|
distance: c.dist,
|
||||||
parallacticAngle: pa
|
parallacticAngle: pa
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// calculations for illumination parameters of the moon,
|
// calculations for illumination parameters of the moon,
|
||||||
// based on http://idlastro.gsfc.nasa.gov/ftp/pro/astro/mphase.pro formulas and
|
// based on http://idlastro.gsfc.nasa.gov/ftp/pro/astro/mphase.pro formulas and
|
||||||
// Chapter 48 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
|
// Chapter 48 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
|
||||||
|
|
||||||
// Function updated from gist: https://gist.github.com/endel/dfe6bb2fbe679781948c
|
// Function updated from gist: https://gist.github.com/endel/dfe6bb2fbe679781948c
|
||||||
|
|
||||||
SunCalc.getMoonIllumination = function (date) {
|
SunCalc.getMoonIllumination = function (date) {
|
||||||
let month = date.getMonth();
|
let month = date.getMonth();
|
||||||
let year = date.getFullYear();
|
let year = date.getFullYear();
|
||||||
let day = date.getDate();
|
let day = date.getDate();
|
||||||
|
|
@ -256,16 +256,16 @@ SunCalc.getMoonIllumination = function (date) {
|
||||||
if (b >= 8) b = 0; // 0 and 8 are the same so turn 8 into 0
|
if (b >= 8) b = 0; // 0 and 8 are the same so turn 8 into 0
|
||||||
|
|
||||||
return {phase: b};
|
return {phase: b};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function hoursLater(date, h) {
|
function hoursLater(date, h) {
|
||||||
return new Date(date.valueOf() + h * dayMs / 24);
|
return new Date(date.valueOf() + h * dayMs / 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculations for moon rise/set times are based on http://www.stargazing.net/kepler/moonrise.html article
|
// calculations for moon rise/set times are based on http://www.stargazing.net/kepler/moonrise.html article
|
||||||
|
|
||||||
SunCalc.getMoonTimes = function (date, lat, lng, inUTC) {
|
SunCalc.getMoonTimes = function (date, lat, lng, inUTC) {
|
||||||
var t = date;
|
var t = date;
|
||||||
if (inUTC) t.setUTCHours(0, 0, 0, 0);
|
if (inUTC) t.setUTCHours(0, 0, 0, 0);
|
||||||
else t.setHours(0, 0, 0, 0);
|
else t.setHours(0, 0, 0, 0);
|
||||||
|
|
@ -317,12 +317,12 @@ SunCalc.getMoonTimes = function (date, lat, lng, inUTC) {
|
||||||
if (!rise && !set) result[ye > 0 ? 'alwaysUp' : 'alwaysDown'] = true;
|
if (!rise && !set) result[ye > 0 ? 'alwaysUp' : 'alwaysDown'] = true;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// export as Node module / AMD module / browser variable
|
// export as Node module / AMD module / browser variable
|
||||||
if (typeof exports === 'object' && typeof module !== 'undefined') module.exports = SunCalc;
|
if (typeof exports === 'object' && typeof module !== 'undefined') module.exports = SunCalc;
|
||||||
else if (typeof define === 'function' && define.amd) define(SunCalc);
|
else if (typeof define === 'function' && define.amd) define(SunCalc);
|
||||||
else global.SunCalc = SunCalc;
|
else global.SunCalc = SunCalc;
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
0.02: Modified for use with new bootloader and firmware
|
0.02: Modified for use with new bootloader and firmware
|
||||||
|
0.03: Shrinked size to avoid cut-off edges on the physical device. BTN3: show date. BTN1: show time in decimal.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
# Berlin Clock Watch Face
|
||||||
|
|
||||||
|
This is a clock-face analogous to the [Berlin Clock](https://en.wikipedia.org/wiki/Mengenlehreuhr).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
* BTN1: toggle displaying the time in decimal figures (24 hour format) in the minutes fields. The first two fields are used for the hour and the last two fields for the minute. This might be a help when you're still familarizig yourself with this new way to express the time.
|
||||||
|
* BTN2: start the launcher
|
||||||
|
* BTN3: toggle displaying the current date (in ISO 8601 format) below the actual clock-face.
|
||||||
|
|
||||||
|
|
@ -1,48 +1,86 @@
|
||||||
// place your const, vars, functions or classes here
|
// Berlin Clock see https://en.wikipedia.org/wiki/Mengenlehreuhr
|
||||||
fields = [ 4 , 4 , 11 , 4 ];
|
// https://github.com/eska-muc/BangleApps
|
||||||
width = g.getWidth();
|
const fields = [4, 4, 11, 4];
|
||||||
height = g.getHeight();
|
const offset = 20;
|
||||||
rowHeight = height/4;
|
const width = g.getWidth() - 2 * offset;
|
||||||
|
const height = g.getHeight() - 2 * offset;
|
||||||
|
const rowHeight = height / 4;
|
||||||
|
|
||||||
|
var show_date = false;
|
||||||
|
var show_time = false;
|
||||||
|
var yy = 0;
|
||||||
|
|
||||||
rowlights = [];
|
rowlights = [];
|
||||||
|
time_digit = [];
|
||||||
|
|
||||||
function drawBerlinClock() {
|
function drawBerlinClock() {
|
||||||
|
g.clear();
|
||||||
var now = new Date();
|
var now = new Date();
|
||||||
|
|
||||||
|
// show date below the clock
|
||||||
|
if (show_date) {
|
||||||
|
var yr = now.getFullYear();
|
||||||
|
var month = now.getMonth() + 1;
|
||||||
|
var day = now.getDate();
|
||||||
|
var dateString = `${yr}-${month < 10 ? '0' : ''}${month}-${day < 10 ? '0' : ''}${day}`;
|
||||||
|
var strWidth = g.stringWidth(dateString);
|
||||||
|
g.setColor(1, 1, 1);
|
||||||
|
g.setFontAlign(-1,-1);
|
||||||
|
g.drawString(dateString, ( g.getWidth() - strWidth ) / 2, height + offset + 4);
|
||||||
|
}
|
||||||
|
|
||||||
rowlights[0] = Math.floor(now.getHours() / 5);
|
rowlights[0] = Math.floor(now.getHours() / 5);
|
||||||
rowlights[1] = now.getHours() % 5;
|
rowlights[1] = now.getHours() % 5;
|
||||||
rowlights[2] = Math.floor(now.getMinutes() / 5);
|
rowlights[2] = Math.floor(now.getMinutes() / 5);
|
||||||
rowlights[3] = now.getMinutes() % 5;
|
rowlights[3] = now.getMinutes() % 5;
|
||||||
|
|
||||||
g.clear();
|
time_digit[0] = Math.floor(now.getHours() / 10);
|
||||||
|
time_digit[1] = now.getHours() % 10;
|
||||||
|
time_digit[2] = Math.floor(now.getMinutes() / 10);
|
||||||
|
time_digit[3] = now.getMinutes() % 10;
|
||||||
|
|
||||||
g.drawRect(0,0,width,height);
|
g.drawRect(offset, offset, width + offset, height + offset);
|
||||||
for (row = 0 ; row < 4 ; row++) {
|
for (row = 0; row < 4; row++) {
|
||||||
nfields = fields[row];
|
nfields = fields[row];
|
||||||
boxWidth = width/nfields;
|
boxWidth = width / nfields;
|
||||||
|
|
||||||
for (col = 0 ; col < nfields ; col++) {
|
for (col = 0; col < nfields; col++) {
|
||||||
x1 = col*boxWidth;
|
x1 = col * boxWidth + offset;
|
||||||
y1 = row*rowHeight;
|
y1 = row * rowHeight + offset;
|
||||||
x2 = (col+1)*boxWidth;
|
x2 = (col + 1) * boxWidth + offset;
|
||||||
y2 = (row+1)*rowHeight;
|
y2 = (row + 1) * rowHeight + offset;
|
||||||
|
|
||||||
|
g.setColor(1, 1, 1);
|
||||||
|
g.drawRect(x1, y1, x2, y2);
|
||||||
|
if (col < rowlights[row]) {
|
||||||
|
if (row === 2) {
|
||||||
|
if (((col + 1) % 3) === 0) {
|
||||||
|
g.setColor(1, 0, 0);
|
||||||
|
} else {
|
||||||
|
g.setColor(1, 1, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
g.setColor(1, 0, 0);
|
||||||
|
}
|
||||||
|
g.fillRect(x1 + 2, y1 + 2, x2 - 2, y2 - 2);
|
||||||
|
}
|
||||||
|
if (row == 3 && show_time) {
|
||||||
g.setColor(1,1,1);
|
g.setColor(1,1,1);
|
||||||
g.drawRect(x1,y1,x2,y2);
|
g.setFontAlign(0,0);
|
||||||
if (col<rowlights[row]) {
|
g.drawString(time_digit[col],(x1+x2)/2,(y1+y2)/2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (row === 2 ) {
|
function toggleDate() {
|
||||||
if (((col+1) % 3) === 0) {
|
show_date = ! show_date;
|
||||||
g.setColor(1,0,0);
|
drawBerlinClock();
|
||||||
} else {
|
}
|
||||||
g.setColor(1,1,0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
g.setColor(1,0,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
g.fillRect(x1+2,y1+2,x2-2,y2-2);
|
function toggleTime() {
|
||||||
}
|
show_time = ! show_time;
|
||||||
}
|
drawBerlinClock();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// special function to handle display switch on
|
// special function to handle display switch on
|
||||||
|
|
@ -52,7 +90,8 @@ Bangle.on('lcdPower', (on) => {
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
// call your app function here
|
// call your app function here
|
||||||
drawBerlinClock();
|
drawBerlinClock();
|
||||||
}});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// refesh every 15 sec
|
// refesh every 15 sec
|
||||||
setInterval(drawBerlinClock, 15E3);
|
setInterval(drawBerlinClock, 15E3);
|
||||||
|
|
@ -61,5 +100,9 @@ g.clear();
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
drawBerlinClock();
|
drawBerlinClock();
|
||||||
|
// Toggle date display, when BTN3 is pressed
|
||||||
|
setWatch(toggleTime,BTN1, { repeat : true, edge: "falling"});
|
||||||
|
// Toggle date display, when BTN3 is pressed
|
||||||
|
setWatch(toggleDate,BTN3, { repeat : true, edge: "falling"});
|
||||||
// Show launcher when middle button pressed
|
// Show launcher when middle button pressed
|
||||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
0.01: New App!
|
||||||
|
0.02: Fixed bug where screen didn't clear so incorrect time displayed.
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEwwkEIf4A/AH8AgP/iAECiIJCj/xAgURBoUAn8gAYMP//wAgIMBBwX//4gCAIUAgf/EIUfC5QEBC5MCI4gNCEIPyAgRGDLQMwBIwEJEAYEFAH7v3dQTpDAZ6cDdIYDPdQbpDAZ8QYgTpDAZ5IEAaYAeM4cRTYSuQiABBiQCBbckjmQzFmcggUzGJkBBoMDQgcSkMAAIIXOgL8CC6gvRL4b2CL4MwTIotJAAJfJiIiCC5RfHF4LdHC4wvGAwIvHL5UDYQIuBF44A/AH4A/AH4AbA"))
|
||||||
|
|
@ -0,0 +1,178 @@
|
||||||
|
// Load fonts
|
||||||
|
require("Font7x11Numeric7Seg").add(Graphics);
|
||||||
|
// position on screen
|
||||||
|
const X = 160, Y = 180;
|
||||||
|
var displayTime = 0;
|
||||||
|
var minuteLED = [0,0,0,0,0,0];
|
||||||
|
var hourLED = [0,0,0,0,0];
|
||||||
|
var prevMinute = [0,0,0,0,0,0];
|
||||||
|
var prevHour = [0,0,0,0,0];
|
||||||
|
|
||||||
|
|
||||||
|
function drawTime(d) {
|
||||||
|
// work out how to display the current time
|
||||||
|
var h = d.getHours(), m = d.getMinutes();
|
||||||
|
var time = (" "+h).substr(-2) + ":" + ("0"+m).substr(-2);
|
||||||
|
// draw the current time (4x size 7 segment)
|
||||||
|
g.setFont("7x11Numeric7Seg",4);
|
||||||
|
g.setFontAlign(1,1); // align right bottom
|
||||||
|
g.drawString(time, X, Y, true /*clear background*/);
|
||||||
|
// draw the seconds (2x size 7 segment)
|
||||||
|
g.setFont("7x11Numeric7Seg",2);
|
||||||
|
g.drawString(("0"+d.getSeconds()).substr(-2), X+30, Y, true /*clear background*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateHourArray(hours){
|
||||||
|
|
||||||
|
var j;
|
||||||
|
for(j=0;j<hourLED.length;j++){
|
||||||
|
prevHour[j] = hourLED[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
var i;
|
||||||
|
for(i = 0;i < hourLED.length;i++){
|
||||||
|
hourLED[i]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hours > 15){
|
||||||
|
hourLED[0] = 1;
|
||||||
|
hours = hours - 16;
|
||||||
|
}
|
||||||
|
if(hours > 7){
|
||||||
|
hourLED[1] = 1;
|
||||||
|
hours = hours - 8;
|
||||||
|
}
|
||||||
|
if(hours > 3){
|
||||||
|
hourLED[2] = 1;
|
||||||
|
hours = hours - 4;
|
||||||
|
}
|
||||||
|
if(hours > 1){
|
||||||
|
hourLED[3] = 1;
|
||||||
|
hours = hours - 2;
|
||||||
|
}
|
||||||
|
if(hours > 0){
|
||||||
|
hourLED[4] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hourLED;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateMinuteArray(minutes){
|
||||||
|
var j;
|
||||||
|
for(j=0;j<minuteLED.length;j++){
|
||||||
|
prevMinute[j] = minuteLED[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
var i;
|
||||||
|
for(i = 0;i < minuteLED.length;i++){
|
||||||
|
minuteLED[i]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(minutes > 31){
|
||||||
|
minuteLED[0] = 1;
|
||||||
|
minutes = minutes - 32;
|
||||||
|
}
|
||||||
|
if(minutes > 15){
|
||||||
|
minuteLED[1] = 1;
|
||||||
|
minutes = minutes - 16;
|
||||||
|
}
|
||||||
|
if(minutes > 7){
|
||||||
|
minuteLED[2] = 1;
|
||||||
|
minutes = minutes - 8;
|
||||||
|
}
|
||||||
|
if(minutes > 3){
|
||||||
|
minuteLED[3] = 1;
|
||||||
|
minutes = minutes - 4;
|
||||||
|
}
|
||||||
|
if(minutes > 1){
|
||||||
|
minuteLED[4] = 1;
|
||||||
|
minutes = minutes - 2;
|
||||||
|
}
|
||||||
|
if(minutes > 0){
|
||||||
|
minuteLED[5] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return minuteLED;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw(){
|
||||||
|
|
||||||
|
// work out how to display the current time
|
||||||
|
var d = new Date();
|
||||||
|
var h = d.getHours(), m = d.getMinutes();
|
||||||
|
|
||||||
|
updateHourArray(h);
|
||||||
|
updateMinuteArray(m);
|
||||||
|
|
||||||
|
var i;
|
||||||
|
//Draw hour circles
|
||||||
|
for(i=0; i<hourLED.length; i++){
|
||||||
|
if(prevHour[i] == hourLED[i]){
|
||||||
|
if(hourLED[i] == 1){
|
||||||
|
g.fillCircle(24+i*48,50,10);
|
||||||
|
} else {
|
||||||
|
var colour = g.getColor();
|
||||||
|
g.setColor(0,0,0);
|
||||||
|
g.fillCircle(24+i*48,50,10);
|
||||||
|
g.setColor(colour);
|
||||||
|
g.drawCircle(24+i*48,50,10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; i<minuteLED.length; i++){
|
||||||
|
if(prevMinute[i] == minuteLED[i]){
|
||||||
|
if(minuteLED[i] == 1){
|
||||||
|
g.fillCircle(20+i*40,100,10);
|
||||||
|
} else {
|
||||||
|
var colour = g.getColor();
|
||||||
|
g.setColor(0,0,0);
|
||||||
|
g.fillCircle(20+i*40,100,10);
|
||||||
|
g.setColor(colour);
|
||||||
|
g.drawCircle(20+i*40,100,10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the date, in a normal font
|
||||||
|
g.setFont("6x8");
|
||||||
|
g.setFontAlign(0,1); // align center bottom
|
||||||
|
// pad the date - this clears the background if the date were to change length
|
||||||
|
var dateStr = " "+require("locale").date(d)+" ";
|
||||||
|
g.drawString(dateStr, g.getWidth()/2, 130, true /*clear background*/);
|
||||||
|
|
||||||
|
if(displayTime){
|
||||||
|
drawTime(d);
|
||||||
|
}else{
|
||||||
|
g.clearRect(0,240,240,130);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the screen once, at startup
|
||||||
|
g.clear();
|
||||||
|
// draw immediately at first
|
||||||
|
draw();
|
||||||
|
var secondInterval = setInterval(draw, 1000);
|
||||||
|
// Stop updates when LCD is off, restart when on
|
||||||
|
Bangle.on('lcdPower',on=>{
|
||||||
|
if (secondInterval) clearInterval(secondInterval);
|
||||||
|
secondInterval = undefined;
|
||||||
|
if (on) {
|
||||||
|
setInterval(draw, 1000);
|
||||||
|
draw(); // draw immediately
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Load widgets
|
||||||
|
Bangle.loadWidgets();
|
||||||
|
Bangle.drawWidgets();
|
||||||
|
// Show launcher when middle button pressed
|
||||||
|
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
||||||
|
setWatch(function() {
|
||||||
|
if(displayTime == 0){
|
||||||
|
displayTime = 1;
|
||||||
|
} else{
|
||||||
|
displayTime = 0;
|
||||||
|
}
|
||||||
|
}, BTN, {edge:"rising", debounce:50, repeat:true});
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 709 B |
|
|
@ -8,11 +8,11 @@ const Spades = { width : 48, height : 48, bpp : 1,
|
||||||
|
|
||||||
const Hearts = { width : 48, height : 48, bpp : 4,
|
const Hearts = { width : 48, height : 48, bpp : 4,
|
||||||
buffer : require("heatshrink").decompress(atob("ADlVqtQBQ8FBYIKIrnMAAINGqoKC4okGCwYAB4AKDhgKE4oWKAAILDBQwYEBYwwDFwojFgoLHEgQ6H5hhCBZAkCBRAjLEgI6IC4YLIC5Y7BBZXBjgjVABYX/C8CnKABbXLABTvMC8sMC6fAC4KQURwIABRypgULwRgULwRIUCwhIRIwiRSRoZITCwx5POoowRCxAwNFxIwNCxQwLFxYwLCxgwJFxowJCxwwHFx4wHCyAwFFyIwFCyQwDFycAgoXBqAXTgFc4oWUJAJGUJARGVAEo"))
|
buffer : require("heatshrink").decompress(atob("ADlVqtQBQ8FBYIKIrnMAAINGqoKC4okGCwYAB4AKDhgKE4oWKAAILDBQwYEBYwwDFwojFgoLHEgQ6H5hhCBZAkCBRAjLEgI6IC4YLIC5Y7BBZXBjgjVABYX/C8CnKABbXLABTvMC8sMC6fAC4KQURwIABRypgULwRgULwRIUCwhIRIwiRSRoZITCwx5POoowRCxAwNFxIwNCxQwLFxYwLCxgwJFxowJCxwwHFx4wHCyAwFFyIwFCyQwDFycAgoXBqAXTgFc4oWUJAJGUJARGVAEo"))
|
||||||
};
|
};
|
||||||
|
|
||||||
const Diamonds = { width : 48, height : 48, bpp : 4,
|
const Diamonds = { width : 48, height : 48, bpp : 4,
|
||||||
buffer : require("heatshrink").decompress(atob("AHUFC60M4AXV5nFIyvM5hGVC4JIUCwJIUIwRIUIwRIUCwZISIwgABqBGUJCQWFPKBGGJCFcC455OCw4wOOox5QIxB5NOpBIOFxZ5LCxYwKOpQwMIxh5KOxipLL6xgNR5QwMX5TvXPJZ1JJBpGLPJR1LJBZGNPJIWOJA5GOPJB1NJBIWQPIpGRJApGRPIoWSJAa8PJA5GTJAYWUJAJGVAAJGVAHo="))
|
buffer : require("heatshrink").decompress(atob("AHUFC60M4AXV5nFIyvM5hGVC4JIUCwJIUIwRIUIwRIUCwZISIwgABqBGUJCQWFPKBGGJCFcC455OCw4wOOox5QIxB5NOpBIOFxZ5LCxYwKOpQwMIxh5KOxipLL6xgNR5QwMX5TvXPJZ1JJBpGLPJR1LJBZGNPJIWOJA5GOPJB1NJBIWQPIpGRJApGRPIoWSJAa8PJA5GTJAYWUJAJGVAAJGVAHo="))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var deck = [];
|
var deck = [];
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@
|
||||||
"rules": {
|
"rules": {
|
||||||
"indent": [
|
"indent": [
|
||||||
"error",
|
"error",
|
||||||
2
|
2,
|
||||||
|
{ "SwitchCase": 1 }
|
||||||
],
|
],
|
||||||
"linebreak-style": [
|
"linebreak-style": [
|
||||||
"error",
|
"error",
|
||||||
|
|
@ -24,10 +25,11 @@
|
||||||
"quotes": [
|
"quotes": [
|
||||||
"error",
|
"error",
|
||||||
"double"
|
"double"
|
||||||
],
|
]
|
||||||
|
/*,
|
||||||
"semi": [
|
"semi": [
|
||||||
"error",
|
"error",
|
||||||
"always"
|
"always"
|
||||||
]
|
]*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -150,4 +150,4 @@ exports = class Exercise {
|
||||||
|
|
||||||
workout.emit("redraw");
|
workout.emit("redraw");
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
@ -25,4 +25,4 @@ exports = class Set {
|
||||||
if (this.reps <= this.minReps) return;
|
if (this.reps <= this.minReps) return;
|
||||||
this.reps--;
|
this.reps--;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
@ -3,7 +3,7 @@ exports = class Workout {
|
||||||
this.title = params.title;
|
this.title = params.title;
|
||||||
this.exercises = [];
|
this.exercises = [];
|
||||||
this.completed = false;
|
this.completed = false;
|
||||||
this.on("redraw", redraw.bind(null, this));
|
this.on("redraw", params.redraw.bind(null, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
addExercises(exercises) {
|
addExercises(exercises) {
|
||||||
|
|
@ -27,11 +27,12 @@ exports = class Workout {
|
||||||
return !!this.completed;
|
return !!this.completed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJSON(workoutJSON) {
|
static fromJSON(workoutJSON, redraw) {
|
||||||
const Set = require("buffgym-set.js");
|
const Set = require("buffgym-set.js");
|
||||||
const Exercise = require("buffgym-exercise.js");
|
const Exercise = require("buffgym-exercise.js");
|
||||||
const workout = new this({
|
const workout = new this({
|
||||||
title: workoutJSON.title,
|
title: workoutJSON.title,
|
||||||
|
redraw: redraw,
|
||||||
});
|
});
|
||||||
const exercises = workoutJSON.exercises.map(exerciseJSON => {
|
const exercises = workoutJSON.exercises.map(exerciseJSON => {
|
||||||
const exercise = new Exercise({
|
const exercise = new Exercise({
|
||||||
|
|
@ -80,4 +81,4 @@ exports = class Workout {
|
||||||
// Call current exercise state machine
|
// Call current exercise state machine
|
||||||
this.currentExercise().next(this);
|
this.currentExercise().next(this);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
@ -248,7 +248,7 @@ function getWorkoutIndex() {
|
||||||
function buildWorkout(fName) {
|
function buildWorkout(fName) {
|
||||||
const Workout = require("buffgym-workout.js");
|
const Workout = require("buffgym-workout.js");
|
||||||
const workoutJSON = require("Storage").readJSON(fName);
|
const workoutJSON = require("Storage").readJSON(fName);
|
||||||
const workout = Workout.fromJSON(workoutJSON);
|
const workout = Workout.fromJSON(workoutJSON, redraw);
|
||||||
|
|
||||||
return workout;
|
return workout;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,12 @@ setWatch(x=>{
|
||||||
},BTN1,{repeat:true});
|
},BTN1,{repeat:true});
|
||||||
|
|
||||||
function updateAdvertising() {
|
function updateAdvertising() {
|
||||||
try {
|
try {
|
||||||
NRF.setAdvertising({},{
|
NRF.setAdvertising({},{
|
||||||
manufacturer: 0x0590,
|
manufacturer: 0x0590,
|
||||||
manufacturerData: new Uint8Array([mycounter>>8,mycounter&255])
|
manufacturerData: new Uint8Array([mycounter>>8,mycounter&255])
|
||||||
});
|
});
|
||||||
} catch(e){}
|
} catch(e){}
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawPlayers() {
|
function drawPlayers() {
|
||||||
|
|
|
||||||
|
|
@ -26,31 +26,31 @@ const ySpace=[y0, y1, y2];
|
||||||
const pixels = [[[0,0], // digit on/off pixels
|
const pixels = [[[0,0], // digit on/off pixels
|
||||||
[1,1],
|
[1,1],
|
||||||
[1,1]],
|
[1,1]],
|
||||||
[[0,1], // digit 1
|
[[0,1], // digit 1
|
||||||
[0,1],
|
[0,1],
|
||||||
[0,1]],
|
[0,1]],
|
||||||
[[0,1],
|
[[0,1],
|
||||||
[1,0],
|
[1,0],
|
||||||
[1,1]],
|
[1,1]],
|
||||||
[[1,1],
|
[[1,1],
|
||||||
[0,1],
|
[0,1],
|
||||||
[1,1]],
|
[1,1]],
|
||||||
[[1,0],
|
[[1,0],
|
||||||
[1,1],
|
[1,1],
|
||||||
[0,1]],
|
[0,1]],
|
||||||
[[1,1],
|
[[1,1],
|
||||||
[1,0],
|
[1,0],
|
||||||
[0,1]],
|
[0,1]],
|
||||||
[[1,0],
|
[[1,0],
|
||||||
[1,1],
|
[1,1],
|
||||||
[1,1]],
|
[1,1]],
|
||||||
[[1,1],
|
[[1,1],
|
||||||
[0,1],
|
[0,1],
|
||||||
[0,1]],
|
[0,1]],
|
||||||
[[1,1],
|
[[1,1],
|
||||||
[1,1],
|
[1,1],
|
||||||
[1,1]],
|
[1,1]],
|
||||||
[[1,1],
|
[[1,1],
|
||||||
[1,1],
|
[1,1],
|
||||||
[0,1]]];
|
[0,1]]];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
require("heatshrink").decompress(atob("/4AYv4CB+YdZABPvEkYA/AGv3EkfPAQP+DrI"))
|
require("heatshrink").decompress(atob("/4AYv4CB+YdZABPvEkYA/AGv3EkfPAQP+DrI"))
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ function redraw() {
|
||||||
g.drawImage(img, 120-96, 120-96, {scale:2});
|
g.drawImage(img, 120-96, 120-96, {scale:2});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Code for button (Puck.js)
|
// Code for button (Puck.js)
|
||||||
var busy = false;
|
var busy = false;
|
||||||
|
|
||||||
var lastTry = getTime();
|
var lastTry = getTime();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,7 @@ const drawClockFace = () => {
|
||||||
g.setColor(0.1,0.7,0);
|
g.setColor(0.1,0.7,0);
|
||||||
}
|
}
|
||||||
g.fillCircle(centerX,centerY,radius*0.98);
|
g.fillCircle(centerX,centerY,radius*0.98);
|
||||||
};
|
};
|
||||||
|
|
||||||
const drawAll = () => {
|
const drawAll = () => {
|
||||||
currentDate = new Date();
|
currentDate = new Date();
|
||||||
|
|
|
||||||
|
|
@ -30,4 +30,4 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
E.showMenu(appMenu)
|
E.showMenu(appMenu)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ function setButtons(){
|
||||||
setWatch(nextwp.bind(null,-1), BTN1, {repeat:true,edge:"falling"});
|
setWatch(nextwp.bind(null,-1), BTN1, {repeat:true,edge:"falling"});
|
||||||
setWatch(doselect, BTN2, {repeat:true,edge:"falling"});
|
setWatch(doselect, BTN2, {repeat:true,edge:"falling"});
|
||||||
setWatch(nextwp.bind(null,1), BTN3, {repeat:true,edge:"falling"});
|
setWatch(nextwp.bind(null,1), BTN3, {repeat:true,edge:"falling"});
|
||||||
};
|
}
|
||||||
|
|
||||||
var SCREENACCESS = {
|
var SCREENACCESS = {
|
||||||
withApp:true,
|
withApp:true,
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
0.03: Fix time output on new firmwares when no GPS time set (fix #104)
|
0.03: Fix time output on new firmwares when no GPS time set (fix #104)
|
||||||
|
0.04: Fix shown UTC time zone sign
|
||||||
|
|
@ -47,7 +47,7 @@ Bangle.on('GPS',function(f) {
|
||||||
g.drawString(t[4],120,185); // time
|
g.drawString(t[4],120,185); // time
|
||||||
if (fix.time) {
|
if (fix.time) {
|
||||||
// timezone
|
// timezone
|
||||||
var tz = (new Date()).getTimezoneOffset()/60;
|
var tz = (new Date()).getTimezoneOffset()/-60;
|
||||||
if (tz==0) tz="UTC";
|
if (tz==0) tz="UTC";
|
||||||
else if (tz>0) tz="UTC+"+tz;
|
else if (tz>0) tz="UTC+"+tz;
|
||||||
else tz="UTC"+tz;
|
else tz="UTC"+tz;
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ function startKeyboardHID() {
|
||||||
getCharacter().then(ch => {
|
getCharacter().then(ch => {
|
||||||
return sendHID(KEY[ch]);
|
return sendHID(KEY[ch]);
|
||||||
}).then(startKeyboardHID);
|
}).then(startKeyboardHID);
|
||||||
};
|
}
|
||||||
|
|
||||||
if (settings.HID=="kb" || settings.HID=="kbmedia") {
|
if (settings.HID=="kb" || settings.HID=="kbmedia") {
|
||||||
if (settings.HID=="kbmedia") {
|
if (settings.HID=="kbmedia") {
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,13 @@ setWatch(x=>{
|
||||||
},BTN1,{repeat:true});
|
},BTN1,{repeat:true});
|
||||||
|
|
||||||
function updateAdvertising() {
|
function updateAdvertising() {
|
||||||
try {
|
try {
|
||||||
NRF.setAdvertising({},{
|
NRF.setAdvertising({},{
|
||||||
manufacturer: 0x0590,
|
manufacturer: 0x0590,
|
||||||
manufacturerData: new Uint8Array([mycounter>>8,mycounter&255]),
|
manufacturerData: new Uint8Array([mycounter>>8,mycounter&255]),
|
||||||
interval: 60
|
interval: 60
|
||||||
});
|
});
|
||||||
} catch(e){}
|
} catch(e){}
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawPlayers() {
|
function drawPlayers() {
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ function draw() {
|
||||||
cg.setFontAlign(1,-1);
|
cg.setFontAlign(1,-1);
|
||||||
cg.drawString(hours, x, 0);
|
cg.drawString(hours, x, 0);
|
||||||
x+=2;
|
x+=2;
|
||||||
|
if (t.getSeconds() & 1)
|
||||||
cg.fillRect(x, 10, x+2, 10+2).fillRect(x, 20, x+2, 20+2);
|
cg.fillRect(x, 10, x+2, 10+2).fillRect(x, 20, x+2, 20+2);
|
||||||
x+=6;
|
x+=6;
|
||||||
cg.setFontAlign(-1,-1);
|
cg.setFontAlign(-1,-1);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ E.showMessage("Jingle Bells");
|
||||||
var eventEmitter = new Object();
|
var eventEmitter = new Object();
|
||||||
|
|
||||||
function strofa(notes, times, current, next){
|
function strofa(notes, times, current, next){
|
||||||
eventEmitter.on(current, () => {
|
eventEmitter.on(current, () => {
|
||||||
if (notes.length == 0) {
|
if (notes.length == 0) {
|
||||||
eventEmitter.emit(next);
|
eventEmitter.emit(next);
|
||||||
return;
|
return;
|
||||||
|
|
@ -15,7 +15,7 @@ eventEmitter.on(current, () => {
|
||||||
eventEmitter.emit(current);
|
eventEmitter.emit(current);
|
||||||
}, time);
|
}, time);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var one = [2637, 2637, 2637, 2637, 2637, 2637, 2637, 3135, 2093, 2349, 2637];
|
var one = [2637, 2637, 2637, 2637, 2637, 2637, 2637, 3135, 2093, 2349, 2637];
|
||||||
|
|
|
||||||
|
|
@ -446,5 +446,23 @@ var locales = {
|
||||||
abday: "ne,po,út,st,čt,pá,so",
|
abday: "ne,po,út,st,čt,pá,so",
|
||||||
day: "neděle,pondělí,úterý,středa,čtvrtek,pátek,sobota",
|
day: "neděle,pondělí,úterý,středa,čtvrtek,pátek,sobota",
|
||||||
trans: { yes: "tak", Yes: "Tak", no: "nie", No: "Nie", ok: "ok", on: "na", off: "poza" }
|
trans: { yes: "tak", Yes: "Tak", no: "nie", No: "Nie", ok: "ok", on: "na", off: "poza" }
|
||||||
|
},
|
||||||
|
"sl_SI": {
|
||||||
|
lang: "sl_SI",
|
||||||
|
decimal_point: ",",
|
||||||
|
thousands_sep: ".",
|
||||||
|
currency_symbol: "\x80",
|
||||||
|
int_curr_symbol: "EUR",
|
||||||
|
speed: "km/h",
|
||||||
|
distance: { 0: "m", 1: "km" },
|
||||||
|
temperature: "°C",
|
||||||
|
ampm: { 0: "dop.", 1: "pop." },
|
||||||
|
timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" },
|
||||||
|
datePattern: { 0: "%d. %b %Y", 1: "%d.%m.%Y" }, // "30. jan. 2020" // "30.01.2020"(short)
|
||||||
|
abmonth: "jan.,feb.,mar.,apr.,maj,jun.,jul.,avg.,sep.,okt.,nov.,dec.",
|
||||||
|
month: "januar,februar,marec,april,maj,junij,julij,avgust,september,oktober,november,december",
|
||||||
|
abday: "ned.,pon.,tor.,sre.,čet.,pet.,sob.",
|
||||||
|
day: "nedelja,ponedeljek,torek,sreda,četrtek,petek,sobota",
|
||||||
|
trans: { yes: "da", Yes: "Da", no: "ne", No: "Ne", ok: "ok", on: "On", off: "Off" }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -16,98 +16,98 @@ var timeInterval;
|
||||||
n is the amount (0..1)
|
n is the amount (0..1)
|
||||||
maxFive is true is this digit only counts 0..5 */
|
maxFive is true is this digit only counts 0..5 */
|
||||||
const DIGITS = {
|
const DIGITS = {
|
||||||
" ":n=>[],
|
" ":n=>[],
|
||||||
"0":n=>[
|
"0":n=>[
|
||||||
[n,0,1,0],
|
[n,0,1,0],
|
||||||
[1,0,1,1],
|
[1,0,1,1],
|
||||||
[1,1,1,2],
|
[1,1,1,2],
|
||||||
[n,2,1,2],
|
[n,2,1,2],
|
||||||
[n,1,n,2],
|
[n,1,n,2],
|
||||||
[n,0,n,1]],
|
[n,0,n,1]],
|
||||||
"1":n=>[
|
"1":n=>[
|
||||||
[1-n,0,1,0],
|
[1-n,0,1,0],
|
||||||
[1,0,1,1],
|
[1,0,1,1],
|
||||||
[1-n,1,1,1],
|
[1-n,1,1,1],
|
||||||
[1-n,1,1-n,2],
|
[1-n,1,1-n,2],
|
||||||
[1-n,2,1,2]],
|
[1-n,2,1,2]],
|
||||||
"2":n=>[
|
"2":n=>[
|
||||||
[0,0,1,0],
|
[0,0,1,0],
|
||||||
[1,0,1,1],
|
[1,0,1,1],
|
||||||
[0,1,1,1],
|
[0,1,1,1],
|
||||||
[0,1+n,0,2],
|
[0,1+n,0,2],
|
||||||
[1,2-n,1,2],
|
[1,2-n,1,2],
|
||||||
[0,2,1,2]],
|
[0,2,1,2]],
|
||||||
"3":n=>[
|
"3":n=>[
|
||||||
[0,0,1-n,0],
|
[0,0,1-n,0],
|
||||||
[0,0,0,n],
|
[0,0,0,n],
|
||||||
[1,0,1,1],
|
[1,0,1,1],
|
||||||
[0,1,1,1],
|
[0,1,1,1],
|
||||||
[1,1,1,2],
|
[1,1,1,2],
|
||||||
[n,2,1,2]],
|
[n,2,1,2]],
|
||||||
"4":n=>[
|
"4":n=>[
|
||||||
[0,0,0,1],
|
[0,0,0,1],
|
||||||
[1,0,1-n,0],
|
[1,0,1-n,0],
|
||||||
[1,0,1,1-n],
|
[1,0,1,1-n],
|
||||||
[0,1,1,1],
|
[0,1,1,1],
|
||||||
[1,1,1,2],
|
[1,1,1,2],
|
||||||
[1-n,2,1,2]],
|
[1-n,2,1,2]],
|
||||||
"5to0": n=>[ // 5 -> 0
|
"5to0": n=>[ // 5 -> 0
|
||||||
[0,0,0,1],
|
[0,0,0,1],
|
||||||
[0,0,1,0],
|
[0,0,1,0],
|
||||||
[n,1,1,1],
|
[n,1,1,1],
|
||||||
[1,1,1,2],
|
[1,1,1,2],
|
||||||
[0,2,1,2],
|
[0,2,1,2],
|
||||||
[0,2,0,2],
|
[0,2,0,2],
|
||||||
[1,1-n,1,1],
|
[1,1-n,1,1],
|
||||||
[0,1,0,1+n]],
|
[0,1,0,1+n]],
|
||||||
"5to6": n=>[ // 5 -> 6
|
"5to6": n=>[ // 5 -> 6
|
||||||
[0,0,0,1],
|
[0,0,0,1],
|
||||||
[0,0,1,0],
|
[0,0,1,0],
|
||||||
[0,1,1,1],
|
[0,1,1,1],
|
||||||
[1,1,1,2],
|
[1,1,1,2],
|
||||||
[0,2,1,2],
|
[0,2,1,2],
|
||||||
[0,2-n,0,2]],
|
[0,2-n,0,2]],
|
||||||
"6":n=>[
|
"6":n=>[
|
||||||
[0,0,0,1-n],
|
[0,0,0,1-n],
|
||||||
[0,0,1,0],
|
[0,0,1,0],
|
||||||
[n,1,1,1],
|
[n,1,1,1],
|
||||||
[1,1-n,1,1],
|
[1,1-n,1,1],
|
||||||
[1,1,1,2],
|
[1,1,1,2],
|
||||||
[n,2,1,2],
|
[n,2,1,2],
|
||||||
[0,1-n,0,2-2*n]],
|
[0,1-n,0,2-2*n]],
|
||||||
"7":n=>[
|
"7":n=>[
|
||||||
[0,0,0,n],
|
[0,0,0,n],
|
||||||
[0,0,1,0],
|
[0,0,1,0],
|
||||||
[1,0,1,1],
|
[1,0,1,1],
|
||||||
[1-n,1,1,1],
|
[1-n,1,1,1],
|
||||||
[1,1,1,2],
|
[1,1,1,2],
|
||||||
[1-n,2,1,2],
|
[1-n,2,1,2],
|
||||||
[1-n,1,1-n,2]],
|
[1-n,1,1-n,2]],
|
||||||
"8":n=>[
|
"8":n=>[
|
||||||
[0,0,0,1],
|
[0,0,0,1],
|
||||||
[0,0,1,0],
|
[0,0,1,0],
|
||||||
[1,0,1,1],
|
[1,0,1,1],
|
||||||
[0,1,1,1],
|
[0,1,1,1],
|
||||||
[1,1,1,2],
|
[1,1,1,2],
|
||||||
[0,2,1,2],
|
[0,2,1,2],
|
||||||
[0,1,0,2-n]],
|
[0,1,0,2-n]],
|
||||||
"9":n=>[
|
"9":n=>[
|
||||||
[0,0,0,1],
|
[0,0,0,1],
|
||||||
[0,0,1,0],
|
[0,0,1,0],
|
||||||
[1,0,1,1],
|
[1,0,1,1],
|
||||||
[0,1,1-n,1],
|
[0,1,1-n,1],
|
||||||
[0,1,0,1+n],
|
[0,1,0,1+n],
|
||||||
[1,1,1,2],
|
[1,1,1,2],
|
||||||
[0,2,1,2]],
|
[0,2,1,2]],
|
||||||
":":n=>[
|
":":n=>[
|
||||||
[0.4,0.4,0.6,0.4],
|
[0.4,0.4,0.6,0.4],
|
||||||
[0.6,0.4,0.6,0.6],
|
[0.6,0.4,0.6,0.6],
|
||||||
[0.6,0.6,0.4,0.6],
|
[0.6,0.6,0.4,0.6],
|
||||||
[0.4,0.4,0.4,0.6],
|
[0.4,0.4,0.4,0.6],
|
||||||
[0.4,1.4,0.6,1.4],
|
[0.4,1.4,0.6,1.4],
|
||||||
[0.6,1.4,0.6,1.6],
|
[0.6,1.4,0.6,1.6],
|
||||||
[0.6,1.6,0.4,1.6],
|
[0.6,1.6,0.4,1.6],
|
||||||
[0.4,1.4,0.4,1.6]]
|
[0.4,1.4,0.4,1.6]]
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Draw a transition between lastText and thisText.
|
/* Draw a transition between lastText and thisText.
|
||||||
|
|
|
||||||
|
|
@ -243,7 +243,7 @@ function drawMoonPhase(offset, x, y){
|
||||||
if (getMPhaseSim(offset) == "waning-gibbous") {g.drawImage(getImg("WaningGibbousNorth"), x, y);}
|
if (getMPhaseSim(offset) == "waning-gibbous") {g.drawImage(getImg("WaningGibbousNorth"), x, y);}
|
||||||
if (getMPhaseSim(offset) == "last-quarter") {g.drawImage(getImg("LastQuarterNorth"), x, y);}
|
if (getMPhaseSim(offset) == "last-quarter") {g.drawImage(getImg("LastQuarterNorth"), x, y);}
|
||||||
if (getMPhaseSim(offset) == "waning-crescent") {g.drawImage(getImg("WaningCrescentNorth"), x, y);}
|
if (getMPhaseSim(offset) == "waning-crescent") {g.drawImage(getImg("WaningCrescentNorth"), x, y);}
|
||||||
}
|
}
|
||||||
else { //Southern hemisphere
|
else { //Southern hemisphere
|
||||||
if (getMPhaseSim(offset) == "new") {g.drawImage(getImg("NewMoon"), x, y);}
|
if (getMPhaseSim(offset) == "new") {g.drawImage(getImg("NewMoon"), x, y);}
|
||||||
if (getMPhaseSim(offset) == "waxing-crescent") {g.drawImage(getImg("WaxingCrescentSouth"), x, y);}
|
if (getMPhaseSim(offset) == "waxing-crescent") {g.drawImage(getImg("WaxingCrescentSouth"), x, y);}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
(function(back) {
|
(function(back) {
|
||||||
function updateSettings() {
|
function updateSettings() {
|
||||||
storage.write('numerals.json', numeralsSettings);
|
storage.write('numerals.json', numeralsSettings);
|
||||||
};
|
}
|
||||||
function resetSettings() {
|
function resetSettings() {
|
||||||
numeralsSettings = {
|
numeralsSettings = {
|
||||||
color:0,
|
color:0,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
0.01: You can now time cooking a Pizza!
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
# Pizza Timer
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEwwkBiIA/AH4AwgCzUgEFqtVDIcQDpkQgtO9wACqAfCoAYKCwIVD93kCQMQgAcDAA8F73tqEAAAQXC6Fe8owIiFO9peBpvdAAIRBgvdHQIwIggKBhsNCoPUF4UEgtAp3gFxHlhsFgvQptAFAMQGoPUhpmCLoouB7tArvV7tVC4QEBAIPuC40O8hECAAVVIwXQKIPQC4xGB8FNotEgBBBXIMQhtAIwPQpx4FiBGCotFgFd7vQBQIUBF4NAhwIBLwpGC6ovCEwMAhvUqvVgsOSAsNRoJcCCwKlCgsNPoIXBCAJ2FLwJ2EgpeBGgKOBD4MEVAkQr3QaAIxCqgvBiFUNAMES4SQERwNA6tdBoPVhpeBCYVQQYKXBC4veNQMECIR2CAoUFoB/CC4vugoJBUgIABBgMQgtNoEFbQMA91RC4wAEgALCYoVQ6HQ7wvFOoYAB6DaBBoSMBBAMApxHGgC9BBgPUprbBB4RLBO4NNC4tVgqMBoHQYgQcBDAcAoFUR4tQhvQKoQuBroDBDAZLBKAYXCCoKzCJYKtBb4QHBGQYXEp3gC4XUVIYFBAQVQGYgACr3gCYVFAQJgCAwIKB6kEqAYFh3lU4JBCAQLDDUwNAH4IvFgnuhtF6FdCAJFDggGBgvuoAXFVANQC4NVhoxBqAUBPAVe9xfGPAKfBIgNNgsNhtVGAPVFwPlC40RhvkIgQqCLgQFBpw9BCwzHBKIKRFAANQIoIuIJAIwBgFUCodFgFd93tdggwGpwYBAAhEBIoIuIDAnu6lEolNCoIWNDAVUCYQAB6sACxoYCgEFqtQAgIVOAH4AC"))
|
||||||
|
|
@ -0,0 +1,270 @@
|
||||||
|
/* UI GLOBALS */
|
||||||
|
|
||||||
|
const HOUR_SCENE = 0;
|
||||||
|
const MIN_SCENE = 1;
|
||||||
|
const SEC_SCENE = 2;
|
||||||
|
const COUNTDOWN_SCENE = 3;
|
||||||
|
|
||||||
|
var currentScene = 0;
|
||||||
|
|
||||||
|
var btn1Watch;
|
||||||
|
var btn2Watch;
|
||||||
|
var btn3Watch;
|
||||||
|
|
||||||
|
var drawInterval;
|
||||||
|
|
||||||
|
/* STATE GLOBALS */
|
||||||
|
|
||||||
|
var menuTime = new Uint8Array([0,0,0]);
|
||||||
|
var countdownTime = menuTime.slice(0);
|
||||||
|
var show = [true, true, true];
|
||||||
|
|
||||||
|
/* COUNTDOWN CONSTANTS */
|
||||||
|
|
||||||
|
const HOUR_INDEX = 0;
|
||||||
|
const MIN_INDEX = 1;
|
||||||
|
const SEC_INDEX = 2;
|
||||||
|
|
||||||
|
var flashIndex = HOUR_INDEX;
|
||||||
|
|
||||||
|
/* logic */
|
||||||
|
|
||||||
|
function setCountdownTime() {
|
||||||
|
countdownTime = menuTime.slice(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function countDownFinished() {
|
||||||
|
return countdownTime[HOUR_INDEX] <= 0 &&
|
||||||
|
countdownTime[MIN_INDEX] <= 0 &&
|
||||||
|
countdownTime[SEC_INDEX] <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function alertCountdownFinished() {
|
||||||
|
if (drawInterval) return;
|
||||||
|
Bangle.buzz()
|
||||||
|
.then(() => new Promise(resolve => setTimeout(resolve, 200)))
|
||||||
|
.then(() => Bangle.buzz());
|
||||||
|
setTimeout(alertCountdownFinished, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function unsetDrawInterval() {
|
||||||
|
clearInterval(drawInterval);
|
||||||
|
drawInterval = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function decrementCountdownTime() {
|
||||||
|
const allZero = countDownFinished();
|
||||||
|
|
||||||
|
if(allZero) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (countdownTime[SEC_INDEX] !== 0) {
|
||||||
|
countdownTime[SEC_INDEX] = countdownTime[SEC_INDEX] - 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
countdownTime[SEC_INDEX] = 59;
|
||||||
|
|
||||||
|
if (countdownTime[MIN_INDEX] !== 0) {
|
||||||
|
countdownTime[MIN_INDEX] = countdownTime[MIN_INDEX] - 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
countdownTime[MIN_INDEX] = 59;
|
||||||
|
|
||||||
|
if (countdownTime[HOUR_INDEX] !== 0) {
|
||||||
|
countdownTime[HOUR_INDEX] = countdownTime[HOUR_INDEX] - 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleShow(timeIndex) {
|
||||||
|
show[timeIndex] = !show[timeIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
function twoPadded(i) {
|
||||||
|
return i.length < 2 ? "0" + i : i;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTimeString(t) {
|
||||||
|
let hour = t[HOUR_INDEX].toString();
|
||||||
|
let min = t[MIN_INDEX].toString();
|
||||||
|
let sec = t[SEC_INDEX].toString();
|
||||||
|
|
||||||
|
hour = show[HOUR_INDEX] ? twoPadded(hour) : " ";
|
||||||
|
min = show[MIN_INDEX] ? twoPadded(min) : " ";
|
||||||
|
sec = show[SEC_INDEX] ? twoPadded(sec) : " ";
|
||||||
|
|
||||||
|
return hour + ":" + min + ":" + sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* drawing */
|
||||||
|
|
||||||
|
/*
|
||||||
|
shamelessly stollen from Bluetooth Music Controls
|
||||||
|
https://github.com/espruino/BangleApps/blob/6b09377414e02d575b8335bb051c831ecc9da9d9/apps/hidmsic/hid-music.js#L42
|
||||||
|
*/
|
||||||
|
function drawArrows() {
|
||||||
|
function c(a) {
|
||||||
|
return {
|
||||||
|
width: 8,
|
||||||
|
height: a.length,
|
||||||
|
bpp: 1,
|
||||||
|
buffer: (new Uint8Array(a)).buffer
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const d = g.getWidth() - 18;
|
||||||
|
g.drawImage(c([16,56,124,254,16,16,16,16]),d,40);
|
||||||
|
g.drawImage(c([16,16,16,16,254,124,56,16]),d,194);
|
||||||
|
g.drawImage(c([0,8,12,14,255,14,12,8]),d,116);
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawTime(input) {
|
||||||
|
g.clear();
|
||||||
|
g.setFontAlign(0,0);
|
||||||
|
g.setFont("4x6",5);
|
||||||
|
g.drawString(input, g.getWidth() / 2, g.getHeight() / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawMenu() {
|
||||||
|
const timeString = getTimeString(menuTime);
|
||||||
|
drawTime(timeString);
|
||||||
|
drawArrows();
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawCountdown() {
|
||||||
|
const timeString = getTimeString(countdownTime);
|
||||||
|
drawTime(timeString);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* button callbacks */
|
||||||
|
|
||||||
|
function getMaxSelectableTime() {
|
||||||
|
return flashIndex === HOUR_INDEX ? 23 : 59;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* btn1 */
|
||||||
|
|
||||||
|
function incrementMenuTime() {
|
||||||
|
const maxTime = getMaxSelectableTime();
|
||||||
|
const currentTime = menuTime[flashIndex];
|
||||||
|
const newTime = currentTime < maxTime ? currentTime + 1 : 0;
|
||||||
|
menuTime[flashIndex] = newTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* btn2 */
|
||||||
|
|
||||||
|
function incrementScene() {
|
||||||
|
currentScene++;
|
||||||
|
}
|
||||||
|
|
||||||
|
function incrementFlashIndex() {
|
||||||
|
flashIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showAll() {
|
||||||
|
for(var i = 0; i < show.length; i++) {
|
||||||
|
show[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showFlashIndex() {
|
||||||
|
show[flashIndex] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideFlashIndex() {
|
||||||
|
show[flashIndex] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
incrementScene();
|
||||||
|
|
||||||
|
if (currentScene === COUNTDOWN_SCENE) {
|
||||||
|
showAll();
|
||||||
|
startCountdownScene();
|
||||||
|
} else {
|
||||||
|
showFlashIndex();
|
||||||
|
incrementFlashIndex();
|
||||||
|
hideFlashIndex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* btn3 */
|
||||||
|
|
||||||
|
function decrementMenuTime() {
|
||||||
|
const maxTime = getMaxSelectableTime();
|
||||||
|
const currentTime = menuTime[flashIndex];
|
||||||
|
const newTime = currentTime > 0 ? currentTime - 1 : maxTime;
|
||||||
|
menuTime[flashIndex] = newTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* watches */
|
||||||
|
|
||||||
|
function setupMenuWatches() {
|
||||||
|
clearWatch();
|
||||||
|
btn1Watch = setWatch(incrementMenuTime, BTN1, {repeat: true});
|
||||||
|
btn2Watch = setWatch(next, BTN2, {repeat: true});
|
||||||
|
btn3Watch = setWatch(decrementMenuTime, BTN3, {repeat: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupCountdownWatches() {
|
||||||
|
clearWatch();
|
||||||
|
btn2Watch = setWatch(main, BTN2, {repeat: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* scenes */
|
||||||
|
|
||||||
|
function menu() {
|
||||||
|
drawMenu();
|
||||||
|
toggleShow(flashIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
function countdown() {
|
||||||
|
decrementCountdownTime();
|
||||||
|
drawCountdown();
|
||||||
|
|
||||||
|
if (countDownFinished()) {
|
||||||
|
unsetDrawInterval();
|
||||||
|
alertCountdownFinished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* init */
|
||||||
|
|
||||||
|
function unsetDrawInterval() {
|
||||||
|
if (!drawInterval) return;
|
||||||
|
clearInterval(drawInterval);
|
||||||
|
drawInterval = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function startMenuScene() {
|
||||||
|
setupMenuWatches();
|
||||||
|
unsetDrawInterval();
|
||||||
|
menu();
|
||||||
|
drawInterval = setInterval(menu, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
function startCountdownScene() {
|
||||||
|
setupCountdownWatches();
|
||||||
|
unsetDrawInterval();
|
||||||
|
setCountdownTime();
|
||||||
|
showAll();
|
||||||
|
drawCountdown();
|
||||||
|
drawInterval = setInterval(countdown, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* main */
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
currentScene = 0;
|
||||||
|
flashIndex = HOUR_INDEX;
|
||||||
|
hideFlashIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
reset();
|
||||||
|
startMenuScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
|
|
@ -206,7 +206,7 @@
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
|
|
||||||
//manage when things should be enabled and not
|
//manage when things should be enabled and not
|
||||||
Bangle.on('lcdPower', function (on) {
|
Bangle.on('lcdPower', function (on) {
|
||||||
if (on) {
|
if (on) {
|
||||||
Bangle.setHRMPower(1);
|
Bangle.setHRMPower(1);
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
0.01: New widget
|
0.01: New widget
|
||||||
0.02: Less invasive, change default clock setting instead of directly loading the new clock (no longer breaks Gadgetbridge notifications)
|
0.02: Less invasive, change default clock setting instead of directly loading the new clock (no longer breaks Gadgetbridge notifications)
|
||||||
|
0.03: Only changes when the widget id reloaded (no longer uses LCD turning off)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Summary
|
# Summary
|
||||||
Random Clock is a widget that will randomly show one of the installed watch faces each time the LCD is turned on.
|
Random Clock is a widget that will randomly show one of the installed watch faces each time after the widget is (re-)loaded.
|
||||||
|
|
||||||
# How it works
|
# How it works
|
||||||
Everytime the LCD is turned off, the widget randomly changes the clock. When you long press BTN 3 the next time,
|
Everytime the widget is reloaded, it randomly changes the clock. When you long press BTN 3 the next time,
|
||||||
you might (or might not, it's random after all) see another watch face.
|
you might (or might not, it's random after all) see another watch face.
|
||||||
|
|
@ -16,20 +16,18 @@
|
||||||
if (clockApps && clockApps.length > 0) {
|
if (clockApps && clockApps.length > 0) {
|
||||||
var clockIndex = getRandomInt(clockApps.length);
|
var clockIndex = getRandomInt(clockApps.length);
|
||||||
|
|
||||||
// Only update the file if the clock really change to be nice to the FLASH mem
|
// Only update the file if the clock really changed to be nice to the FLASH mem
|
||||||
if (clockApps[clockIndex].src != currentClock) {
|
if (clockApps[clockIndex].src != currentClock) {
|
||||||
currentClock = clockApps[clockIndex].src;
|
currentClock = clockApps[clockIndex].src;
|
||||||
settings = require("Storage").readJSON('setting.json', 1);
|
settings = require("Storage").readJSON('setting.json', 1);
|
||||||
settings.clock = clockApps[clockIndex].src;
|
settings.clock = clockApps[clockIndex].src;
|
||||||
require("Storage").write('setting.json', settings);
|
require("Storage").write('setting.json', settings);
|
||||||
|
|
||||||
|
console.log("RandomClockWidget set the clock to '" + clockApps[clockIndex].name + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Bangle.on('lcdPower', (on) => {
|
|
||||||
if (!on) {
|
|
||||||
loadRandomClock();
|
loadRandomClock();
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
@ -2,3 +2,4 @@
|
||||||
0.02: Add widgets to app
|
0.02: Add widgets to app
|
||||||
0.03: Use offscreen buffer (not doublebuffer)
|
0.03: Use offscreen buffer (not doublebuffer)
|
||||||
Use 'locale' to get internationalised speed
|
Use 'locale' to get internationalised speed
|
||||||
|
0.04: Start GPS after loading app, just in case widgets affect it (#449)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
Bangle.setGPSPower(1);
|
|
||||||
var buf = Graphics.createArrayBuffer(240,120,1,{msb:true});
|
var buf = Graphics.createArrayBuffer(240,120,1,{msb:true});
|
||||||
var lastFix = {fix:0,satellites:0};
|
var lastFix = {fix:0,satellites:0};
|
||||||
function onGPS(fix) {
|
function onGPS(fix) {
|
||||||
|
|
@ -31,3 +30,4 @@ Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
|
|
||||||
Bangle.on('GPS', onGPS);
|
Bangle.on('GPS', onGPS);
|
||||||
|
Bangle.setGPSPower(1);
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
(function() {
|
(function() {
|
||||||
var clickTimes = [];
|
var clickTimes = [];
|
||||||
var clickPattern = "";
|
var clickPattern = "";
|
||||||
var TAPS = 4; // number of taps
|
var TAPS = 4; // number of taps
|
||||||
var PERIOD = 1; // seconds
|
var PERIOD = 1; // seconds
|
||||||
|
|
||||||
// we don't actually create/draw a widget here at all...
|
// we don't actually create/draw a widget here at all...
|
||||||
Bangle.on("lcdPower",function(on) {
|
Bangle.on("lcdPower",function(on) {
|
||||||
// First click (that turns LCD on) isn't given to
|
// First click (that turns LCD on) isn't given to
|
||||||
// setWatch, so handle it here
|
// setWatch, so handle it here
|
||||||
if (!on) return;
|
if (!on) return;
|
||||||
clickTimes=[getTime()];
|
clickTimes=[getTime()];
|
||||||
clickPattern="x";
|
clickPattern="x";
|
||||||
});
|
});
|
||||||
function tap(e,c) {
|
function tap(e,c) {
|
||||||
clickPattern = clickPattern.substr(-3)+c;
|
clickPattern = clickPattern.substr(-3)+c;
|
||||||
while (clickTimes.length>=TAPS) clickTimes.shift();
|
while (clickTimes.length>=TAPS) clickTimes.shift();
|
||||||
clickTimes.push(e.time);
|
clickTimes.push(e.time);
|
||||||
|
|
@ -20,7 +20,7 @@ function tap(e,c) {
|
||||||
if (clickPeriod<PERIOD && clickPattern.match(/.313/)) {
|
if (clickPeriod<PERIOD && clickPattern.match(/.313/)) {
|
||||||
load("torch.app.js");
|
load("torch.app.js");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setWatch(function(e) { tap(e,"1"); }, BTN1, {repeat:true, edge:"rising"});
|
setWatch(function(e) { tap(e,"1"); }, BTN1, {repeat:true, edge:"rising"});
|
||||||
setWatch(function(e) { tap(e,"3"); }, BTN3, {repeat:true, edge:"rising"});
|
setWatch(function(e) { tap(e,"3"); }, BTN3, {repeat:true, edge:"rising"});
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
(function(){
|
(function(){
|
||||||
var CHARGING = 0x07E0;
|
var CHARGING = 0x07E0;
|
||||||
|
|
||||||
function setWidth() {
|
function setWidth() {
|
||||||
WIDGETS["bat"].width = 40 + (Bangle.isCharging()?16:0);
|
WIDGETS["bat"].width = 40 + (Bangle.isCharging()?16:0);
|
||||||
}
|
}
|
||||||
function draw() {
|
function draw() {
|
||||||
var s = 39;
|
var s = 39;
|
||||||
var x = this.x, y = this.y;
|
var x = this.x, y = this.y;
|
||||||
if (Bangle.isCharging()) {
|
if (Bangle.isCharging()) {
|
||||||
|
|
@ -17,15 +17,15 @@ function draw() {
|
||||||
g.fillRect(x+s-3,y+10,x+s,y+14);
|
g.fillRect(x+s-3,y+10,x+s,y+14);
|
||||||
g.setColor(CHARGING).fillRect(x+4,y+6,x+4+E.getBattery()*(s-12)/100,y+17);
|
g.setColor(CHARGING).fillRect(x+4,y+6,x+4+E.getBattery()*(s-12)/100,y+17);
|
||||||
g.setColor(-1);
|
g.setColor(-1);
|
||||||
}
|
}
|
||||||
Bangle.on('charging',function(charging) {
|
Bangle.on('charging',function(charging) {
|
||||||
if(charging) Bangle.buzz();
|
if(charging) Bangle.buzz();
|
||||||
setWidth();
|
setWidth();
|
||||||
Bangle.drawWidgets(); // relayout widgets
|
Bangle.drawWidgets(); // relayout widgets
|
||||||
g.flip();
|
g.flip();
|
||||||
});
|
});
|
||||||
var batteryInterval;
|
var batteryInterval;
|
||||||
Bangle.on('lcdPower', function(on) {
|
Bangle.on('lcdPower', function(on) {
|
||||||
if (on) {
|
if (on) {
|
||||||
WIDGETS["bat"].draw();
|
WIDGETS["bat"].draw();
|
||||||
// refresh once a minute if LCD on
|
// refresh once a minute if LCD on
|
||||||
|
|
@ -37,7 +37,7 @@ Bangle.on('lcdPower', function(on) {
|
||||||
batteryInterval = undefined;
|
batteryInterval = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
WIDGETS["bat"]={area:"tr",width:40,draw:draw};
|
WIDGETS["bat"]={area:"tr",width:40,draw:draw};
|
||||||
setWidth();
|
setWidth();
|
||||||
})()
|
})()
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
(function(){
|
(function(){
|
||||||
const COLORS = {
|
const COLORS = {
|
||||||
'white': -1,
|
'white': -1,
|
||||||
'charging': 0x07E0, // "Green"
|
'charging': 0x07E0, // "Green"
|
||||||
'high': 0x05E0, // slightly darker green
|
'high': 0x05E0, // slightly darker green
|
||||||
'ok': 0xFD20, // "Orange"
|
'ok': 0xFD20, // "Orange"
|
||||||
'low':0xF800, // "Red"
|
'low':0xF800, // "Red"
|
||||||
}
|
}
|
||||||
const SETTINGS_FILE = 'widbatpc.json'
|
const SETTINGS_FILE = 'widbatpc.json'
|
||||||
|
|
||||||
let settings
|
let settings
|
||||||
function loadSettings() {
|
function loadSettings() {
|
||||||
settings = require('Storage').readJSON(SETTINGS_FILE, 1) || {}
|
settings = require('Storage').readJSON(SETTINGS_FILE, 1) || {}
|
||||||
const DEFAULTS = {
|
const DEFAULTS = {
|
||||||
'color': 'By Level',
|
'color': 'By Level',
|
||||||
|
|
@ -20,13 +20,13 @@ function loadSettings() {
|
||||||
Object.keys(DEFAULTS).forEach(k=>{
|
Object.keys(DEFAULTS).forEach(k=>{
|
||||||
if (settings[k]===undefined) settings[k]=DEFAULTS[k]
|
if (settings[k]===undefined) settings[k]=DEFAULTS[k]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function setting(key) {
|
function setting(key) {
|
||||||
if (!settings) { loadSettings() }
|
if (!settings) { loadSettings() }
|
||||||
return settings[key];
|
return settings[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
const levelColor = (l) => {
|
const levelColor = (l) => {
|
||||||
// "charging" is very bright -> percentage is hard to read, "high" is ok(ish)
|
// "charging" is very bright -> percentage is hard to read, "high" is ok(ish)
|
||||||
const green = setting('percentage') ? COLORS.high : COLORS.charging
|
const green = setting('percentage') ? COLORS.high : COLORS.charging
|
||||||
switch (setting('color')) {
|
switch (setting('color')) {
|
||||||
|
|
@ -45,12 +45,12 @@ const levelColor = (l) => {
|
||||||
if (l >= 15) return COLORS.ok;
|
if (l >= 15) return COLORS.ok;
|
||||||
return COLORS.low;
|
return COLORS.low;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const chargerColor = () => {
|
const chargerColor = () => {
|
||||||
return (setting('color') === 'Monochrome') ? COLORS.white : COLORS.charging
|
return (setting('color') === 'Monochrome') ? COLORS.white : COLORS.charging
|
||||||
}
|
}
|
||||||
// sets width, returns true if it changed
|
// sets width, returns true if it changed
|
||||||
function setWidth() {
|
function setWidth() {
|
||||||
var w = 40;
|
var w = 40;
|
||||||
if (Bangle.isCharging() && setting('charger'))
|
if (Bangle.isCharging() && setting('charger'))
|
||||||
w += 16;
|
w += 16;
|
||||||
|
|
@ -59,8 +59,8 @@ function setWidth() {
|
||||||
var changed = WIDGETS["batpc"].width != w;
|
var changed = WIDGETS["batpc"].width != w;
|
||||||
WIDGETS["batpc"].width = w;
|
WIDGETS["batpc"].width = w;
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
function draw() {
|
function draw() {
|
||||||
// if hidden, don't draw
|
// if hidden, don't draw
|
||||||
if (!WIDGETS["batpc"].width) return;
|
if (!WIDGETS["batpc"].width) return;
|
||||||
// else...
|
// else...
|
||||||
|
|
@ -100,29 +100,29 @@ function draw() {
|
||||||
gfx.setFont('6x8', 2);
|
gfx.setFont('6x8', 2);
|
||||||
gfx.drawString(l, x + 6, y + 4);
|
gfx.drawString(l, x + 6, y + 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// reload widget, e.g. when settings have changed
|
// reload widget, e.g. when settings have changed
|
||||||
function reload() {
|
function reload() {
|
||||||
loadSettings()
|
loadSettings()
|
||||||
// need to redraw all widgets, because changing the "charger" setting
|
// need to redraw all widgets, because changing the "charger" setting
|
||||||
// can affect the width and mess with the whole widget layout
|
// can affect the width and mess with the whole widget layout
|
||||||
setWidth()
|
setWidth()
|
||||||
g.clear();
|
g.clear();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
}
|
}
|
||||||
// update widget - redraw just widget, or all widgets if size changed
|
// update widget - redraw just widget, or all widgets if size changed
|
||||||
function update() {
|
function update() {
|
||||||
if (setWidth()) Bangle.drawWidgets();
|
if (setWidth()) Bangle.drawWidgets();
|
||||||
else WIDGETS["batpc"].draw();
|
else WIDGETS["batpc"].draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
Bangle.on('charging',function(charging) {
|
Bangle.on('charging',function(charging) {
|
||||||
if(charging) Bangle.buzz();
|
if(charging) Bangle.buzz();
|
||||||
update();
|
update();
|
||||||
g.flip();
|
g.flip();
|
||||||
});
|
});
|
||||||
var batteryInterval;
|
var batteryInterval;
|
||||||
Bangle.on('lcdPower', function(on) {
|
Bangle.on('lcdPower', function(on) {
|
||||||
if (on) {
|
if (on) {
|
||||||
update();
|
update();
|
||||||
// refresh once a minute if LCD on
|
// refresh once a minute if LCD on
|
||||||
|
|
@ -134,7 +134,7 @@ Bangle.on('lcdPower', function(on) {
|
||||||
batteryInterval = undefined;
|
batteryInterval = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
WIDGETS["batpc"]={area:"tr",width:40,draw:draw,reload:reload};
|
WIDGETS["batpc"]={area:"tr",width:40,draw:draw,reload:reload};
|
||||||
setWidth();
|
setWidth();
|
||||||
})()
|
})()
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,19 @@
|
||||||
(function(){
|
(function(){
|
||||||
var img_bt = E.toArrayBuffer(atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="));
|
var img_bt = E.toArrayBuffer(atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="));
|
||||||
|
|
||||||
function draw() {
|
function draw() {
|
||||||
g.reset();
|
g.reset();
|
||||||
if (NRF.getSecurityStatus().connected)
|
if (NRF.getSecurityStatus().connected)
|
||||||
g.setColor(0,0.5,1);
|
g.setColor(0,0.5,1);
|
||||||
else
|
else
|
||||||
g.setColor(0.3,0.3,0.3);
|
g.setColor(0.3,0.3,0.3);
|
||||||
g.drawImage(img_bt,10+this.x,2+this.y);
|
g.drawImage(img_bt,10+this.x,2+this.y);
|
||||||
}
|
}
|
||||||
function changed() {
|
function changed() {
|
||||||
WIDGETS["bluetooth"].draw();
|
WIDGETS["bluetooth"].draw();
|
||||||
g.flip();// turns screen on
|
g.flip();// turns screen on
|
||||||
}
|
}
|
||||||
NRF.on('connect',changed);
|
NRF.on('connect',changed);
|
||||||
NRF.on('disconnect',changed);
|
NRF.on('disconnect',changed);
|
||||||
WIDGETS["bluetooth"]={area:"tr",width:24,draw:draw};
|
WIDGETS["bluetooth"]={area:"tr",width:24,draw:draw};
|
||||||
})()
|
})()
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ var SETTINGS = {
|
||||||
};
|
};
|
||||||
var Utils = require("../js/utils.js");
|
var Utils = require("../js/utils.js");
|
||||||
var AppInfo = require("../js/appinfo.js");
|
var AppInfo = require("../js/appinfo.js");
|
||||||
|
var noble = require('@abandonware/noble');
|
||||||
var apps;
|
var apps;
|
||||||
|
|
||||||
function ERROR(msg) {
|
function ERROR(msg) {
|
||||||
|
|
@ -62,7 +63,6 @@ function cmdInstallApp(appId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function bangleSend(command) {
|
function bangleSend(command) {
|
||||||
var noble = require('noble');
|
|
||||||
var log = function() {
|
var log = function() {
|
||||||
var args = [].slice.call(arguments);
|
var args = [].slice.call(arguments);
|
||||||
console.log("UART: "+args.join(" "));
|
console.log("UART: "+args.join(" "));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
espruinotools.js
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 6,
|
||||||
|
"sourceType": "script"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"indent": [
|
||||||
|
"warn",
|
||||||
|
2,
|
||||||
|
{
|
||||||
|
"SwitchCase": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"node": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@ if (typeof btoa==="undefined") {
|
||||||
// Don't define btoa as a function here because Apple's
|
// Don't define btoa as a function here because Apple's
|
||||||
// iOS browser defines the function even though it's in
|
// iOS browser defines the function even though it's in
|
||||||
// an IF statement that is never executed!
|
// an IF statement that is never executed!
|
||||||
btoa = function(d) { return BufferA.from(d).toString('base64'); }
|
btoa = function(d) { return Buffer.from(d).toString('base64'); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts a string into most efficient way to send to Espruino (either json, base64, or compressed base64)
|
// Converts a string into most efficient way to send to Espruino (either json, base64, or compressed base64)
|
||||||
|
|
|
||||||
44
js/comms.js
44
js/comms.js
|
|
@ -2,13 +2,13 @@ Puck.debug=3;
|
||||||
|
|
||||||
// FIXME: use UART lib so that we handle errors properly
|
// FIXME: use UART lib so that we handle errors properly
|
||||||
var Comms = {
|
var Comms = {
|
||||||
reset : (opt) => new Promise((resolve,reject) => {
|
reset : (opt) => new Promise((resolve,reject) => {
|
||||||
Puck.write(`\x03\x10reset(${opt=="wipe"?"1":""});\n`, (result) => {
|
Puck.write(`\x03\x10reset(${opt=="wipe"?"1":""});\n`, (result) => {
|
||||||
if (result===null) return reject("Connection failed");
|
if (result===null) return reject("Connection failed");
|
||||||
setTimeout(resolve,500);
|
setTimeout(resolve,500);
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
uploadApp : (app,skipReset) => { // expects an apps.json structure (i.e. with `storage`)
|
uploadApp : (app,skipReset) => { // expects an apps.json structure (i.e. with `storage`)
|
||||||
Progress.show({title:`Uploading ${app.name}`,sticky:true});
|
Progress.show({title:`Uploading ${app.name}`,sticky:true});
|
||||||
return AppInfo.getFiles(app, {
|
return AppInfo.getFiles(app, {
|
||||||
fileGetter : httpGet,
|
fileGetter : httpGet,
|
||||||
|
|
@ -75,8 +75,8 @@ uploadApp : (app,skipReset) => { // expects an apps.json structure (i.e. with `s
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getInstalledApps : () => {
|
getInstalledApps : () => {
|
||||||
Progress.show({title:`Getting app list...`,sticky:true});
|
Progress.show({title:`Getting app list...`,sticky:true});
|
||||||
return new Promise((resolve,reject) => {
|
return new Promise((resolve,reject) => {
|
||||||
Puck.write("\x03",(result) => {
|
Puck.write("\x03",(result) => {
|
||||||
|
|
@ -101,8 +101,8 @@ getInstalledApps : () => {
|
||||||
}, true /* callback on newline */);
|
}, true /* callback on newline */);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
removeApp : app => { // expects an appid.info structure (i.e. with `files`)
|
removeApp : app => { // expects an appid.info structure (i.e. with `files`)
|
||||||
if (!app.files && !app.data) return Promise.resolve(); // nothing to erase
|
if (!app.files && !app.data) return Promise.resolve(); // nothing to erase
|
||||||
Progress.show({title:`Removing ${app.name}`,sticky:true});
|
Progress.show({title:`Removing ${app.name}`,sticky:true});
|
||||||
let cmds = '\x10const s=require("Storage");\n';
|
let cmds = '\x10const s=require("Storage");\n';
|
||||||
|
|
@ -138,8 +138,8 @@ removeApp : app => { // expects an appid.info structure (i.e. with `files`)
|
||||||
Progress.hide({sticky:true});
|
Progress.hide({sticky:true});
|
||||||
return Promise.reject(reason);
|
return Promise.reject(reason);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
removeAllApps : () => {
|
removeAllApps : () => {
|
||||||
Progress.show({title:"Removing all apps",progess:"animate",sticky:true});
|
Progress.show({title:"Removing all apps",progess:"animate",sticky:true});
|
||||||
return new Promise((resolve,reject) => {
|
return new Promise((resolve,reject) => {
|
||||||
// Use write with newline here so we wait for it to finish
|
// Use write with newline here so we wait for it to finish
|
||||||
|
|
@ -149,8 +149,8 @@ removeAllApps : () => {
|
||||||
resolve();
|
resolve();
|
||||||
}, true /* wait for newline */);
|
}, true /* wait for newline */);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setTime : () => {
|
setTime : () => {
|
||||||
return new Promise((resolve,reject) => {
|
return new Promise((resolve,reject) => {
|
||||||
var d = new Date();
|
var d = new Date();
|
||||||
var tz = d.getTimezoneOffset()/-60
|
var tz = d.getTimezoneOffset()/-60
|
||||||
|
|
@ -163,15 +163,15 @@ setTime : () => {
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
disconnectDevice: () => {
|
disconnectDevice: () => {
|
||||||
var connection = Puck.getConnection();
|
var connection = Puck.getConnection();
|
||||||
|
|
||||||
if (!connection) return;
|
if (!connection) return;
|
||||||
|
|
||||||
connection.close();
|
connection.close();
|
||||||
},
|
},
|
||||||
watchConnectionChange : cb => {
|
watchConnectionChange : cb => {
|
||||||
var connected = Puck.isConnected();
|
var connected = Puck.isConnected();
|
||||||
|
|
||||||
//TODO Switch to an event listener when Puck will support it
|
//TODO Switch to an event listener when Puck will support it
|
||||||
|
|
@ -186,8 +186,8 @@ watchConnectionChange : cb => {
|
||||||
return () => {
|
return () => {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
listFiles : () => {
|
listFiles : () => {
|
||||||
return new Promise((resolve,reject) => {
|
return new Promise((resolve,reject) => {
|
||||||
Puck.write("\x03",(result) => {
|
Puck.write("\x03",(result) => {
|
||||||
if (result===null) return reject("");
|
if (result===null) return reject("");
|
||||||
|
|
@ -200,8 +200,8 @@ listFiles : () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
readFile : (file) => {
|
readFile : (file) => {
|
||||||
return new Promise((resolve,reject) => {
|
return new Promise((resolve,reject) => {
|
||||||
//encode name to avoid serialization issue due to octal sequence
|
//encode name to avoid serialization issue due to octal sequence
|
||||||
const name = encodeURIComponent(file);
|
const name = encodeURIComponent(file);
|
||||||
|
|
@ -216,8 +216,8 @@ readFile : (file) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
readStorageFile : (filename) => { // StorageFiles are different to normal storage entries
|
readStorageFile : (filename) => { // StorageFiles are different to normal storage entries
|
||||||
return new Promise((resolve,reject) => {
|
return new Promise((resolve,reject) => {
|
||||||
// Use "\xFF" to signal end of file (can't occur in files anyway)
|
// Use "\xFF" to signal end of file (can't occur in files anyway)
|
||||||
var fileContent = "";
|
var fileContent = "";
|
||||||
|
|
@ -261,5 +261,5 @@ readStorageFile : (filename) => { // StorageFiles are different to normal storag
|
||||||
console.log(`StorageFile read started...`);
|
console.log(`StorageFile read started...`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
11
js/index.js
11
js/index.js
|
|
@ -458,15 +458,20 @@ function getAppsToUpdate() {
|
||||||
function refreshMyApps() {
|
function refreshMyApps() {
|
||||||
var panelbody = document.querySelector("#myappscontainer .panel-body");
|
var panelbody = document.querySelector("#myappscontainer .panel-body");
|
||||||
panelbody.innerHTML = appsInstalled.map(appInstalled => {
|
panelbody.innerHTML = appsInstalled.map(appInstalled => {
|
||||||
var app = appNameToApp(appInstalled.id);
|
var app = appNameToApp(appInstalled.id);
|
||||||
var version = getVersionInfo(app, appInstalled);
|
var version = getVersionInfo(app, appInstalled);
|
||||||
return `<div class="tile column col-6 col-sm-12 col-xs-12">
|
var username = "espruino";
|
||||||
|
var githubMatch = window.location.href.match(/\/(\w+)\.github\.io/);
|
||||||
|
if(githubMatch) username = githubMatch[1];
|
||||||
|
var url = `https://github.com/${username}/BangleApps/tree/master/apps/${app.id}`;
|
||||||
|
return `<div class="tile column col-6 col-sm-12 col-xs-12">
|
||||||
<div class="tile-icon">
|
<div class="tile-icon">
|
||||||
<figure class="avatar"><img src="apps/${app.icon?`${app.id}/${app.icon}`:"unknown.png"}" alt="${escapeHtml(app.name)}"></figure>
|
<figure class="avatar"><img src="apps/${app.icon?`${app.id}/${app.icon}`:"unknown.png"}" alt="${escapeHtml(app.name)}"></figure>
|
||||||
</div>
|
</div>
|
||||||
<div class="tile-content">
|
<div class="tile-content">
|
||||||
<p class="tile-title text-bold">${escapeHtml(app.name)} <small>(${version.text})</small></p>
|
<p class="tile-title text-bold">${escapeHtml(app.name)} <small>(${version.text})</small></p>
|
||||||
<p class="tile-subtitle">${escapeHtml(app.description)}</p>
|
<p class="tile-subtitle">${escapeHtml(app.description)}</p>
|
||||||
|
<a href="${url}" target="_blank" class="link-github"><img src="img/github-icon-sml.png" alt="See the code on GitHub"/></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="tile-action">
|
<div class="tile-action">
|
||||||
<button class="btn btn-link btn-action btn-lg ${(appInstalled&&app.interface)?"":"d-hide"}" appid="${app.id}" title="Download data from app"><i class="icon icon-download"></i></button>
|
<button class="btn btn-link btn-action btn-lg ${(appInstalled&&app.interface)?"":"d-hide"}" appid="${app.id}" title="Download data from app"><i class="icon icon-download"></i></button>
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,12 @@
|
||||||
"author": "Gordon Williams <gw@pur3.co.uk> (http://espruino.com)",
|
"author": "Gordon Williams <gw@pur3.co.uk> (http://espruino.com)",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"acorn": ""
|
"acorn": "",
|
||||||
|
"eslint": "7.1.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node bin/sanitycheck.js",
|
"lint-apps": "eslint ./apps --ext .js",
|
||||||
|
"test": "node bin/sanitycheck.js && eslint ./apps --ext .js && eslint ./js",
|
||||||
"start": "npx http-server"
|
"start": "npx http-server"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue