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.
137 lines
3.4 KiB
137 lines
3.4 KiB
import { BaseInterface } from "./base"; |
|
import { BaseService, BaseCharacteritic, BaseApplication } from "./bluez-gatt"; |
|
|
|
export class FTMSService extends BaseService { |
|
UUID = "00001826-0000-1000-8000-00805f9b34fb"; |
|
Primary = true; |
|
|
|
constructor(bus, path) { |
|
super(bus, path); |
|
this.addCharacteristic(new FTMSFeature(bus, this.path + "/char0", this)); |
|
this.addCharacteristic(new IndoorBikeData(bus, this.path + "/char1", this)); |
|
this.addCharacteristic( |
|
new FTMSControlPoint(bus, this.path + "/char2", this) |
|
); |
|
} |
|
} |
|
|
|
class FTMSFeature extends BaseCharacteritic { |
|
constructor(bus, path, service) { |
|
super(bus, path, service, "00002acc-0000-1000-8000-00805f9b34fb", ["read"]); |
|
} |
|
|
|
read() { |
|
console.log("read FTMS Feature"); |
|
// 32bits features + 32bits target supported |
|
// 0x0a 0x44 = feature: cadence (1), inclinaison (3), hr (10), power (14) |
|
// 0x0a 0x20 = target: inclinaison (1), power (3), simulation parameters (13) |
|
return [0x0a, 0x44, 0x00, 0x00, 0x0a, 0x20, 0x00, 0x00]; |
|
} |
|
} |
|
|
|
class FTMSControlPoint extends BaseCharacteritic { |
|
wind = 0; |
|
grade = 0; |
|
crr = 0; |
|
cw = 0; |
|
|
|
constructor(bus, path, service) { |
|
super(bus, path, service, "00002ad9-0000-1000-8000-00805f9b34fb", [ |
|
"write", |
|
"indicate", |
|
]); |
|
} |
|
|
|
write(value, options) { |
|
console.log("FTMS Write Control Point"); |
|
console.log(value); |
|
const arraybuf = value.buffer.slice( |
|
value.byteOffset, |
|
value.byteOffset + value.byteLength |
|
); |
|
const view = new DataView(arraybuf); |
|
|
|
if (value[0] === 0x00) { |
|
// take control |
|
this.notify([0x80, 0x00, 0x01]); |
|
} else if (value[0] === 0x01) { |
|
// reset machine |
|
this.notify([0x80, 0x01, 0x01]); |
|
} else if (value[0] === 0x07) { |
|
// start/resume |
|
this.notify([0x80, 0x07, 0x01]); |
|
} else if (value[0] === 0x11) { |
|
// set simulations param (wind, grade, etc) |
|
const wind = view.getInt16(1, true); |
|
const grade = view.getInt16(3, true); |
|
const crr = view.getUint8(5); |
|
const cw = view.getUint8(6); |
|
|
|
this.wind = wind * 0.001; |
|
this.grade = grade * 0.01; |
|
this.crr = crr * 0.001; |
|
this.cw = cw * 0.01; |
|
|
|
console.log(wind * 0.001); |
|
console.log(grade * 0.01); |
|
console.log(crr * 0.0001); |
|
console.log(cw * 0.01); |
|
|
|
this.notify([0x80, 0x11, 0x01]); |
|
} else { |
|
console.log("FTMS Control point op code " + value[0] + "not supported"); |
|
} |
|
} |
|
|
|
startNotify() { |
|
console.log("FTMS Start Notify CP"); |
|
} |
|
|
|
stopNotify() { |
|
console.log("FTMS Stop Notify CP"); |
|
} |
|
} |
|
|
|
class IndoorBikeData extends BaseCharacteritic { |
|
constructor(bus, path, service) { |
|
super(bus, path, service, "00002ad2-0000-1000-8000-00805f9b34fb", [ |
|
"notify", |
|
]); |
|
} |
|
|
|
startNotify() { |
|
if (this.Notifying) { |
|
return; |
|
} |
|
|
|
this.Notifying = true; |
|
|
|
this.interval = setInterval(() => { |
|
console.log("FTMS Notif Indoor Bike"); |
|
// 0x44 0x02 = fields included: cadence (2), power (6), hr (9) |
|
// 0x00 0x00 = average speed, always included |
|
// cadence is *2 (resolution 0.5 s^-1) |
|
this.notify([ |
|
0x44, |
|
0x02, |
|
0x00, |
|
0x00, |
|
Math.round(160 + Math.random() * 10), |
|
0x00, |
|
Math.round(160 + Math.random() * 40), |
|
0x00, |
|
Math.round(120 + Math.random() * 10), |
|
]); |
|
}, 1000); |
|
} |
|
|
|
stopNotify() { |
|
if (!this.Notifying) { |
|
return; |
|
} |
|
|
|
this.Notifying = false; |
|
|
|
clearInterval(this.interval); |
|
} |
|
}
|
|
|