You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

142 lines
3.2 KiB

const EventEmitter = require("events");
const createDriver = require("../drivers");
class Workout {
/**
* @param {import("../repositories/sqlite3")} repo
* @param {number} id
* @param {{
* id: string,
* name: string,
* driver: string,
* connect: string,
* maxLevel: number,
* }} bike
* @param {{
* id: number,
* name: string,
* cpm: number,
* warmupMin: number,
* warmupCpm: number,
* }} program
* @param {Date} date
*/
constructor(repo, id, bike, program, date) {
this.repo = repo;
this.id = id;
this.bike = bike;
this.program = program;
this.date = date;
this.driver = null;
this.offsetSeconds = 0;
this.offsets = {};
this.events = new EventEmitter();
}
async connect() {
this.driver = createDriver(this.bike.driver, this.bike.connect);
this.driver.events.on("workoutStatus", ws => this.handleworkoutStatus(ws));
return this.driver.connect();
}
start() {
return this.driver.start();
}
pause() {
return this.driver.pause();
}
stop() {
return this.driver.stop();
}
destroy() {
this.events.emit("destroy");
this.events.removeAllListeners();
if (this.driver != null) {
this.driver.destroy();
this.driver = null;
}
}
listMeasurements() {
return this.repo.listMeasurements(this.id);
}
handleworkoutStatus(ws) {
if (this.offsetSeconds > 0) {
const seconds = (ws.minutes * 60) + ws.seconds + this.offsetSeconds;
ws.minutes = Math.floor(seconds / 60);
ws.seconds = seconds % 60;
for (const key in this.offsets) {
if (!this.offsets.hasOwnProperty(key)) {
continue;
}
ws[key] += this.offsets[key];
}
}
this.repo.insertMeasurement({...ws, workoutId: this.id});
this.events.emit("workoutStatus", {...ws});
}
/**
* @param {import("../repositories/sqlite3")} repo
* @param {number} bikeId
* @param {number} programId
*/
static async create(repo, bikeId, programId) {
const bike = await repo.findBike(bikeId);
if (bike == null) {
throw new Error("bike not found");
}
const program = await repo.findProgram(programId);
if (program == null) {
throw new Error("program not found");
}
const date = new Date();
const id = await repo.insertWorkout({
bikeId: bike.id,
programId: program.id,
date: date,
});
return new Workout(repo, id, bike, program, date);
}
/**
* @param {import("../repositories/sqlite3")} repo
* @param {number} id
*/
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 workout = new Workout(repo, id, bike, program, new Date(data.date));
const list = await repo.listMeasurements(id);
if (list.length > 0) {
const last = list[list.length - 1];
workout.offsetSeconds = (last.minutes * 60 + last.seconds);
workout.offsets = {
distance: last.distance,
calories: last.calories,
}
}
return workout;
}
}
module.exports = Workout;