diff --git a/apps.json b/apps.json index 234d5b616..db8e2d92f 100644 --- a/apps.json +++ b/apps.json @@ -3083,9 +3083,10 @@ { "id": "kitchen", "name": "Kitchen Combo", "icon": "kitchen.png", - "version":"0.03", + "version":"0.04", "description": "Combination of the stepo, walkersclock, arrow and waypointer apps into a multiclock format. 'Everything but the kitchen sink'. Requires firmware v2.08.167 or later", "tags": "tool,outdoors,gps", + "type":"clock", "readme": "README.md", "interface":"waypoints.html", "storage": [ @@ -3093,6 +3094,7 @@ {"name":"stepo.kit.js","url":"stepo.kit.js"}, {"name":"gps.kit.js","url":"gps.kit.js"}, {"name":"digi.kit.js","url":"digi.kit.js"}, + {"name":"swatch.kit.js","url":"swatch.kit.js"}, {"name":"compass.kit.js","url":"compass.kit.js"}, {"name":"waypoints.json","url":"waypoints.json","evaluate":false}, {"name":"kitchen.img","url":"kitchen.icon.js","evaluate":true} diff --git a/apps/kitchen/ChangeLog b/apps/kitchen/ChangeLog index b3026a817..2bb3989da 100644 --- a/apps/kitchen/ChangeLog +++ b/apps/kitchen/ChangeLog @@ -1,3 +1,4 @@ 0.01: First version 0.02: compass disable BTN1,BTN2 while waiting for GPS to reach RUNNING status -0.03: Don't buzz for GPS fix in Quiet Mode \ No newline at end of file +0.03: Don't buzz for GPS fix in Quiet Mode +0.04: Added stopwatch face diff --git a/apps/kitchen/README.md b/apps/kitchen/README.md index 3312f4381..06e4a40ba 100644 --- a/apps/kitchen/README.md +++ b/apps/kitchen/README.md @@ -1,4 +1,4 @@ -# Kitchen Combo - a multiclock format of the waypointer, walksersclock, stopo and arrow apps. +# Kitchen Combo - a multiclock format of the waypointer, walksersclock, stepo and arrow apps. ![](screenshot_kitchen.jpg) @@ -14,14 +14,14 @@ Please refer to the section on calibration of the compass. This should be done each time the app is going to be used. The app has 4 faces that can quickly be switched from one to another. -* Stepo - a large font clock that dosplays the current steps in a doughnut guauge +* Stepo - a large font clock that displays the current steps in a doughnut gauge * GPS - when the GPS is on displays current grid ref, lat, lon, speed, altitude and course * Digi - a digital clock with day and date, displays battery and memory status (click BTN1) +* Swatch - a simple stopwatch that times in seconds, minutes and up to 999 hours, with lap times * Waypointer - a compass arrow that points to a selected waypoint when the GPS is on. - enables you to mark waypoints and cycle through a list of waypoints - shows distance and bearing to currently selected waypoint - ## Common buttons used to navigate through the app * BTN3 - short press, next app/clock face @@ -45,9 +45,9 @@ The following buttons depend on which face is currently in use ![](screenshot_stepo.jpg) - Displays the time in large font -- Display current step count in a doughnut guage -- Show step count in the middle of the doughnut guage -- The guage show percentage of steps out of a goal of 10000 steps +- Display current step count in a doughnut gauge +- Show step count in the middle of the doughnut gauge +- The gauge show percentage of steps out of a goal of 10000 steps - When the battery is less than 25% the doughnut turns red - Use BTN3 to switch to the next app @@ -64,6 +64,11 @@ The following buttons depend on which face is currently in use - Use BTN1 to switch between display of battery and memory %. - Use BTN3 to switch to the next app. +## Swatch +- A simple stopwatch +- BTN1 - start, stop +- BTN2 - lap if the timer is running, reset if the timer is stopped + ## Waypointer - Use BTN1 to select previous waypoint (when GPS is on) - Use BTN2 to select the next waypoint (when GPS is on) @@ -197,3 +202,9 @@ the correct direction heading or is not stable with respect to tilt and roll - redo the calibration by pressing *BTN3*. Calibration data is recorded in a storage file named `magnav.json`. +### Issues + +* GPS time display shows GMT and not BST, needs localising +* Occassional buzzing after 2-3 days of use, seems to disappear after + a reset to the launcher menu. Needs investigation +* Stopwatch display to hide hours count if elapsed time is less than 1 hour. diff --git a/apps/kitchen/compass.kit.js b/apps/kitchen/compass.kit.js index f8b2c9393..25bf5433f 100644 --- a/apps/kitchen/compass.kit.js +++ b/apps/kitchen/compass.kit.js @@ -21,7 +21,7 @@ //console.log(o); } - function init(gps) { + function init(gps,sw) { showMem("compass init() START"); gpsObject = gps; pal_by = new Uint16Array([0x0000,0xFFC0],0,1); // black, yellow diff --git a/apps/kitchen/digi.kit.js b/apps/kitchen/digi.kit.js index 1a64882a7..9689d5fd9 100644 --- a/apps/kitchen/digi.kit.js +++ b/apps/kitchen/digi.kit.js @@ -15,7 +15,7 @@ const Y_ACTIVITY = 116; const Y_MODELINE = 200; - function init(gps) { + function init(gps,sw) { showMem("digi init 1"); days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday","Friday", "Saturday"]; prevInfo = ""; diff --git a/apps/kitchen/gps.kit.js b/apps/kitchen/gps.kit.js index ad2dd0ee4..adebc1838 100644 --- a/apps/kitchen/gps.kit.js +++ b/apps/kitchen/gps.kit.js @@ -20,7 +20,7 @@ //console.log(o); } - function init(gps) { + function init(gps, sw) { log_debug("gps init"); //log_debug(gps); gpsObject = gps; diff --git a/apps/kitchen/kitchen.app.js b/apps/kitchen/kitchen.app.js index 84dccf6fa..5f2c4c046 100644 --- a/apps/kitchen/kitchen.app.js +++ b/apps/kitchen/kitchen.app.js @@ -26,7 +26,7 @@ function nextFace(){ g.clear(); g.reset(); - face.init(gpsObj); + face.init(gpsObj, swObj); startdraw(); } @@ -472,13 +472,185 @@ function to_map_ref(digits, easting, northing) { /***************************************************************************** -End of GPS object +Stopwatch Class Code ******************************************************************************/ +function STOPWATCH() { + this.tTotal = Date.now(); + this.tStart = Date.now(); + this.tCurrent = Date.now(); + this.running = false; + this.timeY = 45; + this.TtimeY = 75; + this.lapTimes = []; + this.displayInterval; + this.redrawButtons = true; + this.redrawLaps = true; +} + +STOPWATCH.prototype.log_debug = function(o) { + //console.log(o); +} + +STOPWATCH.prototype.timeToText = function(t) { + let hrs = Math.floor(t/3600000); + let mins = Math.floor(t/60000)%60; + let secs = Math.floor(t/1000)%60; + + let text = ("00"+hrs).substr(-3) + ":" + ("0"+mins).substr(-2) + ":" + ("0"+secs).substr(-2); + this.log_debug(text); + return text; +} + +STOPWATCH.prototype.getLapTimesArray = function() { + this.lapTimes.push(tCurrent-tTotal); + return this.lapTimes.map(timeToText).reverse(); +} + +STOPWATCH.prototype.stopStart = function() { + this.log_debug("stopStart()"); + this.running = !this.running; + + if (this.running) + this.tStart = Date.now() + this.tStart - this.tCurrent; + + this.tTotal = Date.now() + this.tTotal - this.tCurrent; + this.tCurrent = Date.now(); + this.redrawButtons = true; + this.redrawLaps = true; + + this.draw(); +} + +STOPWATCH.prototype.lap = function() { + this.log_debug("lap()"); + if (this.running) { + this.tCurrent = Date.now(); + this.lapTimes.unshift(this.tCurrent - this.tStart); + console.log(this.tCurrent - this.tStart); + } + + this.tStart = this.tCurrent; + this.redrawButtons = true; + this.redrawLaps = true; + this.draw(); +} + +STOPWATCH.prototype.reset = function() { + this.log_debug("reset()"); + if (this.running === false) { + this.tStart = this.tCurrent = this.tTotal = Date.now(); + this.lapTimes = []; + } + g.clear(); + this.draw(); +} + +// lap or reset +STOPWATCH.prototype.lapOrReset = function() { + this.redrawButtons = true; + this.redrawLaptimes = true; + + this.log_debug("lapReset()"); + if (this.running) + this.lap() + else + this.reset(); +} + +STOPWATCH.prototype.draw = function() { + if (this.running) this.tCurrent = Date.now(); + this.log_debug("draw()" + getTime()); + + g.setColor(1,1,1); + if (this.redrawButtons) this.drawButtons(); + this.drawTime(); + if (this.redrawLaps) this.drawLaptimes(); +} + +STOPWATCH.prototype.drawButtons = function() { + this.log_debug("drawButtons()"); + + g.clearRect(0,23,g.getWidth()-1,g.getHeight()-24); + g.setColor(1,1,1); + g.setFont("Vector", 20); + g.setFontAlign(0,0,3); + g.drawString(this.running? "STOP" : "GO", 230, 50); // BTN1 + g.drawString(this.running? "LAP" : "RESET", 230, 120); // BTN2 + this.redrawButtons = false; +} + +STOPWATCH.prototype.drawLaptimes = function() { + g.setFont("Vector",24); + g.setFontAlign(-1,-1); + g.clearRect(4, 205, 239, 229); // clear the last line of the lap times + + let laps = 0; + for (let i in this.lapTimes) { + g.drawString(this.lapTimes.length-i + ": " + this.timeToText(this.lapTimes[i]), 4, this.timeY + 40 + i*24); + if (++laps > 5) break; + } + this.redrawLaps = false; +} + +STOPWATCH.prototype.drawTime = function() { + this.log_debug("drawTime()"); + let t = this.tCurrent - this.tStart; + let Tt = this.tCurrent - this.tTotal; + + let txt = this.timeToText(t); + let Ttxt = this.timeToText(Tt); + + let x = 100; + let Tx = 125; + + // total time + g.setFont("Vector",38); + g.setFontAlign(0,0); + g.clearRect(0,this.timeY-21,200,this.timeY+21); + g.setColor(0xFFC0); + g.drawString(Ttxt,x,this.timeY); + + // current lap time + g.setFont("Vector", 20); + g.clearRect(0, this.TtimeY-7,200, this.TtimeY+7); + g.setColor(1,1,1); + g.drawString(txt,Tx, this.TtimeY); +} + +STOPWATCH.prototype.startTimer = function() { + this.log_debug("startTimer()"); + this.redrawButtons = true; + this.redrawLaps = true; + this.draw(); + this.displayInterval = setInterval(stopwatchDraw, 1000); +} + +STOPWATCH.prototype.stopTimer = function() { + this.log_debug("stopTimer()"); + if (this.displayInterval) { + clearInterval(this.displayInterval); + this.displayInterval = undefined; + } +} + +let swObj = new STOPWATCH(); + +function stopwatchDraw() { + swObj.draw(); +} + + +/***************************************************************************** + +Start App + +******************************************************************************/ + g.clear(); Bangle.loadWidgets(); -face.init(gpsObj); +face.init(gpsObj,swObj); startdraw(); setButtons(); diff --git a/apps/kitchen/stepo.kit.js b/apps/kitchen/stepo.kit.js index 9d7601e2a..068309072 100644 --- a/apps/kitchen/stepo.kit.js +++ b/apps/kitchen/stepo.kit.js @@ -5,7 +5,7 @@ var buf; var intervalRefSec; - function init(g) { + function init(g,sw) { showMem("stepo init 1"); pal4color = new Uint16Array([0x0000,0xFFFF,0x7BEF,0xAFE5],0,2); // b,w,grey,greenyellow pal4red = new Uint16Array([0x0000,0xFFFF,0xF800,0xAFE5],0,2); // b,w,red,greenyellow diff --git a/apps/kitchen/swatch.kit.js b/apps/kitchen/swatch.kit.js new file mode 100644 index 000000000..9f12b0af7 --- /dev/null +++ b/apps/kitchen/swatch.kit.js @@ -0,0 +1,59 @@ +(() => { + function getFace(){ + let swObject = undefined; + + function log_debug(o) { + //console.log(o); + } + + function init(gps, sw) { + showMem("swatch init 1"); + swObject = sw; + g.clear(); + showMem("swatch init 2"); + } + + function freeResources() { + showMem("swatch free 1"); + swObject = undefined; + showMem("swatch free 2"); + } + + function showMem(msg) { + var val = process.memory(); + var str = msg + " " + Math.round(val.usage*100/val.total) + "%"; + log_debug(str); + } + + function startTimer() { + log_debug("swObject.startTimer()"); + swObject.startTimer(); + } + + function stopTimer() { + log_debug("swObject.stopTimer()"); + swObject.stopTimer(); + } + + function onButtonShort(btn) { + switch (btn) { + case 1: + swObject.stopStart(); + break; + case 2: + swObject.lapOrReset(); + break; + case 3: + default: + return; + } + } + + function onButtonLong(btn) {} + + return {init:init, freeResources:freeResources, startTimer:startTimer, stopTimer:stopTimer, + onButtonShort:onButtonShort, onButtonLong:onButtonLong}; + } + + return getFace; +})();