brilliantsole 0.0.27 → 0.0.29

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 (202) hide show
  1. package/assets/3d/anchor.glb +0 -0
  2. package/assets/3d/coin.glb +0 -0
  3. package/assets/3d/glasses.glb +0 -0
  4. package/assets/audio/bounceMedium.wav +0 -0
  5. package/assets/audio/bounceStrong.wav +0 -0
  6. package/assets/audio/bounceWeak.wav +0 -0
  7. package/assets/audio/coin.wav +0 -0
  8. package/assets/audio/getUp.wav +0 -0
  9. package/assets/audio/grab.wav +0 -0
  10. package/assets/audio/kick.wav +0 -0
  11. package/assets/audio/platterFadeIn old.wav +0 -0
  12. package/assets/audio/platterFadeIn.wav +0 -0
  13. package/assets/audio/platterFadeOut.wav +0 -0
  14. package/assets/audio/punch.wav +0 -0
  15. package/assets/audio/punchSqueak.wav +0 -0
  16. package/assets/audio/purr.wav +0 -0
  17. package/assets/audio/purrFadeOut.wav +0 -0
  18. package/assets/audio/release.wav +0 -0
  19. package/assets/audio/splat.wav +0 -0
  20. package/assets/audio/stomp.wav +0 -0
  21. package/build/brilliantsole.cjs +3091 -741
  22. package/build/brilliantsole.cjs.map +1 -1
  23. package/build/brilliantsole.js +2759 -709
  24. package/build/brilliantsole.js.map +1 -1
  25. package/build/brilliantsole.ls.js +2602 -543
  26. package/build/brilliantsole.ls.js.map +1 -1
  27. package/build/brilliantsole.min.js +1 -1
  28. package/build/brilliantsole.min.js.map +1 -1
  29. package/build/brilliantsole.module.d.ts +295 -65
  30. package/build/brilliantsole.module.js +2749 -710
  31. package/build/brilliantsole.module.js.map +1 -1
  32. package/build/brilliantsole.module.min.d.ts +295 -65
  33. package/build/brilliantsole.module.min.js +1 -1
  34. package/build/brilliantsole.module.min.js.map +1 -1
  35. package/build/brilliantsole.node.module.d.ts +289 -62
  36. package/build/brilliantsole.node.module.js +3080 -742
  37. package/build/brilliantsole.node.module.js.map +1 -1
  38. package/build/dts/BS-output.d.ts +10 -0
  39. package/build/dts/BS.d.ts +21 -8
  40. package/build/dts/CameraManager.d.ts +72 -0
  41. package/build/dts/Device.d.ts +64 -13
  42. package/build/dts/DeviceInformationManager.d.ts +4 -4
  43. package/build/dts/DeviceManager.d.ts +2 -0
  44. package/build/dts/FileTransferManager.d.ts +18 -8
  45. package/build/dts/InformationManager.d.ts +2 -0
  46. package/build/dts/MicrophoneManager.d.ts +88 -0
  47. package/build/dts/TfliteManager.d.ts +22 -2
  48. package/build/dts/WifiManager.d.ts +61 -0
  49. package/build/dts/connection/BaseConnectionManager.d.ts +35 -3
  50. package/build/dts/connection/ClientConnectionManager.d.ts +7 -2
  51. package/build/dts/connection/bluetooth/NobleConnectionManager.d.ts +2 -1
  52. package/build/dts/connection/bluetooth/WebBluetoothConnectionManager.d.ts +1 -0
  53. package/build/dts/connection/bluetooth/bluetoothUUIDs.d.ts +2 -2
  54. package/build/dts/connection/udp/UDPConnectionManager.d.ts +28 -0
  55. package/build/dts/connection/webSocket/WebSocketConnectionManager.d.ts +25 -0
  56. package/build/dts/devicePair/DevicePair.d.ts +5 -5
  57. package/build/dts/scanner/BaseScanner.d.ts +4 -1
  58. package/build/dts/scanner/NobleScanner.d.ts +2 -1
  59. package/build/dts/sensor/MotionSensorDataManager.d.ts +5 -2
  60. package/build/dts/sensor/SensorDataManager.d.ts +5 -4
  61. package/build/dts/server/BaseClient.d.ts +5 -3
  62. package/build/dts/server/ServerUtils.d.ts +1 -1
  63. package/build/dts/server/websocket/WebSocketUtils.d.ts +1 -1
  64. package/build/dts/utils/AudioUtils.d.ts +2 -0
  65. package/build/dts/utils/Console.d.ts +2 -0
  66. package/build/dts/utils/ThrottleUtils.d.ts +2 -0
  67. package/build/dts/vibration/VibrationManager.d.ts +19 -2
  68. package/build/index.d.ts +292 -62
  69. package/build/index.node.d.ts +286 -59
  70. package/examples/3d/scene.html +19 -5
  71. package/examples/3d-generic/index.html +144 -0
  72. package/examples/3d-generic/script.js +266 -0
  73. package/examples/basic/index.html +267 -17
  74. package/examples/basic/script.js +958 -105
  75. package/examples/camera/barcode-detector.js +109 -0
  76. package/examples/camera/depth-estimation.js +71 -0
  77. package/examples/camera/face-detector.js +119 -0
  78. package/examples/camera/face-landmark.js +111 -0
  79. package/examples/camera/gesture-recognition.js +97 -0
  80. package/examples/camera/hand-landmark.js +74 -0
  81. package/examples/camera/image-segmentation.js +98 -0
  82. package/examples/camera/image-to-text.js +43 -0
  83. package/examples/camera/image-upscale.js +75 -0
  84. package/examples/camera/index.html +129 -0
  85. package/examples/camera/object-detection.js +98 -0
  86. package/examples/camera/pose-landmark.js +60 -0
  87. package/examples/camera/script.js +316 -0
  88. package/examples/camera/utils.js +165 -0
  89. package/examples/camera/yolo-tiny.js +54 -0
  90. package/examples/camera/yolo.js +119 -0
  91. package/examples/edge-impulse/script.js +157 -48
  92. package/examples/edge-impulse-test/README.md +11 -0
  93. package/examples/edge-impulse-test/edge-impulse-standalone.js +7228 -0
  94. package/examples/edge-impulse-test/edge-impulse-standalone.wasm +0 -0
  95. package/examples/edge-impulse-test/index.html +75 -0
  96. package/examples/edge-impulse-test/run-impulse.js +135 -0
  97. package/examples/edge-impulse-test/script.js +200 -0
  98. package/examples/glasses-gestures/README.md +11 -0
  99. package/examples/glasses-gestures/edge-impulse-standalone.js +7228 -0
  100. package/examples/glasses-gestures/edge-impulse-standalone.wasm +0 -0
  101. package/examples/glasses-gestures/index.html +69 -0
  102. package/examples/glasses-gestures/run-impulse.js +135 -0
  103. package/examples/glasses-gestures/script.js +226 -0
  104. package/examples/gloves/edge-impulse-standalone.js +7228 -0
  105. package/examples/gloves/edge-impulse-standalone.wasm +0 -0
  106. package/examples/gloves/index.html +4 -1
  107. package/examples/gloves/run-impulse.js +135 -0
  108. package/examples/gloves/script.js +367 -51
  109. package/examples/graph/script.js +94 -37
  110. package/examples/microphone/gender.js +54 -0
  111. package/examples/microphone/index.html +102 -0
  112. package/examples/microphone/script.js +394 -0
  113. package/examples/microphone/utils.js +45 -0
  114. package/examples/microphone/whisper-realtime.js +166 -0
  115. package/examples/microphone/whisper.js +132 -0
  116. package/examples/punch/index.html +135 -0
  117. package/examples/punch/punch.tflite +0 -0
  118. package/examples/punch/script.js +169 -0
  119. package/examples/server/index.html +98 -22
  120. package/examples/server/script.js +317 -109
  121. package/examples/ukaton-firmware-update/merged-firmware.bin +0 -0
  122. package/examples/utils/aframe/aframe-master.min.js +2 -0
  123. package/examples/utils/aframe/bs-vibration.js +150 -0
  124. package/examples/utils/aframe/force-pushable.js +80 -0
  125. package/examples/utils/aframe/grabbable-anchor.js +46 -0
  126. package/examples/utils/aframe/grabbable-listener.js +31 -0
  127. package/examples/utils/aframe/grabbable-physics-body.js +190 -0
  128. package/examples/utils/aframe/grow-shrink.js +25 -0
  129. package/examples/utils/aframe/hand-punch.js +119 -0
  130. package/examples/utils/aframe/my-obb-collider.js +293 -0
  131. package/examples/utils/aframe/occlude-hand-tracking-controls.js +47 -0
  132. package/examples/utils/aframe/occlude-mesh.js +42 -0
  133. package/examples/utils/aframe/palm-up-detector.js +47 -0
  134. package/examples/utils/aframe/shadow-material.js +20 -0
  135. package/examples/utils/aframe/soft-shadow-light.js +9 -0
  136. package/examples/webxr-2/assets/3d/soccerBall.glb +0 -0
  137. package/examples/webxr-2/assets/audio/shellBounce.wav +0 -0
  138. package/examples/webxr-2/assets/audio/shellHit.wav +0 -0
  139. package/examples/webxr-2/assets/audio/shellKick.wav +0 -0
  140. package/examples/webxr-2/assets/audio/soccerBounce.wav +0 -0
  141. package/examples/webxr-2/assets/audio/soccerKick.mp3 +0 -0
  142. package/examples/webxr-2/assets/images/shellTexture.png +0 -0
  143. package/examples/webxr-2/components/bs-ankle.js +337 -0
  144. package/examples/webxr-2/components/coin.js +84 -0
  145. package/examples/webxr-2/components/custom-wrap.js +17 -0
  146. package/examples/webxr-2/components/goomba.js +3250 -0
  147. package/examples/webxr-2/components/init-shell-material.js +215 -0
  148. package/examples/webxr-2/components/platter.js +172 -0
  149. package/examples/webxr-2/components/shell.js +374 -0
  150. package/examples/webxr-2/components/soccer-ball.js +250 -0
  151. package/examples/webxr-2/components/squashed-goomba.js +249 -0
  152. package/examples/webxr-2/edge-impulse-standalone.js +7228 -0
  153. package/examples/webxr-2/edge-impulse-standalone.wasm +0 -0
  154. package/examples/webxr-2/index.html +996 -0
  155. package/examples/webxr-2/kick.tflite +0 -0
  156. package/examples/webxr-2/kick2.tflite +0 -0
  157. package/examples/webxr-2/run-impulse.js +135 -0
  158. package/examples/webxr-2/script.js +384 -0
  159. package/examples/webxr-3/components/bs-camera.js +65 -0
  160. package/examples/webxr-3/index.html +134 -0
  161. package/examples/webxr-3/script.js +432 -0
  162. package/package.json +2 -1
  163. package/src/.prettierrc +4 -0
  164. package/src/BS.ts +79 -8
  165. package/src/CameraManager.ts +497 -0
  166. package/src/Device.ts +691 -86
  167. package/src/DeviceInformationManager.ts +19 -10
  168. package/src/DeviceManager.ts +85 -25
  169. package/src/FileTransferManager.ts +145 -20
  170. package/src/InformationManager.ts +40 -15
  171. package/src/MicrophoneManager.ts +599 -0
  172. package/src/TfliteManager.ts +171 -25
  173. package/src/WifiManager.ts +323 -0
  174. package/src/connection/BaseConnectionManager.ts +130 -30
  175. package/src/connection/ClientConnectionManager.ts +34 -10
  176. package/src/connection/bluetooth/BluetoothConnectionManager.ts +8 -2
  177. package/src/connection/bluetooth/NobleConnectionManager.ts +147 -41
  178. package/src/connection/bluetooth/WebBluetoothConnectionManager.ts +99 -34
  179. package/src/connection/bluetooth/bluetoothUUIDs.ts +40 -13
  180. package/src/connection/udp/UDPConnectionManager.ts +356 -0
  181. package/src/connection/websocket/WebSocketConnectionManager.ts +282 -0
  182. package/src/devicePair/DevicePair.ts +95 -25
  183. package/src/devicePair/DevicePairPressureSensorDataManager.ts +27 -7
  184. package/src/scanner/BaseScanner.ts +49 -11
  185. package/src/scanner/NobleScanner.ts +76 -14
  186. package/src/sensor/MotionSensorDataManager.ts +21 -6
  187. package/src/sensor/PressureSensorDataManager.ts +37 -8
  188. package/src/sensor/SensorConfigurationManager.ts +73 -22
  189. package/src/sensor/SensorDataManager.ts +109 -23
  190. package/src/server/BaseClient.ts +150 -36
  191. package/src/server/BaseServer.ts +50 -2
  192. package/src/server/ServerUtils.ts +39 -9
  193. package/src/server/udp/UDPServer.ts +73 -22
  194. package/src/server/udp/UDPUtils.ts +9 -2
  195. package/src/server/websocket/WebSocketClient.ts +27 -7
  196. package/src/server/websocket/WebSocketUtils.ts +4 -2
  197. package/src/utils/AudioUtils.ts +65 -0
  198. package/src/utils/Console.ts +62 -9
  199. package/src/utils/ParseUtils.ts +24 -5
  200. package/src/utils/ThrottleUtils.ts +62 -0
  201. package/src/utils/Timer.ts +1 -1
  202. package/src/vibration/VibrationManager.ts +166 -40
