@hangtime/grip-connect 0.5.0 → 0.5.2

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.
Files changed (65) hide show
  1. package/README.md +17 -38
  2. package/dist/{is-device.d.ts → helpers/is-device.d.ts} +1 -1
  3. package/dist/{is-device.js → helpers/is-device.js} +1 -1
  4. package/dist/index.d.ts +1 -3
  5. package/dist/index.js +2 -4
  6. package/dist/interfaces/base.interface.d.ts +12 -0
  7. package/dist/interfaces/device/climbro.interface.d.ts +3 -0
  8. package/dist/interfaces/device/entralpi.interface.d.ts +49 -0
  9. package/dist/interfaces/device/forceboard.interface.d.ts +18 -0
  10. package/dist/interfaces/device/kilterboard.interface.d.ts +73 -0
  11. package/dist/interfaces/device/motherboard.interface.d.ts +53 -3
  12. package/dist/interfaces/device/mysmartboard.interface.d.ts +3 -0
  13. package/dist/interfaces/device/progressor.interface.d.ts +24 -0
  14. package/dist/interfaces/device/wh-c06.interface.d.ts +3 -0
  15. package/dist/interfaces/device.interface.d.ts +73 -17
  16. package/dist/models/device/entralpi.model.d.ts +22 -6
  17. package/dist/models/device/entralpi.model.js +54 -16
  18. package/dist/models/device/forceboard.model.js +3 -4
  19. package/dist/models/device/kilterboard.model.d.ts +1 -1
  20. package/dist/models/device/kilterboard.model.js +1 -2
  21. package/dist/models/device/motherboard.model.d.ts +5 -0
  22. package/dist/models/device/motherboard.model.js +24 -19
  23. package/dist/models/device/progressor.model.d.ts +5 -0
  24. package/dist/models/device/progressor.model.js +23 -16
  25. package/dist/models/device/wh-c06.model.js +3 -4
  26. package/dist/models/device.model.d.ts +78 -17
  27. package/dist/models/device.model.js +181 -51
  28. package/package.json +1 -1
  29. package/src/{is-device.ts → helpers/is-device.ts} +2 -2
  30. package/src/index.ts +2 -6
  31. package/src/interfaces/base.interface.ts +14 -0
  32. package/src/interfaces/device/climbro.interface.ts +3 -1
  33. package/src/interfaces/device/entralpi.interface.ts +59 -2
  34. package/src/interfaces/device/forceboard.interface.ts +22 -2
  35. package/src/interfaces/device/kilterboard.interface.ts +83 -2
  36. package/src/interfaces/device/motherboard.interface.ts +62 -3
  37. package/src/interfaces/device/mysmartboard.interface.ts +3 -1
  38. package/src/interfaces/device/progressor.interface.ts +29 -2
  39. package/src/interfaces/device/wh-c06.interface.ts +3 -1
  40. package/src/interfaces/device.interface.ts +85 -17
  41. package/src/models/device/entralpi.model.ts +57 -16
  42. package/src/models/device/forceboard.model.ts +3 -4
  43. package/src/models/device/kilterboard.model.ts +2 -3
  44. package/src/models/device/motherboard.model.ts +25 -19
  45. package/src/models/device/progressor.model.ts +24 -16
  46. package/src/models/device/wh-c06.model.ts +4 -4
  47. package/src/models/device.model.ts +201 -55
  48. package/dist/characteristic.d.ts +0 -9
  49. package/dist/characteristic.js +0 -21
  50. package/dist/notify.d.ts +0 -16
  51. package/dist/notify.js +0 -14
  52. package/dist/read.d.ts +0 -10
  53. package/dist/read.js +0 -43
  54. package/dist/stop.d.ts +0 -7
  55. package/dist/stop.js +0 -20
  56. package/dist/write.d.ts +0 -34
  57. package/dist/write.js +0 -58
  58. package/src/characteristic.ts +0 -29
  59. package/src/notify.ts +0 -18
  60. package/src/read.ts +0 -45
  61. package/src/stop.ts +0 -22
  62. package/src/write.ts +0 -74
  63. /package/dist/{struct/index.d.ts → helpers/struct.d.ts} +0 -0
  64. /package/dist/{struct/index.js → helpers/struct.js} +0 -0
  65. /package/src/{struct/index.ts → helpers/struct.ts} +0 -0
