Merge remote-tracking branch 'upstream/master'
36
apps.json
|
@ -65,7 +65,7 @@
|
|||
{ "id": "locale",
|
||||
"name": "Languages",
|
||||
"icon": "locale.png",
|
||||
"version":"0.08",
|
||||
"version":"0.09",
|
||||
"description": "Translations for different countries",
|
||||
"tags": "tool,system,locale,translate",
|
||||
"type": "locale",
|
||||
|
@ -269,6 +269,30 @@
|
|||
{"name":"clock2x3.img","url":"clock2x3-icon.js","evaluate":true}
|
||||
]
|
||||
},
|
||||
{ "id": "geissclk",
|
||||
"name": "Geiss Clock",
|
||||
"icon": "clock.png",
|
||||
"version":"0.01",
|
||||
"description": "7 segment clock with animated background in the style of Ryan Geiss' music visualisation. NOTE: The first run will take ~1 minute to do some precalculation",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
"storage": [
|
||||
{"name":"geissclk.app.js","url":"clock.js"},
|
||||
{"name":"geissclk.precompute.js","url":"precompute.js"},
|
||||
{"name":"geissclk.img","url":"clock-icon.js","evaluate":true}
|
||||
],
|
||||
"data": [
|
||||
{"name":"geissclk.0.map"},
|
||||
{"name":"geissclk.1.map"},
|
||||
{"name":"geissclk.2.map"},
|
||||
{"name":"geissclk.3.map"},
|
||||
{"name":"geissclk.4.map"},
|
||||
{"name":"geissclk.5.map"},
|
||||
{"name":"geissclk.0.pal"},
|
||||
{"name":"geissclk.1.pal"},
|
||||
{"name":"geissclk.2.pal"}
|
||||
]
|
||||
},
|
||||
{ "id": "trex",
|
||||
"name": "T-Rex",
|
||||
"icon": "trex.png",
|
||||
|
@ -1492,7 +1516,7 @@
|
|||
"name": "Digital Assistant, not EDITH",
|
||||
"shortName": "DANE",
|
||||
"icon": "app.png",
|
||||
"version": "0.15",
|
||||
"version": "0.16",
|
||||
"description": "A Watchface inspired by Tony Stark's EDITH and based on https://arwes.dev/",
|
||||
"tags": "clock",
|
||||
"type": "clock",
|
||||
|
@ -2637,11 +2661,11 @@
|
|||
]
|
||||
},
|
||||
{ "id": "speedalt",
|
||||
"name": "GPS Speedo and Altimeter",
|
||||
"shortName":"GPS Speed Alt",
|
||||
"name": "GPS Adventure Sports",
|
||||
"shortName":"GPS Adv Sport",
|
||||
"icon": "app.png",
|
||||
"version":"0.07",
|
||||
"description": "GPS speed and altitude display. Designed for easy viewing and use during outdoor activities such as para-gliding, hang-gliding, sailing, cycling etc.",
|
||||
"version":"1.00",
|
||||
"description": "GPS speed, altitude and distance to waypoint display. Designed for easy viewing and use during outdoor activities such as para-gliding, hang-gliding, sailing, cycling etc.",
|
||||
"tags": "tool,outdoors",
|
||||
"type":"app",
|
||||
"allow_emulator":true,
|
||||
|
|
|
@ -10,4 +10,5 @@
|
|||
0.12: Move code to Arwes Module
|
||||
0.13: Improve icon
|
||||
0.14: Switch Icon back to 8bit web palette to fix it
|
||||
0.15: Hotfix: Remove var declaration from app image
|
||||
0.15: Hotfix: Remove var declaration from app image
|
||||
0.16: Revert: Change Counter back to button control
|
|
@ -67,7 +67,7 @@ function levelColor(l) {
|
|||
|
||||
function drawBattery() {
|
||||
const l = E.getBattery(), c = levelColor(l);
|
||||
count = l;
|
||||
// count = l;
|
||||
const xl = 45 + l * (194 - 46) / 100;
|
||||
g.clearRect(46, 58 + 80 + yOffset + 37, 193, height - 5);
|
||||
g.setColor(c).fillRect(46, 58 + 80 + yOffset + 37, xl, height - 5);
|
||||
|
@ -124,14 +124,14 @@ drawClock();
|
|||
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat: false, edge: "falling"});
|
||||
|
||||
// setWatch(function () {
|
||||
// count++;
|
||||
// drawCounterText();
|
||||
// }, BTN1, {repeat: true, edge: "falling"});
|
||||
// setWatch(function () {
|
||||
// count--;
|
||||
// drawCounterText();
|
||||
// }, BTN3, {repeat: true, edge: "falling"});
|
||||
setWatch(function () {
|
||||
count++;
|
||||
drawCounterText();
|
||||
}, BTN1, {repeat: true, edge: "falling"});
|
||||
setWatch(function () {
|
||||
count--;
|
||||
drawCounterText();
|
||||
}, BTN3, {repeat: true, edge: "falling"});
|
||||
|
||||
// refesh every 100 milliseconds
|
||||
setInterval(updateClock, 500);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
0.01: New App!
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEw4X/AoMF/3G/2m/wOCmoaKmtAAgVQBYsFoECwALMAA0JBZQABBYIbBBaVUBYMVBYkBIIILDgEKGYUBqkA6oLB6sAlQLDqsAioLBCAOq4AkCqtAivCBYMC1YwDitQgtCwNUhWsOwlUBYVQlWwJAlVgtSxNQFwnwGANBqWFqQuE1QwBqNewtKFwgLBGANWytq2EFWoU6gWBqoLBFwNVYIZZBqtXyurioLF1W1q/W1tVPIIxE1NV72VqpTDDAleEIgADnWq3qgBTIYADvQuBAAVUBYla1XVBYYbDyt632qd40Fqulquq0ALFOwO16t6BYpxBvWX6tW0aoDXwNU1XXNQMD1T7CAwPC1abBegPqFodQdQILCO4hxBlWxq2FoqaFBYOBcYNxQggLCToOBqAwBTgwLCiqoGgtCJ4L0BBYsVBYRmBBY0CwEUJ4IwFBYkVBYsMBYI0CJAwLDAA4L2A="))
|
|
@ -0,0 +1,145 @@
|
|||
var W = 79, H = 64;
|
||||
/*var compiled = E.compiledC(`
|
||||
// void transl(int, int, int )
|
||||
int transl(unsigned char *map, unsigned char *imgfrom, unsigned char *imgto) {
|
||||
int n = 0;
|
||||
const int W = 79;
|
||||
const int H = 64;
|
||||
for (int y=0;y<H;y++)
|
||||
for (int x=0;x<W;x++) {
|
||||
int d = map[n];
|
||||
int nx = (x<<3) + ((d )&0x0F) - 8;
|
||||
int ny = (y<<3) + ((d>>4)&0x0F) - 8;
|
||||
int ax = nx&7;
|
||||
int ay = ny&7;
|
||||
int a = (nx>>3) + ((ny>>3)*W);
|
||||
int c = 0;
|
||||
if (a>=0 && a<(W*H-(W+1))) {
|
||||
c = imgfrom[a]*(8-ax)*(8-ay) +
|
||||
imgfrom[a+1]*(ax)*(8-ay) +
|
||||
imgfrom[a+W]*(8-ax)*(ay) +
|
||||
imgfrom[a+W+1]*(ax)*(ay);
|
||||
c = (c>>6) - 4;
|
||||
if (c<0) c=0;
|
||||
}
|
||||
imgto[n] = c;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
`);*/
|
||||
var compiled = (function(){
|
||||
var bin=atob("Len3TwAnT/BPCPsAAJMI+wfzAOsDCdMYAZMAJhn4BkAAnQTwDwMD68YDBesUFAg7CDzdEE/q5AoI+wpaQfJvNapFItgB6woOA/AHAxH4CsCe+AGww/EIBQX7DPwD+wvMnvhPsATwBwQF+wv1ZUPE8QgKCvsMXJ74UFBrQwT7A8SkEQQ8JOrkdADgACQBm5xVATZPLsLRATdAL7bRA7C96PCPAAA=");
|
||||
return {
|
||||
transl:E.nativeCall(1, "void(int, int, int )", bin),
|
||||
};
|
||||
})();
|
||||
|
||||
require("Font7x11Numeric7Seg").add(Graphics);
|
||||
|
||||
// Allocate the data
|
||||
var dataa = new Uint8Array(W*H);
|
||||
var datab = new Uint8Array(W*H);
|
||||
var map = new Uint8Array(W*H);
|
||||
var pal = new Uint16Array(256);
|
||||
var PALETTES = 3;
|
||||
var MAPS = 6;
|
||||
|
||||
// If we're missing any maps, compute them!
|
||||
(function() {
|
||||
var files = require("Storage").list(/^geissclk/);
|
||||
var allOk = true;
|
||||
for (var n=0;n<PALETTES;n++)
|
||||
if (!files.includes("geissclk."+n+".pal"))
|
||||
allOk = false;
|
||||
for (var n=0;n<MAPS;n++)
|
||||
if (!files.includes("geissclk."+n+".map"))
|
||||
allOk = false;
|
||||
if (!allOk)
|
||||
eval(require("Storage").read("geissclk.precompute.js"));
|
||||
})();
|
||||
|
||||
function randomPalette() {
|
||||
var n = (0|Math.random()*200000) % PALETTES;
|
||||
var p = new Uint8Array(pal.buffer);
|
||||
p.set(require("Storage").readArrayBuffer("geissclk."+n+".pal"));
|
||||
}
|
||||
|
||||
function randomMap() {
|
||||
var n = (0|Math.random()*200000) % MAPS;
|
||||
map.set(require("Storage").readArrayBuffer("geissclk."+n+".map"));
|
||||
}
|
||||
|
||||
|
||||
randomPalette();
|
||||
randomMap();
|
||||
|
||||
// Get the address
|
||||
var addra = E.getAddressOf(dataa,true);
|
||||
if (!addra) throw new Error("Not a Flat String");
|
||||
var addrb = E.getAddressOf(datab,true);
|
||||
if (!addrb) throw new Error("Not a Flat String");
|
||||
var addrmap = E.getAddressOf(map,true);
|
||||
if (!addrmap) throw new Error("Not a Flat String");
|
||||
var gfx = Graphics.createArrayBuffer(W,H,8);
|
||||
gfx.buffer = dataa.buffer;
|
||||
|
||||
var im = {
|
||||
width:W, height:H, bpp:8,
|
||||
palette: pal,
|
||||
buffer : dataa.buffer
|
||||
};
|
||||
var lastSeconds = -1;
|
||||
|
||||
function iterate() { "ram"
|
||||
var d = new Date();
|
||||
var time = d.getHours().toString().padStart(2," ")+":"+d.getMinutes().toString().padStart(2,0);
|
||||
var seconds = d.getSeconds().toString().padStart(2,0);
|
||||
t = addra; addra = addrb; addrb = t;
|
||||
t = dataa; dataa = datab; datab = t;
|
||||
if (seconds!=lastSeconds) {
|
||||
lastSeconds = seconds;
|
||||
im.buffer = datab.buffer;
|
||||
gfx.buffer = datab.buffer;
|
||||
} else {
|
||||
im.buffer = dataa.buffer;
|
||||
gfx.buffer = dataa.buffer;
|
||||
}
|
||||
var x,y,n,t = getTime()/10;
|
||||
var amt = 100*Bangle.getAccel().diff;
|
||||
for (var i=0;i<amt;i++) {
|
||||
//x = Math.round((W/2) + 20*Math.sin(t));
|
||||
//y = Math.round((H/2) + 20*Math.cos(t));
|
||||
//t += 0.628;
|
||||
x = 1+(Math.random()*(W-2))|0;
|
||||
y = 1+(Math.random()*(H-2))|0;
|
||||
dataa[x + y*W] = 240;
|
||||
}
|
||||
compiled.transl(addrmap, addra, addrb);
|
||||
|
||||
|
||||
gfx.setFont("7x11Numeric7Seg",2);
|
||||
gfx.drawString(time, -5, 20);
|
||||
gfx.setFont("7x11Numeric7Seg");
|
||||
gfx.drawString(seconds, 62, 30);
|
||||
// firmwares pre-2v09 wouldn't accelerate a 3x blit if it went right to the RHS - hence we're 79px not 80
|
||||
g.drawImage(im,1,24,{scale:3});
|
||||
}
|
||||
|
||||
|
||||
Bangle.on('lcdPower',function(on) {
|
||||
if (animInterval) {
|
||||
clearInterval(animInterval);
|
||||
animInterval = undefined;
|
||||
}
|
||||
if (on) {
|
||||
randomMap();
|
||||
randomPalette();
|
||||
iterate();
|
||||
animInterval = setInterval(iterate, 50);
|
||||
}
|
||||
});
|
||||
g.clear();
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
iterate();
|
||||
animInterval = setInterval(iterate, 50);
|
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,108 @@
|
|||
// PALETTES ---------------------------
|
||||
E.showMessage("Precomputing\npalettes\n\nPlease wait...\n0 / 3");
|
||||
(function() { // fire
|
||||
for (var i=0;i<256;i++) {
|
||||
var r = Math.min(i*6,240);
|
||||
var g = Math.min(i*3,240);
|
||||
var b = E.clip((i-192)*8,0,240);
|
||||
pal[i] = (b>>3) | ((g&0xFC)<<3) | ((r&0xF8)<<8);
|
||||
}pal[255] = 65535;
|
||||
})()
|
||||
require("Storage").write("geissclk.0.pal",pal.buffer);
|
||||
E.showMessage("Precomputing\npalettes\n\nPlease wait...\n1 / 3");
|
||||
(function() { // gunge
|
||||
for (var i=0;i<256;i++) {
|
||||
var r = 0;
|
||||
var g = Math.min(i*3,255);
|
||||
var b = Math.min(i,255);
|
||||
pal[i] = (b>>3) | ((g&0xFC)<<3) | ((r&0xF8)<<8);
|
||||
}pal[255] = 65535;
|
||||
})()
|
||||
require("Storage").write("geissclk.1.pal",pal.buffer);
|
||||
E.showMessage("Precomputing\npalettes\n\nPlease wait...\n2 / 3");
|
||||
(function() { // rainbow
|
||||
for (var i=0;i<256;i++) {
|
||||
var cl = E.HSBtoRGB((48+i)/128,1,Math.min(i/16,0.9),true);
|
||||
var r = cl[0];
|
||||
var g = cl[1];
|
||||
var b = cl[2];
|
||||
pal[i] = (b>>3) | ((g&0xFC)<<3) | ((r&0xF8)<<8);
|
||||
}pal[255] = 65535;pal[255] = 65535;
|
||||
})()
|
||||
require("Storage").write("geissclk.2.pal",pal.buffer);
|
||||
|
||||
|
||||
// MAPS ----------------------------------------------
|
||||
E.showMessage("Precomputing\nmaps\n\nPlease wait...\n0 / 5");
|
||||
// straight out
|
||||
(function() { "ram"; var n = 0; for (var y=0;y<H;y++) {
|
||||
for (var x=0;x<W;x++) {
|
||||
var dx = x-(W/2);
|
||||
var dy = y-(H/2);
|
||||
var d = Math.sqrt(dx*dx + dy*dy);
|
||||
var s = -2 + Math.sin(d*0.5);
|
||||
dx = dx*s/d;
|
||||
dy = dy*s/d;
|
||||
map[n++] = ((dx*2 + 8) & 0x0F) | (((dy*2 + 8) & 0x0F)<<4);
|
||||
}
|
||||
}})();
|
||||
require("Storage").write("geissclk.0.map",map);
|
||||
E.showMessage("Precomputing\nmaps\n\nPlease wait...\n1 / 5");
|
||||
// ripple out
|
||||
(function() { "ram"; var n = 0; for (var y=0;y<H;y++) {
|
||||
for (var x=0;x<W;x++) {
|
||||
var dx = x-(W/2);
|
||||
var dy = y-(H/2);
|
||||
var d = Math.sqrt(dx*dx + dy*dy);
|
||||
var s = -2 + Math.sin(d*0.5)/2;
|
||||
dx = dx*s/d;
|
||||
dy = dy*s/d;
|
||||
map[n++] = ((dx*3 + 8) & 0x0F) | (((dy*3 + 8) & 0x0F)<<4);
|
||||
}
|
||||
}})();
|
||||
require("Storage").write("geissclk.1.map",map);
|
||||
E.showMessage("Precomputing\nmaps\n\nPlease wait...\n2 / 5");
|
||||
// twisty outwards
|
||||
(function() { "ram"; var n = 0; for (var y=0;y<H;y++) {
|
||||
for (var x=0;x<W;x++) {
|
||||
var dx = x-(W/2);
|
||||
var dy = y-(H/2);
|
||||
var d = Math.sqrt(dx*dx + dy*dy);
|
||||
dx = (-dx/d) + (((y&7)>3)?0.5:-0.5);
|
||||
dy = (-dy/d) + (((x&7)>3)?0.5:-0.5);
|
||||
map[n++] = ((dx*3 + 8) & 0x0F) | (((dy*3 + 8) & 0x0F)<<4);
|
||||
}
|
||||
}})()
|
||||
require("Storage").write("geissclk.2.map",map);
|
||||
E.showMessage("Precomputing\nmaps\n\nPlease wait...\n3 / 5");
|
||||
// spiral
|
||||
(function() { "ram"; var n = 0; for (var y=0;y<H;y++) {
|
||||
for (var x=0;x<W;x++) {
|
||||
var dx = x-(W/2);
|
||||
var dy = y-(H/2);
|
||||
var d = Math.sqrt(dx*dx + dy*dy);
|
||||
var cx = (2*dy-dx)/(2*d);
|
||||
var cy = (-2*dx-dy)/(2*d);
|
||||
map[n++] = ((cx*3 + 8) & 0x0F) | (((cy*3 + 8) & 0x0F)<<4);
|
||||
}
|
||||
}})();
|
||||
require("Storage").write("geissclk.3.map",map);
|
||||
E.showMessage("Precomputing\nmaps\n\nPlease wait...\n4 / 5");
|
||||
// blur down
|
||||
(function() { "ram"; var n=0; for (var y=0;y<H;y++) {
|
||||
for (var x=0;x<W;x++) {
|
||||
map[n++] = 136 - 6*16 + (y&1)*8-4;
|
||||
}
|
||||
}})()
|
||||
require("Storage").write("geissclk.4.map",map);
|
||||
E.showMessage("Precomputing\nmaps\n\nPlease wait...\n5 / 5");
|
||||
// twisty
|
||||
(function() { "ram"; var n=0; for (var y=0;y<H;y++) {
|
||||
for (var x=0;x<W;x++) {
|
||||
dx = Math.sin(y*0.2);
|
||||
dy = Math.cos(x*0.2);
|
||||
map[n++] = ((dx*6 + 8) & 0x0F) | (((dy*6 + 8) & 0x0F)<<4);
|
||||
}
|
||||
}})()
|
||||
require("Storage").write("geissclk.5.map",map)
|
||||
E.showMessage("Finished!");
|
|
@ -8,3 +8,4 @@
|
|||
Ensure 'on' is always supplied for translations
|
||||
0.07: Improve handling of non-ASCII characters (fix #469)
|
||||
0.08: Added Mavigation units and en_NAV
|
||||
0.09: Added New Zealand en_NZ
|
||||
|
|
|
@ -245,6 +245,24 @@ var locales = {
|
|||
day: "söndag,måndag,tisdag,onsdag,torsdag,fredag,lördag",
|
||||
trans: { yes: "ja", Yes: "Ja", no: "nej", No: "Nej", ok: "ok", on: "on", off: "off" }
|
||||
},
|
||||
"en_NZ": {
|
||||
lang: "en_NZ",
|
||||
decimal_point: ".",
|
||||
thousands_sep: ",",
|
||||
currency_symbol: "$",
|
||||
int_curr_symbol: "NZD",
|
||||
speed: "kph",
|
||||
distance: { 0: "m", 1: "km" },
|
||||
temperature: "°C",
|
||||
ampm: { 0: "am", 1: "pm" },
|
||||
timePattern: { 0: "%HH:%MM:%SS ", 1: "%HH:%MM" },
|
||||
datePattern: { 0: "%A, %B %d, %Y", "1": "%d/%m/%y" }, // Sunday, 1 March 2020 // 1/3/20
|
||||
abmonth: "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec",
|
||||
month: "January,February,March,April,May,June,July,August,September,October,November,December",
|
||||
abday: "Sun,Mon,Tue,Wed,Thu,Fri,Sat",
|
||||
day: "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday",
|
||||
// No translation for english...
|
||||
},
|
||||
"en_AU": {
|
||||
lang: "en_AU",
|
||||
decimal_point: ".",
|
||||
|
|
|
@ -5,3 +5,4 @@
|
|||
0.05: Add setting to turn vibrate on/off.
|
||||
0.06: Tweaks to vibration settings.
|
||||
0.07: Switch to BTN1 for Max toggle and reset function.
|
||||
1.00: New features. Added waypoints file and distance to selected waypoint display. Added integration with GPS Setup module to switch GPS to low power mode when screen off. Save display settings and restore when app restarted.
|
|
@ -1,18 +1,143 @@
|
|||
Displays the GPS speed and altitude. One is displayed on the watch face using the largest possible characters depending on the number of digits. The other is in a smaller characters below that. Both are always visible. You can display the current or maximum observed speed/altitude values. Current time is always displayed.
|
||||
# GPS Speed, Altimeter and Distance to Waypoint
|
||||
|
||||
Display Tap : Swaps the displays. You can have either speed or altitude on the large primary display.
|
||||
You can switch between two display modes. One showing speed and altitude (A) and one showing speed and distance to waypoint (D).
|
||||
|
||||
BTN1 : Short press < 2 secs toggles the displays between showing the current speed/alt values or the maximum values recorded.
|
||||
Within each display mode one figure is displayed on the watch face using the largest possible characters depending on the number of digits. The other is in a smaller characters below that. Both are always visible. You can display the current or maximum observed speed/altitude values. Current time is always displayed.
|
||||
|
||||
The waypoints list is the same as that used with the [GPS Navigation](https://banglejs.com/apps/#gps%20navigation) app so the same set of waypoints can be used across both apps. Refer to that app for waypoint file information.
|
||||
|
||||
## Buttons and Controls
|
||||
|
||||
BTN3 : Swaps the modes between Speed+[A]ltitude or Speed+[D]istance.
|
||||
|
||||
### [A]ltitude mode
|
||||
|
||||
BTN1 : Short press < 2 secs toggles the displays between showing the current speed/alt values or the maximum speed/alt values recorded.
|
||||
|
||||
BTN1 : Long press > 2 secs resets the recorded maximum values.
|
||||
|
||||
App Settings : Select the desired display units. Speed can be as per the default locale, kph, knots, mph or m/s. Altitude can be feet or metres. Select one of three colour schemes. Colours, high contrast (all white on black) or night ( all red on black ). Vibration can be used to indicate when a fix is lost or gained. One buzz for a lost fix and a double buzz when a fix is found.
|
||||
### [D]istance mode
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
BTN1 : Select next waypoint. Last fix distance from selected waypoint is displayed.
|
||||
|
||||
### Both modes
|
||||
|
||||
BTN2 : Disables/Restores power saving timeout. Locks the screen on to enable reading for longer periods but uses maximum battery drain. Red LED (dot) at top of screen when screen is locked on. Press again to restore power saving timeouts.
|
||||
|
||||
BTN3 : Long press exit and return to watch.
|
||||
|
||||
BTN4 : Left Display Tap : Swaps which figure is in the large display. You can have either speed or [A]ltitude/[D]istance on the large primary display.
|
||||
|
||||
## App Settings
|
||||
|
||||
Select the desired display units. Speed can be as per the default locale, kph, knots, mph or m/s. Distance can be km, miles or nautical miles. Altitude can be feet or metres. Select one of three colour schemes. Default (three colours), high contrast (all white on black) or night ( all red on black ).
|
||||
|
||||
## Loss of fix
|
||||
|
||||
When the GPS obtains a fix the number of satellites is displayed as 'Sats:nn'. When unable to obtain a fix then the last known fix is used and the age of that fix in seconds is displayed as 'Age:nn'. Seeing 'Sats' or 'Age' indicates whether the GPS has a current fix or not.
|
||||
|
||||
## Screens
|
||||
|
||||
Speed and Altitude:<br>
|
||||
<p>
|
||||
Left tap swaps displays:<br>
|
||||
<p>
|
||||
Distance to waypoint DeltaW:<br>
|
||||
<p>
|
||||
MAX Values instead:<br>
|
||||
<p>
|
||||
Settings:<br>
|
||||
<p>
|
||||
|
||||
## Power Saving
|
||||
|
||||
The The GPS Adv Sport app obeys the watch screen off timeouts as a power saving measure. Restore the screen as per any of the colck/watch apps. Use BTN2 to lock the screen on but doing this will use more battery.
|
||||
|
||||
This app will work quite happily on its own but will use the [GPS Setup App](https://banglejs.com/apps/#gps%20setup) if it is installed. You may choose to use the GPS Setup App to gain significantly longer battery life while the GPS is on. Please read the Low Power GPS Setup App Readme to understand what this does.
|
||||
|
||||
When using the GPS Setup App this app switches the GPS to SuperE (default) mode while the display is lit and showing fix information. This ensures that that fixes are updated every second or so. 10 seconds after the display is blanked by the watch this app will switch the GPS to PSMOO mode and will only attempt to get a fix every two minutes. This improves power saving while the display is off and the delay gives an opportunity to restore the display before the GPS power mode is switched.
|
||||
|
||||
The MAX values continue to be collected with the display off so may appear a little odd after the intermittent fixes of the low power mode.
|
||||
|
||||
## Waypoints
|
||||
|
||||
Waypoints are used in [D]istance mode. Create a file waypoints.json and write to storage on the Bangle.js using the IDE. The first 6 characters of the name are displayed in Speed+[D]istance mode.
|
||||
|
||||
The [GPS Navigation](https://banglejs.com/apps/#gps%20navigation) app in the App Loader has a really nice waypoints file editor. (Must be connected to your Bangle.JS and then click on the Download icon.)
|
||||
|
||||
Sample waypoints.json (My sailing waypoints)
|
||||
|
||||
<pre>
|
||||
[
|
||||
{
|
||||
"name":"NONE"
|
||||
},
|
||||
{
|
||||
"name":"Omori",
|
||||
"lat":-38.9058670,
|
||||
"lon":175.7613350
|
||||
},
|
||||
{
|
||||
"name":"DeltaW",
|
||||
"lat":-38.9438550,
|
||||
"lon":175.7676930
|
||||
},
|
||||
{
|
||||
"name":"DeltaE",
|
||||
"lat":-38.9395240,
|
||||
"lon":175.7814420
|
||||
},
|
||||
{
|
||||
"name":"BtClub",
|
||||
"lat":-38.9446020,
|
||||
"lon":175.8475720
|
||||
},
|
||||
{
|
||||
"name":"Hapua",
|
||||
"lat":-38.8177750,
|
||||
"lon":175.8088720
|
||||
},
|
||||
{
|
||||
"name":"Nook",
|
||||
"lat":-38.7848090,
|
||||
"lon":175.7839440
|
||||
},
|
||||
{
|
||||
"name":"ChryBy",
|
||||
"lat":-38.7975050,
|
||||
"lon":175.7551960
|
||||
},
|
||||
{
|
||||
"name":"Waiha",
|
||||
"lat":-38.7219630,
|
||||
"lon":175.7481520
|
||||
},
|
||||
{
|
||||
"name":"KwaKwa",
|
||||
"lat":-38.6632310,
|
||||
"lon":175.8670320
|
||||
},
|
||||
{
|
||||
"name":"Hatepe",
|
||||
"lat":-38.8547420,
|
||||
"lon":176.0089124
|
||||
},
|
||||
{
|
||||
"name":"Kinloc",
|
||||
"lat":-38.6614442,
|
||||
"lon":175.9161607
|
||||
}
|
||||
]
|
||||
</pre>
|
||||
|
||||
## Comments and Feedback
|
||||
|
||||
Developed for my use in sailing, cycling and motorcycling. If you find this software useful or have feedback drop me a line mike[at]kereru.com. Enjoy!
|
||||
|
||||
( Many thanks to Gordon Williams. Awesome job. )
|
||||
## Thanks
|
||||
|
||||
Many thanks to Gordon Williams. Awesome job.
|
||||
|
||||
Special thanks also to @jeffmer, for the [GPS Navigation](https://banglejs.com/apps/#gps%20navigation) app and @hughbarney for the Low power GPS code development.
|
||||
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
require("heatshrink").decompress(atob("m02xH+AH4AJlgAMGWQ4lEw1Wq2BAAgHBG8QhFq+C1nXABGswQ4GGjhkBGJIAHOQI2ZDIcyGaQ3EmQ3WNAiaKABusNyoUDNCxuGGySdDNDBuGUoY0e2etAAWzGzoOCGheJxNlAA2J1o2LGprTNGRAAFbZw0LqwZI1pkGAAgJDUxdWGxTULFAmJFJGzURjaET6Q0DGZKYIrqjRT5Q0EGZwpEUZZqPaYaRMGg6LINhBJKNK40JAAI1Iq6fJGjDrIUQoVCwRqJDhA0OXYQRGwRsEAgWsNTCeIDYTwG1g1GqygJNROsq0ymVWq7TI2ZRJUQg1JUARkMAAg0FDhY1GDAxOKQwgAEKI6IKKAQ1KeAQ1IJ4VXAog1gC4Q1ImQVBAwYFBmQ1K1o1fMoQ1ORIQ1Ua5ahD1uzrqnEULo1L1gVBAAusGrDxHC4NlEY4aDAAZQGDhiHCGpZOJNodWmUyqxpIRBY1GQw7wCURAAPKIWtXhI1EwSFJNhIAMNQSgHwQ1EGwVXKBJsWDJSgENgjyKGyg0CNQ/XNQo1DwIRGbIS+HABYWLwI1GGwVWKhZtQChigGNhg2TCRhqIGwcy1g2YCBmsmQ0INgajIYgY1PdRKfCGpCjMG4ShNBxSfKGwyjIADOsGho1DbRI0YagQ1MG0Y0RGwjbLACLTDGh42FqxuY1lWGig2FmRuWwKdDGiZuHG6WBNC42JHAWCVBWswQyEGjQ3IHAJyBAAgHBCAwzbG5QAMGb44SGUgAkA"))
|
||||
require("heatshrink").decompress(atob("mEwxH+AH4A/AE+sFtoABF12swItsF9QuFR4IwmFwwvnFw4vCGEYuIF4JgjFxIvkFxQvCGBfOAAQvqFwYwRFxYvDGBIvUFxgv/F6IuNF4n+0nB4TvXFxwvF4XBAALlPF7ZfBGC4uPF4rABGAYAGTQwvad4YwKFzYvIGBQvfFwgAE3Qvt4IvEFzgvCLxO7Lx7vULzIzTFwIvgGZheFRAiNRGSQvpGYouesYAGmQAKq3CE4PIC4wviq2eFwPCroveCRSGEC6Qv0DAwRLcoouWC4VdVYQXkr1eAgVdAoIABroNEB4gHHC5QvHwQSDAAOCA74vH1uICQIABxGtA74vIAEwv/F/4vXAH4A/AHY"))
|
||||
|
|
|
@ -1,110 +1,100 @@
|
|||
/*
|
||||
Speed and Altitude [speedalt]
|
||||
Ver : 0.07
|
||||
Mike Bennett mike[at]kereru.com
|
||||
1.16 : Use new GPS settings module
|
||||
*/
|
||||
|
||||
const dbg = 0;
|
||||
|
||||
var v = '1.20';
|
||||
var buf = Graphics.createArrayBuffer(240,160,2,{msb:true});
|
||||
|
||||
// Load fonts
|
||||
require("Font7x11Numeric7Seg").add(Graphics);
|
||||
|
||||
/*
|
||||
var mainmenu = {
|
||||
"" : { "title" : "-- Units --" },
|
||||
"default" : function() { setUnits(0,''); },
|
||||
"Kph (spd)" : function() { setUnits(1,'kph'); },
|
||||
"Knots (spd)" : function() { setUnits(1.852,'knots'); },
|
||||
"Mph (spd)" : function() { setUnits(1.60934,'mph'); },
|
||||
"m/s (spd)" : function() { setUnits(3.6,'m/s'); },
|
||||
"Meters (alt)" : function() { setUnitsAlt(1,'m'); },
|
||||
"Feet (alt)" : function() { setUnitsAlt(0.3048,'feet'); },
|
||||
"Exit" : function() { exitMenu(); }, // remove the menu and restore
|
||||
};
|
||||
*/
|
||||
|
||||
var lastFix = {fix:0,satellites:0};
|
||||
var showSpeed = 1; // 1 = Speed in primary display. 0 = alt in primary
|
||||
var lf = {fix:0,satellites:0};
|
||||
var showMax = 0; // 1 = display the max values. 0 = display the cur fix
|
||||
var maxPress = 0; // Time max button pressed. Used to calculate short or long press.
|
||||
var pwrSav = 1; // 1 = default power saving with watch screen off and GPS to PMOO mode. 0 = screen kept on.
|
||||
var canDraw = 1;
|
||||
var lastBuzz = 0; // What sort of buzz was last performed. 0 = no fix, 1 = fix.
|
||||
var timerBuzz2 = 0; // ID of timer for fix second buzz
|
||||
var time = ''; // Last time string displayed. Re displayed in background colour to remove before drawing new time.
|
||||
var tmrLP; // Timer for delay in switching to low power after screen turns off
|
||||
|
||||
var max = {};
|
||||
max.spd = 0;
|
||||
max.alt = 0;
|
||||
|
||||
var emulator = 0;
|
||||
if (process.env.BOARD=="EMSCRIPTEN") emulator = 1; // 1 = running in emulator. Supplies test values;
|
||||
var emulator = (process.env.BOARD=="EMSCRIPTEN")?1:0; // 1 = running in emulator. Supplies test values;
|
||||
|
||||
var wp = {}; // Waypoint to use for distance from cur position.
|
||||
|
||||
function nxtWp(inc){
|
||||
if (cfg.modeA) return;
|
||||
cfg.wp+=inc;
|
||||
loadWp();
|
||||
}
|
||||
|
||||
function loadWp() {
|
||||
var w = require("Storage").readJSON('waypoints.json')||[{name:"NONE"}];
|
||||
if (cfg.wp>=w.length) cfg.wp=0;
|
||||
if (cfg.wp<0) cfg.wp = w.length-1;
|
||||
savSettings();
|
||||
wp = w[cfg.wp];
|
||||
}
|
||||
|
||||
function radians(a) {
|
||||
return a*Math.PI/180;
|
||||
}
|
||||
|
||||
function distance(a,b){
|
||||
var x = radians(a.lon-b.lon) * Math.cos(radians((a.lat+b.lat)/2));
|
||||
var y = radians(b.lat-a.lat);
|
||||
|
||||
// Distance in selected units
|
||||
var d = Math.sqrt(x*x + y*y) * 6371000;
|
||||
d = (d/parseFloat(cfg.dist)).toFixed(2);
|
||||
if ( d >= 100 ) d = parseFloat(d).toFixed(1);
|
||||
if ( d >= 1000 ) d = parseFloat(d).toFixed(0);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
function drawFix(dat) {
|
||||
|
||||
function drawFix(speed,units,sats,alt,alt_units) {
|
||||
if (!canDraw) return;
|
||||
|
||||
buf.clear();
|
||||
|
||||
var val = '';
|
||||
|
||||
var v = '';
|
||||
var u='';
|
||||
|
||||
// Primary Display
|
||||
val = speed.toString();
|
||||
if ( !showSpeed ) val = alt.toString();
|
||||
v = (cfg.primSpd)?dat.speed.toString():dat.alt.toString();
|
||||
|
||||
// Primary Units
|
||||
u = settings.spd_unit;
|
||||
if ( !showSpeed ) u = alt_units;
|
||||
u = (cfg.primSpd)?cfg.spd_unit:dat.alt_units;
|
||||
|
||||
drawPrimary(val,u);
|
||||
drawPrimary(v,u);
|
||||
|
||||
// Secondary Display
|
||||
val = alt.toString();
|
||||
if ( !showSpeed ) val = speed.toString();
|
||||
v = (cfg.primSpd)?dat.alt.toString():dat.speed.toString();
|
||||
|
||||
// Secondary Units
|
||||
u = alt_units;
|
||||
if ( !showSpeed ) u = settings.spd_unit;
|
||||
u = (cfg.primSpd)?dat.alt_units:cfg.spd_unit;
|
||||
|
||||
drawSecondary(val,u);
|
||||
drawSecondary(v,u);
|
||||
|
||||
// Time
|
||||
drawTime();
|
||||
|
||||
// Waypoint name
|
||||
drawWP();
|
||||
|
||||
//Sats
|
||||
drawSats(sats);
|
||||
|
||||
if ( dat.age > 10 ) {
|
||||
if ( dat.age > 90 ) dat.age = '>90';
|
||||
drawSats('Age:'+dat.age);
|
||||
}
|
||||
else drawSats('Sats:'+dat.sats);
|
||||
|
||||
g.reset();
|
||||
g.drawImage(img,0,40);
|
||||
// g.flip();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function drawNoFix(sats) {
|
||||
if (!canDraw) return;
|
||||
var u;
|
||||
|
||||
buf.clear();
|
||||
|
||||
buf.setFontAlign(0,0);
|
||||
buf.setColor(3);
|
||||
|
||||
buf.setFontVector(25);
|
||||
buf.drawString("Waiting for GPS",120,56);
|
||||
|
||||
// Time
|
||||
drawTime();
|
||||
|
||||
//Sats
|
||||
drawSats(sats);
|
||||
|
||||
g.reset();
|
||||
g.drawImage(img,0,40);
|
||||
// g.flip();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -113,15 +103,16 @@ function drawPrimary(n,u) {
|
|||
// Primary Display
|
||||
|
||||
var s=40; // Font size
|
||||
if ( n.length <= 7 ) s=48;
|
||||
if ( n.length <= 6 ) s=55;
|
||||
if ( n.length <= 5 ) s=68;
|
||||
if ( n.length <= 4 ) s=85;
|
||||
if ( n.length <= 3 ) s=110;
|
||||
var l=n.length;
|
||||
|
||||
if ( l <= 7 ) s=48;
|
||||
if ( l <= 6 ) s=55;
|
||||
if ( l <= 5 ) s=68;
|
||||
if ( l <= 4 ) s=85;
|
||||
if ( l <= 3 ) s=110;
|
||||
|
||||
buf.setFontAlign(0,-1); //Centre
|
||||
buf.setColor(1);
|
||||
|
||||
buf.setFontVector(s);
|
||||
buf.drawString(n,110,0);
|
||||
|
||||
|
@ -135,11 +126,12 @@ function drawPrimary(n,u) {
|
|||
function drawSecondary(n,u) {
|
||||
|
||||
var s=180; // units X position
|
||||
if ( n.length <= 5 ) s=155;
|
||||
if ( n.length <= 4 ) s=125;
|
||||
if ( n.length <= 3 ) s=100;
|
||||
if ( n.length <= 2 ) s=65;
|
||||
if ( n.length <= 1 ) s=35;
|
||||
var l=n.length;
|
||||
if ( l <= 5 ) s=155;
|
||||
if ( l <= 4 ) s=125;
|
||||
if ( l <= 3 ) s=100;
|
||||
if ( l <= 2 ) s=65;
|
||||
if ( l <= 1 ) s=35;
|
||||
|
||||
buf.setFontAlign(-1,1); //left, bottom
|
||||
buf.setColor(1);
|
||||
|
@ -153,7 +145,6 @@ function drawSecondary(n,u) {
|
|||
buf.drawString(u,s,135);
|
||||
}
|
||||
|
||||
|
||||
function drawTime() {
|
||||
var x = 0;
|
||||
var y = 160;
|
||||
|
@ -168,181 +159,225 @@ function drawTime() {
|
|||
buf.drawString(time,x,y);
|
||||
}
|
||||
|
||||
function drawWP() {
|
||||
var nm = wp.name;
|
||||
if ( nm == undefined || nm == 'NONE' || cfg.modeA ) nm = '';
|
||||
|
||||
buf.setFontAlign(-1,1); //left, bottom
|
||||
buf.setColor(2);
|
||||
buf.setFontVector(20);
|
||||
buf.drawString(nm.substring(0,6),77,160);
|
||||
|
||||
}
|
||||
|
||||
function drawSats(sats) {
|
||||
buf.setFontAlign(1,1); //right, bottom
|
||||
|
||||
buf.setColor(3);
|
||||
buf.setFont("6x8", 2);
|
||||
if ( showMax ) {
|
||||
buf.setColor(2);
|
||||
buf.drawString("MAX",240,160);
|
||||
buf.setFontAlign(1,1); //right, bottom
|
||||
buf.drawString(sats,240,160);
|
||||
|
||||
buf.setFontVector(20);
|
||||
buf.setColor(2);
|
||||
|
||||
if ( cfg.modeA ) buf.drawString("A",240,140);
|
||||
else buf.drawString("D",240,140);
|
||||
|
||||
if ( showMax && cfg.modeA ) {
|
||||
buf.setFontAlign(0,1); //centre, bottom
|
||||
buf.drawString("MAX",120,164);
|
||||
}
|
||||
else buf.drawString("Sats:"+sats,240,160);
|
||||
|
||||
|
||||
}
|
||||
|
||||
function onGPS(fix) {
|
||||
lastFix = fix;
|
||||
|
||||
if ( emulator ) {
|
||||
fix.fix = 1;
|
||||
fix.speed = 10;
|
||||
fix.alt = 354;
|
||||
fix.lat = -38.92;
|
||||
fix.lon = 175.7613350;
|
||||
fix.course = 245;
|
||||
fix.satellites = 12;
|
||||
fix.time = new Date();
|
||||
}
|
||||
|
||||
var m;
|
||||
|
||||
if (fix.fix || emulator) {
|
||||
doBuzz(1);
|
||||
var sp = '---';
|
||||
var al = '---';
|
||||
var di = '---';
|
||||
var age = '---';
|
||||
|
||||
//==== Speed ====
|
||||
if ( settings.spd == 0 ) {
|
||||
var strSpeed = require("locale").speed(fix.speed);
|
||||
m = strSpeed.match(/([0-9,\.]+)(.*)/); // regex splits numbers from units
|
||||
|
||||
if ( emulator ) {
|
||||
speed = '125'; //testing only
|
||||
settings.spd_unit = 'kph';
|
||||
}
|
||||
else {
|
||||
speed = m[1];
|
||||
settings.spd_unit = m[2];
|
||||
}
|
||||
}
|
||||
// Calculate for selected units
|
||||
else {
|
||||
speed = fix.speed;
|
||||
if ( emulator ) speed = '100';
|
||||
speed = Math.round(parseFloat(speed)/parseFloat(settings.spd),0);
|
||||
if (fix.fix) lf = fix;
|
||||
if (lf.fix) {
|
||||
|
||||
// Speed
|
||||
if ( cfg.spd == 0 ) {
|
||||
m = require("locale").speed(lf.speed).match(/([0-9,\.]+)(.*)/); // regex splits numbers from units
|
||||
sp = parseFloat(m[1]);
|
||||
cfg.spd_unit = m[2];
|
||||
}
|
||||
else sp = parseFloat(lf.speed)/parseFloat(cfg.spd); // Calculate for selected units
|
||||
|
||||
// ==== Altitude ====
|
||||
alt = fix.alt;
|
||||
if ( emulator ) alt = '360';
|
||||
alt = Math.round(parseFloat(alt)/parseFloat(settings.alt),0);
|
||||
|
||||
// Record max values
|
||||
if (parseFloat(speed) > parseFloat(max.spd) ) max.spd = parseFloat(speed);
|
||||
if (parseFloat(alt) > parseFloat(max.alt) ) max.alt = parseFloat(alt);
|
||||
|
||||
if ( showMax ) drawFix(max.spd,settings.spd_unit,fix.satellites,max.alt,settings.alt_unit);
|
||||
else drawFix(speed,settings.spd_unit,fix.satellites,alt,settings.alt_unit);
|
||||
if ( sp < 10 ) sp = sp.toFixed(1);
|
||||
else sp = Math.round(sp);
|
||||
if (parseFloat(sp) > parseFloat(max.spd) ) max.spd = parseFloat(sp);
|
||||
|
||||
} else {
|
||||
doBuzz(0);
|
||||
drawNoFix(fix.satellites);
|
||||
// Altitude
|
||||
al = lf.alt;
|
||||
al = Math.round(parseFloat(al)/parseFloat(cfg.alt));
|
||||
if (parseFloat(al) > parseFloat(max.alt) ) max.alt = parseFloat(al);
|
||||
|
||||
// Distance to waypoint
|
||||
di = distance(lf,wp);
|
||||
if (isNaN(di)) di = 0;
|
||||
|
||||
// Age of last fix (secs)
|
||||
age = Math.max(0,Math.round(getTime())-(lf.time.getTime()/1000));
|
||||
}
|
||||
|
||||
if ( cfg.modeA ) {
|
||||
if ( showMax )
|
||||
drawFix({
|
||||
speed:max.spd,
|
||||
sats:lf.satellites,
|
||||
alt:max.alt,
|
||||
alt_units:cfg.alt_unit,
|
||||
age:age,
|
||||
fix:lf.fix
|
||||
}); // Speed and alt maximums
|
||||
else
|
||||
drawFix({
|
||||
speed:sp,
|
||||
sats:lf.satellites,
|
||||
alt:al,
|
||||
alt_units:cfg.alt_unit,
|
||||
age:age,
|
||||
fix:lf.fix
|
||||
}); // Show speed/altitude
|
||||
}
|
||||
else {
|
||||
// Show speed/distance
|
||||
if ( di <= 0 )
|
||||
drawFix({
|
||||
speed:sp,
|
||||
sats:lf.satellites,
|
||||
alt:'',
|
||||
alt_units:'',
|
||||
age:age,
|
||||
fix:lf.fix
|
||||
}); // No WP selected
|
||||
else
|
||||
drawFix({
|
||||
speed:sp,
|
||||
sats:lf.satellites,
|
||||
alt:di,
|
||||
alt_units:cfg.dist_unit,
|
||||
age:age,
|
||||
fix:lf.fix
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Vibrate watch when fix lost or gained.
|
||||
function doBuzz(hasFix) {
|
||||
|
||||
// nothing to do
|
||||
if ( lastBuzz === hasFix || !settings.buzz ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// fix gained - double buzz
|
||||
if ( !lastBuzz && hasFix ) {
|
||||
if ( dbg ) print('Fix');
|
||||
lastBuzz = 1;
|
||||
Bangle.buzz();
|
||||
timerBuzz2 = setInterval(doBuzz2, 600); // Trigger a second buzz
|
||||
return;
|
||||
}
|
||||
|
||||
// fix lost - single buzz
|
||||
if ( lastBuzz && !hasFix ) {
|
||||
if ( dbg ) print('Fix lost');
|
||||
lastBuzz = 0;
|
||||
Bangle.buzz();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Second buzz
|
||||
function doBuzz2() {
|
||||
if ( dbg ) print('Buzz2');
|
||||
clearInterval(timerBuzz2);
|
||||
Bangle.buzz();
|
||||
}
|
||||
|
||||
function toggleDisplay() {
|
||||
showSpeed = !showSpeed;
|
||||
onGPS(lastFix); // Back to Speed display
|
||||
}
|
||||
|
||||
function toggleMax() {
|
||||
// if ( inMenu ) return;
|
||||
showMax = !showMax;
|
||||
onGPS(lastFix); // Back to Speed display
|
||||
}
|
||||
|
||||
function setButtons(){
|
||||
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
|
||||
// Switch between fix and max display on short press or reset max values on long press
|
||||
setWatch(maxPressed, BTN1,{repeat:true,edge:"rising"});
|
||||
setWatch(maxReleased, BTN1,{repeat:true,edge:"falling"});
|
||||
|
||||
// Touch screen to toggle display
|
||||
setWatch(toggleDisplay, BTN4, {repeat:true,edge:"falling"});
|
||||
setWatch(toggleDisplay, BTN5, {repeat:true,edge:"falling"});
|
||||
// Spd+Dist : Select next waypoint
|
||||
setWatch(function(e) {
|
||||
var dur = e.time - e.lastTime;
|
||||
if ( cfg.modeA ) {
|
||||
// Spd+Alt mode - Switch between fix and MAX
|
||||
if ( dur < 2 ) showMax = !showMax; // Short press toggle fix/max display
|
||||
else { max.spd = 0; max.alt = 0; } // Long press resets max values.
|
||||
}
|
||||
else nxtWp(1); // Spd+Dist mode - Select next waypoint
|
||||
onGPS(lf);
|
||||
}, BTN1, { edge:"falling",repeat:true});
|
||||
|
||||
// Power saving on/off
|
||||
setWatch(function(e){
|
||||
pwrSav=!pwrSav;
|
||||
if ( pwrSav ) {
|
||||
LED1.reset();
|
||||
var s = require('Storage').readJSON('setting.json',1)||{};
|
||||
var t = s.timeout||10;
|
||||
Bangle.setLCDTimeout(t);
|
||||
}
|
||||
else {
|
||||
Bangle.setLCDTimeout(0);
|
||||
Bangle.setLCDPower(1);
|
||||
LED1.set();
|
||||
}
|
||||
}, BTN2, {repeat:true,edge:"falling"});
|
||||
|
||||
}
|
||||
|
||||
function maxPressed() {
|
||||
maxPress = getTime();
|
||||
}
|
||||
|
||||
function maxReleased() {
|
||||
var dur = getTime()-maxPress;
|
||||
// Toggle between alt or dist
|
||||
setWatch(function(e){
|
||||
cfg.modeA = !cfg.modeA;
|
||||
savSettings();
|
||||
onGPS(lf);
|
||||
}, BTN3, {repeat:true,edge:"falling"});
|
||||
|
||||
if ( dur < 2 ) toggleMax(); // Short press toggle fix/max display
|
||||
else {
|
||||
max.spd = 0; // Long press resets max values.
|
||||
max.alt = 0;
|
||||
onGPS(lastFix); // redraw display
|
||||
}
|
||||
// Touch left screen to toggle display
|
||||
setWatch(function(e){
|
||||
cfg.primSpd = !cfg.primSpd;
|
||||
savSettings();
|
||||
onGPS(lf); // Update display
|
||||
}, BTN4, {repeat:true,edge:"falling"});
|
||||
|
||||
}
|
||||
|
||||
function updateClock() {
|
||||
if ( dbg ) print('Updating clock');
|
||||
if (!canDraw) return;
|
||||
|
||||
drawTime();
|
||||
g.reset();
|
||||
g.drawImage(img,0,40);
|
||||
// g.flip();
|
||||
|
||||
// Something different to display in the emulator
|
||||
if ( emulator ) {
|
||||
max.spd++;
|
||||
max.alt++;
|
||||
}
|
||||
|
||||
if ( emulator ) {max.spd++;max.alt++;}
|
||||
}
|
||||
|
||||
function startDraw(){
|
||||
canDraw=true;
|
||||
setLpMode('SuperE'); // off
|
||||
g.clear();
|
||||
Bangle.drawWidgets();
|
||||
onGPS(lastFix); // draw app screen
|
||||
onGPS(lf); // draw app screen
|
||||
}
|
||||
|
||||
function stopDraw() {
|
||||
canDraw=false;
|
||||
if (!tmrLP) tmrLP=setInterval(function () {if (lf.fix) setLpMode('PSMOO');}, 10000); //Drop to low power in 10 secs. Keep lp mode off until we have a first fix.
|
||||
}
|
||||
|
||||
// ===== Main Prog =====
|
||||
function savSettings() {
|
||||
require("Storage").write('speedalt.json',cfg);
|
||||
}
|
||||
|
||||
function setLpMode(m) {
|
||||
if (tmrLP) {clearInterval(tmrLP);tmrLP = false;} // Stop any scheduled drop to low power
|
||||
if ( !gpssetup ) return;
|
||||
gpssetup.setPowerMode({power_mode:m})
|
||||
}
|
||||
|
||||
// =Main Prog
|
||||
|
||||
// Read settings.
|
||||
let settings = require('Storage').readJSON('speedalt.json',1)||{};
|
||||
let cfg = require('Storage').readJSON('speedalt.json',1)||{};
|
||||
|
||||
settings.spd = settings.spd||0; // Multiplier for speed unit conversions. 0 = use the locale values for speed
|
||||
settings.spd_unit = settings.spd_unit||''; // Displayed speed unit
|
||||
settings.alt = settings.alt||0.3048;// Multiplier for altitude unit conversions.
|
||||
settings.alt_unit = settings.alt_unit||'feet'; // Displayed altitude units
|
||||
settings.colour = settings.colour||0; // Colour scheme.
|
||||
settings.buzz = settings.buzz||0; // Buzz when fix lost or gained.
|
||||
cfg.spd = cfg.spd||0; // Multiplier for speed unit conversions. 0 = use the locale values for speed
|
||||
cfg.spd_unit = cfg.spd_unit||''; // Displayed speed unit
|
||||
cfg.alt = cfg.alt||0.3048;// Multiplier for altitude unit conversions.
|
||||
cfg.alt_unit = cfg.alt_unit||'feet'; // Displayed altitude units
|
||||
cfg.dist = cfg.dist||1000;// Multiplier for distnce unit conversions.
|
||||
cfg.dist_unit = cfg.dist_unit||'km'; // Displayed altitude units
|
||||
cfg.colour = cfg.colour||0; // Colour scheme.
|
||||
cfg.wp = cfg.wp||0; // Last selected waypoint for dist
|
||||
cfg.modeA = cfg.modeA||0; // 0 = [D], 1 = [A]
|
||||
cfg.primSpd = cfg.primSpd||0; // 1 = Spd in primary, 0 = Spd in secondary
|
||||
|
||||
|
||||
loadWp();
|
||||
|
||||
/*
|
||||
Colour Pallet Idx
|
||||
|
@ -359,50 +394,43 @@ var img = {
|
|||
palette:new Uint16Array([0,0x4FE0,0xEFE0,0x07DB])
|
||||
};
|
||||
|
||||
if ( settings.colour == 1 ) img.palette = new Uint16Array([0,0xFFFF,0xFFFF,0xFFFF]);
|
||||
if ( settings.colour == 2 ) img.palette = new Uint16Array([0,0xFF800,0xF800,0xF800]);
|
||||
|
||||
|
||||
// Find speed unit if using locale speed
|
||||
if ( settings.spd == 0 ) {
|
||||
var strSpeed = require("locale").speed(1);
|
||||
m = strSpeed.match(/([0-9,\.]+)(.*)/); // regex splits numbers from units
|
||||
settings.spd_unit = m[2];
|
||||
}
|
||||
if ( cfg.colour == 1 ) img.palette = new Uint16Array([0,0xFFFF,0xFFF6,0xDFFF]);
|
||||
if ( cfg.colour == 2 ) img.palette = new Uint16Array([0,0xFF800,0xFAE0,0xF813]);
|
||||
|
||||
var SCREENACCESS = {
|
||||
withApp:true,
|
||||
request:function(){
|
||||
this.withApp=false;
|
||||
stopDraw();
|
||||
clearWatch();
|
||||
},
|
||||
release:function(){
|
||||
this.withApp=true;
|
||||
startDraw();
|
||||
setButtons();
|
||||
}
|
||||
request:function(){this.withApp=false;stopDraw();},
|
||||
release:function(){this.withApp=true;startDraw();}
|
||||
};
|
||||
|
||||
Bangle.on('lcdPower',function(on) {
|
||||
if (!SCREENACCESS.withApp) return;
|
||||
if (on) {
|
||||
startDraw();
|
||||
} else {
|
||||
stopDraw();
|
||||
}
|
||||
if (on) startDraw();
|
||||
else stopDraw();
|
||||
});
|
||||
|
||||
var gpssetup;
|
||||
try {
|
||||
gpssetup = require("gpssetup");
|
||||
} catch(e) {
|
||||
gpssetup = false;
|
||||
}
|
||||
|
||||
// All set up. Lets go.
|
||||
g.clear();
|
||||
Bangle.setLCDBrightness(1);
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
onGPS(lf);
|
||||
Bangle.setGPSPower(1);
|
||||
|
||||
onGPS(lastFix);
|
||||
if ( gpssetup ) {
|
||||
gpssetup.setPowerMode({power_mode:"SuperE"}).then(function() { Bangle.setGPSPower(1); });
|
||||
}
|
||||
else {
|
||||
Bangle.setGPSPower(1);
|
||||
}
|
||||
|
||||
Bangle.on('GPS', onGPS);
|
||||
|
||||
setButtons();
|
||||
setInterval(updateClock, 30000);
|
||||
|
||||
|
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 4.3 KiB |
|
@ -19,6 +19,12 @@
|
|||
writeSettings();
|
||||
}
|
||||
|
||||
function setUnitsDist(d,u) {
|
||||
settings.dist = d;
|
||||
settings.dist_unit = u;
|
||||
writeSettings();
|
||||
}
|
||||
|
||||
function setColour(c) {
|
||||
settings.colour = c;
|
||||
writeSettings();
|
||||
|
@ -27,13 +33,15 @@
|
|||
const appMenu = {
|
||||
'': {'title': 'GPS Speed Alt'},
|
||||
'< Back': back,
|
||||
'< Load GPS Adv Sport': ()=>{load('speedalt.app.js');},
|
||||
'Units' : function() { E.showMenu(unitsMenu); },
|
||||
'Colours' : function() { E.showMenu(colMenu); },
|
||||
'Colours' : function() { E.showMenu(colMenu); }/*,
|
||||
'Vibrate' : {
|
||||
value : settings.buzz,
|
||||
format : v => v?"On":"Off",
|
||||
onchange : () => { settings.buzz = !settings.buzz; writeSettings(); }
|
||||
}};
|
||||
}*/
|
||||
};
|
||||
|
||||
const unitsMenu = {
|
||||
'': {'title': 'Units'},
|
||||
|
@ -43,6 +51,9 @@
|
|||
'Knots (spd)' : function() { setUnits(1.852,'knots'); },
|
||||
'Mph (spd)' : function() { setUnits(1.60934,'mph'); },
|
||||
'm/s (spd)' : function() { setUnits(3.6,'m/s'); },
|
||||
'Km (dist)' : function() { setUnitsDist(1000,'km'); },
|
||||
'Miles (dist)' : function() { setUnitsDist(1609.344,'miles'); },
|
||||
'Nm (dist)' : function() { setUnitsDist(1852.001,'nm'); },
|
||||
'Meters (alt)' : function() { setUnitsAlt(1,'m'); },
|
||||
'Feet (alt)' : function() { setUnitsAlt(0.3048,'feet'); }
|
||||
};
|
||||
|
|