@@ -8,6 +8,7 @@ import { parseTimestamp } from "./utils/MathUtils.ts";
8
8
  import { SensorType } from "./sensor/SensorDataManager.ts";
9
9
  import Device, { SendMessageCallback } from "./Device.ts";
10
10
  import autoBind from "auto-bind";
11
+ import { FileConfiguration as BaseFileConfiguration } from "./FileTransferManager.ts";
11
12
 
12
13
  const _console = createConsole("TfliteManager", { log: false });
13
14
 
@@ -34,6 +35,17 @@ export type TfliteMessageType = (typeof TfliteMessageTypes)[number];
34
35
  export const TfliteEventTypes = TfliteMessageTypes;
35
36
  export type TfliteEventType = (typeof TfliteEventTypes)[number];
36
37
 
38
+ export const RequiredTfliteMessageTypes: TfliteMessageType[] = [
39
+ "getTfliteName",
40
+ "getTfliteTask",
41
+ "getTfliteSampleRate",
42
+ "getTfliteSensorTypes",
43
+ "tfliteIsReady",
44
+ "getTfliteCaptureDelay",
45
+ "getTfliteThreshold",
46
+ "getTfliteInferencingEnabled",
47
+ ];
48
+
37
49
  export const TfliteTasks = ["classification", "regression"] as const;
