Connect HR using core class

pull/1/head
lambda 5 months ago
parent 5881d32886
commit 200224f0d6

@ -6,6 +6,7 @@
</head> </head>
<body> <body>
<button id="start">start</button> <button id="start">start</button>
<button id="hr">hr</button>
<script type="module" src="js/main.js"></script> <script type="module" src="js/main.js"></script>
</body> </body>
</html> </html>

@ -1,4 +1,4 @@
import { deepFreeze, isFiniteNumber } from "../../utils"; import { deepFreeze, isFiniteNumber } from "../../utils/index.js";
import { CyclingPowerCapabilities } from "./cyclingPower.js"; import { CyclingPowerCapabilities } from "./cyclingPower.js";
export class Control { export class Control {

@ -1,4 +1,4 @@
import { deepFreeze } from "../../utils"; import { deepFreeze } from "../../utils/index.js";
export class Core { export class Core {
constructor({ constructor({

@ -1,4 +1,4 @@
import { deepFreeze } from "../../utils"; import { deepFreeze } from "../../utils/index.js";
export class CyclingPowerCapabilities { export class CyclingPowerCapabilities {
constructor({ controlOpcodes = [], supportsCrankTorque = false } = {}) { constructor({ controlOpcodes = [], supportsCrankTorque = false } = {}) {

@ -1,5 +1,5 @@
import { Control } from "./control"; import { Control } from "./control.js";
import { Sensors } from "./sensors"; import { Sensors } from "./sensors.js";
import { Core } from "./core"; import { Core } from "./core.js";
export { Control, Sensors, Core }; export { Control, Sensors, Core };

@ -1,5 +1,5 @@
import { deepFreeze, isFiniteNumber } from "../../utils"; import { deepFreeze, isFiniteNumber } from "../../utils/index.js";
import { validateCadenceQuality } from "../cadence"; import { validateCadenceQuality } from "../cadence.js";
export class Sensors { export class Sensors {
constructor({ constructor({

@ -1,5 +1,5 @@
import { Control, Sensors, Core } from "./capabilities"; import { Control, Sensors, Core } from "./capabilities/index.js";
import { deepFreeze } from "../utils"; import { deepFreeze } from "../utils/index.js";
const DeviceType = Object.freeze({ const DeviceType = Object.freeze({
HEART_RATE: "heart_rate", HEART_RATE: "heart_rate",
@ -8,7 +8,7 @@ const DeviceType = Object.freeze({
UNKNOWN: "unknown", UNKNOWN: "unknown",
}); });
export class Device { class Device {
constructor({ constructor({
id, id,
name, name,
@ -64,3 +64,5 @@ export class Device {
}), }),
); );
} }
export { Device, Core };

@ -1,24 +1,107 @@
import { Core } from "./device/index.js";
const startButton = document.getElementById("start"); const startButton = document.getElementById("start");
const hrButton = document.getElementById("hr");
console.log(navigator.bluetooth); hrButton.addEventListener("click", async () => {
const hrOptions = {
// Show only devices that advertise the Heart Rate service (0x180D)
filters: [{ services: [0x180d] }],
const devices = await navigator.bluetooth.getDevices(); // After the user picks a device we also want to read the Device
// Information service (optional, no extra prompt)
optionalServices: [0x180a], // Device Information
};
function parseHeartRate(dataView) {
// Flags are in the first byte
const flags = dataView.getUint8(0);
const hrFormatUint16 = flags & 0x01; // 0 = 8bit, 1 = 16bit
if (hrFormatUint16) {
return dataView.getUint16(1, /*littleEndian=*/ true);
}
return dataView.getUint8(1);
}
try {
const device = await navigator.bluetooth.requestDevice(hrOptions);
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()),
]);
devices.forEach(async (device) => { // const [infoService, hrService] = await Promise.all([
const gattServer = await device.gatt.connect(); // server.getPrimaryService(0x180a), // Device Information
const primaryService = await gattServer.getPrimaryService(0x1800); // server.getPrimaryService(0x180d), // Heart Rate
const MANUFACTURER_UUID = 0x2a29; // ]);
const MODEL_UUID = 0x2a0a;
const char = await primaryService.getCharacteristic(MODEL_UUID); // const [manufVal, modelVal, hrChar] = await Promise.all([
const val = await char.readValue(); // infoService.getCharacteristic(0x2a29).then((c) => c.readValue()), // Manufacturer Name (0x2A29)
//const char2 = await primaryService.getCharacteristic(MODEL_UUID); // infoService.getCharacteristic(0x2a24).then((c) => c.readValue()), // Model Number (0x2A24)
//const val2 = await char2.readValue(); // hrService
const decoder = new TextDecoder("utf-8"); // .getCharacteristic(0x2a37)
const manufacturer = decoder.decode(val); // .then((c) => c.startNotifications().then(() => c)), // Heart Rate Measurement
//const model = decoder.decode(val2); // ]);
console.log("Manufacturer:", manufacturer);
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 () => { startButton.addEventListener("click", async () => {
try { try {
const devices = await navigator.bluetooth.getDevices(); const devices = await navigator.bluetooth.getDevices();

Loading…
Cancel
Save