From 984f38d60c999f54c36955429e557beb746309fb Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Tue, 21 May 2024 21:04:33 +0100 Subject: [PATCH 1/5] runplus: only prompt to resume after a given duration --- apps/runplus/ChangeLog | 1 + apps/runplus/app.js | 8 ++++++-- apps/runplus/metadata.json | 2 +- apps/runplus/settings.js | 21 +++++++++++++++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/apps/runplus/ChangeLog b/apps/runplus/ChangeLog index 4016a2463..6506aace5 100644 --- a/apps/runplus/ChangeLog +++ b/apps/runplus/ChangeLog @@ -27,3 +27,4 @@ Write to correct settings file, fixing settings not working. 0.24: Add indicators for lock,gps and pulse to karvonen screen 0.25: Fix step count bug when runs are resumed after a long time 0.26: Add ability to zoom in on a single stat by tapping it +0.27: Allow configuration of time after which the user is prompted to resume diff --git a/apps/runplus/app.js b/apps/runplus/app.js index 3054ffa0c..ebdb0c51e 100644 --- a/apps/runplus/app.js +++ b/apps/runplus/app.js @@ -26,6 +26,10 @@ let settings = Object.assign({ B5: "step", B6: "caden", paceLength: 1000, + resume: { + promptAfter: 10000, + default: false, + }, notify: { dist: { value: 0, @@ -64,10 +68,10 @@ function onStartStop() { } var running = !exs.state.active; - var shouldResume = false; + var shouldResume = settings.resume.default; var promise = Promise.resolve(); - if (running && exs.state.duration > 10000) { // if more than 10 seconds of duration, ask if we should resume? + if (running && exs.state.duration > settings.resume.promptAfter) { // if more than N seconds of duration, ask if we should resume? promise = promise. then(() => { screen = "menu"; diff --git a/apps/runplus/metadata.json b/apps/runplus/metadata.json index 67e44cf2a..fe59050db 100644 --- a/apps/runplus/metadata.json +++ b/apps/runplus/metadata.json @@ -1,7 +1,7 @@ { "id": "runplus", "name": "Run+", - "version": "0.26", + "version": "0.27", "description": "Displays distance, time, steps, cadence, pace and more for runners. Based on the Run app, but extended with additional screens for heart rate interval training and individual stat focus.", "icon": "app.png", "tags": "run,running,fitness,outdoors,gps,karvonen,karvonnen", diff --git a/apps/runplus/settings.js b/apps/runplus/settings.js index 539391a27..0d8e48879 100644 --- a/apps/runplus/settings.js +++ b/apps/runplus/settings.js @@ -17,6 +17,10 @@ B5: "step", B6: "caden", paceLength: 1000, // TODO: Default to either 1km or 1mi based on locale + resume: { + promptAfter: 10000, + default: false, + }, notify: { dist: { increment: 0, @@ -76,6 +80,23 @@ '< Back': function() { E.showMenu(menu) }, } menu[/*LANG*/"Notifications"] = function() { E.showMenu(notificationsMenu)}; + var resumeMenu = { + "Prompt after": { + value : settings.resume.promptAfter / 1000, + onchange : v => { + settings.resume.promptAfter = v * 1000; + saveSettings(); + } + }, + "Resume by default": { + value : settings.resume.default, + onchange : v => { + settings.resume.default = v; + saveSettings(); + }, + }, + }; + menu[/*LANG*/"Resume"] = function() { E.showMenu(resumeMenu) }; ExStats.appendMenuItems(menu, settings, saveSettings); ExStats.appendNotifyMenuItems(notificationsMenu, settings, saveSettings); var vibPatterns = [/*LANG*/"Off", ".", "-", "--", "-.-", "---"]; From 020d26ddef7fb3f8166b1498e8e1b04d854af713 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Mon, 27 May 2024 23:05:21 +0100 Subject: [PATCH 2/5] runplus: update status depending on if in the pause window --- apps/runplus/app.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/apps/runplus/app.js b/apps/runplus/app.js index ebdb0c51e..241df013c 100644 --- a/apps/runplus/app.js +++ b/apps/runplus/app.js @@ -1,4 +1,5 @@ let runInterval; +let statusTimeout; let screen = "main"; // main | karvonen | menu | zoom // Run interface wrapped in a function const ExStats = require("exstats"); @@ -53,9 +54,15 @@ let statIDs = [settings.B1,settings.B2,settings.B3,settings.B4,settings.B5,setti let exs = ExStats.getStats(statIDs, settings); // --------------------------- +function inPauseWindow() { + return exs.state.duration <= settings.resume.promptAfter; +} + function setStatus(running) { - layout.button.label = running ? "STOP" : "START"; - layout.status.label = running ? "RUN" : "STOP"; + const paused = inPauseWindow(); + + layout.button.label = running ? "STOP" : paused ? "RESUME" : "START"; + layout.status.label = running ? "RUN" : paused ? "PAUSE" : "STOP"; layout.status.bgCol = running ? "#0f0" : "#f00"; if (screen === "main") layout.render(); } @@ -71,7 +78,7 @@ function onStartStop() { var shouldResume = settings.resume.default; var promise = Promise.resolve(); - if (running && exs.state.duration > settings.resume.promptAfter) { // if more than N seconds of duration, ask if we should resume? + if (running && !inPauseWindow()) { // if more than N seconds of duration, ask if we should resume? promise = promise. then(() => { screen = "menu"; @@ -107,6 +114,8 @@ function onStartStop() { } promise.then(() => { + if(statusTimeout) clearTimeout(statusTimeout); + if (running) { if (shouldResume) exs.resume(); @@ -114,6 +123,12 @@ function onStartStop() { exs.start(); } else { exs.stop(); + + // convert start/stop label when pause-window ends + statusTimeout = setTimeout(() => { + statusTimeout = undefined; + setStatus(running); + }, settings.resume.promptAfter); } // if stopping running, don't clear state // so we can at least refer to what we've done From 3be97f8d01107227f4cec760ca540a0dd478d230 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Tue, 28 May 2024 08:35:02 +0100 Subject: [PATCH 3/5] runplus: simpler always-resume toggle --- apps/runplus/ChangeLog | 2 +- apps/runplus/app.js | 28 +++++----------------------- apps/runplus/settings.js | 29 ++++++++--------------------- 3 files changed, 14 insertions(+), 45 deletions(-) diff --git a/apps/runplus/ChangeLog b/apps/runplus/ChangeLog index 6506aace5..645f6cf76 100644 --- a/apps/runplus/ChangeLog +++ b/apps/runplus/ChangeLog @@ -27,4 +27,4 @@ Write to correct settings file, fixing settings not working. 0.24: Add indicators for lock,gps and pulse to karvonen screen 0.25: Fix step count bug when runs are resumed after a long time 0.26: Add ability to zoom in on a single stat by tapping it -0.27: Allow configuration of time after which the user is prompted to resume +0.27: Allow setting to alway resume an activity diff --git a/apps/runplus/app.js b/apps/runplus/app.js index 241df013c..e83112219 100644 --- a/apps/runplus/app.js +++ b/apps/runplus/app.js @@ -1,5 +1,4 @@ let runInterval; -let statusTimeout; let screen = "main"; // main | karvonen | menu | zoom // Run interface wrapped in a function const ExStats = require("exstats"); @@ -27,10 +26,7 @@ let settings = Object.assign({ B5: "step", B6: "caden", paceLength: 1000, - resume: { - promptAfter: 10000, - default: false, - }, + alwaysResume: false, notify: { dist: { value: 0, @@ -54,15 +50,9 @@ let statIDs = [settings.B1,settings.B2,settings.B3,settings.B4,settings.B5,setti let exs = ExStats.getStats(statIDs, settings); // --------------------------- -function inPauseWindow() { - return exs.state.duration <= settings.resume.promptAfter; -} - function setStatus(running) { - const paused = inPauseWindow(); - - layout.button.label = running ? "STOP" : paused ? "RESUME" : "START"; - layout.status.label = running ? "RUN" : paused ? "PAUSE" : "STOP"; + layout.button.label = running ? "STOP" : "START"; + layout.status.label = running ? "RUN" : "STOP"; layout.status.bgCol = running ? "#0f0" : "#f00"; if (screen === "main") layout.render(); } @@ -75,10 +65,10 @@ function onStartStop() { } var running = !exs.state.active; - var shouldResume = settings.resume.default; + var shouldResume = settings.alwaysResume; var promise = Promise.resolve(); - if (running && !inPauseWindow()) { // if more than N seconds of duration, ask if we should resume? + if (!shouldResume && running && exs.state.duration > 10000) { // if more than 10 seconds of duration, ask if we should resume? promise = promise. then(() => { screen = "menu"; @@ -114,8 +104,6 @@ function onStartStop() { } promise.then(() => { - if(statusTimeout) clearTimeout(statusTimeout); - if (running) { if (shouldResume) exs.resume(); @@ -123,12 +111,6 @@ function onStartStop() { exs.start(); } else { exs.stop(); - - // convert start/stop label when pause-window ends - statusTimeout = setTimeout(() => { - statusTimeout = undefined; - setStatus(running); - }, settings.resume.promptAfter); } // if stopping running, don't clear state // so we can at least refer to what we've done diff --git a/apps/runplus/settings.js b/apps/runplus/settings.js index 0d8e48879..77343d6b3 100644 --- a/apps/runplus/settings.js +++ b/apps/runplus/settings.js @@ -17,10 +17,7 @@ B5: "step", B6: "caden", paceLength: 1000, // TODO: Default to either 1km or 1mi based on locale - resume: { - promptAfter: 10000, - default: false, - }, + alwaysResume: false, notify: { dist: { increment: 0, @@ -76,27 +73,17 @@ saveSettings(); } }; + menu[/*LANG*/"Always resume run"] = { + value : settings.alwaysResume, + onchange : v => { + settings.alwaysResume = v; + saveSettings(); + }, + }; var notificationsMenu = { '< Back': function() { E.showMenu(menu) }, } menu[/*LANG*/"Notifications"] = function() { E.showMenu(notificationsMenu)}; - var resumeMenu = { - "Prompt after": { - value : settings.resume.promptAfter / 1000, - onchange : v => { - settings.resume.promptAfter = v * 1000; - saveSettings(); - } - }, - "Resume by default": { - value : settings.resume.default, - onchange : v => { - settings.resume.default = v; - saveSettings(); - }, - }, - }; - menu[/*LANG*/"Resume"] = function() { E.showMenu(resumeMenu) }; ExStats.appendMenuItems(menu, settings, saveSettings); ExStats.appendNotifyMenuItems(notificationsMenu, settings, saveSettings); var vibPatterns = [/*LANG*/"Off", ".", "-", "--", "-.-", "---"]; From 8742e68e2e854e834e8a549da6810d6b2db4fda8 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 4 Jun 2024 10:15:00 +0100 Subject: [PATCH 4/5] cscsensor 0.12: Fix regression reporting cadence (reported per second when should be per minute) (fix #3434) --- apps/cscsensor/ChangeLog | 3 ++- apps/cscsensor/cscsensor.app.js | 2 +- apps/cscsensor/metadata.json | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/cscsensor/ChangeLog b/apps/cscsensor/ChangeLog index 8786e727c..77befcb3b 100644 --- a/apps/cscsensor/ChangeLog +++ b/apps/cscsensor/ChangeLog @@ -9,4 +9,5 @@ 0.08: Convert Yes/No On/Off in settings to checkboxes 0.09: Automatically reconnect on error 0.10: Fix cscsensor when using coospoo sensor that supports crank *and* wheel -0.11: Update to use blecsc library \ No newline at end of file +0.11: Update to use blecsc library +0.12: Fix regression reporting cadence (reported per second when should be per minute) (fix #3434) \ No newline at end of file diff --git a/apps/cscsensor/cscsensor.app.js b/apps/cscsensor/cscsensor.app.js index e86a40626..994c5b5a2 100644 --- a/apps/cscsensor/cscsensor.app.js +++ b/apps/cscsensor/cscsensor.app.js @@ -157,7 +157,7 @@ csc.on("data", e => { mySensor.movingTime += e.wdt; if (mySensor.speed>mySensor.maxSpeed && (mySensor.movingTime>3 || mySensor.speed<20) && mySensor.speed<50) mySensor.maxSpeed = mySensor.speed; - mySensor.cadence = e.crps; + mySensor.cadence = e.crps*60; mySensor.updateScreen(); mySensor.updateScreen(); }); diff --git a/apps/cscsensor/metadata.json b/apps/cscsensor/metadata.json index d3752bad5..56b186c44 100644 --- a/apps/cscsensor/metadata.json +++ b/apps/cscsensor/metadata.json @@ -2,7 +2,7 @@ "id": "cscsensor", "name": "Cycling speed sensor", "shortName": "CSCSensor", - "version": "0.11", + "version": "0.12", "description": "Read BLE enabled cycling speed and cadence sensor and display readings on watch", "icon": "icons8-cycling-48.png", "tags": "outdoors,exercise,ble,bluetooth,bike,cycle,bicycle", From 050cd914fa558f41c10ab66546e11a0f3d53cb67 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 4 Jun 2024 10:26:18 +0100 Subject: [PATCH 5/5] blecsc 0.04: Added support for <1 wheel/crank event/second (using idle counters) (ref #3434) --- apps/blecsc/ChangeLog | 3 ++- apps/blecsc/blecsc.js | 16 ++++++++++++++-- apps/blecsc/metadata.json | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/apps/blecsc/ChangeLog b/apps/blecsc/ChangeLog index 4efacaabf..847ef9834 100644 --- a/apps/blecsc/ChangeLog +++ b/apps/blecsc/ChangeLog @@ -1,3 +1,4 @@ 0.01: Initial version 0.02: Minor code improvements -0.03: Moved from cycling app, fixed connection issues and cadence \ No newline at end of file +0.03: Moved from cycling app, fixed connection issues and cadence +0.04: Added support for <1 wheel/crank event/second (using idle counters) (ref #3434) \ No newline at end of file diff --git a/apps/blecsc/blecsc.js b/apps/blecsc/blecsc.js index 0b2024fc1..9811bf21b 100644 --- a/apps/blecsc/blecsc.js +++ b/apps/blecsc/blecsc.js @@ -47,6 +47,8 @@ class BLECSC { this.kph = undefined; this.wrps = 0; // wheel revs per second this.crps = 0; // crank revs per second + this.widle = 0; // wheel idle counter + this.cidle = 0; // crank idle counter //this.batteryLevel = undefined; } @@ -117,7 +119,12 @@ class BLECSC { if (this.lastLwet === undefined) this.lastLwet = this.lwet; if (this.lwet < this.lastLwet) this.lastLwet -= 65536; let secs = (this.lwet - this.lastLwet) / 1024; - this.wrps = (this.cwr - this.lastCwr) / (secs?secs:1); + if (secs) + this.wrps = (this.cwr - this.lastCwr) / secs; + else { + if (this.widle<5) this.widle++; + else this.wrps = 0; + } this.kph = this.wrps * this.settings.circum / 3600; Object.assign(data, { // Notify the 'wheelEvent' handler cwr: this.cwr, // cumulative wheel revolutions @@ -138,7 +145,12 @@ class BLECSC { if (this.lastLcet === undefined) this.lastLcet = this.lcet; if (this.lcet < this.lastLcet) this.lastLcet -= 65536; let secs = (this.lcet - this.lastLcet) / 1024; - this.crps = (this.ccr - this.lastCcr) / (secs?secs:1); + if (secs) + this.crps = (this.ccr - this.lastCcr) / secs; + else { + if (this.cidle<5) this.cidle++; + else this.crps = 0; + } Object.assign(data, { // Notify the 'crankEvent' handler ccr: this.ccr, // cumulative crank revolutions lcet: this.lcet, // last crank event time diff --git a/apps/blecsc/metadata.json b/apps/blecsc/metadata.json index de8c76fec..a1cac0f4d 100644 --- a/apps/blecsc/metadata.json +++ b/apps/blecsc/metadata.json @@ -2,7 +2,7 @@ "id": "blecsc", "name": "BLE Cycling Speed Sensor Library", "shortName": "BLE CSC", - "version": "0.03", + "version": "0.04", "description": "Module to get live values from a BLE Cycle Speed (CSC) sensor. Includes recorder and clockinfo plugins", "icon": "icons8-cycling-48.png", "tags": "outdoors,exercise,ble,bluetooth,clkinfo",