38
50
  export type TfliteTask = (typeof TfliteTasks)[number];
39
51
 
@@ -54,14 +66,36 @@ export interface TfliteInference {
54
66
  values: number[];
55
67
  maxValue?: number;
56
68
  maxIndex?: number;
69
+ maxClass?: string;
70
+ classValues?: { [key: string]: number };
57
71
  }
58
72
 
59
- export type TfliteEventDispatcher = EventDispatcher<Device, TfliteEventType, TfliteEventMessages>;
73
+ export type TfliteEventDispatcher = EventDispatcher<
74
+ Device,
75
+ TfliteEventType,
76
+ TfliteEventMessages
77
+ >;
60
78
  export type SendTfliteMessageCallback = SendMessageCallback<TfliteMessageType>;
61
79
 
62
- export const TfliteSensorTypes: SensorType[] = ["pressure", "linearAcceleration", "gyroscope", "magnetometer"] as const;
80
+ export const TfliteSensorTypes = [
81
+ "pressure",
82
+ "linearAcceleration",
83
+ "gyroscope",
84
+ "magnetometer",
85
+ ] as const satisfies readonly SensorType[];
63
86
  export type TfliteSensorType = (typeof TfliteSensorTypes)[number];
64
87
 
88
+ export interface TfliteFileConfiguration extends BaseFileConfiguration {
89
+ type: "tflite";
90
+ name: string;
91
+ sensorTypes: TfliteSensorType[];
92
+ task: TfliteTask;
93
+ sampleRate: number;
94
+ captureDelay?: number;
95
+ threshold?: number;
96
+ classes?: string[];
97
+ }
98
+
65
99
  class TfliteManager {
66
100
  constructor() {
67
101
  autoBind(this);
@@ -73,7 +107,10 @@ class TfliteManager {
73
107
  _console.assertEnumWithError(task, TfliteTasks);
74
108
  }
75
109
  #assertValidTaskEnum(taskEnum: number) {
76
- _console.assertWithError(taskEnum in TfliteTasks, `invalid taskEnum ${taskEnum}`);
110
+ _console.assertWithError(
111
+ taskEnum in TfliteTasks,
112
+ `invalid taskEnum ${taskEnum}`
113
+ );
77
114
  }
78
115
 
79
116
  eventDispatcher!: TfliteEventDispatcher;
@@ -116,7 +153,10 @@ class TfliteManager {
116
153
  const promise = this.waitForEvent("getTfliteName");
117
154
 
118
155
  const setNameData = textEncoder.encode(newName);
119
- this.sendMessage([{ type: "setTfliteName", data: setNameData.buffer }], sendImmediately);
156
+ this.sendMessage(
157
+ [{ type: "setTfliteName", data: setNameData.buffer }],
158
+ sendImmediately
159
+ );
120
160
 
121
161
  await promise;
122
162
  }
@@ -147,7 +187,10 @@ class TfliteManager {
147
187
  const promise = this.waitForEvent("getTfliteTask");
148
188
 
149
189
  const taskEnum = TfliteTasks.indexOf(newTask);
150
- this.sendMessage([{ type: "setTfliteTask", data: Uint8Array.from([taskEnum]).buffer }], sendImmediately);
190
+ this.sendMessage(
191
+ [{ type: "setTfliteTask", data: Uint8Array.from([taskEnum]).buffer }],
192
+ sendImmediately
193
+ );
151
194
 
152
195
  await promise;
153
196
  }
@@ -164,7 +207,9 @@ class TfliteManager {
164
207
  #updateSampleRate(sampleRate: number) {
165
208
  _console.log({ sampleRate });
166
209
  this.#sampleRate = sampleRate;
167
- this.#dispatchEvent("getTfliteSampleRate", { tfliteSampleRate: sampleRate });
210
+ this.#dispatchEvent("getTfliteSampleRate", {
211
+ tfliteSampleRate: sampleRate,
212
+ });
168
213
  }
