From cb141a012bda3e1de112467e54d0bbe4bb745db7 Mon Sep 17 00:00:00 2001 From: Gisle Aune Date: Sat, 16 Nov 2019 12:35:19 +0100 Subject: [PATCH] *** cooldown *** --- src/api/program.js | 16 ++++++++++--- src/api/workout.js | 48 +++++++++++++++++++++++++++++++++++-- src/repositories/sqlite3.js | 28 +++++++++++++++++----- src/systems/workout.js | 25 ++++++++++++++++++- 4 files changed, 105 insertions(+), 12 deletions(-) diff --git a/src/api/program.js b/src/api/program.js index e998f81..e6c1127 100644 --- a/src/api/program.js +++ b/src/api/program.js @@ -31,9 +31,19 @@ module.exports = function programRouter(repo) { router.post("/", async(req, res) => { try { const {name, cpm, warmupMin, warmupCpm} = req.body; - const id = await repo.insertProgram({name, cpm, warmupMin, warmupCpm}) - - return res.status(200).json({id, name, cpm, warmupMin, warmupCpm}); + + const level = req.body.level || 18; + const warmupLevel = req.body.warmupLevel || level; + const cooldownCpm = req.body.cooldownCpm || cpm; + const cooldownLevel = req.body.cooldownLevel || warmupLevel; + + const data = {name, cpm, warmupMin, warmupCpm, level, warmupLevel, cooldownCpm, cooldownLevel}; + + const id = await repo.insertProgram(data) + + return res.status(200).json( + {id, ...data} + ); } catch (err) { return res.status(400).json({code: 400, message: err.message || err}) } diff --git a/src/api/workout.js b/src/api/workout.js index 1b4133b..504ab05 100644 --- a/src/api/workout.js +++ b/src/api/workout.js @@ -54,7 +54,8 @@ module.exports = function workoutRouter(repo) { bike: workout.bike, program: workout.program, date: workout.date, - ...activeData(w.id), + cooldownMin: workout.cooldownMin, + ...activeData(workout.id), }); } @@ -76,6 +77,11 @@ module.exports = function workoutRouter(repo) { if (measurements == null) { return res.status(404).json({code: 404, message: "measurements not found"}) } + + for (const measurement of measurements) { + delete measurement.id; + delete measurement.workoutId; + } return res.status(200).json(measurements); } catch (err) { @@ -95,6 +101,7 @@ module.exports = function workoutRouter(repo) { bike: workout.bike, program: workout.program, date: workout.date, + cooldownMin: workout.cooldownMin, ...activeData(workout.id), }); } catch (err) { @@ -102,6 +109,31 @@ module.exports = function workoutRouter(repo) { } }); + router.put("/:id", async(req, res) => { + let workout = workouts.find(w => w.id == req.params.id); + if (workout == null) { + return res.status(404).json({code: 404, message: "Workout not found or inactive."}) + } + + try { + if (req.body.cooldownMin) { + workout.setCooldownMin(req.body.cooldownMin); + await repo.updateWorkout(workout) + } + + return res.status(200).json({ + id: workout.id, + bike: workout.bike, + program: workout.program, + date: workout.date, + cooldownMin: workout.cooldownMin, + ...activeData(workout.id), + }); + } catch (err) { + return res.status(400).json({code: 400, message: err.message || err}) + } + }); + router.post("/:id/continue", async(req, res) => { let workout = workouts.find(w => w.id == req.params.id); if (workout != null) { @@ -117,7 +149,8 @@ module.exports = function workoutRouter(repo) { bike: workout.bike, program: workout.program, date: workout.date, - ...activeData(w.id), + cooldownMin: workout.cooldownMin, + ...activeData(workout.id), }); } catch (err) { return res.status(400).json({code: 400, message: err.message || err}) @@ -137,6 +170,7 @@ module.exports = function workoutRouter(repo) { bike: workout.bike, program: workout.program, date: workout.date, + cooldownMin: workout.cooldownMin, ...activeData(workout.id), }); } catch(err) { @@ -157,6 +191,7 @@ module.exports = function workoutRouter(repo) { bike: workout.bike, program: workout.program, date: workout.date, + cooldownMin: workout.cooldownMin, ...activeData(workout.id), }); } catch(err) { @@ -177,6 +212,7 @@ module.exports = function workoutRouter(repo) { bike: workout.bike, program: workout.program, date: workout.date, + cooldownMin: workout.cooldownMin, ...activeData(workout.id), }); } catch(err) { @@ -203,6 +239,7 @@ module.exports = function workoutRouter(repo) { bike: workout.bike, program: workout.program, date: workout.date, + cooldownMin: workout.cooldownMin, ...activeData(workout.id), }); } catch(err) { @@ -229,6 +266,7 @@ module.exports = function workoutRouter(repo) { bike: workout.bike, program: workout.program, date: workout.date, + cooldownMin: workout.cooldownMin, ...activeData(workout.id), }); } catch (err) { @@ -267,10 +305,15 @@ module.exports = function workoutRouter(repo) { } workout.events.on("state", onState); + const onCooldownMin = (cooldownMin) => { + ws.send(JSON.stringify({cooldownMin})) + } + workout.events.on("cooldownMin", onCooldownMin); ws.onclose = () => { workout.events.removeListener("workoutStatus", onWorkoutStatus); workout.events.removeListener("state", onState); + workout.events.removeListener("cooldownMin", onCooldownMin); ws.removeAllListeners(); }; @@ -281,6 +324,7 @@ module.exports = function workoutRouter(repo) { bike: workout.bike, program: workout.program, date: workout.date, + cooldownMin: workout.cooldownMin, }, })); }) diff --git a/src/repositories/sqlite3.js b/src/repositories/sqlite3.js index 3a7f258..af27e72 100644 --- a/src/repositories/sqlite3.js +++ b/src/repositories/sqlite3.js @@ -139,8 +139,15 @@ class SQLite3Repository { return this.delete(bike, "bike", "id"); } - findProgram(id) { - return this.findOne("program", {id}); + async findProgram(id) { + const program = await this.findOne("program", {id}); + + program.level = program.level || 18; + program.warmupLevel = program.warmupLevel || program.level; + program.cooldownCpm = program.cooldownCpm || program.cpm; + program.cooldownLevel = program.cooldownLevel || program.level; + + return program; } listPrograms() { @@ -148,7 +155,7 @@ class SQLite3Repository { } insertProgram(program) { - return this.insert(program, "program", ["name", "cpm", "warmupMin", "warmupCpm"]); + return this.insert(program, "program", ["name", "cpm", "warmupMin", "warmupCpm", "level", "warmupLevel", "cooldownCpm", "cooldownLevel"]); } updateProgram(program) { @@ -168,7 +175,11 @@ class SQLite3Repository { } insertWorkout(workout) { - return this.insert(workout, "workout", ["bikeId","programId","date"]); + return this.insert(workout, "workout", ["bikeId","programId","date","cooldownMin"]); + } + + updateWorkout(workout) { + return this.update(workout, "workout", "id", ["cooldownMin"]); } deleteWorkout(workout) { @@ -211,8 +222,12 @@ const SQL_TABLE_PROGRAM = ` id CHAR(32) PRIMARY KEY, name VARCHAR(255) NOT NULL, cpm INT NOT NULL, + level INT NOT NULL, warmupMin INT NOT NULL, - warmupCpm INT NOT NULL + warmupCpm INT NOT NULL, + warmupLevel INT NOT NULL, + cooldownCpm INT NOT NULL, + cooldownLevel INT NOT NULL ); `; @@ -221,7 +236,8 @@ const SQL_TABLE_WORKOUT = ` id CHAR(32) PRIMARY KEY, bikeId INT NOT NULL, programId INT NOT NULL, - date DATETIME NOT NULL + date DATETIME NOT NULL, + cooldownMin INT NOT NULL ); `; diff --git a/src/systems/workout.js b/src/systems/workout.js index 2092fdb..e4e82e4 100644 --- a/src/systems/workout.js +++ b/src/systems/workout.js @@ -16,8 +16,12 @@ class Workout { * id: number, * name: string, * cpm: number, + * level: number, * warmupMin: number, * warmupCpm: number, + * warmupLevel: number, + * cooldownCpm: number, + * cooldownLevel: number, * }} program * @param {Date} date */ @@ -32,6 +36,7 @@ class Workout { this.state = "disconnected"; this.offsetSeconds = 0; + this.cooldownMin = -1; this.offsets = {}; this.events = new EventEmitter(); @@ -121,11 +126,27 @@ class Workout { } } + // Steer the level + let targetLevel = this.program.level; + if (this.cooldownMin > -1 && ws.minutes >= this.cooldownMin) { + targetLevel = this.program.cooldownLevel; + } else if (this.program.warmupMin > ws.minutes) { + targetLevel = this.program.warmupLevel; + } + if (targetLevel !== ws.level) { + this.driver.setLevel(targetLevel); + } + this.repo.insertMeasurement({...ws, workoutId: this.id}); this.events.emit("workoutStatus", {...ws}); } + setCooldownMin(min) { + this.cooldownMin = min; + this.events.emit("cooldownMin", min); + } + /** * @param {import("../repositories/sqlite3")} repo * @param {number} bikeId @@ -146,6 +167,7 @@ class Workout { bikeId: bike.id, programId: program.id, date: date, + cooldownMin: -1, }); return new Workout(repo, id, bike, program, date); @@ -158,9 +180,10 @@ class Workout { static async continue(repo, id) { const data = await repo.findWorkout(id); const bike = await repo.findBike(data.bikeId); - const program = await repo.findWorkout(data.workoutId); + const program = await repo.findProgram(data.programId); const workout = new Workout(repo, id, bike, program, new Date(data.date)); + workout.cooldownMin = data.cooldownMin; const list = await repo.listMeasurements(id); if (list.length > 0) {