From 95a3598dc40389863f1f8cba8383dc24ce5beadd Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sat, 4 Jan 2025 23:47:29 +0100 Subject: [PATCH 01/27] spacer: Integrate with newer sky library --- apps/spacer/spacer.app.js | 152 ++++++++++++++++++++++++++++++-------- 1 file changed, 121 insertions(+), 31 deletions(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index 13812b2a5..0015c1c76 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -124,13 +124,14 @@ let ui = { let fix = {}; /* Global for sky library */ -/* sky library v0.1.0 */ +/* sky library v0.2.2 */ let sky = { sats: [], snum: 0, sats_used: 0, sky_start: -1, this_usable: 0, + debug: 0, drawGrid: function() { g.setColor(0,0,0); @@ -140,7 +141,8 @@ let sky = { ui.radCircle(1.0); }, - snrLim: 28, + /* 18.. don't get reliable fix in 40s */ + snrLim: 22, drawSat: function(s) { let a = s.azi / 360; let e = ((90 - s.ele) / 90); @@ -172,7 +174,7 @@ let sky = { if (fix && fix.fix && fix.lat) { g.setColor(0, 0, 0) - .setFontAlign(-1, 1); + .setFontAlign(-1, 1); g.drawString(fix.satellites + "/" + fix.hdop, 5, ui.y2); } this.decorate(); @@ -197,13 +199,11 @@ let sky = { msg: {}, tof: function(v) { let i = (1*v); return i.toFixed(0); }, fmtSys: function(sys) { - if (sys && sys.sent !== undefined && sys.d23 !== undefined) - return sys.sent + "." + sys.d23 + "D "+ this.tof(sys.pdop) + " " + this.tof(sys.vdop) + "\n"; - else - return "(no data)\n"; + return sys.sent + "." + sys.d23 + "D "+ this.tof(sys.pdop) + " " + this.tof(sys.vdop) + "\n"; }, display: function() { - if (ui.display != 1) + /* unused on skyspy */ + if (ui.display == 1) return; let m = this.old_msg; let msg = "" + this.tof(m.time) + "\n" + @@ -218,37 +218,122 @@ let sky = { .setFontAlign(-1, -1) .drawString(msg, 0, 0); }, + snrSort: function() { + return this.sats.slice(0, this.snum).sort((a, b) => b.snr - a.snr); + }, + getSatSNR: function(n) { /* Get n-th strongest sat */ + if (n <= 0 || n > this.sats.length) + return -1; + + // Sort the satellites by snr in descending order + let sortedSats = this.snrSort(); + + // Return the SNR of the n-th strongest satellite + return sortedSats[n - 1].snr; + }, + qualest: function() { + // Sort the satellites by snr in descending order + let sortedSats = this.snrSort(); + if (sortedSats[4] && sortedSats[4].snr) { + return "" + sortedSats[4].snr + "dB"; + } + for (i=4; i>=0; i--) { + if (sortedSats[i] && sortedSats[i].snr) + return "S" + (i+1); + } + return "nil"; + }, + satVisibility: [], + trackSatelliteVisibility: function() { + const threshold = this.snrLim; // SNR threshold + const now = getTime(); + let newVisibility = []; + //this.satVisibility = []; + for (let i = 0; i < this.snum; i++) { + let sat = this.sats[i]; + let existingSat = this.satVisibility[sat.id]; + if (sat.snr >= threshold) { + if (!existingSat) { + // New satellite starts visibility + newVisibility[sat.id] = { start: now, visible: true }; + } else + newVisibility[sat.id] = this.satVisibility[sat.id]; + } + } + this.satVisibility = newVisibility; + }, + getnthLowestStartTimeSat: function(n) { + // Collect all satellites from visibility + let satellites = Object.values(this.satVisibility); + + // Ensure we have at least 5 satellites + if (satellites.length < n) + return -1; + + // Sort satellites by start time in ascending order + satellites.sort((a, b) => a.start - b.start); + + // Return the satellite with the 5th lowest start time + return satellites[n-1]; // 0-based index, so 5th is index 4 + }, + goodest: function () { + let s = this.getnthLowestStartTimeSat(5); + if (s==-1) + return "none"; + let t = getTime() - s.start; + return "" + t; + }, + onMessageEnd: function() { /* quality.updateGps(); /* FIXME -- for skyspy */}, + messageEnd: function() { + this.old_msg = this.msg; + this.msg = {}; + this.msg.gp = {}; + this.msg.bd = {}; + this.msg.gl = {}; + this.drawSats(this.sats); + let r = this.qualest(); + let r1 = this.goodest(); + print(r, r1, this.old_msg.hdop, this.old_msg.quality); + if (ui.display == 4) + ui.drawMsg(r + "\n" + r1 + "\n" + this.old_msg.hdop + "-" + this.old_msg.quality + "d\n" + (getTime() - this.sky_start)); + this.trackSatelliteVisibility(); + //print(this.sats); + if (this.sats_used < 5) + this.sky_start = getTime(); + this.snum = 0; + this.sats = []; + this.sats_used = 0; + this.onMessageEnd(); + }, parseRaw: function(msg, lost) { if (lost) print("## data lost"); let s = msg.split(","); + // print(getTime(), s[0]); + //return; let cmd = s[0].slice(3); //print("cmd", cmd); + if (cmd === "TXT") { + this.messageEnd(); + return; + } if (cmd === "GGA") { - this.old_msg = this.msg; - this.msg = {}; this.msg.time = s[1]; this.msg.quality = s[6]; this.msg.in_view = s[7]; this.msg.hdop = s[8]; - this.msg.gp = {}; - this.msg.bd = {}; - this.msg.gl = {}; - print("-----------------------------------------------"); - print("GGA Time", s[1], "fix quality", s[4], "sats in view ", s[5]); - this.drawSats(this.sats); - if (this.sats_used < 5) - this.sky_start = getTime(); - this.snum = 0; - this.sats = []; - this.sats_used = 0; + + if (this.debug > 0) { + print("-----------------------------------------------"); + print("GGA Time", s[1], "fix quality", s[4], "sats in view ", s[5]); + } return; } if (cmd === "GLL") return; /* Position lat/lon */ if (cmd === "GSA") { /* - $GNGSA,A,1,,,,,,,,,,,,,25.5,25.5,25.5,4*04 + $GNGSA,A,1,,,,,,,,,,,,,25.5,25.5,25.5,4*04 0 1 2 15 16 17 18 - */ + */ /* Satelites used, fix type! INTERESTING */ let sys = s[18]; let add = {}; @@ -256,29 +341,34 @@ let sky = { add.pdop = s[15]; add.hdop = s[16]; add.vdop = s[17]; + sys = sys[0]; /* FIXME -- should really add to the sentence */ if (sys == 1) { this.msg.gp = add; } else if (sys == 2) { this.msg.gl = add; } else if (sys == 4) { this.msg.bd = add; } - else print("GSA Unknown system\n"); - - print(msg); + else { + print("GSA Unknown system -- ", sys, "\n"); + print(msg); + } return; } if (s[0] === "$GPGSV") { - print("Have gps sentences", s[1], "/", s[2]); + if (this.debug > 0) + print("Have gps sentences", s[1], "/", s[2]); this.parseSats(s); this.msg.gp.sent = ""+s[2]; return; } if (s[0] === "$BDGSV") { - print("Have baidu sentences", s[1], "/", s[2]); + if (this.debug > 0) + print("Have baidu sentences", s[1], "/", s[2]); this.parseSats(s); this.msg.bd.sent = ""+s[2]; return; } if (s[0] === "$GLGSV") { - print("Have glonass sentences", s[1], "/", s[2]); + if (this.debug > 0) + print("Have glonass sentences", s[1], "/", s[2]); this.parseSats(s); this.msg.gl.sent = ""+s[2]; return; @@ -304,7 +394,7 @@ let sky = { this.sys += 1; if (this.sys == 4) this.sys = 0; - let val = 7; + val = 7; if (this.sys) val = 1 << (this.sys - 1); this.casic_cmd("$PCAS04,"+val); @@ -323,7 +413,7 @@ function start() { // CASIC_CMD("$PCAS06,0"); /* Query product information */ setTimeout(() => sky.casic_cmd("$PCAS04,7"), 1000); /* Enable gps + beidou + glonass */ -setTimeout(() => sky.casic_cmd("$PCAS03,1,1,1,1,1,1,1,1"), 1000); /* Enable gps + beidou + glonass */ +setTimeout(() => sky.casic_cmd("$PCAS03,1,1,1,1,1,1,1,1"), 1500); /* Enable all messages */ //setTimeout(() => sky.casic_cmd("$PCAS10,2"), 1200); /* 2: cold start, 1 warm start, 0: hot start */ From f693bbf80ca4df207323bcc29daf90184ec85d78 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sun, 5 Jan 2025 18:48:51 +0100 Subject: [PATCH 02/27] spacer: Make it easier to split modules, got it back to working order. --- apps/spacer/spacer.app.js | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index 0015c1c76..817b61ffc 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -162,8 +162,6 @@ let sky = { // https://in-the-sky.org//satmap_radar.php?year=2023&month=10&day=24&skin=1 decorate: function() {}, drawSats: function(sats) { - if (ui.display != 0) - return; g.reset() .setColor(1, 1, 1) .fillRect(0, ui.wi, ui.w, ui.y2) @@ -201,10 +199,7 @@ let sky = { fmtSys: function(sys) { return sys.sent + "." + sys.d23 + "D "+ this.tof(sys.pdop) + " " + this.tof(sys.vdop) + "\n"; }, - display: function() { - /* unused on skyspy */ - if (ui.display == 1) - return; + drawRace: function() { let m = this.old_msg; let msg = "" + this.tof(m.time) + "\n" + "q" + m.quality + " " + m.in_view + " " + m.hdop + "\n" + @@ -283,19 +278,31 @@ let sky = { let t = getTime() - s.start; return "" + t; }, - onMessageEnd: function() { /* quality.updateGps(); /* FIXME -- for skyspy */}, + drawEstimates: function() { + let r = this.qualest(); + let r1 = this.goodest(); + print(r, r1, this.old_msg.hdop, this.old_msg.quality); + /* FIXME: -- for skyspy + if (ui.display == 4) + ui.drawMsg(r + "\n" + r1 + "\n" + this.old_msg.hdop + "-" + this.old_msg.quality + "d\n" + (getTime() - this.sky_start)); + */ + }, + onMessageEnd: function() { + /* quality.updateGps(); /* FIXME -- for skyspy */ + if (ui.display == 0) + this.drawSats(this.sats); + if (ui.display == 1) + this.drawRace(); + if (ui.display == 4) + this.drawEstimates(); + }, messageEnd: function() { this.old_msg = this.msg; this.msg = {}; this.msg.gp = {}; this.msg.bd = {}; this.msg.gl = {}; - this.drawSats(this.sats); - let r = this.qualest(); - let r1 = this.goodest(); - print(r, r1, this.old_msg.hdop, this.old_msg.quality); - if (ui.display == 4) - ui.drawMsg(r + "\n" + r1 + "\n" + this.old_msg.hdop + "-" + this.old_msg.quality + "d\n" + (getTime() - this.sky_start)); + this.onMessageEnd(); this.trackSatelliteVisibility(); //print(this.sats); if (this.sats_used < 5) @@ -303,7 +310,6 @@ let sky = { this.snum = 0; this.sats = []; this.sats_used = 0; - this.onMessageEnd(); }, parseRaw: function(msg, lost) { if (lost) print("## data lost"); @@ -312,7 +318,7 @@ let sky = { //return; let cmd = s[0].slice(3); //print("cmd", cmd); - if (cmd === "TXT") { + if (cmd === "TXT") { // FIXME: we want to end on some more common message */ this.messageEnd(); return; } @@ -408,7 +414,6 @@ function start() { setTimeout(function() { Bangle.removeAllListeners('GPS-raw'); }, 1000000); - setInterval(function() { sky.display(); }, 1000); } // CASIC_CMD("$PCAS06,0"); /* Query product information */ From 35a02cd44322c34b74c704324a873c43cbe2b35a Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sun, 5 Jan 2025 18:52:30 +0100 Subject: [PATCH 03/27] spacer: Cleanups. --- apps/spacer/spacer.app.js | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index 817b61ffc..acfd06a87 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -1,20 +1,6 @@ /* Space race */ /* - -Performance Assessment of GNSS Signals in -terms of Time to First Fix for -Cold, Warm and Hot Start -Matteo Paonni, Marco Anghileri, Stefan Wallner, José-Ángel Ávila-Rodríguez, Bernd Eissfeller -Institute of Geodesy and Navigation, University FAF Munich, Germany - -=> 22 to 26 dB -- long time / no fix / ... -=> 26db + -- basically strength no longer matters - -apps/assistedgps/custom.html - -https://github.com/espruino/EspruinoDocs/blob/master/info/Bangle.js2%20Technical.md#gps - gsa mi rika 2d/3d fix, a taky pdop/vdop/hdop CFG-NAVX z CASIC_en -- umoznuje nastavit chodec / auto / letadlo @@ -279,13 +265,19 @@ let sky = { return "" + t; }, drawEstimates: function() { + /* + Performance Assessment of GNSS Signals in terms of Time to + First Fix for Cold, Warm and Hot Start Matteo Paonni, Marco Anghileri, + Stefan Wallner, José-Ángel Ávila-Rodríguez, Bernd Eissfeller Institute + of Geodesy and Navigation, University FAF Munich, Germany + + => 22 to 26 dB -- long time / no fix / ... + => 26db + -- basically strength no longer matters + */ let r = this.qualest(); let r1 = this.goodest(); print(r, r1, this.old_msg.hdop, this.old_msg.quality); - /* FIXME: -- for skyspy - if (ui.display == 4) - ui.drawMsg(r + "\n" + r1 + "\n" + this.old_msg.hdop + "-" + this.old_msg.quality + "d\n" + (getTime() - this.sky_start)); - */ + ui.drawMsg(r + "\n" + r1 + "\n" + this.old_msg.hdop + "-" + this.old_msg.quality + "d\n" + (getTime() - this.sky_start)); }, onMessageEnd: function() { /* quality.updateGps(); /* FIXME -- for skyspy */ From 80065fac88e8f2e8a4fa9076054ed4cf7674aa22 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sun, 5 Jan 2025 18:53:17 +0100 Subject: [PATCH 04/27] spacer: Fix whitespace. --- apps/spacer/spacer.app.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index acfd06a87..449a3ca7f 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -1,6 +1,6 @@ /* Space race */ -/* +/* gsa mi rika 2d/3d fix, a taky pdop/vdop/hdop CFG-NAVX z CASIC_en -- umoznuje nastavit chodec / auto / letadlo @@ -54,12 +54,12 @@ let ui = { touchHandler: function(d) { let x = Math.floor(d.x); let y = Math.floor(d.y); - + if (d.b != 1 || this.last_b != 0) { this.last_b = d.b; return; } - + print("touch", x, y, this.h, this.w); if ((x this.sats.length) return -1; - + // Sort the satellites by snr in descending order let sortedSats = this.snrSort(); @@ -237,7 +237,7 @@ let sky = { if (!existingSat) { // New satellite starts visibility newVisibility[sat.id] = { start: now, visible: true }; - } else + } else newVisibility[sat.id] = this.satVisibility[sat.id]; } } @@ -265,7 +265,7 @@ let sky = { return "" + t; }, drawEstimates: function() { - /* + /* Performance Assessment of GNSS Signals in terms of Time to First Fix for Cold, Warm and Hot Start Matteo Paonni, Marco Anghileri, Stefan Wallner, José-Ángel Ávila-Rodríguez, Bernd Eissfeller Institute @@ -330,7 +330,7 @@ let sky = { if (cmd === "GSA") { /* $GNGSA,A,1,,,,,,,,,,,,,25.5,25.5,25.5,4*04 - 0 1 2 15 16 17 18 + 0 1 2 15 16 17 18 */ /* Satelites used, fix type! INTERESTING */ let sys = s[18]; @@ -376,7 +376,7 @@ let sky = { if (cmd === "ZDA") return; /* Time + timezone */ if (cmd === "TXT") { this.msg.finished = 1; - return; /* Misc text? antena open */ + return; /* Misc text? antena open */ } print(msg); From 6b42dbe1a6cc472ce8b41410b416e21ea38998b9 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sun, 5 Jan 2025 18:57:05 +0100 Subject: [PATCH 05/27] spacer: More cleanups. --- apps/spacer/spacer.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index 449a3ca7f..60e11d26a 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -402,7 +402,7 @@ let sky = { function start() { Bangle.setGPSPower(1); - Bangle.on('GPS-raw', function(a, b) { sky.parseRaw(a, b); }); + Bangle.on('GPS-raw', (a, b) => sky.parseRaw(a, b)); setTimeout(function() { Bangle.removeAllListeners('GPS-raw'); }, 1000000); From 6965a2acfa3fca8da4a01673b3038f9bfc27ecc7 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sun, 5 Jan 2025 19:01:17 +0100 Subject: [PATCH 06/27] spacer: better split into modules --- apps/spacer/spacer.app.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index 60e11d26a..631eb25db 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -279,15 +279,7 @@ let sky = { print(r, r1, this.old_msg.hdop, this.old_msg.quality); ui.drawMsg(r + "\n" + r1 + "\n" + this.old_msg.hdop + "-" + this.old_msg.quality + "d\n" + (getTime() - this.sky_start)); }, - onMessageEnd: function() { - /* quality.updateGps(); /* FIXME -- for skyspy */ - if (ui.display == 0) - this.drawSats(this.sats); - if (ui.display == 1) - this.drawRace(); - if (ui.display == 4) - this.drawEstimates(); - }, + onMessageEnd: function() {}, messageEnd: function() { this.old_msg = this.msg; this.msg = {}; @@ -408,6 +400,17 @@ function start() { }, 1000000); } +function onMessage() { + /* quality.updateGps(); /* FIXME -- for skyspy + if (ui.display == 4) + sky.drawEstimates(); + */ + if (ui.display == 0) + sky.drawSats(sky.sats); + if (ui.display == 1) + sky.drawRace(); +} + // CASIC_CMD("$PCAS06,0"); /* Query product information */ setTimeout(() => sky.casic_cmd("$PCAS04,7"), 1000); /* Enable gps + beidou + glonass */ setTimeout(() => sky.casic_cmd("$PCAS03,1,1,1,1,1,1,1,1"), 1500); /* Enable all messages */ @@ -417,4 +420,5 @@ setTimeout(() => sky.casic_cmd("$PCAS03,1,1,1,1,1,1,1,1"), 1500); /* Enable all ui.init(); ui.topLeft = () => sky.selectSpace(); Bangle.on("drag", (b) => ui.touchHandler(b)); +sky.onMessageEnd = onMessage; start(); From 64c11e13099123c6121c3c8a12ebe9b93a8267fe Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sun, 5 Jan 2025 20:09:06 +0100 Subject: [PATCH 07/27] spacer: Move satelite set related functions to separate struct. --- apps/spacer/spacer.app.js | 183 ++++++++++++++++++++------------------ 1 file changed, 94 insertions(+), 89 deletions(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index 631eb25db..9210eeea4 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -108,62 +108,16 @@ let ui = { }, }; +/* sky library v0.2.3 + needs ui */ + let fix = {}; /* Global for sky library */ -/* sky library v0.2.2 */ -let sky = { +let skys = { sats: [], snum: 0, sats_used: 0, - sky_start: -1, - this_usable: 0, - debug: 0, - - drawGrid: function() { - g.setColor(0,0,0); - ui.radLine(0, 1, 0.5, 1); - ui.radLine(0.25, 1, 0.75, 1); - ui.radCircle(0.5); - ui.radCircle(1.0); - }, - - /* 18.. don't get reliable fix in 40s */ - snrLim: 22, - drawSat: function(s) { - let a = s.azi / 360; - let e = ((90 - s.ele) / 90); - let x = ui.radX(a, e); - let y = ui.radY(a, e); - - if (s.snr == 0) - g.setColor(1, 0.25, 0.25); - else if (s.snr < this.snrLim) - g.setColor(0.25, 0.5, 0.25); - else - g.setColor(0, 0, 0); - g.drawString(s.id, x, y); - }, - - // Should correspond to view from below. - // https://in-the-sky.org//satmap_radar.php?year=2023&month=10&day=24&skin=1 - decorate: function() {}, - drawSats: function(sats) { - g.reset() - .setColor(1, 1, 1) - .fillRect(0, ui.wi, ui.w, ui.y2) - .setFont("Vector", 20) - .setFontAlign(0, 0); - this.drawGrid(); - sats.forEach(s => this.drawSat(s)); - - if (fix && fix.fix && fix.lat) { - g.setColor(0, 0, 0) - .setFontAlign(-1, 1); - g.drawString(fix.satellites + "/" + fix.hdop, 5, ui.y2); - } - this.decorate(); - }, - + parseSats: function(s) { let view = 1 * s[3]; let k = Math.min(4, view - this.snum); @@ -179,26 +133,6 @@ let sky = { } }, - old_msg: {}, - msg: {}, - tof: function(v) { let i = (1*v); return i.toFixed(0); }, - fmtSys: function(sys) { - return sys.sent + "." + sys.d23 + "D "+ this.tof(sys.pdop) + " " + this.tof(sys.vdop) + "\n"; - }, - drawRace: function() { - let m = this.old_msg; - let msg = "" + this.tof(m.time) + "\n" + - "q" + m.quality + " " + m.in_view + " " + m.hdop + "\n" + - "gp"+ this.fmtSys(m.gp) + - "bd" + this.fmtSys(m.bd) + - "gl" + this.fmtSys(m.gl); - if (this.msg.finished != 1) - msg += "!"; - g.reset().clear().setFont("Vector", 30) - .setColor(0, 0, 0) - .setFontAlign(-1, -1) - .drawString(msg, 0, 0); - }, snrSort: function() { return this.sats.slice(0, this.snum).sort((a, b) => b.snr - a.snr); }, @@ -264,6 +198,79 @@ let sky = { let t = getTime() - s.start; return "" + t; }, +}; + +let sky = { + sky_start: -1, + this_usable: 0, + debug: 0, + all: skys, /* Sattelites from all systems */ + + drawGrid: function() { + g.setColor(0,0,0); + ui.radLine(0, 1, 0.5, 1); + ui.radLine(0.25, 1, 0.75, 1); + ui.radCircle(0.5); + ui.radCircle(1.0); + }, + + /* 18.. don't get reliable fix in 40s */ + snrLim: 22, + drawSat: function(s) { + let a = s.azi / 360; + let e = ((90 - s.ele) / 90); + let x = ui.radX(a, e); + let y = ui.radY(a, e); + + if (s.snr == 0) + g.setColor(1, 0.25, 0.25); + else if (s.snr < this.snrLim) + g.setColor(0.25, 0.5, 0.25); + else + g.setColor(0, 0, 0); + g.drawString(s.id, x, y); + }, + + // Should correspond to view from below. + // https://in-the-sky.org//satmap_radar.php?year=2023&month=10&day=24&skin=1 + decorate: function() {}, + drawSats: function(sats) { + g.reset() + .setColor(1, 1, 1) + .fillRect(0, ui.wi, ui.w, ui.y2) + .setFont("Vector", 20) + .setFontAlign(0, 0); + this.drawGrid(); + sats.forEach(s => this.drawSat(s)); + + if (fix && fix.fix && fix.lat) { + g.setColor(0, 0, 0) + .setFontAlign(-1, 1); + g.drawString(fix.satellites + "/" + fix.hdop, 5, ui.y2); + } + this.decorate(); + }, + + old_msg: {}, + msg: {}, + tof: function(v) { let i = (1*v); return i.toFixed(0); }, + fmtSys: function(sys) { + return sys.sent + "." + sys.d23 + "D "+ this.tof(sys.pdop) + " " + this.tof(sys.vdop) + "\n"; + }, + drawRace: function() { + let m = this.old_msg; + let msg = "gmt " + this.tof(m.time) + "\n" + + "q" + m.quality + " S" + m.in_view + " h" + (1*m.hdop).toFixed(1) + "m\n" + + "gp"+ this.fmtSys(m.gp) + + "bd" + this.fmtSys(m.bd) + + "gl" + this.fmtSys(m.gl); + if (this.msg.finished != 1) + msg += "!"; + g.reset().clear().setFont("Vector", 30) + .setColor(0, 0, 0) + .setFontAlign(-1, -1) + .drawString(msg, 0, 0); + }, drawEstimates: function() { /* Performance Assessment of GNSS Signals in terms of Time to @@ -274,8 +281,8 @@ let sky = { => 22 to 26 dB -- long time / no fix / ... => 26db + -- basically strength no longer matters */ - let r = this.qualest(); - let r1 = this.goodest(); + let r = this.all.qualest(); + let r1 = this.all.goodest(); print(r, r1, this.old_msg.hdop, this.old_msg.quality); ui.drawMsg(r + "\n" + r1 + "\n" + this.old_msg.hdop + "-" + this.old_msg.quality + "d\n" + (getTime() - this.sky_start)); }, @@ -287,22 +294,24 @@ let sky = { this.msg.bd = {}; this.msg.gl = {}; this.onMessageEnd(); - this.trackSatelliteVisibility(); + this.all.trackSatelliteVisibility(); //print(this.sats); - if (this.sats_used < 5) + if (this.all.sats_used < 5) this.sky_start = getTime(); - this.snum = 0; - this.sats = []; - this.sats_used = 0; + this.all.snum = 0; + this.all.sats = []; + this.all.sats_used = 0; }, parseRaw: function(msg, lost) { + //print(msg); if (lost) print("## data lost"); let s = msg.split(","); // print(getTime(), s[0]); //return; let cmd = s[0].slice(3); //print("cmd", cmd); - if (cmd === "TXT") { // FIXME: we want to end on some more common message */ + if (cmd === "RMC") { + /* Repeat of position/speed/course */ this.messageEnd(); return; } @@ -345,32 +354,28 @@ let sky = { if (s[0] === "$GPGSV") { if (this.debug > 0) print("Have gps sentences", s[1], "/", s[2]); - this.parseSats(s); + this.all.parseSats(s); this.msg.gp.sent = ""+s[2]; return; } if (s[0] === "$BDGSV") { if (this.debug > 0) print("Have baidu sentences", s[1], "/", s[2]); - this.parseSats(s); + this.all.parseSats(s); this.msg.bd.sent = ""+s[2]; return; } if (s[0] === "$GLGSV") { if (this.debug > 0) print("Have glonass sentences", s[1], "/", s[2]); - this.parseSats(s); + this.all.parseSats(s); this.msg.gl.sent = ""+s[2]; return; } - if (cmd === "RMC") return; /* Repeat of position/speed/course */ + if (cmd === "VTG") return; /* Speeds in knots/kph */ if (cmd === "ZDA") return; /* Time + timezone */ - if (cmd === "TXT") { - this.msg.finished = 1; - return; /* Misc text? antena open */ - } - + if (cmd === "TXT") return; /* Misc text? antena open */ print(msg); }, casic_cmd: function (cmd) { @@ -406,7 +411,7 @@ function onMessage() { sky.drawEstimates(); */ if (ui.display == 0) - sky.drawSats(sky.sats); + sky.drawSats(sky.all.sats); if (ui.display == 1) sky.drawRace(); } From d9d6e23d93a47644a0a6865f95d52713090211f2 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sun, 5 Jan 2025 20:17:41 +0100 Subject: [PATCH 08/27] spacer: More refactoring. --- apps/spacer/spacer.app.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index 9210eeea4..cc9c019a8 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -117,7 +117,12 @@ let skys = { sats: [], snum: 0, sats_used: 0, - + + reset: function() { + this.snum = 0; + this.sats = []; + this.sats_used = 0; + }, parseSats: function(s) { let view = 1 * s[3]; let k = Math.min(4, view - this.snum); @@ -298,9 +303,7 @@ let sky = { //print(this.sats); if (this.all.sats_used < 5) this.sky_start = getTime(); - this.all.snum = 0; - this.all.sats = []; - this.all.sats_used = 0; + this.all.reset(); }, parseRaw: function(msg, lost) { //print(msg); From 641b43af60215766dc16dec53eb13f686e0dc8e8 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sun, 5 Jan 2025 20:26:58 +0100 Subject: [PATCH 09/27] spacer: prepare for printing vdop/pdop --- apps/spacer/spacer.app.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index cc9c019a8..43681264f 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -258,14 +258,17 @@ let sky = { old_msg: {}, msg: {}, - tof: function(v) { let i = (1*v); return i.toFixed(0); }, + tof: function(v, n) { let i = (1*v); return i.toFixed(n); }, + tof0: function(v) { return this.tof(v, 0); }, + tof1: function(v) { return this.tof(v, 1); }, fmtSys: function(sys) { - return sys.sent + "." + sys.d23 + "D "+ this.tof(sys.pdop) + " " + this.tof(sys.vdop) + "\n"; + return sys.sent + "." + sys.d23 + "D "+ this.tof(sys.pdop) + " " + this.tof0(sys.vdop) + "\n"; }, drawRace: function() { let m = this.old_msg; - let msg = "gmt " + this.tof(m.time) + "\n" + - "q" + m.quality + " S" + m.in_view + " h" + (1*m.hdop).toFixed(1) + "m\n" + + let msg = "gmt" + this.tof0(m.time) + "\n" + + "q" + m.quality + " S" + m.in_view + " h" + this.tof0(m.hdop) + "m\n" + +/* "v" + this.tof0(m.vdop) + "m " + "p" + this.tof0(m.pdop) + "m\n" + */ "gp"+ this.fmtSys(m.gp) + "bd" + this.fmtSys(m.bd) + "gl" + this.fmtSys(m.gl); From ebb4cd7c27853d27a00fdf913a349db1b5d27b61 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Mon, 6 Jan 2025 14:22:32 +0100 Subject: [PATCH 10/27] spacer: refactor --- apps/spacer/spacer.app.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index 43681264f..ede98eb6b 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -117,6 +117,7 @@ let skys = { sats: [], snum: 0, sats_used: 0, + sky_start: -1, reset: function() { this.snum = 0; @@ -203,10 +204,14 @@ let skys = { let t = getTime() - s.start; return "" + t; }, + onEnd: function () { + if (this.sats_used < 5) + this.sky_start = getTime(); + this.reset(); + }, }; let sky = { - sky_start: -1, this_usable: 0, debug: 0, all: skys, /* Sattelites from all systems */ @@ -292,7 +297,7 @@ let sky = { let r = this.all.qualest(); let r1 = this.all.goodest(); print(r, r1, this.old_msg.hdop, this.old_msg.quality); - ui.drawMsg(r + "\n" + r1 + "\n" + this.old_msg.hdop + "-" + this.old_msg.quality + "d\n" + (getTime() - this.sky_start)); + ui.drawMsg(r + "\n" + r1 + "\n" + this.old_msg.hdop + "-" + this.old_msg.quality + "d\n" + (getTime() - this.all.sky_start)); }, onMessageEnd: function() {}, messageEnd: function() { @@ -304,9 +309,7 @@ let sky = { this.onMessageEnd(); this.all.trackSatelliteVisibility(); //print(this.sats); - if (this.all.sats_used < 5) - this.sky_start = getTime(); - this.all.reset(); + this.all.onEnd(); }, parseRaw: function(msg, lost) { //print(msg); From ee90dcdfdb79399fad18a1e44a26c938f0629963 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Mon, 6 Jan 2025 14:28:04 +0100 Subject: [PATCH 11/27] spacer: display fix summary --- apps/spacer/spacer.app.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index ede98eb6b..1b31afb64 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -200,9 +200,15 @@ let skys = { goodest: function () { let s = this.getnthLowestStartTimeSat(5); if (s==-1) - return "none"; + return ""; let t = getTime() - s.start; - return "" + t; + return "" + t + "s"; + }, + summary: function () { + let s = this.goodest(); + if (s != "") + return s; + return this.qualest(); }, onEnd: function () { if (this.sats_used < 5) @@ -273,7 +279,8 @@ let sky = { let m = this.old_msg; let msg = "gmt" + this.tof0(m.time) + "\n" + "q" + m.quality + " S" + m.in_view + " h" + this.tof0(m.hdop) + "m\n" + -/* "v" + this.tof0(m.vdop) + "m " + "p" + this.tof0(m.pdop) + "m\n" + */ + /* "v" + this.tof0(m.vdop) + "m " + "p" + this.tof0(m.pdop) + "m\n" + */ + this.all.summary() + "\n" + "gp"+ this.fmtSys(m.gp) + "bd" + this.fmtSys(m.bd) + "gl" + this.fmtSys(m.gl); From 6db2d36193a30e6800596e2000969e194024bb3d Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Mon, 6 Jan 2025 17:43:46 +0100 Subject: [PATCH 12/27] spacer: update icon. --- apps/spacer/app-icon.js | 2 +- apps/spacer/app.png | Bin 14889 -> 1976 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/spacer/app-icon.js b/apps/spacer/app-icon.js index 903d14af5..53dbfa31e 100644 --- a/apps/spacer/app-icon.js +++ b/apps/spacer/app-icon.js @@ -1,2 +1,2 @@ -require("heatshrink").decompress(atob("mEwgIQNgQFEj/gAof+jgECgeAAIIFBgwCBuACBhgCEjAOEAoQ6CmAhCDwItDoEB4AFCsEBFgUEkEDG4XEJYcL8gFCgUP+gxCAoP8DIIFBhfsiEIAoMJAogCBAoYlBiBMBAoUwrA0B////ALECI0QAocgAolgApVADolAHYnAAomAAoqdBAoKVBMoRvCOIQDCRIIFBYwKVBAoKqC4AFBVQVggTRDn0CYgQcBN4LpDV4T7IAooAJA=")) +require("heatshrink").decompress(atob("mEwhHXAH4A/AH4A/AGMAF34v/F34EBAAIvrFwQxnEoIsFGEyNHF9ZgNGrheMF4guJHDAvLEhCdbLyLLdL5ImFfRo6SLpjGOCgw5TdZRhKHwhEPFxjOJCwwOGF6zOJBxpjFAB4TKR6aEJDpgwKd5rzUYBrkVMxwtVF7CYHeBxGRF5LwMR9YvdPiJfjBhYv/F/4v/F/4v/F/4v/F/4v/F/4vfAH4Ad")) diff --git a/apps/spacer/app.png b/apps/spacer/app.png index ce7ac239fd0f72f3a1ab88ccfa91bcd21846caf4..6743d6e59284b3867f46119a9400afa32cecdefa 100644 GIT binary patch literal 1976 zcmd5-c~q0v5>Gxq;bS$C9T9;%8g`J#RyJ8eAZ&u{Vu-RTU;|;5uzVH*NGw{R3I-H# z#ggz?s!$u^Qb9m^(5C@`5+7icB}R4(m45V{_s9F={oi}eotb-Q<~Mido;g!~D1f9S zuPu*4p_F{QJ%bV6y1gM8gmUjqQxJxx2b0`UoFSbL$N{9g`-DKqVnA_aD3t7RA5XWC z9Lhr7aM-xF;?B2QuC<2KD8iNfyteCOEe)$S>1&yH#?`+{T>8BFWl~|wjcNpkgSu}V zju&DMQav^OQ84LVr37N_Xp+;DykEuY!fDh4Xi#^;ziEt=13ra^K}=4D z6sqLgTh*d~%2WH^Vl`#GR1OM<7jRC%6h8@ooVxRiNmQM`0cb?hU!oTZd9}rpm1KjT2F$`xqdV*j&=m}5?-^;tHxOYALHY!lmHySWS4% z+WN8#jJ3Z#NST2cFL&{r<_&LskK9CjiW}2L+)`&k&irv2Cd58o=p?mn{H$`8DM-fH zf6~artas;xh8tJ`;aweZdqHLSAKBexyq38tS!4sT_@W9%iNxDI(L&gTeC7nXS4tL{`#oIcQI0pMDR9UTAqDB<8-XP(&k zw~nm-ZJ0W0`!)aNsZ!1_xVgV?zx@to9mrsh2+J&RT*v6UGY5yNrNw#^J6 zB~1tnB$-+9;Rvnr-N`v!(z09l_39;!#Do(1G9^pP9Ap2ctMN3*L6`GwbROT;qiK#l zR+tA8DTySm`7K485hJwgsEUYB%1$i5I8Iy+v9JOlyXPBcZuv&9r zJ(F43);#5T?w#s4TgM`MDZ@6{hl*J0q7 zcTE0sg2aYc$diY!fa0XE-dZj6*NdKl`93a7-IP><^SXhjbztw#I)b#{eMtpiR+d#) zcq!_ccf)|=B93-@XL7~1>H?uKgWDwAki1DPUXOQuLfm%%{BAelU!*I?%T(Vys&VZW zykztH{nTco4yOt3wit_h+k);`M>ghXET!zxZ?vn2*qSude{=sqsY zPk^%>XV^eS()fiK2U^zLRImMt?rf_3bTfM|5E6g*^@qMn{uXW$9eIKi+)n=~bOUKk zwKeid)lsr7+2X}=dXMj~&@jQx@W|HE3^ceaEe6!N<=Och>9atb*8Ra4P@5TO?l5`IDeQj%^vzV^i*z8F8VV=pJqIi zi@%&MJ>^s7chyFm!sfI2Sl7U0?7C_YkFVr#b-kdZZt3UtG=L6Va*2VW&tB9TDO&ns zDFC-*D@PgI_K~HS`&HLkFH3Fkp7Pc6?8&-wDwkF4mnCd9oJ6bPjBB=sMcIR8o4wCI zCJZ2Pbv`Y1sKbHS8HMrlOXVBNj3?(2`}@lq>HCzCl%UPBBB>86fcN;Z!Tlp6% z9#@RUq?b23F4U70U>>~$}**EcIlv{;Dz~c7*AID8uL3(?XtQ`|TrZ38e7~siq Hr=Ix}GpBEV literal 14889 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

obkzBHHw)%!W~j@Fk!G)!@_9jb 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 oeUItr=y-W~? Date: Tue, 7 Jan 2025 11:44:39 +0100 Subject: [PATCH 13/27] spacer: better docs, compute statistics per-system --- apps/spacer/README.md | 14 +++++++++++- apps/spacer/spacer.app.js | 48 +++++++++++++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/apps/spacer/README.md b/apps/spacer/README.md index 5a8725a96..00d9de4a3 100644 --- a/apps/spacer/README.md +++ b/apps/spacer/README.md @@ -4,5 +4,17 @@ Compare GPS with Baido and Glonass This turns GNSS receiver into mode with all three systems enabled, and displays debug info from all of them. Click into top left corner to -switch navigation systems. +switch navigation systems. Clicks in bottom half of screen switch info +pages. + +GNSS acquisition has few phases, and this software is assuming you are +not doing a cold start. GNSS fix needs 4 or 5 satellites with +reasonable signal strength, and then holding the same place for 40 or +so seconds. + +nil -- no satellites visible + +S1..S4 -- not enough satellites being decoded (5 needed) + +XXdB -- have enough satellites, but signal is not strong enough diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index 1b31afb64..7d4699a7b 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -217,10 +217,37 @@ let skys = { }, }; +function deepCopy(obj) { + if (obj === null || typeof obj !== "object") { + return obj; // Return primitive values as-is + } + + if (Array.isArray(obj)) { + return obj.map(deepCopy); // Handle arrays recursively + } + + const copy = {}; + for (const key in obj) { + if (obj.hasOwnProperty(key)) { + copy[key] = deepCopy(obj[key]); // Recursively copy properties + } + } + return copy; +} + let sky = { this_usable: 0, debug: 0, all: skys, /* Sattelites from all systems */ + split: 1, + + init: function () { + if (this.split) { + this.s_gp = deepCopy(skys); + this.s_gl = deepCopy(skys); + this.s_bd = deepCopy(skys); + } + }, drawGrid: function() { g.setColor(0,0,0); @@ -272,8 +299,12 @@ let sky = { tof: function(v, n) { let i = (1*v); return i.toFixed(n); }, tof0: function(v) { return this.tof(v, 0); }, tof1: function(v) { return this.tof(v, 1); }, - fmtSys: function(sys) { - return sys.sent + "." + sys.d23 + "D "+ this.tof(sys.pdop) + " " + this.tof0(sys.vdop) + "\n"; + fmtSys: function(sys, sats) { + let r = sys.sent + " "; + // r+= sys.d23 + "D "; + if (sats) + r += sats.sats_used + "/" + sats.snum; + return r + "\n"; }, drawRace: function() { let m = this.old_msg; @@ -281,9 +312,9 @@ let sky = { "q" + m.quality + " S" + m.in_view + " h" + this.tof0(m.hdop) + "m\n" + /* "v" + this.tof0(m.vdop) + "m " + "p" + this.tof0(m.pdop) + "m\n" + */ this.all.summary() + "\n" + - "gp"+ this.fmtSys(m.gp) + - "bd" + this.fmtSys(m.bd) + - "gl" + this.fmtSys(m.gl); + "gp"+ this.fmtSys(m.gp, this.s_gp) + + "bd" + this.fmtSys(m.bd, this.s_bd) + + "gl" + this.fmtSys(m.gl, this.s_gl); if (this.msg.finished != 1) msg += "!"; g.reset().clear().setFont("Vector", 30) @@ -371,6 +402,8 @@ let sky = { if (this.debug > 0) print("Have gps sentences", s[1], "/", s[2]); this.all.parseSats(s); + if (this.split) + this.s_gp.parseSats(s); this.msg.gp.sent = ""+s[2]; return; } @@ -378,6 +411,8 @@ let sky = { if (this.debug > 0) print("Have baidu sentences", s[1], "/", s[2]); this.all.parseSats(s); + if (this.split) + this.s_bd.parseSats(s); this.msg.bd.sent = ""+s[2]; return; } @@ -385,6 +420,8 @@ let sky = { if (this.debug > 0) print("Have glonass sentences", s[1], "/", s[2]); this.all.parseSats(s); + if (this.split) + this.s_gl.parseSats(s); this.msg.gl.sent = ""+s[2]; return; } @@ -442,4 +479,5 @@ ui.init(); ui.topLeft = () => sky.selectSpace(); Bangle.on("drag", (b) => ui.touchHandler(b)); sky.onMessageEnd = onMessage; +sky.init(); start(); From 9605d0d2bbcb516ffc2f24403165e52b1b10b860 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Tue, 7 Jan 2025 12:34:08 +0100 Subject: [PATCH 14/27] spacer: report details for each system --- apps/spacer/spacer.app.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index 7d4699a7b..d66defaf6 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -162,7 +162,7 @@ let skys = { if (sortedSats[i] && sortedSats[i].snr) return "S" + (i+1); } - return "nil"; + return "U" + this.snum; }, satVisibility: [], trackSatelliteVisibility: function() { @@ -303,7 +303,8 @@ let sky = { let r = sys.sent + " "; // r+= sys.d23 + "D "; if (sats) - r += sats.sats_used + "/" + sats.snum; + // r += sats.sats_used + "/" + sats.snum; + r += sats.summary(); return r + "\n"; }, drawRace: function() { From 302e1009d6b41d9f41a426eeb0b9988c1130c55f Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 10 Jan 2025 11:17:14 +0100 Subject: [PATCH 15/27] spacer: Fix computations on multiple systems --- apps/spacer/spacer.app.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index d66defaf6..95f2ab426 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -211,6 +211,7 @@ let skys = { return this.qualest(); }, onEnd: function () { + this.trackSatelliteVisibility(); if (this.sats_used < 5) this.sky_start = getTime(); this.reset(); @@ -346,9 +347,13 @@ let sky = { this.msg.bd = {}; this.msg.gl = {}; this.onMessageEnd(); - this.all.trackSatelliteVisibility(); //print(this.sats); this.all.onEnd(); + if (this.split) { + this.s_gp.onEnd(); + this.s_gl.onEnd(); + this.s_bd.onEnd(); + } }, parseRaw: function(msg, lost) { //print(msg); From f870343b4254af8f2325f2b23d28d0f50d2b59b5 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 10 Jan 2025 11:22:49 +0100 Subject: [PATCH 16/27] spacer: Display systems with no data as "off" --- apps/spacer/spacer.app.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index 95f2ab426..2a12d1f50 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -301,6 +301,8 @@ let sky = { tof0: function(v) { return this.tof(v, 0); }, tof1: function(v) { return this.tof(v, 1); }, fmtSys: function(sys, sats) { + if (!sys.sent) + return " off\n"; let r = sys.sent + " "; // r+= sys.d23 + "D "; if (sats) From d2276bee06867d690adc5fe6c5e41f75e231ae1c Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 10 Jan 2025 20:14:34 +0100 Subject: [PATCH 17/27] spacer: Document current behaviour --- apps/spacer/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/spacer/README.md b/apps/spacer/README.md index 00d9de4a3..b3fc437ba 100644 --- a/apps/spacer/README.md +++ b/apps/spacer/README.md @@ -12,9 +12,9 @@ not doing a cold start. GNSS fix needs 4 or 5 satellites with reasonable signal strength, and then holding the same place for 40 or so seconds. -nil -- no satellites visible +Uxx -- satellites are known but not being received S1..S4 -- not enough satellites being decoded (5 needed) -XXdB -- have enough satellites, but signal is not strong enough +XXdB -- this is strength of 5th strongest satellite From d38dec5e4c7d21654552af2909431ee5d845aed8 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 10 Jan 2025 20:14:47 +0100 Subject: [PATCH 18/27] spacer: version 0.10 --- apps/spacer/ChangeLog | 1 + apps/spacer/metadata.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/spacer/ChangeLog b/apps/spacer/ChangeLog index 263d4078d..88e8a64fc 100644 --- a/apps/spacer/ChangeLog +++ b/apps/spacer/ChangeLog @@ -1 +1,2 @@ 0.01: attempt to import +0.10: major updates, display satellites, display per-system satellite info diff --git a/apps/spacer/metadata.json b/apps/spacer/metadata.json index 55598f953..e114d8dd1 100644 --- a/apps/spacer/metadata.json +++ b/apps/spacer/metadata.json @@ -1,6 +1,6 @@ { "id": "spacer", "name": "Space Race", - "version": "0.01", + "version": "0.10", "description": "Compare GPS with Baido and Glonass", "icon": "app.png", "readme": "README.md", From 473b9734107677d5d6461458ad4ec5f747a916d1 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 10 Jan 2025 21:21:21 +0100 Subject: [PATCH 19/27] spacer: fix some warnings --- apps/spacer/spacer.app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/spacer/spacer.app.js b/apps/spacer/spacer.app.js index 2a12d1f50..99453e79a 100644 --- a/apps/spacer/spacer.app.js +++ b/apps/spacer/spacer.app.js @@ -158,7 +158,7 @@ let skys = { if (sortedSats[4] && sortedSats[4].snr) { return "" + sortedSats[4].snr + "dB"; } - for (i=4; i>=0; i--) { + for (let i=4; i>=0; i--) { if (sortedSats[i] && sortedSats[i].snr) return "S" + (i+1); } @@ -450,7 +450,7 @@ let sky = { this.sys += 1; if (this.sys == 4) this.sys = 0; - val = 7; + let val = 7; if (this.sys) val = 1 << (this.sys - 1); this.casic_cmd("$PCAS04,"+val); From 018052d63d0caf9735752362abe517bd9781e37a Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 20 Jan 2025 10:48:23 +0000 Subject: [PATCH 20/27] add more docs for recorder items --- apps/recorder/README.md | 17 +++++++++++++++++ apps/recorder/widget.js | 16 +++++++++------- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/apps/recorder/README.md b/apps/recorder/README.md index 6da739b1c..d04e0342d 100644 --- a/apps/recorder/README.md +++ b/apps/recorder/README.md @@ -52,6 +52,23 @@ As long as widgets are loaded, you can: * Call `WIDGETS["recorder"].setRecording(true, {force:"new"/"append"/"overwrite")` to start recording (it returns a promise, and will not show a menu) * Call `WIDGETS["recorder"].setRecording(false)` to stop recording +### Recording new items + +You can add new data items to record by creating a JS file on the Bangle named ending in `.recorder.js` that adds a new item +to the supplied `recorders` array. For example `foobar.recorder.js` could contain: + +``` +(function(recorders) { + recorders.foobar = { + name : "Foobar", // Name to appear in UIs + fields : ["foobar"], // Column headings to appear as header in recorded CSV data + getValues : () => [123], // Columns of data (length should match 'fields') + start : () => {}, // Called when recording starts - turn on any hardware/intervals you need + stop : () => {}, // Called when recording stops - turn off any hardware/intervals + draw (x,y) => {} // draw 12x12px status image at x,y on g + } +}) +``` ## Tips diff --git a/apps/recorder/widget.js b/apps/recorder/widget.js index 74cffb068..740df922f 100644 --- a/apps/recorder/widget.js +++ b/apps/recorder/widget.js @@ -145,15 +145,17 @@ } } - /* eg. foobar.recorder.js + /* You can add new data items to record by creating a JS file on the Bangle named ending in `.recorder.js` that adds a new item +to the supplied `recorders` array. For example `foobar.recorder.js` could contain: + (function(recorders) { recorders.foobar = { - name : "Foobar", - fields : ["foobar"], - getValues : () => [123], - start : () => {}, - stop : () => {}, - draw (x,y) => {} // draw 12x12px status image + name : "Foobar", // Name to appear in UIs + fields : ["foobar"], // Column headings to appear as header in recorded CSV data + getValues : () => [123], // Columns of data (length should match 'fields') + start : () => {}, // Called when recording starts - turn on any hardware/intervals you need + stop : () => {}, // Called when recording stops - turn off any hardware/intervals + draw (x,y) => {} // draw 12x12px status image at x,y on g } }) */ From a603d96c6eeee2242437a7a9e148106fc5950eb6 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 20 Jan 2025 10:48:41 +0000 Subject: [PATCH 21/27] lint exemptions --- apps/lint_exemptions.js | 63 ----------------------------------------- 1 file changed, 63 deletions(-) diff --git a/apps/lint_exemptions.js b/apps/lint_exemptions.js index 1b3a3cc11..70b5bbb38 100644 --- a/apps/lint_exemptions.js +++ b/apps/lint_exemptions.js @@ -79,12 +79,6 @@ module.exports = { "no-undef" ] }, - "apps/podadrem/app.js": { - "hash": "f7392e74974f69553aade2dcc07527b5d3b71a9b84e6dc5e0dd995e78dff8007", - "rules": [ - "no-unused-vars" - ] - }, "apps/openstmap/imagefilter.js": { "hash": "8a71e9a0ecfa94150379c41a5a915cfdac39f8b2e485e5cc1ce4629e85293acd", "rules": [ @@ -148,13 +142,6 @@ module.exports = { "no-unused-vars" ] }, - "apps/waypoints/waypoints.app.js": { - "hash": "ff02639eb8f81784c942093d57d254295e2c78918adb4bcffdf0d0284ebfac55", - "rules": [ - "no-unused-vars", - "no-undef" - ] - }, "apps/timerclk/timer.js": { "hash": "3b70606f1742b34bf4769f6e8703144ff0c3ba401a3a21f97ddcab5432c94db5", "rules": [ @@ -195,12 +182,6 @@ module.exports = { "no-unused-vars" ] }, - "apps/poweroff/settings.js": { - "hash": "c197afe72c612a4b3825a3a12a628d0f4ed83823da3f28885bbf473037a02506", - "rules": [ - "no-unused-vars" - ] - }, "apps/oxofocus/app.js": { "hash": "cd29309373974ef038725e26d8a2ff2634a437c89cdffc3b12defd65a948db75", "rules": [ @@ -208,13 +189,6 @@ module.exports = { "no-undef" ] }, - "apps/orloj/app.js": { - "hash": "fa43f035d759ba94f564392f410c0c6c485bb41a33c062f03d666738d517ccf3", - "rules": [ - "no-unused-vars", - "no-undef" - ] - }, "apps/nixie/m_vatch.js": { "hash": "36a7fa956f99d5815cd6bac570d2b86833d1d37474d7eef0bb21892bdf6723a8", "rules": [ @@ -490,13 +464,6 @@ module.exports = { "no-undef" ] }, - "apps/doztime/app-bangle1.js": { - "hash": "1e9598c201175180ae77d1c3bc47e8138b339b72eb58782b5057fb7aefdc88a1", - "rules": [ - "no-unused-vars", - "no-undef" - ] - }, "apps/carcrazy/app.js": { "hash": "fd9f98f4f9e24c63a8fa02918dceab4503edf88e06537922caf86e85884408f3", "rules": [ @@ -587,12 +554,6 @@ module.exports = { "no-undef" ] }, - "apps/swp2clk/settings.js": { - "hash": "2d9de7ffdf171f6e7b058741046c8a326cf9d5dba651f52fcdb523214b08d626", - "rules": [ - "no-undef" - ] - }, "apps/sunclock/app.js": { "hash": "54f49294816e06907003a71289a8b79641b1cd082044fb22bb4c4b80f6845459", "rules": [ @@ -617,12 +578,6 @@ module.exports = { "no-undef" ] }, - "apps/spotrem/app.js": { - "hash": "35f3ee5371acde28427fd01e191ff58108d3d9e4db1a221dca081b7a7b9c3c77", - "rules": [ - "no-undef" - ] - }, "apps/speedalt/app.js": { "hash": "2c8a2c0d7f60a8c25ee86e943f59df8fb5816ceac00e9e077220227d8885b133", "rules": [ @@ -761,12 +716,6 @@ module.exports = { "no-undef" ] }, - "apps/owmweather/boot.js": { - "hash": "10fe98e871a7df3338fc764d62ac4db65c20c44774aad112f5faf26c7497f78e", - "rules": [ - "no-undef" - ] - }, "apps/openwind/app.js": { "hash": "91bfda771bd5cc3127ede3b52f5f088b733ac9e7fc2d8dff4f1d732e66a8af47", "rules": [ @@ -917,12 +866,6 @@ module.exports = { "no-undef" ] }, - "apps/infoclk/settings.js": { - "hash": "56adc3eff3cbc04dd08238ed7e559416ebbc7736c872070c757d70bf5f31b440", - "rules": [ - "no-undef" - ] - }, "apps/infoclk/app.js": { "hash": "27cc368eb1be14658db7fd482e78c4bc7673e2a1c68bc3a1a5f7c7e29915ca88", "rules": [ @@ -971,12 +914,6 @@ module.exports = { "no-undef" ] }, - "apps/gpssetup/gpssetup.js": { - "hash": "a63f670f4adf04895e6837270fcf19bd56f0a6d049cfb8e3ad8928c283d1bfd3", - "rules": [ - "no-undef" - ] - }, "apps/glbasic/glbasic.app.js": { "hash": "7d12a030d6f0ef69a0e5a9783229fd49c0a6a06bf751e3ac562145d2ce8350e9", "rules": [ From 1251f261da4ff7a6eb0d7ecab8124303f7fdbb57 Mon Sep 17 00:00:00 2001 From: thyttan <6uuxstm66@mozmail.com⁩> Date: Tue, 2 Jul 2024 00:43:29 +0200 Subject: [PATCH 22/27] spotrem: refactor to handle ui all inside setUI and fix lint warnings --- apps/spotrem/ChangeLog | 1 + apps/spotrem/app.js | 15 ++++----------- apps/spotrem/metadata.json | 2 +- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/apps/spotrem/ChangeLog b/apps/spotrem/ChangeLog index 723fbd2d7..f21454551 100644 --- a/apps/spotrem/ChangeLog +++ b/apps/spotrem/ChangeLog @@ -11,3 +11,4 @@ when fastloading. 0.10: Some refactoring to shorten the code. 0.11: Further refactoring to shorten the code. Fixed search and play that was broken in v0.10. 0.12: Fix some warnings from the linter. +0.13: Move ui-handlers inside setUI-call. diff --git a/apps/spotrem/app.js b/apps/spotrem/app.js index 4abc5392c..bbe706b93 100644 --- a/apps/spotrem/app.js +++ b/apps/spotrem/app.js @@ -14,7 +14,6 @@ let gfx = function() { widgetUtils.hide(); R = Bangle.appRect; const MARIGIN = 8; - // g.drawString(str, x, y, solid) g.clearRect(R); g.reset(); @@ -100,23 +99,17 @@ let swipeHandler = function(LR, _) { // Navigation input on the main layout let setUI = function() { -// Bangle.setUI code from rigrig's smessages app for volume control: https://git.tubul.net/rigrig/BangleApps/src/branch/personal/apps/smessages/app.js Bangle.setUI( {mode : "updown", - remove : ()=>{ - Bangle.removeListener("touch", touchHandler); - Bangle.removeListener("swipe", swipeHandler); - clearWatch(buttonHandler); - widgetUtils.show(); - } + touch: touchHandler, + swipe: swipeHandler, + btn: ()=>load(), + remove : ()=>widgetUtils.show(), }, ud => { if (ud) Bangle.musicControl(ud>0 ? "volumedown" : "volumeup"); } ); - Bangle.on("touch", touchHandler); - Bangle.on("swipe", swipeHandler); - let buttonHandler = setWatch(()=>{load();}, BTN, {edge:'falling'}); }; // Get back to the main layout diff --git a/apps/spotrem/metadata.json b/apps/spotrem/metadata.json index f25b0e42b..8ecc0d867 100644 --- a/apps/spotrem/metadata.json +++ b/apps/spotrem/metadata.json @@ -1,7 +1,7 @@ { "id": "spotrem", "name": "Remote for Spotify", - "version": "0.12", + "version": "0.13", "description": "Control spotify on your android device.", "readme": "README.md", "type": "app", From 9ab4ed8a129686becbef21ba4bf4e9ffefeb196f Mon Sep 17 00:00:00 2001 From: June Bennison Date: Sat, 25 Jan 2025 18:21:45 +1100 Subject: [PATCH 23/27] Add Dense Clock app --- apps/denseclock/app-icon.js | 1 + apps/denseclock/app.js | 157 ++++++++++++++++++++++++++++++++++ apps/denseclock/app.png | Bin 0 -> 1569 bytes apps/denseclock/metadata.json | 14 +++ 4 files changed, 172 insertions(+) create mode 100644 apps/denseclock/app-icon.js create mode 100644 apps/denseclock/app.js create mode 100644 apps/denseclock/app.png create mode 100644 apps/denseclock/metadata.json diff --git a/apps/denseclock/app-icon.js b/apps/denseclock/app-icon.js new file mode 100644 index 000000000..380a7b4ff --- /dev/null +++ b/apps/denseclock/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mElwMBwf/AAeAAomYAomcAov4/E/w/jzngnEPg+AzninGOn+IznnnPOn+cCIIFBh4RBAoPPC4Xn/PP8efAo3jAoWPwAdCC4OB+AjC4BGEAEnH/ADBx/BGoN//0PwPx8E/AoOP/HnAoPPAoPmn0/ApHkn//5+DDoQFBEYPhAoX48YFE4/jAogvBAoWP8QFBFAKDBn0+geBwHwvwFBwYA=")) diff --git a/apps/denseclock/app.js b/apps/denseclock/app.js new file mode 100644 index 000000000..62a40154e --- /dev/null +++ b/apps/denseclock/app.js @@ -0,0 +1,157 @@ +// FONTS + +/* + Share Tech Mono: https://fonts.google.com/specimen/Share+Tech+Mono + Converted with: https://www.espruino.com/Font+Converter +*/ + +Graphics.prototype.setFontShareTechMonoBig = function(scale) { + // Actual height 56 (55 - 0) + this.setFontCustom( + atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAAAAAAAB+AAAAAAAAB+AAAAAAAAB+AAAAAAAAB+AAAAAAAAB+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAHwAAAAAAAA/wAAAAAAAD/wAAAAAAAf/wAAAAAAB//gAAAAAAP/8AAAAAAA//wAAAAAAH/+AAAAAAA//4AAAAAAD//AAAAAAAf/8AAAAAAB//gAAAAAAP/8AAAAAAB//wAAAAAAH/+AAAAAAA//4AAAAAAD//AAAAAAAf/4AAAAAAB//gAAAAAAP/8AAAAAAA//wAAAAAAA/+AAAAAAAA/4AAAAAAAA/AAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf///4AAAAD/////AAAAP/////wAAAf/////4AAA//////8AAA//////8AAB/AAB/j+AAB+AAH/B+AAB8AAP8A+AAB8AA/4A+AAB8AB/gA+AAB8AH/AA+AAB8AP8AA+AAB8A/4AA+AAB8B/gAA+AAB+D/AAB+AAA//+AAP8AAA//////8AAAf/////4AAAP/////wAAAH/////gAAAB////+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPgAAAAeAAAfgAAAA+AAAfAAAAA+AAA/AAAAA+AAA+AAAAA+AAA+AAAAA+AAB+AAAAA+AAB8AAAAA+AAB//////+AAB//////+AAB//////+AAB//////+AAB//////+AAB//////+AAAAAAAAA+AAAAAAAAA+AAAAAAAAA+AAAAAAAAA+AAAAAAAAA+AAAAAAAAA+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAB8AAAAD+AAB8AAAAP+AAB8AAAAf+AAB8AAAB/+AAB8AAAD/+AAB8AAAH/+AAB8AAAf8+AAB8AAA/4+AAB8AAD/w+AAB8AAH/A+AAB+AAf+A+AAB+AA/4A+AAA////wA+AAA////gA+AAAf//+AA+AAAP//8AA+AAAH//wAA+AAAB/+AAA+AAAAAAAAA+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8AAAAA+AAB8AAAAA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AD8AA+AAB+AH+AB+AAA////gD+AAA//////8AAAf/////8AAAP//P//4AAAH/+H//wAAAA/4D//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAAAAAP/wAAAAAAD//wAAAAAB///wAAAAAf///wAAAAH////wAAAB///+HwAAAB///gHwAAAB//wAHwAAAB/4AAHwAAAB+AAAHwAAABAAAAHwAAAAAAP///+AAAAAf///+AAAAAf///+AAAAAf///+AAAAAf///+AAAAAf///+AAAAAAAHwAAAAAAAAHwAAAAAAAAHwAAAAAAAAHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB///wAA+AAB///wAA+AAB///wAA+AAB///wAA+AAB///wAA+AAB///wAA+AAB8AHwAA+AAB8AHwAA+AAB8AHwAA+AAB8AD4AA+AAB8AD4AA+AAB8AD4AB+AAB8AD+AD+AAB8AD///8AAB8AB///8AAB8AA///4AAB8AAf//wAAB4AAP//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////AAAAP/////gAAAf/////4AAAf/////4AAA//////8AAA/APgAD+AAB+APgAB+AAB8APgAA+AAB8APgAA+AAB8APgAA+AAB8APgAA+AAB8APgAA+AAB8APgAA+AAB8AHwAA+AAB8AHwAB+AAB8AH+AP8AAB8AH///8AAB8AD///4AAAAAB///wAAAAAA///gAAAAAAP/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8AAAAAAAAB8AAAAAAAAB8AAAAAAAAB8AAAAAAAAB8AAAAAOAAB8AAAAD+AAB8AAAAf+AAB8AAAD/+AAB8AAA//+AAB8AAH//+AAB8AB///gAAB8AP//8AAAB8D///AAAAB8f//4AAAAB////AAAAAB///wAAAAAB//+AAAAAAB//gAAAAAAB/8AAAAAAAB/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//AAAAD/8H//wAAAP//P//4AAAf/////8AAA//////8AAA//////+AAB/AP+AB+AAB8AD8AA+AAB8AD8AA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AB8AA+AAB8AD8AA+AAB+AH+AA+AAA////AD+AAA//////8AAAf/////8AAAP//P//4AAAH/+H//wAAAA/4D//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//4AAAAAAP//+AAAAAAf///AAAAAAf///AA+AAA////gA+AAB/AAfgA+AAB+AAPgA+AAB8AAPwA+AAB8AAHwA+AAB8AAHwA+AAB8AAHwA+AAB8AAHwA+AAB8AAHwA+AAB8AAHwB+AAB+AAHwB+AAA//////8AAA//////8AAAf/////4AAAP/////wAAAH/////gAAAB////+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAB+AAAAB+AAB+AAAAB+AAB+AAAAB+AAB+AAAAB+AAB+AAAAB+AAB+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'), + 46, + 32, + 60+(scale<<8)+(1<<16) + ); + return this; +}; + +Graphics.prototype.setFontShareTechMono = function(scale) { + // Actual height 38 (37 - 0) + this.setFontCustom( + atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgAAAAAeAAAAAB4AAAAAHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAfAAAAAP8AAAAD/gAAAB/4AAAAf+AAAAP/AAAAH/gAAAB/4AAAA/8AAAAP/AAAAH/gAAAD/wAAAA/8AAAAP+AAAAA/gAAAADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//4AAA///8AAP///8AA////wAHwAfvgAeAH4eABwA/A4AHAHwDgAcB+AOAB4PgB4AHj8AHgAf///+AA////wAB///+AAD///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAOAA8AAA4ADwAADgAeAAAOAB4AAA4AH////gAf///+AB////4AH////gAAAAAOAAAAAA4AAAAADgAAAAAOAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4AHAAAfgAcAAD+ABwAA/4AHAAH/gAcAA/OABwAP44AHgB+DgAfAfwOAA//8A4AD//gDgAH/4AOAAH+AA4AAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAOABwBwA4AHAHADgAcAcAOABwBwA4AHAHADgAeA+AOAB8H4B4AD////gAP///8AAf+f/gAAPgf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPgAAAAP+AAAAP/4AAAf//gAAf//OAAB//A4AAH+ADgAAcAAOAAAAH//4AAA///gAAD//+AAAP//4AAAAHgAAAAAOAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/+ADgAf/4AOAB//gA4AH/+ADgAcA4AOABwDgA4AHAPADgAcA8AeABwD//4AHAH//AAcAP/4AAAAf/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///8AAH///4AA////wAH////gAeB4AeABwHgA4AHAeADgAcB4AOABwHgA4AHAeAHgAcA//+ABwD//wAAAH/+AAAAP/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAABwAAAAAHAAAAgAcAAAeABwAAf4AHAAP/gAcAH/+ABwH/+AAHD//AAAf//AAAB//gAAAH/gAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/gAAP+f/gAD////AAP///+AB//8B4AHgPgDgAcAcAOABwBwA4AHAHADgAcAcAOAB4D4B4AH////gAP///8AAf/f/wAAfw/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//AAAAH/+AAAA//8A4AH4HwDgAeAHgOABwAeA4AHAB4DgAcAHgOABwAeB4AHgB4HgAf///+AA////wAB///+AAB///gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4AHgAAHgAeAAAeAB4AAB4AHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='), + 46, + 22, + 40+(scale<<8)+(1<<16) + ); + return this; +}; + +Graphics.prototype.setFontShareTechMonoSmall = function(scale) { + // Actual height 23 (22 - 0) + this.setFontCustom( + atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zgP/zgP/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAAPwAAPwAAAAAAPwAAPwAAPAAAAAAAAAAAAAAAAAAAAAAAAwYAP//gP//gP//gAwYAP//gP//gP//gAwYAAAAAAAAAAAAAAAAAB4AAD+BgH/Bg+HB8+DB8+DB8GD/gGB/AAAcAAAAAAAAAABAAH7AAP7AAMLAAMbAAP7AAHzfAAG/gAGxgAGxgAG/gAGfAAGAAAAAAAAAADz/AH//gP+DgMOBgMMBgMMBgMP/gAP/gAMAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAPwAAPwAAPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wP//8/AA+4AAGgAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAC4AAG/AB+P//8D//wAAAAAAAAAAAAAAAAAAAAAAAADAAADuAAB+AAP4AAfwAAP8AAB+AADsAADAAAAAAAAAAAAAAAAAAAADgAADgAADgAAf8AAf8AAf8AADgAADgAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeAAD+AAD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAADgAADgAADgAADgAADgAADgAADgAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAADgAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAeAAD8AAfwAB+AAP4AA/AAH8AAfgAA8AAAwAAAAAAAAAAAAAAAD/+AH//APB/gMDxgMHBgMeBgP//gH//AD/+AAAAAAAAAAAAAAAAAGAAgGABgOABgOABgP//gP//gAABgAABgAABgAAAAAAAAAAAAAAAAAABgMAHgMAPgMA9gMB5gOHxgH/BgD+BgAABgAAAAAAAAAAAAAAAAAAAAMCBgMGBgMGBgMHBgP/DgH//gD5/AAAAAAAAAAAAAAAAAAAAAAD4AA/4AP/4APwYAMAYAAP/gAP/gAAcAAAYAAAAAAAAAAAAAAAAAAAAAP+BgP+BgMGBgMGBgMHDgMH/gMD/AAAAAAAAAAAAAAAAAAAAAD/+AH//AP//gMMBgMMBgMOBgMP/gMH/AAD+AAAAAAAAAAAAAAAAAMAAAMAAAMADgMAfgMH/AM/4AP/AAPwAAGAAAAAAAAAAAAAAAAAAAD5/AH//gP/DgMHBgMGBgMHBgP/jgH//gD5/AAAAAAAAAAAAAAAAAD+AAH/AgP/hgMBhgMBhgMBhgP//gH//AD/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcDgAcDgAcDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeAcD+AcD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgAAHgAAPwAAMwAAc4AAY4AA4cAA4cABwMAAAAAAAAAAAAAAAAAAMYAAMYAAMYAAMYAAMYAAMYAAMYAAMYAAMYAAAAAAAAAAAAAAAAABwMAA4cAA4cAAY4AAc4AAMwAAPwAAHgAAHgAAAAAAAAAAAAAAAAAAAAAMAAAMABgMDzgMHzgOeAAH8AAD4AAAAAAAAAAAAAAB/8AH//AP//gMHhgMf5gM/9gMwNgM/5gM/8gMAMAP/8AH/8AA/wAAAAAAADgAA/gAP/gD/4AP8YAPAYAP8YAD/4AAP/gAA/gAADgAAAAAAAAAAAAP//gP//gMGBgMGBgMGBgMGBgP/DgH//gD5/AAAAAAAAAAAAAAAAAB/8AH//AP//gOABgMABgMABgMABgMABgMABgAAAAAAAAAAAAAAAAP//gP//gMABgMABgMABgMABgOADgH//gH//AAAAAAAAAAAAAAAAAP//gP//gP//gMGBgMGBgMGBgMGBgMGBgMABgAAAAAAAAAAAAAAAAP//gP//gP//gMHAAMHAAMHAAMHAAMHAAMAAAAAAAAAAAAAAAAAAAD/+AH//AP//gMABgMDBgMDBgMD/gMD/gAD/gAAAAAAAAAAAAAAAAP//gP//gAHAAAHAAAHAAAHAAAHAAP//gP//gAAAAAAAAAAAAAAAAAAAAMABgMABgP//gP//gP//gMABgMABgAAAAAAAAAAAAAAAAAAAAAAAAAABgMABgMABgMABgMAHgP//AP/+AAAAAAAAAAAAAAAAAAAAAP//gP//gAPAAAfgAB/4ADw+APAfgOAHgIABgAAAAAAAAAAAAAAAAAAAAP//gP//gAABgAABgAABgAABgAABgAAAAAAAAAAAAAAAAP//gP//gPgAAP+AAB/gAAHwAB/gAP8AAPgAAP//gP//gAAAAAAAAAAAAP//gP//gPwAAP/AAA/8AAD/gAAPgP//gP//gAAAAAAAAAAAAA/8AH//AH//gOADgMABgMABgMABgOADgH//gH//AA/4AAAAAAAAAAAAAP//gP//gMDgAMDgAMDgAMDgAP/AAH/AAD+AAAAAAAAAAAAAAA/8AH//AH//gOADgMABgMABgMABgOADgH//gH//wA/4wAAAAAAAAH//gP//gP//gMDAAMDAAMDgAOD8AP//AH+PgB4DgAAAgAAAAAAAAAAAAD4AAH+BgP+BgOGBgMHBgMHBgMH/gMD/AAA+AAAAAAAAAAAAAMAAAMAAAMAAAMAAAP//gP//gP//gMAAAMAAAMAAAMAAAAAAAAAAAAAAAP//AP//gAADgAABgAABgAABgAADgP//gP//AAAAAAAAAAAAAMAAAP4AAP/wAA//AAB/gAAHgAD/gB/+AP/AAPwAAIAAAAAAAAAAAP/gAP//gAP/gAAfgAH+AAHwAAD/gAAfgAf/gP//gP8AAAAAAAAAAAAAgOADgPgPgH4+AB/4AAfwAB/4AH4/APgPgOADgAAAgAAAAAAAAMAAAPAAAPwAAD8AAA//gAP/gAf/gD8AAPwAAPAAAIAAAAAAAAAAAAAAAMADgMAPgMA/gMD5gMPhgM+BgP4BgPgBgOABgAAAAAAAAAAAAAAAAAAAAAAAA///+///+wAAGwAAGwAAGAAAAAAAAAAAAAAAAAAAAwAAA+AAAfgAAH8AAA/AAAP4AAB+AAAPwAAD8AAAeAAAGAAAAAAAAAAAAAAAAAAAAwAAGwAAGwAAG///+///+AAAAAAAAAAAAAAAAAAAAAAAAA4AAD4AAPwAAeAAAYAAAeAAAPwAAD4AAAYAAAAAAAAAAAAAGAAAGAAAGAAAGAAAGAAAGAAAGAAAGAAAGAAAGAAAGAAAGAAAGAAAAAAAAAAAAAAAAIAAAMAAAOAAAGAAACAAAAAAAAAAAAAAAAAAAAAAAAAOAAY/gAY/gAZxgAZxgAZxgAZxgAf/gAP/gAABgAAAgAAAAAAAAAAAAP//gP//gAcBgAYBgAYBgAYBgAcDgAf/gAP/AAAAAAAAAAAAAAAAAAAAAAP/AAf/gAYBgAYBgAYBgAYBgAYBgAAAAAAAAAAAAAAAAAAAAAP/AAf/gAcDgAYBgAYBgAYBgAYDgP//gP//gAAAAAAAAAAAAAAAAAP+AAf/gAf/gAYxgAYxgAYxgAfxgAPxgAHwAAAAAAAAAAAAAAAAAAYBgAYBgD//gP//gP//gMYBgMYBgMYBgMQAAAAAAAAAAAAAAAAAAAPwGAf/GAYfGAYfGAYfGAYfGAY7mAf7+Afx8AAAAAAAAAAAAAAAAP//gP//gAcAAAYAAAYAAAYAAAcAAAf/gAP/gAAAAAAAAAAAAAAAAAYAAAYAAAYAAMf/gOf/gMf/gAABgAABgAABgAAAAAAAAAAAAAAAAAAAAAAAGAYAGAYAGAYAGMf/+Of/+Mf/8AAAAAAAAAAAAAAAAAAAAP//gP//gP//gADwAAH8AAefAAcHgAYDgAQAgAAAAAAAAAAAAEAAAMAAAMAAAMAAAP//AP//gAADgAABgAABgAABgAAAgAAAAAAAAAf/gAf/gAYAAAYAAAf/gAf/gAf/gAYAAAYAAAf/gAP/gAAAAAAAAAAAAAf/gAf/gAcAAAYAAAYAAAYAAAcAAAf/gAP/gAAAAAAAAAAAAAAAAAP/AAf/gAcDgAYBgAYBgAYBgAcDgAf/gAP/AAAAAAAAAAAAAAAAAAf/+Af/+AcBgAYBgAYBgAYBgAcDgAf/gAP/AAAAAAAAAAAAAAAAAAP/AAf/gAcDgAYBgAYBgAYBgAYDgAf/+Af/+AAAAAAAAAAAAAAAAAYBgAYBgAf/gAf/gAcBgAYBgAYBgAYAAAYAAAAAAAAAAAAAAAAAAAAAAAPhgAfxgAZxgAYxgAYxgAY/gAYfAAAAAAAAAAAAAAAAAAAAAAYAAAYAAAYAAD//AD//gAYBgAYBgAYBgAYBgAAAAAAAAAAAAAAAAAf+AAf/gAf/gAABgAABgAABgAf/gAf/gAf/gAAAAAAAAAAAAAQAAAeAAAf4AAH/AAAfgAADgAAfgAH/AAf4AAeAAAQAAAAAAAAAAAfAAAf/AAD/gAAPgAD/gAH4AAH/gAAPgAD/gAf+AAfAAAAAAAAAAAAAAAYBgAcHgAfPAAH+AAD4AAH+AAfPgAcDgAQBgAAAAAAAAAAAAAQAAAeAAAfwGAH+GAA/uAAD+AAf8AH/AAf4AAeAAAQAAAAAAAAAAAAAAAABgAYHgAYPgAY/gAZ5gAfxgAfBgAeBgAYAAAAAAAAAAAAAAAAAAAAAAADgAADgAf//8/+/+4AAGwAAGwAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf//+///+f//+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAGwAAG4AAG/+/+f//8ADgAADgAAAAAAAAAAAAAAAAAAAAAADgAADAAADAAADAAADAAADgAABgAADgAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'), + 32, + atob("DQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0H"), + 24+(scale<<8)+(1<<16) + ); + return this; +}; + +{ + + // VARS + + let FONT_NAME = "ShareTechMono"; + let BIG_FONT_HEIGHT = 60; + //let NORMAL_FONT_HEIGHT = 40; + let SMALL_FONT_HEIGHT = 24; + + let timeDrawTimeout; + let infoDrawTimeout; + let lockState = Bangle.isLocked(); + let pressure; + + + + // LISTENERS + + Bangle.on('lock', function(isLocked) { + lockState = isLocked; + timeDraw(); + infoDraw(); + }); + + + + // DRAW FUNCTIONS + + let timeDraw = function() { + g.reset(); + g.clearRect(Bangle.appRect.x, Bangle.appRect.y, Bangle.appRect.x2, Bangle.appRect.y + BIG_FONT_HEIGHT); + + var date = new Date(); + var timeArray = [date.getHours().toString().padStart(2, "0"), + date.getMinutes().toString().padStart(2, "0")]; + if (!lockState) timeArray.push(date.getSeconds().toString().padStart(2, "0")); + var timeString = timeArray.join(":"); + g.setFontAlign(0, 0).setColor(g.theme.fg).setFont(FONT_NAME + (lockState ? "Big" : "")); + g.drawString(timeString, Bangle.appRect.x2/2, Bangle.appRect.y + BIG_FONT_HEIGHT/2); + + if (timeDrawTimeout) clearTimeout(timeDrawTimeout); + timeDrawTimeout = setTimeout(function() { + timeDrawTimeout = undefined; + timeDraw(); + }, (lockState ? 10000 - (Date.now() % 10000) : 1000 - (Date.now() % 1000))); // if locked, every clock's 10s, otherwise every 1s + }; + + let infoDraw = function() { + g.reset(); + + var date = new Date(); + var dateString = [date.getFullYear().toString().padStart(4,"0"), + (date.getMonth()+1).toString().padStart(2,"0"), + date.getDate().toString().padStart(2,"0")].join("-"); + + var tzOffset = -(date.getTimezoneOffset())/60; + var tzOffsetString = (tzOffset >= 0 ? "+" + tzOffset : tzOffset); + + var batteryString = (Bangle.isCharging() ? "+" : "") + E.getBattery() + "%"; + + var pressureString = (pressure ? pressure + "hPa" : "(hPa)"); + + var powerString = (E.getPowerUsage().total / 1000) + "mA"; + + var stepsString = Bangle.getHealthStatus("day").steps + "ST"; + + var bluetoothStatus = NRF.getSecurityStatus(); + var bluetoothString = (bluetoothStatus.connected ? bluetoothStatus.connected_addr.split(" ")[0].substr(-5) : "N/C"); + + var infoMatrix = [ + [dateString + tzOffsetString ], + [batteryString, pressureString], + [powerString ], + [stepsString, bluetoothString ] + ]; + + g.clearRect(Bangle.appRect.x, Bangle.appRect.y + BIG_FONT_HEIGHT, Bangle.appRect.x2, Bangle.appRect.y2); + g.setFontAlign(0, -1).setColor(g.theme.fg2).setFont(FONT_NAME+"Small"); + + infoMatrix.forEach((lineArray, lineNumber) => { + g.drawString(lineArray.join(" "), Bangle.appRect.x2/2, Bangle.appRect.y + BIG_FONT_HEIGHT + SMALL_FONT_HEIGHT*lineNumber); + }); + + Bangle.getPressure().then(baroValue => { pressure=Math.round(baroValue.pressure); }); + + if (infoDrawTimeout) clearTimeout(infoDrawTimeout); + infoDrawTimeout = setTimeout(function() { + infoDrawTimeout = undefined; + infoDraw(); + }, (lockState ? 60000 : 10000)); // if locked, a minute from now, otherwise in 10s + }; + + + + // DRAW CALLS + + g.clear(); + + Bangle.setUI({ + mode: "clock", + remove: function() { + if (timeDrawTimeout) clearTimeout(timeDrawTimeout); + timeDrawTimeout = undefined; + if (infoDrawTimeout) clearTimeout(infoDrawTimeout); + infoDrawTimeout = undefined; + + delete Graphics.prototype.setFontShareTechMono; + delete Graphics.prototype.setFontShareTechMonoBig; + delete Graphics.prototype.setFontShareTechMonoSmall; + }}); + + Bangle.loadWidgets(); + Bangle.drawWidgets(); + + timeDraw(); + infoDraw(); +} diff --git a/apps/denseclock/app.png b/apps/denseclock/app.png new file mode 100644 index 0000000000000000000000000000000000000000..e395fcf8dab8c375e49b2d5a3ee61ab18999aa49 GIT binary patch literal 1569 zcmV++2HyFJP)EX>4Tx04R}tkv&MmP!xqv8>J!@K|828WT;MdQ4z;lg(6f4wL+^7CNKSiCJjl7 zi=*ILaPVib>fqw6tAnc`2>yV$3r>nIQsR9{p+$@r9`ED4dk*j22Lu}xrdeHaK+|nA zolJli&xt2Yx*+i**A;ArbawX991=)@`G8A zRnA+SwMvb(?#W*m&g(17T&FdPBo?s*2_h8KP(}qdVzld|SV+@(!pA@2`XzEHZ+(5ySo_p#$NPXOT=xYFDHY6F=4B)#6& zqDMggHgIv>)|5Tqat9cCGGtSBC4pA3PypV~=$mrD;4RR*=FP2jj?)JqL$gZV00)P_ zc#*Q#ecs*EIk$g%TJ!q>9cprf@^f1Q00006VoOIv0RI600RN!9r;`8x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru=>Zu7DgtiJ!V&-g02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00a3+L_t(&-tC!hXx3E}$3H!7uG!L26BCU{39&Xqos1B{ z#_UD2@GlPbLIOpiB1QZM>I*57FvQ3|IHTn&YnAq*cj_of){Ew!LM6n;h*h*~vN`{4 z&wSzc%JK5Mzdg^hIVb+U@bJ68bI6j*I&y+9jq0@w>& z9qvl30{Q~KUx5+BdGaameY1XF>b(@0_aIroZmnygtsBmh&kNA|fF7X0+d?CNw}IKf zIG_VK4txw;7f%)NzRpf3Fa~G`nt&ZZw3_X%8h|svRPoFKW&ppaf03T8 zz-K^O?@d|A&Da7n4Bs@-o-?$H2n&o7ZKR>q7#WSCHN-4jtlU%<7RWd4AGHrp2l^e{ zirz4^BGdj|&&9z1a@*@Y?-(mLmE++r0!9N*4A6;e16tHBmfPM2EYDPKUXFs-8o>_d zav0|iU@}k+JPm9BW&&>j`!bQ6*H4(?LJRu@I0~E`Bv*bzVGF>kQednX+63kL3RLMi zNe2($A3fU)-%8IL-fd@hNZY-!qHRl?=M)w&%1 z27U&11}YNsbXh$szuW*E9)SG0zzX0Q(Pnw!1G?C1Bfh_LU(`q3a%Unc5~~9@;>H{% zKN7eQF;-N3wml$sgR{Wvz)NaR1m0BpE!Bnq9#f3+IB*L1PF5>dK0Fq{#5SqAapwA5rb~1Czkw>R{MV~0 zT3QEb5x2|lOAX)o2tgGpLUo(ciN!3S5SU_Um6G!VaMLWXa~6d; zd=XfwQ|iAE=x>RUYwwOD0iM^gRiFUastMf$E~*q*ID`sxYTRW>GLaxbg8PqKe2H?b Tdy8}$00000NkvXXu0mjfaLv*} literal 0 HcmV?d00001 diff --git a/apps/denseclock/metadata.json b/apps/denseclock/metadata.json new file mode 100644 index 000000000..fa8c620a2 --- /dev/null +++ b/apps/denseclock/metadata.json @@ -0,0 +1,14 @@ +{ "id": "denseclock", + "name": "Dense Clock", + "shortName":"Dense Clock", + "version":"0.01", + "description": "A clockface dense with text-only information. Switches between showing seconds and minutes when unlocked/locked, in the interest of saving power.", + "icon": "app.png", + "type": "clock", + "tags": "clock", + "supports" : ["BANGLEJS2"], + "storage": [ + {"name":"denseclock.app.js","url":"app.js"}, + {"name":"denseclock.img","url":"app-icon.js","evaluate":true} + ] +} From d6c08245ee7256f0caee2c2991ca8d1f0249e596 Mon Sep 17 00:00:00 2001 From: June Bennison Date: Sat, 25 Jan 2025 18:32:11 +1100 Subject: [PATCH 24/27] denseclock: add screenshots --- apps/denseclock/metadata.json | 4 ++++ apps/denseclock/screenshot_locked.png | Bin 0 -> 3535 bytes apps/denseclock/screenshot_unlocked.png | Bin 0 -> 3590 bytes 3 files changed, 4 insertions(+) create mode 100644 apps/denseclock/screenshot_locked.png create mode 100644 apps/denseclock/screenshot_unlocked.png diff --git a/apps/denseclock/metadata.json b/apps/denseclock/metadata.json index fa8c620a2..d5bcd3cd5 100644 --- a/apps/denseclock/metadata.json +++ b/apps/denseclock/metadata.json @@ -10,5 +10,9 @@ "storage": [ {"name":"denseclock.app.js","url":"app.js"}, {"name":"denseclock.img","url":"app-icon.js","evaluate":true} + ], + "screenshots": [ + {"url":"screenshot_locked.png"}, + {"url":"screenshot_unlocked.png"} ] } diff --git a/apps/denseclock/screenshot_locked.png b/apps/denseclock/screenshot_locked.png new file mode 100644 index 0000000000000000000000000000000000000000..61a05ca446c9a44b1d72c6c66739fa70e1149029 GIT binary patch literal 3535 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 literal 0 HcmV?d00001 diff --git a/apps/denseclock/screenshot_unlocked.png b/apps/denseclock/screenshot_unlocked.png new file mode 100644 index 0000000000000000000000000000000000000000..f1af09cbacbe67306b90ec6c26ff191aa57ff786 GIT binary patch literal 3590 zcmai1X*kqh`~S|@%rr)_6d_F-LLyuC#xi7VsU+D=wz3oXVWJU*44NeS5*5iHTVh5d zexyiALz2c4F(V_!zWnF^>Ur_Jc+Pd5^SSQ(x<2=LaW9{9QqJ4r1d&om000CnEzInA zSo{AQ0q31Hucq9201d}l+9P=DCc-;HwAz2rDlIPE<;q!7S-!ilp#ts zo?5w%L@+-*HQT3-MBvR;(r5)BxOV+G*^~r=ITx(GRLglmT&<>r%ZPyQ;K1;I(|;>y zocvF`NCDWg>=~CQi?2-(%$e!9)ORqBxZllSVQ}sB>!0ZB5b7DJ;zNl*T=1V)$*w>M zxoZY~lvtd@8vd)?8b~WB1v+7=GvwOsW+!+C#K0i&dHSu zVM}I!)88-#husn^lXb+oIuk65@9wVbnTi_K)(UY_Uxx<*->Ej|ef)surj@Yfjz*qZ zq@<#w+UG^tEuWyKh_#FHA{{n$`^f&0)&{?F-sxYn)0n*PsJ!`Z^u#Q4-Jr7X=4{d& z9^Bewok)E%BnAC8PX!`_G=zN}TAC zbO87LISRHwSYk7`Is3#n}>5MToC3i z5M|;EWR$QIr>Rm4-S{fl&x@blDC5*!fB8~!4sE01@Ci;CP>p#W1DyGjkIAPQW&~?T zp!BORpVl%^IpWL-c8Yf**6a;Y5g+t8U=uNlBnGr`m$MritL|_*agRCd<(&etX0CU} zMiW*5K1h-$=Vus&JGhn|#e}XXV#o1a+~%d_^q+Y~;PA%*4zgE{He~Bt;@!3KH{;G4 z63EssjFoySAi5estl2@{n4X6tH6B>_%A&n;UGAa)To3{;lizzB%n462%bb;xha;Fr zUgmhKd8N2Mx%=_1PWT5hvLPoB;%XomGo|8hDmL5`V?Vst<^)4|+ebT?;o(csF~a@C zsC3HJ^QWNLlobnox`^b31)$lU!8}Rzu)>@J81kZiq>(GcF3>xZ;m2`Yg1l*suF>FuB5Wk4Nr(40G94l^P zByTblJUS0|P?8~DuB>VN!t48nM2%WI2!v`EODS|P2Fi~;jL+h^v*rTk8$eK3Zm3a|(T5 zt9(^|Z$r1Ec9Dg$$Q$SUsK#IsL3DUrM2AcA5?YH~)lZA|0m+Nq68I$Z^|gz?`dJNI z)^cd})u4K(mR`oZw7s_%Wc^==;lc(PAh2YL%l#Bb4jjM-Xo4xf$Nw%obKwsa5=>5G z9AVm>eo|UzvLAA{y_SKW$Q_^2GY-KlEY&)urI58!^t>P^Gwd5gqajhns}^QKg4#ur zaUa2)Z_T80jjkds{CI&#$kyfD?|f|7d3oxJae_TQr11BCU6(9Er>VUtgZ65%?1m{@ z;l=Di1XhO%5+DT!DeaqogHO>ZTFS*$dYB25{p}kJ&?ga2`SI)5fv+;dk$8Z>alW)D zCatj=S|sTrFq}ZPOuTVh%@Exa&`wxO#oiX@w_hk~i&o#uCvi51OWdE^4|S36XvJ2V zu-ycT+KngmLi|;WY+$}yS2Cg?Hug+%O7f|kZ-PC5^r8@@v?yrmq2f8m5L5UIzg<*L z{Cla?VdJi4tHi6_dcBcp>>m`0PfDq2Ptd!fcwr6A?19&4VuvTh*Cf)Z12P_)E4uL2qx=sk{8Gs?TNO0S|zslw!W+N8iw@#*4eQ}=JB7nuiy>6wWP4KE&gMPz-o4nP^Iw zZLswrhlK2TQpnzjM{Q)+vX;zAsG5>Qol~7!>8ET%%{G3#>?GN(=MN`WtXVO0R_`4s{#1B^fmzatr z1b;020mKgb>1QqRv>R2jfVVb+|iYos-rh|+H5;A%@J?g2j{Gx+GID73;58%e?@HCR=ssNq0~ z1NU0?7``&?4F`}kVCRxCAi&&x;}So{=aToM1SAgNqc|&TWV} z^OMB!PnHnKsHH`&6Yp{3Ue@X`|AYwqk$cixb%8fxdsFEZ**i-gaaW5IBKD`4v;|@&98ZoX$JJLsn_ty{ zQSI8MkCrQ0755xiFI|jo!~=Q*L-n>rzR7=5yHA&c8HuHrv_9O+hDprky2RE4?$lpY zgqbZwhFbZOL>G@(vjJuyR8w1P;;LsaN=(AC6G@caes(Zbto!wxbAElpJS7VV zU<_UbT&)LxBLfd}-37)?zVb0g_@2!SDWiLC{1K|n4rN8+<>)hVRJ!p^vzmS==Sb&* zpc=A^jl5|=+H#C_3Ztfp!G;HrU+-6u>hBr};jO=+a1~toUF>ZV3&ODw^d)cBe~g8g zKX5a6gp*fw`E@@B%7LpuA6%;uU9P=yc=s1Zx#iK2VZr9Q1HrETOI=zOYxec;C4vJJ zbz4*05s(Gy1JnRQ6RrPXdx|o_i1@*%`iT~v%UZ7aXEwhAnI8 z=!MpIQ4Nys)^rKkY`Ms=tEZW1a%TyADvmTtV=I-s65R}d6-KMh8D?JID_1QoxxFd?1K>`qdH zcKsei-SI0peX+cH$r@b$T4WwUmDo>HR}x0b>sM!Te)|5|7yA5PP!Lu-6utswSm}Pj zl9tOEc8~8&P>LSeo#b1>b%Ri((lib5Lp-syrq!yPJ@+K)M}xl|Tj zwnTN5D(?3?O5O9I?rqd0Md|eyE$3*tY|G_J4Ze%^Isrv9F5s|^WSe1|uF03?z#E7sO@axYHPaS9^D6lePpl%+=b8@k0Ecp5m4ZL H{O$h(BRQD5 literal 0 HcmV?d00001 From f47af9fe0fb422ab432f3b914aadb0a01611f5aa Mon Sep 17 00:00:00 2001 From: June Bennison Date: Sat, 25 Jan 2025 18:51:37 +1100 Subject: [PATCH 25/27] denseclock: bump version --- apps/denseclock/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/denseclock/metadata.json b/apps/denseclock/metadata.json index d5bcd3cd5..515e4661c 100644 --- a/apps/denseclock/metadata.json +++ b/apps/denseclock/metadata.json @@ -1,7 +1,7 @@ { "id": "denseclock", "name": "Dense Clock", "shortName":"Dense Clock", - "version":"0.01", + "version":"0.02", "description": "A clockface dense with text-only information. Switches between showing seconds and minutes when unlocked/locked, in the interest of saving power.", "icon": "app.png", "type": "clock", From 5a8f9328d1e7b0936d0ef184a14d8b5dbef67845 Mon Sep 17 00:00:00 2001 From: June Bennison Date: Sat, 25 Jan 2025 19:22:29 +1100 Subject: [PATCH 26/27] denseclock: (retroactive) changelog --- apps/denseclock/ChangeLog | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 apps/denseclock/ChangeLog diff --git a/apps/denseclock/ChangeLog b/apps/denseclock/ChangeLog new file mode 100644 index 000000000..2e09e5bb2 --- /dev/null +++ b/apps/denseclock/ChangeLog @@ -0,0 +1,2 @@ +0.01: Begin rewrite from old code. +0.02: Changed visuals: uA > mA, info order, battery state indication From 9b473e185ee6fc5ed0bb4d62f757b4e46224a5a9 Mon Sep 17 00:00:00 2001 From: June Bennison Date: Sat, 25 Jan 2025 21:19:16 +1100 Subject: [PATCH 27/27] denseclock: app icon update blurred inverted background to improve readability note in changelog --- apps/denseclock/ChangeLog | 1 + apps/denseclock/app-icon.js | 2 +- apps/denseclock/app.png | Bin 1569 -> 4198 bytes apps/denseclock/metadata.json | 2 +- 4 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/denseclock/ChangeLog b/apps/denseclock/ChangeLog index 2e09e5bb2..7ae520fa5 100644 --- a/apps/denseclock/ChangeLog +++ b/apps/denseclock/ChangeLog @@ -1,2 +1,3 @@ 0.01: Begin rewrite from old code. 0.02: Changed visuals: uA > mA, info order, battery state indication +0.03: Update app icon diff --git a/apps/denseclock/app-icon.js b/apps/denseclock/app-icon.js index 380a7b4ff..b8a0761f8 100644 --- a/apps/denseclock/app-icon.js +++ b/apps/denseclock/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mElwMBwf/AAeAAomYAomcAov4/E/w/jzngnEPg+AzninGOn+IznnnPOn+cCIIFBh4RBAoPPC4Xn/PP8efAo3jAoWPwAdCC4OB+AjC4BGEAEnH/ADBx/BGoN//0PwPx8E/AoOP/HnAoPPAoPmn0/ApHkn//5+DDoQFBEYPhAoX48YFE4/jAogvBAoWP8QFBFAKDBn0+geBwHwvwFBwYA=")) +require("heatshrink").decompress(atob("mEwwcBkmSpIC/AS0nwEHCh5yBggROgP4jgROh1ICKWT4Hkz0AC4NPgFypPgAQIRDyBLBCIMAiVAgECpAGBCInwn4RBg4dBoH/yV4j+ACI0Dz05kARB8gRJgARFgYRBgEB5IRKBwICCI4/8CIdJ/kCGoP+CIMPUIIRBkgRIYop9DgJHCPowDBTwUAyAREiSkBCITCOAX4CuwE5kmT4D1BBYSMByShBhwRCgEkWYQRDUIIRCUIWfEALXBCIsDCIMf+QICvEECIILBBAV5CIUcBAYRFpEEBYIRKnARIgFyHwfk+PAGogREgQIBPQMk+EACI9J/hrCyUHCIMHCJEnwAIByEBCIJrFCI/wWYIROwP5CIShECI7FBgjFDPoTFBgTXGBYICCCI6PDAX4C/ARoA=")) diff --git a/apps/denseclock/app.png b/apps/denseclock/app.png index e395fcf8dab8c375e49b2d5a3ee61ab18999aa49..4f27b473ca189d0d1457b960d08599b436dfa66d 100644 GIT binary patch delta 4103 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 IM6N<$f^!zRApigX diff --git a/apps/denseclock/metadata.json b/apps/denseclock/metadata.json index 515e4661c..c361313ff 100644 --- a/apps/denseclock/metadata.json +++ b/apps/denseclock/metadata.json @@ -1,7 +1,7 @@ { "id": "denseclock", "name": "Dense Clock", "shortName":"Dense Clock", - "version":"0.02", + "version":"0.03", "description": "A clockface dense with text-only information. Switches between showing seconds and minutes when unlocked/locked, in the interest of saving power.", "icon": "app.png", "type": "clock",