@hangtime/grip-connect 0.5.8 → 0.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/interfaces/device.interface.d.ts +69 -4
- package/dist/models/device/entralpi.model.d.ts +2 -2
- package/dist/models/device/entralpi.model.js +2 -3
- package/dist/models/device/forceboard.model.d.ts +2 -2
- package/dist/models/device/forceboard.model.js +2 -3
- package/dist/models/device/motherboard.model.d.ts +2 -2
- package/dist/models/device/motherboard.model.js +2 -3
- package/dist/models/device/progressor.model.d.ts +2 -2
- package/dist/models/device/progressor.model.js +2 -3
- package/dist/models/device.model.d.ts +90 -7
- package/dist/models/device.model.js +156 -31
- package/package.json +1 -1
- package/src/interfaces/device.interface.ts +67 -4
- package/src/models/device/entralpi.model.ts +2 -3
- package/src/models/device/forceboard.model.ts +2 -3
- package/src/models/device/motherboard.model.ts +2 -3
- package/src/models/device/progressor.model.ts +2 -3
- package/src/models/device.model.ts +159 -33
|
@@ -187,6 +187,11 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
187
187
|
* @param {number} [options.duration=1000] - The duration (in milliseconds) to monitor the input for activity.
|
|
188
188
|
* @returns {void}
|
|
189
189
|
* @public
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* device.active((isActive) => {
|
|
193
|
+
* console.log(`Device is ${isActive ? 'active' : 'inactive'}`);
|
|
194
|
+
* }, { threshold: 3.0, duration: 1500 });
|
|
190
195
|
*/
|
|
191
196
|
active = (callback: ActiveCallback, options?: { threshold?: number; duration?: number }): void => {
|
|
192
197
|
this.activeCallback = callback
|
|
@@ -207,21 +212,35 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
207
212
|
*
|
|
208
213
|
* @param {number} input - The dynamic value to check for activity status.
|
|
209
214
|
* @returns {Promise<void>} A promise that resolves once the activity check is complete.
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* await device.activityCheck(5.0);
|
|
210
218
|
*/
|
|
211
219
|
protected activityCheck = (input: number): Promise<void> => {
|
|
212
220
|
return new Promise((resolve) => {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
+
const startTime = Date.now()
|
|
222
|
+
const checkActivity = () => {
|
|
223
|
+
const currentTime = Date.now()
|
|
224
|
+
const elapsedTime = currentTime - startTime
|
|
225
|
+
|
|
226
|
+
if (elapsedTime >= this.activeConfig.duration) {
|
|
227
|
+
// Determine the activity status based on the most recent input
|
|
228
|
+
const activeNow = input > this.activeConfig.threshold
|
|
229
|
+
if (this.isActive !== activeNow) {
|
|
230
|
+
this.isActive = activeNow
|
|
231
|
+
if (this.activeCallback) {
|
|
232
|
+
this.activeCallback(activeNow)
|
|
233
|
+
}
|
|
221
234
|
}
|
|
235
|
+
resolve()
|
|
236
|
+
} else {
|
|
237
|
+
// Continue checking until the duration is met
|
|
238
|
+
requestAnimationFrame(checkActivity)
|
|
222
239
|
}
|
|
223
|
-
|
|
224
|
-
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Start the activity check
|
|
243
|
+
checkActivity()
|
|
225
244
|
})
|
|
226
245
|
}
|
|
227
246
|
|
|
@@ -230,6 +249,12 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
230
249
|
* @param {Function} [onSuccess] - Optional callback function to execute on successful connection. Default logs success.
|
|
231
250
|
* @param {Function} [onError] - Optional callback function to execute on error. Default logs the error.
|
|
232
251
|
* @public
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* device.connect(
|
|
255
|
+
* () => console.log("Connected successfully"),
|
|
256
|
+
* (error) => console.error("Connection failed:", error)
|
|
257
|
+
* );
|
|
233
258
|
*/
|
|
234
259
|
connect = async (
|
|
235
260
|
onSuccess: () => void = () => console.log("Connected successfully"),
|
|
@@ -264,15 +289,40 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
264
289
|
|
|
265
290
|
/**
|
|
266
291
|
* Disconnects the device if it is currently connected.
|
|
267
|
-
* -
|
|
268
|
-
* -
|
|
292
|
+
* - Removes all notification listeners from the device's characteristics.
|
|
293
|
+
* - Removes the 'gattserverdisconnected' event listener.
|
|
294
|
+
* - Attempts to gracefully disconnect the device's GATT server.
|
|
295
|
+
* - Resets relevant properties to their initial states.
|
|
296
|
+
* @returns {void}
|
|
269
297
|
* @public
|
|
298
|
+
*
|
|
299
|
+
* @example
|
|
300
|
+
* device.disconnect();
|
|
270
301
|
*/
|
|
271
302
|
disconnect = (): void => {
|
|
272
|
-
// Verify that the device is connected using the provided helper function
|
|
273
303
|
if (this.isConnected()) {
|
|
304
|
+
// Remove all notification listeners
|
|
305
|
+
this.services.forEach((service) => {
|
|
306
|
+
service.characteristics.forEach((char) => {
|
|
307
|
+
if (char.characteristic && char.id === "rx") {
|
|
308
|
+
char.characteristic.stopNotifications()
|
|
309
|
+
char.characteristic.removeEventListener("characteristicvaluechanged", (event: Event) => {
|
|
310
|
+
const target = event.target as BluetoothRemoteGATTCharacteristic
|
|
311
|
+
if (target && target.value) {
|
|
312
|
+
this.handleNotifications(target)
|
|
313
|
+
}
|
|
314
|
+
})
|
|
315
|
+
}
|
|
316
|
+
})
|
|
317
|
+
})
|
|
318
|
+
// Remove disconnect listener
|
|
319
|
+
this.bluetooth?.removeEventListener("gattserverdisconnected", this.onDisconnected)
|
|
274
320
|
// Safely attempt to disconnect the device's GATT server, if available
|
|
275
321
|
this.bluetooth?.gatt?.disconnect()
|
|
322
|
+
// Reset properties
|
|
323
|
+
this.server = undefined
|
|
324
|
+
this.writeLast = null
|
|
325
|
+
this.isActive = false
|
|
276
326
|
}
|
|
277
327
|
}
|
|
278
328
|
|
|
@@ -280,9 +330,17 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
280
330
|
* Converts the `downloadPackets` array into a CSV formatted string.
|
|
281
331
|
* @returns {string} A CSV string representation of the `downloadPackets` data, with each packet on a new line.
|
|
282
332
|
* @private
|
|
333
|
+
*
|
|
334
|
+
* @example
|
|
335
|
+
* const csvData = device.downloadToCSV();
|
|
336
|
+
* console.log(csvData);
|
|
283
337
|
*/
|
|
284
338
|
private downloadToCSV = (): string => {
|
|
285
|
-
|
|
339
|
+
const packets = [...this.downloadPackets]
|
|
340
|
+
if (packets.length === 0) {
|
|
341
|
+
return ""
|
|
342
|
+
}
|
|
343
|
+
return packets
|
|
286
344
|
.map((packet) =>
|
|
287
345
|
[
|
|
288
346
|
packet.received.toString(),
|
|
@@ -302,6 +360,10 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
302
360
|
* Converts an array of DownloadPacket objects to a JSON string.
|
|
303
361
|
* @returns {string} JSON string representation of the data.
|
|
304
362
|
* @private
|
|
363
|
+
*
|
|
364
|
+
* @example
|
|
365
|
+
* const jsonData = device.downloadToJSON();
|
|
366
|
+
* console.log(jsonData);
|
|
305
367
|
*/
|
|
306
368
|
private downloadToJSON = (): string => {
|
|
307
369
|
// Pretty print JSON with 2-space indentation
|
|
@@ -312,6 +374,10 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
312
374
|
* Converts an array of DownloadPacket objects to an XML string.
|
|
313
375
|
* @returns {string} XML string representation of the data.
|
|
314
376
|
* @private
|
|
377
|
+
*
|
|
378
|
+
* @example
|
|
379
|
+
* const xmlData = device.downloadToXML();
|
|
380
|
+
* console.log(xmlData);
|
|
315
381
|
*/
|
|
316
382
|
private downloadToXML = (): string => {
|
|
317
383
|
const xmlPackets = this.downloadPackets
|
|
@@ -341,6 +407,9 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
341
407
|
*
|
|
342
408
|
* @returns {void} Initiates a download of the data in the specified format.
|
|
343
409
|
* @private
|
|
410
|
+
*
|
|
411
|
+
* @example
|
|
412
|
+
* device.download('json');
|
|
344
413
|
*/
|
|
345
414
|
download = (format: "csv" | "json" | "xml" = "csv"): void => {
|
|
346
415
|
let content = ""
|
|
@@ -394,9 +463,13 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
394
463
|
* Returns UUIDs of all services associated with the device.
|
|
395
464
|
* @returns {string[]} Array of service UUIDs.
|
|
396
465
|
* @protected
|
|
466
|
+
*
|
|
467
|
+
* @example
|
|
468
|
+
* const serviceUUIDs = device.getAllServiceUUIDs();
|
|
469
|
+
* console.log(serviceUUIDs);
|
|
397
470
|
*/
|
|
398
471
|
protected getAllServiceUUIDs = (): string[] => {
|
|
399
|
-
return this.services.map((service) => service.uuid)
|
|
472
|
+
return this.services.filter((service) => service?.uuid).map((service) => service.uuid)
|
|
400
473
|
}
|
|
401
474
|
|
|
402
475
|
/**
|
|
@@ -405,6 +478,12 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
405
478
|
* @param {string} characteristicId - The UUID of the characteristic.
|
|
406
479
|
* @returns {BluetoothRemoteGATTCharacteristic | undefined} The characteristic, if found.
|
|
407
480
|
* @protected
|
|
481
|
+
*
|
|
482
|
+
* @example
|
|
483
|
+
* const characteristic = device.getCharacteristic('battery', 'level');
|
|
484
|
+
* if (characteristic) {
|
|
485
|
+
* console.log('Characteristic found');
|
|
486
|
+
* }
|
|
408
487
|
*/
|
|
409
488
|
protected getCharacteristic = (
|
|
410
489
|
serviceId: string,
|
|
@@ -428,19 +507,22 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
428
507
|
|
|
429
508
|
/**
|
|
430
509
|
* Handles notifications received from a characteristic.
|
|
431
|
-
* @param {
|
|
432
|
-
*
|
|
510
|
+
* @param {BluetoothRemoteGATTCharacteristic} characteristic - The notification event.
|
|
511
|
+
*
|
|
512
|
+
* @example
|
|
513
|
+
* device.handleNotifications(someCharacteristic);
|
|
433
514
|
*/
|
|
434
|
-
protected handleNotifications = (
|
|
435
|
-
const
|
|
436
|
-
const value: DataView | undefined = characteristic.value
|
|
515
|
+
protected handleNotifications = (characteristic: BluetoothRemoteGATTCharacteristic): void => {
|
|
516
|
+
const value = characteristic.value
|
|
437
517
|
|
|
438
|
-
if (value) {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
518
|
+
if (!value) {
|
|
519
|
+
return
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
if (value.buffer) {
|
|
523
|
+
console.log(value)
|
|
524
|
+
} else {
|
|
525
|
+
console.log(value)
|
|
444
526
|
}
|
|
445
527
|
}
|
|
446
528
|
|
|
@@ -448,6 +530,13 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
448
530
|
* Checks if a Bluetooth device is connected.
|
|
449
531
|
* @returns {boolean} A boolean indicating whether the device is connected.
|
|
450
532
|
* @public
|
|
533
|
+
*
|
|
534
|
+
* @example
|
|
535
|
+
* if (device.isConnected()) {
|
|
536
|
+
* console.log('Device is connected');
|
|
537
|
+
* } else {
|
|
538
|
+
* console.log('Device is not connected');
|
|
539
|
+
* }
|
|
451
540
|
*/
|
|
452
541
|
isConnected = (): boolean => {
|
|
453
542
|
// Check if the device is defined and available
|
|
@@ -463,6 +552,11 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
463
552
|
* @param {NotifyCallback} callback - The callback function to be set.
|
|
464
553
|
* @returns {void}
|
|
465
554
|
* @public
|
|
555
|
+
*
|
|
556
|
+
* @example
|
|
557
|
+
* device.notify((data) => {
|
|
558
|
+
* console.log('Received notification:', data);
|
|
559
|
+
* });
|
|
466
560
|
*/
|
|
467
561
|
notify = (callback: NotifyCallback): void => {
|
|
468
562
|
this.notifyCallback = callback
|
|
@@ -472,10 +566,18 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
472
566
|
* Handles the 'connected' event.
|
|
473
567
|
* @param {Function} onSuccess - Callback function to execute on successful connection.
|
|
474
568
|
* @public
|
|
569
|
+
*
|
|
570
|
+
* @example
|
|
571
|
+
* device.onConnected(() => {
|
|
572
|
+
* console.log('Device connected successfully');
|
|
573
|
+
* });
|
|
475
574
|
*/
|
|
476
575
|
protected onConnected = async (onSuccess: () => void): Promise<void> => {
|
|
576
|
+
if (!this.server) {
|
|
577
|
+
throw new Error("GATT server is not available")
|
|
578
|
+
}
|
|
477
579
|
// Connect to GATT server and set up characteristics
|
|
478
|
-
const services: BluetoothRemoteGATTService[] | undefined = await this.server
|
|
580
|
+
const services: BluetoothRemoteGATTService[] | undefined = await this.server.getPrimaryServices()
|
|
479
581
|
|
|
480
582
|
if (!services || services.length === 0) {
|
|
481
583
|
throw new Error("No services found")
|
|
@@ -502,7 +604,10 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
502
604
|
if (element.id === "rx") {
|
|
503
605
|
matchingCharacteristic.startNotifications()
|
|
504
606
|
matchingCharacteristic.addEventListener("characteristicvaluechanged", (event: Event) => {
|
|
505
|
-
|
|
607
|
+
const target = event.target as BluetoothRemoteGATTCharacteristic
|
|
608
|
+
if (target && target.value) {
|
|
609
|
+
this.handleNotifications(target)
|
|
610
|
+
}
|
|
506
611
|
})
|
|
507
612
|
}
|
|
508
613
|
}
|
|
@@ -521,11 +626,14 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
521
626
|
* Handles the 'disconnected' event.
|
|
522
627
|
* @param {Event} event - The 'disconnected' event.
|
|
523
628
|
* @public
|
|
629
|
+
*
|
|
630
|
+
* @example
|
|
631
|
+
* device.onDisconnected(event);
|
|
524
632
|
*/
|
|
525
633
|
protected onDisconnected = (event: Event): void => {
|
|
526
634
|
this.bluetooth = undefined
|
|
527
635
|
const device = event.target as BluetoothDevice
|
|
528
|
-
|
|
636
|
+
console.warn(`Device ${device.name} is disconnected.`)
|
|
529
637
|
}
|
|
530
638
|
|
|
531
639
|
/**
|
|
@@ -535,6 +643,10 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
535
643
|
* @param {number} [duration=0] - The duration to wait before resolving the promise, in milliseconds.
|
|
536
644
|
* @returns {Promise<string | undefined>} A promise that resolves when the read operation is completed.
|
|
537
645
|
* @public
|
|
646
|
+
*
|
|
647
|
+
* @example
|
|
648
|
+
* const value = await device.read('battery', 'level', 1000);
|
|
649
|
+
* console.log('Battery level:', value);
|
|
538
650
|
*/
|
|
539
651
|
read = async (serviceId: string, characteristicId: string, duration = 0): Promise<string | undefined> => {
|
|
540
652
|
if (!this.isConnected()) {
|
|
@@ -572,14 +684,24 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
572
684
|
/**
|
|
573
685
|
* Initiates the tare calibration process.
|
|
574
686
|
* @param {number} duration - The duration time for tare calibration.
|
|
575
|
-
* @returns {
|
|
687
|
+
* @returns {boolean} A boolean indicating whether the tare calibration was successful.
|
|
576
688
|
* @public
|
|
577
|
-
|
|
578
|
-
|
|
689
|
+
*
|
|
690
|
+
* @example
|
|
691
|
+
* const success = device.tare(5000);
|
|
692
|
+
* if (success) {
|
|
693
|
+
* console.log('Tare calibration started');
|
|
694
|
+
* } else {
|
|
695
|
+
* console.log('Tare calibration failed to start');
|
|
696
|
+
* }
|
|
697
|
+
*/
|
|
698
|
+
tare(duration = 5000): boolean {
|
|
699
|
+
if (this.tareActive) return false
|
|
579
700
|
this.tareActive = true
|
|
580
701
|
this.tareDuration = duration
|
|
581
702
|
this.tareSamples = []
|
|
582
703
|
this.tareStartTime = Date.now()
|
|
704
|
+
return true
|
|
583
705
|
}
|
|
584
706
|
|
|
585
707
|
/**
|
|
@@ -587,6 +709,10 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
587
709
|
* @param {number} sample - The sample to calibrate.
|
|
588
710
|
* @returns {number} The calibrated tare value.
|
|
589
711
|
* @protected
|
|
712
|
+
*
|
|
713
|
+
* @example
|
|
714
|
+
* const calibratedSample = device.applyTare(rawSample);
|
|
715
|
+
* console.log('Calibrated sample:', calibratedSample);
|
|
590
716
|
*/
|
|
591
717
|
protected applyTare(sample: number): number {
|
|
592
718
|
if (this.tareActive && this.tareStartTime) {
|
|
@@ -635,7 +761,7 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
635
761
|
): Promise<void> => {
|
|
636
762
|
// Check if not connected or no message is provided
|
|
637
763
|
if (!this.isConnected() || message === undefined) {
|
|
638
|
-
return
|
|
764
|
+
return Promise.resolve()
|
|
639
765
|
}
|
|
640
766
|
// Get the characteristic from the service
|
|
641
767
|
const characteristic = this.getCharacteristic(serviceId, characteristicId)
|