@hangtime/grip-connect 0.5.11 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -5
- package/deno.json +1 -1
- package/dist/index.d.ts +2 -1
- 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 +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/interfaces/index.d.ts +8 -0
- package/dist/interfaces/index.js +1 -0
- 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 +8 -7
- package/dist/models/device/kilterboard.model.js +7 -6
- 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 +4 -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 +7 -4
- package/dist/models/device.model.d.ts +15 -9
- package/dist/models/device.model.js +51 -35
- package/dist/models/index.d.ts +8 -8
- package/dist/models/index.js +8 -9
- package/package.json +6 -3
- package/src/index.ts +12 -1
- 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/interfaces/index.ts +15 -0
- package/src/models/base.model.ts +1 -1
- package/src/models/device/climbro.model.ts +4 -3
- package/src/models/device/entralpi.model.ts +6 -2
- package/src/models/device/forceboard.model.ts +4 -3
- package/src/models/device/kilterboard.model.ts +15 -14
- package/src/models/device/motherboard.model.ts +5 -4
- package/src/models/device/mysmartboard.model.ts +4 -3
- package/src/models/device/progressor.model.ts +5 -4
- package/src/models/device/wh-c06.model.ts +10 -6
- package/src/models/device.model.ts +57 -39
- package/src/models/index.ts +8 -10
|
@@ -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.
|
|
@@ -239,12 +239,10 @@ export class Device extends BaseModel {
|
|
|
239
239
|
*/
|
|
240
240
|
connect = async (onSuccess = () => console.log("Connected successfully"), onError = (error) => console.error(error)) => {
|
|
241
241
|
try {
|
|
242
|
-
if (typeof navigator === "undefined" || !("bluetooth" in navigator)) {
|
|
243
|
-
throw new Error("Web Bluetooth API not supported in this environment.");
|
|
244
|
-
}
|
|
245
242
|
// Request device and set up connection
|
|
246
243
|
const deviceServices = this.getAllServiceUUIDs();
|
|
247
|
-
|
|
244
|
+
const bluetooth = await this.getBluetooth();
|
|
245
|
+
this.bluetooth = await bluetooth.requestDevice({
|
|
248
246
|
filters: this.filters,
|
|
249
247
|
optionalServices: deviceServices,
|
|
250
248
|
});
|
|
@@ -374,54 +372,57 @@ export class Device extends BaseModel {
|
|
|
374
372
|
* @param {('csv' | 'json' | 'xml')} [format='csv'] - The format in which to download the data.
|
|
375
373
|
* Defaults to 'csv'. Accepted values are 'csv', 'json', and 'xml'.
|
|
376
374
|
*
|
|
377
|
-
* @returns {void}
|
|
378
|
-
* @
|
|
375
|
+
* @returns {Promise<void>} Resolves when the data has been downloaded/written
|
|
376
|
+
* @public
|
|
379
377
|
*
|
|
380
378
|
* @example
|
|
381
|
-
* device.download('json');
|
|
379
|
+
* await device.download('json');
|
|
382
380
|
*/
|
|
383
|
-
download = (format = "csv") => {
|
|
384
|
-
if (typeof document === "undefined" || typeof window === "undefined") {
|
|
385
|
-
console.warn("Download is not supported outside a browser environment.");
|
|
386
|
-
return;
|
|
387
|
-
}
|
|
381
|
+
download = async (format = "csv") => {
|
|
388
382
|
let content = "";
|
|
389
|
-
let mimeType = "";
|
|
390
|
-
let fileName = "";
|
|
391
383
|
if (format === "csv") {
|
|
392
384
|
content = this.downloadToCSV();
|
|
393
|
-
mimeType = "text/csv";
|
|
394
385
|
}
|
|
395
386
|
else if (format === "json") {
|
|
396
387
|
content = this.downloadToJSON();
|
|
397
|
-
mimeType = "application/json";
|
|
398
388
|
}
|
|
399
389
|
else if (format === "xml") {
|
|
400
390
|
content = this.downloadToXML();
|
|
401
|
-
mimeType = "application/xml";
|
|
402
391
|
}
|
|
403
392
|
const now = new Date();
|
|
404
393
|
// YYYY-MM-DD
|
|
405
394
|
const date = now.toISOString().split("T")[0];
|
|
406
395
|
// HH-MM-SS
|
|
407
396
|
const time = now.toTimeString().split(" ")[0].replace(/:/g, "-");
|
|
408
|
-
fileName = `data-export-${date}-${time}.${format}`;
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
397
|
+
const fileName = `data-export-${date}-${time}.${format}`;
|
|
398
|
+
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
399
|
+
const mimeTypes = {
|
|
400
|
+
csv: "text/csv",
|
|
401
|
+
json: "application/json",
|
|
402
|
+
xml: "application/xml",
|
|
403
|
+
};
|
|
404
|
+
// Create a Blob object containing the data
|
|
405
|
+
const blob = new Blob([content], { type: mimeTypes[format] });
|
|
406
|
+
// Create a URL for the Blob
|
|
407
|
+
const url = globalThis.URL.createObjectURL(blob);
|
|
408
|
+
// Create a link element
|
|
409
|
+
const link = document.createElement("a");
|
|
410
|
+
// Set link attributes
|
|
411
|
+
link.href = url;
|
|
412
|
+
link.setAttribute("download", fileName);
|
|
413
|
+
// Append link to document body
|
|
414
|
+
document.body.appendChild(link);
|
|
415
|
+
// Programmatically click the link to trigger the download
|
|
416
|
+
link.click();
|
|
417
|
+
// Clean up: remove the link and revoke the URL
|
|
418
|
+
document.body.removeChild(link);
|
|
419
|
+
globalThis.URL.revokeObjectURL(url);
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
const { writeFile } = await import("node:fs/promises");
|
|
423
|
+
await writeFile(fileName, content);
|
|
424
|
+
console.log(`File saved as ${fileName}`);
|
|
425
|
+
}
|
|
425
426
|
};
|
|
426
427
|
/**
|
|
427
428
|
* Returns UUIDs of all services associated with the device.
|
|
@@ -435,6 +436,21 @@ export class Device extends BaseModel {
|
|
|
435
436
|
getAllServiceUUIDs = () => {
|
|
436
437
|
return this.services.filter((service) => service?.uuid).map((service) => service.uuid);
|
|
437
438
|
};
|
|
439
|
+
/**
|
|
440
|
+
* Attempt to use ES module import rather than require.
|
|
441
|
+
* This approach uses an async dynamic import for `webbluetooth`,
|
|
442
|
+
* so we can fallback if `navigator.bluetooth` is unavailable.
|
|
443
|
+
*/
|
|
444
|
+
async getBluetooth() {
|
|
445
|
+
// If we're in a browser with real Web Bluetooth available:
|
|
446
|
+
if (typeof navigator !== "undefined" && "bluetooth" in navigator) {
|
|
447
|
+
return navigator.bluetooth;
|
|
448
|
+
}
|
|
449
|
+
// Otherwise, we're likely in Node or an environment without `navigator.bluetooth`.
|
|
450
|
+
// Use a dynamic import for the ESM version:
|
|
451
|
+
const { bluetooth } = await import("webbluetooth");
|
|
452
|
+
return bluetooth;
|
|
453
|
+
}
|
|
438
454
|
/**
|
|
439
455
|
* Retrieves the characteristic from the device's service.
|
|
440
456
|
* @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,9 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
8
|
-
export {
|
|
9
|
-
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,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hangtime/grip-connect",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Griptonite Motherboard, Tindeq Progressor, PitchSix Force Board, WHC-06, Entralpi, Climbro, mySmartBoard: Web Bluetooth API Force-Sensing strength analysis for climbers",
|
|
3
|
+
"version": "0.6.1",
|
|
4
|
+
"description": "Griptonite Motherboard, Tindeq Progressor, PitchSix Force Board, WHC-06, Entralpi, Climbro, mySmartBoard: Web + Node 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",
|
|
@@ -33,5 +33,8 @@
|
|
|
33
33
|
"bugs": {
|
|
34
34
|
"url": "https://github.com/Stevie-Ray/hangtime-grip-connect/issues"
|
|
35
35
|
},
|
|
36
|
-
"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
|
+
}
|
|
37
40
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
IClimbro,
|
|
3
|
+
IEntralpi,
|
|
4
|
+
IForceBoard,
|
|
5
|
+
IKilterBoard,
|
|
6
|
+
IMotherboard,
|
|
7
|
+
ImySmartBoard,
|
|
8
|
+
IProgressor,
|
|
9
|
+
IWHC06,
|
|
10
|
+
} from "./interfaces/index.js"
|
|
11
|
+
|
|
1
12
|
export {
|
|
2
13
|
Climbro,
|
|
3
14
|
Entralpi,
|
|
@@ -7,4 +18,4 @@ export {
|
|
|
7
18
|
mySmartBoard,
|
|
8
19
|
Progressor,
|
|
9
20
|
WHC06,
|
|
10
|
-
} from "./models/index"
|
|
21
|
+
} from "./models/index.js"
|
|
@@ -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.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type { IClimbro } from "./device/climbro.interface.js"
|
|
2
|
+
|
|
3
|
+
export type { IEntralpi } from "./device/entralpi.interface.js"
|
|
4
|
+
|
|
5
|
+
export type { IForceBoard } from "./device/forceboard.interface.js"
|
|
6
|
+
|
|
7
|
+
export type { IKilterBoard } from "./device/kilterboard.interface.js"
|
|
8
|
+
|
|
9
|
+
export type { IMotherboard } from "./device/motherboard.interface.js"
|
|
10
|
+
|
|
11
|
+
export type { ImySmartBoard } from "./device/mysmartboard.interface.js"
|
|
12
|
+
|
|
13
|
+
export type { IProgressor } from "./device/progressor.interface.js"
|
|
14
|
+
|
|
15
|
+
export type { IWHC06 } from "./device/wh-c06.interface.js"
|
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({
|
|
@@ -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() {
|
|
@@ -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
|
/**
|
|
@@ -135,9 +136,9 @@ export class KilterBoard extends Device implements IKilterBoard {
|
|
|
135
136
|
/**
|
|
136
137
|
* Calculates the checksum for a byte array by summing up all bytes ot hre packet in a single-byte variable.
|
|
137
138
|
* @param data - The array of bytes to calculate the checksum for.
|
|
138
|
-
* @returns The calculated checksum value.
|
|
139
|
+
* @returns {number} The calculated checksum value.
|
|
139
140
|
*/
|
|
140
|
-
private checksum(data: number[]) {
|
|
141
|
+
private checksum(data: number[]): number {
|
|
141
142
|
let i = 0
|
|
142
143
|
for (const value of data) {
|
|
143
144
|
i = (i + value) & 255
|
|
@@ -148,9 +149,9 @@ export class KilterBoard extends Device implements IKilterBoard {
|
|
|
148
149
|
/**
|
|
149
150
|
* Wraps a byte array with header and footer bytes for transmission.
|
|
150
151
|
* @param data - The array of bytes to wrap.
|
|
151
|
-
* @returns The wrapped byte array.
|
|
152
|
+
* @returns {number[]} The wrapped byte array.
|
|
152
153
|
*/
|
|
153
|
-
private wrapBytes(data: number[]) {
|
|
154
|
+
private wrapBytes(data: number[]): number[] {
|
|
154
155
|
if (data.length > KilterBoard.messageBodyMaxLength) {
|
|
155
156
|
return []
|
|
156
157
|
}
|
|
@@ -172,9 +173,9 @@ export class KilterBoard extends Device implements IKilterBoard {
|
|
|
172
173
|
* The lowest 8 bits of the position get put in the first byte of the group.
|
|
173
174
|
* The highest 8 bits of the position get put in the second byte of the group.
|
|
174
175
|
* @param position - The position to encode.
|
|
175
|
-
* @returns The encoded byte array representing the position.
|
|
176
|
+
* @returns {number[]} The encoded byte array representing the position.
|
|
176
177
|
*/
|
|
177
|
-
private encodePosition(position: number) {
|
|
178
|
+
private encodePosition(position: number): number[] {
|
|
178
179
|
const position1 = position & 255
|
|
179
180
|
const position2 = (position & 65280) >> 8
|
|
180
181
|
|
|
@@ -187,7 +188,7 @@ export class KilterBoard extends Device implements IKilterBoard {
|
|
|
187
188
|
* @param color - The color string in hexadecimal format (e.g., 'FFFFFF').
|
|
188
189
|
* @returns The encoded /compressed color value.
|
|
189
190
|
*/
|
|
190
|
-
private encodeColor(color: string) {
|
|
191
|
+
private encodeColor(color: string): number {
|
|
191
192
|
const substring = color.substring(0, 2)
|
|
192
193
|
const substring2 = color.substring(2, 4)
|
|
193
194
|
|
|
@@ -208,7 +209,7 @@ export class KilterBoard extends Device implements IKilterBoard {
|
|
|
208
209
|
* @param ledColor - The color of the LED in hexadecimal format (e.g., 'FFFFFF').
|
|
209
210
|
* @returns The encoded byte array representing the placement.
|
|
210
211
|
*/
|
|
211
|
-
private encodePlacement(position: number, ledColor: string) {
|
|
212
|
+
private encodePlacement(position: number, ledColor: string): number[] {
|
|
212
213
|
return [...this.encodePosition(position), this.encodeColor(ledColor)]
|
|
213
214
|
}
|
|
214
215
|
|
|
@@ -217,7 +218,7 @@ export class KilterBoard extends Device implements IKilterBoard {
|
|
|
217
218
|
* @param {{ position: number; role_id: number }[]} climbPlacementList - The list of climb placements containing position and role ID.
|
|
218
219
|
* @returns {number[]} The final byte array ready for transmission.
|
|
219
220
|
*/
|
|
220
|
-
private prepBytesV3(climbPlacementList: { position: number; role_id: number }[]) {
|
|
221
|
+
private prepBytesV3(climbPlacementList: { position: number; role_id: number }[]): number[] {
|
|
221
222
|
const resultArray: number[][] = []
|
|
222
223
|
let tempArray: number[] = [KilterBoardPacket.V3_MIDDLE]
|
|
223
224
|
|
|
@@ -256,9 +257,9 @@ export class KilterBoard extends Device implements IKilterBoard {
|
|
|
256
257
|
* https://github.com/ramda/ramda/blob/master/source/splitEvery.js
|
|
257
258
|
* @param {Number} n
|
|
258
259
|
* @param {Array} list
|
|
259
|
-
* @return {Array}
|
|
260
|
+
* @return {Array<number[]>}
|
|
260
261
|
*/
|
|
261
|
-
private splitEvery(n: number, list: number[]) {
|
|
262
|
+
private splitEvery(n: number, list: number[]): number[][] {
|
|
262
263
|
if (n <= 0) {
|
|
263
264
|
throw new Error("First argument to splitEvery must be a positive integer")
|
|
264
265
|
}
|
|
@@ -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
|
/**
|
|
@@ -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,8 @@
|
|
|
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
|
-
*
|
|
5
|
+
* Progressor responses
|
|
6
6
|
*/
|
|
7
7
|
enum ProgressorResponses {
|
|
8
8
|
/**
|
|
@@ -37,7 +37,8 @@ enum ProgressorResponses {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
-
* Represents a Tindeq Progressor device
|
|
40
|
+
* Represents a Tindeq Progressor device.
|
|
41
|
+
* {@link https://tindeq.com}
|
|
41
42
|
*/
|
|
42
43
|
export class Progressor extends Device implements IProgressor {
|
|
43
44
|
constructor() {
|
|
@@ -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
|
|
@@ -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
|
})
|