@hangtime/grip-connect 0.13.0 → 0.13.1
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 +9 -9
- package/dist/cjs/index.d.ts +2 -2
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +2 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/interfaces/device/aurora.interface.d.ts +17 -0
- package/dist/cjs/interfaces/device/aurora.interface.d.ts.map +1 -0
- package/dist/cjs/interfaces/device/{kilterboard.interface.js → aurora.interface.js} +1 -1
- package/dist/cjs/interfaces/device/aurora.interface.js.map +1 -0
- package/dist/cjs/interfaces/device/motherboard.interface.d.ts +1 -1
- package/dist/cjs/interfaces/device/pb-700bt.interface.d.ts +53 -0
- package/dist/cjs/interfaces/device/pb-700bt.interface.d.ts.map +1 -0
- package/dist/cjs/interfaces/device/pb-700bt.interface.js +3 -0
- package/dist/cjs/interfaces/device/pb-700bt.interface.js.map +1 -0
- package/dist/cjs/interfaces/index.d.ts +2 -1
- package/dist/cjs/interfaces/index.d.ts.map +1 -1
- package/dist/cjs/models/device/{kilterboard.model.d.ts → aurora.model.d.ts} +82 -40
- package/dist/cjs/models/device/aurora.model.d.ts.map +1 -0
- package/dist/cjs/models/device/aurora.model.js +407 -0
- package/dist/cjs/models/device/aurora.model.js.map +1 -0
- package/dist/cjs/models/device/climbro.model.js +1 -1
- package/dist/cjs/models/device/climbro.model.js.map +1 -1
- package/dist/cjs/models/device/cts500.model.d.ts.map +1 -1
- package/dist/cjs/models/device/cts500.model.js +12 -4
- package/dist/cjs/models/device/cts500.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 +6 -2
- package/dist/cjs/models/device/forceboard.model.js.map +1 -1
- package/dist/cjs/models/device/motherboard.model.d.ts +4 -1
- package/dist/cjs/models/device/motherboard.model.d.ts.map +1 -1
- package/dist/cjs/models/device/motherboard.model.js +26 -10
- package/dist/cjs/models/device/motherboard.model.js.map +1 -1
- package/dist/cjs/models/device/pb-700bt.model.d.ts +2 -1
- package/dist/cjs/models/device/pb-700bt.model.d.ts.map +1 -1
- package/dist/cjs/models/device/pb-700bt.model.js.map +1 -1
- package/dist/cjs/models/device/progressor.model.d.ts.map +1 -1
- package/dist/cjs/models/device/progressor.model.js +1 -6
- package/dist/cjs/models/device/progressor.model.js.map +1 -1
- package/dist/cjs/models/device/wh-c06.model.d.ts +2 -0
- package/dist/cjs/models/device/wh-c06.model.d.ts.map +1 -1
- package/dist/cjs/models/device/wh-c06.model.js +45 -34
- package/dist/cjs/models/device/wh-c06.model.js.map +1 -1
- package/dist/cjs/models/device.model.d.ts +18 -5
- package/dist/cjs/models/device.model.d.ts.map +1 -1
- package/dist/cjs/models/device.model.js +71 -16
- package/dist/cjs/models/device.model.js.map +1 -1
- package/dist/cjs/models/index.d.ts +1 -1
- package/dist/cjs/models/index.d.ts.map +1 -1
- package/dist/cjs/models/index.js +3 -4
- package/dist/cjs/models/index.js.map +1 -1
- package/dist/cjs/package.json +3 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces/device/aurora.interface.d.ts +17 -0
- package/dist/interfaces/device/aurora.interface.d.ts.map +1 -0
- package/dist/interfaces/device/aurora.interface.js +2 -0
- package/dist/interfaces/device/aurora.interface.js.map +1 -0
- package/dist/interfaces/device/motherboard.interface.d.ts +1 -1
- package/dist/interfaces/device/pb-700bt.interface.d.ts +53 -0
- package/dist/interfaces/device/pb-700bt.interface.d.ts.map +1 -0
- package/dist/interfaces/device/pb-700bt.interface.js +2 -0
- package/dist/interfaces/device/pb-700bt.interface.js.map +1 -0
- package/dist/interfaces/index.d.ts +2 -1
- package/dist/interfaces/index.d.ts.map +1 -1
- package/dist/models/device/{kilterboard.model.d.ts → aurora.model.d.ts} +82 -40
- package/dist/models/device/aurora.model.d.ts.map +1 -0
- package/dist/models/device/aurora.model.js +401 -0
- package/dist/models/device/aurora.model.js.map +1 -0
- package/dist/models/device/climbro.model.js +1 -1
- package/dist/models/device/climbro.model.js.map +1 -1
- package/dist/models/device/cts500.model.d.ts.map +1 -1
- package/dist/models/device/cts500.model.js +12 -4
- package/dist/models/device/cts500.model.js.map +1 -1
- package/dist/models/device/forceboard.model.d.ts.map +1 -1
- package/dist/models/device/forceboard.model.js +6 -2
- package/dist/models/device/forceboard.model.js.map +1 -1
- package/dist/models/device/motherboard.model.d.ts +4 -1
- package/dist/models/device/motherboard.model.d.ts.map +1 -1
- package/dist/models/device/motherboard.model.js +26 -10
- package/dist/models/device/motherboard.model.js.map +1 -1
- package/dist/models/device/pb-700bt.model.d.ts +2 -1
- package/dist/models/device/pb-700bt.model.d.ts.map +1 -1
- package/dist/models/device/pb-700bt.model.js.map +1 -1
- package/dist/models/device/progressor.model.d.ts.map +1 -1
- package/dist/models/device/progressor.model.js +1 -6
- package/dist/models/device/progressor.model.js.map +1 -1
- package/dist/models/device/wh-c06.model.d.ts +2 -0
- package/dist/models/device/wh-c06.model.d.ts.map +1 -1
- package/dist/models/device/wh-c06.model.js +44 -34
- package/dist/models/device/wh-c06.model.js.map +1 -1
- package/dist/models/device.model.d.ts +18 -5
- package/dist/models/device.model.d.ts.map +1 -1
- package/dist/models/device.model.js +71 -16
- package/dist/models/device.model.js.map +1 -1
- package/dist/models/index.d.ts +1 -1
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/index.js +1 -1
- package/dist/models/index.js.map +1 -1
- package/package.json +45 -42
- package/src/index.ts +4 -3
- package/src/interfaces/device/aurora.interface.ts +18 -0
- package/src/interfaces/device/motherboard.interface.ts +1 -1
- package/src/interfaces/device/pb-700bt.interface.ts +61 -0
- package/src/interfaces/index.ts +4 -2
- package/src/models/device/aurora.model.ts +497 -0
- package/src/models/device/climbro.model.ts +1 -1
- package/src/models/device/cts500.model.ts +14 -7
- package/src/models/device/forceboard.model.ts +6 -2
- package/src/models/device/motherboard.model.ts +51 -9
- package/src/models/device/pb-700bt.model.ts +2 -1
- package/src/models/device/progressor.model.ts +1 -6
- package/src/models/device/wh-c06.model.ts +54 -42
- package/src/models/device.model.ts +82 -16
- package/src/models/index.ts +2 -2
- package/dist/cjs/interfaces/device/kilterboard.interface.d.ts +0 -17
- package/dist/cjs/interfaces/device/kilterboard.interface.d.ts.map +0 -1
- package/dist/cjs/interfaces/device/kilterboard.interface.js.map +0 -1
- package/dist/cjs/models/device/kilterboard.model.d.ts.map +0 -1
- package/dist/cjs/models/device/kilterboard.model.js +0 -327
- package/dist/cjs/models/device/kilterboard.model.js.map +0 -1
- package/dist/interfaces/device/kilterboard.interface.d.ts +0 -17
- package/dist/interfaces/device/kilterboard.interface.d.ts.map +0 -1
- package/dist/interfaces/device/kilterboard.interface.js +0 -2
- package/dist/interfaces/device/kilterboard.interface.js.map +0 -1
- package/dist/models/device/kilterboard.model.d.ts.map +0 -1
- package/dist/models/device/kilterboard.model.js +0 -323
- package/dist/models/device/kilterboard.model.js.map +0 -1
- package/dist/tsconfig.cjs.tsbuildinfo +0 -1
- package/src/interfaces/device/kilterboard.interface.ts +0 -12
- package/src/models/device/kilterboard.model.ts +0 -347
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Device } from "../device.model.js"
|
|
2
|
+
import type { IPB700BT } from "../../interfaces/device/pb-700bt.interface.js"
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Represents a NSD PB-700BT device.
|
|
5
6
|
* {@link https://www.nsd.com.tw/}
|
|
6
7
|
*/
|
|
7
|
-
export class PB700BT extends Device {
|
|
8
|
+
export class PB700BT extends Device implements IPB700BT {
|
|
8
9
|
constructor() {
|
|
9
10
|
super({
|
|
10
11
|
filters: [{ name: "NSD Workout" }],
|
|
@@ -456,12 +456,7 @@ export class Progressor extends NordicDfuDevice implements IProgressor {
|
|
|
456
456
|
*/
|
|
457
457
|
stream = async (duration = 0): Promise<void> => {
|
|
458
458
|
// Reset download packets and session stats for fresh measurement
|
|
459
|
-
this.
|
|
460
|
-
this.peak = Number.NEGATIVE_INFINITY
|
|
461
|
-
this.mean = 0
|
|
462
|
-
this.sum = 0
|
|
463
|
-
this.dataPointCount = 0
|
|
464
|
-
this.min = Number.POSITIVE_INFINITY
|
|
459
|
+
this.resetSessionData()
|
|
465
460
|
this.resetPacketTracking()
|
|
466
461
|
this.recentSampleTimestamps = []
|
|
467
462
|
// Start streaming data
|
|
@@ -41,6 +41,45 @@ export class WHC06 extends Device implements IWHC06 {
|
|
|
41
41
|
*/
|
|
42
42
|
private readonly advertisementTimeoutTime: number = 10
|
|
43
43
|
|
|
44
|
+
private readonly onAdvertisementReceived = (event: BluetoothAdvertisingEvent): void => {
|
|
45
|
+
const data = event.manufacturerData.get(WHC06.manufacturerId)
|
|
46
|
+
if (data) {
|
|
47
|
+
this.currentSamplesPerPacket = 1
|
|
48
|
+
this.recordPacketReceived()
|
|
49
|
+
const weight = (data.getUint8(WHC06.weightOffset) << 8) | data.getUint8(WHC06.weightOffset + 1)
|
|
50
|
+
// const stable = (data.getUint8(STABLE_OFFSET) & 0xf0) >> 4
|
|
51
|
+
// const unit = data.getUint8(STABLE_OFFSET) & 0x0f
|
|
52
|
+
const receivedTime: number = Date.now()
|
|
53
|
+
const receivedData = weight / 100
|
|
54
|
+
|
|
55
|
+
const numericData = receivedData - this.applyTare(receivedData)
|
|
56
|
+
const currentMassTotal = Math.max(-1000, numericData)
|
|
57
|
+
|
|
58
|
+
// Update session stats before building packet
|
|
59
|
+
this.peak = Math.max(this.peak, numericData)
|
|
60
|
+
this.min = Math.min(this.min, Math.max(-1000, numericData))
|
|
61
|
+
this.sum += currentMassTotal
|
|
62
|
+
this.dataPointCount++
|
|
63
|
+
this.mean = this.sum / this.dataPointCount
|
|
64
|
+
|
|
65
|
+
// Add data to downloadable Array
|
|
66
|
+
this.downloadPackets.push(
|
|
67
|
+
this.buildDownloadPacket(currentMassTotal, [numericData], {
|
|
68
|
+
timestamp: receivedTime,
|
|
69
|
+
sampleIndex: this.dataPointCount,
|
|
70
|
+
}),
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
// Check if device is being used
|
|
74
|
+
this.activityCheck(numericData)
|
|
75
|
+
|
|
76
|
+
// Notify with weight data
|
|
77
|
+
this.notifyCallback(this.buildForceMeasurement(currentMassTotal))
|
|
78
|
+
}
|
|
79
|
+
// Reset "still advertising" counter
|
|
80
|
+
this.resetAdvertisementTimeout()
|
|
81
|
+
}
|
|
82
|
+
|
|
44
83
|
// /**
|
|
45
84
|
// * Offset for the byte location in the manufacturer data to determine weight stability.
|
|
46
85
|
// * @type {number}
|
|
@@ -93,47 +132,7 @@ export class WHC06 extends Device implements IWHC06 {
|
|
|
93
132
|
// Update timestamp
|
|
94
133
|
this.updateTimestamp()
|
|
95
134
|
|
|
96
|
-
|
|
97
|
-
onSuccess()
|
|
98
|
-
|
|
99
|
-
this.bluetooth.addEventListener("advertisementreceived", (event) => {
|
|
100
|
-
const data = event.manufacturerData.get(WHC06.manufacturerId)
|
|
101
|
-
if (data) {
|
|
102
|
-
this.currentSamplesPerPacket = 1
|
|
103
|
-
this.recordPacketReceived()
|
|
104
|
-
const weight = (data.getUint8(WHC06.weightOffset) << 8) | data.getUint8(WHC06.weightOffset + 1)
|
|
105
|
-
// const stable = (data.getUint8(STABLE_OFFSET) & 0xf0) >> 4
|
|
106
|
-
// const unit = data.getUint8(STABLE_OFFSET) & 0x0f
|
|
107
|
-
const receivedTime: number = Date.now()
|
|
108
|
-
const receivedData = weight / 100
|
|
109
|
-
|
|
110
|
-
const numericData = receivedData - this.applyTare(receivedData) * -1
|
|
111
|
-
const currentMassTotal = Math.max(-1000, numericData)
|
|
112
|
-
|
|
113
|
-
// Update session stats before building packet
|
|
114
|
-
this.peak = Math.max(this.peak, numericData)
|
|
115
|
-
this.min = Math.min(this.min, Math.max(-1000, numericData))
|
|
116
|
-
this.sum += currentMassTotal
|
|
117
|
-
this.dataPointCount++
|
|
118
|
-
this.mean = this.sum / this.dataPointCount
|
|
119
|
-
|
|
120
|
-
// Add data to downloadable Array
|
|
121
|
-
this.downloadPackets.push(
|
|
122
|
-
this.buildDownloadPacket(currentMassTotal, [numericData], {
|
|
123
|
-
timestamp: receivedTime,
|
|
124
|
-
sampleIndex: this.dataPointCount,
|
|
125
|
-
}),
|
|
126
|
-
)
|
|
127
|
-
|
|
128
|
-
// Check if device is being used
|
|
129
|
-
this.activityCheck(numericData)
|
|
130
|
-
|
|
131
|
-
// Notify with weight data
|
|
132
|
-
this.notifyCallback(this.buildForceMeasurement(currentMassTotal))
|
|
133
|
-
}
|
|
134
|
-
// Reset "still advertising" counter
|
|
135
|
-
this.resetAdvertisementTimeout()
|
|
136
|
-
})
|
|
135
|
+
this.bluetooth.addEventListener("advertisementreceived", this.onAdvertisementReceived)
|
|
137
136
|
|
|
138
137
|
// When the companyIdentifier is provided we want to get manufacturerData using watchAdvertisements.
|
|
139
138
|
if (optionalManufacturerData.length) {
|
|
@@ -148,7 +147,11 @@ export class WHC06 extends Device implements IWHC06 {
|
|
|
148
147
|
)
|
|
149
148
|
}
|
|
150
149
|
}
|
|
150
|
+
|
|
151
|
+
// Device has no services / characteristics, so success means advertisement watching is ready.
|
|
152
|
+
onSuccess()
|
|
151
153
|
} catch (error) {
|
|
154
|
+
this.disconnect()
|
|
152
155
|
onError(error as Error)
|
|
153
156
|
}
|
|
154
157
|
}
|
|
@@ -167,7 +170,7 @@ export class WHC06 extends Device implements IWHC06 {
|
|
|
167
170
|
*/
|
|
168
171
|
private resetAdvertisementTimeout = (): void => {
|
|
169
172
|
// Clear the previous timeout
|
|
170
|
-
if (this.advertisementTimeout) {
|
|
173
|
+
if (this.advertisementTimeout !== null) {
|
|
171
174
|
clearTimeout(this.advertisementTimeout)
|
|
172
175
|
}
|
|
173
176
|
|
|
@@ -184,4 +187,13 @@ export class WHC06 extends Device implements IWHC06 {
|
|
|
184
187
|
this.onDisconnected(disconnectedEvent)
|
|
185
188
|
}, this.advertisementTimeoutTime * 1000) // 10 seconds
|
|
186
189
|
}
|
|
190
|
+
|
|
191
|
+
protected override onDisconnectCleanup(): void {
|
|
192
|
+
if (this.advertisementTimeout !== null) {
|
|
193
|
+
clearTimeout(this.advertisementTimeout)
|
|
194
|
+
this.advertisementTimeout = null
|
|
195
|
+
}
|
|
196
|
+
this.bluetooth?.removeEventListener("advertisementreceived", this.onAdvertisementReceived)
|
|
197
|
+
delete this.bluetooth
|
|
198
|
+
}
|
|
187
199
|
}
|
|
@@ -284,6 +284,8 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
284
284
|
*/
|
|
285
285
|
private notificationListeners = new Map<string, EventListener>()
|
|
286
286
|
|
|
287
|
+
private activeCheckPending: { target: boolean; timeout: ReturnType<typeof setTimeout> } | undefined = undefined
|
|
288
|
+
|
|
287
289
|
constructor(device: Partial<IDevice>) {
|
|
288
290
|
super(device)
|
|
289
291
|
|
|
@@ -312,19 +314,20 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
312
314
|
/**
|
|
313
315
|
* Builds a ForceMeasurement for a single zone (e.g. left/center/right).
|
|
314
316
|
* With one argument, current/peak/mean are all set to that value.
|
|
315
|
-
* With three arguments, uses the given current, peak, and
|
|
317
|
+
* With three or four arguments, uses the given current, peak, mean, and min for the zone.
|
|
316
318
|
* @param valueOrCurrent - Force value, or current force for this zone
|
|
317
319
|
* @param peak - Optional peak for this zone (required if mean is provided)
|
|
318
320
|
* @param mean - Optional mean for this zone
|
|
321
|
+
* @param min - Optional session minimum for this zone
|
|
319
322
|
* @returns ForceMeasurement (no nested distribution)
|
|
320
323
|
* @protected
|
|
321
324
|
*/
|
|
322
|
-
protected buildZoneMeasurement(valueOrCurrent: number, peak?: number, mean?: number): ForceMeasurement {
|
|
325
|
+
protected buildZoneMeasurement(valueOrCurrent: number, peak?: number, mean?: number, min?: number): ForceMeasurement {
|
|
323
326
|
const useFullStats = peak !== undefined && mean !== undefined
|
|
324
327
|
const current = valueOrCurrent
|
|
325
328
|
const zonePeak = useFullStats ? (peak === 0 && current < 0 ? current : peak) : valueOrCurrent
|
|
326
329
|
const zoneMean = useFullStats ? mean : valueOrCurrent
|
|
327
|
-
const zoneMin = useFullStats ? Math.min(zonePeak, current) : current
|
|
330
|
+
const zoneMin = useFullStats ? (min ?? Math.min(zonePeak, current)) : current
|
|
328
331
|
return {
|
|
329
332
|
unit: this.unit,
|
|
330
333
|
timestamp: Date.now(),
|
|
@@ -501,6 +504,21 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
501
504
|
}
|
|
502
505
|
}
|
|
503
506
|
|
|
507
|
+
/**
|
|
508
|
+
* Resets per-session measurement state: the download buffer and force statistics.
|
|
509
|
+
* Device models call this at the start of a new streaming session so stats from a
|
|
510
|
+
* previous session do not leak into the next one.
|
|
511
|
+
* @protected
|
|
512
|
+
*/
|
|
513
|
+
protected resetSessionData(): void {
|
|
514
|
+
this.downloadPackets.length = 0
|
|
515
|
+
this.peak = Number.NEGATIVE_INFINITY
|
|
516
|
+
this.min = Number.POSITIVE_INFINITY
|
|
517
|
+
this.mean = 0
|
|
518
|
+
this.sum = 0
|
|
519
|
+
this.dataPointCount = 0
|
|
520
|
+
}
|
|
521
|
+
|
|
504
522
|
/**
|
|
505
523
|
* Checks if a dynamic value is active based on a threshold and duration.
|
|
506
524
|
*
|
|
@@ -509,20 +527,37 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
509
527
|
* the previous state, the callback function is called with the updated activity status.
|
|
510
528
|
*
|
|
511
529
|
* @param {number} input - The dynamic value to check for activity status.
|
|
512
|
-
* @returns {Promise<void>} A promise that resolves once the activity check is complete.
|
|
513
530
|
*
|
|
514
531
|
* @example
|
|
515
|
-
*
|
|
532
|
+
* device.activityCheck(5.0);
|
|
516
533
|
*/
|
|
517
|
-
protected activityCheck =
|
|
518
|
-
const startValue = input
|
|
534
|
+
protected activityCheck = (input: number): void => {
|
|
519
535
|
const { threshold, duration } = this.activeConfig
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
536
|
+
const activeNow = input > threshold
|
|
537
|
+
|
|
538
|
+
if (activeNow === this.isActive) {
|
|
539
|
+
if (this.activeCheckPending) {
|
|
540
|
+
clearTimeout(this.activeCheckPending.timeout)
|
|
541
|
+
this.activeCheckPending = undefined
|
|
542
|
+
}
|
|
543
|
+
return
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
if (this.activeCheckPending?.target === activeNow) {
|
|
547
|
+
return
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
if (this.activeCheckPending) {
|
|
551
|
+
clearTimeout(this.activeCheckPending.timeout)
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
this.activeCheckPending = {
|
|
555
|
+
target: activeNow,
|
|
556
|
+
timeout: setTimeout(() => {
|
|
557
|
+
this.isActive = activeNow
|
|
558
|
+
this.activeCallback(activeNow)
|
|
559
|
+
this.activeCheckPending = undefined
|
|
560
|
+
}, duration),
|
|
526
561
|
}
|
|
527
562
|
}
|
|
528
563
|
|
|
@@ -577,6 +612,13 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
577
612
|
})
|
|
578
613
|
}
|
|
579
614
|
|
|
615
|
+
if (!this.bluetooth) {
|
|
616
|
+
throw new Error("Bluetooth device is not available")
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// Hook for when a device has been selected.
|
|
620
|
+
this.onBluetoothDeviceSelected(this.bluetooth)
|
|
621
|
+
|
|
580
622
|
if (!this.bluetooth.gatt) {
|
|
581
623
|
throw new Error("GATT is not available on this device")
|
|
582
624
|
}
|
|
@@ -585,10 +627,13 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
585
627
|
|
|
586
628
|
this.server = this.bluetooth.gatt.connected ? this.bluetooth.gatt : await this.bluetooth.gatt.connect()
|
|
587
629
|
|
|
588
|
-
if (this.server.connected) {
|
|
589
|
-
|
|
630
|
+
if (!this.server.connected) {
|
|
631
|
+
throw new Error("GATT server did not connect")
|
|
590
632
|
}
|
|
633
|
+
|
|
634
|
+
await this.onConnected(onSuccess)
|
|
591
635
|
} catch (error) {
|
|
636
|
+
this.disconnect()
|
|
592
637
|
onError(error as Error)
|
|
593
638
|
}
|
|
594
639
|
}
|
|
@@ -639,6 +684,15 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
639
684
|
this.server = undefined
|
|
640
685
|
this.writeLast = null
|
|
641
686
|
this.isActive = false
|
|
687
|
+
if (this.activeCheckPending) {
|
|
688
|
+
clearTimeout(this.activeCheckPending.timeout)
|
|
689
|
+
this.activeCheckPending = undefined
|
|
690
|
+
}
|
|
691
|
+
this.onDisconnectCleanup()
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
protected onDisconnectCleanup(): void {
|
|
695
|
+
return
|
|
642
696
|
}
|
|
643
697
|
|
|
644
698
|
/**
|
|
@@ -830,6 +884,14 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
830
884
|
throw new Error("Bluetooth not available.")
|
|
831
885
|
}
|
|
832
886
|
|
|
887
|
+
/**
|
|
888
|
+
* Hook for device-specific setup after a Bluetooth device has been selected.
|
|
889
|
+
*/
|
|
890
|
+
protected onBluetoothDeviceSelected(device: BluetoothDevice): void {
|
|
891
|
+
void device
|
|
892
|
+
return
|
|
893
|
+
}
|
|
894
|
+
|
|
833
895
|
/**
|
|
834
896
|
* Handles notifications received from a characteristic.
|
|
835
897
|
* @param {DataView} value - The notification event.
|
|
@@ -934,7 +996,7 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
934
996
|
// Look for our default notify characteristic id that accepts notifications
|
|
935
997
|
if (descriptor.id === this.notifyCharacteristicId) {
|
|
936
998
|
// Start receiving notifications for changes on this characteristic
|
|
937
|
-
matchingCharacteristic.startNotifications()
|
|
999
|
+
await matchingCharacteristic.startNotifications()
|
|
938
1000
|
// Triggered when the characteristic's value changes
|
|
939
1001
|
const listener = (event: Event) => {
|
|
940
1002
|
// Cast the event's target to a BluetoothRemoteGATTCharacteristic to access its properties
|
|
@@ -944,6 +1006,10 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
944
1006
|
this.handleNotifications(target.value)
|
|
945
1007
|
}
|
|
946
1008
|
}
|
|
1009
|
+
const existingListener = this.notificationListeners.get(descriptor.uuid)
|
|
1010
|
+
if (existingListener) {
|
|
1011
|
+
matchingCharacteristic.removeEventListener("characteristicvaluechanged", existingListener)
|
|
1012
|
+
}
|
|
947
1013
|
// Attach the event listener to listen for changes in the characteristic's value
|
|
948
1014
|
matchingCharacteristic.addEventListener("characteristicvaluechanged", listener)
|
|
949
1015
|
// Store the listener so it can be referenced (for later removal)
|
package/src/models/index.ts
CHANGED
|
@@ -8,8 +8,6 @@ export { ForceBoard } from "./device/forceboard.model.js"
|
|
|
8
8
|
|
|
9
9
|
export { NordicDfuDevice, createNordicDfuService } from "./nordic.model.js"
|
|
10
10
|
|
|
11
|
-
export { KilterBoard, KilterBoardPlacementRoles } from "./device/kilterboard.model.js"
|
|
12
|
-
|
|
13
11
|
export { Motherboard } from "./device/motherboard.model.js"
|
|
14
12
|
|
|
15
13
|
export { mySmartBoard } from "./device/mysmartboard.model.js"
|
|
@@ -21,3 +19,5 @@ export { Progressor } from "./device/progressor.model.js"
|
|
|
21
19
|
export { SmartBoardPro } from "./device/smartboard-pro.model.js"
|
|
22
20
|
|
|
23
21
|
export { WHC06 } from "./device/wh-c06.model.js"
|
|
22
|
+
|
|
23
|
+
export { AuroraBoard } from "./device/aurora.model.js"
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { IDevice } from "../device.interface.js";
|
|
2
|
-
/**
|
|
3
|
-
* Interface representing the KilterBoard device, extending the base Device interface.
|
|
4
|
-
*/
|
|
5
|
-
export interface IKilterBoard extends IDevice {
|
|
6
|
-
/**
|
|
7
|
-
* Configures the LEDs based on an array of climb placements.
|
|
8
|
-
* @param {{ position: number; role_id?: number; color?: string }[]} config - Array of climb placements for the LEDs. Either role_id or color (hex string) must be provided.
|
|
9
|
-
* @returns {Promise<number[] | undefined>} A promise that resolves with the payload array for the Kilter Board if LED settings were applied, or `undefined` if no action was taken or for the Motherboard.
|
|
10
|
-
*/
|
|
11
|
-
led(config: {
|
|
12
|
-
position: number;
|
|
13
|
-
role_id?: number;
|
|
14
|
-
color?: string;
|
|
15
|
-
}[]): Promise<number[] | undefined>;
|
|
16
|
-
}
|
|
17
|
-
//# sourceMappingURL=kilterboard.interface.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"kilterboard.interface.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/device/kilterboard.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AACrD;;GAEG;AACH,MAAM,WAAW,YAAa,SAAQ,OAAO;IAC3C;;;;OAIG;IACH,GAAG,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,CAAA;CACrG"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"kilterboard.interface.js","sourceRoot":"","sources":["../../../../src/interfaces/device/kilterboard.interface.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"kilterboard.model.d.ts","sourceRoot":"","sources":["../../../../src/models/device/kilterboard.model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kDAAkD,CAAA;AAEpF;;;;GAIG;AACH,oBAAY,iBAAiB;IAC3B,oEAAoE;IACpE,SAAS,KAAK;IACd,4FAA4F;IAC5F,QAAQ,KAAA;IACR,+EAA+E;IAC/E,OAAO,KAAA;IACP,8IAA8I;IAC9I,OAAO,KAAA;IACP,oEAAoE;IACpE,SAAS,KAAA;IACT,4FAA4F;IAC5F,QAAQ,KAAA;IACR,+EAA+E;IAC/E,OAAO,KAAA;IACP,8IAA8I;IAC9I,OAAO,KAAA;CACR;AACD;;GAEG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;GAqCrC,CAAA;AAED;;;;GAIG;AACH,qBAAa,WAAY,SAAQ,MAAO,YAAW,YAAY;IAC7D;;;;;;;OAOG;IACH,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAyC;IAE3E;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAc;IAE1D;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAa;;IA+B5D;;;;OAIG;IACH,OAAO,CAAC,QAAQ;IAQhB;;;;OAIG;IACH,OAAO,CAAC,SAAS;IAiBjB;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;IAOtB;;;;;;OAMG;IACH,OAAO,CAAC,WAAW;IAenB;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAIvB;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAsEnB;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAYlB;;;;;;OAMG;IACH,OAAO,CAAC,aAAa,CAC2E;IAEhG;;OAEG;YACW,kBAAkB;IAMhC;;;;OAIG;IACH,GAAG,GAAU,QAAQ;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,KAAG,OAAO,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,CAW5G;CACF"}
|