make things work, hopefully.

This commit is contained in:
2019-10-30 20:07:39 +01:00
parent 2932123c38
commit 8d7f7fca16
6 changed files with 109 additions and 10 deletions
+67
View File
@@ -0,0 +1,67 @@
const Client = require("iconsole-bike-client");
const _ = require("underscore");
class IConsoleDriver {
constructor(connect) {
this.connectString = connect;
this.client = null;
this.maxLevel = 24;
this.lastLevel = 18;
this.workoutState = {};
}
async connect() {
this.client = await Client.scan(this.connectString, 15000)
this.client.events.on("maxLevel", ({maxLevel}) => {
this.maxLevel = maxLevel;
this.events.emit("maxLevel", maxLevel);
});
this.client.events.on("workoutState", ({workoutState}) => {
this.workoutState = workoutState;
if (!_.isEqual(this.workoutState, workoutState)) {
this.workoutState = {...workoutState};
this.events.emit("workoutState", {...workoutState});
}
});
}
async start() {
await this.client.start({level: this.lastLevel});
}
async pause() {
await this.client.pause();
}
async resume() {
await this.client.resume();
}
async stop() {
await this.client.pause();
}
async setLevel(n) {
if (n < 0 || n > this.maxLevel) {
return Promise.reject(new Error(`Level is out of range (0 - ${this.maxLevel})`))
}
this.lastLevel = n;
return await this.client.setLevel(n);
}
destroy() {
this.stop();
this.client.disconnect();
this.events.emit("destroy");
this.events.removeAllListeners();
}
}
module.exports = IConsoleDriver;
+5 -2
View File
@@ -1,9 +1,12 @@
const MockDriver = require("./mock"); const MockDriver = require("./mock");
const IConsoleDriver = require("./iconsole");
module.exports = function createDriver(name) { module.exports = function createDriver(name, connect) {
switch (name) { switch (name) {
case "mock": case "mock":
return new MockDriver(); return new MockDriver(connect);
case "iconsole":
return new IConsoleDriver(connect);
default: default:
throw new Error(`Driver ${name} doesn't exist!`) throw new Error(`Driver ${name} doesn't exist!`)
} }
+6
View File
@@ -23,6 +23,10 @@ class MockDriver {
} }
connect() { connect() {
setTimeout(() => {
this.events.emit("maxLevel", 32);
})
return Promise.resolve(); return Promise.resolve();
} }
@@ -66,6 +70,8 @@ class MockDriver {
} }
this.level = n; this.level = n;
return Promise.resolve();
} }
pause() { pause() {
+23 -6
View File
@@ -1,5 +1,16 @@
const sqlite3 = require("sqlite3").verbose(); const sqlite3 = require("sqlite3").verbose();
function generateId() {
const buffer = Buffer.alloc(18);
buffer.writeUInt32BE(Date.now() / (2 ** 32), 0);
buffer.writeUInt32BE(Date.now() % (2 ** 32), 4);
for (let i = 8; i < 18; ++i) {
buffer[i] = Math.floor(Math.random() * 255);
}
return buffer.slice(2).toString("hex");
}
class SQLite3Repository { class SQLite3Repository {
constructor(path) { constructor(path) {
this.db = new sqlite3.Database(path); this.db = new sqlite3.Database(path);
@@ -39,15 +50,21 @@ class SQLite3Repository {
} }
insert(obj, table, params) { insert(obj, table, params) {
if (!params.includes("id")) {
params.push("id");
obj = {...obj, id: table.charAt(0).toUpperCase() + generateId(0, -1)};
}
let id = obj.id;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const query = `INSERT INTO ${table} (${params.join(", ")}) VALUES (${params.map(p => ':'+p).join(", ")});`; const query = `INSERT INTO ${table} (${params.join(", ")}) VALUES (${params.map(p => ':'+p).join(", ")});`;
const values = params.map(p => obj[p]); const values = params.map(p => obj[p]);
this.db.run(query, values, function(err) { this.db.run(query, values, (err) => {
if (err != null) { if (err != null) {
return reject(err); return reject(err);
} }
resolve(this.lastID); resolve(id);
}); });
}); });
} }
@@ -181,7 +198,7 @@ class SQLite3Repository {
const SQL_TABLE_BIKE = ` const SQL_TABLE_BIKE = `
CREATE TABLE IF NOT EXISTS bike ( CREATE TABLE IF NOT EXISTS bike (
id INTEGER PRIMARY KEY, id CHAR(32) PRIMARY KEY,
name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL,
driver VARCHAR(255) NOT NULL, driver VARCHAR(255) NOT NULL,
connect VARCHAR(255) NOT NULL, connect VARCHAR(255) NOT NULL,
@@ -191,7 +208,7 @@ const SQL_TABLE_BIKE = `
const SQL_TABLE_PROGRAM = ` const SQL_TABLE_PROGRAM = `
CREATE TABLE IF NOT EXISTS program ( CREATE TABLE IF NOT EXISTS program (
id INTEGER 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,
warmupMin INT NOT NULL, warmupMin INT NOT NULL,
@@ -201,7 +218,7 @@ const SQL_TABLE_PROGRAM = `
const SQL_TABLE_WORKOUT = ` const SQL_TABLE_WORKOUT = `
CREATE TABLE IF NOT EXISTS workout ( CREATE TABLE IF NOT EXISTS workout (
id INTEGER 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
@@ -210,7 +227,7 @@ const SQL_TABLE_WORKOUT = `
const SQL_TABLE_MEASUREMENT = ` const SQL_TABLE_MEASUREMENT = `
CREATE TABLE IF NOT EXISTS measurement ( CREATE TABLE IF NOT EXISTS measurement (
id INTEGER PRIMARY KEY, id CHAR(32) PRIMARY KEY,
workoutId INT NOT NULL, workoutId INT NOT NULL,
minutes INT, minutes INT,
seconds INT, seconds INT,
+7 -1
View File
@@ -6,6 +6,8 @@ const repo = new SQLite3Repository("stuff.db");
repo.setup().catch(err => { repo.setup().catch(err => {
console.error("Failed to setup db:", err); console.error("Failed to setup db:", err);
process.exit(1); process.exit(1);
}).then(() => {
console.log("Datbase setup complete.")
}); });
const app = express(); const app = express();
@@ -16,5 +18,9 @@ app.use("/api/bike/", require("./api/bike")(repo));
app.use("/api/program/", require("./api/program")(repo)); app.use("/api/program/", require("./api/program")(repo));
app.use("/api/workout/", require("./api/workout")(repo)); app.use("/api/workout/", require("./api/workout")(repo));
app.listen(8780); const port = process.env.PORT || 8780;
const host = process.env.HOST || "0.0.0.0";
app.listen(port, host, () => {
console.log(`Listening on ${host}:${port}...`)
});
+1 -1
View File
@@ -36,7 +36,7 @@ class Workout {
} }
async connect() { async connect() {
this.driver = createDriver(this.bike.driver); this.driver = createDriver(this.bike.driver, this.bike.connect);
this.driver.events.on("workoutState", ws => this.handleWorkoutState(ws)); this.driver.events.on("workoutState", ws => this.handleWorkoutState(ws));
return this.driver.connect(); return this.driver.connect();