169
214
  async setSampleRate(newSampleRate: number, sendImmediately?: boolean) {
170
215
  _console.assertTypeWithError(newSampleRate, "number");
@@ -182,40 +227,56 @@ class TfliteManager {
182
227
 
183
228
  const dataView = new DataView(new ArrayBuffer(2));
184
229
  dataView.setUint16(0, newSampleRate, true);
185
- this.sendMessage([{ type: "setTfliteSampleRate", data: dataView.buffer }], sendImmediately);
230
+ this.sendMessage(
231
+ [{ type: "setTfliteSampleRate", data: dataView.buffer }],
232
+ sendImmediately
233
+ );
186
234
 
187
235
  await promise;
188
236
  }
189
237
 
190
238
  static AssertValidSensorType(sensorType: SensorType) {
191
239
  SensorDataManager.AssertValidSensorType(sensorType);
192
- _console.assertWithError(TfliteSensorTypes.includes(sensorType), `invalid tflite sensorType "${sensorType}"`);
240
+ const tfliteSensorType = sensorType as TfliteSensorType;
241
+ _console.assertWithError(
242
+ TfliteSensorTypes.includes(tfliteSensorType),
243
+ `invalid tflite sensorType "${sensorType}"`
244
+ );
193
245
  }
194
246
 
195
- #sensorTypes: SensorType[] = [];
247
+ #sensorTypes: TfliteSensorType[] = [];
196
248
  get sensorTypes() {
197
249
  return this.#sensorTypes.slice();
198
250
  }
199
251
  #parseSensorTypes(dataView: DataView) {
200
252
  _console.log("parseSensorTypes", dataView);
201
- const sensorTypes: SensorType[] = [];
253
+ const sensorTypes: TfliteSensorType[] = [];
202
254
  for (let index = 0; index < dataView.byteLength; index++) {
203
255
  const sensorTypeEnum = dataView.getUint8(index);
204
- const sensorType = SensorTypes[sensorTypeEnum];
256
+ const sensorType = SensorTypes[sensorTypeEnum] as TfliteSensorType;
205
257
  if (sensorType) {
206
- sensorTypes.push(sensorType);
258
+ if (TfliteSensorTypes.includes(sensorType)) {
259
+ sensorTypes.push(sensorType);
260
+ } else {
261
+ _console.error(`invalid tfliteSensorType ${sensorType}`);
262
+ }
207
263
  } else {
208
264
  _console.error(`invalid sensorTypeEnum ${sensorTypeEnum}`);
209
265
  }
210
266
  }
211
267
  this.#updateSensorTypes(sensorTypes);
212
268
  }
213
- #updateSensorTypes(sensorTypes: SensorType[]) {
269
+ #updateSensorTypes(sensorTypes: TfliteSensorType[]) {
214
270
  _console.log({ sensorTypes });
215
271
  this.#sensorTypes = sensorTypes;
216
- this.#dispatchEvent("getTfliteSensorTypes", { tfliteSensorTypes: sensorTypes });
272
+ this.#dispatchEvent("getTfliteSensorTypes", {
273
+ tfliteSensorTypes: sensorTypes,
274
+ });
217
275
  }
