@hangtime/grip-connect 0.5.2 → 0.5.4
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/README.md +1 -1
- 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/forceboard.interface.d.ts +16 -0
- package/dist/interfaces/device.interface.d.ts +21 -21
- package/dist/models/device/entralpi.model.d.ts +1 -1
- package/dist/models/device/entralpi.model.js +19 -76
- package/dist/models/device/forceboard.model.d.ts +24 -0
- package/dist/models/device/forceboard.model.js +81 -23
- 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 +79 -100
- package/dist/models/device/progressor.model.d.ts +1 -1
- package/dist/models/device/progressor.model.js +76 -52
- 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 +73 -24
- package/dist/models/device.model.js +125 -78
- 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/forceboard.interface.ts +19 -0
- package/src/interfaces/device.interface.ts +24 -23
- package/src/models/device/entralpi.model.ts +19 -77
- package/src/models/device/forceboard.model.ts +93 -23
- package/src/models/device/kilterboard.model.ts +93 -13
- package/src/models/device/motherboard.model.ts +84 -105
- package/src/models/device/progressor.model.ts +79 -52
- package/src/models/device/wh-c06.model.ts +20 -18
- package/src/models/device.model.ts +143 -88
- 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,27 +1,42 @@
|
|
|
1
1
|
import { Device } from "../device.model"
|
|
2
2
|
import type { IMotherboard } from "../../interfaces/device/motherboard.interface"
|
|
3
|
-
import { applyTare } from "../../tare"
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import type { DownloadPacket } from "../../types/download"
|
|
8
|
-
|
|
9
|
-
// Constants
|
|
10
|
-
const PACKET_LENGTH = 32
|
|
11
|
-
const NUM_SAMPLES = 3
|
|
12
|
-
let MASS_MAX = "0"
|
|
13
|
-
let MASS_AVERAGE = "0"
|
|
14
|
-
let MASS_TOTAL_SUM = 0
|
|
15
|
-
let DATAPOINT_COUNT = 0
|
|
16
|
-
|
|
17
|
-
const receiveBuffer: number[] = []
|
|
18
|
-
|
|
19
|
-
export const CALIBRATION = [[], [], [], []]
|
|
3
|
+
import { applyTare } from "../../helpers/tare"
|
|
4
|
+
import { checkActivity } from "../../helpers/is-active"
|
|
5
|
+
import { DownloadPackets, emptyDownloadPackets } from "../../helpers/download"
|
|
6
|
+
import type { DownloadPacket } from "../../interfaces/download.interface"
|
|
20
7
|
|
|
21
8
|
/**
|
|
22
9
|
* Represents a Griptonite Motherboard device
|
|
23
10
|
*/
|
|
24
11
|
export class Motherboard extends Device implements IMotherboard {
|
|
12
|
+
/**
|
|
13
|
+
* Length of the packet received from the device.
|
|
14
|
+
* @private
|
|
15
|
+
* @type {number}
|
|
16
|
+
*/
|
|
17
|
+
private PACKET_LENGTH = 32
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Number of samples contained in the data packet.
|
|
21
|
+
* @private
|
|
22
|
+
* @type {number}
|
|
23
|
+
*/
|
|
24
|
+
private NUM_SAMPLES = 3
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Buffer to store received data from the device.
|
|
28
|
+
* @private
|
|
29
|
+
* @type {number[]}
|
|
30
|
+
*/
|
|
31
|
+
private receiveBuffer: number[] = []
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Calibration data for each sensor of the device.
|
|
35
|
+
* @private
|
|
36
|
+
* @type {number[][][]}
|
|
37
|
+
*/
|
|
38
|
+
private CALIBRATION: number[][][] = [[], [], [], []]
|
|
39
|
+
|
|
25
40
|
constructor() {
|
|
26
41
|
super({
|
|
27
42
|
filters: [{ name: "Motherboard" }],
|
|
@@ -100,6 +115,15 @@ export class Motherboard extends Device implements IMotherboard {
|
|
|
100
115
|
],
|
|
101
116
|
},
|
|
102
117
|
],
|
|
118
|
+
commands: {
|
|
119
|
+
GET_SERIAL: "#",
|
|
120
|
+
START_WEIGHT_MEAS: "S30",
|
|
121
|
+
STOP_WEIGHT_MEAS: "", // All commands will stop the data stream.
|
|
122
|
+
GET_CALIBRATION: "C",
|
|
123
|
+
SLEEP: 0,
|
|
124
|
+
GET_TEXT: "T",
|
|
125
|
+
DEBUG_STREAM: "D",
|
|
126
|
+
},
|
|
103
127
|
})
|
|
104
128
|
}
|
|
105
129
|
|
|
@@ -150,11 +174,7 @@ export class Motherboard extends Device implements IMotherboard {
|
|
|
150
174
|
* @returns {Promise<string | undefined>} A Promise that resolves with the battery or voltage information,
|
|
151
175
|
*/
|
|
152
176
|
battery = async (): Promise<string | undefined> => {
|
|
153
|
-
|
|
154
|
-
return await this.read("battery", "level", 250)
|
|
155
|
-
}
|
|
156
|
-
// If device is not found, return undefined
|
|
157
|
-
return undefined
|
|
177
|
+
return await this.read("battery", "level", 250)
|
|
158
178
|
}
|
|
159
179
|
|
|
160
180
|
/**
|
|
@@ -162,13 +182,9 @@ export class Motherboard extends Device implements IMotherboard {
|
|
|
162
182
|
* @returns {Promise<void>} A Promise that resolves when the command is successfully sent.
|
|
163
183
|
*/
|
|
164
184
|
calibration = async (): Promise<void> => {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
await this.write("uart", "tx", MotherboardCommands.GET_CALIBRATION, 2500, (data) => {
|
|
169
|
-
console.log(data)
|
|
170
|
-
})
|
|
171
|
-
}
|
|
185
|
+
await this.write("uart", "tx", this.commands.GET_CALIBRATION, 2500, (data) => {
|
|
186
|
+
console.log(data)
|
|
187
|
+
})
|
|
172
188
|
}
|
|
173
189
|
|
|
174
190
|
/**
|
|
@@ -176,13 +192,7 @@ export class Motherboard extends Device implements IMotherboard {
|
|
|
176
192
|
* @returns {Promise<string>} A Promise that resolves with the firmware version,
|
|
177
193
|
*/
|
|
178
194
|
firmware = async (): Promise<string | undefined> => {
|
|
179
|
-
|
|
180
|
-
if (this.isConnected()) {
|
|
181
|
-
// Read firmware version from the Motherboard
|
|
182
|
-
return await this.read("device", "firmware", 250)
|
|
183
|
-
}
|
|
184
|
-
// If device is not found, return undefined
|
|
185
|
-
return undefined
|
|
195
|
+
return await this.read("device", "firmware", 250)
|
|
186
196
|
}
|
|
187
197
|
|
|
188
198
|
/**
|
|
@@ -199,12 +209,12 @@ export class Motherboard extends Device implements IMotherboard {
|
|
|
199
209
|
if (value) {
|
|
200
210
|
if (value.buffer) {
|
|
201
211
|
for (let i = 0; i < value.byteLength; i++) {
|
|
202
|
-
receiveBuffer.push(value.getUint8(i))
|
|
212
|
+
this.receiveBuffer.push(value.getUint8(i))
|
|
203
213
|
}
|
|
204
214
|
|
|
205
215
|
let idx: number
|
|
206
|
-
while ((idx = receiveBuffer.indexOf(10)) >= 0) {
|
|
207
|
-
const line: number[] = receiveBuffer.splice(0, idx + 1).slice(0, -1) // Combine and remove LF
|
|
216
|
+
while ((idx = this.receiveBuffer.indexOf(10)) >= 0) {
|
|
217
|
+
const line: number[] = this.receiveBuffer.splice(0, idx + 1).slice(0, -1) // Combine and remove LF
|
|
208
218
|
if (line.length > 0 && line[line.length - 1] === 13) line.pop() // Remove CR
|
|
209
219
|
const decoder: TextDecoder = new TextDecoder("utf-8")
|
|
210
220
|
const receivedData: string = decoder.decode(new Uint8Array(line))
|
|
@@ -215,7 +225,7 @@ export class Motherboard extends Device implements IMotherboard {
|
|
|
215
225
|
const isAllHex: boolean = /^[0-9A-Fa-f]+$/g.test(receivedData)
|
|
216
226
|
|
|
217
227
|
// Handle streaming packet
|
|
218
|
-
if (isAllHex && receivedData.length === PACKET_LENGTH) {
|
|
228
|
+
if (isAllHex && receivedData.length === this.PACKET_LENGTH) {
|
|
219
229
|
// Base-16 decode the string: convert hex pairs to byte values
|
|
220
230
|
const bytes: number[] = Array.from({ length: receivedData.length / 2 }, (_, i) =>
|
|
221
231
|
Number(`0x${receivedData.substring(i * 2, i * 2 + 2)}`),
|
|
@@ -232,7 +242,7 @@ export class Motherboard extends Device implements IMotherboard {
|
|
|
232
242
|
|
|
233
243
|
const dataView = new DataView(new Uint8Array(bytes).buffer)
|
|
234
244
|
|
|
235
|
-
for (let i = 0; i < NUM_SAMPLES; i++) {
|
|
245
|
+
for (let i = 0; i < this.NUM_SAMPLES; i++) {
|
|
236
246
|
const sampleStart: number = 4 + 3 * i
|
|
237
247
|
// Use DataView to read the 24-bit unsigned integer
|
|
238
248
|
const rawValue =
|
|
@@ -246,7 +256,7 @@ export class Motherboard extends Device implements IMotherboard {
|
|
|
246
256
|
if (packet.samples[i] >= 0x7fffff) {
|
|
247
257
|
packet.samples[i] -= 0x1000000
|
|
248
258
|
}
|
|
249
|
-
packet.masses[i] = this.applyCalibration(packet.samples[i], CALIBRATION[i])
|
|
259
|
+
packet.masses[i] = this.applyCalibration(packet.samples[i], this.CALIBRATION[i])
|
|
250
260
|
}
|
|
251
261
|
// invert center and right values
|
|
252
262
|
packet.masses[1] *= -1
|
|
@@ -270,15 +280,15 @@ export class Motherboard extends Device implements IMotherboard {
|
|
|
270
280
|
center -= applyTare(center)
|
|
271
281
|
right -= applyTare(right)
|
|
272
282
|
|
|
273
|
-
|
|
283
|
+
this.massMax = Math.max(Number(this.massMax), Math.max(-1000, left + center + right)).toFixed(1)
|
|
274
284
|
|
|
275
285
|
// Update running sum and count
|
|
276
286
|
const currentMassTotal = Math.max(-1000, left + center + right)
|
|
277
|
-
|
|
278
|
-
|
|
287
|
+
this.massTotalSum += currentMassTotal
|
|
288
|
+
this.dataPointCount++
|
|
279
289
|
|
|
280
290
|
// Calculate the average dynamically
|
|
281
|
-
|
|
291
|
+
this.massAverage = (this.massTotalSum / this.dataPointCount).toFixed(1)
|
|
282
292
|
|
|
283
293
|
// Check if device is being used
|
|
284
294
|
checkActivity(center)
|
|
@@ -286,18 +296,18 @@ export class Motherboard extends Device implements IMotherboard {
|
|
|
286
296
|
// Notify with weight data
|
|
287
297
|
this.notifyCallback({
|
|
288
298
|
massTotal: Math.max(-1000, left + center + right).toFixed(1),
|
|
289
|
-
massMax:
|
|
290
|
-
massAverage:
|
|
299
|
+
massMax: this.massMax,
|
|
300
|
+
massAverage: this.massAverage,
|
|
291
301
|
massLeft: Math.max(-1000, packet.masses[0]).toFixed(1),
|
|
292
302
|
massCenter: Math.max(-1000, packet.masses[1]).toFixed(1),
|
|
293
303
|
massRight: Math.max(-1000, packet.masses[2]).toFixed(1),
|
|
294
304
|
})
|
|
295
|
-
} else if (this.writeLast ===
|
|
305
|
+
} else if (this.writeLast === this.commands.GET_CALIBRATION) {
|
|
296
306
|
// check data integrity
|
|
297
307
|
if ((receivedData.match(/,/g) || []).length === 3) {
|
|
298
308
|
const parts: string[] = receivedData.split(",")
|
|
299
309
|
const numericParts: number[] = parts.map((x) => parseFloat(x))
|
|
300
|
-
;(CALIBRATION[numericParts[0]] as number[][]).push(numericParts.slice(1))
|
|
310
|
+
;(this.CALIBRATION[numericParts[0]] as number[][]).push(numericParts.slice(1))
|
|
301
311
|
}
|
|
302
312
|
} else {
|
|
303
313
|
// unhandled data
|
|
@@ -313,13 +323,7 @@ export class Motherboard extends Device implements IMotherboard {
|
|
|
313
323
|
* @returns {Promise<string>} A Promise that resolves with the hardware version,
|
|
314
324
|
*/
|
|
315
325
|
hardware = async (): Promise<string | undefined> => {
|
|
316
|
-
|
|
317
|
-
if (this.isConnected()) {
|
|
318
|
-
// Read hardware version from the device
|
|
319
|
-
return await this.read("device", "hardware", 250)
|
|
320
|
-
}
|
|
321
|
-
// If device is not found, return undefined
|
|
322
|
-
return undefined
|
|
326
|
+
return await this.read("device", "hardware", 250)
|
|
323
327
|
}
|
|
324
328
|
|
|
325
329
|
/**
|
|
@@ -349,13 +353,7 @@ export class Motherboard extends Device implements IMotherboard {
|
|
|
349
353
|
* @returns {Promise<string>} A Promise that resolves with the manufacturer information,
|
|
350
354
|
*/
|
|
351
355
|
manufacturer = async (): Promise<string | undefined> => {
|
|
352
|
-
|
|
353
|
-
if (this.isConnected()) {
|
|
354
|
-
// Read manufacturer information from the device
|
|
355
|
-
return await this.read("device", "manufacturer", 250)
|
|
356
|
-
}
|
|
357
|
-
// If device is not found, return undefined
|
|
358
|
-
return undefined
|
|
356
|
+
return await this.read("device", "manufacturer", 250)
|
|
359
357
|
}
|
|
360
358
|
|
|
361
359
|
/**
|
|
@@ -363,17 +361,11 @@ export class Motherboard extends Device implements IMotherboard {
|
|
|
363
361
|
* @returns {Promise<string>} A Promise that resolves with the serial number,
|
|
364
362
|
*/
|
|
365
363
|
serial = async (): Promise<string | undefined> => {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
response = data
|
|
372
|
-
})
|
|
373
|
-
return response
|
|
374
|
-
}
|
|
375
|
-
// If device is not found, return undefined
|
|
376
|
-
return undefined
|
|
364
|
+
let response: string | undefined = undefined
|
|
365
|
+
await this.write("uart", "tx", this.commands.GET_SERIAL, 250, (data) => {
|
|
366
|
+
response = data
|
|
367
|
+
})
|
|
368
|
+
return response
|
|
377
369
|
}
|
|
378
370
|
|
|
379
371
|
/**
|
|
@@ -381,10 +373,7 @@ export class Motherboard extends Device implements IMotherboard {
|
|
|
381
373
|
* @returns {Promise<void>} A promise that resolves when the stream is stopped.
|
|
382
374
|
*/
|
|
383
375
|
stop = async (): Promise<void> => {
|
|
384
|
-
|
|
385
|
-
// Stop stream of device
|
|
386
|
-
await this.write("uart", "tx", MotherboardCommands.STOP_WEIGHT_MEAS, 0)
|
|
387
|
-
}
|
|
376
|
+
await this.write("uart", "tx", this.commands.STOP_WEIGHT_MEAS, 0)
|
|
388
377
|
}
|
|
389
378
|
|
|
390
379
|
/**
|
|
@@ -393,21 +382,17 @@ export class Motherboard extends Device implements IMotherboard {
|
|
|
393
382
|
* @returns {Promise<void>} A promise that resolves when the streaming operation is completed.
|
|
394
383
|
*/
|
|
395
384
|
stream = async (duration = 0): Promise<void> => {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
await this.
|
|
407
|
-
// Stop streaming if duration is set
|
|
408
|
-
if (duration !== 0) {
|
|
409
|
-
await this.stop()
|
|
410
|
-
}
|
|
385
|
+
// Reset download packets
|
|
386
|
+
emptyDownloadPackets()
|
|
387
|
+
// Read calibration data if not already available
|
|
388
|
+
if (!this.CALIBRATION[0].length) {
|
|
389
|
+
await this.calibration()
|
|
390
|
+
}
|
|
391
|
+
// Start streaming data
|
|
392
|
+
await this.write("uart", "tx", this.commands.START_WEIGHT_MEAS, duration)
|
|
393
|
+
// Stop streaming if duration is set
|
|
394
|
+
if (duration !== 0) {
|
|
395
|
+
await this.stop()
|
|
411
396
|
}
|
|
412
397
|
}
|
|
413
398
|
|
|
@@ -421,16 +406,10 @@ export class Motherboard extends Device implements IMotherboard {
|
|
|
421
406
|
* @returns {Promise<string>} A Promise that resolves with the 320-byte memory content as a string,
|
|
422
407
|
*/
|
|
423
408
|
text = async (): Promise<string | undefined> => {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
response = data
|
|
430
|
-
})
|
|
431
|
-
return response
|
|
432
|
-
}
|
|
433
|
-
// If device is not found, return undefined
|
|
434
|
-
return undefined
|
|
409
|
+
let response: string | undefined = undefined
|
|
410
|
+
await this.write("uart", "tx", this.commands.GET_TEXT, 250, (data) => {
|
|
411
|
+
response = data
|
|
412
|
+
})
|
|
413
|
+
return response
|
|
435
414
|
}
|
|
436
415
|
}
|
|
@@ -1,16 +1,44 @@
|
|
|
1
1
|
import { Device } from "../device.model"
|
|
2
2
|
import type { IProgressor } from "../../interfaces/device/progressor.interface"
|
|
3
|
-
import { ProgressorCommands, ProgressorResponses } from "../../commands/progressor"
|
|
4
3
|
import struct from "../../helpers/struct"
|
|
5
|
-
import { checkActivity } from "../../is-active"
|
|
6
|
-
import { DownloadPackets, emptyDownloadPackets } from "../../download"
|
|
7
|
-
import { applyTare } from "../../tare"
|
|
4
|
+
import { checkActivity } from "../../helpers/is-active"
|
|
5
|
+
import { DownloadPackets, emptyDownloadPackets } from "../../helpers/download"
|
|
6
|
+
import { applyTare } from "../../helpers/tare"
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Represents the possible responses of a Tindeq Progressor device.
|
|
10
|
+
*/
|
|
11
|
+
enum ProgressorResponses {
|
|
12
|
+
/**
|
|
13
|
+
* Response received after sending a command to the device.
|
|
14
|
+
* This could include acknowledgment or specific data related to the command sent.
|
|
15
|
+
*/
|
|
16
|
+
COMMAND_RESPONSE,
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Data representing a weight measurement from the device.
|
|
20
|
+
* Typically used for tracking load or force applied.
|
|
21
|
+
*/
|
|
22
|
+
WEIGHT_MEASURE,
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Peak rate of force development (RFD) measurement.
|
|
26
|
+
* This measures how quickly the force is applied over time.
|
|
27
|
+
*/
|
|
28
|
+
PEAK_RFD_MEAS,
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Series of peak rate of force development (RFD) measurements.
|
|
32
|
+
* This could be used for analyzing force trends over multiple data points.
|
|
33
|
+
*/
|
|
34
|
+
PEAK_RFD_MEAS_SERIES,
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Low battery warning from the device.
|
|
38
|
+
* Indicates that the battery level is below a critical threshold.
|
|
39
|
+
*/
|
|
40
|
+
LOW_BATTERY_WARNING,
|
|
41
|
+
}
|
|
14
42
|
|
|
15
43
|
/**
|
|
16
44
|
* Represents a Tindeq Progressor device
|
|
@@ -50,6 +78,20 @@ export class Progressor extends Device implements IProgressor {
|
|
|
50
78
|
],
|
|
51
79
|
},
|
|
52
80
|
],
|
|
81
|
+
commands: {
|
|
82
|
+
TARE_SCALE: "d", // 0x64
|
|
83
|
+
START_WEIGHT_MEAS: "e", // 0x65
|
|
84
|
+
STOP_WEIGHT_MEAS: "f", // 0x66
|
|
85
|
+
START_PEAK_RFD_MEAS: "g", // 0x67
|
|
86
|
+
START_PEAK_RFD_MEAS_SERIES: "h", // 0x68
|
|
87
|
+
ADD_CALIB_POINT: "i", // 0x69
|
|
88
|
+
SAVE_CALIB: "j", // 0x6a
|
|
89
|
+
GET_FW_VERSION: "k", // 0x6b
|
|
90
|
+
GET_ERR_INFO: "l", // 0x6c
|
|
91
|
+
CLR_ERR_INFO: "m", // 0x6d
|
|
92
|
+
SLEEP: "n", // 0x6e
|
|
93
|
+
GET_BATT_VLTG: "o", // 0x6f
|
|
94
|
+
},
|
|
53
95
|
})
|
|
54
96
|
}
|
|
55
97
|
|
|
@@ -58,15 +100,11 @@ export class Progressor extends Device implements IProgressor {
|
|
|
58
100
|
* @returns {Promise<string | undefined>} A Promise that resolves with the battery or voltage information,
|
|
59
101
|
*/
|
|
60
102
|
battery = async (): Promise<string | undefined> => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return response
|
|
67
|
-
}
|
|
68
|
-
// If device is not found, return undefined
|
|
69
|
-
return undefined
|
|
103
|
+
let response: string | undefined = undefined
|
|
104
|
+
await this.write("progressor", "tx", this.commands.GET_BATT_VLTG, 250, (data) => {
|
|
105
|
+
response = data
|
|
106
|
+
})
|
|
107
|
+
return response
|
|
70
108
|
}
|
|
71
109
|
|
|
72
110
|
/**
|
|
@@ -74,21 +112,15 @@ export class Progressor extends Device implements IProgressor {
|
|
|
74
112
|
* @returns {Promise<string>} A Promise that resolves with the firmware version,
|
|
75
113
|
*/
|
|
76
114
|
firmware = async (): Promise<string | undefined> => {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
response = data
|
|
83
|
-
})
|
|
84
|
-
return response
|
|
85
|
-
}
|
|
86
|
-
// If device is not found, return undefined
|
|
87
|
-
return undefined
|
|
115
|
+
let response: string | undefined = undefined
|
|
116
|
+
await this.write("progressor", "tx", this.commands.GET_FW_VERSION, 250, (data) => {
|
|
117
|
+
response = data
|
|
118
|
+
})
|
|
119
|
+
return response
|
|
88
120
|
}
|
|
89
121
|
|
|
90
122
|
/**
|
|
91
|
-
* Handles data received from the
|
|
123
|
+
* Handles data received from the device, processes weight measurements,
|
|
92
124
|
* and updates mass data including maximum and average values.
|
|
93
125
|
* It also handles command responses for retrieving device information.
|
|
94
126
|
*
|
|
@@ -120,21 +152,21 @@ export class Progressor extends Device implements IProgressor {
|
|
|
120
152
|
// Tare correction
|
|
121
153
|
weight -= applyTare(weight)
|
|
122
154
|
// Check for max weight
|
|
123
|
-
|
|
155
|
+
this.massMax = Math.max(Number(this.massMax), Number(weight)).toFixed(1)
|
|
124
156
|
// Update running sum and count
|
|
125
157
|
const currentMassTotal = Math.max(-1000, Number(weight))
|
|
126
|
-
|
|
127
|
-
|
|
158
|
+
this.massTotalSum += currentMassTotal
|
|
159
|
+
this.dataPointCount++
|
|
128
160
|
|
|
129
161
|
// Calculate the average dynamically
|
|
130
|
-
|
|
162
|
+
this.massAverage = (this.massTotalSum / this.dataPointCount).toFixed(1)
|
|
131
163
|
|
|
132
164
|
// Check if device is being used
|
|
133
165
|
checkActivity(weight)
|
|
134
166
|
|
|
135
167
|
this.notifyCallback({
|
|
136
|
-
massMax:
|
|
137
|
-
massAverage:
|
|
168
|
+
massMax: this.massMax,
|
|
169
|
+
massAverage: this.massAverage,
|
|
138
170
|
massTotal: Math.max(-1000, weight).toFixed(1),
|
|
139
171
|
})
|
|
140
172
|
}
|
|
@@ -144,11 +176,11 @@ export class Progressor extends Device implements IProgressor {
|
|
|
144
176
|
|
|
145
177
|
let value = ""
|
|
146
178
|
|
|
147
|
-
if (this.writeLast ===
|
|
179
|
+
if (this.writeLast === this.commands.GET_BATT_VLTG) {
|
|
148
180
|
value = new DataView(data.buffer, 2).getUint32(0, true).toString()
|
|
149
|
-
} else if (this.writeLast ===
|
|
181
|
+
} else if (this.writeLast === this.commands.GET_FW_VERSION) {
|
|
150
182
|
value = new TextDecoder().decode(data.buffer.slice(2))
|
|
151
|
-
} else if (this.writeLast ===
|
|
183
|
+
} else if (this.writeLast === this.commands.GET_ERR_INFO) {
|
|
152
184
|
value = new TextDecoder().decode(data.buffer.slice(2))
|
|
153
185
|
}
|
|
154
186
|
this.writeCallback(value)
|
|
@@ -166,10 +198,7 @@ export class Progressor extends Device implements IProgressor {
|
|
|
166
198
|
* @returns {Promise<void>} A promise that resolves when the stream is stopped.
|
|
167
199
|
*/
|
|
168
200
|
stop = async (): Promise<void> => {
|
|
169
|
-
|
|
170
|
-
// Stop stream of device
|
|
171
|
-
await this.write("progressor", "tx", ProgressorCommands.STOP_WEIGHT_MEAS, 0)
|
|
172
|
-
}
|
|
201
|
+
await this.write("progressor", "tx", this.commands.STOP_WEIGHT_MEAS, 0)
|
|
173
202
|
}
|
|
174
203
|
|
|
175
204
|
/**
|
|
@@ -178,15 +207,13 @@ export class Progressor extends Device implements IProgressor {
|
|
|
178
207
|
* @returns {Promise<void>} A promise that resolves when the streaming operation is completed.
|
|
179
208
|
*/
|
|
180
209
|
stream = async (duration = 0): Promise<void> => {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
await this.stop()
|
|
189
|
-
}
|
|
210
|
+
// Reset download packets
|
|
211
|
+
emptyDownloadPackets()
|
|
212
|
+
// Start streaming data
|
|
213
|
+
await this.write("progressor", "tx", this.commands.START_WEIGHT_MEAS, duration)
|
|
214
|
+
// Stop streaming if duration is set
|
|
215
|
+
if (duration !== 0) {
|
|
216
|
+
await this.stop()
|
|
190
217
|
}
|
|
191
218
|
}
|
|
192
219
|
}
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import { Device } from "../device.model"
|
|
2
|
-
import { applyTare } from "../../tare"
|
|
3
|
-
import { checkActivity } from "../../is-active"
|
|
2
|
+
import { applyTare } from "../../helpers/tare"
|
|
3
|
+
import { checkActivity } from "../../helpers/is-active"
|
|
4
4
|
import type { IWHC06 } from "../../interfaces/device/wh-c06.interface"
|
|
5
5
|
|
|
6
|
-
// Constants
|
|
7
|
-
let MASS_MAX = "0"
|
|
8
|
-
let MASS_AVERAGE = "0"
|
|
9
|
-
let MASS_TOTAL_SUM = 0
|
|
10
|
-
let DATAPOINT_COUNT = 0
|
|
11
|
-
const WEIGHT_OFFSET = 10
|
|
12
|
-
// const STABLE_OFFSET = 14
|
|
13
|
-
|
|
14
6
|
/**
|
|
15
7
|
* Represents a Weiheng - WH-C06 (or MAT Muscle Meter) device
|
|
16
8
|
* Enable 'Experimental Web Platform features' Chrome Flags.
|
|
17
9
|
*/
|
|
18
10
|
export class WHC06 extends Device implements IWHC06 {
|
|
11
|
+
/**
|
|
12
|
+
* Offset for the byte location in the manufacturer data to extract the weight.
|
|
13
|
+
* This value is constant across all instances of the class.
|
|
14
|
+
* @type {number}
|
|
15
|
+
* @constant
|
|
16
|
+
*/
|
|
17
|
+
private static readonly WEIGHT_OFFSET = 10
|
|
18
|
+
|
|
19
|
+
// private static readonly STABLE_OFFSET = 14
|
|
20
|
+
|
|
19
21
|
constructor() {
|
|
20
22
|
super({
|
|
21
23
|
filters: [
|
|
@@ -66,7 +68,7 @@ export class WHC06 extends Device implements IWHC06 {
|
|
|
66
68
|
const data = event.manufacturerData.get(MANUFACTURER_ID)
|
|
67
69
|
if (data) {
|
|
68
70
|
// Handle recieved data
|
|
69
|
-
const weight = (data.getUint8(WEIGHT_OFFSET) << 8) | data.getUint8(WEIGHT_OFFSET + 1)
|
|
71
|
+
const weight = (data.getUint8(WHC06.WEIGHT_OFFSET) << 8) | data.getUint8(WHC06.WEIGHT_OFFSET + 1)
|
|
70
72
|
// const stable = (data.getUint8(STABLE_OFFSET) & 0xf0) >> 4
|
|
71
73
|
// const unit = data.getUint8(STABLE_OFFSET) & 0x0f
|
|
72
74
|
|
|
@@ -75,24 +77,24 @@ export class WHC06 extends Device implements IWHC06 {
|
|
|
75
77
|
// Tare correction
|
|
76
78
|
numericData -= applyTare(numericData)
|
|
77
79
|
|
|
78
|
-
// Update
|
|
79
|
-
|
|
80
|
+
// Update massMax
|
|
81
|
+
this.massMax = Math.max(Number(this.massMax), numericData).toFixed(1)
|
|
80
82
|
|
|
81
83
|
// Update running sum and count
|
|
82
84
|
const currentMassTotal = Math.max(-1000, numericData)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
+
this.massTotalSum += currentMassTotal
|
|
86
|
+
this.dataPointCount++
|
|
85
87
|
|
|
86
88
|
// Calculate the average dynamically
|
|
87
|
-
|
|
89
|
+
this.massAverage = (this.massTotalSum / this.dataPointCount).toFixed(1)
|
|
88
90
|
|
|
89
91
|
// Check if device is being used
|
|
90
92
|
checkActivity(numericData)
|
|
91
93
|
|
|
92
94
|
// Notify with weight data
|
|
93
95
|
this.notifyCallback({
|
|
94
|
-
massMax:
|
|
95
|
-
massAverage:
|
|
96
|
+
massMax: this.massMax,
|
|
97
|
+
massAverage: this.massAverage,
|
|
96
98
|
massTotal: Math.max(-1000, numericData).toFixed(1),
|
|
97
99
|
})
|
|
98
100
|
}
|