@hangtime/grip-connect 0.6.1 → 0.6.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 +2 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/interfaces/device/climbro.interface.d.ts +1 -1
- package/dist/interfaces/device/entralpi.interface.d.ts +1 -1
- package/dist/interfaces/device/forceboard.interface.d.ts +1 -1
- package/dist/interfaces/device/kilterboard.interface.d.ts +1 -1
- package/dist/interfaces/device/motherboard.interface.d.ts +1 -1
- package/dist/interfaces/device/mysmartboard.interface.d.ts +1 -1
- package/dist/interfaces/device/progressor.interface.d.ts +1 -1
- package/dist/interfaces/device/wh-c06.interface.d.ts +1 -1
- package/dist/interfaces/device.interface.d.ts +3 -3
- package/dist/interfaces/index.d.ts +8 -8
- package/dist/models/base.model.d.ts +1 -1
- package/dist/models/device/climbro.model.d.ts +2 -2
- package/dist/models/device/climbro.model.js +1 -1
- package/dist/models/device/entralpi.model.d.ts +2 -2
- package/dist/models/device/entralpi.model.js +1 -1
- package/dist/models/device/forceboard.model.d.ts +2 -2
- package/dist/models/device/forceboard.model.js +1 -1
- package/dist/models/device/kilterboard.model.d.ts +3 -3
- package/dist/models/device/kilterboard.model.js +2 -2
- package/dist/models/device/motherboard.model.d.ts +2 -2
- package/dist/models/device/motherboard.model.js +1 -1
- package/dist/models/device/mysmartboard.model.d.ts +2 -2
- package/dist/models/device/mysmartboard.model.js +1 -1
- package/dist/models/device/progressor.model.d.ts +2 -2
- package/dist/models/device/progressor.model.js +1 -1
- package/dist/models/device/wh-c06.model.d.ts +2 -2
- package/dist/models/device/wh-c06.model.js +1 -1
- package/dist/models/device.model.d.ts +13 -23
- package/dist/models/device.model.js +51 -64
- package/dist/models/index.d.ts +8 -8
- package/dist/models/index.js +8 -8
- package/package.json +3 -3
- package/src/index.ts +2 -2
- package/src/interfaces/device/climbro.interface.ts +1 -1
- package/src/interfaces/device/entralpi.interface.ts +1 -1
- package/src/interfaces/device/forceboard.interface.ts +1 -1
- package/src/interfaces/device/kilterboard.interface.ts +1 -1
- package/src/interfaces/device/motherboard.interface.ts +1 -1
- package/src/interfaces/device/mysmartboard.interface.ts +1 -1
- package/src/interfaces/device/progressor.interface.ts +1 -1
- package/src/interfaces/device/wh-c06.interface.ts +1 -1
- package/src/interfaces/device.interface.ts +3 -3
- package/src/interfaces/index.ts +8 -8
- package/src/models/base.model.ts +1 -1
- package/src/models/device/climbro.model.ts +2 -2
- package/src/models/device/entralpi.model.ts +2 -2
- package/src/models/device/forceboard.model.ts +2 -2
- package/src/models/device/kilterboard.model.ts +3 -3
- package/src/models/device/motherboard.model.ts +3 -3
- package/src/models/device/mysmartboard.model.ts +2 -2
- package/src/models/device/progressor.model.ts +2 -2
- package/src/models/device/wh-c06.model.ts +2 -2
- package/src/models/device.model.ts +60 -77
- package/src/models/index.ts +8 -8
package/README.md
CHANGED
|
@@ -35,9 +35,8 @@ Learn more: [Documentation](https://stevie-ray.github.io/hangtime-grip-connect/)
|
|
|
35
35
|
|
|
36
36
|
## Install
|
|
37
37
|
|
|
38
|
-
This package
|
|
39
|
-
[NPM](https://www.npmjs.com/package/@hangtime/grip-connect) and [JSR](https://jsr.io/@hangtime/grip-connect)
|
|
40
|
-
registries.
|
|
38
|
+
This package works with Node.js, Bun, Deno, and the web, and is available on both
|
|
39
|
+
[NPM](https://www.npmjs.com/package/@hangtime/grip-connect) and [JSR](https://jsr.io/@hangtime/grip-connect).
|
|
41
40
|
|
|
42
41
|
```sh [npm]
|
|
43
42
|
$ npm install @hangtime/grip-connect
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type { IClimbro, IEntralpi, IForceBoard, IKilterBoard, IMotherboard, ImySmartBoard, IProgressor, IWHC06, } from "./interfaces/index
|
|
2
|
-
export { Climbro, Entralpi, ForceBoard, KilterBoard, Motherboard, mySmartBoard, Progressor, WHC06, } from "./models/index
|
|
1
|
+
export type { IClimbro, IEntralpi, IForceBoard, IKilterBoard, IMotherboard, ImySmartBoard, IProgressor, IWHC06, } from "./interfaces/index";
|
|
2
|
+
export { Climbro, Entralpi, ForceBoard, KilterBoard, Motherboard, mySmartBoard, Progressor, WHC06, } from "./models/index";
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { Climbro, Entralpi, ForceBoard, KilterBoard, Motherboard, mySmartBoard, Progressor, WHC06, } from "./models/index
|
|
1
|
+
export { Climbro, Entralpi, ForceBoard, KilterBoard, Motherboard, mySmartBoard, Progressor, WHC06, } from "./models/index";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { IBase } from "./base.interface
|
|
2
|
-
import type { massObject } from "./callback.interface
|
|
3
|
-
import type { Commands } from "./command.interface
|
|
1
|
+
import type { IBase } from "./base.interface";
|
|
2
|
+
import type { massObject } from "./callback.interface";
|
|
3
|
+
import type { Commands } from "./command.interface";
|
|
4
4
|
/**
|
|
5
5
|
* Represents a characteristic of a Bluetooth service.
|
|
6
6
|
*/
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export type { IClimbro } from "./device/climbro.interface
|
|
2
|
-
export type { IEntralpi } from "./device/entralpi.interface
|
|
3
|
-
export type { IForceBoard } from "./device/forceboard.interface
|
|
4
|
-
export type { IKilterBoard } from "./device/kilterboard.interface
|
|
5
|
-
export type { IMotherboard } from "./device/motherboard.interface
|
|
6
|
-
export type { ImySmartBoard } from "./device/mysmartboard.interface
|
|
7
|
-
export type { IProgressor } from "./device/progressor.interface
|
|
8
|
-
export type { IWHC06 } from "./device/wh-c06.interface
|
|
1
|
+
export type { IClimbro } from "./device/climbro.interface";
|
|
2
|
+
export type { IEntralpi } from "./device/entralpi.interface";
|
|
3
|
+
export type { IForceBoard } from "./device/forceboard.interface";
|
|
4
|
+
export type { IKilterBoard } from "./device/kilterboard.interface";
|
|
5
|
+
export type { IMotherboard } from "./device/motherboard.interface";
|
|
6
|
+
export type { ImySmartBoard } from "./device/mysmartboard.interface";
|
|
7
|
+
export type { IProgressor } from "./device/progressor.interface";
|
|
8
|
+
export type { IWHC06 } from "./device/wh-c06.interface";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Device } from "../device.model
|
|
2
|
-
import type { IClimbro } from "../../interfaces/device/climbro.interface
|
|
1
|
+
import { Device } from "../device.model";
|
|
2
|
+
import type { IClimbro } from "../../interfaces/device/climbro.interface";
|
|
3
3
|
/**
|
|
4
4
|
* Represents a Climbro device.
|
|
5
5
|
* TODO: Add services, do you own a Climbro? Help us!
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Device } from "../device.model
|
|
2
|
-
import type { IEntralpi } from "../../interfaces/device/entralpi.interface
|
|
1
|
+
import { Device } from "../device.model";
|
|
2
|
+
import type { IEntralpi } from "../../interfaces/device/entralpi.interface";
|
|
3
3
|
/**
|
|
4
4
|
* Represents a Entralpi device.
|
|
5
5
|
* {@link https://entralpi.com}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Device } from "../device.model
|
|
2
|
-
import type { IForceBoard } from "../../interfaces/device/forceboard.interface
|
|
1
|
+
import { Device } from "../device.model";
|
|
2
|
+
import type { IForceBoard } from "../../interfaces/device/forceboard.interface";
|
|
3
3
|
/**
|
|
4
4
|
* Represents a PitchSix Force Board device.
|
|
5
5
|
* {@link https://pitchsix.com}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Device } from "../device.model
|
|
2
|
-
import type { IKilterBoard } from "../../interfaces/device/kilterboard.interface
|
|
1
|
+
import { Device } from "../device.model";
|
|
2
|
+
import type { IKilterBoard } from "../../interfaces/device/kilterboard.interface";
|
|
3
3
|
/**
|
|
4
4
|
* For API level 2 and API level 3.
|
|
5
5
|
* The first byte in the data is dependent on where the packet is in the message as a whole.
|
|
@@ -113,7 +113,7 @@ export declare class KilterBoard extends Device implements IKilterBoard {
|
|
|
113
113
|
private prepBytesV3;
|
|
114
114
|
/**
|
|
115
115
|
* Splits a collection into slices of the specified length.
|
|
116
|
-
* https://github.com/ramda/ramda/blob/master/source/splitEvery
|
|
116
|
+
* https://github.com/ramda/ramda/blob/master/source/splitEvery
|
|
117
117
|
* @param {Number} n
|
|
118
118
|
* @param {Array} list
|
|
119
119
|
* @return {Array<number[]>}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Device } from "../device.model
|
|
1
|
+
import { Device } from "../device.model";
|
|
2
2
|
/**
|
|
3
3
|
* For API level 2 and API level 3.
|
|
4
4
|
* The first byte in the data is dependent on where the packet is in the message as a whole.
|
|
@@ -234,7 +234,7 @@ export class KilterBoard extends Device {
|
|
|
234
234
|
}
|
|
235
235
|
/**
|
|
236
236
|
* Splits a collection into slices of the specified length.
|
|
237
|
-
* https://github.com/ramda/ramda/blob/master/source/splitEvery
|
|
237
|
+
* https://github.com/ramda/ramda/blob/master/source/splitEvery
|
|
238
238
|
* @param {Number} n
|
|
239
239
|
* @param {Array} list
|
|
240
240
|
* @return {Array<number[]>}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Device } from "../device.model
|
|
2
|
-
import type { IMotherboard } from "../../interfaces/device/motherboard.interface
|
|
1
|
+
import { Device } from "../device.model";
|
|
2
|
+
import type { IMotherboard } from "../../interfaces/device/motherboard.interface";
|
|
3
3
|
/**
|
|
4
4
|
* Represents a Griptonite Motherboard device.
|
|
5
5
|
* {@link https://griptonite.io}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Device } from "../device.model
|
|
2
|
-
import type { ImySmartBoard } from "../../interfaces/device/mysmartboard.interface
|
|
1
|
+
import { Device } from "../device.model";
|
|
2
|
+
import type { ImySmartBoard } from "../../interfaces/device/mysmartboard.interface";
|
|
3
3
|
/**
|
|
4
4
|
* Represents a Smartboard Climbing mySmartBoard device.
|
|
5
5
|
* TODO: Add services, do you own a mySmartBoard? Help us!
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Device } from "../device.model
|
|
2
|
-
import type { IProgressor } from "../../interfaces/device/progressor.interface
|
|
1
|
+
import { Device } from "../device.model";
|
|
2
|
+
import type { IProgressor } from "../../interfaces/device/progressor.interface";
|
|
3
3
|
/**
|
|
4
4
|
* Represents a Tindeq Progressor device.
|
|
5
5
|
* {@link https://tindeq.com}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Device } from "../device.model
|
|
2
|
-
import type { IWHC06 } from "../../interfaces/device/wh-c06.interface
|
|
1
|
+
import { Device } from "../device.model";
|
|
2
|
+
import type { IWHC06 } from "../../interfaces/device/wh-c06.interface";
|
|
3
3
|
/**
|
|
4
4
|
* Represents a Weiheng - WH-C06 (or MAT Muscle Meter) device.
|
|
5
5
|
* To use this device enable: `chrome://flags/#enable-experimental-web-platform-features`.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { BaseModel } from "./../models/base.model
|
|
2
|
-
import type { IDevice, Service } from "../interfaces/device.interface
|
|
3
|
-
import type { ActiveCallback, NotifyCallback, WriteCallback } from "../interfaces/callback.interface
|
|
4
|
-
import type { DownloadPacket } from "../interfaces/download.interface
|
|
5
|
-
import type { Commands } from "../interfaces/command.interface
|
|
1
|
+
import { BaseModel } from "./../models/base.model";
|
|
2
|
+
import type { IDevice, Service } from "../interfaces/device.interface";
|
|
3
|
+
import type { ActiveCallback, NotifyCallback, WriteCallback } from "../interfaces/callback.interface";
|
|
4
|
+
import type { DownloadPacket } from "../interfaces/download.interface";
|
|
5
|
+
import type { Commands } from "../interfaces/command.interface";
|
|
6
6
|
export declare abstract class Device extends BaseModel implements IDevice {
|
|
7
7
|
/**
|
|
8
8
|
* Filters to identify the device during Bluetooth scanning.
|
|
@@ -26,7 +26,7 @@ export declare abstract class Device extends BaseModel implements IDevice {
|
|
|
26
26
|
* @type {BluetoothDevice | undefined}
|
|
27
27
|
* @public
|
|
28
28
|
*/
|
|
29
|
-
bluetooth?: BluetoothDevice
|
|
29
|
+
bluetooth?: BluetoothDevice;
|
|
30
30
|
/**
|
|
31
31
|
* Object representing the set of commands available for this device.
|
|
32
32
|
* These commands allow communication with the device to perform various operations such as starting measurements, retrieving data, or calibrating the device.
|
|
@@ -275,25 +275,15 @@ export declare abstract class Device extends BaseModel implements IDevice {
|
|
|
275
275
|
*/
|
|
276
276
|
protected getAllServiceUUIDs: () => string[];
|
|
277
277
|
/**
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
|
|
282
|
-
protected getBluetooth(): Promise<Bluetooth | import("webbluetooth").Bluetooth>;
|
|
283
|
-
/**
|
|
284
|
-
* Retrieves the characteristic from the device's service.
|
|
285
|
-
* @param {string} serviceId - The UUID of the service.
|
|
286
|
-
* @param {string} characteristicId - The UUID of the characteristic.
|
|
287
|
-
* @returns {BluetoothRemoteGATTCharacteristic | undefined} The characteristic, if found.
|
|
288
|
-
* @protected
|
|
278
|
+
* Returns the Bluetooth instance available for the current environment.
|
|
279
|
+
* In browsers, it returns the native Web Bluetooth API (i.e. `navigator.bluetooth`).
|
|
280
|
+
* In a Node, Bun, or Deno environment, it dynamically imports the `webbluetooth` package.
|
|
281
|
+
* {@link https://github.com/thegecko/webbluetooth}
|
|
289
282
|
*
|
|
290
|
-
* @
|
|
291
|
-
*
|
|
292
|
-
* if (characteristic) {
|
|
293
|
-
* console.log('Characteristic found');
|
|
294
|
-
* }
|
|
283
|
+
* @returns {Promise<Bluetooth>} A promise that resolves to the Bluetooth instance.
|
|
284
|
+
* @throws {Error} If Web Bluetooth is not available in the current environment.
|
|
295
285
|
*/
|
|
296
|
-
protected
|
|
286
|
+
protected getBluetooth(): Promise<Bluetooth>;
|
|
297
287
|
/**
|
|
298
288
|
* Handles notifications received from a characteristic.
|
|
299
289
|
* @param {BluetoothRemoteGATTCharacteristic} characteristic - The notification event.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseModel } from "./../models/base.model
|
|
1
|
+
import { BaseModel } from "./../models/base.model";
|
|
2
2
|
export class Device extends BaseModel {
|
|
3
3
|
/**
|
|
4
4
|
* Filters to identify the device during Bluetooth scanning.
|
|
@@ -208,22 +208,16 @@ export class Device extends BaseModel {
|
|
|
208
208
|
* @example
|
|
209
209
|
* await device.activityCheck(5.0);
|
|
210
210
|
*/
|
|
211
|
-
activityCheck = (input) => {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
this.activeCallback(activeNow);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
resolve();
|
|
225
|
-
}, duration);
|
|
226
|
-
});
|
|
211
|
+
activityCheck = async (input) => {
|
|
212
|
+
const startValue = input;
|
|
213
|
+
const { threshold, duration } = this.activeConfig;
|
|
214
|
+
// After waiting for `duration`, check if still active.
|
|
215
|
+
await new Promise((resolve) => setTimeout(resolve, duration));
|
|
216
|
+
const activeNow = startValue > threshold;
|
|
217
|
+
if (this.isActive !== activeNow) {
|
|
218
|
+
this.isActive = activeNow;
|
|
219
|
+
this.activeCallback?.(activeNow);
|
|
220
|
+
}
|
|
227
221
|
};
|
|
228
222
|
/**
|
|
229
223
|
* Connects to a Bluetooth device.
|
|
@@ -277,7 +271,7 @@ export class Device extends BaseModel {
|
|
|
277
271
|
// Remove all notification listeners
|
|
278
272
|
this.services.forEach((service) => {
|
|
279
273
|
service.characteristics.forEach((char) => {
|
|
280
|
-
//
|
|
274
|
+
// Look for the "rx" characteristic that accepts notifications
|
|
281
275
|
if (char.characteristic && char.id === "rx") {
|
|
282
276
|
char.characteristic.stopNotifications();
|
|
283
277
|
const listener = this.notificationListeners.get(char.uuid);
|
|
@@ -437,47 +431,28 @@ export class Device extends BaseModel {
|
|
|
437
431
|
return this.services.filter((service) => service?.uuid).map((service) => service.uuid);
|
|
438
432
|
};
|
|
439
433
|
/**
|
|
440
|
-
*
|
|
441
|
-
*
|
|
442
|
-
*
|
|
434
|
+
* Returns the Bluetooth instance available for the current environment.
|
|
435
|
+
* In browsers, it returns the native Web Bluetooth API (i.e. `navigator.bluetooth`).
|
|
436
|
+
* In a Node, Bun, or Deno environment, it dynamically imports the `webbluetooth` package.
|
|
437
|
+
* {@link https://github.com/thegecko/webbluetooth}
|
|
438
|
+
*
|
|
439
|
+
* @returns {Promise<Bluetooth>} A promise that resolves to the Bluetooth instance.
|
|
440
|
+
* @throws {Error} If Web Bluetooth is not available in the current environment.
|
|
443
441
|
*/
|
|
444
442
|
async getBluetooth() {
|
|
445
|
-
// If
|
|
446
|
-
if (typeof navigator !== "undefined" &&
|
|
443
|
+
// If running in a browser with native Web Bluetooth support:
|
|
444
|
+
if (typeof navigator !== "undefined" && navigator.bluetooth) {
|
|
447
445
|
return navigator.bluetooth;
|
|
448
446
|
}
|
|
449
|
-
|
|
450
|
-
//
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
/**
|
|
455
|
-
* Retrieves the characteristic from the device's service.
|
|
456
|
-
* @param {string} serviceId - The UUID of the service.
|
|
457
|
-
* @param {string} characteristicId - The UUID of the characteristic.
|
|
458
|
-
* @returns {BluetoothRemoteGATTCharacteristic | undefined} The characteristic, if found.
|
|
459
|
-
* @protected
|
|
460
|
-
*
|
|
461
|
-
* @example
|
|
462
|
-
* const characteristic = device.getCharacteristic('battery', 'level');
|
|
463
|
-
* if (characteristic) {
|
|
464
|
-
* console.log('Characteristic found');
|
|
465
|
-
* }
|
|
466
|
-
*/
|
|
467
|
-
getCharacteristic = (serviceId, characteristicId) => {
|
|
468
|
-
// Find the service with the specified serviceId
|
|
469
|
-
const boardService = this.services.find((service) => service.id === serviceId);
|
|
470
|
-
if (boardService) {
|
|
471
|
-
// If the service is found, find the characteristic with the specified characteristicId
|
|
472
|
-
const boardCharacteristic = boardService.characteristics.find((characteristic) => characteristic.id === characteristicId);
|
|
473
|
-
if (boardCharacteristic) {
|
|
474
|
-
// If the characteristic is found, return it
|
|
475
|
-
return boardCharacteristic.characteristic;
|
|
476
|
-
}
|
|
447
|
+
const process = await import("node:process");
|
|
448
|
+
// If running in Node, Bun, or Deno environment
|
|
449
|
+
if (typeof process !== "undefined" && process.versions?.node) {
|
|
450
|
+
const { bluetooth } = await import("webbluetooth");
|
|
451
|
+
return bluetooth;
|
|
477
452
|
}
|
|
478
|
-
//
|
|
479
|
-
|
|
480
|
-
}
|
|
453
|
+
// If none of the above conditions are met, throw an error.
|
|
454
|
+
throw new Error("Bluetooth not available.");
|
|
455
|
+
}
|
|
481
456
|
/**
|
|
482
457
|
* Handles notifications received from a characteristic.
|
|
483
458
|
* @param {BluetoothRemoteGATTCharacteristic} characteristic - The notification event.
|
|
@@ -507,7 +482,7 @@ export class Device extends BaseModel {
|
|
|
507
482
|
*/
|
|
508
483
|
isConnected = () => {
|
|
509
484
|
// Check if the device is defined and available
|
|
510
|
-
if (!this
|
|
485
|
+
if (!this.bluetooth) {
|
|
511
486
|
return false;
|
|
512
487
|
}
|
|
513
488
|
// Check if the device is connected
|
|
@@ -550,26 +525,34 @@ export class Device extends BaseModel {
|
|
|
550
525
|
for (const service of services) {
|
|
551
526
|
const matchingService = this.services.find((boardService) => boardService.uuid === service.uuid);
|
|
552
527
|
if (matchingService) {
|
|
553
|
-
// Android bug:
|
|
528
|
+
// Android bug: Add a small delay before getting characteristics
|
|
554
529
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
555
530
|
const characteristics = await service.getCharacteristics();
|
|
556
531
|
for (const characteristic of matchingService.characteristics) {
|
|
557
532
|
const matchingCharacteristic = characteristics.find((char) => char.uuid === characteristic.uuid);
|
|
558
533
|
if (matchingCharacteristic) {
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
//
|
|
563
|
-
|
|
534
|
+
// Find the corresponding characteristic descriptor in the service's characteristics array
|
|
535
|
+
const descriptor = matchingService.characteristics.find((char) => char.uuid === matchingCharacteristic.uuid);
|
|
536
|
+
if (descriptor) {
|
|
537
|
+
// Assign the actual Bluetooth characteristic object to the descriptor so it can be used later
|
|
538
|
+
descriptor.characteristic = matchingCharacteristic;
|
|
539
|
+
// Look for the "rx" characteristic id that accepts notifications
|
|
540
|
+
if (descriptor.id === "rx") {
|
|
541
|
+
// Start receiving notifications for changes on this characteristic
|
|
564
542
|
matchingCharacteristic.startNotifications();
|
|
543
|
+
// Triggered when the characteristic's value changes
|
|
565
544
|
const listener = (event) => {
|
|
545
|
+
// Cast the event's target to a BluetoothRemoteGATTCharacteristic to access its properties
|
|
566
546
|
const target = event.target;
|
|
567
547
|
if (target && target.value) {
|
|
548
|
+
// Delegate the data to handleNotifications method
|
|
568
549
|
this.handleNotifications(target);
|
|
569
550
|
}
|
|
570
551
|
};
|
|
552
|
+
// Attach the event listener to listen for changes in the characteristic's value
|
|
571
553
|
matchingCharacteristic.addEventListener("characteristicvaluechanged", listener);
|
|
572
|
-
|
|
554
|
+
// Store the listener so it can be referenced (for later removal)
|
|
555
|
+
this.notificationListeners.set(descriptor.uuid, listener);
|
|
573
556
|
}
|
|
574
557
|
}
|
|
575
558
|
}
|
|
@@ -611,7 +594,9 @@ export class Device extends BaseModel {
|
|
|
611
594
|
return undefined;
|
|
612
595
|
}
|
|
613
596
|
// Get the characteristic from the service
|
|
614
|
-
const characteristic = this.
|
|
597
|
+
const characteristic = this.services
|
|
598
|
+
.find((service) => service.id === serviceId)
|
|
599
|
+
?.characteristics.find((char) => char.id === characteristicId)?.characteristic;
|
|
615
600
|
if (!characteristic) {
|
|
616
601
|
throw new Error(`Characteristic "${characteristicId}" not found in service "${serviceId}"`);
|
|
617
602
|
}
|
|
@@ -723,7 +708,9 @@ export class Device extends BaseModel {
|
|
|
723
708
|
return Promise.resolve();
|
|
724
709
|
}
|
|
725
710
|
// Get the characteristic from the service
|
|
726
|
-
const characteristic = this.
|
|
711
|
+
const characteristic = this.services
|
|
712
|
+
.find((service) => service.id === serviceId)
|
|
713
|
+
?.characteristics.find((char) => char.id === characteristicId)?.characteristic;
|
|
727
714
|
if (!characteristic) {
|
|
728
715
|
throw new Error(`Characteristic "${characteristicId}" not found in service "${serviceId}"`);
|
|
729
716
|
}
|
package/dist/models/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { Climbro } from "./device/climbro.model
|
|
2
|
-
export { Entralpi } from "./device/entralpi.model
|
|
3
|
-
export { ForceBoard } from "./device/forceboard.model
|
|
4
|
-
export { KilterBoard } from "./device/kilterboard.model
|
|
5
|
-
export { Motherboard } from "./device/motherboard.model
|
|
6
|
-
export { mySmartBoard } from "./device/mysmartboard.model
|
|
7
|
-
export { Progressor } from "./device/progressor.model
|
|
8
|
-
export { WHC06 } from "./device/wh-c06.model
|
|
1
|
+
export { Climbro } from "./device/climbro.model";
|
|
2
|
+
export { Entralpi } from "./device/entralpi.model";
|
|
3
|
+
export { ForceBoard } from "./device/forceboard.model";
|
|
4
|
+
export { KilterBoard } from "./device/kilterboard.model";
|
|
5
|
+
export { Motherboard } from "./device/motherboard.model";
|
|
6
|
+
export { mySmartBoard } from "./device/mysmartboard.model";
|
|
7
|
+
export { Progressor } from "./device/progressor.model";
|
|
8
|
+
export { WHC06 } from "./device/wh-c06.model";
|
package/dist/models/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { Climbro } from "./device/climbro.model
|
|
2
|
-
export { Entralpi } from "./device/entralpi.model
|
|
3
|
-
export { ForceBoard } from "./device/forceboard.model
|
|
4
|
-
export { KilterBoard } from "./device/kilterboard.model
|
|
5
|
-
export { Motherboard } from "./device/motherboard.model
|
|
6
|
-
export { mySmartBoard } from "./device/mysmartboard.model
|
|
7
|
-
export { Progressor } from "./device/progressor.model
|
|
8
|
-
export { WHC06 } from "./device/wh-c06.model
|
|
1
|
+
export { Climbro } from "./device/climbro.model";
|
|
2
|
+
export { Entralpi } from "./device/entralpi.model";
|
|
3
|
+
export { ForceBoard } from "./device/forceboard.model";
|
|
4
|
+
export { KilterBoard } from "./device/kilterboard.model";
|
|
5
|
+
export { Motherboard } from "./device/motherboard.model";
|
|
6
|
+
export { mySmartBoard } from "./device/mysmartboard.model";
|
|
7
|
+
export { Progressor } from "./device/progressor.model";
|
|
8
|
+
export { WHC06 } from "./device/wh-c06.model";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hangtime/grip-connect",
|
|
3
|
-
"version": "0.6.
|
|
4
|
-
"description": "Griptonite Motherboard, Tindeq Progressor, PitchSix Force Board, WHC-06, Entralpi, Climbro, mySmartBoard:
|
|
3
|
+
"version": "0.6.2",
|
|
4
|
+
"description": "Griptonite Motherboard, Tindeq Progressor, PitchSix Force Board, WHC-06, Entralpi, Climbro, mySmartBoard: Bluetooth API Force-Sensing strength analysis for climbers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -35,6 +35,6 @@
|
|
|
35
35
|
},
|
|
36
36
|
"homepage": "https://stevie-ray.github.io/hangtime-grip-connect/",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"webbluetooth": "^3.2
|
|
38
|
+
"webbluetooth": "^3.3.2"
|
|
39
39
|
}
|
|
40
40
|
}
|
package/src/index.ts
CHANGED
|
@@ -7,7 +7,7 @@ export type {
|
|
|
7
7
|
ImySmartBoard,
|
|
8
8
|
IProgressor,
|
|
9
9
|
IWHC06,
|
|
10
|
-
} from "./interfaces/index
|
|
10
|
+
} from "./interfaces/index"
|
|
11
11
|
|
|
12
12
|
export {
|
|
13
13
|
Climbro,
|
|
@@ -18,4 +18,4 @@ export {
|
|
|
18
18
|
mySmartBoard,
|
|
19
19
|
Progressor,
|
|
20
20
|
WHC06,
|
|
21
|
-
} from "./models/index
|
|
21
|
+
} from "./models/index"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { IBase } from "./base.interface
|
|
2
|
-
import type { massObject } from "./callback.interface
|
|
3
|
-
import type { Commands } from "./command.interface
|
|
1
|
+
import type { IBase } from "./base.interface"
|
|
2
|
+
import type { massObject } from "./callback.interface"
|
|
3
|
+
import type { Commands } from "./command.interface"
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Represents a characteristic of a Bluetooth service.
|
package/src/interfaces/index.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
export type { IClimbro } from "./device/climbro.interface
|
|
1
|
+
export type { IClimbro } from "./device/climbro.interface"
|
|
2
2
|
|
|
3
|
-
export type { IEntralpi } from "./device/entralpi.interface
|
|
3
|
+
export type { IEntralpi } from "./device/entralpi.interface"
|
|
4
4
|
|
|
5
|
-
export type { IForceBoard } from "./device/forceboard.interface
|
|
5
|
+
export type { IForceBoard } from "./device/forceboard.interface"
|
|
6
6
|
|
|
7
|
-
export type { IKilterBoard } from "./device/kilterboard.interface
|
|
7
|
+
export type { IKilterBoard } from "./device/kilterboard.interface"
|
|
8
8
|
|
|
9
|
-
export type { IMotherboard } from "./device/motherboard.interface
|
|
9
|
+
export type { IMotherboard } from "./device/motherboard.interface"
|
|
10
10
|
|
|
11
|
-
export type { ImySmartBoard } from "./device/mysmartboard.interface
|
|
11
|
+
export type { ImySmartBoard } from "./device/mysmartboard.interface"
|
|
12
12
|
|
|
13
|
-
export type { IProgressor } from "./device/progressor.interface
|
|
13
|
+
export type { IProgressor } from "./device/progressor.interface"
|
|
14
14
|
|
|
15
|
-
export type { IWHC06 } from "./device/wh-c06.interface
|
|
15
|
+
export type { IWHC06 } from "./device/wh-c06.interface"
|
package/src/models/base.model.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Device } from "../device.model
|
|
2
|
-
import type { IClimbro } from "../../interfaces/device/climbro.interface
|
|
1
|
+
import { Device } from "../device.model"
|
|
2
|
+
import type { IClimbro } from "../../interfaces/device/climbro.interface"
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Represents a Climbro device.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Device } from "../device.model
|
|
2
|
-
import type { IEntralpi } from "../../interfaces/device/entralpi.interface
|
|
1
|
+
import { Device } from "../device.model"
|
|
2
|
+
import type { IEntralpi } from "../../interfaces/device/entralpi.interface"
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Represents a Entralpi device.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Device } from "../device.model
|
|
2
|
-
import type { IForceBoard } from "../../interfaces/device/forceboard.interface
|
|
1
|
+
import { Device } from "../device.model"
|
|
2
|
+
import type { IForceBoard } from "../../interfaces/device/forceboard.interface"
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Represents a PitchSix Force Board device.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Device } from "../device.model
|
|
2
|
-
import type { IKilterBoard } from "../../interfaces/device/kilterboard.interface
|
|
1
|
+
import { Device } from "../device.model"
|
|
2
|
+
import type { IKilterBoard } from "../../interfaces/device/kilterboard.interface"
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* For API level 2 and API level 3.
|
|
@@ -254,7 +254,7 @@ export class KilterBoard extends Device implements IKilterBoard {
|
|
|
254
254
|
|
|
255
255
|
/**
|
|
256
256
|
* Splits a collection into slices of the specified length.
|
|
257
|
-
* https://github.com/ramda/ramda/blob/master/source/splitEvery
|
|
257
|
+
* https://github.com/ramda/ramda/blob/master/source/splitEvery
|
|
258
258
|
* @param {Number} n
|
|
259
259
|
* @param {Array} list
|
|
260
260
|
* @return {Array<number[]>}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Device } from "../device.model
|
|
2
|
-
import type { IMotherboard } from "../../interfaces/device/motherboard.interface
|
|
3
|
-
import type { DownloadPacket } from "../../interfaces/download.interface
|
|
1
|
+
import { Device } from "../device.model"
|
|
2
|
+
import type { IMotherboard } from "../../interfaces/device/motherboard.interface"
|
|
3
|
+
import type { DownloadPacket } from "../../interfaces/download.interface"
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Represents a Griptonite Motherboard device.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Device } from "../device.model
|
|
2
|
-
import type { ImySmartBoard } from "../../interfaces/device/mysmartboard.interface
|
|
1
|
+
import { Device } from "../device.model"
|
|
2
|
+
import type { ImySmartBoard } from "../../interfaces/device/mysmartboard.interface"
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Represents a Smartboard Climbing mySmartBoard device.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Device } from "../device.model
|
|
2
|
-
import type { IProgressor } from "../../interfaces/device/progressor.interface
|
|
1
|
+
import { Device } from "../device.model"
|
|
2
|
+
import type { IProgressor } from "../../interfaces/device/progressor.interface"
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Progressor responses
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Device } from "../device.model
|
|
2
|
-
import type { IWHC06 } from "../../interfaces/device/wh-c06.interface
|
|
1
|
+
import { Device } from "../device.model"
|
|
2
|
+
import type { IWHC06 } from "../../interfaces/device/wh-c06.interface"
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Represents a Weiheng - WH-C06 (or MAT Muscle Meter) device.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { BaseModel } from "./../models/base.model
|
|
2
|
-
import type { IDevice, Service } from "../interfaces/device.interface
|
|
3
|
-
import type { ActiveCallback, massObject, NotifyCallback, WriteCallback } from "../interfaces/callback.interface
|
|
4
|
-
import type { DownloadPacket } from "../interfaces/download.interface
|
|
5
|
-
import type { Commands } from "../interfaces/command.interface
|
|
1
|
+
import { BaseModel } from "./../models/base.model"
|
|
2
|
+
import type { IDevice, Service } from "../interfaces/device.interface"
|
|
3
|
+
import type { ActiveCallback, massObject, NotifyCallback, WriteCallback } from "../interfaces/callback.interface"
|
|
4
|
+
import type { DownloadPacket } from "../interfaces/download.interface"
|
|
5
|
+
import type { Commands } from "../interfaces/command.interface"
|
|
6
6
|
|
|
7
7
|
export abstract class Device extends BaseModel implements IDevice {
|
|
8
8
|
/**
|
|
@@ -29,7 +29,7 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
29
29
|
* @type {BluetoothDevice | undefined}
|
|
30
30
|
* @public
|
|
31
31
|
*/
|
|
32
|
-
bluetooth?: BluetoothDevice
|
|
32
|
+
bluetooth?: BluetoothDevice
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* Object representing the set of commands available for this device.
|
|
@@ -240,22 +240,16 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
240
240
|
* @example
|
|
241
241
|
* await device.activityCheck(5.0);
|
|
242
242
|
*/
|
|
243
|
-
protected activityCheck = (input: number): Promise<void> => {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
this.activeCallback(activeNow)
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
resolve()
|
|
257
|
-
}, duration)
|
|
258
|
-
})
|
|
243
|
+
protected activityCheck = async (input: number): Promise<void> => {
|
|
244
|
+
const startValue = input
|
|
245
|
+
const { threshold, duration } = this.activeConfig
|
|
246
|
+
// After waiting for `duration`, check if still active.
|
|
247
|
+
await new Promise((resolve) => setTimeout(resolve, duration))
|
|
248
|
+
const activeNow = startValue > threshold
|
|
249
|
+
if (this.isActive !== activeNow) {
|
|
250
|
+
this.isActive = activeNow
|
|
251
|
+
this.activeCallback?.(activeNow)
|
|
252
|
+
}
|
|
259
253
|
}
|
|
260
254
|
|
|
261
255
|
/**
|
|
@@ -319,7 +313,7 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
319
313
|
// Remove all notification listeners
|
|
320
314
|
this.services.forEach((service) => {
|
|
321
315
|
service.characteristics.forEach((char) => {
|
|
322
|
-
//
|
|
316
|
+
// Look for the "rx" characteristic that accepts notifications
|
|
323
317
|
if (char.characteristic && char.id === "rx") {
|
|
324
318
|
char.characteristic.stopNotifications()
|
|
325
319
|
const listener = this.notificationListeners.get(char.uuid)
|
|
@@ -494,53 +488,30 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
494
488
|
}
|
|
495
489
|
|
|
496
490
|
/**
|
|
497
|
-
*
|
|
498
|
-
*
|
|
499
|
-
*
|
|
491
|
+
* Returns the Bluetooth instance available for the current environment.
|
|
492
|
+
* In browsers, it returns the native Web Bluetooth API (i.e. `navigator.bluetooth`).
|
|
493
|
+
* In a Node, Bun, or Deno environment, it dynamically imports the `webbluetooth` package.
|
|
494
|
+
* {@link https://github.com/thegecko/webbluetooth}
|
|
495
|
+
*
|
|
496
|
+
* @returns {Promise<Bluetooth>} A promise that resolves to the Bluetooth instance.
|
|
497
|
+
* @throws {Error} If Web Bluetooth is not available in the current environment.
|
|
500
498
|
*/
|
|
501
|
-
protected async getBluetooth() {
|
|
502
|
-
// If
|
|
503
|
-
if (typeof navigator !== "undefined" &&
|
|
499
|
+
protected async getBluetooth(): Promise<Bluetooth> {
|
|
500
|
+
// If running in a browser with native Web Bluetooth support:
|
|
501
|
+
if (typeof navigator !== "undefined" && navigator.bluetooth) {
|
|
504
502
|
return navigator.bluetooth
|
|
505
503
|
}
|
|
506
504
|
|
|
507
|
-
|
|
508
|
-
// Use a dynamic import for the ESM version:
|
|
509
|
-
const { bluetooth } = await import("webbluetooth")
|
|
510
|
-
return bluetooth
|
|
511
|
-
}
|
|
505
|
+
const process = await import("node:process")
|
|
512
506
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
* @returns {BluetoothRemoteGATTCharacteristic | undefined} The characteristic, if found.
|
|
518
|
-
* @protected
|
|
519
|
-
*
|
|
520
|
-
* @example
|
|
521
|
-
* const characteristic = device.getCharacteristic('battery', 'level');
|
|
522
|
-
* if (characteristic) {
|
|
523
|
-
* console.log('Characteristic found');
|
|
524
|
-
* }
|
|
525
|
-
*/
|
|
526
|
-
protected getCharacteristic = (
|
|
527
|
-
serviceId: string,
|
|
528
|
-
characteristicId: string,
|
|
529
|
-
): BluetoothRemoteGATTCharacteristic | undefined => {
|
|
530
|
-
// Find the service with the specified serviceId
|
|
531
|
-
const boardService = this.services.find((service) => service.id === serviceId)
|
|
532
|
-
if (boardService) {
|
|
533
|
-
// If the service is found, find the characteristic with the specified characteristicId
|
|
534
|
-
const boardCharacteristic = boardService.characteristics.find(
|
|
535
|
-
(characteristic) => characteristic.id === characteristicId,
|
|
536
|
-
)
|
|
537
|
-
if (boardCharacteristic) {
|
|
538
|
-
// If the characteristic is found, return it
|
|
539
|
-
return boardCharacteristic.characteristic
|
|
540
|
-
}
|
|
507
|
+
// If running in Node, Bun, or Deno environment
|
|
508
|
+
if (typeof process !== "undefined" && process.versions?.node) {
|
|
509
|
+
const { bluetooth } = await import("webbluetooth")
|
|
510
|
+
return bluetooth
|
|
541
511
|
}
|
|
542
|
-
|
|
543
|
-
|
|
512
|
+
|
|
513
|
+
// If none of the above conditions are met, throw an error.
|
|
514
|
+
throw new Error("Bluetooth not available.")
|
|
544
515
|
}
|
|
545
516
|
|
|
546
517
|
/**
|
|
@@ -573,7 +544,7 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
573
544
|
*/
|
|
574
545
|
isConnected = (): boolean => {
|
|
575
546
|
// Check if the device is defined and available
|
|
576
|
-
if (!this
|
|
547
|
+
if (!this.bluetooth) {
|
|
577
548
|
return false
|
|
578
549
|
}
|
|
579
550
|
// Check if the device is connected
|
|
@@ -612,7 +583,7 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
612
583
|
throw new Error("GATT server is not available")
|
|
613
584
|
}
|
|
614
585
|
// Connect to GATT server and set up characteristics
|
|
615
|
-
const services: BluetoothRemoteGATTService[]
|
|
586
|
+
const services: BluetoothRemoteGATTService[] = await this.server.getPrimaryServices()
|
|
616
587
|
|
|
617
588
|
if (!services || services.length === 0) {
|
|
618
589
|
throw new Error("No services found")
|
|
@@ -622,7 +593,7 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
622
593
|
const matchingService = this.services.find((boardService) => boardService.uuid === service.uuid)
|
|
623
594
|
|
|
624
595
|
if (matchingService) {
|
|
625
|
-
// Android bug:
|
|
596
|
+
// Android bug: Add a small delay before getting characteristics
|
|
626
597
|
await new Promise((resolve) => setTimeout(resolve, 100))
|
|
627
598
|
|
|
628
599
|
const characteristics = await service.getCharacteristics()
|
|
@@ -631,21 +602,28 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
631
602
|
const matchingCharacteristic = characteristics.find((char) => char.uuid === characteristic.uuid)
|
|
632
603
|
|
|
633
604
|
if (matchingCharacteristic) {
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
605
|
+
// Find the corresponding characteristic descriptor in the service's characteristics array
|
|
606
|
+
const descriptor = matchingService.characteristics.find((char) => char.uuid === matchingCharacteristic.uuid)
|
|
607
|
+
if (descriptor) {
|
|
608
|
+
// Assign the actual Bluetooth characteristic object to the descriptor so it can be used later
|
|
609
|
+
descriptor.characteristic = matchingCharacteristic
|
|
610
|
+
// Look for the "rx" characteristic id that accepts notifications
|
|
611
|
+
if (descriptor.id === "rx") {
|
|
612
|
+
// Start receiving notifications for changes on this characteristic
|
|
640
613
|
matchingCharacteristic.startNotifications()
|
|
614
|
+
// Triggered when the characteristic's value changes
|
|
641
615
|
const listener = (event: Event) => {
|
|
616
|
+
// Cast the event's target to a BluetoothRemoteGATTCharacteristic to access its properties
|
|
642
617
|
const target = event.target as BluetoothRemoteGATTCharacteristic
|
|
643
618
|
if (target && target.value) {
|
|
619
|
+
// Delegate the data to handleNotifications method
|
|
644
620
|
this.handleNotifications(target)
|
|
645
621
|
}
|
|
646
622
|
}
|
|
623
|
+
// Attach the event listener to listen for changes in the characteristic's value
|
|
647
624
|
matchingCharacteristic.addEventListener("characteristicvaluechanged", listener)
|
|
648
|
-
|
|
625
|
+
// Store the listener so it can be referenced (for later removal)
|
|
626
|
+
this.notificationListeners.set(descriptor.uuid, listener)
|
|
649
627
|
}
|
|
650
628
|
}
|
|
651
629
|
} else {
|
|
@@ -654,7 +632,6 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
654
632
|
}
|
|
655
633
|
}
|
|
656
634
|
}
|
|
657
|
-
|
|
658
635
|
// Call the onSuccess callback after successful connection and setup
|
|
659
636
|
onSuccess()
|
|
660
637
|
}
|
|
@@ -689,7 +666,10 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
689
666
|
return undefined
|
|
690
667
|
}
|
|
691
668
|
// Get the characteristic from the service
|
|
692
|
-
const characteristic = this.
|
|
669
|
+
const characteristic = this.services
|
|
670
|
+
.find((service) => service.id === serviceId)
|
|
671
|
+
?.characteristics.find((char) => char.id === characteristicId)?.characteristic
|
|
672
|
+
|
|
693
673
|
if (!characteristic) {
|
|
694
674
|
throw new Error(`Characteristic "${characteristicId}" not found in service "${serviceId}"`)
|
|
695
675
|
}
|
|
@@ -815,7 +795,10 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
815
795
|
return Promise.resolve()
|
|
816
796
|
}
|
|
817
797
|
// Get the characteristic from the service
|
|
818
|
-
const characteristic = this.
|
|
798
|
+
const characteristic = this.services
|
|
799
|
+
.find((service) => service.id === serviceId)
|
|
800
|
+
?.characteristics.find((char) => char.id === characteristicId)?.characteristic
|
|
801
|
+
|
|
819
802
|
if (!characteristic) {
|
|
820
803
|
throw new Error(`Characteristic "${characteristicId}" not found in service "${serviceId}"`)
|
|
821
804
|
}
|
package/src/models/index.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
export { Climbro } from "./device/climbro.model
|
|
1
|
+
export { Climbro } from "./device/climbro.model"
|
|
2
2
|
|
|
3
|
-
export { Entralpi } from "./device/entralpi.model
|
|
3
|
+
export { Entralpi } from "./device/entralpi.model"
|
|
4
4
|
|
|
5
|
-
export { ForceBoard } from "./device/forceboard.model
|
|
5
|
+
export { ForceBoard } from "./device/forceboard.model"
|
|
6
6
|
|
|
7
|
-
export { KilterBoard } from "./device/kilterboard.model
|
|
7
|
+
export { KilterBoard } from "./device/kilterboard.model"
|
|
8
8
|
|
|
9
|
-
export { Motherboard } from "./device/motherboard.model
|
|
9
|
+
export { Motherboard } from "./device/motherboard.model"
|
|
10
10
|
|
|
11
|
-
export { mySmartBoard } from "./device/mysmartboard.model
|
|
11
|
+
export { mySmartBoard } from "./device/mysmartboard.model"
|
|
12
12
|
|
|
13
|
-
export { Progressor } from "./device/progressor.model
|
|
13
|
+
export { Progressor } from "./device/progressor.model"
|
|
14
14
|
|
|
15
|
-
export { WHC06 } from "./device/wh-c06.model
|
|
15
|
+
export { WHC06 } from "./device/wh-c06.model"
|