*** cooldown ***
This commit is contained in:
+13
-3
@@ -31,9 +31,19 @@ module.exports = function programRouter(repo) {
|
|||||||
router.post("/", async(req, res) => {
|
router.post("/", async(req, res) => {
|
||||||
try {
|
try {
|
||||||
const {name, cpm, warmupMin, warmupCpm} = req.body;
|
const {name, cpm, warmupMin, warmupCpm} = req.body;
|
||||||
const id = await repo.insertProgram({name, cpm, warmupMin, warmupCpm})
|
|
||||||
|
const level = req.body.level || 18;
|
||||||
return res.status(200).json({id, name, cpm, warmupMin, warmupCpm});
|
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) {
|
} catch (err) {
|
||||||
return res.status(400).json({code: 400, message: err.message || err})
|
return res.status(400).json({code: 400, message: err.message || err})
|
||||||
}
|
}
|
||||||
|
|||||||
+46
-2
@@ -54,7 +54,8 @@ module.exports = function workoutRouter(repo) {
|
|||||||
bike: workout.bike,
|
bike: workout.bike,
|
||||||
program: workout.program,
|
program: workout.program,
|
||||||
date: workout.date,
|
date: workout.date,
|
||||||
...activeData(w.id),
|
cooldownMin: workout.cooldownMin,
|
||||||
|
...activeData(workout.id),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +77,11 @@ module.exports = function workoutRouter(repo) {
|
|||||||
if (measurements == null) {
|
if (measurements == null) {
|
||||||
return res.status(404).json({code: 404, message: "measurements not found"})
|
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);
|
return res.status(200).json(measurements);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -95,6 +101,7 @@ module.exports = function workoutRouter(repo) {
|
|||||||
bike: workout.bike,
|
bike: workout.bike,
|
||||||
program: workout.program,
|
program: workout.program,
|
||||||
date: workout.date,
|
date: workout.date,
|
||||||
|
cooldownMin: workout.cooldownMin,
|
||||||
...activeData(workout.id),
|
...activeData(workout.id),
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} 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) => {
|
router.post("/:id/continue", async(req, res) => {
|
||||||
let workout = workouts.find(w => w.id == req.params.id);
|
let workout = workouts.find(w => w.id == req.params.id);
|
||||||
if (workout != null) {
|
if (workout != null) {
|
||||||
@@ -117,7 +149,8 @@ module.exports = function workoutRouter(repo) {
|
|||||||
bike: workout.bike,
|
bike: workout.bike,
|
||||||
program: workout.program,
|
program: workout.program,
|
||||||
date: workout.date,
|
date: workout.date,
|
||||||
...activeData(w.id),
|
cooldownMin: workout.cooldownMin,
|
||||||
|
...activeData(workout.id),
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return res.status(400).json({code: 400, message: err.message || err})
|
return res.status(400).json({code: 400, message: err.message || err})
|
||||||
@@ -137,6 +170,7 @@ module.exports = function workoutRouter(repo) {
|
|||||||
bike: workout.bike,
|
bike: workout.bike,
|
||||||
program: workout.program,
|
program: workout.program,
|
||||||
date: workout.date,
|
date: workout.date,
|
||||||
|
cooldownMin: workout.cooldownMin,
|
||||||
...activeData(workout.id),
|
...activeData(workout.id),
|
||||||
});
|
});
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
@@ -157,6 +191,7 @@ module.exports = function workoutRouter(repo) {
|
|||||||
bike: workout.bike,
|
bike: workout.bike,
|
||||||
program: workout.program,
|
program: workout.program,
|
||||||
date: workout.date,
|
date: workout.date,
|
||||||
|
cooldownMin: workout.cooldownMin,
|
||||||
...activeData(workout.id),
|
...activeData(workout.id),
|
||||||
});
|
});
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
@@ -177,6 +212,7 @@ module.exports = function workoutRouter(repo) {
|
|||||||
bike: workout.bike,
|
bike: workout.bike,
|
||||||
program: workout.program,
|
program: workout.program,
|
||||||
date: workout.date,
|
date: workout.date,
|
||||||
|
cooldownMin: workout.cooldownMin,
|
||||||
...activeData(workout.id),
|
...activeData(workout.id),
|
||||||
});
|
});
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
@@ -203,6 +239,7 @@ module.exports = function workoutRouter(repo) {
|
|||||||
bike: workout.bike,
|
bike: workout.bike,
|
||||||
program: workout.program,
|
program: workout.program,
|
||||||
date: workout.date,
|
date: workout.date,
|
||||||
|
cooldownMin: workout.cooldownMin,
|
||||||
...activeData(workout.id),
|
...activeData(workout.id),
|
||||||
});
|
});
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
@@ -229,6 +266,7 @@ module.exports = function workoutRouter(repo) {
|
|||||||
bike: workout.bike,
|
bike: workout.bike,
|
||||||
program: workout.program,
|
program: workout.program,
|
||||||
date: workout.date,
|
date: workout.date,
|
||||||
|
cooldownMin: workout.cooldownMin,
|
||||||
...activeData(workout.id),
|
...activeData(workout.id),
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -267,10 +305,15 @@ module.exports = function workoutRouter(repo) {
|
|||||||
}
|
}
|
||||||
workout.events.on("state", onState);
|
workout.events.on("state", onState);
|
||||||
|
|
||||||
|
const onCooldownMin = (cooldownMin) => {
|
||||||
|
ws.send(JSON.stringify({cooldownMin}))
|
||||||
|
}
|
||||||
|
workout.events.on("cooldownMin", onCooldownMin);
|
||||||
|
|
||||||
ws.onclose = () => {
|
ws.onclose = () => {
|
||||||
workout.events.removeListener("workoutStatus", onWorkoutStatus);
|
workout.events.removeListener("workoutStatus", onWorkoutStatus);
|
||||||
workout.events.removeListener("state", onState);
|
workout.events.removeListener("state", onState);
|
||||||
|
workout.events.removeListener("cooldownMin", onCooldownMin);
|
||||||
ws.removeAllListeners();
|
ws.removeAllListeners();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -281,6 +324,7 @@ module.exports = function workoutRouter(repo) {
|
|||||||
bike: workout.bike,
|
bike: workout.bike,
|
||||||
program: workout.program,
|
program: workout.program,
|
||||||
date: workout.date,
|
date: workout.date,
|
||||||
|
cooldownMin: workout.cooldownMin,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -139,8 +139,15 @@ class SQLite3Repository {
|
|||||||
return this.delete(bike, "bike", "id");
|
return this.delete(bike, "bike", "id");
|
||||||
}
|
}
|
||||||
|
|
||||||
findProgram(id) {
|
async findProgram(id) {
|
||||||
return this.findOne("program", {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() {
|
listPrograms() {
|
||||||
@@ -148,7 +155,7 @@ class SQLite3Repository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
insertProgram(program) {
|
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) {
|
updateProgram(program) {
|
||||||
@@ -168,7 +175,11 @@ class SQLite3Repository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
insertWorkout(workout) {
|
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) {
|
deleteWorkout(workout) {
|
||||||
@@ -211,8 +222,12 @@ const SQL_TABLE_PROGRAM = `
|
|||||||
id CHAR(32) PRIMARY KEY,
|
id CHAR(32) PRIMARY KEY,
|
||||||
name VARCHAR(255) NOT NULL,
|
name VARCHAR(255) NOT NULL,
|
||||||
cpm INT NOT NULL,
|
cpm INT NOT NULL,
|
||||||
|
level INT NOT NULL,
|
||||||
warmupMin 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,
|
id CHAR(32) PRIMARY KEY,
|
||||||
bikeId INT NOT NULL,
|
bikeId INT NOT NULL,
|
||||||
programId INT NOT NULL,
|
programId INT NOT NULL,
|
||||||
date DATETIME NOT NULL
|
date DATETIME NOT NULL,
|
||||||
|
cooldownMin INT NOT NULL
|
||||||
);
|
);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
+24
-1
@@ -16,8 +16,12 @@ class Workout {
|
|||||||
* id: number,
|
* id: number,
|
||||||
* name: string,
|
* name: string,
|
||||||
* cpm: number,
|
* cpm: number,
|
||||||
|
* level: number,
|
||||||
* warmupMin: number,
|
* warmupMin: number,
|
||||||
* warmupCpm: number,
|
* warmupCpm: number,
|
||||||
|
* warmupLevel: number,
|
||||||
|
* cooldownCpm: number,
|
||||||
|
* cooldownLevel: number,
|
||||||
* }} program
|
* }} program
|
||||||
* @param {Date} date
|
* @param {Date} date
|
||||||
*/
|
*/
|
||||||
@@ -32,6 +36,7 @@ class Workout {
|
|||||||
this.state = "disconnected";
|
this.state = "disconnected";
|
||||||
|
|
||||||
this.offsetSeconds = 0;
|
this.offsetSeconds = 0;
|
||||||
|
this.cooldownMin = -1;
|
||||||
this.offsets = {};
|
this.offsets = {};
|
||||||
|
|
||||||
this.events = new EventEmitter();
|
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.repo.insertMeasurement({...ws, workoutId: this.id});
|
||||||
|
|
||||||
this.events.emit("workoutStatus", {...ws});
|
this.events.emit("workoutStatus", {...ws});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setCooldownMin(min) {
|
||||||
|
this.cooldownMin = min;
|
||||||
|
this.events.emit("cooldownMin", min);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("../repositories/sqlite3")} repo
|
* @param {import("../repositories/sqlite3")} repo
|
||||||
* @param {number} bikeId
|
* @param {number} bikeId
|
||||||
@@ -146,6 +167,7 @@ class Workout {
|
|||||||
bikeId: bike.id,
|
bikeId: bike.id,
|
||||||
programId: program.id,
|
programId: program.id,
|
||||||
date: date,
|
date: date,
|
||||||
|
cooldownMin: -1,
|
||||||
});
|
});
|
||||||
|
|
||||||
return new Workout(repo, id, bike, program, date);
|
return new Workout(repo, id, bike, program, date);
|
||||||
@@ -158,9 +180,10 @@ class Workout {
|
|||||||
static async continue(repo, id) {
|
static async continue(repo, id) {
|
||||||
const data = await repo.findWorkout(id);
|
const data = await repo.findWorkout(id);
|
||||||
const bike = await repo.findBike(data.bikeId);
|
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));
|
const workout = new Workout(repo, id, bike, program, new Date(data.date));
|
||||||
|
workout.cooldownMin = data.cooldownMin;
|
||||||
|
|
||||||
const list = await repo.listMeasurements(id);
|
const list = await repo.listMeasurements(id);
|
||||||
if (list.length > 0) {
|
if (list.length > 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user