@hangtime/grip-connect 0.5.1 → 0.5.3
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 +8 -17
- package/dist/{download.d.ts → helpers/download.d.ts} +1 -1
- package/dist/helpers/is-device.d.ts +37 -0
- package/dist/helpers/is-device.js +39 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -5
- package/dist/interfaces/callback.interface.d.ts +49 -0
- package/dist/interfaces/command.interface.d.ts +85 -0
- package/dist/interfaces/device.interface.d.ts +54 -12
- package/dist/models/device/entralpi.model.js +18 -24
- package/dist/models/device/forceboard.model.js +7 -8
- package/dist/models/device/kilterboard.model.d.ts +61 -2
- package/dist/models/device/kilterboard.model.js +92 -13
- package/dist/models/device/motherboard.model.d.ts +24 -1
- package/dist/models/device/motherboard.model.js +63 -43
- package/dist/models/device/progressor.model.js +64 -26
- package/dist/models/device/wh-c06.model.d.ts +7 -0
- package/dist/models/device/wh-c06.model.js +18 -17
- package/dist/models/device.model.d.ts +105 -11
- package/dist/models/device.model.js +181 -10
- package/package.json +1 -1
- package/src/{download.ts → helpers/download.ts} +1 -1
- package/src/helpers/is-device.ts +50 -0
- package/src/index.ts +4 -5
- package/src/interfaces/callback.interface.ts +56 -0
- package/src/interfaces/command.interface.ts +106 -0
- package/src/interfaces/device.interface.ts +66 -13
- package/src/models/device/entralpi.model.ts +18 -25
- package/src/models/device/forceboard.model.ts +7 -8
- package/src/models/device/kilterboard.model.ts +94 -15
- package/src/models/device/motherboard.model.ts +68 -47
- package/src/models/device/progressor.model.ts +68 -27
- package/src/models/device/wh-c06.model.ts +20 -18
- package/src/models/device.model.ts +207 -17
- package/dist/characteristic.d.ts +0 -9
- package/dist/characteristic.js +0 -21
- package/dist/commands/climbro.d.ts +0 -6
- package/dist/commands/climbro.js +0 -5
- package/dist/commands/entralpi.d.ts +0 -6
- package/dist/commands/entralpi.js +0 -5
- package/dist/commands/forceboard.d.ts +0 -6
- package/dist/commands/forceboard.js +0 -5
- package/dist/commands/index.d.ts +0 -7
- package/dist/commands/index.js +0 -7
- package/dist/commands/kilterboard.d.ts +0 -35
- package/dist/commands/kilterboard.js +0 -65
- package/dist/commands/motherboard.d.ts +0 -6
- package/dist/commands/motherboard.js +0 -13
- package/dist/commands/mysmartboard.d.ts +0 -6
- package/dist/commands/mysmartboard.js +0 -5
- package/dist/commands/progressor.d.ts +0 -17
- package/dist/commands/progressor.js +0 -30
- package/dist/commands/wh-c06.d.ts +0 -6
- package/dist/commands/wh-c06.js +0 -5
- package/dist/is-device.d.ts +0 -37
- package/dist/is-device.js +0 -39
- package/dist/read.d.ts +0 -10
- package/dist/read.js +0 -43
- package/dist/types/commands.d.ts +0 -18
- package/dist/types/notify.d.ts +0 -14
- package/dist/write.d.ts +0 -34
- package/dist/write.js +0 -58
- package/src/characteristic.ts +0 -29
- package/src/commands/climbro.ts +0 -6
- package/src/commands/entralpi.ts +0 -6
- package/src/commands/forceboard.ts +0 -6
- package/src/commands/index.ts +0 -13
- package/src/commands/kilterboard.ts +0 -64
- package/src/commands/motherboard.ts +0 -14
- package/src/commands/mysmartboard.ts +0 -6
- package/src/commands/progressor.ts +0 -31
- package/src/commands/wh-c06.ts +0 -6
- package/src/is-device.ts +0 -50
- package/src/read.ts +0 -45
- package/src/types/commands.ts +0 -21
- package/src/types/notify.ts +0 -14
- package/src/write.ts +0 -74
- /package/dist/{download.js → helpers/download.js} +0 -0
- /package/dist/{is-active.d.ts → helpers/is-active.d.ts} +0 -0
- /package/dist/{is-active.js → helpers/is-active.js} +0 -0
- /package/dist/{struct/index.d.ts → helpers/struct.d.ts} +0 -0
- /package/dist/{struct/index.js → helpers/struct.js} +0 -0
- /package/dist/{tare.d.ts → helpers/tare.d.ts} +0 -0
- /package/dist/{tare.js → helpers/tare.js} +0 -0
- /package/dist/{types/commands.js → interfaces/callback.interface.js} +0 -0
- /package/dist/{types/download.js → interfaces/command.interface.js} +0 -0
- /package/dist/{types/download.d.ts → interfaces/download.interface.d.ts} +0 -0
- /package/dist/{types/notify.js → interfaces/download.interface.js} +0 -0
- /package/src/{is-active.ts → helpers/is-active.ts} +0 -0
- /package/src/{struct/index.ts → helpers/struct.ts} +0 -0
- /package/src/{tare.ts → helpers/tare.ts} +0 -0
- /package/src/{types/download.ts → interfaces/download.interface.ts} +0 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents the available commands for various devices such as the Motherboard and Tindeq Progressor.
|
|
3
|
+
*/
|
|
4
|
+
export interface Commands {
|
|
5
|
+
// Motherboard, Progressor
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Starts a weight measurement on the device.
|
|
9
|
+
* Used to begin collecting weight or force data.
|
|
10
|
+
*/
|
|
11
|
+
START_WEIGHT_MEAS?: string
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Stops the current weight measurement on the device.
|
|
15
|
+
* Used to end the data collection.
|
|
16
|
+
*/
|
|
17
|
+
STOP_WEIGHT_MEAS?: string
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Puts the device to sleep or in a low-power mode.
|
|
21
|
+
* The format can be a string or a number depending on the device.
|
|
22
|
+
*/
|
|
23
|
+
SLEEP?: number | string
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Retrieves the serial number of the device.
|
|
27
|
+
* This command fetches the unique identifier assigned by the manufacturer.
|
|
28
|
+
*/
|
|
29
|
+
GET_SERIAL?: string
|
|
30
|
+
|
|
31
|
+
// Griptonite Motherboard
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Retrieves textual information from the device.
|
|
35
|
+
* May include readable data.
|
|
36
|
+
*/
|
|
37
|
+
GET_TEXT?: string
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Starts or stops a debug data stream from the device.
|
|
41
|
+
* Used for diagnostic purposes or to monitor real-time data.
|
|
42
|
+
*/
|
|
43
|
+
DEBUG_STREAM?: string
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Retrieves calibration data from the device.
|
|
47
|
+
* Used to ensure accurate measurements by applying calibration points.
|
|
48
|
+
*/
|
|
49
|
+
GET_CALIBRATION?: string
|
|
50
|
+
|
|
51
|
+
// Tindeq Progressor
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Tares the scale, zeroing the current weight measurement.
|
|
55
|
+
* Used to reset the baseline for weight data.
|
|
56
|
+
*/
|
|
57
|
+
TARE_SCALE?: string
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Starts measuring the peak rate of force development (RFD).
|
|
61
|
+
* Captures how quickly force is applied over time.
|
|
62
|
+
*/
|
|
63
|
+
START_PEAK_RFD_MEAS?: string
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Starts measuring a series of peak RFD measurements.
|
|
67
|
+
* This captures multiple RFD data points over a period of time.
|
|
68
|
+
*/
|
|
69
|
+
START_PEAK_RFD_MEAS_SERIES?: string
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Adds a calibration point to the device.
|
|
73
|
+
* Used to improve the accuracy of future measurements.
|
|
74
|
+
*/
|
|
75
|
+
ADD_CALIB_POINT?: string
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Saves the current calibration settings to the device.
|
|
79
|
+
* Ensures the device remembers the calibration for future sessions.
|
|
80
|
+
*/
|
|
81
|
+
SAVE_CALIB?: string
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Retrieves the firmware version of the device.
|
|
85
|
+
* Useful for ensuring compatibility and tracking updates.
|
|
86
|
+
*/
|
|
87
|
+
GET_FW_VERSION?: string
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Retrieves error information from the device.
|
|
91
|
+
* Provides details on any faults or issues that occurred during operation.
|
|
92
|
+
*/
|
|
93
|
+
GET_ERR_INFO?: string
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Clears the error information on the device.
|
|
97
|
+
* Used to reset error logs after troubleshooting or repair.
|
|
98
|
+
*/
|
|
99
|
+
CLR_ERR_INFO?: string
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Retrieves the battery voltage level of the device.
|
|
103
|
+
* Provides insight into the device's remaining battery power.
|
|
104
|
+
*/
|
|
105
|
+
GET_BATT_VLTG?: string
|
|
106
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { IBase } from "./base.interface"
|
|
2
|
-
import type { massObject } from "
|
|
2
|
+
import type { massObject } from "./callback.interface"
|
|
3
|
+
import type { Commands } from "./command.interface"
|
|
3
4
|
|
|
4
|
-
type NotifyCallback = (data: massObject) => void
|
|
5
5
|
/**
|
|
6
6
|
* Represents a characteristic of a Bluetooth service.
|
|
7
7
|
*/
|
|
@@ -34,13 +34,30 @@ export interface Service {
|
|
|
34
34
|
* Represents a Bluetooth device.
|
|
35
35
|
*/
|
|
36
36
|
export interface IDevice extends IBase {
|
|
37
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* Filters to identify the device during Bluetooth scanning.
|
|
39
|
+
* Used to match devices that meet specific criteria such as name, service UUIDs, etc.
|
|
40
|
+
*/
|
|
38
41
|
filters: BluetoothLEScanFilter[]
|
|
39
|
-
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Array of services provided by the device.
|
|
45
|
+
* Services represent functionalities that the device supports, such as weight measurement, battery information, or custom services.
|
|
46
|
+
*/
|
|
40
47
|
services: Service[]
|
|
41
|
-
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Reference to the `BluetoothDevice` object representing this device.
|
|
51
|
+
* This is the actual device object obtained from the Web Bluetooth API after a successful connection.
|
|
52
|
+
*/
|
|
42
53
|
bluetooth?: BluetoothDevice
|
|
43
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Object representing the set of commands available for this device.
|
|
57
|
+
* These commands allow communication with the device to perform various operations such as starting measurements, retrieving data, or calibrating the device.
|
|
58
|
+
*/
|
|
59
|
+
commands: Commands
|
|
60
|
+
|
|
44
61
|
/**
|
|
45
62
|
* Connects to a Bluetooth device.
|
|
46
63
|
* @param {Function} [onSuccess] - Optional callback function to execute on successful connection. Default logs success.
|
|
@@ -61,6 +78,14 @@ export interface IDevice extends IBase {
|
|
|
61
78
|
*/
|
|
62
79
|
getAllServiceUUIDs(): string[]
|
|
63
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Retrieves the characteristic from the device's service.
|
|
83
|
+
* @param {string} serviceId - The UUID of the service.
|
|
84
|
+
* @param {string} characteristicId - The UUID of the characteristic.
|
|
85
|
+
* @returns {BluetoothRemoteGATTCharacteristic | undefined} The characteristic, if found.
|
|
86
|
+
*/
|
|
87
|
+
getCharacteristic(serviceId: string, characteristicId: string): BluetoothRemoteGATTCharacteristic | undefined
|
|
88
|
+
|
|
64
89
|
/**
|
|
65
90
|
* Handles notifications received from a characteristic.
|
|
66
91
|
* @param {Event} event - The notification event.
|
|
@@ -78,14 +103,7 @@ export interface IDevice extends IBase {
|
|
|
78
103
|
* @param {NotifyCallback} callback - The callback function to be set.
|
|
79
104
|
* @returns {void}
|
|
80
105
|
*/
|
|
81
|
-
notify(callback:
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Defines the type for the callback function.
|
|
85
|
-
* @callback NotifyCallback
|
|
86
|
-
* @param {massObject} data - The data passed to the callback.
|
|
87
|
-
*/
|
|
88
|
-
notifyCallback: NotifyCallback
|
|
106
|
+
notify(callback: (data: massObject) => void): void
|
|
89
107
|
|
|
90
108
|
/**
|
|
91
109
|
* Handles the 'connected' event.
|
|
@@ -98,4 +116,39 @@ export interface IDevice extends IBase {
|
|
|
98
116
|
* @param {Event} event - The 'disconnected' event.
|
|
99
117
|
*/
|
|
100
118
|
onDisconnected(event: Event): void
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Reads the value of the specified characteristic from the device.
|
|
122
|
+
* @param {string} serviceId - The service ID where the characteristic belongs.
|
|
123
|
+
* @param {string} characteristicId - The characteristic ID to read from.
|
|
124
|
+
* @param {number} [duration=0] - The duration to wait before resolving the promise, in milliseconds.
|
|
125
|
+
* @returns {Promise<string>} A promise that resolves when the read operation is completed.
|
|
126
|
+
*/
|
|
127
|
+
read(serviceId: string, characteristicId: string, duration?: number): Promise<string>
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Writes a message to the specified characteristic of a Bluetooth device and optionally provides a callback to handle responses.
|
|
131
|
+
* @param {string} serviceId - The service UUID of the Bluetooth device containing the target characteristic.
|
|
132
|
+
* @param {string} characteristicId - The characteristic UUID where the message will be written.
|
|
133
|
+
* @param {string | Uint8Array | undefined} message - The message to be written to the characteristic. It can be a string or a Uint8Array.
|
|
134
|
+
* @param {number} [duration=0] - Optional. The time in milliseconds to wait before resolving the promise. Defaults to 0 for immediate resolution.
|
|
135
|
+
* @param {WriteCallback} [callback=writeCallback] - Optional. A custom callback to handle the response after the write operation is successful.
|
|
136
|
+
*
|
|
137
|
+
* @returns {Promise<void>} A promise that resolves once the write operation is complete.
|
|
138
|
+
*
|
|
139
|
+
* @throws {Error} Throws an error if the characteristic is undefined.
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* // Example usage of the write function with a custom callback
|
|
143
|
+
* await Progressor.write("progressor", "tx", ProgressorCommands.GET_BATT_VLTG, 250, (data) => {
|
|
144
|
+
* console.log(`Battery voltage: ${data}`);
|
|
145
|
+
* });
|
|
146
|
+
*/
|
|
147
|
+
write(
|
|
148
|
+
serviceId: string,
|
|
149
|
+
characteristicId: string,
|
|
150
|
+
message: string | Uint8Array | undefined,
|
|
151
|
+
duration?: number,
|
|
152
|
+
callback?: (data: string) => void,
|
|
153
|
+
): Promise<void>
|
|
101
154
|
}
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
import { Device } from "../device.model"
|
|
2
2
|
import type { IEntralpi } from "../../interfaces/device/entralpi.interface"
|
|
3
|
-
import { applyTare } from "../../tare"
|
|
4
|
-
import { checkActivity } from "../../is-active"
|
|
5
|
-
import { read } from "../../read"
|
|
6
|
-
|
|
7
|
-
// Constants
|
|
8
|
-
let MASS_MAX = "0"
|
|
9
|
-
let MASS_AVERAGE = "0"
|
|
10
|
-
let MASS_TOTAL_SUM = 0
|
|
11
|
-
let DATAPOINT_COUNT = 0
|
|
3
|
+
import { applyTare } from "../../helpers/tare"
|
|
4
|
+
import { checkActivity } from "../../helpers/is-active"
|
|
12
5
|
|
|
13
6
|
export class Entralpi extends Device implements IEntralpi {
|
|
14
7
|
constructor() {
|
|
@@ -139,7 +132,7 @@ export class Entralpi extends Device implements IEntralpi {
|
|
|
139
132
|
*/
|
|
140
133
|
battery = async (): Promise<string | undefined> => {
|
|
141
134
|
if (this.isConnected()) {
|
|
142
|
-
return await read(
|
|
135
|
+
return await this.read("battery", "level", 250)
|
|
143
136
|
}
|
|
144
137
|
// If device is not found, return undefined
|
|
145
138
|
return undefined
|
|
@@ -153,7 +146,7 @@ export class Entralpi extends Device implements IEntralpi {
|
|
|
153
146
|
// Check if the device is connected
|
|
154
147
|
if (this.isConnected()) {
|
|
155
148
|
// Read certification from the device
|
|
156
|
-
return await read(
|
|
149
|
+
return await this.read("device", "certification", 250)
|
|
157
150
|
}
|
|
158
151
|
// If device is not found, return undefined
|
|
159
152
|
return undefined
|
|
@@ -167,7 +160,7 @@ export class Entralpi extends Device implements IEntralpi {
|
|
|
167
160
|
// Check if the device is connected
|
|
168
161
|
if (this.isConnected()) {
|
|
169
162
|
// Read firmware version from the Motherboard
|
|
170
|
-
return await read(
|
|
163
|
+
return await this.read("device", "firmware", 250)
|
|
171
164
|
}
|
|
172
165
|
// If device is not found, return undefined
|
|
173
166
|
return undefined
|
|
@@ -195,24 +188,24 @@ export class Entralpi extends Device implements IEntralpi {
|
|
|
195
188
|
// Tare correction
|
|
196
189
|
numericData -= applyTare(numericData)
|
|
197
190
|
|
|
198
|
-
// Update
|
|
199
|
-
|
|
191
|
+
// Update massMax
|
|
192
|
+
this.massMax = Math.max(Number(this.massMax), numericData).toFixed(1)
|
|
200
193
|
|
|
201
194
|
// Update running sum and count
|
|
202
195
|
const currentMassTotal = Math.max(-1000, numericData)
|
|
203
|
-
|
|
204
|
-
|
|
196
|
+
this.massTotalSum += currentMassTotal
|
|
197
|
+
this.dataPointCount++
|
|
205
198
|
|
|
206
199
|
// Calculate the average dynamically
|
|
207
|
-
|
|
200
|
+
this.massAverage = (this.massTotalSum / this.dataPointCount).toFixed(1)
|
|
208
201
|
|
|
209
202
|
// Check if device is being used
|
|
210
203
|
checkActivity(numericData)
|
|
211
204
|
|
|
212
205
|
// Notify with weight data
|
|
213
206
|
this.notifyCallback({
|
|
214
|
-
massMax:
|
|
215
|
-
massAverage:
|
|
207
|
+
massMax: this.massMax,
|
|
208
|
+
massAverage: this.massAverage,
|
|
216
209
|
massTotal: Math.max(-1000, numericData).toFixed(1),
|
|
217
210
|
})
|
|
218
211
|
}
|
|
@@ -227,7 +220,7 @@ export class Entralpi extends Device implements IEntralpi {
|
|
|
227
220
|
// Check if the device is connected
|
|
228
221
|
if (this.isConnected()) {
|
|
229
222
|
// Read hardware version from the device
|
|
230
|
-
return await read(
|
|
223
|
+
return await this.read("device", "hardware", 250)
|
|
231
224
|
}
|
|
232
225
|
// If device is not found, return undefined
|
|
233
226
|
return undefined
|
|
@@ -241,7 +234,7 @@ export class Entralpi extends Device implements IEntralpi {
|
|
|
241
234
|
// Check if the device is connected
|
|
242
235
|
if (this.isConnected()) {
|
|
243
236
|
// Read manufacturer information from the device
|
|
244
|
-
return await read(
|
|
237
|
+
return await this.read("device", "manufacturer", 250)
|
|
245
238
|
}
|
|
246
239
|
// If device is not found, return undefined
|
|
247
240
|
return undefined
|
|
@@ -255,7 +248,7 @@ export class Entralpi extends Device implements IEntralpi {
|
|
|
255
248
|
// Check if the device is connected
|
|
256
249
|
if (this.isConnected()) {
|
|
257
250
|
// Read model number from the Entralpi
|
|
258
|
-
return await read(
|
|
251
|
+
return await this.read("device", "model", 250)
|
|
259
252
|
}
|
|
260
253
|
// If device is not found, return undefined
|
|
261
254
|
return undefined
|
|
@@ -270,7 +263,7 @@ export class Entralpi extends Device implements IEntralpi {
|
|
|
270
263
|
// Check if the device is connected
|
|
271
264
|
if (this.isConnected()) {
|
|
272
265
|
// Read software version from the Entralpi
|
|
273
|
-
return await read(
|
|
266
|
+
return await this.read("device", "pnp", 250)
|
|
274
267
|
}
|
|
275
268
|
// If device is not found, return undefined
|
|
276
269
|
return undefined
|
|
@@ -284,7 +277,7 @@ export class Entralpi extends Device implements IEntralpi {
|
|
|
284
277
|
// Check if the device is connected
|
|
285
278
|
if (this.isConnected()) {
|
|
286
279
|
// Read software version from the Entralpi
|
|
287
|
-
return await read(
|
|
280
|
+
return await this.read("device", "software", 250)
|
|
288
281
|
}
|
|
289
282
|
// If device is not found, return undefined
|
|
290
283
|
return undefined
|
|
@@ -298,7 +291,7 @@ export class Entralpi extends Device implements IEntralpi {
|
|
|
298
291
|
// Check if the device is connected
|
|
299
292
|
if (this.isConnected()) {
|
|
300
293
|
// Read system id from the device
|
|
301
|
-
return await read(
|
|
294
|
+
return await this.read("device", "system", 250)
|
|
302
295
|
}
|
|
303
296
|
// If device is not found, return undefined
|
|
304
297
|
return undefined
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Device } from "../device.model"
|
|
2
2
|
import type { IForceBoard } from "../../interfaces/device/forceboard.interface"
|
|
3
|
-
import { read } from "../../read"
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* Represents a PitchSix Force Board device
|
|
@@ -81,19 +80,19 @@ export class ForceBoard extends Device implements IForceBoard {
|
|
|
81
80
|
],
|
|
82
81
|
},
|
|
83
82
|
{
|
|
84
|
-
name: "",
|
|
85
|
-
id: "",
|
|
83
|
+
name: "Temperature Serivce",
|
|
84
|
+
id: "temperature",
|
|
86
85
|
uuid: "3a90328c-c266-4c76-b05a-6af6104a0b13",
|
|
87
86
|
characteristics: [
|
|
88
87
|
{
|
|
89
88
|
name: "Read",
|
|
90
|
-
id: "",
|
|
89
|
+
id: "level",
|
|
91
90
|
uuid: "3a90328d-c266-4c76-b05a-6af6104a0b13",
|
|
92
91
|
},
|
|
93
92
|
],
|
|
94
93
|
},
|
|
95
94
|
{
|
|
96
|
-
name: "",
|
|
95
|
+
name: "Forceboard Service",
|
|
97
96
|
id: "forceboard",
|
|
98
97
|
uuid: "9a88d67f-8df2-4afe-9e0d-c2bbbe773dd0",
|
|
99
98
|
characteristics: [
|
|
@@ -171,7 +170,7 @@ export class ForceBoard extends Device implements IForceBoard {
|
|
|
171
170
|
*/
|
|
172
171
|
battery = async (): Promise<string | undefined> => {
|
|
173
172
|
if (this.isConnected()) {
|
|
174
|
-
return await read(
|
|
173
|
+
return await this.read("battery", "level", 250)
|
|
175
174
|
}
|
|
176
175
|
// If device is not found, return undefined
|
|
177
176
|
return undefined
|
|
@@ -184,7 +183,7 @@ export class ForceBoard extends Device implements IForceBoard {
|
|
|
184
183
|
humidity = async (): Promise<string | undefined> => {
|
|
185
184
|
// Check if the device is connected
|
|
186
185
|
if (this.isConnected()) {
|
|
187
|
-
return await read(
|
|
186
|
+
return await this.read("humidity", "level", 250)
|
|
188
187
|
}
|
|
189
188
|
// If device is not found, return undefined
|
|
190
189
|
return undefined
|
|
@@ -198,7 +197,7 @@ export class ForceBoard extends Device implements IForceBoard {
|
|
|
198
197
|
// Check if the device is connected
|
|
199
198
|
if (this.isConnected()) {
|
|
200
199
|
// Read manufacturer information from the device
|
|
201
|
-
return await read(
|
|
200
|
+
return await this.read("device", "manufacturer", 250)
|
|
202
201
|
}
|
|
203
202
|
// If device is not found, return undefined
|
|
204
203
|
return undefined
|
|
@@ -1,22 +1,74 @@
|
|
|
1
1
|
import { Device } from "../device.model"
|
|
2
2
|
import type { IKilterBoard } from "../../interfaces/device/kilterboard.interface"
|
|
3
|
-
import { KilterBoardPacket, KilterBoardPlacementRoles } from "../../commands/kilterboard"
|
|
4
|
-
import { write } from "../../write"
|
|
5
3
|
|
|
6
4
|
/**
|
|
7
|
-
*
|
|
5
|
+
* For API level 2 and API level 3.
|
|
6
|
+
* The first byte in the data is dependent on where the packet is in the message as a whole.
|
|
7
|
+
* More details: https://github.com/1-max-1/fake_kilter_board
|
|
8
8
|
*/
|
|
9
|
-
export
|
|
10
|
-
|
|
9
|
+
export enum KilterBoardPacket {
|
|
10
|
+
/** If this packet is in the middle, the byte gets set to 77 (M). */
|
|
11
|
+
V2_MIDDLE = 77,
|
|
12
|
+
/** If this packet is the first packet in the message, then this byte gets set to 78 (N). */
|
|
13
|
+
V2_FIRST,
|
|
14
|
+
/** If this is the last packet in the message, this byte gets set to 79 (0). */
|
|
15
|
+
V2_LAST,
|
|
16
|
+
/** If this packet is the only packet in the message, the byte gets set to 80 (P). Note that this takes priority over the other conditions. */
|
|
17
|
+
V2_ONLY,
|
|
18
|
+
/** If this packet is in the middle, the byte gets set to 81 (Q). */
|
|
19
|
+
V3_MIDDLE,
|
|
20
|
+
/** If this packet is the first packet in the message, then this byte gets set to 82 (R). */
|
|
21
|
+
V3_FIRST,
|
|
22
|
+
/** If this is the last packet in the message, this byte gets set to 83 (S). */
|
|
23
|
+
V3_LAST,
|
|
24
|
+
/** If this packet is the only packet in the message, the byte gets set to 84 (T). Note that this takes priority over the other conditions. */
|
|
25
|
+
V3_ONLY,
|
|
26
|
+
}
|
|
11
27
|
/**
|
|
12
|
-
*
|
|
28
|
+
* Extracted from placement_roles database table.
|
|
13
29
|
*/
|
|
14
|
-
const
|
|
30
|
+
export const KilterBoardPlacementRoles = [
|
|
31
|
+
{
|
|
32
|
+
id: 12,
|
|
33
|
+
product_id: 1,
|
|
34
|
+
position: 1,
|
|
35
|
+
name: "start",
|
|
36
|
+
full_name: "Start",
|
|
37
|
+
led_color: "00FF00",
|
|
38
|
+
screen_color: "00DD00",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: 13,
|
|
42
|
+
product_id: 1,
|
|
43
|
+
position: 2,
|
|
44
|
+
name: "middle",
|
|
45
|
+
full_name: "Middle",
|
|
46
|
+
led_color: "00FFFF",
|
|
47
|
+
screen_color: "00FFFF",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: 14,
|
|
51
|
+
product_id: 1,
|
|
52
|
+
position: 3,
|
|
53
|
+
name: "finish",
|
|
54
|
+
full_name: "Finish",
|
|
55
|
+
led_color: "FF00FF",
|
|
56
|
+
screen_color: "FF00FF",
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: 15,
|
|
60
|
+
product_id: 1,
|
|
61
|
+
position: 4,
|
|
62
|
+
name: "foot",
|
|
63
|
+
full_name: "Foot Only",
|
|
64
|
+
led_color: "FFB600",
|
|
65
|
+
screen_color: "FFA500",
|
|
66
|
+
},
|
|
67
|
+
]
|
|
68
|
+
|
|
15
69
|
/**
|
|
16
|
-
*
|
|
70
|
+
* Represents climbs_placements from the Kilter Board application
|
|
17
71
|
*/
|
|
18
|
-
const MAX_BLUETOOTH_MESSAGE_SIZE = 20
|
|
19
|
-
|
|
20
72
|
class ClimbPlacement {
|
|
21
73
|
position: number
|
|
22
74
|
role_id: number
|
|
@@ -32,11 +84,38 @@ class ClimbPlacement {
|
|
|
32
84
|
* Kilter Board, Tension Board, Decoy Board, Touchstone Board, Grasshopper Board, Aurora Board, So iLL Board
|
|
33
85
|
*/
|
|
34
86
|
export class KilterBoard extends Device implements IKilterBoard {
|
|
87
|
+
/**
|
|
88
|
+
* UUID for the Aurora Climbing Advertising service.
|
|
89
|
+
* This constant is used to identify the specific Bluetooth service for Kilter Boards.
|
|
90
|
+
*
|
|
91
|
+
* @type {string}
|
|
92
|
+
*/
|
|
93
|
+
public static AuroraUUID = "4488b571-7806-4df6-bcff-a2897e4953ff"
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Maximum length of the message body for byte wrapping.
|
|
97
|
+
* This value defines the limit for the size of messages that can be sent or received
|
|
98
|
+
* to ensure proper byte wrapping in communication.
|
|
99
|
+
*
|
|
100
|
+
* @type {number}
|
|
101
|
+
* @private
|
|
102
|
+
*/
|
|
103
|
+
private MESSAGE_BODY_MAX_LENGTH = 255
|
|
104
|
+
/**
|
|
105
|
+
* Maximum length of the Bluetooth message chunk.
|
|
106
|
+
* This value sets the upper limit for the size of individual Bluetooth messages
|
|
107
|
+
* sent to and from the device to comply with Bluetooth protocol constraints.
|
|
108
|
+
*
|
|
109
|
+
* @type {number}
|
|
110
|
+
* @private
|
|
111
|
+
*/
|
|
112
|
+
private MAX_BLUETOOTH_MESSAGE_SIZE = 20
|
|
113
|
+
|
|
35
114
|
constructor() {
|
|
36
115
|
super({
|
|
37
116
|
filters: [
|
|
38
117
|
{
|
|
39
|
-
services: [AuroraUUID],
|
|
118
|
+
services: [KilterBoard.AuroraUUID],
|
|
40
119
|
},
|
|
41
120
|
],
|
|
42
121
|
services: [
|
|
@@ -79,7 +158,7 @@ export class KilterBoard extends Device implements IKilterBoard {
|
|
|
79
158
|
* @returns The wrapped byte array.
|
|
80
159
|
*/
|
|
81
160
|
wrapBytes(data: number[]) {
|
|
82
|
-
if (data.length > MESSAGE_BODY_MAX_LENGTH) {
|
|
161
|
+
if (data.length > this.MESSAGE_BODY_MAX_LENGTH) {
|
|
83
162
|
return []
|
|
84
163
|
}
|
|
85
164
|
/**
|
|
@@ -146,7 +225,7 @@ export class KilterBoard extends Device implements IKilterBoard {
|
|
|
146
225
|
let tempArray: number[] = [KilterBoardPacket.V3_MIDDLE]
|
|
147
226
|
|
|
148
227
|
for (const climbPlacement of climbPlacementList) {
|
|
149
|
-
if (tempArray.length + 3 > MESSAGE_BODY_MAX_LENGTH) {
|
|
228
|
+
if (tempArray.length + 3 > this.MESSAGE_BODY_MAX_LENGTH) {
|
|
150
229
|
resultArray.push(tempArray)
|
|
151
230
|
tempArray = [KilterBoardPacket.V3_MIDDLE]
|
|
152
231
|
}
|
|
@@ -200,13 +279,13 @@ export class KilterBoard extends Device implements IKilterBoard {
|
|
|
200
279
|
* @param buffer
|
|
201
280
|
*/
|
|
202
281
|
splitMessages = (buffer: number[]) =>
|
|
203
|
-
this.splitEvery(MAX_BLUETOOTH_MESSAGE_SIZE, buffer).map((arr) => new Uint8Array(arr))
|
|
282
|
+
this.splitEvery(this.MAX_BLUETOOTH_MESSAGE_SIZE, buffer).map((arr) => new Uint8Array(arr))
|
|
204
283
|
/**
|
|
205
284
|
* Sends a series of messages to a device.
|
|
206
285
|
*/
|
|
207
286
|
async writeMessageSeries(messages: Uint8Array[]) {
|
|
208
287
|
for (const message of messages) {
|
|
209
|
-
await write(
|
|
288
|
+
await this.write("uart", "tx", message)
|
|
210
289
|
}
|
|
211
290
|
}
|
|
212
291
|
/**
|