@@ -1,4 +1,5 @@
1
1
  import type { IBase } from "./base.interface"
2
+ import type { massObject } from "../types/notify"
2
3
 
3
4
  /**
4
5
  * Represents a characteristic of a Bluetooth service.
@@ -40,10 +41,32 @@ export interface IDevice extends IBase {
40
41
  bluetooth?: BluetoothDevice
41
42
 
42
43
  /**
43
- * Handles the 'disconnected' event.
44
- * @param {Event} event - The 'disconnected' event.
44
+ * Connects to a Bluetooth device.
45
+ * @param {Function} [onSuccess] - Optional callback function to execute on successful connection. Default logs success.
46
+ * @param {Function} [onError] - Optional callback function to execute on error. Default logs the error.
45
47
  */
46
- onDisconnected(event: Event): void
48
+ connect(onSuccess?: () => void, onError?: (error: Error) => void): Promise<void>
49
+
50
+ /**
51
+ * Disconnects the device if it is currently connected.
52
+ * - Checks if the device is connected via it's GATT server.
53
+ * - If the device is connected, it attempts to gracefully disconnect.
54
+ */
55
+ disconnect(): void
56
+
57
+ /**
58
+ * Returns UUIDs of all services associated with the device.
59
+ * @returns {string[]} Array of service UUIDs.
60
+ */
61
+ getAllServiceUUIDs(): string[]
62
+
63
+ /**
64
+ * Retrieves the characteristic from the device's service.
65
+ * @param {string} serviceId - The UUID of the service.
66
+ * @param {string} characteristicId - The UUID of the characteristic.
67
+ * @returns {BluetoothRemoteGATTCharacteristic | undefined} The characteristic, if found.
68
+ */
69
+ getCharacteristic(serviceId: string, characteristicId: string): BluetoothRemoteGATTCharacteristic | undefined
47
70
 
48
71
  /**
49
72
  * Handles notifications received from a characteristic.
@@ -51,6 +74,26 @@ export interface IDevice extends IBase {
51
74
  */
52
75
  handleNotifications(event: Event): void
53
76
 
77
+ /**
78
+ * Checks if a Bluetooth device is connected.
79
+ * @returns {boolean} A boolean indicating whether the device is connected.
80
+ */
81
+ isConnected(): boolean
82
+
83
+ /**
84
+ * Sets the callback function to be called when notifications are received.
85
+ * @param {NotifyCallback} callback - The callback function to be set.
86
+ * @returns {void}
87
+ */
88
+ notify(callback: (data: massObject) => void): void
89
+
90
+ /**
91
+ * Defines the type for the callback function.
92
+ * @callback NotifyCallback
93
+ * @param {massObject} data - The data passed to the callback.
94
+ */
95
+ notifyCallback: (data: massObject) => void
96
+
54
97
  /**
55
98
  * Handles the 'connected' event.
56
99
  * @param {Function} onSuccess - Callback function to execute on successful connection.
@@ -58,28 +101,53 @@ export interface IDevice extends IBase {
58
101
  onConnected(onSuccess: () => void): Promise<void>
59
102
 
60
103
  /**
61
- * Returns UUIDs of all services associated with the device.
62
- * @returns {string[]} Array of service UUIDs.
104
+ * Handles the 'disconnected' event.
105
+ * @param {Event} event - The 'disconnected' event.
63
106
  */
64
- getAllServiceUUIDs(): string[]
107
+ onDisconnected(event: Event): void
65
108
 
66
109
  /**
67
- * Connects to a Bluetooth device.
68
- * @param {Function} [onSuccess] - Optional callback function to execute on successful connection. Default logs success.
69
- * @param {Function} [onError] - Optional callback function to execute on error. Default logs the error.
110
+ * Reads the value of the specified characteristic from the device.
111
+ * @param {string} serviceId - The service ID where the characteristic belongs.
112
+ * @param {string} characteristicId - The characteristic ID to read from.
113
+ * @param {number} [duration=0] - The duration to wait before resolving the promise, in milliseconds.
114
+ * @returns {Promise<string>} A promise that resolves when the read operation is completed.
70
115
  */
