@hangtime/grip-connect 0.5.10 → 0.6.0
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 +13 -3
- package/deno.json +8 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -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 +2 -2
- package/dist/interfaces/device/mysmartboard.interface.d.ts +2 -2
- package/dist/interfaces/device/progressor.interface.d.ts +2 -2
- package/dist/interfaces/device/wh-c06.interface.d.ts +2 -2
- package/dist/interfaces/device.interface.d.ts +3 -3
- package/dist/models/base.model.d.ts +1 -1
- package/dist/models/device/climbro.model.d.ts +4 -3
- package/dist/models/device/climbro.model.js +3 -2
- package/dist/models/device/entralpi.model.d.ts +6 -2
- package/dist/models/device/entralpi.model.js +5 -1
- package/dist/models/device/forceboard.model.d.ts +4 -3
- package/dist/models/device/forceboard.model.js +3 -2
- package/dist/models/device/kilterboard.model.d.ts +4 -3
- package/dist/models/device/kilterboard.model.js +4 -3
- package/dist/models/device/motherboard.model.d.ts +4 -3
- package/dist/models/device/motherboard.model.js +3 -2
- package/dist/models/device/mysmartboard.model.d.ts +4 -3
- package/dist/models/device/mysmartboard.model.js +3 -2
- package/dist/models/device/progressor.model.d.ts +3 -3
- package/dist/models/device/progressor.model.js +4 -3
- package/dist/models/device/wh-c06.model.d.ts +6 -4
- package/dist/models/device/wh-c06.model.js +12 -6
- package/dist/models/device.model.d.ts +11 -5
- package/dist/models/device.model.js +24 -8
- package/dist/models/index.d.ts +8 -8
- package/dist/models/index.js +8 -8
- package/package.json +6 -2
- package/src/index.ts +4 -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 +2 -2
- package/src/interfaces/device/mysmartboard.interface.ts +2 -2
- package/src/interfaces/device/progressor.interface.ts +2 -2
- package/src/interfaces/device/wh-c06.interface.ts +2 -2
- package/src/interfaces/device.interface.ts +3 -3
- package/src/models/base.model.ts +1 -1
- package/src/models/device/climbro.model.ts +4 -3
- package/src/models/device/entralpi.model.ts +7 -3
- package/src/models/device/forceboard.model.ts +5 -4
- package/src/models/device/kilterboard.model.ts +5 -4
- package/src/models/device/motherboard.model.ts +6 -5
- package/src/models/device/mysmartboard.model.ts +4 -3
- package/src/models/device/progressor.model.ts +6 -5
- package/src/models/device/wh-c06.model.ts +17 -10
- package/src/models/device.model.ts +31 -12
- package/src/models/index.ts +8 -8
package/README.md
CHANGED
|
@@ -35,12 +35,22 @@ Learn more: [Documentation](https://stevie-ray.github.io/hangtime-grip-connect/)
|
|
|
35
35
|
|
|
36
36
|
## Install
|
|
37
37
|
|
|
38
|
-
This
|
|
38
|
+
This package is compatible with both Node.js and browser environments. It can be found in the
|
|
39
|
+
[NPM](https://www.npmjs.com/package/@hangtime/grip-connect) and [JSR](https://jsr.io/@hangtime/grip-connect) package
|
|
40
|
+
registries.
|
|
39
41
|
|
|
40
42
|
```sh [npm]
|
|
41
43
|
$ npm install @hangtime/grip-connect
|
|
42
44
|
```
|
|
43
45
|
|
|
46
|
+
```sh [yarn]
|
|
47
|
+
$ yarn add @hangtime/grip-connect
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```sh [pnpm]
|
|
51
|
+
$ pnpm add @hangtime/grip-connect
|
|
52
|
+
```
|
|
53
|
+
|
|
44
54
|
## Example usage (with a Motherboard)
|
|
45
55
|
|
|
46
56
|
Simply importing the device you need from `@hangtime/grip-connect`.
|
|
@@ -113,8 +123,8 @@ document.querySelector("#motherboard").addEventListener("click", async () => {
|
|
|
113
123
|
- By default [watchAdvertisements](https://chromestatus.com/feature/5180688812736512) isn't supported . For Chrome,
|
|
114
124
|
enable it at `chrome://flags/#enable-experimental-web-platform-features`.
|
|
115
125
|
- ✅ [Kilter Board](https://stevie-ray.github.io/hangtime-grip-connect/devices/kilterboard.html)
|
|
116
|
-
- ✅ [Entralpi](https://stevie-ray.github.io/hangtime-grip-connect/devices/entralpi.html) / Lefu Scale
|
|
117
|
-
- ✅ [PitchSix Force Board](https://stevie-ray.github.io/hangtime-grip-connect/devices/forceboard.html)
|
|
126
|
+
- ✅ [Entralpi](https://stevie-ray.github.io/hangtime-grip-connect/devices/entralpi.html) / Lefu / Unique CW275 Scale
|
|
127
|
+
- ✅ [PitchSix - Force Board](https://stevie-ray.github.io/hangtime-grip-connect/devices/forceboard.html)
|
|
118
128
|
- ➡️ [Climbro](https://stevie-ray.github.io/hangtime-grip-connect/devices/climbro.html)
|
|
119
129
|
- ➡️ [Smartboard Climbing - mySmartBoard](https://stevie-ray.github.io/hangtime-grip-connect/devices/mysmartboard.html)
|
|
120
130
|
|
package/deno.json
ADDED
package/dist/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { Climbro, Entralpi, ForceBoard, KilterBoard, Motherboard, mySmartBoard,
|
|
1
|
+
export { Climbro, Entralpi, ForceBoard, KilterBoard, Motherboard, mySmartBoard, Progressor, WHC06, } from "./models/index.js";
|
package/dist/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
// @ts-types="npm:@types/web-bluetooth@^0.0.20"
|
|
2
|
+
export { Climbro, Entralpi, ForceBoard, KilterBoard, Motherboard, mySmartBoard, Progressor, WHC06, } from "./models/index.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { IDevice } from "../device.interface";
|
|
1
|
+
import type { IDevice } from "../device.interface.js";
|
|
2
2
|
/**
|
|
3
|
-
* Interface representing the Griptonite Motherboard device.
|
|
3
|
+
* Interface representing the Griptonite Motherboard device, extending the base Device interface.
|
|
4
4
|
*/
|
|
5
5
|
export interface IMotherboard extends IDevice {
|
|
6
6
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { IDevice } from "../device.interface";
|
|
1
|
+
import type { IDevice } from "../device.interface.js";
|
|
2
2
|
/**
|
|
3
|
-
* Interface representing the mySmartBoard device, extending the base Device interface.
|
|
3
|
+
* Interface representing the Smartboard Climbing mySmartBoard device, extending the base Device interface.
|
|
4
4
|
*/
|
|
5
5
|
export interface ImySmartBoard extends IDevice {
|
|
6
6
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { IDevice } from "../device.interface";
|
|
1
|
+
import type { IDevice } from "../device.interface.js";
|
|
2
2
|
/**
|
|
3
|
-
* Interface representing the Tindeq Progressor device.
|
|
3
|
+
* Interface representing the Tindeq Progressor device, extending the base Device interface.
|
|
4
4
|
*/
|
|
5
5
|
export interface IProgressor extends IDevice {
|
|
6
6
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { IDevice } from "../device.interface";
|
|
1
|
+
import type { IDevice } from "../device.interface.js";
|
|
2
2
|
/**
|
|
3
|
-
* Interface representing the Weiheng WH-C06 device.
|
|
3
|
+
* Interface representing the Weiheng WH-C06 device, extending the base Device interface.
|
|
4
4
|
*/
|
|
5
5
|
export interface IWHC06 extends IDevice {
|
|
6
6
|
}
|
|
@@ -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.js";
|
|
2
|
+
import type { massObject } from "./callback.interface.js";
|
|
3
|
+
import type { Commands } from "./command.interface.js";
|
|
4
4
|
/**
|
|
5
5
|
* Represents a characteristic of a Bluetooth service.
|
|
6
6
|
*/
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { Device } from "../device.model";
|
|
2
|
-
import type { IClimbro } from "../../interfaces/device/climbro.interface";
|
|
1
|
+
import { Device } from "../device.model.js";
|
|
2
|
+
import type { IClimbro } from "../../interfaces/device/climbro.interface.js";
|
|
3
3
|
/**
|
|
4
|
-
* Represents a Climbro device
|
|
4
|
+
* Represents a Climbro device.
|
|
5
5
|
* TODO: Add services, do you own a Climbro? Help us!
|
|
6
|
+
* {@link https://climbro.com/}
|
|
6
7
|
*/
|
|
7
8
|
export declare class Climbro extends Device implements IClimbro {
|
|
8
9
|
constructor();
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Device } from "../device.model";
|
|
1
|
+
import { Device } from "../device.model.js";
|
|
2
2
|
/**
|
|
3
|
-
* Represents a Climbro device
|
|
3
|
+
* Represents a Climbro device.
|
|
4
4
|
* TODO: Add services, do you own a Climbro? Help us!
|
|
5
|
+
* {@link https://climbro.com/}
|
|
5
6
|
*/
|
|
6
7
|
export class Climbro extends Device {
|
|
7
8
|
constructor() {
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import { Device } from "../device.model";
|
|
2
|
-
import type { IEntralpi } from "../../interfaces/device/entralpi.interface";
|
|
1
|
+
import { Device } from "../device.model.js";
|
|
2
|
+
import type { IEntralpi } from "../../interfaces/device/entralpi.interface.js";
|
|
3
|
+
/**
|
|
4
|
+
* Represents a Entralpi device.
|
|
5
|
+
* {@link https://entralpi.com}
|
|
6
|
+
*/
|
|
3
7
|
export declare class Entralpi extends Device implements IEntralpi {
|
|
4
8
|
constructor();
|
|
5
9
|
/**
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Device } from "../device.model";
|
|
2
|
-
import type { IForceBoard } from "../../interfaces/device/forceboard.interface";
|
|
1
|
+
import { Device } from "../device.model.js";
|
|
2
|
+
import type { IForceBoard } from "../../interfaces/device/forceboard.interface.js";
|
|
3
3
|
/**
|
|
4
|
-
* Represents a PitchSix Force Board device
|
|
4
|
+
* Represents a PitchSix Force Board device.
|
|
5
|
+
* {@link https://pitchsix.com}
|
|
5
6
|
*/
|
|
6
7
|
export declare class ForceBoard extends Device implements IForceBoard {
|
|
7
8
|
constructor();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Device } from "../device.model";
|
|
1
|
+
import { Device } from "../device.model.js";
|
|
2
2
|
/**
|
|
3
|
-
* Represents a PitchSix Force Board device
|
|
3
|
+
* Represents a PitchSix Force Board device.
|
|
4
|
+
* {@link https://pitchsix.com}
|
|
4
5
|
*/
|
|
5
6
|
export class ForceBoard extends Device {
|
|
6
7
|
constructor() {
|
|
@@ -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.js";
|
|
2
|
+
import type { IKilterBoard } from "../../interfaces/device/kilterboard.interface.js";
|
|
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.
|
|
@@ -36,8 +36,9 @@ export declare const KilterBoardPlacementRoles: {
|
|
|
36
36
|
screen_color: string;
|
|
37
37
|
}[];
|
|
38
38
|
/**
|
|
39
|
-
* Represents a Aurora Climbing device
|
|
39
|
+
* Represents a Aurora Climbing device.
|
|
40
40
|
* Kilter Board, Tension Board, Decoy Board, Touchstone Board, Grasshopper Board, Aurora Board, So iLL Board
|
|
41
|
+
* {@link https://auroraclimbing.com}
|
|
41
42
|
*/
|
|
42
43
|
export declare class KilterBoard extends Device implements IKilterBoard {
|
|
43
44
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Device } from "../device.model";
|
|
1
|
+
import { Device } from "../device.model.js";
|
|
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.
|
|
@@ -65,8 +65,9 @@ export const KilterBoardPlacementRoles = [
|
|
|
65
65
|
},
|
|
66
66
|
];
|
|
67
67
|
/**
|
|
68
|
-
* Represents a Aurora Climbing device
|
|
68
|
+
* Represents a Aurora Climbing device.
|
|
69
69
|
* Kilter Board, Tension Board, Decoy Board, Touchstone Board, Grasshopper Board, Aurora Board, So iLL Board
|
|
70
|
+
* {@link https://auroraclimbing.com}
|
|
70
71
|
*/
|
|
71
72
|
export class KilterBoard extends Device {
|
|
72
73
|
/**
|
|
@@ -154,7 +155,7 @@ export class KilterBoard extends Device {
|
|
|
154
155
|
- 0x2
|
|
155
156
|
- *packets
|
|
156
157
|
- 0x3
|
|
157
|
-
|
|
158
|
+
|
|
158
159
|
First byte is always 1, the second is a number of packets, then checksum, then 2, packets themselves, and finally 3.
|
|
159
160
|
*/
|
|
160
161
|
return [1, data.length, this.checksum(data), 2, ...data, 3];
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Device } from "../device.model";
|
|
2
|
-
import type { IMotherboard } from "../../interfaces/device/motherboard.interface";
|
|
1
|
+
import { Device } from "../device.model.js";
|
|
2
|
+
import type { IMotherboard } from "../../interfaces/device/motherboard.interface.js";
|
|
3
3
|
/**
|
|
4
|
-
* Represents a Griptonite Motherboard device
|
|
4
|
+
* Represents a Griptonite Motherboard device.
|
|
5
|
+
* {@link https://griptonite.io}
|
|
5
6
|
*/
|
|
6
7
|
export declare class Motherboard extends Device implements IMotherboard {
|
|
7
8
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Device } from "../device.model";
|
|
1
|
+
import { Device } from "../device.model.js";
|
|
2
2
|
/**
|
|
3
|
-
* Represents a Griptonite Motherboard device
|
|
3
|
+
* Represents a Griptonite Motherboard device.
|
|
4
|
+
* {@link https://griptonite.io}
|
|
4
5
|
*/
|
|
5
6
|
export class Motherboard extends Device {
|
|
6
7
|
/**
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { Device } from "../device.model";
|
|
2
|
-
import type { ImySmartBoard } from "../../interfaces/device/mysmartboard.interface";
|
|
1
|
+
import { Device } from "../device.model.js";
|
|
2
|
+
import type { ImySmartBoard } from "../../interfaces/device/mysmartboard.interface.js";
|
|
3
3
|
/**
|
|
4
|
-
* Represents a mySmartBoard device
|
|
4
|
+
* Represents a Smartboard Climbing mySmartBoard device.
|
|
5
5
|
* TODO: Add services, do you own a mySmartBoard? Help us!
|
|
6
|
+
* {@link https://www.smartboard-climbing.com}
|
|
6
7
|
*/
|
|
7
8
|
export declare class mySmartBoard extends Device implements ImySmartBoard {
|
|
8
9
|
constructor();
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Device } from "../device.model";
|
|
1
|
+
import { Device } from "../device.model.js";
|
|
2
2
|
/**
|
|
3
|
-
* Represents a mySmartBoard device
|
|
3
|
+
* Represents a Smartboard Climbing mySmartBoard device.
|
|
4
4
|
* TODO: Add services, do you own a mySmartBoard? Help us!
|
|
5
|
+
* {@link https://www.smartboard-climbing.com}
|
|
5
6
|
*/
|
|
6
7
|
export class mySmartBoard extends Device {
|
|
7
8
|
constructor() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Device } from "../device.model";
|
|
2
|
-
import type { IProgressor } from "../../interfaces/device/progressor.interface";
|
|
1
|
+
import { Device } from "../device.model.js";
|
|
2
|
+
import type { IProgressor } from "../../interfaces/device/progressor.interface.js";
|
|
3
3
|
/**
|
|
4
|
-
* Represents a Tindeq Progressor device
|
|
4
|
+
* Represents a Tindeq Progressor device.
|
|
5
5
|
*/
|
|
6
6
|
export declare class Progressor extends Device implements IProgressor {
|
|
7
7
|
constructor();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Device } from "../device.model";
|
|
1
|
+
import { Device } from "../device.model.js";
|
|
2
2
|
/**
|
|
3
|
-
* Represents
|
|
3
|
+
* Represents a Tindeq Progressor device.
|
|
4
|
+
* {@link https://tindeq.com}
|
|
4
5
|
*/
|
|
5
6
|
var ProgressorResponses;
|
|
6
7
|
(function (ProgressorResponses) {
|
|
@@ -31,7 +32,7 @@ var ProgressorResponses;
|
|
|
31
32
|
ProgressorResponses[ProgressorResponses["LOW_BATTERY_WARNING"] = 4] = "LOW_BATTERY_WARNING";
|
|
32
33
|
})(ProgressorResponses || (ProgressorResponses = {}));
|
|
33
34
|
/**
|
|
34
|
-
* Represents a Tindeq Progressor device
|
|
35
|
+
* Represents a Tindeq Progressor device.
|
|
35
36
|
*/
|
|
36
37
|
export class Progressor extends Device {
|
|
37
38
|
constructor() {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { Device } from "../device.model";
|
|
2
|
-
import type { IWHC06 } from "../../interfaces/device/wh-c06.interface";
|
|
1
|
+
import { Device } from "../device.model.js";
|
|
2
|
+
import type { IWHC06 } from "../../interfaces/device/wh-c06.interface.js";
|
|
3
3
|
/**
|
|
4
|
-
* Represents a
|
|
5
|
-
*
|
|
4
|
+
* Represents a Weiheng - WH-C06 (or MAT Muscle Meter) device.
|
|
5
|
+
* To use this device enable: `chrome://flags/#enable-experimental-web-platform-features`.
|
|
6
|
+
* {@link https://googlechrome.github.io/samples/web-bluetooth/scan.html| Web Bluetooth}
|
|
7
|
+
* {@link https://weihengmanufacturer.com}
|
|
6
8
|
*/
|
|
7
9
|
export declare class WHC06 extends Device implements IWHC06 {
|
|
8
10
|
/**
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { Device } from "../device.model";
|
|
1
|
+
import { Device } from "../device.model.js";
|
|
2
2
|
/**
|
|
3
|
-
* Represents a
|
|
4
|
-
*
|
|
3
|
+
* Represents a Weiheng - WH-C06 (or MAT Muscle Meter) device.
|
|
4
|
+
* To use this device enable: `chrome://flags/#enable-experimental-web-platform-features`.
|
|
5
|
+
* {@link https://googlechrome.github.io/samples/web-bluetooth/scan.html| Web Bluetooth}
|
|
6
|
+
* {@link https://weihengmanufacturer.com}
|
|
5
7
|
*/
|
|
6
8
|
export class WHC06 extends Device {
|
|
7
9
|
/**
|
|
@@ -65,7 +67,8 @@ export class WHC06 extends Device {
|
|
|
65
67
|
try {
|
|
66
68
|
// Only data matching the optionalManufacturerData parameter to requestDevice is included in the advertisement event: https://github.com/WebBluetoothCG/web-bluetooth/issues/598
|
|
67
69
|
const optionalManufacturerData = this.filters.flatMap((filter) => filter.manufacturerData?.map((data) => data.companyIdentifier) || []);
|
|
68
|
-
|
|
70
|
+
const bluetooth = await this.getBluetooth();
|
|
71
|
+
this.bluetooth = await bluetooth.requestDevice({
|
|
69
72
|
filters: this.filters,
|
|
70
73
|
optionalManufacturerData,
|
|
71
74
|
});
|
|
@@ -154,10 +157,13 @@ export class WHC06 extends Device {
|
|
|
154
157
|
clearTimeout(this.advertisementTimeout);
|
|
155
158
|
}
|
|
156
159
|
// Set a new timeout to stop tracking if no advertisement is received
|
|
157
|
-
this.advertisementTimeout =
|
|
160
|
+
this.advertisementTimeout = globalThis.setTimeout(() => {
|
|
158
161
|
// Mimic a disconnect
|
|
159
162
|
const disconnectedEvent = new Event("gattserverdisconnected");
|
|
160
|
-
Object.defineProperty(disconnectedEvent, "target", {
|
|
163
|
+
Object.defineProperty(disconnectedEvent, "target", {
|
|
164
|
+
value: this.bluetooth,
|
|
165
|
+
writable: false,
|
|
166
|
+
});
|
|
161
167
|
// Print error to the console
|
|
162
168
|
console.error(`No advertisement received for ${this.advertisementTimeoutTime} seconds, stopping tracking..`);
|
|
163
169
|
this.onDisconnected(disconnectedEvent);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { BaseModel } from "./../models/base.model";
|
|
2
|
-
import type { IDevice, Service } from "../interfaces/device.interface";
|
|
3
|
-
import type { NotifyCallback, WriteCallback
|
|
4
|
-
import type { DownloadPacket } from "../interfaces/download.interface";
|
|
5
|
-
import type { Commands } from "../interfaces/command.interface";
|
|
1
|
+
import { BaseModel } from "./../models/base.model.js";
|
|
2
|
+
import type { IDevice, Service } from "../interfaces/device.interface.js";
|
|
3
|
+
import type { ActiveCallback, NotifyCallback, WriteCallback } from "../interfaces/callback.interface.js";
|
|
4
|
+
import type { DownloadPacket } from "../interfaces/download.interface.js";
|
|
5
|
+
import type { Commands } from "../interfaces/command.interface.js";
|
|
6
6
|
export declare abstract class Device extends BaseModel implements IDevice {
|
|
7
7
|
/**
|
|
8
8
|
* Filters to identify the device during Bluetooth scanning.
|
|
@@ -274,6 +274,12 @@ export declare abstract class Device extends BaseModel implements IDevice {
|
|
|
274
274
|
* console.log(serviceUUIDs);
|
|
275
275
|
*/
|
|
276
276
|
protected getAllServiceUUIDs: () => string[];
|
|
277
|
+
/**
|
|
278
|
+
* Attempt to use ES module import rather than require.
|
|
279
|
+
* This approach uses an async dynamic import for `webbluetooth`,
|
|
280
|
+
* so we can fallback if `navigator.bluetooth` is unavailable.
|
|
281
|
+
*/
|
|
282
|
+
protected getBluetooth(): Promise<Bluetooth | import("webbluetooth").Bluetooth>;
|
|
277
283
|
/**
|
|
278
284
|
* Retrieves the characteristic from the device's service.
|
|
279
285
|
* @param {string} serviceId - The UUID of the service.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseModel } from "./../models/base.model";
|
|
1
|
+
import { BaseModel } from "./../models/base.model.js";
|
|
2
2
|
export class Device extends BaseModel {
|
|
3
3
|
/**
|
|
4
4
|
* Filters to identify the device during Bluetooth scanning.
|
|
@@ -51,7 +51,10 @@ export class Device extends BaseModel {
|
|
|
51
51
|
/**
|
|
52
52
|
* Configuration for threshold and duration.
|
|
53
53
|
*/
|
|
54
|
-
activeConfig = {
|
|
54
|
+
activeConfig = {
|
|
55
|
+
threshold: 2.5,
|
|
56
|
+
duration: 1000,
|
|
57
|
+
};
|
|
55
58
|
/**
|
|
56
59
|
* Maximum mass recorded from the device, initialized to "0".
|
|
57
60
|
* @type {string}
|
|
@@ -236,12 +239,10 @@ export class Device extends BaseModel {
|
|
|
236
239
|
*/
|
|
237
240
|
connect = async (onSuccess = () => console.log("Connected successfully"), onError = (error) => console.error(error)) => {
|
|
238
241
|
try {
|
|
239
|
-
if (typeof navigator === "undefined" || !("bluetooth" in navigator)) {
|
|
240
|
-
throw new Error("Web Bluetooth API not supported in this environment.");
|
|
241
|
-
}
|
|
242
242
|
// Request device and set up connection
|
|
243
243
|
const deviceServices = this.getAllServiceUUIDs();
|
|
244
|
-
|
|
244
|
+
const bluetooth = await this.getBluetooth();
|
|
245
|
+
this.bluetooth = await bluetooth.requestDevice({
|
|
245
246
|
filters: this.filters,
|
|
246
247
|
optionalServices: deviceServices,
|
|
247
248
|
});
|
|
@@ -406,7 +407,7 @@ export class Device extends BaseModel {
|
|
|
406
407
|
// Create a Blob object containing the data
|
|
407
408
|
const blob = new Blob([content], { type: mimeType });
|
|
408
409
|
// Create a URL for the Blob
|
|
409
|
-
const url =
|
|
410
|
+
const url = globalThis.URL.createObjectURL(blob);
|
|
410
411
|
// Create a link element
|
|
411
412
|
const link = document.createElement("a");
|
|
412
413
|
// Set link attributes
|
|
@@ -418,7 +419,7 @@ export class Device extends BaseModel {
|
|
|
418
419
|
link.click();
|
|
419
420
|
// Clean up: remove the link and revoke the URL
|
|
420
421
|
document.body.removeChild(link);
|
|
421
|
-
|
|
422
|
+
globalThis.URL.revokeObjectURL(url);
|
|
422
423
|
};
|
|
423
424
|
/**
|
|
424
425
|
* Returns UUIDs of all services associated with the device.
|
|
@@ -432,6 +433,21 @@ export class Device extends BaseModel {
|
|
|
432
433
|
getAllServiceUUIDs = () => {
|
|
433
434
|
return this.services.filter((service) => service?.uuid).map((service) => service.uuid);
|
|
434
435
|
};
|
|
436
|
+
/**
|
|
437
|
+
* Attempt to use ES module import rather than require.
|
|
438
|
+
* This approach uses an async dynamic import for `webbluetooth`,
|
|
439
|
+
* so we can fallback if `navigator.bluetooth` is unavailable.
|
|
440
|
+
*/
|
|
441
|
+
async getBluetooth() {
|
|
442
|
+
// If we're in a browser with real Web Bluetooth available:
|
|
443
|
+
if (typeof navigator !== "undefined" && "bluetooth" in navigator) {
|
|
444
|
+
return navigator.bluetooth;
|
|
445
|
+
}
|
|
446
|
+
// Otherwise, we're likely in Node or an environment without `navigator.bluetooth`.
|
|
447
|
+
// Use a dynamic import for the ESM version:
|
|
448
|
+
const { bluetooth } = await import("webbluetooth");
|
|
449
|
+
return bluetooth;
|
|
450
|
+
}
|
|
435
451
|
/**
|
|
436
452
|
* Retrieves the characteristic from the device's service.
|
|
437
453
|
* @param {string} serviceId - The UUID of the service.
|
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.js";
|
|
2
|
+
export { Entralpi } from "./device/entralpi.model.js";
|
|
3
|
+
export { ForceBoard } from "./device/forceboard.model.js";
|
|
4
|
+
export { KilterBoard } from "./device/kilterboard.model.js";
|
|
5
|
+
export { Motherboard } from "./device/motherboard.model.js";
|
|
6
|
+
export { mySmartBoard } from "./device/mysmartboard.model.js";
|
|
7
|
+
export { Progressor } from "./device/progressor.model.js";
|
|
8
|
+
export { WHC06 } from "./device/wh-c06.model.js";
|
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.js";
|
|
2
|
+
export { Entralpi } from "./device/entralpi.model.js";
|
|
3
|
+
export { ForceBoard } from "./device/forceboard.model.js";
|
|
4
|
+
export { KilterBoard } from "./device/kilterboard.model.js";
|
|
5
|
+
export { Motherboard } from "./device/motherboard.model.js";
|
|
6
|
+
export { mySmartBoard } from "./device/mysmartboard.model.js";
|
|
7
|
+
export { Progressor } from "./device/progressor.model.js";
|
|
8
|
+
export { WHC06 } from "./device/wh-c06.model.js";
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hangtime/grip-connect",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Griptonite Motherboard, Tindeq Progressor, PitchSix Force Board, WHC-06, Entralpi, Climbro, mySmartBoard: Web Bluetooth API Force-Sensing strength analysis for climbers",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"main": "dist/index.js",
|
|
6
7
|
"types": "dist/index.d.ts",
|
|
7
8
|
"scripts": {
|
|
@@ -32,5 +33,8 @@
|
|
|
32
33
|
"bugs": {
|
|
33
34
|
"url": "https://github.com/Stevie-Ray/hangtime-grip-connect/issues"
|
|
34
35
|
},
|
|
35
|
-
"homepage": "https://stevie-ray.github.io/hangtime-grip-connect/"
|
|
36
|
+
"homepage": "https://stevie-ray.github.io/hangtime-grip-connect/",
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"webbluetooth": "^3.2.1"
|
|
39
|
+
}
|
|
36
40
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { IDevice } from "../device.interface"
|
|
1
|
+
import type { IDevice } from "../device.interface.js"
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Interface representing the Griptonite Motherboard device.
|
|
4
|
+
* Interface representing the Griptonite Motherboard device, extending the base Device interface.
|
|
5
5
|
*/
|
|
6
6
|
export interface IMotherboard extends IDevice {
|
|
7
7
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { IDevice } from "../device.interface"
|
|
1
|
+
import type { IDevice } from "../device.interface.js"
|
|
2
2
|
/**
|
|
3
|
-
* Interface representing the mySmartBoard device, extending the base Device interface.
|
|
3
|
+
* Interface representing the Smartboard Climbing mySmartBoard device, extending the base Device interface.
|
|
4
4
|
*/
|
|
5
5
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
6
6
|
export interface ImySmartBoard extends IDevice {}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { IDevice } from "../device.interface"
|
|
1
|
+
import type { IDevice } from "../device.interface.js"
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Interface representing the Tindeq Progressor device.
|
|
4
|
+
* Interface representing the Tindeq Progressor device, extending the base Device interface.
|
|
5
5
|
*/
|
|
6
6
|
export interface IProgressor extends IDevice {
|
|
7
7
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { IDevice } from "../device.interface"
|
|
1
|
+
import type { IDevice } from "../device.interface.js"
|
|
2
2
|
/**
|
|
3
|
-
* Interface representing the Weiheng WH-C06 device.
|
|
3
|
+
* Interface representing the Weiheng WH-C06 device, extending the base Device interface.
|
|
4
4
|
*/
|
|
5
5
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
6
6
|
export interface IWHC06 extends IDevice {}
|
|
@@ -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.js"
|
|
2
|
+
import type { massObject } from "./callback.interface.js"
|
|
3
|
+
import type { Commands } from "./command.interface.js"
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Represents a characteristic of a Bluetooth service.
|
package/src/models/base.model.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { Device } from "../device.model"
|
|
2
|
-
import type { IClimbro } from "../../interfaces/device/climbro.interface"
|
|
1
|
+
import { Device } from "../device.model.js"
|
|
2
|
+
import type { IClimbro } from "../../interfaces/device/climbro.interface.js"
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Represents a Climbro device
|
|
5
|
+
* Represents a Climbro device.
|
|
6
6
|
* TODO: Add services, do you own a Climbro? Help us!
|
|
7
|
+
* {@link https://climbro.com/}
|
|
7
8
|
*/
|
|
8
9
|
export class Climbro extends Device implements IClimbro {
|
|
9
10
|
constructor() {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import { Device } from "../device.model"
|
|
2
|
-
import type { IEntralpi } from "../../interfaces/device/entralpi.interface"
|
|
1
|
+
import { Device } from "../device.model.js"
|
|
2
|
+
import type { IEntralpi } from "../../interfaces/device/entralpi.interface.js"
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Represents a Entralpi device.
|
|
6
|
+
* {@link https://entralpi.com}
|
|
7
|
+
*/
|
|
4
8
|
export class Entralpi extends Device implements IEntralpi {
|
|
5
9
|
constructor() {
|
|
6
10
|
super({
|
|
@@ -155,7 +159,7 @@ export class Entralpi extends Device implements IEntralpi {
|
|
|
155
159
|
*
|
|
156
160
|
* @param {BluetoothRemoteGATTCharacteristic} characteristic - The notification event.
|
|
157
161
|
*/
|
|
158
|
-
handleNotifications = (characteristic: BluetoothRemoteGATTCharacteristic): void => {
|
|
162
|
+
override handleNotifications = (characteristic: BluetoothRemoteGATTCharacteristic): void => {
|
|
159
163
|
const value: DataView | undefined = characteristic.value
|
|
160
164
|
|
|
161
165
|
if (value) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { Device } from "../device.model"
|
|
2
|
-
import type { IForceBoard } from "../../interfaces/device/forceboard.interface"
|
|
1
|
+
import { Device } from "../device.model.js"
|
|
2
|
+
import type { IForceBoard } from "../../interfaces/device/forceboard.interface.js"
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Represents a PitchSix Force Board device
|
|
5
|
+
* Represents a PitchSix Force Board device.
|
|
6
|
+
* {@link https://pitchsix.com}
|
|
6
7
|
*/
|
|
7
8
|
export class ForceBoard extends Device implements IForceBoard {
|
|
8
9
|
constructor() {
|
|
@@ -182,7 +183,7 @@ export class ForceBoard extends Device implements IForceBoard {
|
|
|
182
183
|
*
|
|
183
184
|
* @param {BluetoothRemoteGATTCharacteristic} characteristic - The notification event.
|
|
184
185
|
*/
|
|
185
|
-
handleNotifications = (characteristic: BluetoothRemoteGATTCharacteristic): void => {
|
|
186
|
+
override handleNotifications = (characteristic: BluetoothRemoteGATTCharacteristic): void => {
|
|
186
187
|
const value: DataView | undefined = characteristic.value
|
|
187
188
|
if (value) {
|
|
188
189
|
// Update timestamp
|
|
@@ -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.js"
|
|
2
|
+
import type { IKilterBoard } from "../../interfaces/device/kilterboard.interface.js"
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* For API level 2 and API level 3.
|
|
@@ -67,8 +67,9 @@ export const KilterBoardPlacementRoles = [
|
|
|
67
67
|
]
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
|
-
* Represents a Aurora Climbing device
|
|
70
|
+
* Represents a Aurora Climbing device.
|
|
71
71
|
* Kilter Board, Tension Board, Decoy Board, Touchstone Board, Grasshopper Board, Aurora Board, So iLL Board
|
|
72
|
+
* {@link https://auroraclimbing.com}
|
|
72
73
|
*/
|
|
73
74
|
export class KilterBoard extends Device implements IKilterBoard {
|
|
74
75
|
/**
|
|
@@ -161,7 +162,7 @@ export class KilterBoard extends Device implements IKilterBoard {
|
|
|
161
162
|
- 0x2
|
|
162
163
|
- *packets
|
|
163
164
|
- 0x3
|
|
164
|
-
|
|
165
|
+
|
|
165
166
|
First byte is always 1, the second is a number of packets, then checksum, then 2, packets themselves, and finally 3.
|
|
166
167
|
*/
|
|
167
168
|
return [1, data.length, this.checksum(data), 2, ...data, 3]
|
|
@@ -1,9 +1,10 @@
|
|
|
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.js"
|
|
2
|
+
import type { IMotherboard } from "../../interfaces/device/motherboard.interface.js"
|
|
3
|
+
import type { DownloadPacket } from "../../interfaces/download.interface.js"
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Represents a Griptonite Motherboard device
|
|
6
|
+
* Represents a Griptonite Motherboard device.
|
|
7
|
+
* {@link https://griptonite.io}
|
|
7
8
|
*/
|
|
8
9
|
export class Motherboard extends Device implements IMotherboard {
|
|
9
10
|
/**
|
|
@@ -203,7 +204,7 @@ export class Motherboard extends Device implements IMotherboard {
|
|
|
203
204
|
*
|
|
204
205
|
* @param {BluetoothRemoteGATTCharacteristic} characteristic - The notification event.
|
|
205
206
|
*/
|
|
206
|
-
handleNotifications = (characteristic: BluetoothRemoteGATTCharacteristic): void => {
|
|
207
|
+
override handleNotifications = (characteristic: BluetoothRemoteGATTCharacteristic): void => {
|
|
207
208
|
const value: DataView | undefined = characteristic.value
|
|
208
209
|
|
|
209
210
|
if (value) {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { Device } from "../device.model"
|
|
2
|
-
import type { ImySmartBoard } from "../../interfaces/device/mysmartboard.interface"
|
|
1
|
+
import { Device } from "../device.model.js"
|
|
2
|
+
import type { ImySmartBoard } from "../../interfaces/device/mysmartboard.interface.js"
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Represents a mySmartBoard device
|
|
5
|
+
* Represents a Smartboard Climbing mySmartBoard device.
|
|
6
6
|
* TODO: Add services, do you own a mySmartBoard? Help us!
|
|
7
|
+
* {@link https://www.smartboard-climbing.com}
|
|
7
8
|
*/
|
|
8
9
|
export class mySmartBoard extends Device implements ImySmartBoard {
|
|
9
10
|
constructor() {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { Device } from "../device.model"
|
|
2
|
-
import type { IProgressor } from "../../interfaces/device/progressor.interface"
|
|
1
|
+
import { Device } from "../device.model.js"
|
|
2
|
+
import type { IProgressor } from "../../interfaces/device/progressor.interface.js"
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Represents
|
|
5
|
+
* Represents a Tindeq Progressor device.
|
|
6
|
+
* {@link https://tindeq.com}
|
|
6
7
|
*/
|
|
7
8
|
enum ProgressorResponses {
|
|
8
9
|
/**
|
|
@@ -37,7 +38,7 @@ enum ProgressorResponses {
|
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
/**
|
|
40
|
-
* Represents a Tindeq Progressor device
|
|
41
|
+
* Represents a Tindeq Progressor device.
|
|
41
42
|
*/
|
|
42
43
|
export class Progressor extends Device implements IProgressor {
|
|
43
44
|
constructor() {
|
|
@@ -122,7 +123,7 @@ export class Progressor extends Device implements IProgressor {
|
|
|
122
123
|
*
|
|
123
124
|
* @param {BluetoothRemoteGATTCharacteristic} characteristic - The notification event.
|
|
124
125
|
*/
|
|
125
|
-
handleNotifications = (characteristic: BluetoothRemoteGATTCharacteristic): void => {
|
|
126
|
+
override handleNotifications = (characteristic: BluetoothRemoteGATTCharacteristic): void => {
|
|
126
127
|
const value: DataView | undefined = characteristic.value
|
|
127
128
|
|
|
128
129
|
if (value) {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { Device } from "../device.model"
|
|
2
|
-
import type { IWHC06 } from "../../interfaces/device/wh-c06.interface"
|
|
1
|
+
import { Device } from "../device.model.js"
|
|
2
|
+
import type { IWHC06 } from "../../interfaces/device/wh-c06.interface.js"
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Represents a
|
|
6
|
-
*
|
|
5
|
+
* Represents a Weiheng - WH-C06 (or MAT Muscle Meter) device.
|
|
6
|
+
* To use this device enable: `chrome://flags/#enable-experimental-web-platform-features`.
|
|
7
|
+
* {@link https://googlechrome.github.io/samples/web-bluetooth/scan.html| Web Bluetooth}
|
|
8
|
+
* {@link https://weihengmanufacturer.com}
|
|
7
9
|
*/
|
|
8
10
|
export class WHC06 extends Device implements IWHC06 {
|
|
9
11
|
/**
|
|
@@ -29,7 +31,7 @@ export class WHC06 extends Device implements IWHC06 {
|
|
|
29
31
|
* @type {number|null}
|
|
30
32
|
* @private
|
|
31
33
|
*/
|
|
32
|
-
private advertisementTimeout:
|
|
34
|
+
private advertisementTimeout: ReturnType<typeof setTimeout> | null = null
|
|
33
35
|
|
|
34
36
|
/**
|
|
35
37
|
* The limit in seconds when timeout is triggered
|
|
@@ -68,7 +70,7 @@ export class WHC06 extends Device implements IWHC06 {
|
|
|
68
70
|
* @param {Function} [onSuccess] - Optional callback function to execute on successful connection. Default logs success.
|
|
69
71
|
* @param {Function} [onError] - Optional callback function to execute on error. Default logs the error.
|
|
70
72
|
*/
|
|
71
|
-
connect = async (
|
|
73
|
+
override connect = async (
|
|
72
74
|
onSuccess: () => void = () => console.log("Connected successfully"),
|
|
73
75
|
onError: (error: Error) => void = (error) => console.error(error),
|
|
74
76
|
): Promise<void> => {
|
|
@@ -78,7 +80,9 @@ export class WHC06 extends Device implements IWHC06 {
|
|
|
78
80
|
(filter) => filter.manufacturerData?.map((data) => data.companyIdentifier) || [],
|
|
79
81
|
)
|
|
80
82
|
|
|
81
|
-
|
|
83
|
+
const bluetooth = await this.getBluetooth()
|
|
84
|
+
|
|
85
|
+
this.bluetooth = await bluetooth.requestDevice({
|
|
82
86
|
filters: this.filters,
|
|
83
87
|
optionalManufacturerData,
|
|
84
88
|
})
|
|
@@ -168,7 +172,7 @@ export class WHC06 extends Device implements IWHC06 {
|
|
|
168
172
|
* For the WH-C06 device, the `gatt.connected` property remains `false` even after the device is connected.
|
|
169
173
|
* @returns {boolean} A boolean indicating whether the device is connected.
|
|
170
174
|
*/
|
|
171
|
-
isConnected = (): boolean => {
|
|
175
|
+
override isConnected = (): boolean => {
|
|
172
176
|
return !!this.bluetooth
|
|
173
177
|
}
|
|
174
178
|
|
|
@@ -182,10 +186,13 @@ export class WHC06 extends Device implements IWHC06 {
|
|
|
182
186
|
}
|
|
183
187
|
|
|
184
188
|
// Set a new timeout to stop tracking if no advertisement is received
|
|
185
|
-
this.advertisementTimeout =
|
|
189
|
+
this.advertisementTimeout = globalThis.setTimeout(() => {
|
|
186
190
|
// Mimic a disconnect
|
|
187
191
|
const disconnectedEvent = new Event("gattserverdisconnected")
|
|
188
|
-
Object.defineProperty(disconnectedEvent, "target", {
|
|
192
|
+
Object.defineProperty(disconnectedEvent, "target", {
|
|
193
|
+
value: this.bluetooth,
|
|
194
|
+
writable: false,
|
|
195
|
+
})
|
|
189
196
|
// Print error to the console
|
|
190
197
|
console.error(`No advertisement received for ${this.advertisementTimeoutTime} seconds, stopping tracking..`)
|
|
191
198
|
this.onDisconnected(disconnectedEvent)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { BaseModel } from "./../models/base.model"
|
|
2
|
-
import type { IDevice, Service } from "../interfaces/device.interface"
|
|
3
|
-
import type {
|
|
4
|
-
import type { DownloadPacket } from "../interfaces/download.interface"
|
|
5
|
-
import type { Commands } from "../interfaces/command.interface"
|
|
1
|
+
import { BaseModel } from "./../models/base.model.js"
|
|
2
|
+
import type { IDevice, Service } from "../interfaces/device.interface.js"
|
|
3
|
+
import type { ActiveCallback, massObject, NotifyCallback, WriteCallback } from "../interfaces/callback.interface.js"
|
|
4
|
+
import type { DownloadPacket } from "../interfaces/download.interface.js"
|
|
5
|
+
import type { Commands } from "../interfaces/command.interface.js"
|
|
6
6
|
|
|
7
7
|
export abstract class Device extends BaseModel implements IDevice {
|
|
8
8
|
/**
|
|
@@ -61,7 +61,10 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
61
61
|
/**
|
|
62
62
|
* Configuration for threshold and duration.
|
|
63
63
|
*/
|
|
64
|
-
private activeConfig: { threshold: number; duration: number } = {
|
|
64
|
+
private activeConfig: { threshold: number; duration: number } = {
|
|
65
|
+
threshold: 2.5,
|
|
66
|
+
duration: 1000,
|
|
67
|
+
}
|
|
65
68
|
|
|
66
69
|
/**
|
|
67
70
|
* Maximum mass recorded from the device, initialized to "0".
|
|
@@ -272,13 +275,12 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
272
275
|
onError: (error: Error) => void = (error) => console.error(error),
|
|
273
276
|
): Promise<void> => {
|
|
274
277
|
try {
|
|
275
|
-
if (typeof navigator === "undefined" || !("bluetooth" in navigator)) {
|
|
276
|
-
throw new Error("Web Bluetooth API not supported in this environment.")
|
|
277
|
-
}
|
|
278
278
|
// Request device and set up connection
|
|
279
279
|
const deviceServices = this.getAllServiceUUIDs()
|
|
280
280
|
|
|
281
|
-
|
|
281
|
+
const bluetooth = await this.getBluetooth()
|
|
282
|
+
|
|
283
|
+
this.bluetooth = await bluetooth.requestDevice({
|
|
282
284
|
filters: this.filters,
|
|
283
285
|
optionalServices: deviceServices,
|
|
284
286
|
})
|
|
@@ -456,7 +458,7 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
456
458
|
const blob = new Blob([content], { type: mimeType })
|
|
457
459
|
|
|
458
460
|
// Create a URL for the Blob
|
|
459
|
-
const url =
|
|
461
|
+
const url = globalThis.URL.createObjectURL(blob)
|
|
460
462
|
|
|
461
463
|
// Create a link element
|
|
462
464
|
const link = document.createElement("a")
|
|
@@ -473,7 +475,7 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
473
475
|
|
|
474
476
|
// Clean up: remove the link and revoke the URL
|
|
475
477
|
document.body.removeChild(link)
|
|
476
|
-
|
|
478
|
+
globalThis.URL.revokeObjectURL(url)
|
|
477
479
|
}
|
|
478
480
|
|
|
479
481
|
/**
|
|
@@ -489,6 +491,23 @@ export abstract class Device extends BaseModel implements IDevice {
|
|
|
489
491
|
return this.services.filter((service) => service?.uuid).map((service) => service.uuid)
|
|
490
492
|
}
|
|
491
493
|
|
|
494
|
+
/**
|
|
495
|
+
* Attempt to use ES module import rather than require.
|
|
496
|
+
* This approach uses an async dynamic import for `webbluetooth`,
|
|
497
|
+
* so we can fallback if `navigator.bluetooth` is unavailable.
|
|
498
|
+
*/
|
|
499
|
+
protected async getBluetooth() {
|
|
500
|
+
// If we're in a browser with real Web Bluetooth available:
|
|
501
|
+
if (typeof navigator !== "undefined" && "bluetooth" in navigator) {
|
|
502
|
+
return navigator.bluetooth
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// Otherwise, we're likely in Node or an environment without `navigator.bluetooth`.
|
|
506
|
+
// Use a dynamic import for the ESM version:
|
|
507
|
+
const { bluetooth } = await import("webbluetooth")
|
|
508
|
+
return bluetooth
|
|
509
|
+
}
|
|
510
|
+
|
|
492
511
|
/**
|
|
493
512
|
* Retrieves the characteristic from the device's service.
|
|
494
513
|
* @param {string} serviceId - The UUID of the service.
|
package/src/models/index.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
export { Climbro } from "./device/climbro.model"
|
|
1
|
+
export { Climbro } from "./device/climbro.model.js"
|
|
2
2
|
|
|
3
|
-
export { Entralpi } from "./device/entralpi.model"
|
|
3
|
+
export { Entralpi } from "./device/entralpi.model.js"
|
|
4
4
|
|
|
5
|
-
export { ForceBoard } from "./device/forceboard.model"
|
|
5
|
+
export { ForceBoard } from "./device/forceboard.model.js"
|
|
6
6
|
|
|
7
|
-
export { KilterBoard } from "./device/kilterboard.model"
|
|
7
|
+
export { KilterBoard } from "./device/kilterboard.model.js"
|
|
8
8
|
|
|
9
|
-
export { Motherboard } from "./device/motherboard.model"
|
|
9
|
+
export { Motherboard } from "./device/motherboard.model.js"
|
|
10
10
|
|
|
11
|
-
export { mySmartBoard } from "./device/mysmartboard.model"
|
|
11
|
+
export { mySmartBoard } from "./device/mysmartboard.model.js"
|
|
12
12
|
|
|
13
|
-
export { Progressor } from "./device/progressor.model"
|
|
13
|
+
export { Progressor } from "./device/progressor.model.js"
|
|
14
14
|
|
|
15
|
-
export { WHC06 } from "./device/wh-c06.model"
|
|
15
|
+
export { WHC06 } from "./device/wh-c06.model.js"
|