218
- async setSensorTypes(newSensorTypes: SensorType[], sendImmediately?: boolean) {
276
+ async setSensorTypes(
277
+ newSensorTypes: SensorType[],
278
+ sendImmediately?: boolean
279
+ ) {
219
280
  newSensorTypes.forEach((sensorType) => {
220
281
  TfliteManager.AssertValidSensorType(sensorType);
221
282
  });
@@ -223,10 +284,17 @@ class TfliteManager {
223
284
  const promise = this.waitForEvent("getTfliteSensorTypes");
224
285
 
225
286
  newSensorTypes = arrayWithoutDuplicates(newSensorTypes);
226
- const newSensorTypeEnums = newSensorTypes.map((sensorType) => SensorTypes.indexOf(sensorType)).sort();
287
+ const newSensorTypeEnums = newSensorTypes
288
+ .map((sensorType) => SensorTypes.indexOf(sensorType))
289
+ .sort();
227
290
  _console.log(newSensorTypes, newSensorTypeEnums);
228
291
  this.sendMessage(
229
- [{ type: "setTfliteSensorTypes", data: Uint8Array.from(newSensorTypeEnums).buffer }],
292
+ [
293
+ {
294
+ type: "setTfliteSensorTypes",
295
+ data: Uint8Array.from(newSensorTypeEnums).buffer,
296
+ },
297
+ ],
230
298
  sendImmediately
231
299
  );
232
300
 
@@ -263,7 +331,9 @@ class TfliteManager {
263
331
  #updateCaptueDelay(captureDelay: number) {
264
332
  _console.log({ captureDelay });
265
333
  this.#captureDelay = captureDelay;
266
- this.#dispatchEvent("getTfliteCaptureDelay", { tfliteCaptureDelay: captureDelay });
334
+ this.#dispatchEvent("getTfliteCaptureDelay", {
335
+ tfliteCaptureDelay: captureDelay,
336
+ });
267
337
  }
268
338
  async setCaptureDelay(newCaptureDelay: number, sendImmediately: boolean) {
269
339
  _console.assertTypeWithError(newCaptureDelay, "number");
@@ -276,7 +346,10 @@ class TfliteManager {
276
346
 
277
347
  const dataView = new DataView(new ArrayBuffer(2));
278
348
  dataView.setUint16(0, newCaptureDelay, true);
279
- this.sendMessage([{ type: "setTfliteCaptureDelay", data: dataView.buffer }], sendImmediately);
349
+ this.sendMessage(
350
+ [{ type: "setTfliteCaptureDelay", data: dataView.buffer }],
351
+ sendImmediately
352
+ );
280
353
 
281
354
  await promise;
282
355
  }
@@ -297,7 +370,10 @@ class TfliteManager {
297
370
  }
298
371
  async setThreshold(newThreshold: number, sendImmediately: boolean) {
299
372
  _console.assertTypeWithError(newThreshold, "number");
300
- _console.assertWithError(newThreshold >= 0, `threshold must be positive (got ${newThreshold})`);
373
+ _console.assertWithError(
374
+ newThreshold >= 0,
375
+ `threshold must be positive (got ${newThreshold})`
376
+ );
301
377
  if (this.#threshold == newThreshold) {
302
378
  _console.log(`redundant threshold assignment ${newThreshold}`);
303
379
  return;
@@ -307,7 +383,10 @@ class TfliteManager {
307
383
 
308
384
  const dataView = new DataView(new ArrayBuffer(4));
309
385
  dataView.setFloat32(0, newThreshold, true);
310
- this.sendMessage([{ type: "setTfliteThreshold", data: dataView.buffer }], sendImmediately);
386
+ this.sendMessage(
387
+ [{ type: "setTfliteThreshold", data: dataView.buffer }],
388
+ sendImmediately
389
+ );
311
390
 
312
391
  await promise;
313
392
  }
@@ -324,16 +403,23 @@ class TfliteManager {
324
403
  #updateInferencingEnabled(inferencingEnabled: boolean) {
325
404
  _console.log({ inferencingEnabled });
326
405
  this.#inferencingEnabled = inferencingEnabled;
327
- this.#dispatchEvent("getTfliteInferencingEnabled", { tfliteInferencingEnabled: inferencingEnabled });
406
+ this.#dispatchEvent("getTfliteInferencingEnabled", {
407
+ tfliteInferencingEnabled: inferencingEnabled,
408
+ });
328
409
  }
329
- async setInferencingEnabled(newInferencingEnabled: boolean, sendImmediately: boolean = true) {
410
+ async setInferencingEnabled(
411
+ newInferencingEnabled: boolean,
412
+ sendImmediately: boolean = true
413
+ ) {
330
414
  _console.assertTypeWithError(newInferencingEnabled, "boolean");
331
415
  if (!newInferencingEnabled && !this.isReady) {
332
416
  return;
333
417
  }
334
418
  this.#assertIsReady();
335
419
  if (this.#inferencingEnabled == newInferencingEnabled) {
336
- _console.log(`redundant inferencingEnabled assignment ${newInferencingEnabled}`);
420
+ _console.log(
421
+ `redundant inferencingEnabled assignment ${newInferencingEnabled}`
422
+ );
337
423
  return;
338
424
  }
339
425
 
@@ -375,7 +461,11 @@ class TfliteManager {
375
461
  _console.log({ timestamp });
376
462
 
377
463
  const values: number[] = [];
378
- for (let index = 0, byteOffset = 2; byteOffset < dataView.byteLength; index++, byteOffset += 4) {
464
+ for (
465
+ let index = 0, byteOffset = 2;
466
+ byteOffset < dataView.byteLength;
467
+ index++, byteOffset += 4
468
+ ) {
379
469
  const value = dataView.getFloat32(byteOffset, true);
380
470
  values.push(value);
381
471
  }
@@ -398,6 +488,15 @@ class TfliteManager {
398
488
  _console.log({ maxIndex, maxValue });
399
489
  inference.maxIndex = maxIndex;
400
490
  inference.maxValue = maxValue;
491
+ if (this.#configuration?.classes) {
492
+ const { classes } = this.#configuration;
493
+ inference.maxClass = classes[maxIndex];
494
+ inference.classValues = {};
495
+ values.forEach((value, index) => {
496
+ const key = classes[index];
497
+ inference.classValues![key] = value;
498
+ });
499
+ }
401
500
  }
402
501
 
403
502
  this.#dispatchEvent("tfliteInference", { tfliteInference: inference });
@@ -445,6 +544,53 @@ class TfliteManager {
445
544
  throw Error(`uncaught messageType ${messageType}`);
446
545
  }
447
546
  }
547
+
548
+ #configuration?: TfliteFileConfiguration;
549
+ get configuration() {
550
+ return this.#configuration;
551
+ }
552
+ sendConfiguration(
553
+ configuration: TfliteFileConfiguration,
554
+ sendImmediately?: boolean
555
+ ) {
556
+ if (configuration == this.#configuration) {
557
+ _console.log("redundant tflite configuration assignment");
558
+ return;
559
+ }
560
+ this.#configuration = configuration;
561
+ _console.log("assigned new tflite configuration", this.configuration);
562
+ if (!this.configuration) {
563
+ return;
564
+ }
565
+ const { name, task, captureDelay, sampleRate, threshold, sensorTypes } =
566
+ this.configuration;
567
+ this.setName(name, false);
568
+ this.setTask(task, false);
569
+ if (captureDelay != undefined) {
570
+ this.setCaptureDelay(captureDelay, false);
571
+ }
572
+ this.setSampleRate(sampleRate, false);
573
+ if (threshold != undefined) {
574
+ this.setThreshold(threshold, false);
575
+ }
576
+ this.setSensorTypes(sensorTypes, sendImmediately);
577
+ }
578
+
579
+ clear() {
580
+ this.#configuration = undefined;
581
+ this.#inferencingEnabled = false;
582
+ this.#sensorTypes = [];
583
+ this.#sampleRate = 0;
584
+ this.#isReady = false;
585
+ }
586
+
587
+ requestRequiredInformation() {
588
+ _console.log("requesting required tflite information");
589
+ const messages = RequiredTfliteMessageTypes.map((messageType) => ({
590
+ type: messageType,
591
+ }));
592
+ this.sendMessage(messages, false);
593
+ }
448
594
  }
449
595
 
450
596
  export default TfliteManager;
@@ -0,0 +1,323 @@
1
+ import Device, { SendMessageCallback } from "./Device.ts";
2
+ import { createConsole } from "./utils/Console.ts";
3
+ import { isInNode } from "./utils/environment.ts";
4
+ import EventDispatcher from "./utils/EventDispatcher.ts";
5
+ import { textDecoder, textEncoder } from "./utils/Text.ts";
6
+ import autoBind from "auto-bind";
7
+
8
+ const _console = createConsole("WifiManager", { log: false });
9
+
10
+ export const MinWifiSSIDLength = 1;
11
+ export const MaxWifiSSIDLength = 32;
12
+
13
+ export const MinWifiPasswordLength = 8;
14
+ export const MaxWifiPasswordLength = 64;
15
+
16
+ export const WifiMessageTypes = [
17
+ "isWifiAvailable",
18
+ "getWifiSSID",
19
+ "setWifiSSID",
20
+ "getWifiPassword",
21
+ "setWifiPassword",
22
+ "getWifiConnectionEnabled",
23
+ "setWifiConnectionEnabled",
24
+ "isWifiConnected",
25
+ "ipAddress",
26
+ "isWifiSecure",
27
+ ] as const;
28
+ export type WifiMessageType = (typeof WifiMessageTypes)[number];
29
+
30
+ export const RequiredWifiMessageTypes: WifiMessageType[] = [
31
+ "getWifiSSID",
32
+ "getWifiPassword",
33
+ "getWifiConnectionEnabled",
34
+ "isWifiConnected",
35
+ "ipAddress",
36
+ "isWifiSecure",
37
+ ] as const;
38
+
39
+ export const WifiEventTypes = WifiMessageTypes;
40
+ export type WifiEventType = (typeof WifiEventTypes)[number];
41
+
42
+ export interface WifiEventMessages {
43
+ isWifiAvailable: { isWifiAvailable: boolean };
44
+ getWifiSSID: { wifiSSID: string };
45
+ getWifiPassword: { wifiPassword: string };
46
+ getEnableWifiConnection: { wifiConnectionEnabled: boolean };
47
+ isWifiConnected: { isWifiConnected: boolean };
48
+ ipAddress: { ipAddress?: string };
49
+ }
50
+
51
+ export type WifiEventDispatcher = EventDispatcher<
52
+ Device,
53
+ WifiEventType,
54
+ WifiEventMessages
55
+ >;
56
+ export type SendWifiMessageCallback = SendMessageCallback<WifiMessageType>;
57
+
58
+ class WifiManager {
59
+ constructor() {
60
+ autoBind(this);
61
+ }
62
+
63
+ sendMessage!: SendWifiMessageCallback;
64
+
65
+ eventDispatcher!: WifiEventDispatcher;
66
+ get #dispatchEvent() {
67
+ return this.eventDispatcher.dispatchEvent;
68
+ }
69
+ get waitForEvent() {
70
+ return this.eventDispatcher.waitForEvent;
71
+ }
72
+
73
+ requestRequiredInformation() {
74
+ _console.log("requesting required wifi information");
75
+ const messages = RequiredWifiMessageTypes.map((messageType) => ({
76
+ type: messageType,
77
+ }));
78
+ this.sendMessage(messages, false);
79
+ }
80
+
81
+ // PROPERTIES
82
+
83
+ #isWifiAvailable = false;
84
+ get isWifiAvailable() {
85
+ return this.#isWifiAvailable;
86
+ }
87
+ #updateIsWifiAvailable(updatedIsWifiAvailable: boolean) {
88
+ _console.assertTypeWithError(updatedIsWifiAvailable, "boolean");
89
+ this.#isWifiAvailable = updatedIsWifiAvailable;
90
+ _console.log({ isWifiAvailable: this.#isWifiAvailable });
91
+ this.#dispatchEvent("isWifiAvailable", {
92
+ isWifiAvailable: this.#isWifiAvailable,
93
+ });
94
+ }
95
+
96
+ #assertWifiIsAvailable() {
97
+ _console.assertWithError(this.#isWifiAvailable, "wifi is not available");
98
+ }
99
+
100
+ // WIFI SSID
101
+ #wifiSSID = "";
102
+ get wifiSSID() {
103
+ return this.#wifiSSID;
104
+ }
105
+
106
+ #updateWifiSSID(updatedWifiSSID: string) {
107
+ _console.assertTypeWithError(updatedWifiSSID, "string");
108
+ this.#wifiSSID = updatedWifiSSID;
109
+ _console.log({ wifiSSID: this.#wifiSSID });
110
+ this.#dispatchEvent("getWifiSSID", { wifiSSID: this.#wifiSSID });
111
+ }
112
+ async setWifiSSID(newWifiSSID: string) {
113
+ this.#assertWifiIsAvailable();
114
+ if (this.#wifiConnectionEnabled) {
115
+ _console.error("cannot change ssid while wifi connection is enabled");
116
+ return;
117
+ }
118
+ _console.assertTypeWithError(newWifiSSID, "string");
119
+ _console.assertRangeWithError(
120
+ "wifiSSID",
121
+ newWifiSSID.length,
122
+ MinWifiSSIDLength,
123
+ MaxWifiSSIDLength
124
+ );
125
+
126
+ const setWifiSSIDData = textEncoder.encode(newWifiSSID);
127
+ _console.log({ setWifiSSIDData });
128
+
129
+ const promise = this.waitForEvent("getWifiSSID");
130
+ this.sendMessage([{ type: "setWifiSSID", data: setWifiSSIDData.buffer }]);
131
+ await promise;
132
+ }
133
+
134
+ // WIFI PASSWORD
135
+ #wifiPassword = "";
136
+ get wifiPassword() {
137
+ return this.#wifiPassword;
138
+ }
139
+
140
+ #updateWifiPassword(updatedWifiPassword: string) {
141
+ _console.assertTypeWithError(updatedWifiPassword, "string");
142
+ this.#wifiPassword = updatedWifiPassword;
143
+ _console.log({ wifiPassword: this.#wifiPassword });
144
+ this.#dispatchEvent("getWifiPassword", {
145
+ wifiPassword: this.#wifiPassword,
146
+ });
147
+ }
148
+ async setWifiPassword(newWifiPassword: string) {
149
+ this.#assertWifiIsAvailable();
150
+ if (this.#wifiConnectionEnabled) {
151
+ _console.error("cannot change password while wifi connection is enabled");
152
+ return;
153
+ }
154
+ _console.assertTypeWithError(newWifiPassword, "string");
155
+ if (newWifiPassword.length > 0) {
156
+ _console.assertRangeWithError(
157
+ "wifiPassword",
158
+ newWifiPassword.length,
159
+ MinWifiPasswordLength,
160
+ MaxWifiPasswordLength
161
+ );
162
+ }
163
+
164
+ const setWifiPasswordData = textEncoder.encode(newWifiPassword);
165
+ _console.log({ setWifiPasswordData });
166
+
167
+ const promise = this.waitForEvent("getWifiPassword");
168
+ this.sendMessage([
169
+ { type: "setWifiPassword", data: setWifiPasswordData.buffer },
170
+ ]);
171
+ await promise;
172
+ }
173
+
174
+ // ENABLE WIFI CONNECTION
175
+ #wifiConnectionEnabled!: boolean;
176
+ get wifiConnectionEnabled() {
177
+ return this.#wifiConnectionEnabled;
178
+ }
179
+ #updateWifiConnectionEnabled(wifiConnectionEnabled: boolean) {
180
+ _console.log({ wifiConnectionEnabled });
181
+ this.#wifiConnectionEnabled = wifiConnectionEnabled;
182
+ this.#dispatchEvent("getWifiConnectionEnabled", {
183
+ wifiConnectionEnabled: wifiConnectionEnabled,
184
+ });
185
+ }
186
+ async setWifiConnectionEnabled(
187
+ newWifiConnectionEnabled: boolean,
188
+ sendImmediately: boolean = true
189
+ ) {
190
+ this.#assertWifiIsAvailable();
191
+ _console.assertTypeWithError(newWifiConnectionEnabled, "boolean");
192
+ if (this.#wifiConnectionEnabled == newWifiConnectionEnabled) {
193
+ _console.log(
194
+ `redundant wifiConnectionEnabled assignment ${newWifiConnectionEnabled}`
195
+ );
196
+ return;
197
+ }
198
+
199
+ const promise = this.waitForEvent("getWifiConnectionEnabled");
200
+ this.sendMessage(
201
+ [
202
+ {
203
+ type: "setWifiConnectionEnabled",
204
+ data: Uint8Array.from([Number(newWifiConnectionEnabled)]).buffer,
205
+ },
206
+ ],
207
+ sendImmediately
208
+ );
209
+ await promise;
210
+ }
211
+ async toggleWifiConnection() {
212
+ return this.setWifiConnectionEnabled(!this.wifiConnectionEnabled);
213
+ }
214
+ async enableWifiConnection() {
215
+ return this.setWifiConnectionEnabled(true);
216
+ }
217
+ async disableWifiConnection() {
218
+ return this.setWifiConnectionEnabled(false);
219
+ }
220
+
221
+ // IS WIFI CONNECTED
222
+ #isWifiConnected = false;
223
+ get isWifiConnected() {
224
+ return this.#isWifiConnected;
225
+ }
226
+ #updateIsWifiConnected(updatedIsWifiConnected: boolean) {
227
+ _console.assertTypeWithError(updatedIsWifiConnected, "boolean");
228
+ this.#isWifiConnected = updatedIsWifiConnected;
229
+ _console.log({ isWifiConnected: this.#isWifiConnected });
230
+ this.#dispatchEvent("isWifiConnected", {
231
+ isWifiConnected: this.#isWifiConnected,
232
+ });
233
+ }
234
+
235
+ // IP ADDRESS
236
+ #ipAddress?: string;
237
+ get ipAddress() {
238
+ return this.#ipAddress;
239
+ }
240
+
241
+ #updateIpAddress(updatedIpAddress?: string) {
242
+ this.#ipAddress = updatedIpAddress;
243
+ _console.log({ ipAddress: this.#ipAddress });
244
+ this.#dispatchEvent("ipAddress", {
245
+ ipAddress: this.#ipAddress,
246
+ });
247
+ }
248
+
249
+ // IS WIFI SECURE
250
+ #isWifiSecure = false;
251
+ get isWifiSecure() {
252
+ return this.#isWifiSecure;
253
+ }
254
+ #updateIsWifiSecure(updatedIsWifiSecure: boolean) {
255
+ _console.assertTypeWithError(updatedIsWifiSecure, "boolean");
256
+ this.#isWifiSecure = updatedIsWifiSecure;
257
+ _console.log({ isWifiSecure: this.#isWifiSecure });
258
+ this.#dispatchEvent("isWifiSecure", {
259
+ isWifiSecure: this.#isWifiSecure,
260
+ });
261
+ }
262
+
263
+ // MESSAGE
264
+ parseMessage(messageType: WifiMessageType, dataView: DataView) {
265
+ _console.log({ messageType });
266
+
267
+ switch (messageType) {
268
+ case "isWifiAvailable":
269
+ const isWifiAvailable = Boolean(dataView.getUint8(0));
270
+ _console.log({ isWifiAvailable });
271
+ this.#updateIsWifiAvailable(isWifiAvailable);
272
+ break;
273
+ case "getWifiSSID":
274
+ case "setWifiSSID":
275
+ const ssid = textDecoder.decode(dataView.buffer);
276
+ _console.log({ ssid });
277
+ this.#updateWifiSSID(ssid);
278
+ break;
279
+ case "getWifiPassword":
280
+ case "setWifiPassword":
281
+ const password = textDecoder.decode(dataView.buffer);
282
+ _console.log({ password });
283
+ this.#updateWifiPassword(password);
284
+ break;
285
+ case "getWifiConnectionEnabled":
286
+ case "setWifiConnectionEnabled":
287
+ const enableWifiConnection = Boolean(dataView.getUint8(0));
288
+ _console.log({ enableWifiConnection });
289
+ this.#updateWifiConnectionEnabled(enableWifiConnection);
290
+ break;
291
+ case "isWifiConnected":
292
+ const isWifiConnected = Boolean(dataView.getUint8(0));
293
+ _console.log({ isWifiConnected });
294
+ this.#updateIsWifiConnected(isWifiConnected);
295
+ break;
296
+ case "ipAddress":
297
+ let ipAddress: string | undefined = undefined;
298
+ if (dataView.byteLength == 4) {
299
+ ipAddress = new Uint8Array(dataView.buffer.slice(0, 4)).join(".");
300
+ }
301
+ _console.log({ ipAddress });
302
+ this.#updateIpAddress(ipAddress);
303
+ break;
304
+ case "isWifiSecure":
305
+ const isWifiSecure = Boolean(dataView.getUint8(0));
306
+ _console.log({ isWifiSecure });
307
+ this.#updateIsWifiSecure(isWifiSecure);
308
+ break;
309
+ default:
310
+ throw Error(`uncaught messageType ${messageType}`);
311
+ }
312
+ }
313
+
314
+ clear() {
315
+ this.#wifiSSID = "";
316
+ this.#wifiPassword = "";
317
+ this.#ipAddress = "";
318
+ this.#isWifiConnected = false;
319
+ this.#isWifiAvailable = false;
320
+ }
321
+ }
322
+
323
+ export default WifiManager;