Merge branch 'espruino:master' into master

master
jukioo 2022-11-01 12:32:16 +02:00 committed by GitHub
commit 75bb05776e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
62 changed files with 83 additions and 441 deletions

2
apps/alpinenav/ChangeLog Normal file
View File

@ -0,0 +1,2 @@
0.01: New App!
0.02: Added adjustment for Bangle.js magnetometer heading fix

View File

@ -224,7 +224,7 @@ Bangle.on('mag', function (m) {
if (isNaN(m.heading)) if (isNaN(m.heading))
compass_heading = "---"; compass_heading = "---";
else else
compass_heading = 360 - Math.round(m.heading); compass_heading = Math.round(m.heading);
current_colour = g.getColor(); current_colour = g.getColor();
g.reset(); g.reset();
g.setColor(background_colour); g.setColor(background_colour);

View File

@ -1,7 +1,7 @@
{ {
"id": "alpinenav", "id": "alpinenav",
"name": "Alpine Nav", "name": "Alpine Nav",
"version": "0.01", "version": "0.02",
"description": "App that performs GPS monitoring to track and display position relative to a given origin in realtime", "description": "App that performs GPS monitoring to track and display position relative to a given origin in realtime",
"icon": "app-icon.png", "icon": "app-icon.png",
"tags": "outdoors,gps", "tags": "outdoors,gps",

View File

@ -2,3 +2,4 @@
0.02: Fixed Whirlpool galaxy RA/DA, larger compass display, fixed moonphase overlapping battery widget 0.02: Fixed Whirlpool galaxy RA/DA, larger compass display, fixed moonphase overlapping battery widget
0.03: Update to use Bangle.setUI instead of setWatch 0.03: Update to use Bangle.setUI instead of setWatch
0.04: Tell clock widgets to hide. 0.04: Tell clock widgets to hide.
0.05: Added adjustment for Bangle.js magnetometer heading fix

View File

@ -834,7 +834,7 @@ Bangle.on('mag', function (m) {
if (isNaN(m.heading)) if (isNaN(m.heading))
compass_heading = "---"; compass_heading = "---";
else else
compass_heading = 360 - Math.round(m.heading); compass_heading = Math.round(m.heading);
// g.setColor("#000000"); // g.setColor("#000000");
// g.fillRect(160, 10, 160, 20); // g.fillRect(160, 10, 160, 20);
g.setColor(display_colour); g.setColor(display_colour);

View File

@ -1,7 +1,7 @@
{ {
"id": "astral", "id": "astral",
"name": "Astral Clock", "name": "Astral Clock",
"version": "0.04", "version": "0.05",
"description": "Clock that calculates and displays Alt Az positions of all planets, Sun as well as several other astronomy targets (customizable) and current Moon phase. Coordinates are calculated by GPS & time and onscreen compass assists orienting. See Readme before using.", "description": "Clock that calculates and displays Alt Az positions of all planets, Sun as well as several other astronomy targets (customizable) and current Moon phase. Coordinates are calculated by GPS & time and onscreen compass assists orienting. See Readme before using.",
"icon": "app-icon.png", "icon": "app-icon.png",
"type": "clock", "type": "clock",

3
apps/beer/ChangeLog Normal file
View File

@ -0,0 +1,3 @@
0.01: New App!
0.02: Added adjustment for Bangle.js magnetometer heading fix
Bangle.js 2 compatibility

View File

@ -1 +1 @@
require("heatshrink").decompress(atob("mEwghC/AB0O/4AG8AXNgYXHmAXl94XH+AXNn4XH/wXW+YX/C6oWHAAIXN7sz9vdAAoXN9sznvuAAXf/vuC53jC4Xd7wXQ93jn3u9vv9vt7wXT/4tBAgIXQ7wvCC4PgC5sO6czIQJfBC6PumaPDC6wwCC50NYAJcBVgIDBCxrAFbgYXP7yoDF6TADL4YXPVAIXCRyAXC7wXW9zwBC6cNC9zABC4gWQC653CR4fQC6x3TF6gXXI4M9d6wAEC9EN73dAAZfQgczAAkwC/4XXAH4")) require("heatshrink").decompress(atob("mEw4cA///wH9/++1P+u3//3/qv/gv+KHkJkmABxcBBwNJkmQCJYOByQCCCBUCCItJkARQkgQHggLBku25IRDJQ4LCtu27Mt2RKJCInbAQIRLpYROglt24OB6wSC7dwLQ4LB9u2EgfbsARJ8u2mwRO+u3CNJtHCJFpCINALJoRCpCiGBoMSdQcpegIRGyaPB+QRDkARIyQRBc4YRKyet23iCJxHB6QRBzOJCJ+dCJY1CpfMGphrCp2YNZlL54CBEZgLBAQoRBiTFFCNMvmQRPndiEcJHEyQQECJMpAYIRQyARQwAROI4IAGB4wCBNAoRmhIRHCA4A/AAo"))

View File

@ -127,6 +127,8 @@
var img_nofix = require("heatshrink").decompress(atob("mUyxH+ACYhJDygtYGsqLVF8u02gziGBoyhQ5gwDGRozRGCQydGCgybGCwyZC5gAaGPQwnGRAwpGQ4xwGFYyFDKsrlYxYDCsBmUyg4yXLyUsFwMyq1WAgUsNCRjUmVXroAEq8yMbcllkskwCEkplDmQwDq0sC54xEHQ9RqQAGqIwCFgOBAASYBSgMBltRAA0sgJsOGJeBxAAGwMrgIXIloxOJYNSvl8CwIDCqMBlYxNC4wxQDIOCwVYDIIDBGJ9YwV8rADBwRJCSqAVCAYaVMC4oxCPYYxQSo4xMSpIxPY4T5HY54XIMbIxKgwXKfKjhEllWGJNWlgXJGLNXruCGI+CrtXGKP+GJB9HMZ6VO/wxJcI8lfJclfKAxKfJEAGJIXLGKSvBWYQZCMZbfEqTHBGJYyFfIo1DGJ4tDGJQwCGJB9IMZyVNGIYyEfJQxPfJgwEMgoZJgAxMltRAA0tGJQyEksslkmAQklGINXxDTBFwIDCq8rC4YACC4gwJMowAJldWAAwwBABowIGJ4AYGJIymGBQylGBgyjGBwyhGCAzeF6YycGCwzYF7IzVF7o1PDqYA==")); var img_nofix = require("heatshrink").decompress(atob("mUyxH+ACYhJDygtYGsqLVF8u02gziGBoyhQ5gwDGRozRGCQydGCgybGCwyZC5gAaGPQwnGRAwpGQ4xwGFYyFDKsrlYxYDCsBmUyg4yXLyUsFwMyq1WAgUsNCRjUmVXroAEq8yMbcllkskwCEkplDmQwDq0sC54xEHQ9RqQAGqIwCFgOBAASYBSgMBltRAA0sgJsOGJeBxAAGwMrgIXIloxOJYNSvl8CwIDCqMBlYxNC4wxQDIOCwVYDIIDBGJ9YwV8rADBwRJCSqAVCAYaVMC4oxCPYYxQSo4xMSpIxPY4T5HY54XIMbIxKgwXKfKjhEllWGJNWlgXJGLNXruCGI+CrtXGKP+GJB9HMZ6VO/wxJcI8lfJclfKAxKfJEAGJIXLGKSvBWYQZCMZbfEqTHBGJYyFfIo1DGJ4tDGJQwCGJB9IMZyVNGIYyEfJQxPfJgwEMgoZJgAxMltRAA0tGJQyEksslkmAQklGINXxDTBFwIDCq8rC4YACC4gwJMowAJldWAAwwBABowIGJ4AYGJIymGBQylGBgyjGBwyhGCAzeF6YycGCwzYF7IzVF7o1PDqYA=="));
var img_fix = require("heatshrink").decompress(atob("mUyxH+ACYhJDygtYGsqLVF94zaDYkq6wAOlQyYJo2A63VAAIoC2m0GI16My5/H5/V64ABGQIwBGQ+rTKwWHkhiBGIYwDGQ3VZioVIqoiBGAJhEGRFPGSYTIYwQxCGA4yFqodJGKeqSgQwJGQmkGKQSJfAYwLGQfPDxQwRgHVfAi/EAA4xLGQwRLYwb5BABoxQCBcA43G5wABAgIAMEBgxQ0QxB54xB5gAG4xgBBYOiGJ4PMGInPGIhcCGIt4EJoxPvHM5oxBGAnO6xrCGoXMqgxdpwxD5qQFL4QADlQxdgAhBGILIDMYoADEBwwPgCHBfQzHDAAb4NACTIIAA74OACLIIMo7GOACQoBZAoHBHQPNA4QwggGiZBA5B54HBY0DIKMYtUGMMqFYLIGY4jGhZAr6FAAYwiZAgxIY0TIFfQgADvAfR/zISGJTGR/wxRkj6CGJBiSGKL6DGP4xOGSKVDGAwxRGAQxU5oxcGR75DGJEkGCYxPlXM5vPGA/MlQxUGR1OGIL4I5lOGCgyOqgxBShHMqgwVGJt4GJd4GKwyMvHG5vGABAxMGBQyM1mtABWsGC4yLGBYABGDAyKGKwwQGZKVUF6b/OABowWGbAvZGaovdGp4dTA")); var img_fix = require("heatshrink").decompress(atob("mUyxH+ACYhJDygtYGsqLVF94zaDYkq6wAOlQyYJo2A63VAAIoC2m0GI16My5/H5/V64ABGQIwBGQ+rTKwWHkhiBGIYwDGQ3VZioVIqoiBGAJhEGRFPGSYTIYwQxCGA4yFqodJGKeqSgQwJGQmkGKQSJfAYwLGQfPDxQwRgHVfAi/EAA4xLGQwRLYwb5BABoxQCBcA43G5wABAgIAMEBgxQ0QxB54xB5gAG4xgBBYOiGJ4PMGInPGIhcCGIt4EJoxPvHM5oxBGAnO6xrCGoXMqgxdpwxD5qQFL4QADlQxdgAhBGILIDMYoADEBwwPgCHBfQzHDAAb4NACTIIAA74OACLIIMo7GOACQoBZAoHBHQPNA4QwggGiZBA5B54HBY0DIKMYtUGMMqFYLIGY4jGhZAr6FAAYwiZAgxIY0TIFfQgADvAfR/zISGJTGR/wxRkj6CGJBiSGKL6DGP4xOGSKVDGAwxRGAQxU5oxcGR75DGJEkGCYxPlXM5vPGA/MlQxUGR1OGIL4I5lOGCgyOqgxBShHMqgwVGJt4GJd4GKwyMvHG5vGABAxMGBQyM1mtABWsGC4yLGBYABGDAyKGKwwQGZKVUF6b/OABowWGbAvZGaovdGp4dTA"));
var W = g.getWidth(), H = g.getHeight();
// https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.SphericalMercator.js // https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.SphericalMercator.js
function project(latlong) { function project(latlong) {
var d = Math.PI / 180, var d = Math.PI / 180,
@ -170,32 +172,30 @@ Bangle.on('GPS', function(f) {
Bangle.on('mag', function(m) { Bangle.on('mag', function(m) {
if (!Bangle.isLCDOn()) return; if (!Bangle.isLCDOn()) return;
var headingrad = m.heading*Math.PI/180; // in radians var headingrad = (360-m.heading)*Math.PI/180; // in radians
if (!isFinite(headingrad)) headingrad=0; if (!isFinite(headingrad)) headingrad=0;
if (nearest) if (nearest)
g.drawImage(img_fix,120,120,{ g.drawImage(img_fix,W/2,H/2,{
rotate: (Math.PI/2)+headingrad-nearestangle, rotate: (Math.PI/2)+headingrad-nearestangle,
scale:3, scale:3,
}); });
else else
g.drawImage(img_nofix,120,120,{ g.drawImage(img_nofix,W/2,H/2,{
rotate: headingrad, rotate: headingrad,
scale:2, scale:2,
}); });
g.clearRect(60,0,180,24); g.clearRect(0,0,W,24).setFontAlign(0,0).setFont("6x8");
g.setFontAlign(0,0);
g.setFont("6x8");
if (fix.fix) { if (fix.fix) {
g.drawString(nearest ? nearest.name : "---",120,4); g.drawString(nearest ? nearest.name : "---",W/2,4);
g.setFont("6x8",2); g.setFont("6x8",2);
g.drawString(nearest ? Math.round(nearestdist)+"m" : "---",120,16); g.drawString(nearest ? Math.round(nearestdist)+"m" : "---",W/2,16);
} else { } else {
g.drawString(fix.satellites+" satellites",120,4); g.drawString(fix.satellites+" satellites",W/2,4);
} }
}); });
Bangle.setCompassPower(1); Bangle.setCompassPower(1);
Bangle.setGPSPower(1); Bangle.setGPSPower(1);
g.clear();`; g.setColor("#fff").setBgColor("#000").clear();`;
sendCustomizedApp({ sendCustomizedApp({
storage:[ storage:[

View File

@ -1,11 +1,11 @@
{ {
"id": "beer", "id": "beer",
"name": "Beer Compass", "name": "Beer Compass",
"version": "0.01", "version": "0.02",
"description": "Uploads all the pubs in an area onto your watch, so it can always point you at the nearest one", "description": "Uploads all the pubs in an area onto your watch, so it can always point you at the nearest one",
"icon": "app.png", "icon": "app.png",
"tags": "", "tags": "",
"supports": ["BANGLEJS"], "supports": ["BANGLEJS","BANGLEJS2"],
"custom": "custom.html", "custom": "custom.html",
"storage": [ "storage": [
{"name":"beer.app.js"}, {"name":"beer.app.js"},

View File

@ -55,3 +55,5 @@
0.49: Store first found clock as a setting to speed up further boots 0.49: Store first found clock as a setting to speed up further boots
0.50: Allow setting of screen rotation 0.50: Allow setting of screen rotation
Remove support for 2v11 and earlier firmware Remove support for 2v11 and earlier firmware
0.51: Remove patches for 2v10 firmware (BEEPSET and setUI)
Add patch to ensure that compass heading is corrected

View File

@ -62,23 +62,6 @@ if (s.ble===false) boot += `if (!NRF.getSecurityStatus().connected) NRF.sleep();
if (s.timeout!==undefined) boot += `Bangle.setLCDTimeout(${s.timeout});\n`; if (s.timeout!==undefined) boot += `Bangle.setLCDTimeout(${s.timeout});\n`;
if (!s.timeout) boot += `Bangle.setLCDPower(1);\n`; if (!s.timeout) boot += `Bangle.setLCDPower(1);\n`;
boot += `E.setTimeZone(${s.timezone});`; boot += `E.setTimeZone(${s.timezone});`;
// Set vibrate, beep, etc IF on older firmwares
if (!Bangle.F_BEEPSET) {
if (!s.vibrate) boot += `Bangle.buzz=Promise.resolve;\n`
if (s.beep===false) boot += `Bangle.beep=Promise.resolve;\n`
else if (s.beep=="vib" && !BANGLEJS2) boot += `Bangle.beep = function (time, freq) {
return new Promise(function(resolve) {
if ((0|freq)<=0) freq=4000;
if ((0|time)<=0) time=200;
if (time>5000) time=5000;
analogWrite(D13,0.1,{freq:freq});
setTimeout(function() {
digitalWrite(D13,0);
resolve();
}, time);
});
};\n`;
}
// Draw out of memory errors onto the screen // Draw out of memory errors onto the screen
boot += `E.on('errorFlag', function(errorFlags) { boot += `E.on('errorFlag', function(errorFlags) {
g.reset(1).setColor("#ff0000").setFont("6x8").setFontAlign(0,1).drawString(errorFlags,g.getWidth()/2,g.getHeight()-1).flip(); g.reset(1).setColor("#ff0000").setFont("6x8").setFontAlign(0,1).drawString(errorFlags,g.getWidth()/2,g.getHeight()-1).flip();
@ -93,28 +76,12 @@ if (s.brightness && s.brightness!=1) boot+=`Bangle.setLCDBrightness(${s.brightne
if (s.passkey!==undefined && s.passkey.length==6) boot+=`NRF.setSecurity({passkey:${E.toJS(s.passkey.toString())}, mitm:1, display:1});\n`; if (s.passkey!==undefined && s.passkey.length==6) boot+=`NRF.setSecurity({passkey:${E.toJS(s.passkey.toString())}, mitm:1, display:1});\n`;
if (s.whitelist) boot+=`NRF.on('connect', function(addr) { if (!(require('Storage').readJSON('setting.json',1)||{}).whitelist.includes(addr)) NRF.disconnect(); });\n`; if (s.whitelist) boot+=`NRF.on('connect', function(addr) { if (!(require('Storage').readJSON('setting.json',1)||{}).whitelist.includes(addr)) NRF.disconnect(); });\n`;
if (s.rotate) boot+=`g.setRotation(${s.rotate&3},${s.rotate>>2});\n` // screen rotation if (s.rotate) boot+=`g.setRotation(${s.rotate&3},${s.rotate>>2});\n` // screen rotation
// Pre-2v10 firmwares without a theme/setUI // ================================================== FIXING OLDER FIRMWARES
delete g.theme; // deleting stops us getting confused by our own decl. builtins can't be deleted // 2v15.68 and before had compass heading inverted.
if (!g.theme) { if (process.version.replace("v","")<215.68)
boot += `g.theme={fg:-1,bg:0,fg2:-1,bg2:7,fgH:-1,bgH:0x02F7,dark:true};\n`; boot += `Bangle.on('mag',e=>{if(!isNaN(e.heading)) e.heading=360-e.heading;});`;
}
try {
Bangle.setUI({}); // In 2v12.xx we added the option for mode to be an object - for 2v12 and earlier, add a fix if it fails with an object supplied
} catch(e) {
boot += `Bangle._setUI = Bangle.setUI;
Bangle.setUI=function(mode, cb) {
if (Bangle.uiRemove) {
Bangle.uiRemove();
delete Bangle.uiRemove;
}
if ("object"==typeof mode) {
// TODO: handle mode.back?
mode = mode.mode;
}
Bangle._setUI(mode, cb);
};\n`;
}
// ================================================== BOOT.JS
// Append *.boot.js files // Append *.boot.js files
// These could change bleServices/bleServiceOptions if needed // These could change bleServices/bleServiceOptions if needed
var bootFiles = require('Storage').list(/\.boot\.js$/).sort((a,b)=>{ var bootFiles = require('Storage').list(/\.boot\.js$/).sort((a,b)=>{

View File

@ -1,7 +1,7 @@
{ {
"id": "boot", "id": "boot",
"name": "Bootloader", "name": "Bootloader",
"version": "0.50", "version": "0.51",
"description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings", "description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings",
"icon": "bootloader.png", "icon": "bootloader.png",
"type": "bootloader", "type": "bootloader",

View File

@ -5,3 +5,4 @@
0.05: Fix bearing not clearing correctly (visible in single or double digit bearings) 0.05: Fix bearing not clearing correctly (visible in single or double digit bearings)
0.06: Add button for force compass calibration 0.06: Add button for force compass calibration
0.07: Use 360-heading to output the correct heading value (fix #1866) 0.07: Use 360-heading to output the correct heading value (fix #1866)
0.08: Added adjustment for Bangle.js magnetometer heading fix

View File

@ -20,7 +20,7 @@ ag.setColor(1).fillCircle(AGM,AGM,AGM-1,AGM-1);
ag.setColor(0).fillCircle(AGM,AGM,AGM-11,AGM-11); ag.setColor(0).fillCircle(AGM,AGM,AGM-11,AGM-11);
function arrow(r,c) { function arrow(r,c) {
r=r*Math.PI/180; r=(360-r)*Math.PI/180;
var p = Math.PI/2; var p = Math.PI/2;
ag.setColor(c).fillPoly([ ag.setColor(c).fillPoly([
AGM+AGH*Math.sin(r), AGM-AGH*Math.cos(r), AGM+AGH*Math.sin(r), AGM-AGH*Math.cos(r),
@ -34,7 +34,7 @@ var oldHeading = 0;
Bangle.on('mag', function(m) { Bangle.on('mag', function(m) {
if (!Bangle.isLCDOn()) return; if (!Bangle.isLCDOn()) return;
g.reset(); g.reset();
if (isNaN(m.heading)) { if (isNaN(m.heading)) {
if (!wasUncalibrated) { if (!wasUncalibrated) {
g.clearRect(0,24,W,48); g.clearRect(0,24,W,48);
g.setFontAlign(0,-1).setFont("6x8"); g.setFontAlign(0,-1).setFont("6x8");
@ -49,7 +49,7 @@ Bangle.on('mag', function(m) {
g.setFontAlign(0,0).setFont("6x8",3); g.setFontAlign(0,0).setFont("6x8",3);
var y = 36; var y = 36;
g.clearRect(M-40,24,M+40,48); g.clearRect(M-40,24,M+40,48);
g.drawString(Math.round(360-m.heading),M,y,true); g.drawString(Math.round(m.heading),M,y,true);
} }

View File

@ -1,7 +1,7 @@
{ {
"id": "compass", "id": "compass",
"name": "Compass", "name": "Compass",
"version": "0.07", "version": "0.08",
"description": "Simple compass that points North", "description": "Simple compass that points North",
"icon": "compass.png", "icon": "compass.png",
"screenshots": [{"url":"screenshot_compass.png"}], "screenshots": [{"url":"screenshot_compass.png"}],

View File

@ -1 +1,2 @@
0.01: Create dotmatrix clock app 0.01: Create dotmatrix clock app
0.02: Added adjustment for Bangle.js magnetometer heading fix

View File

@ -186,7 +186,7 @@ function drawCompass(lastHeading) {
'NW' 'NW'
]; ];
const cps = Bangle.getCompass(); const cps = Bangle.getCompass();
let angle = cps.heading; let angle = 360-cps.heading;
let heading = angle? let heading = angle?
directions[Math.round(((angle %= 360) < 0 ? angle + 360 : angle) / 45) % 8]: directions[Math.round(((angle %= 360) < 0 ? angle + 360 : angle) / 45) % 8]:
"-- "; "-- ";
@ -351,4 +351,4 @@ Bangle.on('faceUp', (up) => {
setSensors(1); setSensors(1);
resetDisplayTimeout(); resetDisplayTimeout();
} }
}); });

View File

@ -1,7 +1,7 @@
{ {
"id": "dotmatrixclock", "id": "dotmatrixclock",
"name": "Dotmatrix Clock", "name": "Dotmatrix Clock",
"version": "0.01", "version": "0.02",
"description": "A clear white-on-blue dotmatrix simulated clock", "description": "A clear white-on-blue dotmatrix simulated clock",
"icon": "dotmatrixclock.png", "icon": "dotmatrixclock.png",
"type": "clock", "type": "clock",

View File

@ -13,7 +13,7 @@
E.showMenu({ E.showMenu({
"" : { "title" : "GPS auto time" }, "" : { "title" : "GPS auto time" },
"< Back" : () => back(), "< Back" : () => back(),
'Show Widgets': { 'Show Widget': {
value: !!settings.show, value: !!settings.show,
onchange: v => { onchange: v => {
settings.show = v; settings.show = v;

View File

@ -9,7 +9,7 @@
delete settings; delete settings;
Bangle.on('GPS',function(fix) { Bangle.on('GPS',function(fix) {
if (fix.fix) { if (fix.fix && fix.time) {
var curTime = fix.time.getTime()/1000; var curTime = fix.time.getTime()/1000;
setTime(curTime); setTime(curTime);
lastTimeSet = curTime; lastTimeSet = curTime;

View File

@ -3,3 +3,4 @@
0.03: Fix listener for accel always active 0.03: Fix listener for accel always active
Use custom UI with swipes instead of leftright Use custom UI with swipes instead of leftright
0.04: Fix compass heading 0.04: Fix compass heading
0.05: Added adjustment for Bangle.js magnetometer heading fix

View File

@ -1,7 +1,7 @@
{ {
"id": "gpstrek", "id": "gpstrek",
"name": "GPS Trekking", "name": "GPS Trekking",
"version": "0.04", "version": "0.05",
"description": "Helper for tracking the status/progress during hiking. Do NOT depend on this for navigation!", "description": "Helper for tracking the status/progress during hiking. Do NOT depend on this for navigation!",
"icon": "icon.png", "icon": "icon.png",
"screenshots": [{"url":"screen1.png"},{"url":"screen2.png"},{"url":"screen3.png"},{"url":"screen4.png"}], "screenshots": [{"url":"screen1.png"},{"url":"screen2.png"},{"url":"screen3.png"},{"url":"screen4.png"}],

View File

@ -24,13 +24,13 @@ function onGPS(fix) {
} }
function onMag(e) { function onMag(e) {
if (!state.compassHeading) state.compassHeading = e.heading; if (!state.compassHeading) state.compassHeading = 360-e.heading;
//if (a+180)mod 360 == b then //if (a+180)mod 360 == b then
//return (a+b)/2 mod 360 and ((a+b)/2 mod 360) + 180 (they are both the solution, so you may choose one depending if you prefer counterclockwise or clockwise direction) //return (a+b)/2 mod 360 and ((a+b)/2 mod 360) + 180 (they are both the solution, so you may choose one depending if you prefer counterclockwise or clockwise direction)
//else //else
//return arctan( (sin(a)+sin(b)) / (cos(a)+cos(b) ) //return arctan( (sin(a)+sin(b)) / (cos(a)+cos(b) )
/* /*
let average; let average;
let a = radians(compassHeading); let a = radians(compassHeading);
@ -112,7 +112,7 @@ function stop(bg){
saveState(); saveState();
Bangle.drawWidgets(); Bangle.drawWidgets();
} }
function initState(){ function initState(){
//cleanup volatile state here //cleanup volatile state here
state.currentPos={}; state.currentPos={};

View File

@ -1 +0,0 @@
0.01: New App!

View File

@ -1,13 +0,0 @@
{
"id": "ncfrun",
"name": "NCEU 5K Fun Run",
"version": "0.01",
"description": "Display a map of the NodeConf EU 2019 5K Fun Run route and your location on it",
"icon": "nceu-funrun.png",
"tags": "health",
"supports": ["BANGLEJS"],
"storage": [
{"name":"ncfrun.app.js","url":"nceu-funrun.js"},
{"name":"ncfrun.img","url":"nceu-funrun-icon.js","evaluate":true}
]
}

View File

@ -1 +0,0 @@
require("heatshrink").decompress(atob("mEwwgurglEC6tDmYYUgkzAANAFygXKKYIADBwgXDkg8LBwwXMoQXEH4hHNC4s0O6BfECAKhDHYKnOghCB3cga6dEnYYBaScC2cznewC6W7OQU7BYyIFAAhFBAAYwGC5RFBC5QAJlY0FSIQAMkUjGgrTJRYoXFPQIXGLg8iAAJFDDgIXGgYXJGAWweQJHOC4jtBC6cidgQXUUQQXBogACDYR3HmQXHAAYzKU4IACC48kJBwFBgg7EMZYwDJAReDoh5PC4QARJAoARJAYXTJChtDoSgNAAaeEAAU0C5wqCC4q5LOYYvWgjOEaJ4AGoZGQPY6OPFw0yF34uFRlYXCFykAoQuVeIQWUAB4A="))

View File

@ -1,140 +0,0 @@
var coordScale = 0.6068;
var coords = new Int32Array([-807016,6918514,-807057,6918544,-807135,6918582,-807238,6918630,-807289,6918646,-807308,6918663,-807376,6918755,-807413,6918852,-807454,6919002,-807482,6919080,-807509,6919158,-807523,6919221,-807538,6919256,-807578,6919336,-807628,6919447,-807634,6919485,-807640,6919505,-807671,6919531,-807703,6919558,-807760,6919613,-807752,6919623,-807772,6919643,-807802,6919665,-807807,6919670,-807811,6919685,-807919,6919656,-807919,6919645,-807890,6919584,-807858,6919533,-807897,6919503,-807951,6919463,-807929,6919430,-807916,6919412,-807907,6919382,-807901,6919347,-807893,6919322,-807878,6919292,-807858,6919274,-807890,6919232,-807909,6919217,-807938,6919206,-807988,6919180,-807940,6919127,-807921,6919100,-807908,6919072,-807903,6919039,-807899,6919006,-807911,6918947,-807907,6918936,-807898,6918905,-807881,6918911,-807874,6918843,-807870,6918821,-807854,6918775,-807811,6918684,-807768,6918593,-807767,6918593,-807729,6918516,-807726,6918505,-807726,6918498,-807739,6918481,-807718,6918465,-807697,6918443,-807616,6918355,-807518,6918263,-807459,6918191,-807492,6918162,-807494,6918147,-807499,6918142,-807500,6918142,-807622,6918041,-807558,6917962,-807520,6917901,-807475,6917933,-807402,6917995,-807381,6918024,-807361,6918068,-807323,6918028,-807262,6918061,-807263,6918061,-807159,6918116,-807148,6918056,-807028,6918063,-807030,6918063,-806979,6918068,-806892,6918090,-806760,6918115,-806628,6918140,-806556,6918162,-806545,6918175,-806531,6918173,-806477,6918169,-806424,6918180,-806425,6918180,-806367,6918195,-806339,6918197,-806309,6918191,-806282,6918182,-806248,6918160,-806225,6918136,-806204,6918107,-806190,6918076,-806169,6917968,-806167,6917953,-806157,6917925,-806140,6917896,-806087,6917839,-806071,6917824,-805969,6917904,-805867,6917983,-805765,6918063,-805659,6918096,-805677,6918131,-805676,6918131,-805717,6918212,-805757,6918294,-805798,6918397,-805827,6918459,-805877,6918557,-805930,6918608,-805965,6918619,-806037,6918646,-806149,6918676,-806196,6918685,-806324,6918703,-806480,6918735,-806528,6918738,-806644,6918712,-806792,6918667,-806846,6918659,-806914,6918654,-806945,6918661,-806971,6918676,-806993,6918689,-806992,6918692,-807065,6918753,-807086,6918786,-807094,6918788,-807102,6918795,-807104,6918793,-807107,6918799,-807102,6918802,-807112,6918812,-807106,6918815,-807115,6918826,-807120,6918823,-807132,6918841,-807141,6918850,-807151,6918841,-807170,6918832,-807193,6918813,-807222,6918775,-807246,6918718,-807250,6918694,-807264,6918637,-807238,6918630,-807148,6918587,-807057,6918544,-806948,6918463]);
var min = {"x":-807988,"y":6917824};
var max = {"x":-805659,"y":6919685};
var gcoords = new Uint8Array(coords.length);
var coordDistance = new Uint16Array(coords.length/2);
var PT_DISTANCE = 30; // distance to a point before we consider it complete
function toScr(p) {
return {
x : 10 + (p.x-min.x)*100/(max.x-min.x),
y : 230 - (p.y-min.y)*100/(max.y-min.y)
};
}
var last;
var totalDistance = 0;
for (var i=0;i<coords.length;i+=2) {
var c = {x:coords[i],y:coords[i+1]};
var s = toScr(c);
gcoords[i ] = s.x;
gcoords[i+1] = s.y;
if (last) {
var dx = c.x-last.x;
var dy = c.y-last.y;
totalDistance += Math.sqrt(dx*dx+dy*dy)*coordScale;
coordDistance[i/2] = totalDistance;
}
last = c;
}
var fix, lastFix;
var nextPtIdx = 0; // 2x the number of points
var nextPt = {x:coords[nextPtIdx], y:coords[nextPtIdx+1]};
var nextAngle = 0;
var nextDist = 0;
var currentDist = 0;
function drawMap() {
g.clearRect(0,0,239,120);
g.setFontAlign(0,0);
g.setColor(1,0,0);
g.setFontVector(40);
g.drawString((currentDist===undefined)?"?":(Math.round(currentDist)+"m"), 160, 30);
g.setColor(1,1,1);
g.setFont("6x8",2);
g.drawString(Math.round(totalDistance)+"m", 160, 70);
g.drawString((nextPtIdx/2)+"/"+coordDistance.length, 50, 20);
if (!fix.fix) {
g.setColor(1,0,0);
g.drawString("No GPS", 50, 50);
g.setFont("6x8",1);
g.drawString(fix.satellites+" Sats", 50, 70);
}
if (lastFix && lastFix.fix) {
g.setColor(0,0,0);
g.drawCircle(lastFix.s.x,lastFix.s.y,10);
}
for (var i=0;i<gcoords.length;i+=2) {
g.setColor((i<=nextPtIdx) ? 63488 : 46486); // red/grey
g.fillRect(gcoords[i]-2,gcoords[i+1]-2,gcoords[i]+2,gcoords[i+1]+2);
}
g.setColor(1,0,0); // first part of path
g.drawPoly(new Uint8Array(gcoords.buffer, 0, nextPtIdx+2));
g.setColor(1,1,1); // remaining part of path
g.drawPoly(new Uint8Array(gcoords.buffer, nextPtIdx));
if (fix && fix.fix) {
g.setColor(1,0,0);
g.drawCircle(fix.s.x,fix.s.y,10);
}
lastFix = fix;
}
function getNextPtInfo() {
var dx = nextPt.x - fix.p.x;
var dy = nextPt.y - fix.p.y;
nextAngle = Math.atan2(dx,dy)*180/Math.PI;
nextDist = Math.sqrt(dx*dx+dy*dy)*coordScale;
}
function onGPS(f) {
fix = f;
fix.p = Bangle.project(fix);
fix.s = toScr(fix.p);
getNextPtInfo();
if ((nextDist < PT_DISTANCE) &&
(nextPtIdx < coords.length)) {
nextPtIdx+=2;
nextPt = {x:coords[nextPtIdx], y:coords[nextPtIdx+1]};
getNextPtInfo();
}
// work out how far we are (based on distance to next point)
if (!fix.fix) {
currentDist = undefined
} else if (nextPtIdx+2 < coordDistance.length) {
currentDist = coordDistance[1+(nextPtIdx/2)] - nextDist;
} else if (nextPtIdx+2 == coordDistance.length) {
currentDist = totalDistance - nextDist;
} else {
currentDist = totalDistance;
}
if (!Bangle.isLCDOn()) return;
drawMap();
}
function arrow(r,c) {
r=r*Math.PI/180;
var p = Math.PI*3/4;
g.setColor(c);
g.fillPoly([
180+40*Math.sin(r), 180-40*Math.cos(r),
180+20*Math.sin(r+p), 180-20*Math.cos(r+p),
180-10*Math.sin(r), 180+10*Math.cos(r),
180+20*Math.sin(r+-p), 180-20*Math.cos(r-p),
]);
}
function onCompass(m) {
if (!Bangle.isLCDOn()) return;
arrow(oldHeading,0);
var heading = m.heading + nextAngle;
arrow(heading,0xF800);
oldHeading = heading;
}
// draw the heading
var oldHeading = 0;
Bangle.on('GPS', onGPS);
Bangle.on('mag', onCompass);
Bangle.setGPSPower(1);
Bangle.setCompassPower(1);
g.clear();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,9 +0,0 @@
0.02: Modified for use with new bootloader and firmware
Renamed as nodeconf-specific
0.03: Move configuration into App/widget settings
Move loader into welcome.boot.js
0.04: Run again when updated
Don't run again when settings app is updated (or absent)
Add "Run Now" option to settings
0.05: Don't overwrite existing settings on app update
0.06: Allow welcome to run after a fresh install

View File

@ -1,9 +0,0 @@
(function() {
let s = require('Storage').readJSON('ncstart.json', 1) || {};
if (!s.welcomed) {
setTimeout(() => {
require('Storage').write('ncstart.json', {welcomed: true})
load('ncstart.app.js')
})
}
})()

View File

@ -1,21 +0,0 @@
{
"id": "ncstart",
"name": "NCEU Startup",
"version": "0.06",
"description": "NodeConfEU 2019 'First Start' Sequence",
"icon": "start.png",
"tags": "start,welcome",
"supports": ["BANGLEJS"],
"storage": [
{"name":"ncstart.app.js","url":"start.js"},
{"name":"ncstart.boot.js","url":"boot.js"},
{"name":"ncstart.settings.js","url":"settings.js"},
{"name":"ncstart.img","url":"start-icon.js","evaluate":true},
{"name":"nc-bangle.img","url":"start-bangle.js","evaluate":true},
{"name":"nc-nceu.img","url":"start-nceu.js","evaluate":true},
{"name":"nc-nfr.img","url":"start-nfr.js","evaluate":true},
{"name":"nc-nodew.img","url":"start-nodew.js","evaluate":true},
{"name":"nc-tf.img","url":"start-tf.js","evaluate":true}
],
"data": [{"name":"ncstart.json"}]
}

View File

@ -1,14 +0,0 @@
(function(back) {
let settings = require('Storage').readJSON('ncstart.json', 1)
|| require('Storage').readJSON('setting.json', 1) || {}
E.showMenu({
'': { 'title': 'NCEU Startup' },
'Run on Next Boot': {
value: !settings.welcomed,
format: v => v ? 'OK' : 'No',
onchange: v => require('Storage').write('ncstart.json', {welcomed: !v}),
},
'Run Now': () => load('ncstart.app.js'),
'< Back': back,
})
})

View File

@ -1 +0,0 @@
require("heatshrink").decompress(atob("s8wxH+AH4AQ/4AJJX5mmM/5m/AH5m/M34A/M35l/M35mqM/5m/AH5m/M34A/MqQKQJm5laOh7kNM35MGbiQxLM9osWIiZnGDI5m/VTBm/MsrOGM35maB4xm/MsoZFORZm/Fq5mDAAwUKBhAHBDJYLGAY4rOPShmRF44TIIoqlJCIxmKEZLMSBxY1GE5RTIJpwYSP5hmQZxodKLBKpIDBQZHMxS4MM1IKCMzKNQHJJmtFwbbUMy4AIM35mcJR5mbLCo1GZrxLOLZ6BMH5wOHMyAYRSRLOWGRY+MAxRmODCZeNMyLNMAA4TIBgpmPFA4YMHBZnPFIp/cADa0cC9Zm2J5YkKMtgsIGjZRTCYLMsFow0dDqJluGAgzhEJwxiAGpYLMn70hAA5N/M34A/M35mzJn5m/AH5nNJf5m/AH5m/M34A/M35m/MpgA="))

View File

@ -1 +0,0 @@
require("heatshrink").decompress(atob("mEwxH+AHMPADQv/F+YxZYtb1wFto7SEbwwQBIsen0/ADU+jxfOjwtbAAYwDWZVWF79WfBAvEq4vfq4vIGQgviR44AEFz4vEGRQvnGA4v/F79YX9IHEq4aKh//jwvRrBcHG4ovL/4ABB5gAFRAwvVGIQveoAAIF4oABq0/CZIACF8BiBrAvTGIoaKF5AABIpVXd44AFJBQvKh4vOGBIvVL54vdX5iPhqztLoFYFpYvSh8/FxgABFpYvQRRgveoEP/8eFqAvbACi/CeA4IDP6IvUGIYGEF+EMADwvJR4ovmdoovnFoowDF8QsIF4dZF79ZF5RpCj1AFztAjy7JAAgwdFwbAFFwwAmF/4vhGFrxLFkoAvA="))

View File

@ -1 +0,0 @@
require("heatshrink").decompress(atob("o9HxH+AEOAwAkiIkIADIv5CEI/4/IJHbNLbPA4Iv1+JHREIwkmk2EJBBE2IoUnIwJHBCx5GoBA2DIgQACBw5G3aQQADwRG+wEmagQCBvxGufoQpDFxOCI4YNIDgxNeD4gDHCY+EwgMKBQIjGJDJlHA4YlKvzRHDRZHZDJQkMBZojVECb+OHJgkOZ6w6KCJAHJCgY1dK5wPDCg4GICYjDZBY9+vxGMArItLeRgWDwOEwmBJA5Ggv2GlMMwJGTwRFBI5JGfv2HlIACwRGRwBFDAAIUGIz+FIYMMI4R0CIxzSCRwhaMIBy2FAAaMBhmHI4QjIRqwUFIxxFJOgLTDlMGRqJHFwF+CpAWDIxgwJBgN+aoSMEIyAGBweDXBg6FABIWLAgOCw+GMhRGKByI9IIxYtQIywaJC5YTTIzwRGOyQqTIzLGNCTJGgXqIRTIzILIIzQvUI5a4EBgh6TDI7dKZJo7IAwQLFIzAjKIhwQGChBvMEhojLIqIjGBaZGPEbppOEerrLBYpGVEZrVOBpJjJIzCHNcpoqPI6gaUIywfSCLJGgXBYSZIzwRFCxoSGFSJGYCA4XLCRArQIywOJYxDPLFqA3OwFPp4HCy4lKHogAIM5uulukMIxGNy1MAAWW2JENFBJIMv8B0ksAAQQDIx2AptMpoCCChZGQGROYIocslsBIyGVIQNOp5HByhaMIxj9IAAWMIYUtRwiNPaIKNCpgUGIB4FNAAMXRq/+yhDBAAOUtJGlgKOCAAOvCJRGH2OVp1OypFGI0BHB0jUBzCMCIyAABtJEHI0RICIgYRMJBBGMCg4GICYgnPCBhHPBwQSIA5IUDGpxWOJBwgLfpgkOIhwVOEBj9WIipsKA4YiKgMBERojIIqphHAgYjKy+n1VpTJYjIADZlGEpOVlwABhTJKRL4oHFxIIEIgUKlula44/hShwIG1RFB02lJQJVII2zTC0iNBhVpI24vGgOmlpIBl2WagwWIJGFp1UKhRFGImI0FGouAaIoPIJGQMWJG5E7H5BE/I4pF/JA4kiA"))

View File

@ -1 +0,0 @@
require("heatshrink").decompress(atob("5EuxH+AAkPABIQFABIaKDiIA/AH6qaVpwbbAH4A/YzysMDbYA/AH7GfVhbHgChrr0MT5FoTDobOQijH/Y/6aYcqzH/Y/5EeZDLHmFxTH/Y/4TVY84uJY/7H7TibHuC4rH5XmiHRZC7HpDAjSQF5QpJCgYGJY6Y8MFR4bJBSrITY9RNJb6LFNY5ALFP6CsVY55PQTzDH6MhrGPY7opYY7IZFAgqfRY9xzIWx7GQY6QsYFTTHQZDLHlL44ONDxIfJdKS3PA54qSCRL1MWpDIRY8yLNCg5FICB7ZMHZwrKaB4bQEpTHZH5bHgRhiZNbCTZSY5qBNHiDHZZCbHsOZjHPRSTHYOZbHyZDLH/Y8pQRY+zIYY8xPLG6bHsDJjHuUiTbQdTjHfQBjHYVaLHyUqbHoKJC2KCBgRDBA7HeThbHvZETHdVxKKPTkzISfJLHpZELHeOZLGOY9g8OY+TIgY74OJLqDHqFZIMJY/7HuFxRcPYJbHeXi7HUKAqGYCSgdRAH4A/XC7IdY/4A/Y9rIZY/4A/Y/7H/AH7H2ZDDH/AH7HvZC7H/SMrH/Io7IZDCoVIBgwNFBSA7JBRoZOJ5jboY6IOBY9oWKDpYLFApZkNH6YIHJ5BMNY97IZY6yvTTJCGRBwQRIExYVKB4zH+ZDDHpBQ7HgH5Q+QY/7IYY9KDJY6QeKY6xDOY/7H7BhRiPCRQGHA4SsRCJDH4ZDJqUfpQiIBR6UNDRISQOJ52TY9DIYNSyvSIZLfOAxoaIY/7HVZC4SQQBSJUC57HTDIw9QGZzH/Y7xmINyTHTAAwfKHyzH/OBTH3CRg1LYxAUFD5Y+QY9RXLLxQaWY6yIYY6g5SH57kHY9StRcbZPQQJivRC6AKJEBpGHBxrH/DcbHUEpQKQBojSPH5gpIXx7HjVp4caJkbjRGv4AkA=="))

View File

@ -1 +0,0 @@
require("heatshrink").decompress(atob("5E1xH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A6hEICD4A/AH7FlY6TJ/AH7G1Y6bI/AH7FyY6rJ/AH7GyY6zI/AH7H/Y/4A/Y3DHXg5g/AH4Ak5jH/AH4A/Y9VXq5l/AH4Ag47HjZAJm/AH7GgY5S9KZBjHDZH4A/Y9S5KBxrH/AH7GkY5DGOCIrHJZA4pGBiQAPKpAQLHKQmPADRSQY6LFQCZLHPQJjIeQqwKVHTLHoEpDISY4rIGJRbH/IjBYXC67GCY5LGRY7CCaY8hEPV87Ha4zHEYyoXGY6SOKY9IQJIhRDUY+YdEY64YCAgTIBY6CDPMBxRIDpAvMIaZALV5z/NFRrHH5glGYyqOFY4LIJDJoHKaZolPMZIRMUZAyLHxotLLJzHJ4zGBY8TICY6KXJO6wdQWiJCHGRp+QJaTINYoRbQY6bICZINRY8RJQDhowPY8RMYY5YABgR9US6MHgIwGJ5QMLE44GIURY4NBSoyKIZQRObhrIMg7HkgQvIJBapSBzrBPCBhdJY5w+NeBgAFzO93rIFY8AFBxmGwydKFxSFOMJR6JFZhXLIKbHVPhbHPZALJBZA7HcAgLFBY5qFYY+KsLY/DICY4rIWC4kC/2MY6CGJOZjWPRBy8KY95MHY62ZAoLICY64/G/zGIMRxcQdB7HWBZqeQEZxcIY7e9Y4ZMHY/AwJIByrOY7JzLCJAbNY8jITCozHVURqDRDrY/MGSDHWPhTHOZAbHFZCgxHY4gxGIJbrLT6AQIDiRLQOp7ITGBbHcZB4wKY5o+IOxwWLBoQdUY54zMCJTTQBQ6GSZAjHGZCJCLY5IA/AH4AWY5L7LBpzHDNH4A/ZEDHIXQoALaZLH/AH7HsZB4WHgTHCM34A/AELHjY34A/AErHhAH4A/AEzH/AH4A/Y8xe/AH7IwCsgA/AH7IiCkYA/AH7IjCcQA/AH7JkCMAA/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AHIA="))

View File

@ -1 +0,0 @@
require("heatshrink").decompress(atob("4M7ghC/AH4A/AEcBiMQAgY+3iIACIAQhcAgYjdTzZgfYH5giYHo5BIIQGDAQYLHgMQBoZZFYAoYENGREDGgI6BAYYMDBYrXDA4RTDAobnFLgbNEYF5LFVAIGCAghsEBQYMFYAoMEC4TAxAAg5DLoqiCZQZ2CAQa2DYAiGFA4bAvXYj6DAIZkEVYizHLYhyDNoaGCL9zAEHw5aGOIwHJYAqBFL96zCHxJsEKwcBYAx5GYA4SCFobAuMohoDAQ4UCKgYCEYBR7FYGqsDIIwLFYAzUFYAhbEL+IyGIojAFBYbAEKYZYHCgghEYGoGFWoQGFJIYHBgRZDbQpsFYGiNuIP4AedooA/L/4A5gJf/AH4A/AH4A/AH4A/AH4A/AH4A/ACsN7oAJG+oJC6AoaL5QmbG7PQTLrA/YH7A/YH7AhFgxbrYA4JQFkTArWwzAlEQhnCA4bPDBQwLDHwwJH5oGBEAydNAwQHDEgggDcaJBDEY4JDJoYSEH5A7GBAbAPHg5aHCQoiSEYpNHBIxpIBIQHGTpwzGGQJlMESZCIFowTNCQLAVSZAXFGQnNL5AiNBJAeBBIYsDNJIJHTpwyMCQhGEQQwsFYo7kGAoQJDEQQyDS5ChDCgxRJGRJ4DUIpAFYBQiFJgwUGBIr3IIAy5EaJgyNcgoTGcZZCFWwxMLboxqLYBoUJGw5GIYBaSGFoo3GLApAOYCAUJQYycLYBCSHDIoUJYBfdYDwKDEwQFCBAbAfIwwHEFA6rKTpLAPEoQCDYEBgIFgzAMHwzAOXpDAkMIxALYD4wEAozAOaA7AKMIxAJVZjAWApLAOBxasGEYYZCIAyrOYCQlBYC4jGhpHCYBBpJAYSrSTp4FELQZmFYBoRDBQjAMGwvcHQYiEdBDANHgpTFApbALaYgWERpISGHYoJFYCo8JVBKAHFg5COAoY2JBI65IYBofHOYZmIYBxgGNIr4KSxJJHYCQfGCQhmIYBwjFPZDVKQg53IYCI8IBIgFIERgjEPZLVJEhHcAwUMYCo8IYBIfGAH4A/AHw"))

View File

@ -1,120 +0,0 @@
g.setFontAlign(1, 1, 0);
const d = g.getWidth() - 18;
function c(a) {
return {
width: 8,
height: a.length,
bpp: 1,
buffer: (new Uint8Array(a)).buffer
};
}
function welcome() {
var welcomes = [
'Welcome',
'Failte',
'Bienvenue',
'Willkommen',
'Bienvenido'
];
function next() {
var n = welcomes.shift();
E.showMessage(n);
g.drawImage(c([0,8,12,14,255,14,12,8]),d,116);
welcomes.push(n);
}
return new Promise((res) => {
next();
var i = setInterval(next, 2000);
setWatch(() => {
clearInterval(i);
clearWatch();
E.showMessage('Loading...');
res();
}, BTN2, {repeat:false});
});
}
function logos() {
var logos = [
['nfr', 20, 90, ()=>{}],
['nceu', 20, 90, ()=>{
g.setFont("6x8", 2);
g.setColor(0,0,1);
g.drawString('Welcome To', 160, 110);
g.drawString('NodeConfEU', 160, 130);
g.drawString('2019', 200, 150);
}],
['bangle', 70, 90, ()=>{}],
['nodew', 20, 90, ()=>{}],
['tf', 24, 90, ()=>{}],
];
function next() {
var n = logos.shift();
var img = require("Storage").read("nc-"+n[0]+".img");
g.clear();
g.drawImage(img, n[1], n[2]);
n[3]();
g.drawImage(c([0,8,12,14,255,14,12,8]),d,116);
logos.push(n);
}
return new Promise((res) => {
next();
var i = setInterval(next, 2000);
setWatch(() => {
clearInterval(i);
clearWatch();
res();
}, BTN2, {repeat:false});
});
}
function info() {
var slides = [
() => E.showMessage('Visit\nnodewatch.dev\nfor info'),
() => E.showMessage('Visit\nbanglejs.com/apps\nfor apps'),
() => E.showMessage('Remember\nto charge\nyour watch!'),
() => {
g.clear();
g.setFont('6x8',2);
g.setColor(1,1,1);
g.drawImage(c([0,8,12,14,255,14,12,8]),d,40);
g.drawImage(c([0,8,12,14,255,14,12,8]),d,194);
g.drawImage(c([0,8,12,14,255,14,12,8]),d,116);
g.drawString('Menu Up', d - 50, 42);
g.drawString('Select', d - 40, 118);
g.drawString('Menu Down', d - 60, 196);
},
() => {
g.clear();
E.showMessage('Hold\nto return\nto clock');
g.drawImage(c([0,8,12,14,255,14,12,8]),d,194);
},
() => {
g.clear();
E.showMessage('Hold both\nto reboot');
g.drawImage(c([0,8,12,14,255,14,12,8]),d,40);
g.drawImage(c([0,8,12,14,255,14,12,8]),d,116);
},
() => E.showMessage('Open Settings\nto enable\nBluetooth')
];
function next() {
var n = slides.shift();
n();
slides.push(n);
}
return new Promise((res) => {
next();
var i = setInterval(next, 2000);
setWatch(()=>{
clearInterval(i);
clearWatch();
res();
}, BTN2, {repeat:false});
});
}
welcome()
.then(logos)
.then(info)
.then(load);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1,3 +1,4 @@
0.01: New App! 0.01: New App!
0.02: Change img when no fix 0.02: Change img when no fix
0.03: Add HTML class for Spectre.CSS 0.03: Add HTML class for Spectre.CSS
0.04: Added adjustment for Bangle.js magnetometer heading fix

View File

@ -187,7 +187,7 @@ Bangle.on('GPS', function(f) {
Bangle.on('mag', function(m) { Bangle.on('mag', function(m) {
if (!Bangle.isLCDOn()) return; if (!Bangle.isLCDOn()) return;
var headingrad = m.heading*Math.PI/180; // in radians var headingrad = (360-m.heading)*Math.PI/180; // in radians
if (!isFinite(headingrad)) headingrad=0; if (!isFinite(headingrad)) headingrad=0;
if (nearest) if (nearest)
g.drawImage(img_fix,120,120,{ g.drawImage(img_fix,120,120,{

View File

@ -1,7 +1,7 @@
{ {
"id": "osmpoi", "id": "osmpoi",
"name": "POI Compass", "name": "POI Compass",
"version": "0.03", "version": "0.04",
"description": "Uploads all the points of interest in an area onto your watch, same as Beer Compass with more p.o.i.", "description": "Uploads all the points of interest in an area onto your watch, same as Beer Compass with more p.o.i.",
"icon": "app.png", "icon": "app.png",
"tags": "tool,outdoors,gps", "tags": "tool,outdoors,gps",

View File

@ -1,3 +1,4 @@
0.01: Initial check-in. 0.01: Initial check-in.
0.02: Make internal menu time out + small fixes. 0.02: Make internal menu time out + small fixes.
0.03: Autolight feature. 0.03: Autolight feature.
0.04: Added adjustment for Bangle.js magnetometer heading fix

View File

@ -70,7 +70,7 @@ class Options {
delay delay
); );
} }
bless(k) { bless(k) {
Object.defineProperty(this, k, { Object.defineProperty(this, k, {
get: () => this.backing[k], get: () => this.backing[k],
@ -103,7 +103,7 @@ class Options {
if (this.bored) clearTimeout(this.bored); if (this.bored) clearTimeout(this.bored);
this.bored = setTimeout(_ => this.showMenu(), 15000); this.bored = setTimeout(_ => this.showMenu(), 15000);
} }
reset() { reset() {
this.backing = {__proto__: this.constructor.defaults}; this.backing = {__proto__: this.constructor.defaults};
this.writeBack(0); this.writeBack(0);
@ -145,7 +145,7 @@ class RomanOptions extends Options {
Defaults: _ => {this.reset(); this.interact();} Defaults: _ => {this.reset(); this.interact();}
}; };
} }
interact() {this.showMenu(this.menu);} interact() {this.showMenu(this.menu);}
} }
@ -337,7 +337,7 @@ const events = {
// colour: colour, dramatic?: bool, event?: any} // colour: colour, dramatic?: bool, event?: any}
fixed: [{time: Number.POSITIVE_INFINITY}], // indexed by ms absolute fixed: [{time: Number.POSITIVE_INFINITY}], // indexed by ms absolute
wall: [{time: Number.POSITIVE_INFINITY}], // indexed by nominal ms + TZ ms wall: [{time: Number.POSITIVE_INFINITY}], // indexed by nominal ms + TZ ms
clean: function(now, l) { clean: function(now, l) {
let o = now.getTimezoneOffset() * 60000; let o = now.getTimezoneOffset() * 60000;
let tf = now.getTime() + l, tw = tf - o; let tf = now.getTime() + l, tw = tf - o;
@ -345,7 +345,7 @@ const events = {
while (this.wall[0].time <= tw) this.wall.shift(); while (this.wall[0].time <= tw) this.wall.shift();
while (this.fixed[0].time <= tf) this.fixed.shift(); while (this.fixed[0].time <= tf) this.fixed.shift();
}, },
scan: function(now, from, to, f) { scan: function(now, from, to, f) {
result = Infinity; result = Infinity;
let o = now.getTimezoneOffset() * 60000; let o = now.getTimezoneOffset() * 60000;
@ -482,7 +482,7 @@ class Sidebar {
compassI, compassI,
this.x + 4 + imageWidth(compassI) / 2, this.x + 4 + imageWidth(compassI) / 2,
this.y + 4 + imageHeight(compassI) / 2, this.y + 4 + imageHeight(compassI) / 2,
a ? {rotate: c.heading / 180 * Math.PI} : undefined a ? {rotate: (360-c.heading) / 180 * Math.PI} : undefined
); );
this.y += 4 + imageHeight(compassI); this.y += 4 + imageHeight(compassI);
} }
@ -535,13 +535,13 @@ class Roman {
static pos(p, r) { static pos(p, r) {
let h = r * rectW / 2; let h = r * rectW / 2;
let v = r * rectH / 2; let v = r * rectH / 2;
p = (p + 1) % 12; p = (p + 1) % 12;
return p <= 2 ? [faceCX + h * (p - 1), faceCY - v] return p <= 2 ? [faceCX + h * (p - 1), faceCY - v]
: p < 6 ? [faceCX + h, faceCY + v / 2 * (p - 4)] : p < 6 ? [faceCX + h, faceCY + v / 2 * (p - 4)]
: p <= 8 ? [faceCX - h * (p - 7), faceCY + v] : p <= 8 ? [faceCX - h * (p - 7), faceCY + v]
: [faceCX - h, faceCY - v / 2 * (p - 10)]; : [faceCX - h, faceCY - v / 2 * (p - 10)];
} }
alert(e, date, now, past) { alert(e, date, now, past) {
const g = this.g; const g = this.g;
g.setColor(e.colour); g.setColor(e.colour);
@ -564,7 +564,7 @@ class Roman {
} }
return Infinity; return Infinity;
} }
render(d, rate) { render(d, rate) {
const g = this.g; const g = this.g;
const state = this.state || (g.clear(true), this.state = {}); const state = this.state || (g.clear(true), this.state = {});
@ -625,7 +625,7 @@ class Roman {
for (let h = keyHour; h < keyHour + 12; h++) { for (let h = keyHour; h < keyHour + 12; h++) {
g.drawString( g.drawString(
numeral(h % 24, options), numeral(h % 24, options),
faceX + layout[h % 12 * 2], faceX + layout[h % 12 * 2],
faceY + layout[h % 12 * 2 + 1] faceY + layout[h % 12 * 2 + 1]
); );
} }
@ -643,7 +643,7 @@ class Roman {
(e, t, p) => this.alert(e, t, d, p) (e, t, p) => this.alert(e, t, d, p)
); );
if (rate > requestedRate) rate = requestedRate; if (rate > requestedRate) rate = requestedRate;
// Hands // Hands
// Here we are using incremental hands for hours and minutes. // Here we are using incremental hands for hours and minutes.
// If we quantised, we could use hand-crafted bitmaps, though. // If we quantised, we could use hand-crafted bitmaps, though.
@ -668,7 +668,7 @@ class Clock {
this.rates = {}; this.rates = {};
this.options.on('done', () => this.start()); this.options.on('done', () => this.start());
this.listeners = { this.listeners = {
charging: _ => {face.doIcons('charging'); this.active();}, charging: _ => {face.doIcons('charging'); this.active();},
lock: _ => {face.doIcons('locked'); this.active();}, lock: _ => {face.doIcons('locked'); this.active();},
@ -723,7 +723,7 @@ class Clock {
this.face.reset(); // Cancel any ongoing background rendering this.face.reset(); // Cancel any ongoing background rendering
return this; return this;
} }
active() { active() {
const prev = this.rate; const prev = this.rate;
const now = Date.now(); const now = Date.now();

View File

@ -1,7 +1,7 @@
{ "id": "pooqroman", { "id": "pooqroman",
"name": "pooq Roman watch face", "name": "pooq Roman watch face",
"shortName":"pooq Roman", "shortName":"pooq Roman",
"version":"0.03", "version":"0.04",
"description": "A classic watch face with a certain dynamicity. Most amusing in 24h mode. Slide up to show more hands, down for less(!). By design does not support standard widgets, sorry!", "description": "A classic watch face with a certain dynamicity. Most amusing in 24h mode. Slide up to show more hands, down for less(!). By design does not support standard widgets, sorry!",
"icon": "app.png", "icon": "app.png",
"type": "clock", "type": "clock",

View File

@ -1,3 +1,4 @@
0.01: New App! 0.01: New App!
0.02: Change color from red->yellow to ease readability (fix #710) 0.02: Change color from red->yellow to ease readability (fix #710)
0.03: Color/positioning change to allow it to work with Bangle.js 1 (although not pretty) 0.03: Color/positioning change to allow it to work with Bangle.js 1 (although not pretty)
0.04: Added adjustment for Bangle.js magnetometer heading fix

View File

@ -231,7 +231,7 @@ document.getElementById("upload").addEventListener("click", function() {
if (!Bangle.isLCDOn()) return; if (!Bangle.isLCDOn()) return;
arrow(oldHeading,g.theme.bg); arrow(oldHeading,g.theme.bg);
var heading = m.heading + nextAngle; var heading = (360-m.heading) + nextAngle;
arrow(heading,"#f00"); arrow(heading,"#f00");
oldHeading = heading; oldHeading = heading;
} }

View File

@ -1,7 +1,7 @@
{ {
"id": "route", "id": "route",
"name": "Route Viewer", "name": "Route Viewer",
"version": "0.03", "version": "0.04",
"description": "Upload a KML file of a route, and have your watch display a map with how far around it you are", "description": "Upload a KML file of a route, and have your watch display a map with how far around it you are",
"icon": "app.png", "icon": "app.png",
"tags": "", "tags": "",

View File

@ -10,4 +10,4 @@
0.09: Vibrate with configured pattern 0.09: Vibrate with configured pattern
Add setting to defer start of algorithm Add setting to defer start of algorithm
Add setting to disable scheduler alarm Add setting to disable scheduler alarm
0.10: Fix: Do not wake when falling asleep

View File

@ -9,6 +9,8 @@ The display shows:
- Time difference between current time and alarm time (ETA). - Time difference between current time and alarm time (ETA).
- Current state of the ESS algorithm, "Sleep" or "Awake", useful for debugging. State can also be "Deferred", see the "Run before alarm"-option. - Current state of the ESS algorithm, "Sleep" or "Awake", useful for debugging. State can also be "Deferred", see the "Run before alarm"-option.
Replacing the watch strap with a more comfortable one (e.g. made of nylon) is recommended.
## Settings ## Settings
* **Keep alarm enabled** * **Keep alarm enabled**
@ -16,7 +18,7 @@ The display shows:
- No: No action at configured alarm time from scheduler. - No: No action at configured alarm time from scheduler.
* **Run before alarm** * **Run before alarm**
- disabled: (default) The ESS algorithm starts immediately when the application starts. - disabled: (default) The ESS algorithm starts immediately when the application starts.
- 1..23: The ESS algorithm starts the configured time before the alarm. E.g. when set to 1h for an alarm at 7:00 the ESS algorithm will start at 6:00. This improves battery life. - 1..23: The ESS algorithm starts the configured time before the alarm. E.g. when set to 1h for an alarm at 7:00 the ESS algorithm will start at 6:00. This increases battery life.
## Logging ## Logging

View File

@ -168,7 +168,7 @@ if (nextAlarmDate !== undefined) {
// The alarm widget should handle this one // The alarm widget should handle this one
addLog(now, "alarm"); addLog(now, "alarm");
setTimeout(load, 1000); setTimeout(load, 1000);
} else if (measure && now >= minAlarm && swest_last === false) { } else if (measure && now >= minAlarm && swest === false) {
addLog(now, "alarm"); addLog(now, "alarm");
buzz(); buzz();
measure = false; measure = false;

View File

@ -30,7 +30,7 @@ function getData() {
// remove window // remove window
Util.hideModal(); Util.hideModal();
logs = logs.filter(log => log != null); logs = logs.filter(log => log != null && log.filter(entry => entry.type === "alarm").length > 0);
logs.sort(function(a, b) {return new Date(b?.filter(entry => entry.type === "alarm")[0]?.time) - new Date(a?.filter(entry => entry.type === "alarm")[0]?.time)}); // sort by alarm date desc logs.sort(function(a, b) {return new Date(b?.filter(entry => entry.type === "alarm")[0]?.time) - new Date(a?.filter(entry => entry.type === "alarm")[0]?.time)}); // sort by alarm date desc
logs.forEach((log, i) => { logs.forEach((log, i) => {
const timeStr = log.filter(entry => entry.type === "alarm")[0]?.time; const timeStr = log.filter(entry => entry.type === "alarm")[0]?.time;

View File

@ -2,7 +2,7 @@
"id": "sleepphasealarm", "id": "sleepphasealarm",
"name": "SleepPhaseAlarm", "name": "SleepPhaseAlarm",
"shortName": "SleepPhaseAlarm", "shortName": "SleepPhaseAlarm",
"version": "0.09", "version": "0.10",
"description": "Uses the accelerometer to estimate sleep and wake states with the principle of Estimation of Stationary Sleep-segments (ESS, see https://ubicomp.eti.uni-siegen.de/home/datasets/ichi14/index.html.en). This app will read the next alarm from the alarm application and will wake you up to 30 minutes early at the best guessed time when you are almost already awake.", "description": "Uses the accelerometer to estimate sleep and wake states with the principle of Estimation of Stationary Sleep-segments (ESS, see https://ubicomp.eti.uni-siegen.de/home/datasets/ichi14/index.html.en). This app will read the next alarm from the alarm application and will wake you up to 30 minutes early at the best guessed time when you are almost already awake.",
"icon": "app.png", "icon": "app.png",
"tags": "alarm", "tags": "alarm",

View File

@ -3,3 +3,4 @@
0.03: Silently use built in heading when no magnav calibration file is present 0.03: Silently use built in heading when no magnav calibration file is present
0.04: Move waypoints.json (and editor) to 'waypoints' app 0.04: Move waypoints.json (and editor) to 'waypoints' app
0.05: Fix not displaying of wpindex = 0 0.05: Fix not displaying of wpindex = 0
0.06: Added adjustment for Bangle.js magnetometer heading fix

View File

@ -80,7 +80,7 @@ function tiltfixread(O,S){
var m = Bangle.getCompass(); var m = Bangle.getCompass();
if (O === undefined || S === undefined) { if (O === undefined || S === undefined) {
// no valid calibration from magnav, use built in // no valid calibration from magnav, use built in
return 360-m.heading; return m.heading;
} }
var g = Bangle.getAccel(); var g = Bangle.getAccel();
m.dx =(m.x-O.x)*S.x; m.dy=(m.y-O.y)*S.y; m.dz=(m.z-O.z)*S.z; m.dx =(m.x-O.x)*S.x; m.dy=(m.y-O.y)*S.y; m.dz=(m.z-O.z)*S.z;

View File

@ -1,7 +1,7 @@
{ {
"id": "waypointer", "id": "waypointer",
"name": "Way Pointer", "name": "Way Pointer",
"version": "0.05", "version": "0.06",
"description": "Navigate to a waypoint using the GPS for bearing and compass to point way, uses the same waypoint interface as GPS Navigation", "description": "Navigate to a waypoint using the GPS for bearing and compass to point way, uses the same waypoint interface as GPS Navigation",
"icon": "waypointer.png", "icon": "waypointer.png",
"tags": "tool,outdoors,gps", "tags": "tool,outdoors,gps",

View File

@ -1,3 +1,4 @@
... ...
0.02: First update with ChangeLog Added 0.02: First update with ChangeLog Added
0.03: Move waypoints.json (and editor) to 'waypoints' app 0.03: Move waypoints.json (and editor) to 'waypoints' app
0.04: Added adjustment for Bangle.js magnetometer heading fix

View File

@ -134,7 +134,7 @@ function read_heading() {
Bangle.setCompassPower(1); Bangle.setCompassPower(1);
var d = 0; var d = 0;
var m = Bangle.getCompass(); var m = Bangle.getCompass();
if (!isNaN(m.heading)) d = -m.heading; if (!isNaN(m.heading)) d = m.heading;
heading = d; heading = d;
} }

View File

@ -2,7 +2,7 @@
"id": "wpmoto", "id": "wpmoto",
"name": "Waypointer Moto", "name": "Waypointer Moto",
"shortName": "Waypointer Moto", "shortName": "Waypointer Moto",
"version": "0.03", "version": "0.04",
"description": "Waypoint-based motorcycle navigation aid", "description": "Waypoint-based motorcycle navigation aid",
"icon": "wpmoto.png", "icon": "wpmoto.png",
"tags": "tool,outdoors,gps", "tags": "tool,outdoors,gps",

View File

@ -5403,15 +5403,6 @@ declare class Bangle {
*/ */
static getHealthStatus(range?: "current" | "last" | "day"): HealthStatus; static getHealthStatus(range?: "current" | "last" | "day"): HealthStatus;
/**
* Feature flag - If true, this Bangle.js firmware reads `setting.json` and
* modifies beep & buzz behaviour accordingly (the bootloader doesn't need to do
* it).
* @returns {boolean}
* @url http://www.espruino.com/Reference#l_Bangle_F_BEEPSET
*/
static F_BEEPSET: boolean;
/** /**
* Reads debug info * Reads debug info
* @returns {any} * @returns {any}
@ -13018,4 +13009,4 @@ type Libraries = {
*/ */
read(length: number, addr: number): any; read(length: number, addr: number): any;
} }
} }