diff --git a/apps/openstmap/ChangeLog b/apps/openstmap/ChangeLog index a256b459c..d8ab55482 100644 --- a/apps/openstmap/ChangeLog +++ b/apps/openstmap/ChangeLog @@ -17,3 +17,5 @@ Satellite count moved to widget bar to leave more room for the map 0.15: Make track drawing an option (default off) 0.16: Draw waypoints, too. +0.17: With new Recorder app allow track to be drawn in the background + Switch tile layer URL for faster/more reliable map tiles \ No newline at end of file diff --git a/apps/openstmap/app.js b/apps/openstmap/app.js index a5130d23e..c69ccece3 100644 --- a/apps/openstmap/app.js +++ b/apps/openstmap/app.js @@ -5,6 +5,7 @@ var fix = {}; var mapVisible = false; var hasScrolled = false; var settings = require("Storage").readJSON("openstmap.json",1)||{}; +var plotTrack; // Redraw the whole page function redraw() { @@ -20,7 +21,9 @@ function redraw() { } if (HASWIDGETS && WIDGETS["recorder"] && WIDGETS["recorder"].plotTrack) { g.setColor("#f00").flip(); // force immediate draw on double-buffered screens - track will update later - WIDGETS["recorder"].plotTrack(m); + plotTrack = WIDGETS["recorder"].plotTrack(m, { async : true, callback : function() { + plotTrack = undefined; + }}); } } g.setClipRect(0,0,g.getWidth()-1,g.getHeight()-1); @@ -79,6 +82,7 @@ function showMap() { g.reset().clearRect(R); redraw(); Bangle.setUI({mode:"custom",drag:e=>{ + if (plotTrack && plotTrack.stop) plotTrack.stop(); if (e.b) { g.setClipRect(R.x,R.y,R.x2,R.y2); g.scroll(e.dx,e.dy); @@ -90,6 +94,7 @@ function showMap() { redraw(); } }, btn: btn=>{ + if (plotTrack && plotTrack.stop) plotTrack.stop(); mapVisible = false; var menu = {"":{title:"Map"}, "< Back": ()=> showMap(), diff --git a/apps/openstmap/interface.html b/apps/openstmap/interface.html index 0bf2268a4..ba1246d9f 100644 --- a/apps/openstmap/interface.html +++ b/apps/openstmap/interface.html @@ -87,8 +87,8 @@ TODO: However some don't allow cross-origin use */ //var TILELAYER = 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png'; // simple, high contrast, TOO SLOW //var TILELAYER = 'http://a.tile.stamen.com/toner/{z}/{x}/{y}.png'; // black and white - var TILELAYER = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'; - var PREVIEWTILELAYER = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'; + var TILELAYER = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'; + var PREVIEWTILELAYER = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'; var loadedMaps = []; diff --git a/apps/openstmap/metadata.json b/apps/openstmap/metadata.json index 4419cd411..97bc7cc05 100644 --- a/apps/openstmap/metadata.json +++ b/apps/openstmap/metadata.json @@ -2,7 +2,7 @@ "id": "openstmap", "name": "OpenStreetMap", "shortName": "OpenStMap", - "version": "0.16", + "version": "0.17", "description": "Loads map tiles from OpenStreetMap onto your Bangle.js and displays a map of where you are. Once installed this also adds map functionality to `GPS Recorder` and `Recorder` apps", "readme": "README.md", "icon": "app.png", diff --git a/apps/recorder/ChangeLog b/apps/recorder/ChangeLog index c3e20ed34..5f1b7a492 100644 --- a/apps/recorder/ChangeLog +++ b/apps/recorder/ChangeLog @@ -26,3 +26,6 @@ 0.20: Automatic translation of some more strings. 0.21: Speed report now uses speed units from locale 0.22: Convert Yes/No On/Off in settings to checkboxes +0.23: Add graphing for HRM, fix some other graphs + Altitude graphing now uses barometer altitude if it exists + plotTrack in widget allows track to be drawn in the background (doesn't block execution) \ No newline at end of file diff --git a/apps/recorder/README.md b/apps/recorder/README.md index 87be34424..34955b986 100644 --- a/apps/recorder/README.md +++ b/apps/recorder/README.md @@ -20,10 +20,29 @@ You can record * **BAT** Battery percentage and voltage * **Core** CoreTemp body temperature +You can then start/stop recording from the Recorder app itself (and as long as widgets are +enabled in the app you're using, you can move to another app and continue recording). +Some apps like the [Run app](https://banglejs.com/apps/?id=run) are able to automatically start/stop the Recorder too. + **Note:** It is possible for other apps to record information using this app as well. They need to define a `foobar.recorder.js` file - see the `getRecorders` function in `widget.js` for more information. +## Graphing + +You can download the information to the PC using [the App Loader](https://banglejs.com/apps/?id=recorder). Connect +to your Bangle, then in `My Apps` click the disk icon next to the `Recorder` app to download data. + +You can also view some information on the watch. + +* Tap `View Tracks` +* Tap on the Track number you're interested in, and you'll see a page with information about that track... + * `Plot Map` plots a map using GPS coordinates + * `Plot OpenStMap` plots a map using GPS coordinates on top of an OpenStreetMap map (if the app is installed) + * `Plot Alt` plots altitude over time + * `Plot Speed` plots speed over time + * `Plot HRM` plots heart rate over time + ## Tips When recording GPS, it usually takes several minutes for the watch to get a [GPS fix](https://en.wikipedia.org/wiki/Time_to_first_fix). There is a red satellite symbol, which you will see turn green when you get an actual GPS Fix. You can [upload assistant files](https://banglejs.com/apps/#assisted%20gps%20update) to speed up the time spent on getting a GPS fix. diff --git a/apps/recorder/app.js b/apps/recorder/app.js index 972a9580d..9e9b58f78 100644 --- a/apps/recorder/app.js +++ b/apps/recorder/app.js @@ -60,9 +60,9 @@ function showMainMenu() { setTimeout(function() { E.showMenu(); WIDGETS["recorder"].setRecording(v).then(function() { - print(/*LANG*/"Complete"); + //print("Record start Complete"); loadSettings(); - print(settings.recording); + print("Recording: "+settings.recording); showMainMenu(); }); }, 1); @@ -185,7 +185,7 @@ function viewTrack(filename, info) { '': { 'title': /*LANG*/'Track '+info.fn } }; if (info.time) - menu[info.time.toISOString().substr(0,16).replace("T"," ")] = function(){}; + menu[info.time.toISOString().substr(0,16).replace("T"," ")] = {}; menu["Duration"] = { value : asTime(info.duration)}; menu["Records"] = { value : ""+info.records }; if (info.fields.includes("Latitude")) @@ -198,7 +198,8 @@ function viewTrack(filename, info) { info.qOSTM = true; plotTrack(info); } - if (info.fields.includes("Altitude")) + if (info.fields.includes("Altitude") || + info.fields.includes("Barometer Altitude")) menu[/*LANG*/'Plot Alt.'] = function() { plotGraph(info, "Altitude"); }; @@ -206,6 +207,10 @@ function viewTrack(filename, info) { menu[/*LANG*/'Plot Speed'] = function() { plotGraph(info, "Speed"); }; + if (info.fields.includes("Heartrate")) + menu[/*LANG*/'Plot HRM'] = function() { + plotGraph(info, "Heartrate"); + }; // TODO: steps, heart rate? menu[/*LANG*/'Erase'] = function() { E.showPrompt(/*LANG*/"Delete Track?").then(function(v) { @@ -331,14 +336,26 @@ function viewTrack(filename, info) { var l = f.readLine(f); l = f.readLine(f); // skip headers var nl = 0, c, i; + var factor = 1; // multiplier used for values when graphing var timeIdx = info.fields.indexOf("Time"); if (l!==undefined) { c = l.split(","); strt = c[timeIdx]; } - if (style=="Altitude") { - title = /*LANG*/"Altitude (m)"; - var altIdx = info.fields.indexOf("Altitude"); + if (style=="Heartrate") { + title = /*LANG*/"Heartrate (bpm)"; + var hrmIdx = info.fields.indexOf("Heartrate"); + while(l!==undefined) { + ++nl;c=l.split(",");l = f.readLine(f); + if (c[hrmIdx]=="") continue; + i = Math.round(80*(c[timeIdx] - strt)/dur); + infn[i]+=+c[hrmIdx]; + infc[i]++; + } + } else if (style=="Altitude") { + title = /*LANG*/"Altitude (m)"; + var altIdx = info.fields.indexOf("Barometer Altitude"); + if (altIdx<0) altIdx = info.fields.indexOf("Altitude"); while(l!==undefined) { ++nl;c=l.split(",");l = f.readLine(f); if (c[altIdx]=="") continue; @@ -350,7 +367,7 @@ function viewTrack(filename, info) { // use locate to work out units var localeStr = require("locale").speed(1,5); // get what 1kph equates to let units = localeStr.replace(/[0-9.]*/,""); - var factor = parseFloat(localeStr)*3.6; // m/sec to whatever out units are + factor = parseFloat(localeStr)*3.6; // m/sec to whatever out units are // title title = /*LANG*/"Speed"+` (${units})`; var latIdx = info.fields.indexOf("Latitude"); @@ -386,6 +403,10 @@ function viewTrack(filename, info) { var min=100000,max=-100000; for (var i=0;i0) infn[i]=factor*infn[i]/infc[i]; + else { // no data - search back and see if we can find something + for (var j=i-1;j>=0;j--) + if (infc[j]) { infn[i]=infn[j]; break; } + } var n = infn[i]; if (n>max) max=n; if (n