@ovok/native 1.16.1-dev.2099 → 1.16.1-dev.2101
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/modules/next/bluetooth/channel.js +89 -0
- package/lib/commonjs/modules/next/bluetooth/channel.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/driver.js +48 -0
- package/lib/commonjs/modules/next/bluetooth/driver.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/drivers.js +20 -0
- package/lib/commonjs/modules/next/bluetooth/drivers.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/index.js +65 -0
- package/lib/commonjs/modules/next/bluetooth/index.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/legacy-driver.js +55 -0
- package/lib/commonjs/modules/next/bluetooth/legacy-driver.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/link.js +105 -0
- package/lib/commonjs/modules/next/bluetooth/link.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/result-policy.js +69 -0
- package/lib/commonjs/modules/next/bluetooth/result-policy.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/sig-profiles.js +164 -0
- package/lib/commonjs/modules/next/bluetooth/sig-profiles.js.map +1 -0
- package/lib/commonjs/modules/next/bluetooth/sig-values.js +46 -0
- package/lib/commonjs/modules/next/bluetooth/sig-values.js.map +1 -0
- package/lib/module/modules/next/bluetooth/channel.js +85 -0
- package/lib/module/modules/next/bluetooth/channel.js.map +1 -0
- package/lib/module/modules/next/bluetooth/driver.js +45 -0
- package/lib/module/modules/next/bluetooth/driver.js.map +1 -0
- package/lib/module/modules/next/bluetooth/drivers.js +17 -0
- package/lib/module/modules/next/bluetooth/drivers.js.map +1 -0
- package/lib/module/modules/next/bluetooth/index.js +8 -0
- package/lib/module/modules/next/bluetooth/index.js.map +1 -0
- package/lib/module/modules/next/bluetooth/legacy-driver.js +51 -0
- package/lib/module/modules/next/bluetooth/legacy-driver.js.map +1 -0
- package/lib/module/modules/next/bluetooth/link.js +103 -0
- package/lib/module/modules/next/bluetooth/link.js.map +1 -0
- package/lib/module/modules/next/bluetooth/result-policy.js +61 -0
- package/lib/module/modules/next/bluetooth/result-policy.js.map +1 -0
- package/lib/module/modules/next/bluetooth/sig-profiles.js +156 -0
- package/lib/module/modules/next/bluetooth/sig-profiles.js.map +1 -0
- package/lib/module/modules/next/bluetooth/sig-values.js +38 -0
- package/lib/module/modules/next/bluetooth/sig-values.js.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/channel.d.ts +19 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/channel.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/driver.d.ts +32 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/driver.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/drivers.d.ts +7 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/drivers.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/index.d.ts +9 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/legacy-driver.d.ts +8 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/legacy-driver.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/link.d.ts +13 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/link.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/result-policy.d.ts +14 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/result-policy.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/sig-profiles.d.ts +16 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/sig-profiles.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/sig-values.d.ts +15 -0
- package/lib/typescript/commonjs/src/modules/next/bluetooth/sig-values.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/channel.d.ts +19 -0
- package/lib/typescript/module/src/modules/next/bluetooth/channel.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/driver.d.ts +32 -0
- package/lib/typescript/module/src/modules/next/bluetooth/driver.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/drivers.d.ts +7 -0
- package/lib/typescript/module/src/modules/next/bluetooth/drivers.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/index.d.ts +9 -0
- package/lib/typescript/module/src/modules/next/bluetooth/index.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/legacy-driver.d.ts +8 -0
- package/lib/typescript/module/src/modules/next/bluetooth/legacy-driver.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/link.d.ts +13 -0
- package/lib/typescript/module/src/modules/next/bluetooth/link.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/result-policy.d.ts +14 -0
- package/lib/typescript/module/src/modules/next/bluetooth/result-policy.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/sig-profiles.d.ts +16 -0
- package/lib/typescript/module/src/modules/next/bluetooth/sig-profiles.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/next/bluetooth/sig-values.d.ts +15 -0
- package/lib/typescript/module/src/modules/next/bluetooth/sig-values.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_next","require","_bloodPressureStates","_sigUuid","_sigValues","KPA_TO_MMHG","KG_PER_SI_COUNT","KG_PER_IMPERIAL_COUNT","WEIGHT_UNSUCCESSFUL","DATE_TIME_BYTES","BP_KPA","BP_TIMESTAMP","BP_PULSE","BP_USER","BP_STATUS","BP_BODY_MOVEMENT","BP_LOOSE_CUFF","BP_IRREGULAR_PULSE","TEMPERATURE_FAHRENHEIT","TEMPERATURE_TIMESTAMP","WEIGHT_IMPERIAL","WEIGHT_TIMESTAMP","PLX_TIMESTAMP","HEART_RATE_UINT16","HEART_RATE_CONTACT_BITS","HEART_RATE_NO_CONTACT","bloodPressureStatus","status","BloodPressureStates","DISTURB_DETECTED","LOOSE_SLEEVE","REGULAR","bloodPressureExtras","view","flags","offset","extras","recordedAt","dateTimeAt","heartRate","sfloatAt","user","getUint8","memorySlot","undefined","getUint16","irregularHeartbeat","bloodPressure","pressure","value","roundTo","systolic","diastolic","mean","map","reading","measurementTypeKey","MeasurementTypeKey","withDefined","meanArterialPressure","exports","temperature","floatAt","bodyTemp","bodyWeight","counts","pulseOximetry","bloodOxygen","pulseRate","bloodOxygenPulseRate","subscribed","service","characteristic","decode","link","frame","subscribe","sigUuid","decodeFrame","SIG_PROTOCOLS","Map"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/sig-profiles.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.withDefined = exports.sfloatAt = exports.roundTo = exports.floatAt = exports.decodeFrame = exports.dateTimeAt = void 0;
|
|
7
|
+
var _decodeMedicalFloat = require("../../bt-management/utils/decode-medical-float.js");
|
|
8
|
+
/** Reads one GATT value; undefined when it holds no reading. */
|
|
9
|
+
|
|
10
|
+
const sfloatAt = (view, offset) => (0, _decodeMedicalFloat.decodeMedicalFloat)(view.getUint16(offset, true), 4, 12);
|
|
11
|
+
exports.sfloatAt = sfloatAt;
|
|
12
|
+
const floatAt = (view, offset) => (0, _decodeMedicalFloat.decodeMedicalFloat)(view.getUint32(offset, true), 8, 24);
|
|
13
|
+
|
|
14
|
+
/** The SIG Date Time characteristic as a phone-local date; undefined for unknown or impossible fields. */
|
|
15
|
+
exports.floatAt = floatAt;
|
|
16
|
+
const dateTimeAt = (view, offset) => {
|
|
17
|
+
const fields = [view.getUint16(offset, true), ...[2, 3, 4, 5, 6].map(index => view.getUint8(offset + index))];
|
|
18
|
+
const [year = 0, month = 0, day = 0, hours = 0, minutes = 0, seconds = 0] = fields;
|
|
19
|
+
const date = new Date(year, month - 1, day, hours, minutes, seconds);
|
|
20
|
+
const stored = [date.getFullYear(), date.getMonth() + 1, date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()];
|
|
21
|
+
return fields.every((field, index) => field === stored[index]) ? date : undefined;
|
|
22
|
+
};
|
|
23
|
+
exports.dateTimeAt = dateTimeAt;
|
|
24
|
+
const roundTo = (value, decimals) => Number(value.toFixed(decimals));
|
|
25
|
+
|
|
26
|
+
/** `reading` plus each of `fields` that has a value. */
|
|
27
|
+
exports.roundTo = roundTo;
|
|
28
|
+
const withDefined = (reading, fields) => ({
|
|
29
|
+
...reading,
|
|
30
|
+
...Object.fromEntries(Object.entries(fields).filter(([, value]) => value !== undefined))
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
/** A frame too short for what its flags announce holds no reading. */
|
|
34
|
+
exports.withDefined = withDefined;
|
|
35
|
+
const decodeFrame = (decode, frame) => {
|
|
36
|
+
try {
|
|
37
|
+
return decode(new DataView(frame.buffer, frame.byteOffset, frame.byteLength));
|
|
38
|
+
} catch (error) {
|
|
39
|
+
if (error instanceof RangeError) {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
exports.decodeFrame = decodeFrame;
|
|
46
|
+
//# sourceMappingURL=sig-values.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_decodeMedicalFloat","require","sfloatAt","view","offset","decodeMedicalFloat","getUint16","exports","floatAt","getUint32","dateTimeAt","fields","map","index","getUint8","year","month","day","hours","minutes","seconds","date","Date","stored","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","every","field","undefined","roundTo","value","decimals","Number","toFixed","withDefined","reading","Object","fromEntries","entries","filter","decodeFrame","decode","frame","DataView","buffer","byteOffset","byteLength","error","RangeError"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/sig-values.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const DONE = {
|
|
4
|
+
value: undefined,
|
|
5
|
+
done: true
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
/** Callback-pushed values as an async iterator for one consumer; `onClose` runs once, however it ends. */
|
|
9
|
+
class Channel {
|
|
10
|
+
buffered = [];
|
|
11
|
+
closed = false;
|
|
12
|
+
constructor(onClose = () => {}) {
|
|
13
|
+
this.onClose = onClose;
|
|
14
|
+
}
|
|
15
|
+
push(value) {
|
|
16
|
+
if (this.closed) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const waiter = this.takeWaiter();
|
|
20
|
+
if (waiter) {
|
|
21
|
+
waiter.resolve({
|
|
22
|
+
value,
|
|
23
|
+
done: false
|
|
24
|
+
});
|
|
25
|
+
} else {
|
|
26
|
+
this.buffered.push(value);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
end() {
|
|
30
|
+
if (this.close()) {
|
|
31
|
+
this.takeWaiter()?.resolve(DONE);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
fail(error) {
|
|
35
|
+
if (this.close()) {
|
|
36
|
+
this.failure = {
|
|
37
|
+
error
|
|
38
|
+
};
|
|
39
|
+
this.takeWaiter()?.reject(error);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
next() {
|
|
43
|
+
if (this.buffered.length > 0) {
|
|
44
|
+
return Promise.resolve({
|
|
45
|
+
value: this.buffered.shift(),
|
|
46
|
+
done: false
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (this.failure) {
|
|
50
|
+
return Promise.reject(this.failure.error);
|
|
51
|
+
}
|
|
52
|
+
if (this.closed) {
|
|
53
|
+
return Promise.resolve(DONE);
|
|
54
|
+
}
|
|
55
|
+
return new Promise((resolve, reject) => {
|
|
56
|
+
this.waiter = {
|
|
57
|
+
resolve,
|
|
58
|
+
reject
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return() {
|
|
63
|
+
this.buffered.length = 0;
|
|
64
|
+
this.end();
|
|
65
|
+
return Promise.resolve(DONE);
|
|
66
|
+
}
|
|
67
|
+
[Symbol.asyncIterator]() {
|
|
68
|
+
return this;
|
|
69
|
+
}
|
|
70
|
+
close() {
|
|
71
|
+
if (this.closed) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
this.closed = true;
|
|
75
|
+
this.onClose();
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
takeWaiter() {
|
|
79
|
+
const waiter = this.waiter;
|
|
80
|
+
this.waiter = undefined;
|
|
81
|
+
return waiter;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export { Channel };
|
|
85
|
+
//# sourceMappingURL=channel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["DONE","value","undefined","done","Channel","buffered","closed","constructor","onClose","push","waiter","takeWaiter","resolve","end","close","fail","error","failure","reject","next","length","Promise","shift","return","Symbol","asyncIterator"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/channel.ts"],"mappings":";;AAKA,MAAMA,IAAqC,GAAG;EAAEC,KAAK,EAAEC,SAAS;EAAEC,IAAI,EAAE;AAAK,CAAC;;AAE9E;AACA,MAAMC,OAAO,CAAwC;EAClCC,QAAQ,GAAQ,EAAE;EAG3BC,MAAM,GAAG,KAAK;EAEfC,WAAWA,CAAkBC,OAAmB,GAAGA,CAAA,KAAM,CAAC,CAAC,EAAE;IAAA,KAAhCA,OAAmB,GAAnBA,OAAmB;EAAc;EAE9DC,IAAIA,CAACR,KAAQ,EAAQ;IAC1B,IAAI,IAAI,CAACK,MAAM,EAAE;MACf;IACF;IAEA,MAAMI,MAAM,GAAG,IAAI,CAACC,UAAU,CAAC,CAAC;IAEhC,IAAID,MAAM,EAAE;MACVA,MAAM,CAACE,OAAO,CAAC;QAAEX,KAAK;QAAEE,IAAI,EAAE;MAAM,CAAC,CAAC;IACxC,CAAC,MAAM;MACL,IAAI,CAACE,QAAQ,CAACI,IAAI,CAACR,KAAK,CAAC;IAC3B;EACF;EAEOY,GAAGA,CAAA,EAAS;IACjB,IAAI,IAAI,CAACC,KAAK,CAAC,CAAC,EAAE;MAChB,IAAI,CAACH,UAAU,CAAC,CAAC,EAAEC,OAAO,CAACZ,IAAI,CAAC;IAClC;EACF;EAEOe,IAAIA,CAACC,KAAc,EAAQ;IAChC,IAAI,IAAI,CAACF,KAAK,CAAC,CAAC,EAAE;MAChB,IAAI,CAACG,OAAO,GAAG;QAAED;MAAM,CAAC;MACxB,IAAI,CAACL,UAAU,CAAC,CAAC,EAAEO,MAAM,CAACF,KAAK,CAAC;IAClC;EACF;EAEOG,IAAIA,CAAA,EAA+B;IACxC,IAAI,IAAI,CAACd,QAAQ,CAACe,MAAM,GAAG,CAAC,EAAE;MAC5B,OAAOC,OAAO,CAACT,OAAO,CAAC;QAAEX,KAAK,EAAE,IAAI,CAACI,QAAQ,CAACiB,KAAK,CAAC,CAAM;QAAEnB,IAAI,EAAE;MAAM,CAAC,CAAC;IAC5E;IAEA,IAAI,IAAI,CAACc,OAAO,EAAE;MAChB,OAAOI,OAAO,CAACH,MAAM,CAAC,IAAI,CAACD,OAAO,CAACD,KAAK,CAAC;IAC3C;IAEA,IAAI,IAAI,CAACV,MAAM,EAAE;MACf,OAAOe,OAAO,CAACT,OAAO,CAACZ,IAAI,CAAC;IAC9B;IAEA,OAAO,IAAIqB,OAAO,CAAC,CAACT,OAAO,EAAEM,MAAM,KAAK;MACtC,IAAI,CAACR,MAAM,GAAG;QAAEE,OAAO;QAAEM;MAAO,CAAC;IACnC,CAAC,CAAC;EACJ;EAEOK,MAAMA,CAAA,EAA+B;IAC1C,IAAI,CAAClB,QAAQ,CAACe,MAAM,GAAG,CAAC;IACxB,IAAI,CAACP,GAAG,CAAC,CAAC;IAEV,OAAOQ,OAAO,CAACT,OAAO,CAACZ,IAAI,CAAC;EAC9B;EAEA,CAAQwB,MAAM,CAACC,aAAa,IAA8B;IACxD,OAAO,IAAI;EACb;EAEQX,KAAKA,CAAA,EAAY;IACvB,IAAI,IAAI,CAACR,MAAM,EAAE;MACf,OAAO,KAAK;IACd;IAEA,IAAI,CAACA,MAAM,GAAG,IAAI;IAClB,IAAI,CAACE,OAAO,CAAC,CAAC;IAEd,OAAO,IAAI;EACb;EAEQG,UAAUA,CAAA,EAA0B;IAC1C,MAAMD,MAAM,GAAG,IAAI,CAACA,MAAM;IAE1B,IAAI,CAACA,MAAM,GAAGR,SAAS;IAEvB,OAAOQ,MAAM;EACf;AACF;AAEA,SAASN,OAAO","ignoreList":[]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { DeviceStatus } from "../../bt-management/types/device-status.js";
|
|
4
|
+
import { createStableResultId } from "../../bt-management/utils/result-identity.js";
|
|
5
|
+
import { openBleLink } from "./link.js";
|
|
6
|
+
|
|
7
|
+
/** Connects to a scanned device and reports what happens until it disconnects or `signal` aborts. */
|
|
8
|
+
|
|
9
|
+
/** One device's conversation over a link, as the readings it produces. */
|
|
10
|
+
|
|
11
|
+
const readingIdentity = (deviceName, device) => ({
|
|
12
|
+
id: device.id,
|
|
13
|
+
name: deviceName,
|
|
14
|
+
localName: device.localName ?? "",
|
|
15
|
+
manufacturerData: device.manufacturerData ?? "",
|
|
16
|
+
sn: "",
|
|
17
|
+
measurementTypes: []
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
/** Runs a protocol over a fresh BLE link. */
|
|
21
|
+
const gattDriver = (deviceName, protocol) => async function* (device, signal) {
|
|
22
|
+
const link = await openBleLink(device, signal);
|
|
23
|
+
const identity = readingIdentity(deviceName, device);
|
|
24
|
+
try {
|
|
25
|
+
yield {
|
|
26
|
+
kind: "status",
|
|
27
|
+
status: DeviceStatus.CONNECTED
|
|
28
|
+
};
|
|
29
|
+
for await (const reading of protocol(link)) {
|
|
30
|
+
yield {
|
|
31
|
+
kind: "reading",
|
|
32
|
+
id: createStableResultId(identity, reading),
|
|
33
|
+
reading
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
yield {
|
|
37
|
+
kind: "status",
|
|
38
|
+
status: DeviceStatus.DISCONNECTED
|
|
39
|
+
};
|
|
40
|
+
} finally {
|
|
41
|
+
await link.close();
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
export { gattDriver };
|
|
45
|
+
//# sourceMappingURL=driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["DeviceStatus","createStableResultId","openBleLink","readingIdentity","deviceName","device","id","name","localName","manufacturerData","sn","measurementTypes","gattDriver","protocol","signal","link","identity","kind","status","CONNECTED","reading","DISCONNECTED","close"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/driver.ts"],"mappings":";;AAMA,SAASA,YAAY,QAAQ,4CAAyC;AACtE,SAASC,oBAAoB,QAAQ,8CAA2C;AAEhF,SAAeC,WAAW,QAAQ,WAAQ;;AAU1C;;AAGA;;AAGA,MAAMC,eAAe,GAAGA,CAACC,UAAqB,EAAEC,MAAc,MAAM;EAClEC,EAAE,EAAED,MAAM,CAACC,EAAE;EACbC,IAAI,EAAEH,UAAU;EAChBI,SAAS,EAAEH,MAAM,CAACG,SAAS,IAAI,EAAE;EACjCC,gBAAgB,EAAEJ,MAAM,CAACI,gBAAgB,IAAI,EAAE;EAC/CC,EAAE,EAAE,EAAE;EACNC,gBAAgB,EAAE;AACpB,CAAC,CAAC;;AAEF;AACA,MAAMC,UAAU,GAAGA,CAACR,UAAqB,EAAES,QAAwB,KACjE,iBAAiBR,MAAM,EAAES,MAAM,EAAE;EAC/B,MAAMC,IAAI,GAAG,MAAMb,WAAW,CAACG,MAAM,EAAES,MAAM,CAAC;EAC9C,MAAME,QAAQ,GAAGb,eAAe,CAACC,UAAU,EAAEC,MAAM,CAAC;EAEpD,IAAI;IACF,MAAM;MAAEY,IAAI,EAAE,QAAQ;MAAEC,MAAM,EAAElB,YAAY,CAACmB;IAAU,CAAC;IACxD,WAAW,MAAMC,OAAO,IAAIP,QAAQ,CAACE,IAAI,CAAC,EAAE;MAC1C,MAAM;QAAEE,IAAI,EAAE,SAAS;QAAEX,EAAE,EAAEL,oBAAoB,CAACe,QAAQ,EAAEI,OAAO,CAAC;QAAEA;MAAQ,CAAC;IACjF;IACA,MAAM;MAAEH,IAAI,EAAE,QAAQ;MAAEC,MAAM,EAAElB,YAAY,CAACqB;IAAa,CAAC;EAC7D,CAAC,SAAS;IACR,MAAMN,IAAI,CAACO,KAAK,CAAC,CAAC;EACpB;AACF,CAAC;AAEH,SAASV,UAAU","ignoreList":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { DeviceCreator } from "../../bt-management/services/device-creator.js";
|
|
4
|
+
import { gattDriver } from "./driver.js";
|
|
5
|
+
import { legacyDriver } from "./legacy-driver.js";
|
|
6
|
+
import { SIG_PROTOCOLS } from "./sig-profiles.js";
|
|
7
|
+
|
|
8
|
+
/** The driver for each device key `accepted` can resolve: its native protocol, else its legacy class. */
|
|
9
|
+
const createDrivers = accepted => {
|
|
10
|
+
const creator = new DeviceCreator(accepted);
|
|
11
|
+
return deviceName => {
|
|
12
|
+
const protocol = SIG_PROTOCOLS.get(String(deviceName));
|
|
13
|
+
return protocol ? gattDriver(deviceName, protocol) : legacyDriver(creator, deviceName);
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export { createDrivers };
|
|
17
|
+
//# sourceMappingURL=drivers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["DeviceCreator","gattDriver","legacyDriver","SIG_PROTOCOLS","createDrivers","accepted","creator","deviceName","protocol","get","String"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/drivers.ts"],"mappings":";;AAAA,SAASA,aAAa,QAAQ,gDAA6C;AAI3E,SAAiBC,UAAU,QAAQ,aAAU;AAC7C,SAASC,YAAY,QAAQ,oBAAiB;AAC9C,SAASC,aAAa,QAAQ,mBAAgB;;AAE9C;AACA,MAAMC,aAAa,GAAIC,QAAmC,IAA0C;EAClG,MAAMC,OAAO,GAAG,IAAIN,aAAa,CAACK,QAAQ,CAAC;EAE3C,OAAQE,UAAU,IAAK;IACrB,MAAMC,QAAQ,GAAGL,aAAa,CAACM,GAAG,CAACC,MAAM,CAACH,UAAU,CAAC,CAAC;IAEtD,OAAOC,QAAQ,GAAGP,UAAU,CAACM,UAAU,EAAEC,QAAQ,CAAC,GAAGN,YAAY,CAACI,OAAO,EAAEC,UAAU,CAAC;EACxF,CAAC;AACH,CAAC;AAED,SAASH,aAAa","ignoreList":[]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
export { gattDriver } from "./driver.js";
|
|
4
|
+
export { createDrivers } from "./drivers.js";
|
|
5
|
+
export { openBleLink } from "./link.js";
|
|
6
|
+
export { dailyTotalsOnly, everyReading, firstReadingPerKind, keepReadings, policyByKind } from "./result-policy.js";
|
|
7
|
+
export { SIG_PROTOCOLS } from "./sig-profiles.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["gattDriver","createDrivers","openBleLink","dailyTotalsOnly","everyReading","firstReadingPerKind","keepReadings","policyByKind","SIG_PROTOCOLS"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/index.ts"],"mappings":";;AAAA,SAASA,UAAU,QAAQ,aAAU;AAErC,SAASC,aAAa,QAAQ,cAAW;AACzC,SAASC,WAAW,QAAQ,WAAQ;AAEpC,SAASC,eAAe,EAAEC,YAAY,EAAEC,mBAAmB,EAAEC,YAAY,EAAEC,YAAY,QAAQ,oBAAiB;AAEhH,SAASC,aAAa,QAAQ,mBAAgB","ignoreList":[]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { DeviceStatus } from "../../bt-management/types/device-status.js";
|
|
4
|
+
import { Channel } from "./channel.js";
|
|
5
|
+
/** Runs a device class from `@ovok/native/bt-management` until its protocol moves to a `DeviceProtocol`. */
|
|
6
|
+
const legacyDriver = (creator, deviceName) => (device, signal) => {
|
|
7
|
+
const events = new Channel(() => void managed.disconnect());
|
|
8
|
+
const managed = creator.createDevice({
|
|
9
|
+
device,
|
|
10
|
+
deviceName,
|
|
11
|
+
onResult: ({
|
|
12
|
+
id,
|
|
13
|
+
data
|
|
14
|
+
}) => events.push({
|
|
15
|
+
kind: "reading",
|
|
16
|
+
id,
|
|
17
|
+
reading: data
|
|
18
|
+
}),
|
|
19
|
+
onDeviceStatusChanged: ({
|
|
20
|
+
status
|
|
21
|
+
}) => {
|
|
22
|
+
events.push({
|
|
23
|
+
kind: "status",
|
|
24
|
+
status
|
|
25
|
+
});
|
|
26
|
+
if (status === DeviceStatus.DISCONNECTED) {
|
|
27
|
+
events.end();
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
onConnectionEvent: ({
|
|
31
|
+
deviceData: _deviceData,
|
|
32
|
+
...event
|
|
33
|
+
}) => events.push({
|
|
34
|
+
kind: "connection",
|
|
35
|
+
event
|
|
36
|
+
}),
|
|
37
|
+
onError: ({
|
|
38
|
+
error
|
|
39
|
+
}) => events.push({
|
|
40
|
+
kind: "error",
|
|
41
|
+
error
|
|
42
|
+
})
|
|
43
|
+
});
|
|
44
|
+
signal.addEventListener("abort", () => events.end(), {
|
|
45
|
+
once: true
|
|
46
|
+
});
|
|
47
|
+
managed.connect().catch(error => events.fail(error));
|
|
48
|
+
return events;
|
|
49
|
+
};
|
|
50
|
+
export { legacyDriver };
|
|
51
|
+
//# sourceMappingURL=legacy-driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["DeviceStatus","Channel","legacyDriver","creator","deviceName","device","signal","events","managed","disconnect","createDevice","onResult","id","data","push","kind","reading","onDeviceStatusChanged","status","DISCONNECTED","end","onConnectionEvent","deviceData","_deviceData","event","onError","error","addEventListener","once","connect","catch","fail"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/legacy-driver.ts"],"mappings":";;AAKA,SAASA,YAAY,QAAQ,4CAAyC;AAEtE,SAASC,OAAO,QAAQ,cAAW;AAGnC;AACA,MAAMC,YAAY,GAAGA,CAACC,OAAiD,EAAEC,UAAqB,KAC5F,CAACC,MAAM,EAAEC,MAAM,KAAK;EAClB,MAAMC,MAAM,GAAG,IAAIN,OAAO,CAAc,MAAM,KAAKO,OAAO,CAACC,UAAU,CAAC,CAAC,CAAC;EAExE,MAAMD,OAAO,GAAGL,OAAO,CAACO,YAAY,CAAC;IACnCL,MAAM;IACND,UAAU;IACVO,QAAQ,EAAEA,CAAC;MAAEC,EAAE;MAAEC;IAAK,CAAC,KAAKN,MAAM,CAACO,IAAI,CAAC;MAAEC,IAAI,EAAE,SAAS;MAAEH,EAAE;MAAEI,OAAO,EAAEH;IAAoB,CAAC,CAAC;IAC9FI,qBAAqB,EAAEA,CAAC;MAAEC;IAAO,CAAC,KAAK;MACrCX,MAAM,CAACO,IAAI,CAAC;QAAEC,IAAI,EAAE,QAAQ;QAAEG;MAAO,CAAC,CAAC;MACvC,IAAIA,MAAM,KAAKlB,YAAY,CAACmB,YAAY,EAAE;QACxCZ,MAAM,CAACa,GAAG,CAAC,CAAC;MACd;IACF,CAAC;IACDC,iBAAiB,EAAEA,CAAC;MAAEC,UAAU,EAAEC,WAAW;MAAE,GAAGC;IAAM,CAAC,KAAKjB,MAAM,CAACO,IAAI,CAAC;MAAEC,IAAI,EAAE,YAAY;MAAES;IAAM,CAAC,CAAC;IACxGC,OAAO,EAAEA,CAAC;MAAEC;IAAM,CAAC,KAAKnB,MAAM,CAACO,IAAI,CAAC;MAAEC,IAAI,EAAE,OAAO;MAAEW;IAAM,CAAC;EAC9D,CAAC,CAAC;EAEFpB,MAAM,CAACqB,gBAAgB,CAAC,OAAO,EAAE,MAAMpB,MAAM,CAACa,GAAG,CAAC,CAAC,EAAE;IAAEQ,IAAI,EAAE;EAAK,CAAC,CAAC;EACpEpB,OAAO,CAACqB,OAAO,CAAC,CAAC,CAACC,KAAK,CAAEJ,KAAc,IAAKnB,MAAM,CAACwB,IAAI,CAACL,KAAK,CAAC,CAAC;EAE/D,OAAOnB,MAAM;AACf,CAAC;AAEH,SAASL,YAAY","ignoreList":[]}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { toBluetoothError } from "../../bt-management/types/bluetooth-error.js";
|
|
4
|
+
import { sentryLogger } from "../../helpers/utils/sentry-logger.js";
|
|
5
|
+
import { Channel } from "./channel.js";
|
|
6
|
+
|
|
7
|
+
/** An open GATT connection: bytes in, bytes out, no knowledge of any device. */
|
|
8
|
+
|
|
9
|
+
const CONNECT_ATTEMPTS = 5;
|
|
10
|
+
const FIRST_RETRY_DELAY_MS = 1000;
|
|
11
|
+
const MAX_RETRY_DELAY_MS = 5000;
|
|
12
|
+
|
|
13
|
+
/** BleErrorCode.OperationCancelled and DeviceDisconnected; the enum is not available at runtime. */
|
|
14
|
+
const ENDS_THE_LINK = new Set([2, 201]);
|
|
15
|
+
const toBytes = base64 => Uint8Array.from(atob(base64), char => char.charCodeAt(0));
|
|
16
|
+
const toBase64 = bytes => btoa(String.fromCharCode(...bytes));
|
|
17
|
+
const retryDelay = attempt => Math.min(FIRST_RETRY_DELAY_MS * 2 ** (attempt - 1), MAX_RETRY_DELAY_MS);
|
|
18
|
+
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
19
|
+
const abortReason = signal => signal.reason ?? new Error("The Bluetooth connection was cancelled");
|
|
20
|
+
async function connectWithRetries(device, signal) {
|
|
21
|
+
for (let attempt = 1;; attempt += 1) {
|
|
22
|
+
if (signal.aborted) {
|
|
23
|
+
throw abortReason(signal);
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
if (!(await device.isConnected())) {
|
|
27
|
+
await device.connect();
|
|
28
|
+
}
|
|
29
|
+
return;
|
|
30
|
+
} catch (error) {
|
|
31
|
+
if (attempt >= CONNECT_ATTEMPTS) {
|
|
32
|
+
sentryLogger("error", "BLUETOOTH: Connection failed", {
|
|
33
|
+
errorCode: toBluetoothError(error).code,
|
|
34
|
+
attempts: attempt
|
|
35
|
+
});
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
await wait(retryDelay(attempt));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
class BleLink {
|
|
43
|
+
channels = new Set();
|
|
44
|
+
ended = false;
|
|
45
|
+
constructor(device) {
|
|
46
|
+
this.device = device;
|
|
47
|
+
this.disconnected = device.onDisconnected(() => this.endAll());
|
|
48
|
+
}
|
|
49
|
+
subscribe(service, characteristic) {
|
|
50
|
+
const channel = new Channel(() => {
|
|
51
|
+
subscription.remove();
|
|
52
|
+
this.channels.delete(channel);
|
|
53
|
+
});
|
|
54
|
+
const subscription = this.device.monitorCharacteristicForService(service, characteristic, (error, value) => {
|
|
55
|
+
if (error) {
|
|
56
|
+
this.endOrFail(channel, error);
|
|
57
|
+
} else if (value?.value) {
|
|
58
|
+
channel.push(toBytes(value.value));
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
this.channels.add(channel);
|
|
62
|
+
if (this.ended) {
|
|
63
|
+
channel.end();
|
|
64
|
+
}
|
|
65
|
+
return channel;
|
|
66
|
+
}
|
|
67
|
+
async write(service, characteristic, bytes) {
|
|
68
|
+
await this.device.writeCharacteristicWithResponseForService(service, characteristic, toBase64(bytes));
|
|
69
|
+
}
|
|
70
|
+
async close() {
|
|
71
|
+
this.endAll();
|
|
72
|
+
this.disconnected.remove();
|
|
73
|
+
await this.device.cancelConnection().catch(() => undefined);
|
|
74
|
+
}
|
|
75
|
+
endOrFail(channel, error) {
|
|
76
|
+
if (ENDS_THE_LINK.has(error.errorCode)) {
|
|
77
|
+
channel.end();
|
|
78
|
+
} else {
|
|
79
|
+
channel.fail(toBluetoothError(error));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
endAll() {
|
|
83
|
+
this.ended = true;
|
|
84
|
+
[...this.channels].forEach(channel => channel.end());
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Connects (retrying with backoff) and discovers services; aborting `signal` closes the link. */
|
|
89
|
+
async function openBleLink(device, signal) {
|
|
90
|
+
await connectWithRetries(device, signal);
|
|
91
|
+
await device.discoverAllServicesAndCharacteristics();
|
|
92
|
+
const link = new BleLink(device);
|
|
93
|
+
if (signal.aborted) {
|
|
94
|
+
await link.close();
|
|
95
|
+
throw abortReason(signal);
|
|
96
|
+
}
|
|
97
|
+
signal.addEventListener("abort", () => void link.close(), {
|
|
98
|
+
once: true
|
|
99
|
+
});
|
|
100
|
+
return link;
|
|
101
|
+
}
|
|
102
|
+
export { openBleLink };
|
|
103
|
+
//# sourceMappingURL=link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["toBluetoothError","sentryLogger","Channel","CONNECT_ATTEMPTS","FIRST_RETRY_DELAY_MS","MAX_RETRY_DELAY_MS","ENDS_THE_LINK","Set","toBytes","base64","Uint8Array","from","atob","char","charCodeAt","toBase64","bytes","btoa","String","fromCharCode","retryDelay","attempt","Math","min","wait","ms","Promise","resolve","setTimeout","abortReason","signal","reason","Error","connectWithRetries","device","aborted","isConnected","connect","error","errorCode","code","attempts","BleLink","channels","ended","constructor","disconnected","onDisconnected","endAll","subscribe","service","characteristic","channel","subscription","remove","delete","monitorCharacteristicForService","value","endOrFail","push","add","end","write","writeCharacteristicWithResponseForService","close","cancelConnection","catch","undefined","has","fail","forEach","openBleLink","discoverAllServicesAndCharacteristics","link","addEventListener","once"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/link.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { dailyTotalDay } from "../../bt-management/utils/daily-total-day.js";
|
|
4
|
+
|
|
5
|
+
/** Makes, for each connection, the test of which readings to keep. */
|
|
6
|
+
|
|
7
|
+
const everyReading = () => () => true;
|
|
8
|
+
const firstReadingPerKind = () => {
|
|
9
|
+
const reported = new Set();
|
|
10
|
+
return ({
|
|
11
|
+
measurementTypeKey
|
|
12
|
+
}) => {
|
|
13
|
+
if (reported.has(measurementTypeKey)) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
reported.add(measurementTypeKey);
|
|
17
|
+
return true;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/** Activity totals count only once their day has closed, and each day only once. */
|
|
22
|
+
const dailyTotalsOnly = () => {
|
|
23
|
+
const reported = new Set();
|
|
24
|
+
return reading => {
|
|
25
|
+
const day = dailyTotalDay(reading, Date.now());
|
|
26
|
+
if (day === undefined) {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
const key = `${reading.measurementTypeKey}:${day}`;
|
|
30
|
+
if (day === "future" || reported.has(key)) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
reported.add(key);
|
|
34
|
+
return true;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
const policyByKind = (policies, fallback = everyReading) => () => {
|
|
38
|
+
const tests = new Map();
|
|
39
|
+
const fallbackTest = fallback();
|
|
40
|
+
return reading => {
|
|
41
|
+
const policy = policies[reading.measurementTypeKey];
|
|
42
|
+
if (!policy) {
|
|
43
|
+
return fallbackTest(reading);
|
|
44
|
+
}
|
|
45
|
+
const test = tests.get(reading.measurementTypeKey) ?? policy();
|
|
46
|
+
tests.set(reading.measurementTypeKey, test);
|
|
47
|
+
return test(reading);
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/** A driver's events minus the readings `policy` drops. */
|
|
52
|
+
async function* keepReadings(events, policy) {
|
|
53
|
+
const keep = policy();
|
|
54
|
+
for await (const event of events) {
|
|
55
|
+
if (event.kind !== "reading" || keep(event.reading)) {
|
|
56
|
+
yield event;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export { dailyTotalsOnly, everyReading, firstReadingPerKind, keepReadings, policyByKind };
|
|
61
|
+
//# sourceMappingURL=result-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["dailyTotalDay","everyReading","firstReadingPerKind","reported","Set","measurementTypeKey","has","add","dailyTotalsOnly","reading","day","Date","now","undefined","key","policyByKind","policies","fallback","tests","Map","fallbackTest","policy","test","get","set","keepReadings","events","keep","event","kind"],"sourceRoot":"../../../../../src","sources":["modules/next/bluetooth/result-policy.ts"],"mappings":";;AAEA,SAASA,aAAa,QAAQ,8CAA2C;;AAIzE;;AAGA,MAAMC,YAA0B,GAAGA,CAAA,KAAM,MAAM,IAAI;AAEnD,MAAMC,mBAAiC,GAAGA,CAAA,KAAM;EAC9C,MAAMC,QAAQ,GAAG,IAAIC,GAAG,CAAqB,CAAC;EAE9C,OAAO,CAAC;IAAEC;EAAmB,CAAC,KAAK;IACjC,IAAIF,QAAQ,CAACG,GAAG,CAACD,kBAAkB,CAAC,EAAE;MACpC,OAAO,KAAK;IACd;IAEAF,QAAQ,CAACI,GAAG,CAACF,kBAAkB,CAAC;IAEhC,OAAO,IAAI;EACb,CAAC;AACH,CAAC;;AAED;AACA,MAAMG,eAA6B,GAAGA,CAAA,KAAM;EAC1C,MAAML,QAAQ,GAAG,IAAIC,GAAG,CAAS,CAAC;EAElC,OAAQK,OAAO,IAAK;IAClB,MAAMC,GAAG,GAAGV,aAAa,CAACS,OAAO,EAAEE,IAAI,CAACC,GAAG,CAAC,CAAC,CAAC;IAE9C,IAAIF,GAAG,KAAKG,SAAS,EAAE;MACrB,OAAO,IAAI;IACb;IAEA,MAAMC,GAAG,GAAG,GAAGL,OAAO,CAACJ,kBAAkB,IAAIK,GAAG,EAAE;IAElD,IAAIA,GAAG,KAAK,QAAQ,IAAIP,QAAQ,CAACG,GAAG,CAACQ,GAAG,CAAC,EAAE;MACzC,OAAO,KAAK;IACd;IAEAX,QAAQ,CAACI,GAAG,CAACO,GAAG,CAAC;IAEjB,OAAO,IAAI;EACb,CAAC;AACH,CAAC;AAED,MAAMC,YAAY,GAAGA,CACnBC,QAA2D,EAC3DC,QAAsB,GAAGhB,YAAY,KAErC,MAAM;EACJ,MAAMiB,KAAK,GAAG,IAAIC,GAAG,CAAwD,CAAC;EAC9E,MAAMC,YAAY,GAAGH,QAAQ,CAAC,CAAC;EAE/B,OAAQR,OAAO,IAAK;IAClB,MAAMY,MAAM,GAAGL,QAAQ,CAACP,OAAO,CAACJ,kBAAkB,CAAC;IAEnD,IAAI,CAACgB,MAAM,EAAE;MACX,OAAOD,YAAY,CAACX,OAAO,CAAC;IAC9B;IAEA,MAAMa,IAAI,GAAGJ,KAAK,CAACK,GAAG,CAACd,OAAO,CAACJ,kBAAkB,CAAC,IAAIgB,MAAM,CAAC,CAAC;IAE9DH,KAAK,CAACM,GAAG,CAACf,OAAO,CAACJ,kBAAkB,EAAEiB,IAAI,CAAC;IAE3C,OAAOA,IAAI,CAACb,OAAO,CAAC;EACtB,CAAC;AACH,CAAC;;AAEH;AACA,gBAAgBgB,YAAYA,CAACC,MAAkC,EAAEL,MAAoB,EAA8B;EACjH,MAAMM,IAAI,GAAGN,MAAM,CAAC,CAAC;EAErB,WAAW,MAAMO,KAAK,IAAIF,MAAM,EAAE;IAChC,IAAIE,KAAK,CAACC,IAAI,KAAK,SAAS,IAAIF,IAAI,CAACC,KAAK,CAACnB,OAAO,CAAC,EAAE;MACnD,MAAMmB,KAAK;IACb;EACF;AACF;AAEA,SAASpB,eAAe,EAAEP,YAAY,EAAEC,mBAAmB,EAAEuB,YAAY,EAAEV,YAAY","ignoreList":[]}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { MeasurementTypeKey } from "@ovok/core/next";
|
|
4
|
+
import { BloodPressureStates } from "../../bt-management/types/blood-pressure-states.js";
|
|
5
|
+
import { sigUuid } from "../../bt-management/utils/sig-uuid.js";
|
|
6
|
+
import { dateTimeAt, decodeFrame, floatAt, roundTo, sfloatAt, withDefined } from "./sig-values.js";
|
|
7
|
+
const KPA_TO_MMHG = 7.50062;
|
|
8
|
+
const KG_PER_SI_COUNT = 0.005;
|
|
9
|
+
const KG_PER_IMPERIAL_COUNT = 0.01 * 0.45359237;
|
|
10
|
+
const WEIGHT_UNSUCCESSFUL = 0xffff;
|
|
11
|
+
const DATE_TIME_BYTES = 7;
|
|
12
|
+
const BP_KPA = 0x01;
|
|
13
|
+
const BP_TIMESTAMP = 0x02;
|
|
14
|
+
const BP_PULSE = 0x04;
|
|
15
|
+
const BP_USER = 0x08;
|
|
16
|
+
const BP_STATUS = 0x10;
|
|
17
|
+
const BP_BODY_MOVEMENT = 0x01;
|
|
18
|
+
const BP_LOOSE_CUFF = 0x02;
|
|
19
|
+
const BP_IRREGULAR_PULSE = 0x04;
|
|
20
|
+
const TEMPERATURE_FAHRENHEIT = 0x01;
|
|
21
|
+
const TEMPERATURE_TIMESTAMP = 0x02;
|
|
22
|
+
const WEIGHT_IMPERIAL = 0x01;
|
|
23
|
+
const WEIGHT_TIMESTAMP = 0x02;
|
|
24
|
+
const PLX_TIMESTAMP = 0x01;
|
|
25
|
+
const HEART_RATE_UINT16 = 0x01;
|
|
26
|
+
const HEART_RATE_CONTACT_BITS = 0x06;
|
|
27
|
+
const HEART_RATE_NO_CONTACT = 0x04;
|
|
28
|
+
|
|
29
|
+
/** Core does not export its status enum; this one has the same values. */
|
|
30
|
+
|
|
31
|
+
const bloodPressureStatus = status => {
|
|
32
|
+
if (status & BP_BODY_MOVEMENT) {
|
|
33
|
+
return BloodPressureStates.DISTURB_DETECTED;
|
|
34
|
+
}
|
|
35
|
+
return status & BP_LOOSE_CUFF ? BloodPressureStates.LOOSE_SLEEVE : BloodPressureStates.REGULAR;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/** The fields a blood-pressure frame's flags add after the pressures, each in flag order. */
|
|
39
|
+
const bloodPressureExtras = (view, flags) => {
|
|
40
|
+
let offset = 7;
|
|
41
|
+
const extras = {};
|
|
42
|
+
if (flags & BP_TIMESTAMP) {
|
|
43
|
+
extras.recordedAt = dateTimeAt(view, offset);
|
|
44
|
+
offset += DATE_TIME_BYTES;
|
|
45
|
+
}
|
|
46
|
+
if (flags & BP_PULSE) {
|
|
47
|
+
extras.heartRate = sfloatAt(view, offset);
|
|
48
|
+
offset += 2;
|
|
49
|
+
}
|
|
50
|
+
if (flags & BP_USER) {
|
|
51
|
+
const user = view.getUint8(offset);
|
|
52
|
+
extras.memorySlot = user < 2 ? user + 1 : undefined;
|
|
53
|
+
offset += 1;
|
|
54
|
+
}
|
|
55
|
+
if (flags & BP_STATUS) {
|
|
56
|
+
const status = view.getUint16(offset, true);
|
|
57
|
+
extras.status = bloodPressureStatus(status);
|
|
58
|
+
extras.irregularHeartbeat = status & BP_IRREGULAR_PULSE ? true : undefined;
|
|
59
|
+
}
|
|
60
|
+
return extras;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/** Blood Pressure Measurement 0x2A35, in mmHg. */
|
|
64
|
+
const bloodPressure = view => {
|
|
65
|
+
const flags = view.getUint8(0);
|
|
66
|
+
const pressure = value => flags & BP_KPA ? roundTo(value * KPA_TO_MMHG, 0) : value;
|
|
67
|
+
const [systolic, diastolic, mean] = [1, 3, 5].map(offset => sfloatAt(view, offset));
|
|
68
|
+
if (systolic === undefined || diastolic === undefined) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
const reading = {
|
|
72
|
+
measurementTypeKey: MeasurementTypeKey.bloodPressure,
|
|
73
|
+
systolic: pressure(systolic),
|
|
74
|
+
diastolic: pressure(diastolic)
|
|
75
|
+
};
|
|
76
|
+
return withDefined(reading, {
|
|
77
|
+
meanArterialPressure: mean === undefined ? undefined : pressure(mean),
|
|
78
|
+
...bloodPressureExtras(view, flags)
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/** Temperature Measurement 0x2A1C, in Celsius. */
|
|
83
|
+
const temperature = view => {
|
|
84
|
+
const flags = view.getUint8(0);
|
|
85
|
+
const value = floatAt(view, 1);
|
|
86
|
+
if (value === undefined) {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
const reading = {
|
|
90
|
+
measurementTypeKey: MeasurementTypeKey.temperature,
|
|
91
|
+
bodyTemp: flags & TEMPERATURE_FAHRENHEIT ? roundTo((value - 32) * 5 / 9, 2) : value
|
|
92
|
+
};
|
|
93
|
+
return flags & TEMPERATURE_TIMESTAMP ? withDefined(reading, {
|
|
94
|
+
recordedAt: dateTimeAt(view, 5)
|
|
95
|
+
}) : reading;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/** Weight Measurement 0x2A9D, in kilograms. */
|
|
99
|
+
const bodyWeight = view => {
|
|
100
|
+
const flags = view.getUint8(0);
|
|
101
|
+
const counts = view.getUint16(1, true);
|
|
102
|
+
if (counts === WEIGHT_UNSUCCESSFUL) {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
const reading = {
|
|
106
|
+
measurementTypeKey: MeasurementTypeKey.bodyWeight,
|
|
107
|
+
bodyWeight: roundTo(counts * (flags & WEIGHT_IMPERIAL ? KG_PER_IMPERIAL_COUNT : KG_PER_SI_COUNT), 3)
|
|
108
|
+
};
|
|
109
|
+
return flags & WEIGHT_TIMESTAMP ? withDefined(reading, {
|
|
110
|
+
recordedAt: dateTimeAt(view, 3)
|
|
111
|
+
}) : reading;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/** PLX Spot-Check Measurement 0x2A5E. */
|
|
115
|
+
const pulseOximetry = view => {
|
|
116
|
+
const flags = view.getUint8(0);
|
|
117
|
+
const bloodOxygen = sfloatAt(view, 1);
|
|
118
|
+
const pulseRate = sfloatAt(view, 3);
|
|
119
|
+
if (bloodOxygen === undefined || pulseRate === undefined) {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
const reading = {
|
|
123
|
+
measurementTypeKey: MeasurementTypeKey.bloodOxygenPulseRate,
|
|
124
|
+
bloodOxygen,
|
|
125
|
+
pulseRate
|
|
126
|
+
};
|
|
127
|
+
return flags & PLX_TIMESTAMP ? withDefined(reading, {
|
|
128
|
+
recordedAt: dateTimeAt(view, 5)
|
|
129
|
+
}) : reading;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
/** Heart Rate Measurement 0x2A37; a strap reporting no skin contact has no reading. */
|
|
133
|
+
const heartRate = view => {
|
|
134
|
+
const flags = view.getUint8(0);
|
|
135
|
+
if ((flags & HEART_RATE_CONTACT_BITS) === HEART_RATE_NO_CONTACT) {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
const reading = {
|
|
139
|
+
measurementTypeKey: MeasurementTypeKey.heartRate,
|
|
140
|
+
heartRate: flags & HEART_RATE_UINT16 ? view.getUint16(1, true) : view.getUint8(1)
|
|
141
|
+
};
|
|
142
|
+
return reading;
|
|
143
|
+
};
|
|
144
|
+
const subscribed = (service, characteristic, decode) => async function* (link) {
|
|
145
|
+
for await (const frame of link.subscribe(sigUuid(service), sigUuid(characteristic))) {
|
|
146
|
+
const reading = decodeFrame(decode, frame);
|
|
147
|
+
if (reading) {
|
|
148
|
+
yield reading;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
/** By the ids the SDK catalog gives the Bluetooth SIG profiles. */
|
|
154
|
+
const SIG_PROTOCOLS = new Map([["standard-blood-pressure", subscribed("1810", "2a35", bloodPressure)], ["standard-body-temperature", subscribed("1809", "2a1c", temperature)], ["standard-body-weight", subscribed("181d", "2a9d", bodyWeight)], ["standard-blood-oxygen-pulse-rate", subscribed("1822", "2a5e", pulseOximetry)], ["standard-heart-rate", subscribed("180d", "2a37", heartRate)]]);
|
|
155
|
+
export { bloodPressure, bodyWeight, heartRate, pulseOximetry, SIG_PROTOCOLS, temperature };
|
|
156
|
+
//# sourceMappingURL=sig-profiles.js.map
|