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.
		
		
		
		
		
			
		
			
				
					
					
						
							135 lines
						
					
					
						
							3.0 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							135 lines
						
					
					
						
							3.0 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.driver.events.on("workoutState", ws => this.handleWorkoutState(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);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  handleWorkoutState(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("workoutState", ws);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /**
							 | 
						|
								   * @param {import("../repositories/sqlite3")} repo
							 | 
						|
								   * @param {number} bikeId 
							 | 
						|
								   * @param {number} programId 
							 | 
						|
								   */
							 | 
						|
								  static async create(repo, bikeId, programId) {
							 | 
						|
								    const bike = await repo.findBike(bikeId);
							 | 
						|
								    const program = await repo.findProgram(programId);
							 | 
						|
								    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, parseInt(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;
							 |