// Example 1 (from the spec): let chosenHeartRateService: BluetoothRemoteGATTService = null; navigator.bluetooth.requestDevice({ filters: [{ services: ['heart_rate'], }] }).then((device: BluetoothDevice) => device.gatt.connect()) .then((server: BluetoothRemoteGATTServer) => server.getPrimaryService('heart_rate')) .then((service: BluetoothRemoteGATTService) => { chosenHeartRateService = service; return Promise.all([ service.getCharacteristic('body_sensor_location') .then(handleBodySensorLocationCharacteristic), service.getCharacteristic('heart_rate_measurement') .then(handleHeartRateMeasurementCharacteristic), ]); }); function handleBodySensorLocationCharacteristic(characteristic: BluetoothRemoteGATTCharacteristic) { if (characteristic === null) { console.log("Unknown sensor location."); return Promise.resolve(); } return characteristic.readValue() .then(sensorLocationData => { let sensorLocation = sensorLocationData.getUint8(0); switch (sensorLocation) { case 0: return 'Other'; case 1: return 'Chest'; case 2: return 'Wrist'; case 3: return 'Finger'; case 4: return 'Hand'; case 5: return 'Ear Lobe'; case 6: return 'Foot'; default: return 'Unknown'; } }).then(location => console.log(location)); } function handleHeartRateMeasurementCharacteristic(characteristic: BluetoothRemoteGATTCharacteristic) { return characteristic.startNotifications() .then(char => { characteristic.addEventListener('characteristicvaluechanged', onHeartRateChanged); }); } function onHeartRateChanged(event: Event) { let characteristic = event.target as BluetoothRemoteGATTCharacteristic; console.log(parseHeartRate(characteristic.value)); } function parseHeartRate(data: DataView) { let flags = data.getUint8(0); let rate16Bits = flags & 0x1; let result: any = {}; let index = 1; if (rate16Bits) { result.heartRate = data.getUint16(index, /*littleEndian=*/true); index += 2; } else { result.heartRate = data.getUint8(index); index += 1; } let contactDetected = flags & 0x2; let contactSensorPresent = flags & 0x4; if (contactSensorPresent) { result.contactDetected = !!contactDetected; } let energyPresent = flags & 0x8; if (energyPresent) { result.energyExpended = data.getUint16(index, /*littleEndian=*/true); index += 2; } let rrIntervalPresent = flags & 0x10; if (rrIntervalPresent) { let rrIntervals: number[] = []; for (; index + 1 < data.byteLength; index += 2) { rrIntervals.push(data.getUint16(index, /*littleEndian=*/true)); } result.rrIntervals = rrIntervals; } return result; }