71
- connect(onSuccess?: () => void, onError?: (error: Error) => void): Promise<void>
116
+ read(serviceId: string, characteristicId: string, duration?: number): Promise<string>
72
117
 
73
118
  /**
74
- * Checks if a Bluetooth device is connected.
75
- * @returns {boolean} A boolean indicating whether the device is connected.
119
+ * Writes a message to the specified characteristic of a Bluetooth device and optionally provides a callback to handle responses.
120
+ * @param {string} serviceId - The service UUID of the Bluetooth device containing the target characteristic.
121
+ * @param {string} characteristicId - The characteristic UUID where the message will be written.
122
+ * @param {string | Uint8Array | undefined} message - The message to be written to the characteristic. It can be a string or a Uint8Array.
123
+ * @param {number} [duration=0] - Optional. The time in milliseconds to wait before resolving the promise. Defaults to 0 for immediate resolution.
124
+ * @param {WriteCallback} [callback=writeCallback] - Optional. A custom callback to handle the response after the write operation is successful.
125
+ *
126
+ * @returns {Promise<void>} A promise that resolves once the write operation is complete.
127
+ *
128
+ * @throws {Error} Throws an error if the characteristic is undefined.
129
+ *
130
+ * @example
131
+ * // Example usage of the write function with a custom callback
132
+ * await Progressor.write("progressor", "tx", ProgressorCommands.GET_BATT_VLTG, 250, (data) => {
133
+ * console.log(`Battery voltage: ${data}`);
134
+ * });
76
135
  */
77
- isConnected(): boolean
136
+ write(
137
+ serviceId: string,
138
+ characteristicId: string,
139
+ message: string | Uint8Array | undefined,
140
+ duration?: number,
141
+ callback?: (data: string) => void,
142
+ ): Promise<void>
78
143
 
79
144
  /**
80
- * Disconnects the device if it is currently connected.
81
- * - Checks if the device is connected via it's GATT server.
82
- * - If the device is connected, it attempts to gracefully disconnect.
145
+ * A default write callback that logs the response
83
146
  */
84
- disconnect(): void
147
+ writeCallback: (data: string) => void
148
+ /**
149
+ * The last message written to the device.
150
+ * @type {string | Uint8Array | null}
151
+ */
152
+ writeLast: string | Uint8Array | null
85
153
  }
@@ -1,9 +1,7 @@
1
1
  import { Device } from "../device.model"
2
2
  import type { IEntralpi } from "../../interfaces/device/entralpi.interface"
3
- import { notifyCallback } from "../../notify"
4
3
  import { applyTare } from "../../tare"
5
4
  import { checkActivity } from "../../is-active"
6
- import { read } from "../../read"
7
5
 
8
6
  // Constants
9
7
  let MASS_MAX = "0"
