@hangtime/grip-connect 0.0.9 → 0.0.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hangtime/grip-connect",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
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 Motherboard, Climbro, SmartBoard, Entralpi or Tindeq Progressor",
5
5
  "main": "src/index.ts",
6
6
  "scripts": {
package/src/connect.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { notifyCallback } from "./notify";
2
2
  import { handleMotherboardData } from "./devices/moterboard";
3
+ import { handleEntralpiData } from "./devices/entralpi";
3
4
  let server;
4
5
  const receiveBuffer = [];
5
6
  /**
@@ -22,27 +23,22 @@ const handleNotifications = (event, board) => {
22
23
  const value = characteristic.value;
23
24
  if (value) {
24
25
  if (board.name === "Motherboard") {
25
- if (value) {
26
- for (let i = 0; i < value.byteLength; i++) {
27
- receiveBuffer.push(value.getUint8(i));
28
- }
29
- let idx;
30
- while ((idx = receiveBuffer.indexOf(10)) >= 0) {
31
- const line = receiveBuffer.splice(0, idx + 1).slice(0, -1); // Combine and remove LF
32
- if (line.length > 0 && line[line.length - 1] === 13)
33
- line.pop(); // Remove CR
34
- const decoder = new TextDecoder("utf-8");
35
- const receivedString = decoder.decode(new Uint8Array(line));
36
- handleMotherboardData(characteristic.uuid, receivedString);
37
- }
26
+ for (let i = 0; i < value.byteLength; i++) {
27
+ receiveBuffer.push(value.getUint8(i));
28
+ }
29
+ let idx;
30
+ while ((idx = receiveBuffer.indexOf(10)) >= 0) {
31
+ const line = receiveBuffer.splice(0, idx + 1).slice(0, -1); // Combine and remove LF
32
+ if (line.length > 0 && line[line.length - 1] === 13)
33
+ line.pop(); // Remove CR
34
+ const decoder = new TextDecoder("utf-8");
35
+ const receivedData = decoder.decode(new Uint8Array(line));
36
+ handleMotherboardData(characteristic.uuid, receivedData);
38
37
  }
39
38
  }
40
39
  else if (board.name === "ENTRALPI") {
41
- // TODO: handle Entralpi notify
42
- // characteristic.value!.getInt16(0) / 100;
43
- if (notifyCallback) {
44
- notifyCallback({ uuid: characteristic.uuid, value: value });
45
- }
40
+ const receivedData = value.getInt16(0) / 100;
41
+ handleEntralpiData(characteristic.uuid, receivedData);
46
42
  }
47
43
  else if (board.name === "Tindeq") {
48
44
  // TODO: handle Tindeq notify
package/src/connect.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Device } from "./devices/types"
2
2
  import { notifyCallback } from "./notify"
3
3
  import { handleMotherboardData } from "./devices/moterboard"
4
+ import { handleEntralpiData } from "./devices/entralpi"
4
5
 
5
6
  let server: BluetoothRemoteGATTServer
6
7
  const receiveBuffer: number[] = []
@@ -25,26 +26,21 @@ const handleNotifications = (event: Event, board: Device): void => {
25
26
  const value = characteristic.value
26
27
  if (value) {
27
28
  if (board.name === "Motherboard") {
28
- if (value) {
29
- for (let i = 0; i < value.byteLength; i++) {
30
- receiveBuffer.push(value.getUint8(i))
31
- }
29
+ for (let i = 0; i < value.byteLength; i++) {
30
+ receiveBuffer.push(value.getUint8(i))
31
+ }
32
32
 
33
- let idx: number
34
- while ((idx = receiveBuffer.indexOf(10)) >= 0) {
35
- const line = receiveBuffer.splice(0, idx + 1).slice(0, -1) // Combine and remove LF
36
- if (line.length > 0 && line[line.length - 1] === 13) line.pop() // Remove CR
37
- const decoder = new TextDecoder("utf-8")
38
- const receivedString = decoder.decode(new Uint8Array(line))
39
- handleMotherboardData(characteristic.uuid, receivedString)
40
- }
33
+ let idx: number
34
+ while ((idx = receiveBuffer.indexOf(10)) >= 0) {
35
+ const line = receiveBuffer.splice(0, idx + 1).slice(0, -1) // Combine and remove LF
36
+ if (line.length > 0 && line[line.length - 1] === 13) line.pop() // Remove CR
37
+ const decoder = new TextDecoder("utf-8")
38
+ const receivedData = decoder.decode(new Uint8Array(line))
39
+ handleMotherboardData(characteristic.uuid, receivedData)
41
40
  }
42
41
  } else if (board.name === "ENTRALPI") {
43
- // TODO: handle Entralpi notify
44
- // characteristic.value!.getInt16(0) / 100;
45
- if (notifyCallback) {
46
- notifyCallback({ uuid: characteristic.uuid, value: value })
47
- }
42
+ const receivedData: number = value.getInt16(0) / 100
43
+ handleEntralpiData(characteristic.uuid, receivedData)
48
44
  } else if (board.name === "Tindeq") {
49
45
  // TODO: handle Tindeq notify
50
46
  } else {
@@ -1,2 +1,8 @@
1
1
  import { Device } from "./types";
2
2
  export declare const Entralpi: Device;
3
+ /**
4
+ * handleEntralpiData
5
+ * @param uuid - Unique identifier
6
+ * @param receivedData - Received data string
7
+ */
8
+ export declare function handleEntralpiData(uuid: string, receivedData: number): void;
@@ -1,3 +1,4 @@
1
+ import { notifyCallback } from "../notify";
1
2
  export const Entralpi = {
2
3
  name: "ENTRALPI",
3
4
  services: [
@@ -50,3 +51,16 @@ export const Entralpi = {
50
51
  },
51
52
  ],
52
53
  };
54
+ /**
55
+ * handleEntralpiData
56
+ * @param uuid - Unique identifier
57
+ * @param receivedData - Received data string
58
+ */
59
+ export function handleEntralpiData(uuid, receivedData) {
60
+ notifyCallback({
61
+ uuid,
62
+ value: {
63
+ massTotal: receivedData,
64
+ },
65
+ });
66
+ }
@@ -1,4 +1,5 @@
1
1
  import { Device } from "./types"
2
+ import { notifyCallback } from "../notify"
2
3
 
3
4
  export const Entralpi: Device = {
4
5
  name: "ENTRALPI",
@@ -52,3 +53,17 @@ export const Entralpi: Device = {
52
53
  },
53
54
  ],
54
55
  }
