@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.
Files changed (76) hide show
  1. package/dist/{download.d.ts → helpers/download.d.ts} +1 -1
  2. package/dist/helpers/is-device.d.ts +16 -16
  3. package/dist/helpers/is-device.js +18 -18
  4. package/dist/index.d.ts +4 -4
  5. package/dist/index.js +4 -5
  6. package/dist/interfaces/callback.interface.d.ts +49 -0
  7. package/dist/interfaces/command.interface.d.ts +85 -0
  8. package/dist/interfaces/device.interface.d.ts +19 -19
  9. package/dist/models/device/entralpi.model.js +9 -14
  10. package/dist/models/device/forceboard.model.js +4 -4
  11. package/dist/models/device/kilterboard.model.d.ts +61 -2
  12. package/dist/models/device/kilterboard.model.js +91 -11
  13. package/dist/models/device/motherboard.model.d.ts +24 -1
  14. package/dist/models/device/motherboard.model.js +56 -33
  15. package/dist/models/device/progressor.model.js +61 -22
  16. package/dist/models/device/wh-c06.model.d.ts +7 -0
  17. package/dist/models/device/wh-c06.model.js +18 -17
  18. package/dist/models/device.model.d.ts +71 -22
  19. package/dist/models/device.model.js +76 -21
  20. package/package.json +1 -1
  21. package/src/{download.ts → helpers/download.ts} +1 -1
  22. package/src/helpers/is-device.ts +23 -23
  23. package/src/index.ts +4 -5
  24. package/src/interfaces/callback.interface.ts +56 -0
  25. package/src/interfaces/command.interface.ts +106 -0
  26. package/src/interfaces/device.interface.ts +22 -21
  27. package/src/models/device/entralpi.model.ts +9 -15
  28. package/src/models/device/forceboard.model.ts +4 -4
  29. package/src/models/device/kilterboard.model.ts +93 -13
  30. package/src/models/device/motherboard.model.ts +61 -37
  31. package/src/models/device/progressor.model.ts +64 -22
  32. package/src/models/device/wh-c06.model.ts +20 -18
  33. package/src/models/device.model.ts +92 -30
  34. package/dist/commands/climbro.d.ts +0 -6
  35. package/dist/commands/climbro.js +0 -5
  36. package/dist/commands/entralpi.d.ts +0 -6
  37. package/dist/commands/entralpi.js +0 -5
  38. package/dist/commands/forceboard.d.ts +0 -6
  39. package/dist/commands/forceboard.js +0 -5
  40. package/dist/commands/index.d.ts +0 -7
  41. package/dist/commands/index.js +0 -7
  42. package/dist/commands/kilterboard.d.ts +0 -35
  43. package/dist/commands/kilterboard.js +0 -65
  44. package/dist/commands/motherboard.d.ts +0 -6
  45. package/dist/commands/motherboard.js +0 -13
  46. package/dist/commands/mysmartboard.d.ts +0 -6
  47. package/dist/commands/mysmartboard.js +0 -5
  48. package/dist/commands/progressor.d.ts +0 -17
  49. package/dist/commands/progressor.js +0 -30
  50. package/dist/commands/wh-c06.d.ts +0 -6
  51. package/dist/commands/wh-c06.js +0 -5
  52. package/dist/types/commands.d.ts +0 -18
  53. package/dist/types/notify.d.ts +0 -14
  54. package/src/commands/climbro.ts +0 -6
  55. package/src/commands/entralpi.ts +0 -6
  56. package/src/commands/forceboard.ts +0 -6
  57. package/src/commands/index.ts +0 -13
  58. package/src/commands/kilterboard.ts +0 -64
  59. package/src/commands/motherboard.ts +0 -14
  60. package/src/commands/mysmartboard.ts +0 -6
  61. package/src/commands/progressor.ts +0 -31
  62. package/src/commands/wh-c06.ts +0 -6
  63. package/src/types/commands.ts +0 -21
  64. package/src/types/notify.ts +0 -14
  65. /package/dist/{download.js → helpers/download.js} +0 -0
  66. /package/dist/{is-active.d.ts → helpers/is-active.d.ts} +0 -0
  67. /package/dist/{is-active.js → helpers/is-active.js} +0 -0
  68. /package/dist/{tare.d.ts → helpers/tare.d.ts} +0 -0
  69. /package/dist/{tare.js → helpers/tare.js} +0 -0
  70. /package/dist/{types/commands.js → interfaces/callback.interface.js} +0 -0
  71. /package/dist/{types/download.js → interfaces/command.interface.js} +0 -0
  72. /package/dist/{types/download.d.ts → interfaces/download.interface.d.ts} +0 -0
  73. /package/dist/{types/notify.js → interfaces/download.interface.js} +0 -0
  74. /package/src/{is-active.ts → helpers/is-active.ts} +0 -0
  75. /package/src/{tare.ts → helpers/tare.ts} +0 -0
  76. /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 { MotherboardCommands } from "../../commands";