@@ -27,7 +25,7 @@ export class Entralpi extends Device implements IEntralpi {
27
25
  characteristics: [
28
26
  {
29
27
  name: "System ID",
30
- id: "id",
28
+ id: "system",
31
29
  uuid: "00002a23-0000-1000-8000-00805f9b34fb",
32
30
  },
33
31
  {
@@ -136,11 +134,25 @@ export class Entralpi extends Device implements IEntralpi {
136
134
 
137
135
  /**
138
136
  * Retrieves battery or voltage information from the device.
139
- * @returns {Promise<string | undefined>} A Promise that resolves with the battery or voltage information,
137
+ * @returns {Promise<string | undefined>} A Promise that resolves with the battery or voltage information.
140
138
  */
141
139
  battery = async (): Promise<string | undefined> => {
142
140
  if (this.isConnected()) {
143
- return await read(this, "battery", "level", 250)
141
+ return await this.read("battery", "level", 250)
142
+ }
143
+ // If device is not found, return undefined
144
+ return undefined
145
+ }
146
+
147
+ /**
148
+ * Retrieves IEEE 11073-20601 Regulatory Certification from the device.
149
+ * @returns {Promise<string>} A Promise that resolves with the certification.
150
+ */
151
+ certification = async (): Promise<string | undefined> => {
152
+ // Check if the device is connected
153
+ if (this.isConnected()) {
154
+ // Read certification from the device
155
+ return await this.read("device", "certification", 250)
144
156
  }
145
157
  // If device is not found, return undefined
146
158
  return undefined
@@ -148,13 +160,13 @@ export class Entralpi extends Device implements IEntralpi {
148
160
 
149
161
  /**
150
162
  * Retrieves firmware version from the device.
151
- * @returns {Promise<string>} A Promise that resolves with the firmware version,
163
+ * @returns {Promise<string>} A Promise that resolves with the firmware version.
152
164
  */
153
165
  firmware = async (): Promise<string | undefined> => {
154
166
  // Check if the device is connected
155
167
  if (this.isConnected()) {
156
168
  // Read firmware version from the Motherboard
157
- return await read(this, "device", "firmware", 250)
169
+ return await this.read("device", "firmware", 250)
158
170
  }
159
171
  // If device is not found, return undefined
160
172
  return undefined
@@ -197,7 +209,7 @@ export class Entralpi extends Device implements IEntralpi {
197
209
  checkActivity(numericData)
198
210
 
199
211
  // Notify with weight data
200
- notifyCallback({
212
+ this.notifyCallback({
201
213
  massMax: MASS_MAX,
202
214
  massAverage: MASS_AVERAGE,
203
215
  massTotal: Math.max(-1000, numericData).toFixed(1),
@@ -208,13 +220,13 @@ export class Entralpi extends Device implements IEntralpi {
208
220
 
209
221
  /**
210
222
  * Retrieves hardware version from the device.
211
- * @returns {Promise<string>} A Promise that resolves with the hardware version,
223
+ * @returns {Promise<string>} A Promise that resolves with the hardware version.
212
224
  */
213
225
  hardware = async (): Promise<string | undefined> => {
214
226
  // Check if the device is connected
215
227
  if (this.isConnected()) {
216
228
  // Read hardware version from the device
217
- return await read(this, "device", "hardware", 250)
229
+ return await this.read("device", "hardware", 250)
218
230
  }
219
231
  // If device is not found, return undefined
220
232
  return undefined
@@ -222,13 +234,13 @@ export class Entralpi extends Device implements IEntralpi {
222
234
 
223
235
  /**
224
236
  * Retrieves manufacturer information from the device.
225
- * @returns {Promise<string>} A Promise that resolves with the manufacturer information,
237
+ * @returns {Promise<string>} A Promise that resolves with the manufacturer information.
226
238
  */
227
239
  manufacturer = async (): Promise<string | undefined> => {
228
240
  // Check if the device is connected
229
241
  if (this.isConnected()) {
230
242
  // Read manufacturer information from the device
231
- return await read(this, "device", "manufacturer", 250)
243
+ return await this.read("device", "manufacturer", 250)
232
244
  }
233
245
  // If device is not found, return undefined
234
246
  return undefined
@@ -236,13 +248,28 @@ export class Entralpi extends Device implements IEntralpi {
236
248
 
237
249
  /**
238
250
  * Retrieves model number from the device.
239
- * @returns {Promise<string>} A Promise that resolves with the model number,
251
+ * @returns {Promise<string>} A Promise that resolves with the model number.
240
252
  */
241
253
  model = async (): Promise<string | undefined> => {
242
254
  // Check if the device is connected
243
255
  if (this.isConnected()) {
244
256
  // Read model number from the Entralpi
245
- return await read(this, "device", "model", 250)
257
+ return await this.read("device", "model", 250)
258
+ }
259
+ // If device is not found, return undefined
260
+ return undefined
261
+ }
262
+
263
+ /**
264
+ * Retrieves PnP ID from the device, a set of values that used to create a device ID value that is unique for this device.
265
+ * Included in the characteristic is a Vendor ID Source field, a Vendor ID field, a Product ID field and a Product Version field
266
+ * @returns {Promise<string>} A Promise that resolves with the PnP ID.
267
+ */
268
+ pnp = async (): Promise<string | undefined> => {
269
+ // Check if the device is connected
270
+ if (this.isConnected()) {
271
+ // Read software version from the Entralpi
272
+ return await this.read("device", "pnp", 250)
246
273
  }
247
274
  // If device is not found, return undefined
248
275
  return undefined
@@ -250,13 +277,27 @@ export class Entralpi extends Device implements IEntralpi {
250
277
 
251
278
  /**
252
279
  * Retrieves software version from the device.
253
- * @returns {Promise<string>} A Promise that resolves with the software version,
280
+ * @returns {Promise<string>} A Promise that resolves with the software version.
254
281
  */
255
282
  software = async (): Promise<string | undefined> => {
256
283
  // Check if the device is connected
257
284
  if (this.isConnected()) {
258
285
  // Read software version from the Entralpi
259
- return await read(this, "device", "software", 250)
286
+ return await this.read("device", "software", 250)
287
+ }
288
+ // If device is not found, return undefined
289
+ return undefined
290
+ }
291
+
292
+ /**
293
+ * Retrieves system id from the device.
294
+ * @returns {Promise<string>} A Promise that resolves with the system id.
295
+ */
296
+ system = async (): Promise<string | undefined> => {
297
+ // Check if the device is connected
298
+ if (this.isConnected()) {
299
+ // Read system id from the device
300
+ return await this.read("device", "system", 250)
260
301
  }
261
302
  // If device is not found, return undefined
262
303
  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
@@ -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(this, "battery", "level", 250)
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(this, "humidity", "level", 250)
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(this, "device", "manufacturer", 250)
200
+ return await this.read("device", "manufacturer", 250)
202
201
  }
203
202
  // If device is not found, return undefined
204
203
  return undefined
@@ -1,7 +1,6 @@
1
1
  import { Device } from "../device.model"
2
2
  import type { IKilterBoard } from "../../interfaces/device/kilterboard.interface"
3
3
  import { KilterBoardPacket, KilterBoardPlacementRoles } from "../../commands/kilterboard"
4
- import { write } from "../../write"
5
4
 
6
5
  /**
7
6
  * Aurora Climbing Advertising service
@@ -206,7 +205,7 @@ export class KilterBoard extends Device implements IKilterBoard {
206
205
  */
207
206
  async writeMessageSeries(messages: Uint8Array[]) {
208
207
  for (const message of messages) {
209
- await write(this, "uart", "tx", message)
208
+ await this.write("uart", "tx", message)
210
209
  }
211
210
  }
212
211
  /**
@@ -214,7 +213,7 @@ export class KilterBoard extends Device implements IKilterBoard {
214
213
  * @param {ClimbPlacement[]} [config] - Optional color or array of climb placements for the LEDs. Ignored if placements are provided.
215
214
  * @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.
216
215
  */
217
- led = async (config?: "green" | "red" | "orange" | ClimbPlacement[]): Promise<number[] | undefined> => {
216
+ led = async (config?: ClimbPlacement[]): Promise<number[] | undefined> => {
218
217
  // Handle Kilterboard logic: process placements and send payload if connected
219
218
  if (Array.isArray(config)) {
220
219
  // Prepares byte arrays for transmission based on a list of climb placements.
@@ -1,15 +1,10 @@
1
1
  import { Device } from "../device.model"
2
2
  import type { IMotherboard } from "../../interfaces/device/motherboard.interface"
3
- import { notifyCallback } from "../../notify"
4
- import { write, writeCallback } from "../../write"
5
3
  import { applyTare } from "../../tare"
6
4
  import { MotherboardCommands } from "../../commands"
7
5
  import { checkActivity } from "../../is-active"
8
- import { lastWrite } from "../../write"
9
6
  import { DownloadPackets, emptyDownloadPackets } from "../../download"
10
7
  import type { DownloadPacket } from "../../types/download"
11
- import { read } from "../../read"
12
- import { stop } from "../../stop"
13
8
 
14
9
  // Constants
15
10
  const PACKET_LENGTH = 32
@@ -156,7 +151,7 @@ export class Motherboard extends Device implements IMotherboard {
156
151
  */
157
152
  battery = async (): Promise<string | undefined> => {
158
153
  if (this.isConnected()) {
159
- return await read(this, "battery", "level", 250)
154
+ return await this.read("battery", "level", 250)
160
155
  }
161
156
  // If device is not found, return undefined
162
157
  return undefined
@@ -170,7 +165,7 @@ export class Motherboard extends Device implements IMotherboard {
170
165
  // Check if the device is connected
171
166
  if (this.isConnected()) {
172
167
  // Write the command to get calibration data to the device
173
- await write(this, "uart", "tx", MotherboardCommands.GET_CALIBRATION, 2500, (data) => {
168
+ await this.write("uart", "tx", MotherboardCommands.GET_CALIBRATION, 2500, (data) => {
174
169
  console.log(data)
175
170
  })
176
171
  }
@@ -184,7 +179,7 @@ export class Motherboard extends Device implements IMotherboard {
184
179
  // Check if the device is connected
185
180
  if (this.isConnected()) {
186
181
  // Read firmware version from the Motherboard
187
- return await read(this, "device", "firmware", 250)
182
+ return await this.read("device", "firmware", 250)
188
183
  }
189
184
  // If device is not found, return undefined
190
185
  return undefined
@@ -289,7 +284,7 @@ export class Motherboard extends Device implements IMotherboard {
289
284
  checkActivity(center)
290
285
 
291
286
  // Notify with weight data
292
- notifyCallback({
287
+ this.notifyCallback({
293
288
  massTotal: Math.max(-1000, left + center + right).toFixed(1),
294
289
  massMax: MASS_MAX,
295
290
  massAverage: MASS_AVERAGE,
@@ -297,7 +292,7 @@ export class Motherboard extends Device implements IMotherboard {
297
292
  massCenter: Math.max(-1000, packet.masses[1]).toFixed(1),
298
293
  massRight: Math.max(-1000, packet.masses[2]).toFixed(1),
299
294
  })
300
- } else if (lastWrite === MotherboardCommands.GET_CALIBRATION) {
295
+ } else if (this.writeLast === MotherboardCommands.GET_CALIBRATION) {
301
296
  // check data integrity
302
297
  if ((receivedData.match(/,/g) || []).length === 3) {
303
298
  const parts: string[] = receivedData.split(",")
@@ -306,7 +301,7 @@ export class Motherboard extends Device implements IMotherboard {
306
301
  }
307
302
  } else {
308
303
  // unhandled data
309
- writeCallback(receivedData)
304
+ this.writeCallback(receivedData)
310
305
  }
311
306
  }
312
307
  }
@@ -321,7 +316,7 @@ export class Motherboard extends Device implements IMotherboard {
321
316
  // Check if the device is connected
322
317
  if (this.isConnected()) {
323
318
  // Read hardware version from the device
324
- return await read(this, "device", "hardware", 250)
319
+ return await this.read("device", "hardware", 250)
325
320
  }
326
321
  // If device is not found, return undefined
327
322
  return undefined
@@ -343,8 +338,8 @@ export class Motherboard extends Device implements IMotherboard {
343
338
  // Default to "off" color if config is not set or not found in colorMapping
344
339
  const color = typeof config === "string" && colorMapping[config] ? config : "off"
345
340
  const [redValue, greenValue] = colorMapping[color]
346
- await write(this, "led", "red", new Uint8Array(redValue))
347
- await write(this, "led", "green", new Uint8Array(greenValue), 1250)
341
+ await this.write("led", "red", new Uint8Array(redValue))
342
+ await this.write("led", "green", new Uint8Array(greenValue), 1250)
348
343
  }
349
344
  return undefined
350
345
  }
@@ -357,7 +352,7 @@ export class Motherboard extends Device implements IMotherboard {
357
352
  // Check if the device is connected
358
353
  if (this.isConnected()) {
359
354
  // Read manufacturer information from the device
360
- return await read(this, "device", "manufacturer", 250)
355
+ return await this.read("device", "manufacturer", 250)
361
356
  }
362
357
  // If device is not found, return undefined
363
358
  return undefined
@@ -372,7 +367,7 @@ export class Motherboard extends Device implements IMotherboard {
372
367
  if (this.isConnected()) {
373
368
  // Write serial number command to the Motherboard and read output
374
369
  let response: string | undefined = undefined
375
- await write(this, "uart", "tx", MotherboardCommands.GET_SERIAL, 250, (data) => {
370
+ await this.write("uart", "tx", MotherboardCommands.GET_SERIAL, 250, (data) => {
376
371
  response = data
377
372
  })
378
373
  return response
@@ -381,6 +376,17 @@ export class Motherboard extends Device implements IMotherboard {
381
376
  return undefined
382
377
  }
383
378
 
379
+ /**
380
+ * Stops the data stream on the specified device.
381
+ * @returns {Promise<void>} A promise that resolves when the stream is stopped.
382
+ */
383
+ stop = async (): Promise<void> => {
384
+ if (this.isConnected()) {
385
+ // Stop stream of device
386
+ await this.write("uart", "tx", MotherboardCommands.STOP_WEIGHT_MEAS, 0)
387
+ }
388
+ }
389
+
384
390
  /**
385
391
  * Starts streaming data from the specified device.
386
392
  * @param {number} [duration=0] - The duration of the stream in milliseconds. If set to 0, stream will continue indefinitely.
@@ -397,10 +403,10 @@ export class Motherboard extends Device implements IMotherboard {
397
403
  await this.calibration()
398
404
  }
399
405
  // Start streaming data
400
- await write(this, "uart", "tx", MotherboardCommands.START_WEIGHT_MEAS, duration)
406
+ await this.write("uart", "tx", MotherboardCommands.START_WEIGHT_MEAS, duration)
401
407
  // Stop streaming if duration is set
402
408
  if (duration !== 0) {
403
- await stop(this)
409
+ await this.stop()
404
410
  }
405
411
  }
406
412
  }
@@ -419,7 +425,7 @@ export class Motherboard extends Device implements IMotherboard {
419
425
  if (this.isConnected()) {
420
426
  // Write text information command to the Motherboard and read output
421
427
  let response: string | undefined = undefined
422
- await write(this, "uart", "tx", MotherboardCommands.GET_TEXT, 250, (data) => {
428
+ await this.write("uart", "tx", MotherboardCommands.GET_TEXT, 250, (data) => {
423
429
  response = data
424
430
  })
425
431
  return response
@@ -1,13 +1,10 @@
1
1
  import { Device } from "../device.model"
2
2
  import type { IProgressor } from "../../interfaces/device/progressor.interface"
3
- import { notifyCallback } from "../../notify"
4
- import { applyTare } from "../../tare"
5
- import { checkActivity } from "../../is-active"
6
3
  import { ProgressorCommands, ProgressorResponses } from "../../commands/progressor"
7
- import struct from "../../struct"
4
+ import struct from "../../helpers/struct"
5
+ import { checkActivity } from "../../is-active"
8
6
  import { DownloadPackets, emptyDownloadPackets } from "../../download"
9
- import { lastWrite, write, writeCallback } from "../../write"
10
- import { stop } from "../../stop"
7
+ import { applyTare } from "../../tare"
11
8
 
12
9
  // Constants
13
10
  let MASS_MAX = "0"
@@ -63,7 +60,7 @@ export class Progressor extends Device implements IProgressor {
63
60
  battery = async (): Promise<string | undefined> => {
64
61
  if (this.isConnected()) {
65
62
  let response: string | undefined = undefined
66
- await write(this, "progressor", "tx", ProgressorCommands.GET_BATT_VLTG, 250, (data) => {
63
+ await this.write("progressor", "tx", ProgressorCommands.GET_BATT_VLTG, 250, (data) => {
67
64
  response = data
68
65
  })
69
66
  return response
@@ -81,7 +78,7 @@ export class Progressor extends Device implements IProgressor {
81
78
  if (this.isConnected()) {
82
79
  // Read firmware version from the device
83
80
  let response: string | undefined = undefined
84
- await write(this, "progressor", "tx", ProgressorCommands.GET_FW_VERSION, 250, (data) => {
81
+ await this.write("progressor", "tx", ProgressorCommands.GET_FW_VERSION, 250, (data) => {
85
82
  response = data
86
83
  })
87
84
  return response
@@ -135,7 +132,7 @@ export class Progressor extends Device implements IProgressor {
135
132
  // Check if device is being used
136
133
  checkActivity(weight)
137
134
 
138
- notifyCallback({
135
+ this.notifyCallback({
139
136
  massMax: MASS_MAX,
140
137
  massAverage: MASS_AVERAGE,
141
138
  massTotal: Math.max(-1000, weight).toFixed(1),
@@ -143,18 +140,18 @@ export class Progressor extends Device implements IProgressor {
143
140
  }
144
141
  }
145
142
  } else if (kind === ProgressorResponses.COMMAND_RESPONSE) {
146
- if (!lastWrite) return
143
+ if (!this.writeLast) return
147
144
 
148
145
  let value = ""
149
146
 
150
- if (lastWrite === ProgressorCommands.GET_BATT_VLTG) {
147
+ if (this.writeLast === ProgressorCommands.GET_BATT_VLTG) {
151
148
  value = new DataView(data.buffer, 2).getUint32(0, true).toString()
152
- } else if (lastWrite === ProgressorCommands.GET_FW_VERSION) {
149
+ } else if (this.writeLast === ProgressorCommands.GET_FW_VERSION) {
153
150
  value = new TextDecoder().decode(data.buffer.slice(2))
154
- } else if (lastWrite === ProgressorCommands.GET_ERR_INFO) {
151
+ } else if (this.writeLast === ProgressorCommands.GET_ERR_INFO) {
155
152
  value = new TextDecoder().decode(data.buffer.slice(2))
156
153
  }
157
- writeCallback(value)
154
+ this.writeCallback(value)
158
155
  } else if (kind === ProgressorResponses.LOW_BATTERY_WARNING) {
159
156
  console.warn("⚠️ Low power detected. Please consider connecting to a power source.")
160
157
  } else {
@@ -164,6 +161,17 @@ export class Progressor extends Device implements IProgressor {
164
161
  }
165
162
  }
166
163
 
164
+ /**
165
+ * Stops the data stream on the specified device.
166
+ * @returns {Promise<void>} A promise that resolves when the stream is stopped.
167
+ */
168
+ stop = async (): Promise<void> => {
169
+ if (this.isConnected()) {
170
+ // Stop stream of device
171
+ await this.write("progressor", "tx", ProgressorCommands.STOP_WEIGHT_MEAS, 0)
172
+ }
173
+ }
174
+
167
175
  /**
168
176
  * Starts streaming data from the specified device.
169
177
  * @param {number} [duration=0] - The duration of the stream in milliseconds. If set to 0, stream will continue indefinitely.
@@ -174,10 +182,10 @@ export class Progressor extends Device implements IProgressor {
174
182
  // Reset download packets
175
183
  emptyDownloadPackets()
176
184
  // Start streaming data
177
- await write(this, "progressor", "tx", ProgressorCommands.START_WEIGHT_MEAS, duration)
185
+ await this.write("progressor", "tx", ProgressorCommands.START_WEIGHT_MEAS, duration)
178
186
  // Stop streaming if duration is set
179
187
  if (duration !== 0) {
180
- await stop(this)
188
+ await this.stop()
181
189
  }
182
190
  }
183
191
  }
@@ -1,7 +1,6 @@
1
1
  import { Device } from "../device.model"
2
2
  import { applyTare } from "../../tare"
3
3
  import { checkActivity } from "../../is-active"
4
- import { notifyCallback } from "../../notify"
5
4
  import type { IWHC06 } from "../../interfaces/device/wh-c06.interface"
6
5
 
7
6
  // Constants
@@ -57,14 +56,15 @@ export class WHC06 extends Device implements IWHC06 {
57
56
  throw new Error("GATT is not available on this device")
58
57
  }
59
58
 
59
+ // Device has no services / characteristics
60
+ onSuccess()
61
+
60
62
  // WH-C06
61
63
  const MANUFACTURER_ID = 256 // 0x0100
62
64
 
63
65
  this.bluetooth.addEventListener("advertisementreceived", (event) => {
64
66
  const data = event.manufacturerData.get(MANUFACTURER_ID)
65
67
  if (data) {
66
- // Device has no services / characteristics
67
- onSuccess()
68
68
  // Handle recieved data
69
69
  const weight = (data.getUint8(WEIGHT_OFFSET) << 8) | data.getUint8(WEIGHT_OFFSET + 1)
70
70
  // const stable = (data.getUint8(STABLE_OFFSET) & 0xf0) >> 4
@@ -90,7 +90,7 @@ export class WHC06 extends Device implements IWHC06 {
90
90
  checkActivity(numericData)
91
91
 
92
92
  // Notify with weight data
93
- notifyCallback({
93
+ this.notifyCallback({
94
94
  massMax: MASS_MAX,
95
95
  massAverage: MASS_AVERAGE,
96
96
  massTotal: Math.max(-1000, numericData).toFixed(1),