@hangtime/grip-connect 0.5.2 → 0.5.3
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/dist/{download.d.ts → helpers/download.d.ts} +1 -1
- package/dist/helpers/is-device.d.ts +16 -16
- package/dist/helpers/is-device.js +18 -18
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -5
- package/dist/interfaces/callback.interface.d.ts +49 -0
- package/dist/interfaces/command.interface.d.ts +85 -0
- package/dist/interfaces/device.interface.d.ts +19 -19
- package/dist/models/device/entralpi.model.js +9 -14
- package/dist/models/device/forceboard.model.js +4 -4
- package/dist/models/device/kilterboard.model.d.ts +61 -2
- package/dist/models/device/kilterboard.model.js +91 -11
- package/dist/models/device/motherboard.model.d.ts +24 -1
- package/dist/models/device/motherboard.model.js +56 -33
- package/dist/models/device/progressor.model.js +61 -22
- package/dist/models/device/wh-c06.model.d.ts +7 -0
- package/dist/models/device/wh-c06.model.js +18 -17
- package/dist/models/device.model.d.ts +71 -22
- package/dist/models/device.model.js +76 -21
- package/package.json +1 -1
- package/src/{download.ts → helpers/download.ts} +1 -1
- package/src/helpers/is-device.ts +23 -23
- package/src/index.ts +4 -5
- package/src/interfaces/callback.interface.ts +56 -0
- package/src/interfaces/command.interface.ts +106 -0
- package/src/interfaces/device.interface.ts +22 -21
- package/src/models/device/entralpi.model.ts +9 -15
- package/src/models/device/forceboard.model.ts +4 -4
- package/src/models/device/kilterboard.model.ts +93 -13
- package/src/models/device/motherboard.model.ts +61 -37
- package/src/models/device/progressor.model.ts +64 -22
- package/src/models/device/wh-c06.model.ts +20 -18
- package/src/models/device.model.ts +92 -30
- package/dist/commands/climbro.d.ts +0 -6
- package/dist/commands/climbro.js +0 -5
- package/dist/commands/entralpi.d.ts +0 -6
- package/dist/commands/entralpi.js +0 -5
- package/dist/commands/forceboard.d.ts +0 -6
- package/dist/commands/forceboard.js +0 -5
- package/dist/commands/index.d.ts +0 -7
- package/dist/commands/index.js +0 -7
- package/dist/commands/kilterboard.d.ts +0 -35
- package/dist/commands/kilterboard.js +0 -65
- package/dist/commands/motherboard.d.ts +0 -6
- package/dist/commands/motherboard.js +0 -13
- package/dist/commands/mysmartboard.d.ts +0 -6
- package/dist/commands/mysmartboard.js +0 -5
- package/dist/commands/progressor.d.ts +0 -17
- package/dist/commands/progressor.js +0 -30
- package/dist/commands/wh-c06.d.ts +0 -6
- package/dist/commands/wh-c06.js +0 -5
- package/dist/types/commands.d.ts +0 -18
- package/dist/types/notify.d.ts +0 -14
- package/src/commands/climbro.ts +0 -6
- package/src/commands/entralpi.ts +0 -6
- package/src/commands/forceboard.ts +0 -6
- package/src/commands/index.ts +0 -13
- package/src/commands/kilterboard.ts +0 -64
- package/src/commands/motherboard.ts +0 -14
- package/src/commands/mysmartboard.ts +0 -6
- package/src/commands/progressor.ts +0 -31
- package/src/commands/wh-c06.ts +0 -6
- package/src/types/commands.ts +0 -21
- package/src/types/notify.ts +0 -14
- /package/dist/{download.js → helpers/download.js} +0 -0
- /package/dist/{is-active.d.ts → helpers/is-active.d.ts} +0 -0
- /package/dist/{is-active.js → helpers/is-active.js} +0 -0
- /package/dist/{tare.d.ts → helpers/tare.d.ts} +0 -0
- /package/dist/{tare.js → helpers/tare.js} +0 -0
- /package/dist/{types/commands.js → interfaces/callback.interface.js} +0 -0
- /package/dist/{types/download.js → interfaces/command.interface.js} +0 -0
- /package/dist/{types/download.d.ts → interfaces/download.interface.d.ts} +0 -0
- /package/dist/{types/notify.js → interfaces/download.interface.js} +0 -0
- /package/src/{is-active.ts → helpers/is-active.ts} +0 -0
- /package/src/{tare.ts → helpers/tare.ts} +0 -0
- /package/src/{types/download.ts → interfaces/download.interface.ts} +0 -0
|
@@ -1,10 +1,33 @@
|
|
|
1
1
|
import { Device } from "../device.model";
|
|
2
2
|
import type { IMotherboard } from "../../interfaces/device/motherboard.interface";
|
|
3
|
-
export declare const CALIBRATION: never[][];
|
|
4
3
|
/**
|
|
5
4
|
* Represents a Griptonite Motherboard device
|
|
6
5
|
*/
|
|
7
6
|
export declare class Motherboard extends Device implements IMotherboard {
|
|
7
|
+
/**
|
|
8
|
+
* Length of the packet received from the device.
|
|
9
|
+
* @private
|
|
10
|
+
* @type {number}
|
|
11
|
+
*/
|
|
12
|
+
private PACKET_LENGTH;
|
|
13
|
+
/**
|
|
14
|
+
* Number of samples contained in the data packet.
|
|
15
|
+
* @private
|
|
16
|
+
* @type {number}
|
|
17
|
+
*/
|
|
18
|
+
private NUM_SAMPLES;
|
|
19
|
+
/**
|
|
20
|
+
* Buffer to store received data from the device.
|
|
21
|
+
* @private
|
|
22
|
+
* @type {number[]}
|
|
23
|
+
*/
|
|
24
|
+
private receiveBuffer;
|
|
25
|
+
/**
|
|
26
|
+
* Calibration data for each sensor of the device.
|
|
27
|
+
* @private
|
|
28
|
+
* @type {number[][][]}
|
|
29
|
+
*/
|
|
30
|
+
private CALIBRATION;
|
|
8
31
|
constructor();
|
|
9
32
|
/**
|
|
10
33
|
* Applies calibration to a sample value.
|
|
@@ -1,21 +1,35 @@
|
|
|
1
1
|
import { Device } from "../device.model";
|
|
2
|
-
import { applyTare } from "../../tare";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { DownloadPackets, emptyDownloadPackets } from "../../download";
|
|
6
|
-
// Constants
|
|
7
|
-
const PACKET_LENGTH = 32;
|
|
8
|
-
const NUM_SAMPLES = 3;
|
|
9
|
-
let MASS_MAX = "0";
|
|
10
|
-
let MASS_AVERAGE = "0";
|
|
11
|
-
let MASS_TOTAL_SUM = 0;
|
|
12
|
-
let DATAPOINT_COUNT = 0;
|
|
13
|
-
const receiveBuffer = [];
|
|
14
|
-
export const CALIBRATION = [[], [], [], []];
|
|
2
|
+
import { applyTare } from "../../helpers/tare";
|
|
3
|
+
import { checkActivity } from "../../helpers/is-active";
|
|
4
|
+
import { DownloadPackets, emptyDownloadPackets } from "../../helpers/download";
|
|
15
5
|
/**
|
|
16
6
|
* Represents a Griptonite Motherboard device
|
|
17
7
|
*/
|
|
18
8
|
export class Motherboard extends Device {
|
|
9
|
+
/**
|
|
10
|
+
* Length of the packet received from the device.
|
|
11
|
+
* @private
|
|
12
|
+
* @type {number}
|
|
13
|
+
*/
|
|
14
|
+
PACKET_LENGTH = 32;
|
|
15
|
+
/**
|
|
16
|
+
* Number of samples contained in the data packet.
|
|
17
|
+
* @private
|
|
18
|
+
* @type {number}
|
|
19
|
+
*/
|
|
20
|
+
NUM_SAMPLES = 3;
|
|
21
|
+
/**
|
|
22
|
+
* Buffer to store received data from the device.
|
|
23
|
+
* @private
|
|
24
|
+
* @type {number[]}
|
|
25
|
+
*/
|
|
26
|
+
receiveBuffer = [];
|
|
27
|
+
/**
|
|
28
|
+
* Calibration data for each sensor of the device.
|
|
29
|
+
* @private
|
|
30
|
+
* @type {number[][][]}
|
|
31
|
+
*/
|
|
32
|
+
CALIBRATION = [[], [], [], []];
|
|
19
33
|
constructor() {
|
|
20
34
|
super({
|
|
21
35
|
filters: [{ name: "Motherboard" }],
|
|
@@ -94,6 +108,15 @@ export class Motherboard extends Device {
|
|
|
94
108
|
],
|
|
95
109
|
},
|
|
96
110
|
],
|
|
111
|
+
commands: {
|
|
112
|
+
GET_SERIAL: "#",
|
|
113
|
+
START_WEIGHT_MEAS: "S30",
|
|
114
|
+
STOP_WEIGHT_MEAS: "", // All commands will stop the data stream.
|
|
115
|
+
GET_CALIBRATION: "C",
|
|
116
|
+
SLEEP: 0,
|
|
117
|
+
GET_TEXT: "T",
|
|
118
|
+
DEBUG_STREAM: "D",
|
|
119
|
+
},
|
|
97
120
|
});
|
|
98
121
|
}
|
|
99
122
|
/**
|
|
@@ -153,7 +176,7 @@ export class Motherboard extends Device {
|
|
|
153
176
|
// Check if the device is connected
|
|
154
177
|
if (this.isConnected()) {
|
|
155
178
|
// Write the command to get calibration data to the device
|
|
156
|
-
await this.write("uart", "tx",
|
|
179
|
+
await this.write("uart", "tx", this.commands.GET_CALIBRATION, 2500, (data) => {
|
|
157
180
|
console.log(data);
|
|
158
181
|
});
|
|
159
182
|
}
|
|
@@ -184,11 +207,11 @@ export class Motherboard extends Device {
|
|
|
184
207
|
if (value) {
|
|
185
208
|
if (value.buffer) {
|
|
186
209
|
for (let i = 0; i < value.byteLength; i++) {
|
|
187
|
-
receiveBuffer.push(value.getUint8(i));
|
|
210
|
+
this.receiveBuffer.push(value.getUint8(i));
|
|
188
211
|
}
|
|
189
212
|
let idx;
|
|
190
|
-
while ((idx = receiveBuffer.indexOf(10)) >= 0) {
|
|
191
|
-
const line = receiveBuffer.splice(0, idx + 1).slice(0, -1); // Combine and remove LF
|
|
213
|
+
while ((idx = this.receiveBuffer.indexOf(10)) >= 0) {
|
|
214
|
+
const line = this.receiveBuffer.splice(0, idx + 1).slice(0, -1); // Combine and remove LF
|
|
192
215
|
if (line.length > 0 && line[line.length - 1] === 13)
|
|
193
216
|
line.pop(); // Remove CR
|
|
194
217
|
const decoder = new TextDecoder("utf-8");
|
|
@@ -197,7 +220,7 @@ export class Motherboard extends Device {
|
|
|
197
220
|
// Check if the line is entirely hex characters
|
|
198
221
|
const isAllHex = /^[0-9A-Fa-f]+$/g.test(receivedData);
|
|
199
222
|
// Handle streaming packet
|
|
200
|
-
if (isAllHex && receivedData.length === PACKET_LENGTH) {
|
|
223
|
+
if (isAllHex && receivedData.length === this.PACKET_LENGTH) {
|
|
201
224
|
// Base-16 decode the string: convert hex pairs to byte values
|
|
202
225
|
const bytes = Array.from({ length: receivedData.length / 2 }, (_, i) => Number(`0x${receivedData.substring(i * 2, i * 2 + 2)}`));
|
|
203
226
|
// Translate header into packet, number of samples from the packet length
|
|
@@ -209,7 +232,7 @@ export class Motherboard extends Device {
|
|
|
209
232
|
masses: [],
|
|
210
233
|
};
|
|
211
234
|
const dataView = new DataView(new Uint8Array(bytes).buffer);
|
|
212
|
-
for (let i = 0; i < NUM_SAMPLES; i++) {
|
|
235
|
+
for (let i = 0; i < this.NUM_SAMPLES; i++) {
|
|
213
236
|
const sampleStart = 4 + 3 * i;
|
|
214
237
|
// Use DataView to read the 24-bit unsigned integer
|
|
215
238
|
const rawValue = dataView.getUint8(sampleStart) |
|
|
@@ -220,7 +243,7 @@ export class Motherboard extends Device {
|
|
|
220
243
|
if (packet.samples[i] >= 0x7fffff) {
|
|
221
244
|
packet.samples[i] -= 0x1000000;
|
|
222
245
|
}
|
|
223
|
-
packet.masses[i] = this.applyCalibration(packet.samples[i], CALIBRATION[i]);
|
|
246
|
+
packet.masses[i] = this.applyCalibration(packet.samples[i], this.CALIBRATION[i]);
|
|
224
247
|
}
|
|
225
248
|
// invert center and right values
|
|
226
249
|
packet.masses[1] *= -1;
|
|
@@ -240,31 +263,31 @@ export class Motherboard extends Device {
|
|
|
240
263
|
left -= applyTare(left);
|
|
241
264
|
center -= applyTare(center);
|
|
242
265
|
right -= applyTare(right);
|
|
243
|
-
|
|
266
|
+
this.massMax = Math.max(Number(this.massMax), Math.max(-1000, left + center + right)).toFixed(1);
|
|
244
267
|
// Update running sum and count
|
|
245
268
|
const currentMassTotal = Math.max(-1000, left + center + right);
|
|
246
|
-
|
|
247
|
-
|
|
269
|
+
this.massTotalSum += currentMassTotal;
|
|
270
|
+
this.dataPointCount++;
|
|
248
271
|
// Calculate the average dynamically
|
|
249
|
-
|
|
272
|
+
this.massAverage = (this.massTotalSum / this.dataPointCount).toFixed(1);
|
|
250
273
|
// Check if device is being used
|
|
251
274
|
checkActivity(center);
|
|
252
275
|
// Notify with weight data
|
|
253
276
|
this.notifyCallback({
|
|
254
277
|
massTotal: Math.max(-1000, left + center + right).toFixed(1),
|
|
255
|
-
massMax:
|
|
256
|
-
massAverage:
|
|
278
|
+
massMax: this.massMax,
|
|
279
|
+
massAverage: this.massAverage,
|
|
257
280
|
massLeft: Math.max(-1000, packet.masses[0]).toFixed(1),
|
|
258
281
|
massCenter: Math.max(-1000, packet.masses[1]).toFixed(1),
|
|
259
282
|
massRight: Math.max(-1000, packet.masses[2]).toFixed(1),
|
|
260
283
|
});
|
|
261
284
|
}
|
|
262
|
-
else if (this.writeLast ===
|
|
285
|
+
else if (this.writeLast === this.commands.GET_CALIBRATION) {
|
|
263
286
|
// check data integrity
|
|
264
287
|
if ((receivedData.match(/,/g) || []).length === 3) {
|
|
265
288
|
const parts = receivedData.split(",");
|
|
266
289
|
const numericParts = parts.map((x) => parseFloat(x));
|
|
267
|
-
CALIBRATION[numericParts[0]].push(numericParts.slice(1));
|
|
290
|
+
this.CALIBRATION[numericParts[0]].push(numericParts.slice(1));
|
|
268
291
|
}
|
|
269
292
|
}
|
|
270
293
|
else {
|
|
@@ -331,7 +354,7 @@ export class Motherboard extends Device {
|
|
|
331
354
|
if (this.isConnected()) {
|
|
332
355
|
// Write serial number command to the Motherboard and read output
|
|
333
356
|
let response = undefined;
|
|
334
|
-
await this.write("uart", "tx",
|
|
357
|
+
await this.write("uart", "tx", this.commands.GET_SERIAL, 250, (data) => {
|
|
335
358
|
response = data;
|
|
336
359
|
});
|
|
337
360
|
return response;
|
|
@@ -346,7 +369,7 @@ export class Motherboard extends Device {
|
|
|
346
369
|
stop = async () => {
|
|
347
370
|
if (this.isConnected()) {
|
|
348
371
|
// Stop stream of device
|
|
349
|
-
await this.write("uart", "tx",
|
|
372
|
+
await this.write("uart", "tx", this.commands.STOP_WEIGHT_MEAS, 0);
|
|
350
373
|
}
|
|
351
374
|
};
|
|
352
375
|
/**
|
|
@@ -360,11 +383,11 @@ export class Motherboard extends Device {
|
|
|
360
383
|
emptyDownloadPackets();
|
|
361
384
|
// Device specific logic
|
|
362
385
|
// Read calibration data if not already available
|
|
363
|
-
if (!CALIBRATION[0].length) {
|
|
386
|
+
if (!this.CALIBRATION[0].length) {
|
|
364
387
|
await this.calibration();
|
|
365
388
|
}
|
|
366
389
|
// Start streaming data
|
|
367
|
-
await this.write("uart", "tx",
|
|
390
|
+
await this.write("uart", "tx", this.commands.START_WEIGHT_MEAS, duration);
|
|
368
391
|
// Stop streaming if duration is set
|
|
369
392
|
if (duration !== 0) {
|
|
370
393
|
await this.stop();
|
|
@@ -385,7 +408,7 @@ export class Motherboard extends Device {
|
|
|
385
408
|
if (this.isConnected()) {
|
|
386
409
|
// Write text information command to the Motherboard and read output
|
|
387
410
|
let response = undefined;
|
|
388
|
-
await this.write("uart", "tx",
|
|
411
|
+
await this.write("uart", "tx", this.commands.GET_TEXT, 250, (data) => {
|
|
389
412
|
response = data;
|
|
390
413
|
});
|
|
391
414
|
return response;
|
|
@@ -1,14 +1,39 @@
|
|
|
1
1
|
import { Device } from "../device.model";
|
|
2
|
-
import { ProgressorCommands, ProgressorResponses } from "../../commands/progressor";
|
|
3
2
|
import struct from "../../helpers/struct";
|
|
4
|
-
import { checkActivity } from "../../is-active";
|
|
5
|
-
import { DownloadPackets, emptyDownloadPackets } from "../../download";
|
|
6
|
-
import { applyTare } from "../../tare";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
import { checkActivity } from "../../helpers/is-active";
|
|
4
|
+
import { DownloadPackets, emptyDownloadPackets } from "../../helpers/download";
|
|
5
|
+
import { applyTare } from "../../helpers/tare";
|
|
6
|
+
/**
|
|
7
|
+
* Represents the possible responses of a Tindeq Progressor device.
|
|
8
|
+
*/
|
|
9
|
+
var ProgressorResponses;
|
|
10
|
+
(function (ProgressorResponses) {
|
|
11
|
+
/**
|
|
12
|
+
* Response received after sending a command to the device.
|
|
13
|
+
* This could include acknowledgment or specific data related to the command sent.
|
|
14
|
+
*/
|
|
15
|
+
ProgressorResponses[ProgressorResponses["COMMAND_RESPONSE"] = 0] = "COMMAND_RESPONSE";
|
|
16
|
+
/**
|
|
17
|
+
* Data representing a weight measurement from the device.
|
|
18
|
+
* Typically used for tracking load or force applied.
|
|
19
|
+
*/
|
|
20
|
+
ProgressorResponses[ProgressorResponses["WEIGHT_MEASURE"] = 1] = "WEIGHT_MEASURE";
|
|
21
|
+
/**
|
|
22
|
+
* Peak rate of force development (RFD) measurement.
|
|
23
|
+
* This measures how quickly the force is applied over time.
|
|
24
|
+
*/
|
|
25
|
+
ProgressorResponses[ProgressorResponses["PEAK_RFD_MEAS"] = 2] = "PEAK_RFD_MEAS";
|
|
26
|
+
/**
|
|
27
|
+
* Series of peak rate of force development (RFD) measurements.
|
|
28
|
+
* This could be used for analyzing force trends over multiple data points.
|
|
29
|
+
*/
|
|
30
|
+
ProgressorResponses[ProgressorResponses["PEAK_RFD_MEAS_SERIES"] = 3] = "PEAK_RFD_MEAS_SERIES";
|
|
31
|
+
/**
|
|
32
|
+
* Low battery warning from the device.
|
|
33
|
+
* Indicates that the battery level is below a critical threshold.
|
|
34
|
+
*/
|
|
35
|
+
ProgressorResponses[ProgressorResponses["LOW_BATTERY_WARNING"] = 4] = "LOW_BATTERY_WARNING";
|
|
36
|
+
})(ProgressorResponses || (ProgressorResponses = {}));
|
|
12
37
|
/**
|
|
13
38
|
* Represents a Tindeq Progressor device
|
|
14
39
|
*/
|
|
@@ -47,6 +72,20 @@ export class Progressor extends Device {
|
|
|
47
72
|
],
|
|
48
73
|
},
|
|
49
74
|
],
|
|
75
|
+
commands: {
|
|
76
|
+
TARE_SCALE: "d", // 0x64
|
|
77
|
+
START_WEIGHT_MEAS: "e", // 0x65
|
|
78
|
+
STOP_WEIGHT_MEAS: "f", // 0x66
|
|
79
|
+
START_PEAK_RFD_MEAS: "g", // 0x67
|
|
80
|
+
START_PEAK_RFD_MEAS_SERIES: "h", // 0x68
|
|
81
|
+
ADD_CALIB_POINT: "i", // 0x69
|
|
82
|
+
SAVE_CALIB: "j", // 0x6a
|
|
83
|
+
GET_FW_VERSION: "k", // 0x6b
|
|
84
|
+
GET_ERR_INFO: "l", // 0x6c
|
|
85
|
+
CLR_ERR_INFO: "m", // 0x6d
|
|
86
|
+
SLEEP: "n", // 0x6e
|
|
87
|
+
GET_BATT_VLTG: "o", // 0x6f
|
|
88
|
+
},
|
|
50
89
|
});
|
|
51
90
|
}
|
|
52
91
|
/**
|
|
@@ -56,7 +95,7 @@ export class Progressor extends Device {
|
|
|
56
95
|
battery = async () => {
|
|
57
96
|
if (this.isConnected()) {
|
|
58
97
|
let response = undefined;
|
|
59
|
-
await this.write("progressor", "tx",
|
|
98
|
+
await this.write("progressor", "tx", this.commands.GET_BATT_VLTG, 250, (data) => {
|
|
60
99
|
response = data;
|
|
61
100
|
});
|
|
62
101
|
return response;
|
|
@@ -73,7 +112,7 @@ export class Progressor extends Device {
|
|
|
73
112
|
if (this.isConnected()) {
|
|
74
113
|
// Read firmware version from the device
|
|
75
114
|
let response = undefined;
|
|
76
|
-
await this.write("progressor", "tx",
|
|
115
|
+
await this.write("progressor", "tx", this.commands.GET_FW_VERSION, 250, (data) => {
|
|
77
116
|
response = data;
|
|
78
117
|
});
|
|
79
118
|
return response;
|
|
@@ -113,18 +152,18 @@ export class Progressor extends Device {
|
|
|
113
152
|
// Tare correction
|
|
114
153
|
weight -= applyTare(weight);
|
|
115
154
|
// Check for max weight
|
|
116
|
-
|
|
155
|
+
this.massMax = Math.max(Number(this.massMax), Number(weight)).toFixed(1);
|
|
117
156
|
// Update running sum and count
|
|
118
157
|
const currentMassTotal = Math.max(-1000, Number(weight));
|
|
119
|
-
|
|
120
|
-
|
|
158
|
+
this.massTotalSum += currentMassTotal;
|
|
159
|
+
this.dataPointCount++;
|
|
121
160
|
// Calculate the average dynamically
|
|
122
|
-
|
|
161
|
+
this.massAverage = (this.massTotalSum / this.dataPointCount).toFixed(1);
|
|
123
162
|
// Check if device is being used
|
|
124
163
|
checkActivity(weight);
|
|
125
164
|
this.notifyCallback({
|
|
126
|
-
massMax:
|
|
127
|
-
massAverage:
|
|
165
|
+
massMax: this.massMax,
|
|
166
|
+
massAverage: this.massAverage,
|
|
128
167
|
massTotal: Math.max(-1000, weight).toFixed(1),
|
|
129
168
|
});
|
|
130
169
|
}
|
|
@@ -134,13 +173,13 @@ export class Progressor extends Device {
|
|
|
134
173
|
if (!this.writeLast)
|
|
135
174
|
return;
|
|
136
175
|
let value = "";
|
|
137
|
-
if (this.writeLast ===
|
|
176
|
+
if (this.writeLast === this.commands.GET_BATT_VLTG) {
|
|
138
177
|
value = new DataView(data.buffer, 2).getUint32(0, true).toString();
|
|
139
178
|
}
|
|
140
|
-
else if (this.writeLast ===
|
|
179
|
+
else if (this.writeLast === this.commands.GET_FW_VERSION) {
|
|
141
180
|
value = new TextDecoder().decode(data.buffer.slice(2));
|
|
142
181
|
}
|
|
143
|
-
else if (this.writeLast ===
|
|
182
|
+
else if (this.writeLast === this.commands.GET_ERR_INFO) {
|
|
144
183
|
value = new TextDecoder().decode(data.buffer.slice(2));
|
|
145
184
|
}
|
|
146
185
|
this.writeCallback(value);
|
|
@@ -161,7 +200,7 @@ export class Progressor extends Device {
|
|
|
161
200
|
stop = async () => {
|
|
162
201
|
if (this.isConnected()) {
|
|
163
202
|
// Stop stream of device
|
|
164
|
-
await this.write("progressor", "tx",
|
|
203
|
+
await this.write("progressor", "tx", this.commands.STOP_WEIGHT_MEAS, 0);
|
|
165
204
|
}
|
|
166
205
|
};
|
|
167
206
|
/**
|
|
@@ -174,7 +213,7 @@ export class Progressor extends Device {
|
|
|
174
213
|
// Reset download packets
|
|
175
214
|
emptyDownloadPackets();
|
|
176
215
|
// Start streaming data
|
|
177
|
-
await this.write("progressor", "tx",
|
|
216
|
+
await this.write("progressor", "tx", this.commands.START_WEIGHT_MEAS, duration);
|
|
178
217
|
// Stop streaming if duration is set
|
|
179
218
|
if (duration !== 0) {
|
|
180
219
|
await this.stop();
|
|
@@ -5,6 +5,13 @@ import type { IWHC06 } from "../../interfaces/device/wh-c06.interface";
|
|
|
5
5
|
* Enable 'Experimental Web Platform features' Chrome Flags.
|
|
6
6
|
*/
|
|
7
7
|
export declare class WHC06 extends Device implements IWHC06 {
|
|
8
|
+
/**
|
|
9
|
+
* Offset for the byte location in the manufacturer data to extract the weight.
|
|
10
|
+
* This value is constant across all instances of the class.
|
|
11
|
+
* @type {number}
|
|
12
|
+
* @constant
|
|
13
|
+
*/
|
|
14
|
+
private static readonly WEIGHT_OFFSET;
|
|
8
15
|
constructor();
|
|
9
16
|
/**
|
|
10
17
|
* Connects to a Bluetooth device.
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { Device } from "../device.model";
|
|
2
|
-
import { applyTare } from "../../tare";
|
|
3
|
-
import { checkActivity } from "../../is-active";
|
|
4
|
-
// Constants
|
|
5
|
-
let MASS_MAX = "0";
|
|
6
|
-
let MASS_AVERAGE = "0";
|
|
7
|
-
let MASS_TOTAL_SUM = 0;
|
|
8
|
-
let DATAPOINT_COUNT = 0;
|
|
9
|
-
const WEIGHT_OFFSET = 10;
|
|
10
|
-
// const STABLE_OFFSET = 14
|
|
2
|
+
import { applyTare } from "../../helpers/tare";
|
|
3
|
+
import { checkActivity } from "../../helpers/is-active";
|
|
11
4
|
/**
|
|
12
5
|
* Represents a Weiheng - WH-C06 (or MAT Muscle Meter) device
|
|
13
6
|
* Enable 'Experimental Web Platform features' Chrome Flags.
|
|
14
7
|
*/
|
|
15
8
|
export class WHC06 extends Device {
|
|
9
|
+
/**
|
|
10
|
+
* Offset for the byte location in the manufacturer data to extract the weight.
|
|
11
|
+
* This value is constant across all instances of the class.
|
|
12
|
+
* @type {number}
|
|
13
|
+
* @constant
|
|
14
|
+
*/
|
|
15
|
+
static WEIGHT_OFFSET = 10;
|
|
16
|
+
// private static readonly STABLE_OFFSET = 14
|
|
16
17
|
constructor() {
|
|
17
18
|
super({
|
|
18
19
|
filters: [
|
|
@@ -52,26 +53,26 @@ export class WHC06 extends Device {
|
|
|
52
53
|
const data = event.manufacturerData.get(MANUFACTURER_ID);
|
|
53
54
|
if (data) {
|
|
54
55
|
// Handle recieved data
|
|
55
|
-
const weight = (data.getUint8(WEIGHT_OFFSET) << 8) | data.getUint8(WEIGHT_OFFSET + 1);
|
|
56
|
+
const weight = (data.getUint8(WHC06.WEIGHT_OFFSET) << 8) | data.getUint8(WHC06.WEIGHT_OFFSET + 1);
|
|
56
57
|
// const stable = (data.getUint8(STABLE_OFFSET) & 0xf0) >> 4
|
|
57
58
|
// const unit = data.getUint8(STABLE_OFFSET) & 0x0f
|
|
58
59
|
let numericData = weight / 100;
|
|
59
60
|
// Tare correction
|
|
60
61
|
numericData -= applyTare(numericData);
|
|
61
|
-
// Update
|
|
62
|
-
|
|
62
|
+
// Update massMax
|
|
63
|
+
this.massMax = Math.max(Number(this.massMax), numericData).toFixed(1);
|
|
63
64
|
// Update running sum and count
|
|
64
65
|
const currentMassTotal = Math.max(-1000, numericData);
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
this.massTotalSum += currentMassTotal;
|
|
67
|
+
this.dataPointCount++;
|
|
67
68
|
// Calculate the average dynamically
|
|
68
|
-
|
|
69
|
+
this.massAverage = (this.massTotalSum / this.dataPointCount).toFixed(1);
|
|
69
70
|
// Check if device is being used
|
|
70
71
|
checkActivity(numericData);
|
|
71
72
|
// Notify with weight data
|
|
72
73
|
this.notifyCallback({
|
|
73
|
-
massMax:
|
|
74
|
-
massAverage:
|
|
74
|
+
massMax: this.massMax,
|
|
75
|
+
massAverage: this.massAverage,
|
|
75
76
|
massTotal: Math.max(-1000, numericData).toFixed(1),
|
|
76
77
|
});
|
|
77
78
|
}
|
|
@@ -1,14 +1,79 @@
|
|
|
1
1
|
import { BaseModel } from "./../models/base.model";
|
|
2
2
|
import type { IDevice, Service } from "../interfaces/device.interface";
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
import type { NotifyCallback, WriteCallback } from "../interfaces/callback.interface";
|
|
4
|
+
import type { Commands } from "../interfaces/command.interface";
|
|
5
|
+
export declare abstract class Device extends BaseModel implements IDevice {
|
|
6
|
+
/**
|
|
7
|
+
* Filters to identify the device during Bluetooth scanning.
|
|
8
|
+
* Used to match devices that meet specific criteria such as name, service UUIDs, etc.
|
|
9
|
+
*/
|
|
9
10
|
filters: BluetoothLEScanFilter[];
|
|
11
|
+
/**
|
|
12
|
+
* Array of services provided by the device.
|
|
13
|
+
* Services represent functionalities that the device supports, such as weight measurement, battery information, or custom services.
|
|
14
|
+
*/
|
|
10
15
|
services: Service[];
|
|
16
|
+
/**
|
|
17
|
+
* Reference to the `BluetoothDevice` object representing this device.
|
|
18
|
+
* This is the actual device object obtained from the Web Bluetooth API after a successful connection.
|
|
19
|
+
*/
|
|
11
20
|
bluetooth?: BluetoothDevice | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Object representing the set of commands available for this device.
|
|
23
|
+
* These commands allow communication with the device to perform various operations such as starting measurements, retrieving data, or calibrating the device.
|
|
24
|
+
*/
|
|
25
|
+
commands: Commands;
|
|
26
|
+
/**
|
|
27
|
+
* The BluetoothRemoteGATTServer interface of the Web Bluetooth API represents a GATT Server on a remote device.
|
|
28
|
+
*/
|
|
29
|
+
private server;
|
|
30
|
+
/**
|
|
31
|
+
* Maximum mass recorded from the device, initialized to "0".
|
|
32
|
+
* @type {string}
|
|
33
|
+
* @protected
|
|
34
|
+
*/
|
|
35
|
+
protected massMax: string;
|
|
36
|
+
/**
|
|
37
|
+
* Average mass calculated from the device data, initialized to "0".
|
|
38
|
+
* @type {string}
|
|
39
|
+
* @protected
|
|
40
|
+
*/
|
|
41
|
+
protected massAverage: string;
|
|
42
|
+
/**
|
|
43
|
+
* Total sum of all mass data points recorded from the device.
|
|
44
|
+
* Used to calculate the average mass.
|
|
45
|
+
* @type {number}
|
|
46
|
+
* @protected
|
|
47
|
+
*/
|
|
48
|
+
protected massTotalSum: number;
|
|
49
|
+
/**
|
|
50
|
+
* Number of data points received from the device.
|
|
51
|
+
* Used to calculate the average mass.
|
|
52
|
+
* @type {number}
|
|
53
|
+
* @protected
|
|
54
|
+
*/
|
|
55
|
+
protected dataPointCount: number;
|
|
56
|
+
/**
|
|
57
|
+
* Optional callback for handling write operations.
|
|
58
|
+
* @callback NotifyCallback
|
|
59
|
+
* @param {massObject} data - The data passed to the callback.
|
|
60
|
+
* @type {NotifyCallback | undefined}
|
|
61
|
+
* @protected
|
|
62
|
+
*/
|
|
63
|
+
protected notifyCallback: NotifyCallback;
|
|
64
|
+
/**
|
|
65
|
+
* Optional callback for handling write operations.
|
|
66
|
+
* @callback WriteCallback
|
|
67
|
+
* @param {string} data - The data passed to the callback.
|
|
68
|
+
* @type {WriteCallback | undefined}
|
|
69
|
+
* @protected
|
|
70
|
+
*/
|
|
71
|
+
protected writeCallback: WriteCallback;
|
|
72
|
+
/**
|
|
73
|
+
* The last message written to the device.
|
|
74
|
+
* @type {string | Uint8Array | null}
|
|
75
|
+
*/
|
|
76
|
+
protected writeLast: string | Uint8Array | null;
|
|
12
77
|
constructor(device: Partial<IDevice>);
|
|
13
78
|
/**
|
|
14
79
|
* Connects to a Bluetooth device.
|
|
@@ -50,12 +115,6 @@ export declare class Device extends BaseModel implements IDevice {
|
|
|
50
115
|
* @returns {void}
|
|
51
116
|
*/
|
|
52
117
|
notify: (callback: NotifyCallback) => void;
|
|
53
|
-
/**
|
|
54
|
-
* Defines the type for the callback function.
|
|
55
|
-
* @callback NotifyCallback
|
|
56
|
-
* @param {massObject} data - The data passed to the callback.
|
|
57
|
-
*/
|
|
58
|
-
notifyCallback: NotifyCallback;
|
|
59
118
|
/**
|
|
60
119
|
* Handles the 'connected' event.
|
|
61
120
|
* @param {Function} onSuccess - Callback function to execute on successful connection.
|
|
@@ -93,14 +152,4 @@ export declare class Device extends BaseModel implements IDevice {
|
|
|
93
152
|
* });
|
|
94
153
|
*/
|
|
95
154
|
write: (serviceId: string, characteristicId: string, message: string | Uint8Array | undefined, duration?: number, callback?: WriteCallback) => Promise<void>;
|
|
96
|
-
/**
|
|
97
|
-
* A default write callback that logs the response
|
|
98
|
-
*/
|
|
99
|
-
writeCallback: WriteCallback;
|
|
100
|
-
/**
|
|
101
|
-
* The last message written to the device.
|
|
102
|
-
* @type {string | Uint8Array | null}
|
|
103
|
-
*/
|
|
104
|
-
writeLast: string | Uint8Array | null;
|
|
105
155
|
}
|
|
106
|
-
export {};
|