@hangtime/grip-connect 0.10.1 → 0.10.2
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/cjs/index.d.ts +1 -2
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +1 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/interfaces/callback.interface.d.ts +19 -12
- package/dist/cjs/interfaces/callback.interface.d.ts.map +1 -1
- package/dist/cjs/interfaces/command.interface.d.ts +10 -6
- package/dist/cjs/interfaces/command.interface.d.ts.map +1 -1
- package/dist/cjs/interfaces/device/progressor.interface.d.ts +42 -0
- package/dist/cjs/interfaces/device/progressor.interface.d.ts.map +1 -1
- package/dist/cjs/interfaces/device.interface.d.ts +1 -1
- package/dist/cjs/interfaces/download.interface.d.ts +8 -11
- package/dist/cjs/interfaces/download.interface.d.ts.map +1 -1
- package/dist/cjs/models/device/climbro.model.d.ts.map +1 -1
- package/dist/cjs/models/device/climbro.model.js +34 -16
- package/dist/cjs/models/device/climbro.model.js.map +1 -1
- package/dist/cjs/models/device/entralpi.model.d.ts.map +1 -1
- package/dist/cjs/models/device/entralpi.model.js +11 -14
- package/dist/cjs/models/device/entralpi.model.js.map +1 -1
- package/dist/cjs/models/device/forceboard.model.d.ts.map +1 -1
- package/dist/cjs/models/device/forceboard.model.js +12 -17
- package/dist/cjs/models/device/forceboard.model.js.map +1 -1
- package/dist/cjs/models/device/motherboard.model.d.ts.map +1 -1
- package/dist/cjs/models/device/motherboard.model.js +28 -20
- package/dist/cjs/models/device/motherboard.model.js.map +1 -1
- package/dist/cjs/models/device/pb-700bt.model.d.ts.map +1 -1
- package/dist/cjs/models/device/pb-700bt.model.js +11 -14
- package/dist/cjs/models/device/pb-700bt.model.js.map +1 -1
- package/dist/cjs/models/device/progressor.model.d.ts +47 -5
- package/dist/cjs/models/device/progressor.model.d.ts.map +1 -1
- package/dist/cjs/models/device/progressor.model.js +185 -49
- package/dist/cjs/models/device/progressor.model.js.map +1 -1
- package/dist/cjs/models/device/smartboard-pro.model.d.ts.map +1 -1
- package/dist/cjs/models/device/smartboard-pro.model.js +11 -16
- package/dist/cjs/models/device/smartboard-pro.model.js.map +1 -1
- package/dist/cjs/models/device/wh-c06.model.d.ts.map +1 -1
- package/dist/cjs/models/device/wh-c06.model.js +11 -14
- package/dist/cjs/models/device/wh-c06.model.js.map +1 -1
- package/dist/cjs/models/device.model.d.ts +64 -3
- package/dist/cjs/models/device.model.d.ts.map +1 -1
- package/dist/cjs/models/device.model.js +142 -37
- package/dist/cjs/models/device.model.js.map +1 -1
- package/dist/cjs/utils.d.ts +1 -1
- package/dist/cjs/utils.d.ts.map +1 -1
- package/dist/cjs/utils.js +29 -6
- package/dist/cjs/utils.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces/callback.interface.d.ts +19 -12
- package/dist/interfaces/callback.interface.d.ts.map +1 -1
- package/dist/interfaces/command.interface.d.ts +10 -6
- package/dist/interfaces/command.interface.d.ts.map +1 -1
- package/dist/interfaces/device/progressor.interface.d.ts +42 -0
- package/dist/interfaces/device/progressor.interface.d.ts.map +1 -1
- package/dist/interfaces/device.interface.d.ts +1 -1
- package/dist/interfaces/download.interface.d.ts +8 -11
- package/dist/interfaces/download.interface.d.ts.map +1 -1
- package/dist/models/device/climbro.model.d.ts.map +1 -1
- package/dist/models/device/climbro.model.js +34 -16
- package/dist/models/device/climbro.model.js.map +1 -1
- package/dist/models/device/entralpi.model.d.ts.map +1 -1
- package/dist/models/device/entralpi.model.js +11 -14
- package/dist/models/device/entralpi.model.js.map +1 -1
- package/dist/models/device/forceboard.model.d.ts.map +1 -1
- package/dist/models/device/forceboard.model.js +12 -17
- package/dist/models/device/forceboard.model.js.map +1 -1
- package/dist/models/device/motherboard.model.d.ts.map +1 -1
- package/dist/models/device/motherboard.model.js +28 -20
- package/dist/models/device/motherboard.model.js.map +1 -1
- package/dist/models/device/pb-700bt.model.d.ts.map +1 -1
- package/dist/models/device/pb-700bt.model.js +11 -14
- package/dist/models/device/pb-700bt.model.js.map +1 -1
- package/dist/models/device/progressor.model.d.ts +47 -5
- package/dist/models/device/progressor.model.d.ts.map +1 -1
- package/dist/models/device/progressor.model.js +184 -49
- package/dist/models/device/progressor.model.js.map +1 -1
- package/dist/models/device/smartboard-pro.model.d.ts.map +1 -1
- package/dist/models/device/smartboard-pro.model.js +11 -16
- package/dist/models/device/smartboard-pro.model.js.map +1 -1
- package/dist/models/device/wh-c06.model.d.ts.map +1 -1
- package/dist/models/device/wh-c06.model.js +11 -14
- package/dist/models/device/wh-c06.model.js.map +1 -1
- package/dist/models/device.model.d.ts +64 -3
- package/dist/models/device.model.d.ts.map +1 -1
- package/dist/models/device.model.js +146 -37
- package/dist/models/device.model.js.map +1 -1
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +29 -6
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +0 -3
- package/src/interfaces/callback.interface.ts +21 -12
- package/src/interfaces/command.interface.ts +11 -6
- package/src/interfaces/device/progressor.interface.ts +50 -0
- package/src/interfaces/device.interface.ts +1 -1
- package/src/interfaces/download.interface.ts +9 -11
- package/src/models/device/climbro.model.ts +38 -20
- package/src/models/device/entralpi.model.ts +15 -17
- package/src/models/device/forceboard.model.ts +15 -19
- package/src/models/device/motherboard.model.ts +38 -26
- package/src/models/device/pb-700bt.model.ts +14 -16
- package/src/models/device/progressor.model.ts +198 -50
- package/src/models/device/smartboard-pro.model.ts +14 -19
- package/src/models/device/wh-c06.model.ts +14 -17
- package/src/models/device.model.ts +181 -41
- package/src/utils.ts +31 -6
|
@@ -88,6 +88,14 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
88
88
|
*/
|
|
89
89
|
protected mean: number
|
|
90
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Lowest instantaneous force recorded in the session; may be negative.
|
|
93
|
+
* Initialized to Number.POSITIVE_INFINITY so the first sample sets the min.
|
|
94
|
+
* @type {number}
|
|
95
|
+
* @protected
|
|
96
|
+
*/
|
|
97
|
+
protected min: number
|
|
98
|
+
|
|
91
99
|
/**
|
|
92
100
|
* Display unit for force measurements (output unit for notify callbacks).
|
|
93
101
|
* @type {ForceUnit}
|
|
@@ -109,6 +117,52 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
109
117
|
*/
|
|
110
118
|
protected samplingRateHz?: number
|
|
111
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Timestamp (ms) of the previous BLE notification for notify-interval calculation.
|
|
122
|
+
* @protected
|
|
123
|
+
*/
|
|
124
|
+
protected lastPacketTimestamp = 0
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Count of data packets received this session (one BLE notification = one packet).
|
|
128
|
+
* @protected
|
|
129
|
+
*/
|
|
130
|
+
protected packetCount = 0
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Notify interval in ms for the current packet (set by recordPacketReceived).
|
|
134
|
+
* @protected
|
|
135
|
+
*/
|
|
136
|
+
protected currentNotifyIntervalMs: number | undefined = undefined
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Samples in the current packet (set by device before buildForceMeasurement).
|
|
140
|
+
* @protected
|
|
141
|
+
*/
|
|
142
|
+
protected currentSamplesPerPacket: number | undefined = undefined
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Call at the start of each BLE notification (packet). Updates notify interval and packet count.
|
|
146
|
+
* @protected
|
|
147
|
+
*/
|
|
148
|
+
protected recordPacketReceived(): void {
|
|
149
|
+
const now = Date.now()
|
|
150
|
+
this.currentNotifyIntervalMs = this.lastPacketTimestamp > 0 ? now - this.lastPacketTimestamp : undefined
|
|
151
|
+
this.lastPacketTimestamp = now
|
|
152
|
+
this.packetCount += 1
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Reset packet tracking (call when starting a new stream).
|
|
157
|
+
* @protected
|
|
158
|
+
*/
|
|
159
|
+
protected resetPacketTracking(): void {
|
|
160
|
+
this.lastPacketTimestamp = 0
|
|
161
|
+
this.packetCount = 0
|
|
162
|
+
this.currentNotifyIntervalMs = undefined
|
|
163
|
+
this.currentSamplesPerPacket = undefined
|
|
164
|
+
}
|
|
165
|
+
|
|
112
166
|
/**
|
|
113
167
|
* Start time of the current rate measurement interval.
|
|
114
168
|
* @type {number}
|
|
@@ -234,6 +288,7 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
234
288
|
|
|
235
289
|
this.peak = Number.NEGATIVE_INFINITY
|
|
236
290
|
this.mean = 0
|
|
291
|
+
this.min = Number.POSITIVE_INFINITY
|
|
237
292
|
this.sum = 0
|
|
238
293
|
this.dataPointCount = 0
|
|
239
294
|
this.unit = "kg"
|
|
@@ -261,17 +316,15 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
261
316
|
const current = valueOrCurrent
|
|
262
317
|
const zonePeak = useFullStats ? (peak === 0 && current < 0 ? current : peak) : valueOrCurrent
|
|
263
318
|
const zoneMean = useFullStats ? mean : valueOrCurrent
|
|
264
|
-
const
|
|
319
|
+
const zoneMin = useFullStats ? Math.min(zonePeak, current) : current
|
|
320
|
+
return {
|
|
265
321
|
unit: this.unit,
|
|
266
322
|
timestamp: Date.now(),
|
|
267
323
|
current,
|
|
268
324
|
peak: zonePeak,
|
|
269
325
|
mean: zoneMean,
|
|
326
|
+
min: zoneMin,
|
|
270
327
|
}
|
|
271
|
-
if (this.samplingRateHz !== undefined) {
|
|
272
|
-
zone.samplingRateHz = this.samplingRateHz
|
|
273
|
-
}
|
|
274
|
-
return zone
|
|
275
328
|
}
|
|
276
329
|
|
|
277
330
|
/**
|
|
@@ -304,49 +357,111 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
304
357
|
}
|
|
305
358
|
|
|
306
359
|
/**
|
|
307
|
-
*
|
|
308
|
-
* @
|
|
309
|
-
* @param distribution - Optional zone distribution: numbers (converted via buildZoneMeasurement) or full ForceMeasurement per zone
|
|
310
|
-
* @returns ForceMeasurement
|
|
311
|
-
* @protected
|
|
360
|
+
* Shared base for ForceMeasurement/DownloadPacket payload construction.
|
|
361
|
+
* @private
|
|
312
362
|
*/
|
|
313
|
-
|
|
363
|
+
private buildForcePayload(
|
|
314
364
|
current: number,
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
right?: ForceMeasurement
|
|
365
|
+
overrides?: {
|
|
366
|
+
timestamp?: number
|
|
367
|
+
sampleIndex?: number
|
|
368
|
+
distribution?: { left?: ForceMeasurement; center?: ForceMeasurement; right?: ForceMeasurement }
|
|
319
369
|
},
|
|
320
370
|
): ForceMeasurement {
|
|
321
|
-
|
|
371
|
+
const timestamp = overrides?.timestamp ?? Date.now()
|
|
322
372
|
const payload: ForceMeasurement = {
|
|
323
373
|
unit: this.unit,
|
|
324
|
-
timestamp
|
|
374
|
+
timestamp,
|
|
325
375
|
current: convertForce(current, this.streamUnit, this.unit),
|
|
326
376
|
peak: convertForce(this.peak, this.streamUnit, this.unit),
|
|
327
377
|
mean: convertForce(this.mean, this.streamUnit, this.unit),
|
|
378
|
+
min: Number.isFinite(this.min)
|
|
379
|
+
? convertForce(this.min, this.streamUnit, this.unit)
|
|
380
|
+
: convertForce(0, this.streamUnit, this.unit),
|
|
381
|
+
performance: {
|
|
382
|
+
packetIndex: this.packetCount,
|
|
383
|
+
...(overrides?.sampleIndex != null && { sampleIndex: overrides.sampleIndex }),
|
|
384
|
+
...(this.currentNotifyIntervalMs != null && { notifyIntervalMs: this.currentNotifyIntervalMs }),
|
|
385
|
+
...(this.currentSamplesPerPacket != null && { samplesPerPacket: this.currentSamplesPerPacket }),
|
|
386
|
+
...(this.samplingRateHz != null && { samplingRateHz: this.samplingRateHz }),
|
|
387
|
+
},
|
|
328
388
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
if (
|
|
333
|
-
distribution !== undefined &&
|
|
334
|
-
(distribution.left !== undefined || distribution.center !== undefined || distribution.right !== undefined)
|
|
335
|
-
) {
|
|
389
|
+
|
|
390
|
+
const distribution = overrides?.distribution
|
|
391
|
+
if (distribution && (distribution.left != null || distribution.center != null || distribution.right != null)) {
|
|
336
392
|
payload.distribution = {}
|
|
337
|
-
if (distribution.left
|
|
393
|
+
if (distribution.left != null) {
|
|
338
394
|
payload.distribution.left = convertForceMeasurement(distribution.left, this.streamUnit, this.unit)
|
|
339
395
|
}
|
|
340
|
-
if (distribution.center
|
|
396
|
+
if (distribution.center != null) {
|
|
341
397
|
payload.distribution.center = convertForceMeasurement(distribution.center, this.streamUnit, this.unit)
|
|
342
398
|
}
|
|
343
|
-
if (distribution.right
|
|
399
|
+
if (distribution.right != null) {
|
|
344
400
|
payload.distribution.right = convertForceMeasurement(distribution.right, this.streamUnit, this.unit)
|
|
345
401
|
}
|
|
346
402
|
}
|
|
403
|
+
|
|
347
404
|
return payload
|
|
348
405
|
}
|
|
349
406
|
|
|
407
|
+
/**
|
|
408
|
+
* Builds a ForceMeasurement payload for notify callbacks.
|
|
409
|
+
* @param current - Current force at this sample
|
|
410
|
+
* @param distribution - Optional per-zone measurements (e.g. from buildZoneMeasurement)
|
|
411
|
+
* @returns ForceMeasurement
|
|
412
|
+
* @protected
|
|
413
|
+
*/
|
|
414
|
+
protected buildForceMeasurement(
|
|
415
|
+
current: number,
|
|
416
|
+
distribution?: {
|
|
417
|
+
left?: ForceMeasurement
|
|
418
|
+
center?: ForceMeasurement
|
|
419
|
+
right?: ForceMeasurement
|
|
420
|
+
},
|
|
421
|
+
): ForceMeasurement {
|
|
422
|
+
this.updateSamplingRate()
|
|
423
|
+
return this.buildForcePayload(
|
|
424
|
+
current,
|
|
425
|
+
distribution != null ? { sampleIndex: this.dataPointCount, distribution } : { sampleIndex: this.dataPointCount },
|
|
426
|
+
)
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Builds a DownloadPacket for export (CSV, JSON, XML).
|
|
431
|
+
* Converts force values from streamUnit to display unit.
|
|
432
|
+
* @param current - Current force at this sample (stream unit)
|
|
433
|
+
* @param samples - Raw sensor/ADC values from device
|
|
434
|
+
* @param options - Optional timestamp, battRaw, sampleIndex, distribution (for multi-zone)
|
|
435
|
+
* @returns DownloadPacket
|
|
436
|
+
* @protected
|
|
437
|
+
*/
|
|
438
|
+
protected buildDownloadPacket(
|
|
439
|
+
current: number,
|
|
440
|
+
samples: number[],
|
|
441
|
+
options?: {
|
|
442
|
+
timestamp?: number
|
|
443
|
+
battRaw?: number
|
|
444
|
+
sampleIndex?: number
|
|
445
|
+
distribution?: { left?: ForceMeasurement; center?: ForceMeasurement; right?: ForceMeasurement }
|
|
446
|
+
},
|
|
447
|
+
): DownloadPacket {
|
|
448
|
+
const overrides: {
|
|
449
|
+
timestamp?: number
|
|
450
|
+
sampleIndex?: number
|
|
451
|
+
distribution?: { left?: ForceMeasurement; center?: ForceMeasurement; right?: ForceMeasurement }
|
|
452
|
+
} = {}
|
|
453
|
+
if (options?.timestamp != null) overrides.timestamp = options.timestamp
|
|
454
|
+
if (options?.sampleIndex != null) overrides.sampleIndex = options.sampleIndex
|
|
455
|
+
if (options?.distribution != null) overrides.distribution = options.distribution
|
|
456
|
+
const packet = this.buildForcePayload(
|
|
457
|
+
current,
|
|
458
|
+
Object.keys(overrides).length > 0 ? overrides : undefined,
|
|
459
|
+
) as DownloadPacket
|
|
460
|
+
packet.samples = samples
|
|
461
|
+
if (options?.battRaw != null) packet.battRaw = options.battRaw
|
|
462
|
+
return packet
|
|
463
|
+
}
|
|
464
|
+
|
|
350
465
|
/**
|
|
351
466
|
* Sets the callback function to be called when the activity status changes,
|
|
352
467
|
* and optionally sets the configuration for threshold and duration.
|
|
@@ -523,18 +638,30 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
523
638
|
return ""
|
|
524
639
|
}
|
|
525
640
|
return packets
|
|
526
|
-
.map((packet) =>
|
|
527
|
-
|
|
528
|
-
packet.
|
|
529
|
-
|
|
530
|
-
|
|
641
|
+
.map((packet) => {
|
|
642
|
+
const forceValues =
|
|
643
|
+
packet.distribution != null
|
|
644
|
+
? [
|
|
645
|
+
packet.distribution.left?.current ?? "",
|
|
646
|
+
packet.distribution.center?.current ?? "",
|
|
647
|
+
packet.distribution.right?.current ?? "",
|
|
648
|
+
].map((v) => (v !== "" ? String(v) : ""))
|
|
649
|
+
: [packet.current.toString()]
|
|
650
|
+
return [
|
|
651
|
+
packet.timestamp.toString(),
|
|
652
|
+
packet.current.toString(),
|
|
653
|
+
packet.peak.toString(),
|
|
654
|
+
packet.mean.toString(),
|
|
655
|
+
packet.min.toString(),
|
|
656
|
+
(packet.performance?.sampleIndex ?? "").toString(),
|
|
657
|
+
(packet.battRaw ?? "").toString(),
|
|
531
658
|
...packet.samples.map(String),
|
|
532
|
-
...
|
|
659
|
+
...forceValues,
|
|
533
660
|
]
|
|
534
661
|
.map((v) => v.replace(/"/g, '""'))
|
|
535
662
|
.map((v) => `"${v}"`)
|
|
536
|
-
.join(",")
|
|
537
|
-
)
|
|
663
|
+
.join(",")
|
|
664
|
+
})
|
|
538
665
|
.join("\r\n")
|
|
539
666
|
}
|
|
540
667
|
|
|
@@ -565,14 +692,27 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
565
692
|
const xmlPackets = this.downloadPackets
|
|
566
693
|
.map((packet) => {
|
|
567
694
|
const samples = packet.samples.map((sample) => `<sample>${sample}</sample>`).join("")
|
|
568
|
-
const
|
|
695
|
+
const distributionElements =
|
|
696
|
+
packet.distribution != null
|
|
697
|
+
? [
|
|
698
|
+
packet.distribution.left?.current != null ? `<left>${packet.distribution.left.current}</left>` : "",
|
|
699
|
+
packet.distribution.center?.current != null
|
|
700
|
+
? `<center>${packet.distribution.center.current}</center>`
|
|
701
|
+
: "",
|
|
702
|
+
packet.distribution.right?.current != null ? `<right>${packet.distribution.right.current}</right>` : "",
|
|
703
|
+
].join("")
|
|
704
|
+
: ""
|
|
569
705
|
return `
|
|
570
706
|
<packet>
|
|
571
|
-
<
|
|
572
|
-
<
|
|
573
|
-
<
|
|
707
|
+
<timestamp>${packet.timestamp}</timestamp>
|
|
708
|
+
<current>${packet.current}</current>
|
|
709
|
+
<peak>${packet.peak}</peak>
|
|
710
|
+
<mean>${packet.mean}</mean>
|
|
711
|
+
<min>${packet.min}</min>
|
|
712
|
+
${packet.performance?.sampleIndex != null ? `<sampleIndex>${packet.performance.sampleIndex}</sampleIndex>` : ""}
|
|
713
|
+
${packet.battRaw != null ? `<battRaw>${packet.battRaw}</battRaw>` : ""}
|
|
574
714
|
<samples>${samples}</samples>
|
|
575
|
-
|
|
715
|
+
${distributionElements}
|
|
576
716
|
</packet>
|
|
577
717
|
`
|
|
578
718
|
})
|
|
@@ -939,7 +1079,7 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
939
1079
|
*
|
|
940
1080
|
* @example
|
|
941
1081
|
* // Example usage of the write function with a custom callback
|
|
942
|
-
* await Progressor.write("progressor", "tx", ProgressorCommands.
|
|
1082
|
+
* await Progressor.write("progressor", "tx", ProgressorCommands.GET_BATTERY_VOLTAGE, 250, (data) => {
|
|
943
1083
|
* console.log(`Battery voltage: ${data}`);
|
|
944
1084
|
* });
|
|
945
1085
|
*/
|
package/src/utils.ts
CHANGED
|
@@ -1,10 +1,34 @@
|
|
|
1
1
|
import type { ForceMeasurement, ForceUnit } from "./interfaces/callback.interface.js"
|
|
2
2
|
|
|
3
|
-
/** 1
|
|
4
|
-
const
|
|
3
|
+
/** 1 kgf = this many N (standard gravity) */
|
|
4
|
+
const KG_TO_N = 9.80665
|
|
5
|
+
/** 1 lbf = this many N */
|
|
6
|
+
const LBS_TO_N = 4.4482216152605
|
|
7
|
+
|
|
8
|
+
function toNewtons(value: number, from: ForceUnit): number {
|
|
9
|
+
switch (from) {
|
|
10
|
+
case "kg":
|
|
11
|
+
return value * KG_TO_N
|
|
12
|
+
case "lbs":
|
|
13
|
+
return value * LBS_TO_N
|
|
14
|
+
case "n":
|
|
15
|
+
return value
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function fromNewtons(value: number, to: ForceUnit): number {
|
|
20
|
+
switch (to) {
|
|
21
|
+
case "kg":
|
|
22
|
+
return value / KG_TO_N
|
|
23
|
+
case "lbs":
|
|
24
|
+
return value / LBS_TO_N
|
|
25
|
+
case "n":
|
|
26
|
+
return value
|
|
27
|
+
}
|
|
28
|
+
}
|
|
5
29
|
|
|
6
30
|
/**
|
|
7
|
-
* Converts a force value between kg and
|
|
31
|
+
* Converts a force value between kg, lbs, and newtons.
|
|
8
32
|
* @param value - The numeric force value in the source unit.
|
|
9
33
|
* @param from - The unit of the input value.
|
|
10
34
|
* @param to - The unit for the output value.
|
|
@@ -12,7 +36,7 @@ const KG_TO_LBS = 2.20462262185
|
|
|
12
36
|
*/
|
|
13
37
|
export function convertForce(value: number, from: ForceUnit, to: ForceUnit): number {
|
|
14
38
|
if (from === to) return value
|
|
15
|
-
return
|
|
39
|
+
return fromNewtons(toNewtons(value, from), to)
|
|
16
40
|
}
|
|
17
41
|
|
|
18
42
|
/**
|
|
@@ -32,9 +56,10 @@ export function convertForceMeasurement(
|
|
|
32
56
|
current: convertForce(measurement.current, from, to),
|
|
33
57
|
peak: convertForce(measurement.peak, from, to),
|
|
34
58
|
mean: convertForce(measurement.mean, from, to),
|
|
59
|
+
min: convertForce(measurement.min, from, to),
|
|
35
60
|
}
|
|
36
|
-
if (measurement.
|
|
37
|
-
out.
|
|
61
|
+
if (measurement.performance !== undefined) {
|
|
62
|
+
out.performance = { ...measurement.performance }
|
|
38
63
|
}
|
|
39
64
|
if (
|
|
40
65
|
measurement.distribution &&
|