56
+
57
+ /**
58
+ * handleEntralpiData
59
+ * @param uuid - Unique identifier
60
+ * @param receivedData - Received data string
61
+ */
62
+ export function handleEntralpiData(uuid: string, receivedData: number): void {
63
+ notifyCallback({
64
+ uuid,
65
+ value: {
66
+ massTotal: receivedData,
67
+ },
68
+ })
69
+ }
@@ -3,6 +3,6 @@ export declare const Motherboard: Device;
3
3
  /**
4
4
  * handleMotherboardData
5
5
  * @param uuid - Unique identifier
6
- * @param receivedString - Received data string
6
+ * @param receivedData - Received data string
7
7
  */
8
- export declare function handleMotherboardData(uuid: string, receivedString: string): void;
8
+ export declare function handleMotherboardData(uuid: string, receivedData: string): void;
@@ -110,7 +110,8 @@ const applyCalibration = (sample, calibration) => {
110
110
  // Interpolate to get the calibrated value within the range
111
111
  final =
112
112
  calibration[i - 1][1] +
113
- ((sample - calibrationStart) / (calibrationEnd - calibrationStart)) * (calibration[i][1] - calibration[i - 1][1]);
113
+ ((sample - calibrationStart) / (calibrationEnd - calibrationStart)) *
114
+ (calibration[i][1] - calibration[i - 1][1]);
114
115
  break;
115
116
  }
116
117
  }
