Files
cardio/static/js/BLE.js
2023-01-26 12:26:12 +11:00

69 lines
1.9 KiB
JavaScript

async function connect(props) {
const device = await navigator.bluetooth.requestDevice({
filters: [{ services: ["cycling_speed_and_cadence"] }],
acceptAllDevices: false,
});
console.log(`%c\n👩🏼‍⚕️`, "font-size: 82px;", "Starting CSC...\n\n");
const server = await device.gatt.connect();
const service = await server.getPrimaryService("cycling_speed_and_cadence");
const char = await service.getCharacteristic("csc_measurement");
char.oncharacteristicvaluechanged = props.onChange;
char.startNotifications();
return char;
}
function parseCSC(e) {
const flags = e.target.value.getUint8(0, true);
const hasWheel = !!(flags & 0x01);
const hasCrank = !!(flags & 0x02);
let index = 1;
const res = {
wheelRevs: null,
wheelTime: null,
crankRevs: null,
crankTime: null,
};
if (hasWheel) {
res.wheelRevs = value.getUint32(index, true);
index += 4;
res.wheelTime = value.getUint16(index, true);
index += 2;
}
if (hasCrank) {
res.crankRevs = value.getUint16(index, true);
index += 2;
res.crankTime = value.getUint16(index, true);
index += 2;
}
console.log("CSC", res);
const pre = document.createElement("pre");
pre.style.border = "1px solid red";
pre.textContent = JSON.stringify(res, null, 2);
document.body.appendChild(pre);
return res;
}
function revsToRPM(t1, t2) {
const deltaRevs = t2.revs - t1.revs;
if (deltaRevs === 0) {
// no rotation
return 0;
}
let deltaTime = (t2.time - t1.time) / 1024;
if (deltaTime < 0) {
// time counter wraparound
deltaTime += Math.pow(2, 16) / 1024;
}
deltaTime /= 60; // seconds to minutes
const rpm = deltaRevs / deltaTime;
return rpm;
}
document.querySelector("#ble-connect").addEventListener("click", () =>
connect({
onChange: parseCSC,
}).catch(console.error)
);