@hangtime/grip-connect 0.3.10 → 0.4.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 +32 -23
- package/dist/battery.d.ts +8 -3
- package/dist/battery.js +19 -7
- package/dist/calibration.js +5 -3
- package/dist/commands/kilterboard.js +1 -1
- package/dist/connect.js +4 -3
- package/dist/data/motherboard.d.ts +6 -2
- package/dist/data/motherboard.js +8 -3
- package/dist/data/progressor.d.ts +6 -2
- package/dist/data/progressor.js +10 -7
- package/dist/devices/kilterboard.d.ts +4 -0
- package/dist/devices/kilterboard.js +5 -1
- package/dist/firmware.d.ts +12 -0
- package/dist/firmware.js +37 -0
- package/dist/hardware.d.ts +11 -0
- package/dist/hardware.js +25 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +10 -4
- package/dist/is-device.d.ts +31 -0
- package/dist/is-device.js +33 -0
- package/dist/led.d.ts +7 -3
- package/dist/led.js +32 -31
- package/dist/manufacturer.d.ts +11 -0
- package/dist/manufacturer.js +25 -0
- package/dist/read.d.ts +2 -2
- package/dist/read.js +3 -5
- package/dist/serial.d.ts +11 -0
- package/dist/serial.js +30 -0
- package/dist/stop.js +5 -5
- package/dist/stream.js +8 -8
- package/dist/text.d.ts +14 -0
- package/dist/text.js +33 -0
- package/dist/write.d.ts +26 -8
- package/dist/write.js +50 -47
- package/package.json +1 -1
- package/src/battery.ts +20 -8
- package/src/calibration.ts +5 -3
- package/src/commands/kilterboard.ts +1 -1
- package/src/connect.ts +4 -3
- package/src/data/motherboard.ts +8 -3
- package/src/data/progressor.ts +10 -7
- package/src/devices/kilterboard.ts +6 -1
- package/src/firmware.ts +39 -0
- package/src/hardware.ts +27 -0
- package/src/index.ts +10 -4
- package/src/is-device.ts +43 -0
- package/src/led.ts +35 -31
- package/src/manufacturer.ts +27 -0
- package/src/read.ts +5 -7
- package/src/serial.ts +32 -0
- package/src/stop.ts +5 -5
- package/src/stream.ts +8 -8
- package/src/text.ts +35 -0
- package/src/types/download.ts +1 -1
- package/src/write.ts +57 -45
- package/dist/info.d.ts +0 -7
- package/dist/info.js +0 -30
- package/src/info.ts +0 -32
package/dist/led.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { write } from "./write";
|
|
2
2
|
import { isConnected } from "./is-connected";
|
|
3
|
-
import { KilterBoard, Motherboard } from "./devices";
|
|
4
3
|
import { KilterBoardPacket, KilterBoardPlacementRoles } from "./commands/kilterboard";
|
|
4
|
+
import { isKilterboard, isMotherboard } from "./is-device";
|
|
5
5
|
/**
|
|
6
6
|
* Maximum length of the message body for byte wrapping.
|
|
7
7
|
*/
|
|
@@ -152,44 +152,45 @@ const splitMessages = (buffer) => splitEvery(MAX_BLUETOOTH_MESSAGE_SIZE, buffer)
|
|
|
152
152
|
/**
|
|
153
153
|
* Sends a series of messages to a device.
|
|
154
154
|
*/
|
|
155
|
-
async function writeMessageSeries(messages) {
|
|
155
|
+
async function writeMessageSeries(board, messages) {
|
|
156
156
|
for (const message of messages) {
|
|
157
|
-
await write(
|
|
157
|
+
await write(board, "uart", "tx", message);
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
/**
|
|
161
161
|
* Sets the LEDs on the specified device.
|
|
162
|
+
*
|
|
163
|
+
* - For Kilter Board: Configures the LEDs based on an array of climb placements. If a configuration is provided, it prepares and sends a payload to the device.
|
|
164
|
+
* - For Motherboard: Sets the LED color based on a single color option. Defaults to turning the LEDs off if no configuration is provided.
|
|
165
|
+
*
|
|
162
166
|
* @param {Device} board - The device on which to set the LEDs.
|
|
163
|
-
* @param {ClimbPlacement[]} [
|
|
164
|
-
* @returns {Promise<number[] | undefined>} A promise that resolves with the payload array if LED settings were applied, or `undefined` if no action was taken.
|
|
167
|
+
* @param {"green" | "red" | "orange" | ClimbPlacement[]} [config] - Optional color or array of climb placements for the LEDs. Ignored if placements are provided.
|
|
168
|
+
* @returns {Promise<number[] | undefined>} A promise that resolves with the payload array for the Kilter Board if LED settings were applied, or `undefined` if no action was taken or for the Motherboard.
|
|
165
169
|
*/
|
|
166
|
-
export const led = async (board,
|
|
167
|
-
//
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if (
|
|
172
|
-
|
|
173
|
-
const payload = prepBytesV3(placement);
|
|
174
|
-
// Sends the payload to the device by splitting it into messages and writing each message.
|
|
175
|
-
if (isConnected(board)) {
|
|
176
|
-
writeMessageSeries(splitMessages(payload));
|
|
177
|
-
}
|
|
178
|
-
return payload;
|
|
170
|
+
export const led = async (board, config) => {
|
|
171
|
+
// Handle Kilterboard logic: process placements and send payload if connected
|
|
172
|
+
if (isKilterboard(board) && Array.isArray(config)) {
|
|
173
|
+
// Prepares byte arrays for transmission based on a list of climb placements.
|
|
174
|
+
const payload = prepBytesV3(config);
|
|
175
|
+
if (isConnected(board)) {
|
|
176
|
+
await writeMessageSeries(board, splitMessages(payload));
|
|
179
177
|
}
|
|
178
|
+
return payload;
|
|
180
179
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
await write(
|
|
193
|
-
await write(
|
|
180
|
+
// Handle Motherboard logic: set color if provided
|
|
181
|
+
if (isMotherboard(board)) {
|
|
182
|
+
const colorMapping = {
|
|
183
|
+
green: [[0x00], [0x01]],
|
|
184
|
+
red: [[0x01], [0x00]],
|
|
185
|
+
orange: [[0x01], [0x01]],
|
|
186
|
+
off: [[0x00], [0x00]],
|
|
187
|
+
};
|
|
188
|
+
// Default to "off" color if config is not set or not found in colorMapping
|
|
189
|
+
const color = typeof config === "string" && colorMapping[config] ? config : "off";
|
|
190
|
+
const [redValue, greenValue] = colorMapping[color];
|
|
191
|
+
await write(board, "led", "red", new Uint8Array(redValue));
|
|
192
|
+
await write(board, "led", "green", new Uint8Array(greenValue), 1250);
|
|
193
|
+
return;
|
|
194
194
|
}
|
|
195
|
+
return;
|
|
195
196
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Device } from "./types/devices";
|
|
2
|
+
/**
|
|
3
|
+
* Retrieves manufacturer information from the device.
|
|
4
|
+
* - For Motherboard devices, it reads the manufacturer information.
|
|
5
|
+
*
|
|
6
|
+
* @param {Device} board - The device from which to retrieve manufacturer information.
|
|
7
|
+
* @returns {Promise<string>} A Promise that resolves with the manufacturer information,
|
|
8
|
+
* or rejects with an error if the device is not connected.
|
|
9
|
+
* @throws {Error} Throws an error if the device is not connected.
|
|
10
|
+
*/
|
|
11
|
+
export declare const manufacturer: (board: Device) => Promise<string | undefined>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { read } from "./read";
|
|
2
|
+
import { isConnected } from "./is-connected";
|
|
3
|
+
import { isMotherboard } from "./is-device";
|
|
4
|
+
/**
|
|
5
|
+
* Retrieves manufacturer information from the device.
|
|
6
|
+
* - For Motherboard devices, it reads the manufacturer information.
|
|
7
|
+
*
|
|
8
|
+
* @param {Device} board - The device from which to retrieve manufacturer information.
|
|
9
|
+
* @returns {Promise<string>} A Promise that resolves with the manufacturer information,
|
|
10
|
+
* or rejects with an error if the device is not connected.
|
|
11
|
+
* @throws {Error} Throws an error if the device is not connected.
|
|
12
|
+
*/
|
|
13
|
+
export const manufacturer = async (board) => {
|
|
14
|
+
// Check if the device is connected
|
|
15
|
+
if (isConnected(board)) {
|
|
16
|
+
// If the device is connected and it is a Motherboard device
|
|
17
|
+
if (isMotherboard(board)) {
|
|
18
|
+
// Read manufacturer information from the Motherboard
|
|
19
|
+
return await read(board, "device", "manufacturer", 250);
|
|
20
|
+
}
|
|
21
|
+
// If device is not found, return undefined
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
throw new Error("Not connected.");
|
|
25
|
+
};
|
package/dist/read.d.ts
CHANGED
|
@@ -5,6 +5,6 @@ import type { Device } from "./types/devices";
|
|
|
5
5
|
* @param {string} serviceId - The service ID where the characteristic belongs.
|
|
6
6
|
* @param {string} characteristicId - The characteristic ID to read from.
|
|
7
7
|
* @param {number} [duration=0] - The duration to wait before resolving the promise, in milliseconds.
|
|
8
|
-
* @returns {Promise<
|
|
8
|
+
* @returns {Promise<string>} A promise that resolves when the read operation is completed.
|
|
9
9
|
*/
|
|
10
|
-
export declare const read: (board: Device, serviceId: string, characteristicId: string, duration?: number) => Promise<
|
|
10
|
+
export declare const read: (board: Device, serviceId: string, characteristicId: string, duration?: number) => Promise<string>;
|
package/dist/read.js
CHANGED
|
@@ -6,7 +6,7 @@ import { isConnected } from "./is-connected";
|
|
|
6
6
|
* @param {string} serviceId - The service ID where the characteristic belongs.
|
|
7
7
|
* @param {string} characteristicId - The characteristic ID to read from.
|
|
8
8
|
* @param {number} [duration=0] - The duration to wait before resolving the promise, in milliseconds.
|
|
9
|
-
* @returns {Promise<
|
|
9
|
+
* @returns {Promise<string>} A promise that resolves when the read operation is completed.
|
|
10
10
|
*/
|
|
11
11
|
export const read = (board, serviceId, characteristicId, duration = 0) => {
|
|
12
12
|
return new Promise((resolve, reject) => {
|
|
@@ -21,17 +21,15 @@ export const read = (board, serviceId, characteristicId, duration = 0) => {
|
|
|
21
21
|
switch (characteristicId) {
|
|
22
22
|
case "level":
|
|
23
23
|
// TODO: This is Motherboard specific.
|
|
24
|
-
decodedValue = value.getUint8(0);
|
|
24
|
+
decodedValue = value.getUint8(0).toString();
|
|
25
25
|
break;
|
|
26
26
|
default:
|
|
27
27
|
decodedValue = decoder.decode(value);
|
|
28
28
|
break;
|
|
29
29
|
}
|
|
30
|
-
// TODO: Create Read callback
|
|
31
|
-
console.log(decodedValue);
|
|
32
30
|
// Resolve after specified duration
|
|
33
31
|
setTimeout(() => {
|
|
34
|
-
resolve();
|
|
32
|
+
return resolve(decodedValue);
|
|
35
33
|
}, duration);
|
|
36
34
|
})
|
|
37
35
|
.catch((error) => {
|
package/dist/serial.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Device } from "./types/devices";
|
|
2
|
+
/**
|
|
3
|
+
* Retrieves serial number from the device.
|
|
4
|
+
* - For Motherboard devices, it reads the serial number.
|
|
5
|
+
*
|
|
6
|
+
* @param {Device} board - The device from which to retrieve serial number.
|
|
7
|
+
* @returns {Promise<string>} A Promise that resolves with the serial number,
|
|
8
|
+
* or rejects with an error if the device is not connected.
|
|
9
|
+
* @throws {Error} Throws an error if the device is not connected.
|
|
10
|
+
*/
|
|
11
|
+
export declare const serial: (board: Device) => Promise<string | undefined>;
|
package/dist/serial.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { write } from "./write";
|
|
2
|
+
import { isConnected } from "./is-connected";
|
|
3
|
+
import { MotherboardCommands } from "./commands";
|
|
4
|
+
import { isMotherboard } from "./is-device";
|
|
5
|
+
/**
|
|
6
|
+
* Retrieves serial number from the device.
|
|
7
|
+
* - For Motherboard devices, it reads the serial number.
|
|
8
|
+
*
|
|
9
|
+
* @param {Device} board - The device from which to retrieve serial number.
|
|
10
|
+
* @returns {Promise<string>} A Promise that resolves with the serial number,
|
|
11
|
+
* or rejects with an error if the device is not connected.
|
|
12
|
+
* @throws {Error} Throws an error if the device is not connected.
|
|
13
|
+
*/
|
|
14
|
+
export const serial = async (board) => {
|
|
15
|
+
// Check if the device is connected
|
|
16
|
+
if (isConnected(board)) {
|
|
17
|
+
// If the device is connected and it is a Motherboard device
|
|
18
|
+
if (isMotherboard(board)) {
|
|
19
|
+
// Write serial number command to the Motherboard and read output
|
|
20
|
+
let response = undefined;
|
|
21
|
+
await write(board, "uart", "tx", MotherboardCommands.GET_SERIAL, 250, (data) => {
|
|
22
|
+
response = data;
|
|
23
|
+
});
|
|
24
|
+
return response;
|
|
25
|
+
}
|
|
26
|
+
// If device is not found, return undefined
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
throw new Error("Not connected.");
|
|
30
|
+
};
|
package/dist/stop.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { write } from "./write";
|
|
2
2
|
import { isConnected } from "./is-connected";
|
|
3
|
-
import { Motherboard, Progressor } from "./devices";
|
|
4
3
|
import { MotherboardCommands, ProgressorCommands } from "./commands";
|
|
4
|
+
import { isMotherboard, isProgressor } from "./is-device";
|
|
5
5
|
/**
|
|
6
6
|
* Stops the data stream on the specified device.
|
|
7
7
|
* @param {Device} board - The device to stop the stream on.
|
|
@@ -9,13 +9,13 @@ import { MotherboardCommands, ProgressorCommands } from "./commands";
|
|
|
9
9
|
*/
|
|
10
10
|
export const stop = async (board) => {
|
|
11
11
|
if (isConnected(board)) {
|
|
12
|
-
if (board
|
|
12
|
+
if (isMotherboard(board)) {
|
|
13
13
|
// Stop stream on Motherboard
|
|
14
|
-
await write(
|
|
14
|
+
await write(board, "uart", "tx", MotherboardCommands.STOP_WEIGHT_MEAS, 0);
|
|
15
15
|
}
|
|
16
|
-
if (board
|
|
16
|
+
if (isProgressor(board)) {
|
|
17
17
|
// Stop stream on Progressor
|
|
18
|
-
await write(
|
|
18
|
+
await write(board, "progressor", "tx", ProgressorCommands.STOP_WEIGHT_MEAS, 0);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
};
|
package/dist/stream.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isConnected } from "./is-connected";
|
|
2
2
|
import { write } from "./write";
|
|
3
3
|
import { stop } from "./stop";
|
|
4
|
-
import {
|
|
4
|
+
import { isMotherboard, isProgressor } from "./is-device";
|
|
5
5
|
import { MotherboardCommands, ProgressorCommands } from "./commands";
|
|
6
6
|
import { emptyDownloadPackets } from "./download";
|
|
7
7
|
import { CALIBRATION } from "./data/motherboard";
|
|
@@ -17,24 +17,24 @@ export const stream = async (board, duration = 0) => {
|
|
|
17
17
|
// Reset download packets
|
|
18
18
|
emptyDownloadPackets();
|
|
19
19
|
// Device specific logic
|
|
20
|
-
if (board
|
|
20
|
+
if (isMotherboard(board)) {
|
|
21
21
|
// Read calibration data if not already available
|
|
22
22
|
if (!CALIBRATION[0].length) {
|
|
23
|
-
await calibration(
|
|
23
|
+
await calibration(board);
|
|
24
24
|
}
|
|
25
25
|
// Start streaming data
|
|
26
|
-
await write(
|
|
26
|
+
await write(board, "uart", "tx", MotherboardCommands.START_WEIGHT_MEAS, duration);
|
|
27
27
|
// Stop streaming if duration is set
|
|
28
28
|
if (duration !== 0) {
|
|
29
|
-
await stop(
|
|
29
|
+
await stop(board);
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
if (board
|
|
32
|
+
if (isProgressor(board)) {
|
|
33
33
|
// Start streaming data
|
|
34
|
-
await write(
|
|
34
|
+
await write(board, "progressor", "tx", ProgressorCommands.START_WEIGHT_MEAS, duration);
|
|
35
35
|
// Stop streaming if duration is set
|
|
36
36
|
if (duration !== 0) {
|
|
37
|
-
await stop(
|
|
37
|
+
await stop(board);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
}
|
package/dist/text.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Device } from "./types/devices";
|
|
2
|
+
/**
|
|
3
|
+
* Retrieves the entire 320 bytes of non-volatile memory from the device.
|
|
4
|
+
*
|
|
5
|
+
* The memory consists of 10 segments, each 32 bytes long. If any segment was previously written,
|
|
6
|
+
* the corresponding data will appear in the response. Unused portions of the memory are
|
|
7
|
+
* padded with whitespace.
|
|
8
|
+
*
|
|
9
|
+
* @param {Device} board - The device from which to retrieve text information.
|
|
10
|
+
* @returns {Promise<string>} A Promise that resolves with the 320-byte memory content as a string,
|
|
11
|
+
* which includes both the written data and any unused, whitespace-padded segments.
|
|
12
|
+
* @throws {Error} Throws an error if the device is not connected.
|
|
13
|
+
*/
|
|
14
|
+
export declare const text: (board: Device) => Promise<string | undefined>;
|
package/dist/text.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { write } from "./write";
|
|
2
|
+
import { isConnected } from "./is-connected";
|
|
3
|
+
import { isMotherboard } from "./is-device";
|
|
4
|
+
import { MotherboardCommands } from "./commands";
|
|
5
|
+
/**
|
|
6
|
+
* Retrieves the entire 320 bytes of non-volatile memory from the device.
|
|
7
|
+
*
|
|
8
|
+
* The memory consists of 10 segments, each 32 bytes long. If any segment was previously written,
|
|
9
|
+
* the corresponding data will appear in the response. Unused portions of the memory are
|
|
10
|
+
* padded with whitespace.
|
|
11
|
+
*
|
|
12
|
+
* @param {Device} board - The device from which to retrieve text information.
|
|
13
|
+
* @returns {Promise<string>} A Promise that resolves with the 320-byte memory content as a string,
|
|
14
|
+
* which includes both the written data and any unused, whitespace-padded segments.
|
|
15
|
+
* @throws {Error} Throws an error if the device is not connected.
|
|
16
|
+
*/
|
|
17
|
+
export const text = async (board) => {
|
|
18
|
+
// Check if the device is connected
|
|
19
|
+
if (isConnected(board)) {
|
|
20
|
+
// If the device is connected and it is a Motherboard device
|
|
21
|
+
if (isMotherboard(board)) {
|
|
22
|
+
// Write text information command to the Motherboard and read output
|
|
23
|
+
let response = undefined;
|
|
24
|
+
await write(board, "uart", "tx", MotherboardCommands.GET_TEXT, 250, (data) => {
|
|
25
|
+
response = data;
|
|
26
|
+
});
|
|
27
|
+
return response;
|
|
28
|
+
}
|
|
29
|
+
// If device is not found, return undefined
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
throw new Error("Not connected.");
|
|
33
|
+
};
|
package/dist/write.d.ts
CHANGED
|
@@ -4,13 +4,31 @@ import type { Device } from "./types/devices";
|
|
|
4
4
|
* @type {string | Uint8Array | null}
|
|
5
5
|
*/
|
|
6
6
|
export declare let lastWrite: string | Uint8Array | null;
|
|
7
|
+
/** Define the type for the callback function */
|
|
8
|
+
type WriteCallback = (data: string) => void;
|
|
7
9
|
/**
|
|
8
|
-
*
|
|
9
|
-
* @param {Device} board - The device board to write to.
|
|
10
|
-
* @param {string} serviceId - The service ID where the characteristic belongs.
|
|
11
|
-
* @param {string} characteristicId - The characteristic ID to write to.
|
|
12
|
-
* @param {string | Uint8Array | undefined} message - The message to write.
|
|
13
|
-
* @param {number} [duration=0] - The duration to wait before resolving the promise, in milliseconds.
|
|
14
|
-
* @returns {Promise<void>} A promise that resolves when the write operation is completed.
|
|
10
|
+
* A default write callback that logs the response
|
|
15
11
|
*/
|
|
16
|
-
export declare
|
|
12
|
+
export declare let writeCallback: WriteCallback;
|
|
13
|
+
/**
|
|
14
|
+
* Writes a message to the specified characteristic of a Bluetooth device and optionally provides a callback to handle responses.
|
|
15
|
+
*
|
|
16
|
+
* @param {Device} board - The Bluetooth device to which the message will be written.
|
|
17
|
+
* @param {string} serviceId - The service UUID of the Bluetooth device containing the target characteristic.
|
|
18
|
+
* @param {string} characteristicId - The characteristic UUID where the message will be written.
|
|
19
|
+
* @param {string | Uint8Array | undefined} message - The message to be written to the characteristic. It can be a string or a Uint8Array.
|
|
20
|
+
* @param {number} [duration=0] - Optional. The time in milliseconds to wait before resolving the promise. Defaults to 0 for immediate resolution.
|
|
21
|
+
* @param {WriteCallback} [callback=writeCallback] - Optional. A custom callback to handle the response after the write operation is successful.
|
|
22
|
+
*
|
|
23
|
+
* @returns {Promise<void>} A promise that resolves once the write operation is complete.
|
|
24
|
+
*
|
|
25
|
+
* @throws {Error} Throws an error if the characteristic is undefined or if the device is not connected.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* // Example usage of the write function with a custom callback
|
|
29
|
+
* await write(device, "serviceId", "characteristicId", "Hello World", 250, (data) => {
|
|
30
|
+
* console.log(`Custom response: ${data}`);
|
|
31
|
+
* });
|
|
32
|
+
*/
|
|
33
|
+
export declare const write: (board: Device, serviceId: string, characteristicId: string, message: string | Uint8Array | undefined, duration?: number, callback?: WriteCallback) => Promise<void>;
|
|
34
|
+
export {};
|
package/dist/write.js
CHANGED
|
@@ -6,52 +6,55 @@ import { getCharacteristic } from "./characteristic";
|
|
|
6
6
|
*/
|
|
7
7
|
export let lastWrite = null;
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
* @param {Device} board - The device board to write to.
|
|
11
|
-
* @param {string} serviceId - The service ID where the characteristic belongs.
|
|
12
|
-
* @param {string} characteristicId - The characteristic ID to write to.
|
|
13
|
-
* @param {string | Uint8Array | undefined} message - The message to write.
|
|
14
|
-
* @param {number} [duration=0] - The duration to wait before resolving the promise, in milliseconds.
|
|
15
|
-
* @returns {Promise<void>} A promise that resolves when the write operation is completed.
|
|
9
|
+
* A default write callback that logs the response
|
|
16
10
|
*/
|
|
17
|
-
export
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
11
|
+
export let writeCallback = (data) => {
|
|
12
|
+
console.log(data);
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Writes a message to the specified characteristic of a Bluetooth device and optionally provides a callback to handle responses.
|
|
16
|
+
*
|
|
17
|
+
* @param {Device} board - The Bluetooth device to which the message will be written.
|
|
18
|
+
* @param {string} serviceId - The service UUID of the Bluetooth device containing the target characteristic.
|
|
19
|
+
* @param {string} characteristicId - The characteristic UUID where the message will be written.
|
|
20
|
+
* @param {string | Uint8Array | undefined} message - The message to be written to the characteristic. It can be a string or a Uint8Array.
|
|
21
|
+
* @param {number} [duration=0] - Optional. The time in milliseconds to wait before resolving the promise. Defaults to 0 for immediate resolution.
|
|
22
|
+
* @param {WriteCallback} [callback=writeCallback] - Optional. A custom callback to handle the response after the write operation is successful.
|
|
23
|
+
*
|
|
24
|
+
* @returns {Promise<void>} A promise that resolves once the write operation is complete.
|
|
25
|
+
*
|
|
26
|
+
* @throws {Error} Throws an error if the characteristic is undefined or if the device is not connected.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* // Example usage of the write function with a custom callback
|
|
30
|
+
* await write(device, "serviceId", "characteristicId", "Hello World", 250, (data) => {
|
|
31
|
+
* console.log(`Custom response: ${data}`);
|
|
32
|
+
* });
|
|
33
|
+
*/
|
|
34
|
+
export const write = async (board, serviceId, characteristicId, message, duration = 0, callback = writeCallback) => {
|
|
35
|
+
if (!isConnected(board)) {
|
|
36
|
+
throw new Error("Device is not connected");
|
|
37
|
+
}
|
|
38
|
+
// Check if message is provided
|
|
39
|
+
if (message === undefined) {
|
|
40
|
+
// If not provided, return without performing write operation
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
// Get the characteristic from the device using serviceId and characteristicId
|
|
44
|
+
const characteristic = getCharacteristic(board, serviceId, characteristicId);
|
|
45
|
+
if (!characteristic) {
|
|
46
|
+
throw new Error("Characteristic is undefined");
|
|
47
|
+
}
|
|
48
|
+
// Convert the message to Uint8Array if it's a string
|
|
49
|
+
const valueToWrite = typeof message === "string" ? new TextEncoder().encode(message) : message;
|
|
50
|
+
// Write the value to the characteristic
|
|
51
|
+
await characteristic.writeValue(valueToWrite);
|
|
52
|
+
// Update the last written message
|
|
53
|
+
lastWrite = message;
|
|
54
|
+
// Assign the provided callback to `writeCallback`
|
|
55
|
+
writeCallback = callback;
|
|
56
|
+
// If a duration is specified, resolve the promise after the duration
|
|
57
|
+
if (duration > 0) {
|
|
58
|
+
await new Promise((resolve) => setTimeout(resolve, duration));
|
|
59
|
+
}
|
|
57
60
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hangtime/grip-connect",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "A client that can establish connections with various Force-Sensing Hangboards/Plates used by climbers for strength measurement. Examples of such hangboards include the Griptonite Motherboard, Climbro, SmartBoard, Entralpi or Tindeq Progressor",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
package/src/battery.ts
CHANGED
|
@@ -2,26 +2,38 @@ import type { Device } from "./types/devices"
|
|
|
2
2
|
import { write } from "./write"
|
|
3
3
|
import { read } from "./read"
|
|
4
4
|
import { isConnected } from "./is-connected"
|
|
5
|
-
import {
|
|
5
|
+
import { isMotherboard, isProgressor } from "./is-device"
|
|
6
6
|
import { ProgressorCommands } from "./commands"
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Retrieves battery or voltage information from the device.
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* - For Motherboard devices, it reads the battery level.
|
|
11
|
+
* - For Progressor devices, it sends a command to retrieve battery voltage information.
|
|
12
|
+
*
|
|
13
|
+
* @param {Device} board - The device from which to retrieve battery information.
|
|
14
|
+
* @returns {Promise<string | undefined>} A Promise that resolves with the battery or voltage information,
|
|
15
|
+
* or rejects with an error if the device is not connected.
|
|
16
|
+
* @throws {Error} Throws an error if the device is not connected.
|
|
12
17
|
*/
|
|
13
|
-
export const battery = async (board: Device): Promise<
|
|
18
|
+
export const battery = async (board: Device): Promise<string | undefined> => {
|
|
14
19
|
// Check if the device is connected
|
|
15
20
|
if (isConnected(board)) {
|
|
16
21
|
// If the device is connected and it is a Motherboard device
|
|
17
|
-
if (board
|
|
22
|
+
if (isMotherboard(board)) {
|
|
18
23
|
// Read battery level information from the Motherboard
|
|
19
|
-
await read(
|
|
24
|
+
return await read(board, "battery", "level", 250)
|
|
20
25
|
}
|
|
21
26
|
// If the device is connected and its name starts with "Progressor"
|
|
22
|
-
if (board
|
|
27
|
+
if (isProgressor(board)) {
|
|
23
28
|
// Write command to get battery voltage information to the Progressor
|
|
24
|
-
|
|
29
|
+
let response: string | undefined = undefined
|
|
30
|
+
await write(board, "progressor", "tx", ProgressorCommands.GET_BATT_VLTG, 250, (data) => {
|
|
31
|
+
response = data
|
|
32
|
+
})
|
|
33
|
+
return response
|
|
25
34
|
}
|
|
35
|
+
// If device is not found, return undefined
|
|
36
|
+
return
|
|
26
37
|
}
|
|
38
|
+
throw new Error("Not connected.")
|
|
27
39
|
}
|
package/src/calibration.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Device } from "./types/devices"
|
|
2
2
|
import { isConnected } from "./is-connected"
|
|
3
3
|
import { write } from "./write"
|
|
4
|
-
import {
|
|
4
|
+
import { isMotherboard } from "./is-device"
|
|
5
5
|
import { MotherboardCommands } from "./commands"
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -13,9 +13,11 @@ export const calibration = async (board: Device): Promise<void> => {
|
|
|
13
13
|
// Check if the device is connected
|
|
14
14
|
if (isConnected(board)) {
|
|
15
15
|
// If the device is connected, and it is a Motherboard device
|
|
16
|
-
if (board
|
|
16
|
+
if (isMotherboard(board)) {
|
|
17
17
|
// Write the command to get calibration data to the device
|
|
18
|
-
await write(
|
|
18
|
+
await write(board, "uart", "tx", MotherboardCommands.GET_CALIBRATION, 2500, (data) => {
|
|
19
|
+
console.log(data)
|
|
20
|
+
})
|
|
19
21
|
}
|
|
20
22
|
}
|
|
21
23
|
}
|
package/src/connect.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Device } from "./types/devices"
|
|
2
2
|
import { handleEntralpiData, handleMotherboardData, handleProgressorData, handleWHC06Data } from "./data"
|
|
3
|
+
import { isEntralpi, isMotherboard, isProgressor } from "./is-device"
|
|
3
4
|
|
|
4
5
|
let server: BluetoothRemoteGATTServer
|
|
5
6
|
const receiveBuffer: number[] = []
|
|
@@ -25,7 +26,7 @@ const handleNotifications = (event: Event, board: Device): void => {
|
|
|
25
26
|
|
|
26
27
|
if (value) {
|
|
27
28
|
// If the device is connected and it is a Motherboard device
|
|
28
|
-
if (board
|
|
29
|
+
if (isMotherboard(board)) {
|
|
29
30
|
for (let i = 0; i < value.byteLength; i++) {
|
|
30
31
|
receiveBuffer.push(value.getUint8(i))
|
|
31
32
|
}
|
|
@@ -38,14 +39,14 @@ const handleNotifications = (event: Event, board: Device): void => {
|
|
|
38
39
|
const receivedData: string = decoder.decode(new Uint8Array(line))
|
|
39
40
|
handleMotherboardData(receivedData)
|
|
40
41
|
}
|
|
41
|
-
} else if (board
|
|
42
|
+
} else if (isEntralpi(board)) {
|
|
42
43
|
if (value.buffer) {
|
|
43
44
|
const buffer: ArrayBuffer = value.buffer
|
|
44
45
|
const rawData: DataView = new DataView(buffer)
|
|
45
46
|
const receivedData: string = (rawData.getUint16(0) / 100).toFixed(1)
|
|
46
47
|
handleEntralpiData(receivedData)
|
|
47
48
|
}
|
|
48
|
-
} else if (board
|
|
49
|
+
} else if (isProgressor(board)) {
|
|
49
50
|
if (value.buffer) {
|
|
50
51
|
const buffer: ArrayBuffer = value.buffer
|
|
51
52
|
const rawData: DataView = new DataView(buffer)
|
package/src/data/motherboard.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { notifyCallback } from "./../notify"
|
|
2
|
+
import { writeCallback } from "./../write"
|
|
2
3
|
import { applyTare } from "./../tare"
|
|
3
4
|
import { MotherboardCommands } from "./../commands"
|
|
4
5
|
import { checkActivity } from "./../is-active"
|
|
@@ -57,8 +58,12 @@ const applyCalibration = (sample: number, calibration: number[][]): number => {
|
|
|
57
58
|
return sign * final
|
|
58
59
|
}
|
|
59
60
|
/**
|
|
60
|
-
* Handles data received from the Motherboard device.
|
|
61
|
-
*
|
|
61
|
+
* Handles data received from the Motherboard device. Processes hex-encoded streaming packets
|
|
62
|
+
* to extract samples, calibrate masses, and update running averages of mass data.
|
|
63
|
+
* If the received data is not a valid hex packet, it returns the unprocessed data.
|
|
64
|
+
*
|
|
65
|
+
* @param {string} receivedData - The raw data received from the Motherboard device.
|
|
66
|
+
* @returns {void}
|
|
62
67
|
*/
|
|
63
68
|
export const handleMotherboardData = (receivedData: string): void => {
|
|
64
69
|
const receivedTime: number = Date.now()
|
|
@@ -153,6 +158,6 @@ export const handleMotherboardData = (receivedData: string): void => {
|
|
|
153
158
|
}
|
|
154
159
|
} else {
|
|
155
160
|
// unhandled data
|
|
156
|
-
|
|
161
|
+
writeCallback(receivedData)
|
|
157
162
|
}
|
|
158
163
|
}
|