4
- import { checkActivity } from "../../is-active";
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", MotherboardCommands.GET_CALIBRATION, 2500, (data) => {
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
- MASS_MAX = Math.max(Number(MASS_MAX), Math.max(-1000, left + center + right)).toFixed(1);
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
- MASS_TOTAL_SUM += currentMassTotal;
247
- DATAPOINT_COUNT++;
269
+ this.massTotalSum += currentMassTotal;
270
+ this.dataPointCount++;
248
271
  // Calculate the average dynamically
249
- MASS_AVERAGE = (MASS_TOTAL_SUM / DATAPOINT_COUNT).toFixed(1);
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: MASS_MAX,
256
- massAverage: MASS_AVERAGE,
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 === MotherboardCommands.GET_CALIBRATION) {
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", MotherboardCommands.GET_SERIAL, 250, (data) => {
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", MotherboardCommands.STOP_WEIGHT_MEAS, 0);
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", MotherboardCommands.START_WEIGHT_MEAS, duration);
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", MotherboardCommands.GET_TEXT, 250, (data) => {
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
- // Constants
8
- let MASS_MAX = "0";
9
- let MASS_AVERAGE = "0";
10
- let MASS_TOTAL_SUM = 0;
11
- let DATAPOINT_COUNT = 0;
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", ProgressorCommands.GET_BATT_VLTG, 250, (data) => {
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", ProgressorCommands.GET_FW_VERSION, 250, (data) => {
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
- MASS_MAX = Math.max(Number(MASS_MAX), Number(weight)).toFixed(1);
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
- MASS_TOTAL_SUM += currentMassTotal;
120
- DATAPOINT_COUNT++;
158
+ this.massTotalSum += currentMassTotal;
159
+ this.dataPointCount++;
121
160
  // Calculate the average dynamically
122
- MASS_AVERAGE = (MASS_TOTAL_SUM / DATAPOINT_COUNT).toFixed(1);
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: MASS_MAX,
127
- massAverage: MASS_AVERAGE,
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 === ProgressorCommands.GET_BATT_VLTG) {
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 === ProgressorCommands.GET_FW_VERSION) {
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 === ProgressorCommands.GET_ERR_INFO) {
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", ProgressorCommands.STOP_WEIGHT_MEAS, 0);
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", ProgressorCommands.START_WEIGHT_MEAS, duration);
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 MASS_MAX
62
- MASS_MAX = Math.max(Number(MASS_MAX), numericData).toFixed(1);
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
- MASS_TOTAL_SUM += currentMassTotal;
66
- DATAPOINT_COUNT++;
66
+ this.massTotalSum += currentMassTotal;
67
+ this.dataPointCount++;
67
68
  // Calculate the average dynamically
68
- MASS_AVERAGE = (MASS_TOTAL_SUM / DATAPOINT_COUNT).toFixed(1);
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: MASS_MAX,
74
- massAverage: MASS_AVERAGE,
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 { massObject } from "./../types/notify";
4
- /** Define the type for the callback function */
5
- type NotifyCallback = (data: massObject) => void;
6
- /** Define the type for the callback function */
7
- type WriteCallback = (data: string) => void;
8
- export declare class Device extends BaseModel implements IDevice {
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 {};