Merge remote-tracking branch 'upstream/master'
commit
fc070cdd71
|
|
@ -5,3 +5,4 @@ package-lock.json
|
|||
*.js.bak
|
||||
appdates.csv
|
||||
.vscode
|
||||
.idea/
|
||||
|
|
|
|||
10
README.md
10
README.md
|
|
@ -219,7 +219,12 @@ and which gives information about the app for the Launcher.
|
|||
"shortName": "Short name", // short name for launcher
|
||||
"icon": "icon.png", // icon in apps/
|
||||
"description": "...", // long description (can contain markdown)
|
||||
"type":"...", // optional(if app) - 'app'/'widget'/'launch'/'bootloader'
|
||||
"type":"...", // optional(if app) -
|
||||
// 'app' - an application
|
||||
// 'widget' - a widget
|
||||
// 'launch' - replacement launcher app
|
||||
// 'bootloader' - code that runs at startup only
|
||||
// 'RAM' - code that runs and doesn't upload anything to storage
|
||||
"tags": "", // comma separated tag list for searching
|
||||
"dependencies" : { "notify":"type" } // optional, app 'types' we depend on
|
||||
// for instance this will use notify/notifyfs is they exist, or will pull in 'notify'
|
||||
|
|
@ -241,7 +246,8 @@ and which gives information about the app for the Launcher.
|
|||
// add an icon to allow your app to be tested
|
||||
|
||||
"storage": [ // list of files to add to storage
|
||||
{"name":"appid.js", // filename to use in storage
|
||||
{"name":"appid.js", // filename to use in storage.
|
||||
// If name=='RAM', the code is sent directly to Bangle.js and is not saved to a file
|
||||
"url":"", // URL of file to load (currently relative to apps/)
|
||||
"content":"..." // if supplied, this content is loaded directly
|
||||
"evaluate":true // if supplied, data isn't quoted into a String before upload
|
||||
|
|
|
|||
29
apps.json
29
apps.json
|
|
@ -80,7 +80,7 @@
|
|||
"name": "Notifications (default)",
|
||||
"shortName":"Notifications",
|
||||
"icon": "notify.png",
|
||||
"version":"0.03",
|
||||
"version":"0.05",
|
||||
"description": "A handler for displaying notifications that displays them in a bar at the top of the screen",
|
||||
"tags": "widget",
|
||||
"type": "notify",
|
||||
|
|
@ -93,7 +93,7 @@
|
|||
"name": "Fullscreen Notifications",
|
||||
"shortName":"Notifications",
|
||||
"icon": "notify.png",
|
||||
"version":"0.04",
|
||||
"version":"0.06",
|
||||
"description": "A handler for displaying notifications that displays them fullscreen. This may not fully restore the screen after on some apps. See `Notifications (default)` for more information about the notifications library.",
|
||||
"tags": "widget",
|
||||
"type": "notify",
|
||||
|
|
@ -692,6 +692,19 @@
|
|||
{"name":"sclock.img","url":"clock-simple-icon.js","evaluate":true}
|
||||
]
|
||||
},
|
||||
{ "id": "vibrclock",
|
||||
"name": "Vibrate Clock",
|
||||
"icon": "app.png",
|
||||
"version":"0.01",
|
||||
"description": "When BTN1 is pressed, vibrate out the time as a series of buzzes, one digit at a time. Hours, then Minutes. Zero is signified by one long buzz. Otherwise a simple digital clock.",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
{"name":"vibrclock.app.js","url":"app.js"},
|
||||
{"name":"vibrclock.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
},
|
||||
{ "id": "svclock",
|
||||
"name": "Simple V-Clock",
|
||||
"icon": "vclock-simple.png",
|
||||
|
|
@ -882,6 +895,16 @@
|
|||
{"name":"gpsinfo.img","url": "gps-info-icon.js","evaluate": true}
|
||||
]
|
||||
},
|
||||
{ "id": "assistedgps",
|
||||
"name": "Assisted GPS Update",
|
||||
"icon": "app.png",
|
||||
"version":"0.01",
|
||||
"description": "Downloads assisted GPS data to Bangle.js for faster GPS startup and more accurate fixes",
|
||||
"custom": "custom.html",
|
||||
"tags": "tool,outdoors",
|
||||
"type": "RAM",
|
||||
"storage": [ ]
|
||||
},
|
||||
{
|
||||
"id": "pomodo",
|
||||
"name":"Pomodoro",
|
||||
|
|
@ -1421,7 +1444,7 @@
|
|||
"name": "Digital Assistant, not EDITH",
|
||||
"shortName": "DANE",
|
||||
"icon": "app.png",
|
||||
"version": "0.07",
|
||||
"version": "0.10",
|
||||
"description": "A Watchface inspired by Tony Stark's EDITH",
|
||||
"tags": "clock",
|
||||
"type": "clock",
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
0.01: New App!
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -0,0 +1,113 @@
|
|||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="../../css/spectre.min.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>Assisted GPS</h2>
|
||||
<p>GPS can take a long time (~5 minutes) to get an accurate position the first time it is used.
|
||||
AGPS uploads a few hints to the GPS receiver about satellite positions that allow it
|
||||
to get a faster, more accurate fix - however they are only valid for a short period of time.</p>
|
||||
<p>You can upload data that covers a longer period of time, but the upload will take longer.</p>
|
||||
<div class="form-group">
|
||||
<label class="form-label">AGPS Validity time</label>
|
||||
<label class="form-radio">
|
||||
<input type="radio" name="agpsperiod" value="1d" checked><i class="form-icon"></i> 1 day (8kB)
|
||||
</label>
|
||||
<label class="form-radio">
|
||||
<input type="radio" name="agpsperiod" value="2d"><i class="form-icon"></i> 2 days (14kB)
|
||||
</label>
|
||||
<label class="form-radio">
|
||||
<input type="radio" name="agpsperiod" value="3d"><i class="form-icon"></i> 3 days (20kB)
|
||||
</label>
|
||||
<label class="form-radio">
|
||||
<input type="radio" name="agpsperiod" value="1wk"><i class="form-icon"></i> 1 week (46kB)
|
||||
</label>
|
||||
</div>
|
||||
<p>Click <button id="upload" class="btn btn-primary">Upload</button></p>
|
||||
|
||||
<script src="../../core/lib/customize.js"></script>
|
||||
|
||||
<script>
|
||||
// When the 'upload' button is clicked...
|
||||
document.getElementById("upload").addEventListener("click", function() {
|
||||
var radios = document.getElementsByName('agpsperiod');
|
||||
var url = "https://www.espruino.com/agps/assistnow_1d.base64";
|
||||
for (var i=0; i<radios.length; i++)
|
||||
if (radios[i].checked)
|
||||
url = "https://www.espruino.com/agps/assistnow_"+radios[i].value+".base64";
|
||||
console.log("Sending...");
|
||||
//var text = document.getElementById("agpsperiod").value;
|
||||
get(url, function(b64) {
|
||||
var js = jsFromBase64(b64);
|
||||
sendCustomizedApp({
|
||||
storage:[
|
||||
{name:"RAM", content:js},
|
||||
]
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function UBX_CMD(cmd) {
|
||||
var d = [0xB5,0x62]; // sync chars
|
||||
d = d.concat(cmd);
|
||||
var a=0,b=0;
|
||||
for (var i=2;i<d.length;i++) {
|
||||
a += d[i];
|
||||
b += a;
|
||||
}
|
||||
d.push(a&255,b&255);
|
||||
return d;
|
||||
}
|
||||
function UBX_MGA_INI_TIME_UTC() {
|
||||
var a = new Uint8Array(4+24);
|
||||
a.set([0x13,0x40,24,0]);
|
||||
a.set([ 0x10, // 0: type
|
||||
0, // 1: version
|
||||
0, // 2: ref - none
|
||||
0x80] ); // 3: leapsecs - unknown
|
||||
var d = new Date();
|
||||
d.setTime(d.getTime()+d.getTimezoneOffset()*60000); // get as UTC
|
||||
var dv = new DataView(a.buffer, 4);
|
||||
dv.setUint16(4, d.getFullYear());
|
||||
dv.setUint8(6, d.getMonth()+1);
|
||||
dv.setUint8(7, d.getDate());
|
||||
dv.setUint8(8, d.getHours());
|
||||
dv.setUint8(9, d.getMinutes());
|
||||
dv.setUint8(10, d.getSeconds());
|
||||
dv.setUint16(16, 10*60); // seconds part of accuracy - 10 minutes
|
||||
return UBX_CMD([].slice.call(a));
|
||||
}
|
||||
|
||||
function jsFromBase64(b64) {
|
||||
var bin = atob(b64);
|
||||
var chunkSize = 128;
|
||||
var js = "\x10Bangle.setGPSPower(1);\n"; // turn GPS on
|
||||
//js += `\x10Bangle.on('GPS-raw',function (d) { if (d.startsWith("\\xB5\\x62\\x05\\x01")) Terminal.println("GPS ACK"); else if (d.startsWith("\\xB5\\x62\\x05\\x00")) Terminal.println("GPS NACK"); })\n`;
|
||||
js += "\x10E.showMessage('Uploading...','AGPS');function p(n) {g.fillRect(0,g.getHeight()-80,g.getWidth()*n,g.getHeight()-60);}";
|
||||
//js += "\x10var t=getTime()+1;while(t>getTime());\n"; // wait 1 sec
|
||||
js += `\x10Serial1.write(atob("${btoa(String.fromCharCode.apply(null,UBX_MGA_INI_TIME_UTC()))}"))\n`; // set GPS time
|
||||
|
||||
for (var i=0;i<bin.length;i+=chunkSize) {
|
||||
var chunk = bin.substr(i,chunkSize);
|
||||
js += `\x10p(${Math.round(100*i/bin.length)/100});Serial1.write(atob("${btoa(chunk)}"))\n`;
|
||||
}
|
||||
js += "\x10p(1);\n"; // finish progress bar
|
||||
return js;
|
||||
}
|
||||
|
||||
function get(url,callback) {
|
||||
console.log("Loading "+url);
|
||||
var oReq = new XMLHttpRequest();
|
||||
oReq.addEventListener("load", function() {
|
||||
var b64 = this.responseText;
|
||||
console.log("Response received...");
|
||||
callback(b64);
|
||||
});
|
||||
oReq.open("GET", url);
|
||||
oReq.send();
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -2,4 +2,7 @@
|
|||
0.04: Added Icon to watchface
|
||||
0.05: bugfix
|
||||
0.06: moved and resized icon
|
||||
0.07: Added Description
|
||||
0.07: Added Description
|
||||
0.08: Removed Image, Reduced RAM usage
|
||||
0.09: Added Unix Time
|
||||
0.10: Added Counter, Added Battery Display
|
||||
171
apps/dane/app.js
171
apps/dane/app.js
|
|
@ -1,66 +1,81 @@
|
|||
const font = "6x8";
|
||||
const timeFontSize = 4;
|
||||
const unixTimeFontSize = 2;
|
||||
const dateFontSize = 3;
|
||||
const smallFontSize = 2;
|
||||
const yOffset = 23;
|
||||
const xyCenter = g.getWidth()/2;
|
||||
const width = g.getWidth();
|
||||
const height = g.getHeight();
|
||||
const xyCenter = width/2+4;
|
||||
const cornerSize = 14;
|
||||
const cornerOffset = 3;
|
||||
const borderWidth = 1;
|
||||
const yposTime = 27+yOffset;
|
||||
const yposDate = 65+yOffset;
|
||||
const yposDate = 65+yOffset+12;
|
||||
const yposCounter = 58+yOffset+35+40;
|
||||
|
||||
const mainColor = "#26dafd";
|
||||
const mainColorDark = "#029dbb";
|
||||
const mainColorLight = "#8bebfe";
|
||||
// const mainColorLight = "#8bebfe";
|
||||
|
||||
const secondaryColor = "#df9527";
|
||||
const secondaryColorDark = "#8b5c15";
|
||||
const secondaryColorLight = "#ecc180";
|
||||
// const secondaryColorLight = "#ecc180";
|
||||
|
||||
const success = "#00ff00";
|
||||
const successDark = "#000900";
|
||||
const successLight = "#060f06";
|
||||
// const successDark = "#000900";
|
||||
// const successLight = "#060f06";
|
||||
|
||||
const alert = "#ff0000";
|
||||
const alertDark = "#090000";
|
||||
const alertLight = "#0f0606";
|
||||
// const alertDark = "#090000";
|
||||
// const alertLight = "#0f0606";
|
||||
|
||||
let count = 100;
|
||||
|
||||
|
||||
// function getImg() {
|
||||
// return atob("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");
|
||||
// }
|
||||
|
||||
// function makeImg() {
|
||||
// return {
|
||||
// width : 120, height : 120, bpp : 8,
|
||||
// transparent : 254,
|
||||
// buffer : require("heatshrink").decompress(getImg())
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
var img = {
|
||||
width : 120, height : 120, bpp : 8,
|
||||
transparent : 254,
|
||||
buffer : require("heatshrink").decompress(atob("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"))
|
||||
}
|
||||
|
||||
|
||||
function drawTopLeftCorner(x,y) {
|
||||
g.setColor(mainColor);
|
||||
var x1 = x-cornerOffset;
|
||||
var y1 = y-cornerOffset;
|
||||
const x1 = x - cornerOffset;
|
||||
const y1 = y - cornerOffset;
|
||||
g.fillRect(x1,y1,x1+cornerSize,y1+cornerSize);
|
||||
g.setColor("#000000");
|
||||
g.fillRect(x,y,x+cornerSize-cornerOffset,y+cornerSize-cornerOffset);
|
||||
}
|
||||
function drawTopRightCorner(x,y) {
|
||||
g.setColor(mainColor);
|
||||
var x1 = x+cornerOffset;
|
||||
var y1 = y-cornerOffset;
|
||||
const x1 = x + cornerOffset;
|
||||
const y1 = y - cornerOffset;
|
||||
g.fillRect(x1,y1,x1-cornerSize,y1+cornerSize);
|
||||
g.setColor("#000000");
|
||||
g.fillRect(x,y,x-cornerSize-cornerOffset,y+cornerSize-cornerOffset);
|
||||
}
|
||||
function drawBottomLeftCorner(x,y) {
|
||||
g.setColor(mainColor);
|
||||
var x1 = x-cornerOffset;
|
||||
var y1 = y+cornerOffset;
|
||||
const x1 = x - cornerOffset;
|
||||
const y1 = y + cornerOffset;
|
||||
g.fillRect(x1,y1,x1+cornerSize,y1-cornerSize);
|
||||
g.setColor("#000000");
|
||||
g.fillRect(x,y,x+cornerSize-cornerOffset,y-cornerSize+cornerOffset);
|
||||
}
|
||||
function drawBottomRightCorner(x,y) {
|
||||
g.setColor(mainColor);
|
||||
var x1 = x+cornerOffset;
|
||||
var y1 = y+cornerOffset;
|
||||
const x1 = x + cornerOffset;
|
||||
const y1 = y + cornerOffset;
|
||||
g.fillRect(x1,y1,x1-cornerSize,y1-cornerSize);
|
||||
g.setColor("#000000");
|
||||
g.fillRect(x,y,x-cornerSize+cornerOffset,y-cornerSize+cornerOffset);
|
||||
|
|
@ -85,79 +100,137 @@ function drawTopFrame(x1,y1,x2,y2) {
|
|||
g.setColor("#000000");
|
||||
g.fillRect(x1+borderWidth,y1+borderWidth,x2-borderWidth,y2-borderWidth);
|
||||
}
|
||||
function drawBottomFrame(x1,y1,x2,y2) {
|
||||
drawTopLeftCorner(x1,y1);
|
||||
drawTopRightCorner(x2,y1);
|
||||
|
||||
function drawFrameNoCorners(x1,y1,x2,y2) {
|
||||
g.setColor(mainColorDark);
|
||||
g.drawRect(x1,y1,x2,y2);
|
||||
g.setColor("#000000");
|
||||
g.fillRect(x1+borderWidth,y1+borderWidth,x2-borderWidth,y2-borderWidth);
|
||||
}
|
||||
// function drawBottomFrame(x1,y1,x2,y2) {
|
||||
// drawTopLeftCorner(x1,y1);
|
||||
// drawTopRightCorner(x2,y1);
|
||||
// g.setColor(mainColorDark);
|
||||
// g.drawRect(x1,y1,x2,y2);
|
||||
// g.setColor("#000000");
|
||||
// g.fillRect(x1+borderWidth,y1+borderWidth,x2-borderWidth,y2-borderWidth);
|
||||
// }
|
||||
|
||||
function getUTCTime(d) {
|
||||
return d.toUTCString().split(' ')[4].split(':').map(function(d){return Number(d);});
|
||||
}
|
||||
// function getUTCTime(d) {
|
||||
// return d.toUTCString().split(' ')[4].split(':').map(function(d){return Number(d);});
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
function drawTimeText(d) {
|
||||
const da = d.toString().split(" ");
|
||||
// var dutc = getUTCTime(d);
|
||||
|
||||
function drawTimeText() {
|
||||
g.setFontAlign(0, 0);
|
||||
var d = new Date();
|
||||
var da = d.toString().split(" ");
|
||||
var dutc = getUTCTime(d);
|
||||
|
||||
var time = da[4].split(":");
|
||||
var hours = time[0],
|
||||
const time = da[4].split(":");
|
||||
const hours = time[0],
|
||||
minutes = time[1],
|
||||
seconds = time[2];
|
||||
g.setColor(mainColor);
|
||||
g.setFont(font, timeFontSize);
|
||||
g.drawString(`${hours}:${minutes}:${seconds}`, xyCenter, yposTime, true);
|
||||
const unix = Math.round(d.getTime());
|
||||
|
||||
g.setFont(font, unixTimeFontSize);
|
||||
g.setColor(secondaryColor);
|
||||
g.drawString(`${unix}`, xyCenter, yposTime +22, true);
|
||||
g.setFont(font, smallFontSize);
|
||||
}
|
||||
function drawDateText() {
|
||||
g.setFontAlign(0, 0);
|
||||
var d = new Date();
|
||||
function drawDateText(d) {
|
||||
g.setColor(mainColor);
|
||||
g.setFont(font, dateFontSize);
|
||||
g.drawString(`${d.getDate()}.${d.getMonth()+1}.${d.getFullYear()}`, xyCenter, yposDate, true);
|
||||
}
|
||||
|
||||
function drawCounterText() {
|
||||
if(count>999) count = 999;
|
||||
if(count<0) count = 0;
|
||||
g.setColor("#000000");
|
||||
g.fillRect(37,58+yOffset+36,203,58+80+yOffset+34);
|
||||
g.setFontAlign(0, 0);
|
||||
g.setColor(alert);
|
||||
g.setFont(font, 8);
|
||||
g.drawString(`${count}`, xyCenter, yposCounter, true);
|
||||
|
||||
|
||||
}
|
||||
|
||||
function levelColor(l) {
|
||||
// no icon -> brightest green to indicate charging, even when showing percentage
|
||||
if (Bangle.isCharging()) return success;
|
||||
if (l >= 50) return success;
|
||||
if (l >= 15) return secondaryColorDark;
|
||||
return alert;
|
||||
}
|
||||
|
||||
function drawBattery() {
|
||||
const l = E.getBattery(), c = levelColor(l);
|
||||
const xl = 45+l*(194-46)/100;
|
||||
g.setColor(c).fillRect(46,58+80+yOffset+37,xl, height-5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function drawClock() {
|
||||
// main frame
|
||||
drawFrame(3,10+yOffset,g.getWidth()-3,g.getHeight()-3);
|
||||
drawFrame(3,10+yOffset,width-3,height-3);
|
||||
// time frame
|
||||
drawTopFrame(20,10+yOffset,220,46+yOffset);
|
||||
drawTopFrame(20,10+yOffset,220,58+yOffset);
|
||||
// date frame
|
||||
drawTopFrame(28,46+yOffset,212,46+yOffset+35);
|
||||
drawTopFrame(28,58+yOffset,212,58+yOffset+35);
|
||||
|
||||
// texts
|
||||
drawTimeText();
|
||||
drawDateText();
|
||||
g.drawImage(img,g.getWidth()/2-(img.width/2),g.getHeight()/2);
|
||||
// counter frame
|
||||
drawTopFrame(36,58+yOffset+35,204,58+80+yOffset+35);
|
||||
|
||||
// battery frame
|
||||
drawFrameNoCorners(44,58+80+yOffset+35,196, height-3);
|
||||
|
||||
|
||||
updateClock();
|
||||
|
||||
// const img = makeImg();
|
||||
// g.drawImage(img,width/2-(img.width/2),height/2);
|
||||
}
|
||||
function updateClock() {
|
||||
drawTimeText();
|
||||
drawDateText();
|
||||
g.setFontAlign(0, 0);
|
||||
const date = new Date();
|
||||
drawTimeText(date);
|
||||
drawDateText(date);
|
||||
drawCounterText();
|
||||
drawBattery();
|
||||
}
|
||||
|
||||
|
||||
Bangle.on('lcdPower', function(on) {
|
||||
if (on) drawClock();
|
||||
|
||||
});
|
||||
|
||||
|
||||
g.clear();
|
||||
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
||||
|
||||
drawClock();
|
||||
|
||||
|
||||
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
|
||||
setWatch(function() {
|
||||
count+=1;
|
||||
drawCounterText();
|
||||
}, BTN1, {repeat:true,edge:"falling"});
|
||||
setWatch(function() {
|
||||
count--;
|
||||
drawCounterText();
|
||||
}, BTN3, {repeat:true,edge:"falling"});
|
||||
|
||||
// refesh every 100 milliseconds
|
||||
setInterval(updateClock, 100);
|
||||
setInterval(updateClock, 500);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
0.01: New Library!
|
||||
0.02: Add notification ID option
|
||||
0.03: Pass `area{x,y,w,h}` to render callback instead of just `y`
|
||||
0.03: Pass `area{x,y,w,h}` to render callback instead of just `y`
|
||||
0.05: Adjust position of notification src text
|
||||
|
|
|
|||
|
|
@ -94,8 +94,8 @@ exports.show = function(options) {
|
|||
g.setColor(-1).setFontAlign(-1, -1, 0).setFont("6x8", 2);
|
||||
g.drawString(title.trim().substring(0, 13), x+25,y+3);
|
||||
if (options.title && options.src) {
|
||||
g.setFont("6x8", 1);
|
||||
g.drawString(options.src.substring(0, 10), x+215,y+5);
|
||||
g.setFont("6x8", 1).setFontAlign(1, 1, 0);
|
||||
g.drawString(options.src.substring(0, 10), g.getWidth()-23,y+18);
|
||||
}
|
||||
y += 20;h -= 20;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
0.01: New Library!
|
||||
0.02: Add notification ID option
|
||||
0.03: Fix custom render callback
|
||||
0.04: Pass `area{x,y,w,h}` to render callback instead of just `y`
|
||||
0.04: Pass `area{x,y,w,h}` to render callback instead of just `y`
|
||||
0.05: Fix `g` corruption issue if .hide gets called twice
|
||||
0.06: Adjust position of notification src text and notifications without title
|
||||
|
|
|
|||
|
|
@ -49,14 +49,13 @@ exports.show = function(options) {
|
|||
if (size>120) {size=120}
|
||||
Bangle.setLCDMode("direct");
|
||||
let x = 0,
|
||||
y = 0,
|
||||
y = 40,
|
||||
w = 240,
|
||||
h = 240;
|
||||
h = size;
|
||||
// clear screen
|
||||
g.clear(1);
|
||||
// top bar
|
||||
if (options.title||options.src) {
|
||||
y=40;h=size;
|
||||
const title = options.title || options.src
|
||||
g.setColor(0x39C7).fillRect(x, y, x+w-1, y+30);
|
||||
g.setColor(-1).setFontAlign(-1, -1, 0).setFont("6x8", 3);
|
||||
|
|
@ -64,7 +63,8 @@ exports.show = function(options) {
|
|||
if (options.title && options.src) {
|
||||
g.setColor(-1).setFontAlign(1, 1, 0).setFont("6x8", 2);
|
||||
// above drawing area, but we are fullscreen
|
||||
g.drawString(options.src.substring(0, 10), x+235, y-32);
|
||||
print(options.src.substring(0, 10), w-23, y-4);
|
||||
g.drawString(options.src.substring(0, 10), w-16, y-4);
|
||||
}
|
||||
y += 30;h -= 30;
|
||||
}
|
||||
|
|
@ -106,8 +106,10 @@ exports.hide = function(options) {
|
|||
options = options||{};
|
||||
if ("id" in options && options.id!==id) return;
|
||||
id = null;
|
||||
g=oldg;
|
||||
oldg = undefined;
|
||||
if (oldg) {
|
||||
g=oldg;
|
||||
oldg = undefined;
|
||||
}
|
||||
Bangle.removeListener("touch", exports.hide);
|
||||
g.clear();
|
||||
Bangle.drawWidgets();
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
0.01: First commit
|
||||
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4ATlgAGFlgylEQUyq1WwOB1msAYIHBmQxeDwQrB1nXABA0BqwxaP4eBFhIAFwIwYLgYtPAAZiWCgMrLhS7BMRUrGCQuN1gvBYxQwCF6S6LF5rEDFyC7MF5zDDF50rD5gvP1iRORpovRSJ6NNF6SRCLzQvSMBksmQdOF6OsmQvLRxwvSSBZqBF5+BmUyUJwvCGBC+QwMrCQMrCZ4vZxErLoJhBGAOsAAgvTwR6OH4QfBmTEBAAYwGwQv7R5uCR8DbOrrvSOoIuHF4VWDZ2CQwOICR3XFxAwCF54ATF5cyUo4vmYB4AM63P53O5/Q6wvKSDfW52j44AC0YFBMEnPFgYAGGBcrYKvWFAnP64wPMAKRV5wuE63W6HIMB6RU6y7E5HO6BfF0aRMGCS9D54EBF4I3BTIhgMGCSOCXYIwBSAICC6ySCF5QwCYYL0PF4fW53OAYjzDF5ZiTR4g0BR4OiR4LxDF5piEwJjLW4QACLgLvBFobvMGJEyqwzBwOCwQ3E6wvFXYLtEF6QxEAAtWBoYmEeYReERx4yNBYowFAAouWABouuAATDE0a7TAH4ASA"))
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
// Simple clock from https://www.espruino.com/Bangle.js+Clock
|
||||
// Load fonts
|
||||
require("Font7x11Numeric7Seg").add(Graphics);
|
||||
// Check settings for what type our clock should be
|
||||
var is12Hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"];
|
||||
// position on screen
|
||||
const X = 160, Y = 140;
|
||||
|
||||
function draw() {
|
||||
// work out how to display the current time
|
||||
var d = new Date();
|
||||
var h = d.getHours(), m = d.getMinutes();
|
||||
if (is12Hour) {
|
||||
if (h == 0) h = 12;
|
||||
else if (h>12) h -= 12;
|
||||
}
|
||||
var time = (" "+h).substr(-2) + ":" + ("0"+m).substr(-2);
|
||||
// Reset the state of the graphics library
|
||||
g.reset();
|
||||
// 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*/);
|
||||
// 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, Y+15, true /*clear background*/);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
secondInterval = 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" });
|
||||
|
||||
// ====================================== Vibration
|
||||
// vibrate 0..9
|
||||
function vibrateDigit(num) {
|
||||
if (num==0) return Bangle.buzz(500);
|
||||
return new Promise(function f(resolve){
|
||||
if (num--<=0) return resolve();
|
||||
Bangle.buzz(100).then(()=>{
|
||||
setTimeout(()=>f(resolve), 200);
|
||||
});
|
||||
});
|
||||
}
|
||||
// vibrate multiple digits (num must be a string)
|
||||
function vibrateNumber(num) {
|
||||
return new Promise(function f(resolve){
|
||||
if (!num.length) return resolve();
|
||||
var digit = num[0];
|
||||
num = num.substr(1);
|
||||
vibrateDigit(digit).then(()=>{
|
||||
setTimeout(()=>f(resolve),500);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var vibrateBusy;
|
||||
function vibrateTime() {
|
||||
if (vibrateBusy) return;
|
||||
vibrateBusy = true;
|
||||
|
||||
var d = new Date();
|
||||
var hours = d.getHours(), minutes = d.getMinutes();
|
||||
if (is12Hour) {
|
||||
if (hours == 0) hours = 12;
|
||||
else if (hours>12) hours -= 12;
|
||||
}
|
||||
|
||||
vibrateNumber(hours.toString()).
|
||||
then(() => new Promise(resolve=>setTimeout(resolve,500))).
|
||||
then(() => vibrateNumber(minutes.toString())).
|
||||
then(() => vibrateBusy=false);
|
||||
}
|
||||
|
||||
// when BTN1 pressed, vibrate
|
||||
setWatch(vibrateTime, BTN1, {repeat:true,edge:"rising"});
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
|
|
@ -19,6 +19,13 @@ var APPS = [ // IDs of apps to install
|
|||
var MINIFY = true;
|
||||
|
||||
var fs = require("fs");
|
||||
global.Const = {
|
||||
/* Are we only putting a single app on a device? If so
|
||||
apps should all be saved as .bootcde and we write info
|
||||
about the current app into app.info */
|
||||
SINGLE_APP_ONLY : false,
|
||||
};
|
||||
|
||||
var AppInfo = require(ROOTDIR+"/core/js/appinfo.js");
|
||||
var appjson = JSON.parse(fs.readFileSync(APPJSON).toString());
|
||||
var appfiles = [];
|
||||
|
|
|
|||
2
core
2
core
|
|
@ -1 +1 @@
|
|||
Subproject commit 9708e1a15ee20734a24f6f2913078aa8bba625dc
|
||||
Subproject commit 62615f6ea4855381e0b4b4b74f8ca69aa594181e
|
||||
|
|
@ -1,12 +1,3 @@
|
|||
/* This code allows you to communicate with the GPS
|
||||
receiver in Bangle.js in order to set it up.
|
||||
|
||||
Protocol spec:
|
||||
|
||||
https://cdn.sparkfun.com/assets/0/b/0/f/7/u-blox8-M8_ReceiverDescrProtSpec__UBX-13003221__Public.pdf
|
||||
|
||||
*/
|
||||
|
||||
Bangle.setGPSPower(1)
|
||||
//Bangle.on('GPS',print);
|
||||
|
||||
|
|
@ -25,9 +16,26 @@ function writeGPScmd(cmd) {
|
|||
a += d[i];
|
||||
b += a;
|
||||
}
|
||||
d.push(a,b);
|
||||
d.push(a&255,b&255);
|
||||
Serial1.write(d);
|
||||
}
|
||||
function readGPScmd(cmd, callback) {
|
||||
var prefix = String.fromCharCode(0xb5,0x62,cmd[0],cmd[1]);
|
||||
function handler(d) {
|
||||
if (!d.startsWith(prefix)) return;
|
||||
clearInterval(timeout);
|
||||
var a = E.toUint8Array(d);
|
||||
// cut off id + length
|
||||
a = new Uint8Array(a.buffer,6, a.length-8);
|
||||
callback(a);
|
||||
}
|
||||
Bangle.on('GPS-raw',handler);
|
||||
var timeout = setTimeout(function() {
|
||||
callback();
|
||||
Bangle.removeListener('GPS-raw',handler);
|
||||
}, 2000);
|
||||
writeGPScmd(cmd);
|
||||
}
|
||||
function UBX_CFG_PMS() {
|
||||
// UBX-CFG-PMS - enable power management - Super-E
|
||||
writeGPScmd([0x06,0x86, // msg class + type
|
||||
|
|
@ -64,4 +72,70 @@ function UBX_CFG_MSG(msg,enable) {
|
|||
// Enter super-e low power
|
||||
// UBX_CFG_PMS()
|
||||
// Disable DTM messages (see UBX_CFG_MSG comments):
|
||||
UBX_CFG_MSG("DTM",false);
|
||||
//UBX_CFG_MSG("DTM",false);
|
||||
// UBX-CFG-HNR (0x06 0x5C) - high rate (up to 30hz)
|
||||
|
||||
|
||||
// GPS 181,98,6,62,60,0,0,32,32,7,0,8,16,0,1,0,1,1,1,1,3,0,0,0,1,1,2,4,8,0,0,0,1,1,3,8,16,0,1,0,1,1,4,0,8,0,0,0,1,3,5,0,3,0,1,0,1,5,6,8,14,0,0,0,1,1,84,27
|
||||
//GPS ACK
|
||||
|
||||
function getUBX_CFG_GNSS() {
|
||||
//
|
||||
readGPScmd([0x06,0x3E,0,0], function(a) {
|
||||
print("CFG_GNSS",a.join(","), a.length);
|
||||
var info = {
|
||||
numTrkChHw : a[1],
|
||||
numTrkChUse : a[2],
|
||||
configs : []
|
||||
};
|
||||
for (var i=4;i<a.length;i+=8) {
|
||||
info.configs.push({
|
||||
gnss : ["GPS","SBAS","Galileo","BeiDou","IMES","QZSS","GLONASS"][a[i+0]],
|
||||
enabled : a[i+4]&1,
|
||||
reservedCh : a[1+1],
|
||||
maxCh : a[i+2],
|
||||
sigCfgMask : a[i+6],
|
||||
flags : [a[i+4],a[i+5],a[i+6],a[i+7]]
|
||||
});
|
||||
}
|
||||
print(info);
|
||||
});
|
||||
}
|
||||
|
||||
function getUBX_CFG_NMEA() {
|
||||
readGPScmd([0x06,0x17,0,0], function(a) {
|
||||
print("CFG_NMEA",a.join(","), a.length);
|
||||
var info = {
|
||||
filter : a[0],
|
||||
nmeaVersion : {0x4b:"4.11",0x41:"4.1",0x40:"4",0x23:"2.3",0x21:"2.1"}[a[1]],
|
||||
flags : a[3]
|
||||
};
|
||||
print(info);
|
||||
});
|
||||
}
|
||||
|
||||
function setUBX_MGA_INI_TIME_UTC() {
|
||||
var a = new Uint8Array(4+24);
|
||||
a.set([0x13,0x40,24,0]);
|
||||
a.set([ 0x10, // 0: type
|
||||
0, // 1: version
|
||||
0, // 2: ref - none
|
||||
0x80] ); // 3: leapsecs - unknown
|
||||
var d = new Date();
|
||||
d.setTime(d.getTime()+d.getTimezoneOffset()*60000); // get as UTC
|
||||
var dv = new DataView(a.buffer, 4);
|
||||
dv.setUint16(4, d.getFullYear());
|
||||
dv.setUint8(6, d.getMonth()+1);
|
||||
dv.setUint8(7, d.getDate());
|
||||
dv.setUint8(8, d.getHours());
|
||||
dv.setUint8(9, d.getMinutes());
|
||||
dv.setUint8(10, d.getSeconds());
|
||||
dv.setUint16(16, 10*60); // seconds part of accuracy - 10 minutes
|
||||
writeGPScmd([].slice.call(a));
|
||||
}
|
||||
|
||||
setUBX_MGA_INI_TIME_UTC();
|
||||
Bangle.on('GPS',print);
|
||||
|
||||
// UBX-MGA-INI-TIME_UTC looks promising for a start time
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue