import { Core } from "./device/index.js"; import { requestHRSensor } from "./ble/index.js"; const startButton = document.getElementById("start"); const hrButton = document.getElementById("hr"); hrButton.addEventListener("click", async () => { function parseHeartRate(dataView) { // Flags are in the first byte const flags = dataView.getUint8(0); const hrFormatUint16 = flags & 0x01; // 0 = 8‑bit, 1 = 16‑bit if (hrFormatUint16) { return dataView.getUint16(1, /*littleEndian=*/ true); } return dataView.getUint8(1); } try { const device = await requestHRSensor(); console.log("D", device); if (!device) return; const server = await device.gatt.connect(); const partialCore = new Core({ supportsBattery: true, supportsManufacturerData: true, gattServices: [ 0x180a, // Device Information 0x180d, // Heart Rate ], gattCharacteristics: [ 0x2a29, // Manufacturer Name 0x2a24, // Model Number 0x2a25, // Serial number 0x2a26, // Firmware version 0x2a37, // Heart Rate Measurement ], }); const info = await server.getPrimaryService(partialCore.gattServices[0]); const [manufacturer, model, firmwareVersion] = await Promise.all([ info.getCharacteristic(0x2a29).then((c) => c.readValue()), info.getCharacteristic(0x2a24).then((c) => c.readValue()), info.getCharacteristic(0x2a26).then((c) => c.readValue()), //info.getCharacteristic(0x2a25).then((c) => c.readValue()), ]); // const [infoService, hrService] = await Promise.all([ // server.getPrimaryService(0x180a), // Device Information // server.getPrimaryService(0x180d), // Heart Rate // ]); // const [manufVal, modelVal, hrChar] = await Promise.all([ // infoService.getCharacteristic(0x2a29).then((c) => c.readValue()), // Manufacturer Name (0x2A29) // infoService.getCharacteristic(0x2a24).then((c) => c.readValue()), // Model Number (0x2A24) // hrService // .getCharacteristic(0x2a37) // .then((c) => c.startNotifications().then(() => c)), // Heart Rate Measurement // ]); const dec = new TextDecoder("utf-8"); const core = partialCore.merge({ manufacturer: dec.decode(manufacturer), model: dec.decode(model), firmwareVersion: dec.decode(firmwareVersion), //serial: dec.decode(serial), }); console.log(core); // hrChar.addEventListener("characteristicvaluechanged", (ev) => // console.log("❤️", parseHeartRate(ev.target.value), "bpm"), // ); } catch (error) { console.error(error); } }); const devices = await navigator.bluetooth.getDevices(); console.log("CONNECTED", devices); // devices.forEach(async (device) => { // const gattServer = await device.gatt.connect(); // const primaryService = await gattServer.getPrimaryService(0x1800); // const MANUFACTURER_UUID = 0x2a29; // const MODEL_UUID = 0x2a0a; // const char = await primaryService.getCharacteristic(MODEL_UUID); // const val = await char.readValue(); // //const char2 = await primaryService.getCharacteristic(MODEL_UUID); // //const val2 = await char2.readValue(); // const decoder = new TextDecoder("utf-8"); // const manufacturer = decoder.decode(val); // //const model = decoder.decode(val2); // console.log("Manufacturer:", manufacturer); // }); startButton.addEventListener("click", async () => { try { const devices = await navigator.bluetooth.getDevices(); console.log(2, devices); const device = await navigator.bluetooth.requestDevice({ filters: [{ services: [0x180d] }], optionalServices: [ 0x1818, // Cycling Power – watts, torque, crank torque, etc. 0x1816, // Cycling Speed & Cadence – speed, cadence, distance 0x180d, // Heart Rate – optional, if the trainer includes an HR sensor 0x180f, // Battery Service – trainer battery level (if battery‑powered) 0x180a, // Device Information – manufacturer, model, firmware version 0x1800, // add any custom 128‑bit UUIDs as strings, e.g. // '0000abcd-0000-1000-8000-00805f9b34fb' ], acceptAllDevices: true, }); const server = await device.gatt.connect(); console.log(await server.getPrimaryServices()); } catch (error) { console.log(error); } }); // startButton.addEventListener("click", async () => { // try { // const devices = await navigator.bluetooth.getDevices(); // console.log(2, devices); // const device = await navigator.bluetooth.requestDevice({ // //filters: [{ services: ["heart_rate"] }], // optionalServices: [ // 0x1818, // Cycling Power – watts, torque, crank torque, etc. // 0x1816, // Cycling Speed & Cadence – speed, cadence, distance // 0x180d, // Heart Rate – optional, if the trainer includes an HR sensor // 0x180f, // Battery Service – trainer battery level (if battery‑powered) // 0x180a, // Device Information – manufacturer, model, firmware version // 0x1800, // // add any custom 128‑bit UUIDs as strings, e.g. // // '0000abcd-0000-1000-8000-00805f9b34fb' // ], // acceptAllDevices: true, // }); // const server = await device.gatt.connect(); // console.log(await server.getPrimaryServices()); // } catch (error) { // console.log(error); // } // });