@@ -120,16 +121,16 @@ const applyCalibration = (sample, calibration) => {
120
121
  /**
121
122
  * handleMotherboardData
122
123
  * @param uuid - Unique identifier
123
- * @param receivedString - Received data string
124
+ * @param receivedData - Received data string
124
125
  */
125
- export function handleMotherboardData(uuid, receivedString) {
126
+ export function handleMotherboardData(uuid, receivedData) {
126
127
  const receivedTime = Date.now();
127
128
  // Check if the line is entirely hex characters
128
- const isAllHex = /^[0-9A-Fa-f]+$/g.test(receivedString);
129
+ const isAllHex = /^[0-9A-Fa-f]+$/g.test(receivedData);
129
130
  // Handle streaming packet
130
- if (isAllHex && receivedString.length === PACKET_LENGTH) {
131
+ if (isAllHex && receivedData.length === PACKET_LENGTH) {
131
132
  // Base-16 decode the string: convert hex pairs to byte values
132
- const bytes = Array.from({ length: receivedString.length / 2 }, (_, i) => Number(`0x${receivedString.substring(i * 2, i * 2 + 2)}`));
133
+ const bytes = Array.from({ length: receivedData.length / 2 }, (_, i) => Number(`0x${receivedData.substring(i * 2, i * 2 + 2)}`));
133
134
  // Translate header into packet, number of samples from the packet length
134
135
  const packet = {
135
136
  received: receivedTime,
@@ -168,15 +169,15 @@ export function handleMotherboardData(uuid, receivedString) {
168
169
  },
169
170
  });
170
171
  }
171
- else if ((receivedString.match(/,/g) || []).length === 3) {
172
- console.log(receivedString);
172
+ else if ((receivedData.match(/,/g) || []).length === 3) {
173
+ console.log(receivedData);
173
174
  // if the returned notification is a calibration string add them to the array
174
- const parts = receivedString.split(",");
175
+ const parts = receivedData.split(",");
175
176
  const numericParts = parts.map((x) => parseFloat(x));
176
177
  CALIBRATION[numericParts[0]].push(numericParts.slice(1));
177
178
  }
178
179
  else {
179
180
  // unhanded data
180
- console.log(receivedString);
181
+ console.log(receivedData);
181
182
  }
182
183
  }
@@ -91,40 +91,41 @@ export const Motherboard: Device = {
91
91
  */
92
92
  const applyCalibration = (sample: number, calibration: number[][]): number => {
93
93
  // Extract the calibrated value for the zero point
94
- const zeroCalibration: number = calibration[0][2];
94
+ const zeroCalibration: number = calibration[0][2]
95
95
 
96
96
  // Initialize sign as positive
97
- let sign: number = 1;
97
+ let sign: number = 1
98
98
 
99
99
  // Initialize the final calibrated value
100
- let final: number = 0;
100
+ let final: number = 0
101
101
 
102
102
  // If the sample value is less than the zero calibration point
103
103
  if (sample < zeroCalibration) {
104
104
  // Change the sign to negative
105
- sign = -1;
105
+ sign = -1
106
106
 
107
107
  // Reflect the sample around the zero calibration point
108
- sample = 2 * zeroCalibration - sample;
108
+ sample = 2 * zeroCalibration - sample
109
109
  }
110
110
 
111
111
  // Iterate through the calibration data
112
112
  for (let i = 1; i < calibration.length; i++) {
113
113
  // Extract the lower and upper bounds of the current calibration range
114
- const calibrationStart: number = calibration[i - 1][2];
115
- const calibrationEnd: number = calibration[i][2];
114
+ const calibrationStart: number = calibration[i - 1][2]
115
+ const calibrationEnd: number = calibration[i][2]
116
116
 
117
117
  // If the sample value is within the current calibration range
118
118
  if (sample < calibrationEnd) {
119
119
  // Interpolate to get the calibrated value within the range
120
120
  final =
121
121
  calibration[i - 1][1] +
122
- ((sample - calibrationStart) / (calibrationEnd - calibrationStart)) * (calibration[i][1] - calibration[i - 1][1]);
123
- break;
122
+ ((sample - calibrationStart) / (calibrationEnd - calibrationStart)) *
123
+ (calibration[i][1] - calibration[i - 1][1])
124
+ break
124
125
  }
125
126
  }
126
127
  // Return the calibrated value with the appropriate sign (positive/negative)
127
- return sign * final;
128
+ return sign * final
128
129
  }
129
130
 
130
131
  interface Packet {
@@ -138,19 +139,19 @@ interface Packet {
138
139
  /**
139
140
  * handleMotherboardData
140
141
  * @param uuid - Unique identifier
141
- * @param receivedString - Received data string
142
+ * @param receivedData - Received data string
142
143
  */
143
- export function handleMotherboardData(uuid: string, receivedString: string): void {
144
+ export function handleMotherboardData(uuid: string, receivedData: string): void {
144
145
  const receivedTime: number = Date.now()
145
146
 
146
147
  // Check if the line is entirely hex characters
147
- const isAllHex: boolean = /^[0-9A-Fa-f]+$/g.test(receivedString);
148
+ const isAllHex: boolean = /^[0-9A-Fa-f]+$/g.test(receivedData)
148
149
 
149
150
  // Handle streaming packet
150
- if (isAllHex && receivedString.length === PACKET_LENGTH) {
151
+ if (isAllHex && receivedData.length === PACKET_LENGTH) {
151
152
  // Base-16 decode the string: convert hex pairs to byte values
152
- const bytes: number[] = Array.from({ length: receivedString.length / 2 }, (_, i) =>
153
- Number(`0x${receivedString.substring(i * 2, i * 2 + 2)}`),
153
+ const bytes: number[] = Array.from({ length: receivedData.length / 2 }, (_, i) =>
154
+ Number(`0x${receivedData.substring(i * 2, i * 2 + 2)}`),
154
155
  )
155
156
 
156
157
  // Translate header into packet, number of samples from the packet length
@@ -162,20 +163,21 @@ export function handleMotherboardData(uuid: string, receivedString: string): voi
162
163
  masses: [],
163
164
  }
164
165
 
165
- const dataView = new DataView(new Uint8Array(bytes).buffer);
166
+ const dataView = new DataView(new Uint8Array(bytes).buffer)
166
167
 
167
168
  for (let i = 0; i < NUM_SAMPLES; i++) {
168
169
  const sampleStart: number = 4 + 3 * i
169
170
  // Use DataView to read the 24-bit unsigned integer
170
- const rawValue = dataView.getUint8(sampleStart) |
171
+ const rawValue =
172
+ dataView.getUint8(sampleStart) |
171
173
  (dataView.getUint8(sampleStart + 1) << 8) |
172
- (dataView.getUint8(sampleStart + 2) << 16);
174
+ (dataView.getUint8(sampleStart + 2) << 16)
173
175
 
174
176
  // Ensure unsigned 32-bit integer
175
- packet.samples[i] = rawValue >>> 0;
177
+ packet.samples[i] = rawValue >>> 0
176
178
 
177
179
  if (packet.samples[i] >= 0x7fffff) {
178
- packet.samples[i] -= 0x1000000;
180
+ packet.samples[i] -= 0x1000000
179
181
  }
180
182
 
181
183
  // TODO: make sure device is calibrated
@@ -196,16 +198,14 @@ export function handleMotherboardData(uuid: string, receivedString: string): voi
196
198
  massCenter: Math.max(-1000, center).toFixed(3),
197
199
  },
198
200
  })
199
- } else if ((receivedString.match(/,/g) || []).length === 3) {
200
- console.log(receivedString)
201
+ } else if ((receivedData.match(/,/g) || []).length === 3) {
202
+ console.log(receivedData)
201
203
  // if the returned notification is a calibration string add them to the array
202
- const parts: string[] = receivedString.split(",")
204
+ const parts: string[] = receivedData.split(",")
203
205
  const numericParts: number[] = parts.map((x) => parseFloat(x))
204
206
  ;(CALIBRATION[numericParts[0]] as number[][]).push(numericParts.slice(1))
205
207
  } else {
206
208
  // unhanded data
207
- console.log(receivedString)
209
+ console.log(receivedData)
208
210
  }
209
211
  }
210
-
211
-