brilliantsole 0.0.26 → 0.0.28

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 (215) hide show
  1. package/README.md +16 -10
  2. package/assets/3d/anchor.glb +0 -0
  3. package/assets/3d/coin.glb +0 -0
  4. package/assets/3d/glasses.glb +0 -0
  5. package/assets/3d/rightHand.glb +0 -0
  6. package/assets/audio/bounceMedium.wav +0 -0
  7. package/assets/audio/bounceStrong.wav +0 -0
  8. package/assets/audio/bounceWeak.wav +0 -0
  9. package/assets/audio/coin.wav +0 -0
  10. package/assets/audio/getUp.wav +0 -0
  11. package/assets/audio/grab.wav +0 -0
  12. package/assets/audio/kick.wav +0 -0
  13. package/assets/audio/platterFadeIn old.wav +0 -0
  14. package/assets/audio/platterFadeIn.wav +0 -0
  15. package/assets/audio/platterFadeOut.wav +0 -0
  16. package/assets/audio/punch.wav +0 -0
  17. package/assets/audio/punchSqueak.wav +0 -0
  18. package/assets/audio/purr.wav +0 -0
  19. package/assets/audio/purrFadeOut.wav +0 -0
  20. package/assets/audio/release.wav +0 -0
  21. package/assets/audio/splat.wav +0 -0
  22. package/assets/audio/stomp.wav +0 -0
  23. package/assets/images/ukaton-pressure-0.svg +9 -0
  24. package/assets/images/ukaton-pressure-1.svg +9 -0
  25. package/assets/images/ukaton-pressure-10.svg +9 -0
  26. package/assets/images/ukaton-pressure-11.svg +9 -0
  27. package/assets/images/ukaton-pressure-12.svg +9 -0
  28. package/assets/images/ukaton-pressure-13.svg +9 -0
  29. package/assets/images/ukaton-pressure-14.svg +9 -0
  30. package/assets/images/ukaton-pressure-15.svg +9 -0
  31. package/assets/images/ukaton-pressure-2.svg +9 -0
  32. package/assets/images/ukaton-pressure-3.svg +9 -0
  33. package/assets/images/ukaton-pressure-4.svg +9 -0
  34. package/assets/images/ukaton-pressure-5.svg +9 -0
  35. package/assets/images/ukaton-pressure-6.svg +9 -0
  36. package/assets/images/ukaton-pressure-7.svg +9 -0
  37. package/assets/images/ukaton-pressure-8.svg +9 -0
  38. package/assets/images/ukaton-pressure-9.svg +9 -0
  39. package/assets/images/ukaton-right-insole.svg +798 -0
  40. package/build/brilliantsole.cjs +2870 -882
  41. package/build/brilliantsole.cjs.map +1 -1
  42. package/build/brilliantsole.js +2477 -782
  43. package/build/brilliantsole.js.map +1 -1
  44. package/build/brilliantsole.ls.js +2260 -592
  45. package/build/brilliantsole.ls.js.map +1 -1
  46. package/build/brilliantsole.min.js +1 -1
  47. package/build/brilliantsole.min.js.map +1 -1
  48. package/build/brilliantsole.module.d.ts +302 -116
  49. package/build/brilliantsole.module.js +2468 -782
  50. package/build/brilliantsole.module.js.map +1 -1
  51. package/build/brilliantsole.module.min.d.ts +302 -116
  52. package/build/brilliantsole.module.min.js +1 -1
  53. package/build/brilliantsole.module.min.js.map +1 -1
  54. package/build/brilliantsole.node.module.d.ts +295 -113
  55. package/build/brilliantsole.node.module.js +2860 -882
  56. package/build/brilliantsole.node.module.js.map +1 -1
  57. package/build/dts/BS-output.d.ts +10 -0
  58. package/build/dts/BS.d.ts +21 -9
  59. package/build/dts/CameraManager.d.ts +72 -0
  60. package/build/dts/Device.d.ts +53 -16
  61. package/build/dts/DeviceInformationManager.d.ts +4 -4
  62. package/build/dts/DeviceManager.d.ts +3 -0
  63. package/build/dts/FileTransferManager.d.ts +18 -8
  64. package/build/dts/InformationManager.d.ts +8 -5
  65. package/build/dts/TfliteManager.d.ts +22 -2
  66. package/build/dts/WifiManager.d.ts +61 -0
  67. package/build/dts/connection/BaseConnectionManager.d.ts +37 -3
  68. package/build/dts/connection/ClientConnectionManager.d.ts +11 -2
  69. package/build/dts/connection/bluetooth/BluetoothConnectionManager.d.ts +1 -0
  70. package/build/dts/connection/bluetooth/NobleConnectionManager.d.ts +3 -1
  71. package/build/dts/connection/bluetooth/WebBluetoothConnectionManager.d.ts +2 -0
  72. package/build/dts/connection/bluetooth/bluetoothUUIDs.d.ts +2 -2
  73. package/build/dts/connection/udp/UDPConnectionManager.d.ts +28 -0
  74. package/build/dts/connection/webSocket/WebSocketConnectionManager.d.ts +25 -0
  75. package/build/dts/devicePair/DevicePair.d.ts +14 -10
  76. package/build/dts/devicePair/DevicePairPressureSensorDataManager.d.ts +8 -4
  77. package/build/dts/devicePair/DevicePairSensorDataManager.d.ts +2 -2
  78. package/build/dts/scanner/BaseScanner.d.ts +4 -1
  79. package/build/dts/scanner/NobleScanner.d.ts +2 -1
  80. package/build/dts/sensor/MotionSensorDataManager.d.ts +5 -2
  81. package/build/dts/sensor/SensorDataManager.d.ts +5 -4
  82. package/build/dts/server/BaseClient.d.ts +6 -3
  83. package/build/dts/server/ServerUtils.d.ts +1 -1
  84. package/build/dts/server/websocket/WebSocketUtils.d.ts +1 -1
  85. package/build/dts/utils/CenterOfPressureHelper.d.ts +2 -2
  86. package/build/dts/utils/Console.d.ts +2 -0
  87. package/build/dts/utils/MathUtils.d.ts +2 -0
  88. package/build/dts/utils/ThrottleUtils.d.ts +2 -0
  89. package/build/dts/vibration/VibrationManager.d.ts +19 -2
  90. package/build/index.d.ts +299 -113
  91. package/build/index.node.d.ts +292 -110
  92. package/examples/3d/scene.html +19 -5
  93. package/examples/3d/script.js +90 -17
  94. package/examples/3d-generic/index.html +144 -0
  95. package/examples/3d-generic/script.js +266 -0
  96. package/examples/balance/script.js +2 -1
  97. package/examples/basic/index.html +232 -18
  98. package/examples/basic/script.js +746 -106
  99. package/examples/bottango/index.html +11 -1
  100. package/examples/bottango/script.js +2 -2
  101. package/examples/center-of-pressure/index.html +114 -114
  102. package/examples/center-of-pressure/script.js +1 -1
  103. package/examples/device-pair/index.html +58 -58
  104. package/examples/device-pair/script.js +12 -8
  105. package/examples/edge-impulse/script.js +135 -44
  106. package/examples/edge-impulse-test/README.md +11 -0
  107. package/examples/edge-impulse-test/edge-impulse-standalone.js +7228 -0
  108. package/examples/edge-impulse-test/edge-impulse-standalone.wasm +0 -0
  109. package/examples/edge-impulse-test/index.html +75 -0
  110. package/examples/edge-impulse-test/run-impulse.js +135 -0
  111. package/examples/edge-impulse-test/script.js +200 -0
  112. package/examples/gloves/edge-impulse-standalone.js +7228 -0
  113. package/examples/gloves/edge-impulse-standalone.wasm +0 -0
  114. package/examples/gloves/index.html +119 -0
  115. package/examples/gloves/run-impulse.js +135 -0
  116. package/examples/gloves/scene.html +124 -0
  117. package/examples/gloves/script.js +931 -0
  118. package/examples/graph/index.html +11 -1
  119. package/examples/graph/script.js +94 -37
  120. package/examples/pressure/index.html +180 -12
  121. package/examples/pressure/script.js +144 -7
  122. package/examples/punch/index.html +135 -0
  123. package/examples/punch/punch.tflite +0 -0
  124. package/examples/punch/script.js +169 -0
  125. package/examples/recording/index.html +191 -183
  126. package/examples/server/index.html +109 -23
  127. package/examples/server/script.js +322 -111
  128. package/examples/ukaton-firmware-update/index.html +20 -0
  129. package/examples/ukaton-firmware-update/manifest.json +11 -0
  130. package/examples/ukaton-firmware-update/merged-firmware.bin +0 -0
  131. package/examples/utils/aframe/aframe-master.min.js +2 -0
  132. package/examples/utils/aframe/bs-vibration.js +150 -0
  133. package/examples/utils/aframe/force-pushable.js +80 -0
  134. package/examples/utils/aframe/grabbable-anchor.js +46 -0
  135. package/examples/utils/aframe/grabbable-listener.js +31 -0
  136. package/examples/utils/aframe/grabbable-physics-body.js +190 -0
  137. package/examples/utils/aframe/grow-shrink.js +25 -0
  138. package/examples/utils/aframe/hand-punch.js +119 -0
  139. package/examples/utils/aframe/my-obb-collider.js +293 -0
  140. package/examples/utils/aframe/occlude-hand-tracking-controls.js +47 -0
  141. package/examples/utils/aframe/occlude-mesh.js +42 -0
  142. package/examples/utils/aframe/palm-up-detector.js +47 -0
  143. package/examples/utils/aframe/shadow-material.js +20 -0
  144. package/examples/utils/aframe/soft-shadow-light.js +9 -0
  145. package/examples/webxr/script.js +3 -3
  146. package/examples/webxr-2/assets/3d/soccerBall.glb +0 -0
  147. package/examples/webxr-2/assets/audio/shellBounce.wav +0 -0
  148. package/examples/webxr-2/assets/audio/shellHit.wav +0 -0
  149. package/examples/webxr-2/assets/audio/shellKick.wav +0 -0
  150. package/examples/webxr-2/assets/audio/soccerBounce.wav +0 -0
  151. package/examples/webxr-2/assets/audio/soccerKick.mp3 +0 -0
  152. package/examples/webxr-2/assets/images/shellTexture.png +0 -0
  153. package/examples/webxr-2/components/bs-ankle.js +337 -0
  154. package/examples/webxr-2/components/coin.js +84 -0
  155. package/examples/webxr-2/components/custom-wrap.js +17 -0
  156. package/examples/webxr-2/components/goomba.js +3250 -0
  157. package/examples/webxr-2/components/init-shell-material.js +215 -0
  158. package/examples/webxr-2/components/platter.js +172 -0
  159. package/examples/webxr-2/components/shell.js +374 -0
  160. package/examples/webxr-2/components/soccer-ball.js +250 -0
  161. package/examples/webxr-2/components/squashed-goomba.js +249 -0
  162. package/examples/webxr-2/edge-impulse-standalone.js +7228 -0
  163. package/examples/webxr-2/edge-impulse-standalone.wasm +0 -0
  164. package/examples/webxr-2/index.html +996 -0
  165. package/examples/webxr-2/kick.tflite +0 -0
  166. package/examples/webxr-2/kick2.tflite +0 -0
  167. package/examples/webxr-2/run-impulse.js +135 -0
  168. package/examples/webxr-2/script.js +384 -0
  169. package/package.json +2 -1
  170. package/src/.prettierrc +4 -0
  171. package/src/BS.ts +66 -9
  172. package/src/CameraManager.ts +499 -0
  173. package/src/Device.ts +620 -92
  174. package/src/DeviceInformationManager.ts +22 -11
  175. package/src/DeviceManager.ts +94 -25
  176. package/src/FileTransferManager.ts +146 -21
  177. package/src/FirmwareManager.ts +1 -1
  178. package/src/InformationManager.ts +62 -20
  179. package/src/TfliteManager.ts +172 -26
  180. package/src/WifiManager.ts +323 -0
  181. package/src/connection/BaseConnectionManager.ts +145 -30
  182. package/src/connection/ClientConnectionManager.ts +47 -11
  183. package/src/connection/bluetooth/BluetoothConnectionManager.ts +14 -3
  184. package/src/connection/bluetooth/NobleConnectionManager.ts +155 -42
  185. package/src/connection/bluetooth/WebBluetoothConnectionManager.ts +104 -35
  186. package/src/connection/bluetooth/bluetoothUUIDs.ts +40 -13
  187. package/src/connection/udp/UDPConnectionManager.ts +356 -0
  188. package/src/connection/websocket/WebSocketConnectionManager.ts +282 -0
  189. package/src/devicePair/DevicePair.ts +145 -49
  190. package/src/devicePair/DevicePairPressureSensorDataManager.ts +72 -24
  191. package/src/devicePair/DevicePairSensorDataManager.ts +5 -5
  192. package/src/scanner/BaseScanner.ts +49 -11
  193. package/src/scanner/NobleScanner.ts +81 -17
  194. package/src/sensor/BarometerSensorDataManager.ts +1 -1
  195. package/src/sensor/MotionSensorDataManager.ts +22 -7
  196. package/src/sensor/PressureSensorDataManager.ts +47 -13
  197. package/src/sensor/SensorConfigurationManager.ts +75 -24
  198. package/src/sensor/SensorDataManager.ts +107 -26
  199. package/src/server/BaseClient.ts +192 -37
  200. package/src/server/BaseServer.ts +201 -43
  201. package/src/server/ServerUtils.ts +39 -9
  202. package/src/server/udp/UDPServer.ts +74 -23
  203. package/src/server/udp/UDPUtils.ts +9 -2
  204. package/src/server/websocket/WebSocketClient.ts +30 -9
  205. package/src/server/websocket/WebSocketServer.ts +1 -1
  206. package/src/server/websocket/WebSocketUtils.ts +4 -2
  207. package/src/utils/CenterOfPressureHelper.ts +5 -5
  208. package/src/utils/Console.ts +62 -9
  209. package/src/utils/MathUtils.ts +31 -1
  210. package/src/utils/ParseUtils.ts +25 -6
  211. package/src/utils/ThrottleUtils.ts +62 -0
  212. package/src/utils/Timer.ts +1 -1
  213. package/src/utils/checksum.ts +1 -1
  214. package/src/utils/mcumgr.js +1 -1
  215. package/src/vibration/VibrationManager.ts +166 -40
package/src/Device.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  import { createConsole } from "./utils/Console.ts";
2
- import EventDispatcher, { BoundEventListeners, Event, EventListenerMap, EventMap } from "./utils/EventDispatcher.ts";
2
+ import EventDispatcher, {
3
+ BoundEventListeners,
4
+ Event,
5
+ EventListenerMap,
6
+ EventMap,
7
+ } from "./utils/EventDispatcher.ts";
3
8
  import BaseConnectionManager, {
4
9
  TxMessage,
5
10
  TxRxMessageType,
@@ -9,6 +14,9 @@ import BaseConnectionManager, {
9
14
  BatteryLevelMessageTypes,
10
15
  ConnectionEventTypes,
11
16
  ConnectionStatusEventMessages,
17
+ ConnectionTypes,
18
+ ConnectionType,
19
+ ConnectOptions,
12
20
  } from "./connection/BaseConnectionManager.ts";
13
21
  import { isInBrowser, isInNode } from "./utils/environment.ts";
14
22
  import WebBluetoothConnectionManager from "./connection/bluetooth/WebBluetoothConnectionManager.ts";
@@ -29,10 +37,15 @@ import SensorDataManager, {
29
37
  SensorType,
30
38
  ContinuousSensorTypes,
31
39
  SensorDataEventDispatcher,
40
+ RequiredPressureMessageTypes,
32
41
  } from "./sensor/SensorDataManager.ts";
33
42
  import VibrationManager, {
34
43
  SendVibrationMessageCallback,
35
44
  VibrationConfiguration,
45
+ VibrationEventDispatcher,
46
+ VibrationEventTypes,
47
+ VibrationMessageType,
48
+ VibrationMessageTypes,
36
49
  } from "./vibration/VibrationManager.ts";
37
50
  import FileTransferManager, {
38
51
  FileTransferEventTypes,
@@ -42,6 +55,8 @@ import FileTransferManager, {
42
55
  FileTransferMessageTypes,
43
56
  FileTransferMessageType,
44
57
  FileType,
58
+ FileTypes,
59
+ RequiredFileTransferMessageTypes,
45
60
  } from "./FileTransferManager.ts";
46
61
  import TfliteManager, {
47
62
  TfliteEventTypes,
@@ -51,6 +66,9 @@ import TfliteManager, {
51
66
  TfliteMessageTypes,
52
67
  TfliteMessageType,
53
68
  TfliteSensorTypes,
69
+ TfliteFileConfiguration,
70
+ TfliteSensorType,
71
+ RequiredTfliteMessageTypes,
54
72
  } from "./TfliteManager.ts";
55
73
  import FirmwareManager, {
56
74
  FirmwareEventDispatcher,
@@ -62,8 +80,8 @@ import FirmwareManager, {
62
80
  import DeviceInformationManager, {
63
81
  DeviceInformationEventDispatcher,
64
82
  DeviceInformationEventTypes,
65
- DeviceInformationMessageType,
66
- DeviceInformationMessageTypes,
83
+ DeviceInformationType,
84
+ DeviceInformationTypes,
67
85
  DeviceInformationEventMessages,
68
86
  } from "./DeviceInformationManager.ts";
69
87
  import InformationManager, {
@@ -77,8 +95,32 @@ import InformationManager, {
77
95
  } from "./InformationManager.ts";
78
96
  import { FileLike } from "./utils/ArrayBufferUtils.ts";
79
97
  import DeviceManager from "./DeviceManager.ts";
80
-
81
- const _console = createConsole("Device", { log: true });
98
+ import CameraManager, {
99
+ CameraEventDispatcher,
100
+ CameraEventMessages,
101
+ CameraEventTypes,
102
+ CameraMessageType,
103
+ CameraMessageTypes,
104
+ RequiredCameraMessageTypes,
105
+ SendCameraMessageCallback,
106
+ } from "./CameraManager.ts";
107
+ import WifiManager, {
108
+ RequiredWifiMessageTypes,
109
+ SendWifiMessageCallback,
110
+ WifiEventDispatcher,
111
+ WifiEventMessages,
112
+ WifiEventTypes,
113
+ WifiMessageType,
114
+ WifiMessageTypes,
115
+ } from "./WifiManager.ts";
116
+ import WebSocketConnectionManager from "./connection/websocket/WebSocketConnectionManager.ts";
117
+ import ClientConnectionManager from "./connection/ClientConnectionManager.ts";
118
+
119
+ /** NODE_START */
120
+ import UDPConnectionManager from "./connection/udp/UDPConnectionManager.ts";
121
+ /** NODE_END */
122
+
123
+ const _console = createConsole("Device", { log: false });
82
124
 
83
125
  export const DeviceEventTypes = [
84
126
  "connectionMessage",
@@ -89,8 +131,11 @@ export const DeviceEventTypes = [
89
131
  ...DeviceInformationEventTypes,
90
132
  ...SensorConfigurationEventTypes,
91
133
  ...SensorDataEventTypes,
134
+ ...VibrationEventTypes,
92
135
  ...FileTransferEventTypes,
93
136
  ...TfliteEventTypes,
137
+ ...WifiEventTypes,
138
+ ...CameraEventTypes,
94
139
  ...FirmwareEventTypes,
95
140
  ] as const;
96
141
  export type DeviceEventType = (typeof DeviceEventTypes)[number];
@@ -103,6 +148,8 @@ export interface DeviceEventMessages
103
148
  SensorConfigurationEventMessages,
104
149
  TfliteEventMessages,
105
150
  FileTransferEventMessages,
151
+ WifiEventMessages,
152
+ CameraEventMessages,
106
153
  FirmwareEventMessages {
107
154
  batteryLevel: { batteryLevel: number };
108
155
  connectionMessage: { messageType: ConnectionMessageType; dataView: DataView };
@@ -115,11 +162,27 @@ export type SendMessageCallback<MessageType extends string> = (
115
162
 
116
163
  export type SendSmpMessageCallback = (data: ArrayBuffer) => Promise<void>;
117
164
 
118
- export type DeviceEventDispatcher = EventDispatcher<Device, DeviceEventType, DeviceEventMessages>;
165
+ export type DeviceEventDispatcher = EventDispatcher<
166
+ Device,
167
+ DeviceEventType,
168
+ DeviceEventMessages
169
+ >;
119
170
  export type DeviceEvent = Event<Device, DeviceEventType, DeviceEventMessages>;
120
- export type DeviceEventMap = EventMap<Device, DeviceEventType, DeviceEventMessages>;
121
- export type DeviceEventListenerMap = EventListenerMap<Device, DeviceEventType, DeviceEventMessages>;
122
- export type BoundDeviceEventListeners = BoundEventListeners<Device, DeviceEventType, DeviceEventMessages>;
171
+ export type DeviceEventMap = EventMap<
172
+ Device,
173
+ DeviceEventType,
174
+ DeviceEventMessages
175
+ >;
176
+ export type DeviceEventListenerMap = EventListenerMap<
177
+ Device,
178
+ DeviceEventType,
179
+ DeviceEventMessages
180
+ >;
181
+ export type BoundDeviceEventListeners = BoundEventListeners<
182
+ Device,
183
+ DeviceEventType,
184
+ DeviceEventMessages
185
+ >;
123
186
 
124
187
  export const RequiredInformationConnectionMessages: TxRxMessageType[] = [
125
188
  "isCharging",
@@ -132,22 +195,12 @@ export const RequiredInformationConnectionMessages: TxRxMessageType[] = [
132
195
  "getCurrentTime",
133
196
  "getSensorConfiguration",
134
197
  "getSensorScalars",
135
- "getPressurePositions",
136
-
137
- "maxFileLength",
138
- "getFileLength",
139
- "getFileChecksum",
140
- "getFileType",
141
- "fileTransferStatus",
142
-
143
- "getTfliteName",
144
- "getTfliteTask",
145
- "getTfliteSampleRate",
146
- "getTfliteSensorTypes",
147
- "tfliteIsReady",
148
- "getTfliteCaptureDelay",
149
- "getTfliteThreshold",
150
- "getTfliteInferencingEnabled",
198
+
199
+ "getVibrationLocations",
200
+
201
+ "getFileTypes",
202
+
203
+ "isWifiAvailable",
151
204
  ];
152
205
 
153
206
  class Device {
@@ -155,33 +208,110 @@ class Device {
155
208
  return this.#connectionManager?.bluetoothId;
156
209
  }
157
210
 
158
- constructor() {
159
- this.#deviceInformationManager.eventDispatcher = this.#eventDispatcher as DeviceInformationEventDispatcher;
160
-
161
- this._informationManager.sendMessage = this.sendTxMessages as SendInformationMessageCallback;
162
- this._informationManager.eventDispatcher = this.#eventDispatcher as InformationEventDispatcher;
163
-
164
- this.#sensorConfigurationManager.sendMessage = this.sendTxMessages as SendSensorConfigurationMessageCallback;
165
- this.#sensorConfigurationManager.eventDispatcher = this.#eventDispatcher as SensorConfigurationEventDispatcher;
166
-
167
- this.#sensorDataManager.eventDispatcher = this.#eventDispatcher as SensorDataEventDispatcher;
168
-
169
- this.#vibrationManager.sendMessage = this.sendTxMessages as SendVibrationMessageCallback;
170
-
171
- this.#tfliteManager.sendMessage = this.sendTxMessages as SendTfliteMessageCallback;
172
- this.#tfliteManager.eventDispatcher = this.#eventDispatcher as TfliteEventDispatcher;
173
-
174
- this.#fileTransferManager.sendMessage = this.sendTxMessages as SendFileTransferMessageCallback;
175
- this.#fileTransferManager.eventDispatcher = this.#eventDispatcher as FileTransferEventDispatcher;
211
+ get isAvailable() {
212
+ return this.#connectionManager?.isAvailable;
213
+ }
176
214
 
177
- this.#firmwareManager.sendMessage = this.sendSmpMessage as SendSmpMessageCallback;
178
- this.#firmwareManager.eventDispatcher = this.#eventDispatcher as FirmwareEventDispatcher;
215
+ constructor() {
216
+ this.#deviceInformationManager.eventDispatcher = this
217
+ .#eventDispatcher as DeviceInformationEventDispatcher;
218
+
219
+ this._informationManager.sendMessage = this
220
+ .sendTxMessages as SendInformationMessageCallback;
221
+ this._informationManager.eventDispatcher = this
222
+ .#eventDispatcher as InformationEventDispatcher;
223
+
224
+ this.#sensorConfigurationManager.sendMessage = this
225
+ .sendTxMessages as SendSensorConfigurationMessageCallback;
226
+ this.#sensorConfigurationManager.eventDispatcher = this
227
+ .#eventDispatcher as SensorConfigurationEventDispatcher;
228
+
229
+ this.#sensorDataManager.eventDispatcher = this
230
+ .#eventDispatcher as SensorDataEventDispatcher;
231
+
232
+ this.#vibrationManager.sendMessage = this
233
+ .sendTxMessages as SendVibrationMessageCallback;
234
+ this.#vibrationManager.eventDispatcher = this
235
+ .#eventDispatcher as VibrationEventDispatcher;
236
+
237
+ this.#tfliteManager.sendMessage = this
238
+ .sendTxMessages as SendTfliteMessageCallback;
239
+ this.#tfliteManager.eventDispatcher = this
240
+ .#eventDispatcher as TfliteEventDispatcher;
241
+
242
+ this.#fileTransferManager.sendMessage = this
243
+ .sendTxMessages as SendFileTransferMessageCallback;
244
+ this.#fileTransferManager.eventDispatcher = this
245
+ .#eventDispatcher as FileTransferEventDispatcher;
246
+
247
+ this.#wifiManager.sendMessage = this
248
+ .sendTxMessages as SendWifiMessageCallback;
249
+ this.#wifiManager.eventDispatcher = this
250
+ .#eventDispatcher as WifiEventDispatcher;
251
+
252
+ this.#cameraManager.sendMessage = this
253
+ .sendTxMessages as SendCameraMessageCallback;
254
+ this.#cameraManager.eventDispatcher = this
255
+ .#eventDispatcher as CameraEventDispatcher;
256
+
257
+ this.#firmwareManager.sendMessage = this
258
+ .sendSmpMessage as SendSmpMessageCallback;
259
+ this.#firmwareManager.eventDispatcher = this
260
+ .#eventDispatcher as FirmwareEventDispatcher;
179
261
 
180
262
  this.addEventListener("getMtu", () => {
181
263
  this.#firmwareManager.mtu = this.mtu;
182
264
  this.#fileTransferManager.mtu = this.mtu;
183
265
  this.connectionManager!.mtu = this.mtu;
184
266
  });
267
+ this.addEventListener("getSensorConfiguration", () => {
268
+ if (this.connectionStatus != "connecting") {
269
+ return;
270
+ }
271
+ if (this.sensorTypes.includes("pressure")) {
272
+ _console.log("requesting required pressure information");
273
+ const messages = RequiredPressureMessageTypes.map((messageType) => ({
274
+ type: messageType,
275
+ }));
276
+ this.sendTxMessages(messages, false);
277
+ } else {
278
+ _console.log("don't need to request pressure infomration");
279
+ }
280
+
281
+ if (this.sensorTypes.includes("camera")) {
282
+ _console.log("requesting required camera information");
283
+ const messages = RequiredCameraMessageTypes.map((messageType) => ({
284
+ type: messageType,
285
+ }));
286
+ this.sendTxMessages(messages, false);
287
+ } else {
288
+ _console.log("don't need to request camera infomration");
289
+ }
290
+ });
291
+ this.addEventListener("getFileTypes", () => {
292
+ if (this.connectionStatus != "connecting") {
293
+ return;
294
+ }
295
+ if (this.fileTypes.length > 0) {
296
+ this.#fileTransferManager.requestRequiredInformation();
297
+ }
298
+ if (this.fileTypes.includes("tflite")) {
299
+ this.#tfliteManager.requestRequiredInformation();
300
+ }
301
+ });
302
+ this.addEventListener("isWifiAvailable", () => {
303
+ if (this.connectionStatus != "connecting") {
304
+ return;
305
+ }
306
+ if (this.connectionType == "client" && !isInNode) {
307
+ return;
308
+ }
309
+ if (this.isWifiAvailable) {
310
+ if (this.connectionType != "client") {
311
+ this.#wifiManager.requestRequiredInformation();
312
+ }
313
+ }
314
+ });
185
315
  DeviceManager.onDevice(this);
186
316
  if (isInBrowser) {
187
317
  window.addEventListener("beforeunload", () => {
@@ -204,7 +334,10 @@ class Device {
204
334
  return new WebBluetoothConnectionManager();
205
335
  }
206
336
 
207
- #eventDispatcher: DeviceEventDispatcher = new EventDispatcher(this as Device, DeviceEventTypes);
337
+ #eventDispatcher: DeviceEventDispatcher = new EventDispatcher(
338
+ this as Device,
339
+ DeviceEventTypes
340
+ );
208
341
  get addEventListener() {
209
342
  return this.#eventDispatcher.addEventListener;
210
343
  }
@@ -237,29 +370,100 @@ class Device {
237
370
  }
238
371
 
239
372
  if (this.connectionManager) {
240
- this.connectionManager.onStatusUpdated = undefined;
241
- this.connectionManager.onMessageReceived = undefined;
242
- this.connectionManager.onMessagesReceived = undefined;
373
+ this.connectionManager.remove();
243
374
  }
244
375
  if (newConnectionManager) {
245
- newConnectionManager.onStatusUpdated = this.#onConnectionStatusUpdated.bind(this);
246
- newConnectionManager.onMessageReceived = this.#onConnectionMessageReceived.bind(this);
247
- newConnectionManager.onMessagesReceived = this.#onConnectionMessagesReceived.bind(this);
376
+ newConnectionManager.onStatusUpdated =
377
+ this.#onConnectionStatusUpdated.bind(this);
378
+ newConnectionManager.onMessageReceived =
379
+ this.#onConnectionMessageReceived.bind(this);
380
+ newConnectionManager.onMessagesReceived =
381
+ this.#onConnectionMessagesReceived.bind(this);
248
382
  }
249
383
 
250
384
  this.#connectionManager = newConnectionManager;
251
385
  _console.log("assigned new connectionManager", this.#connectionManager);
386
+
387
+ this._informationManager.connectionType = this.connectionType;
252
388
  }
253
389
  async #sendTxMessages(messages?: TxMessage[], sendImmediately?: boolean) {
254
390
  await this.#connectionManager?.sendTxMessages(messages, sendImmediately);
255
391
  }
256
392
  private sendTxMessages = this.#sendTxMessages.bind(this);
257
393
 
258
- async connect() {
394
+ async connect(options?: ConnectOptions) {
395
+ _console.log("connect options", options);
396
+ if (options) {
397
+ switch (options.type) {
398
+ case "webBluetooth":
399
+ if (this.connectionType != "webBluetooth") {
400
+ this.connectionManager = new WebBluetoothConnectionManager();
401
+ }
402
+ break;
403
+ case "webSocket":
404
+ {
405
+ let createConnectionManager = false;
406
+ if (this.connectionType == "webSocket") {
407
+ const connectionManager = this
408
+ .connectionManager as WebSocketConnectionManager;
409
+ if (
410
+ connectionManager.ipAddress != options.ipAddress ||
411
+ connectionManager.isSecure != options.isWifiSecure
412
+ ) {
413
+ createConnectionManager = true;
414
+ }
415
+ } else {
416
+ createConnectionManager = true;
417
+ }
418
+ if (createConnectionManager) {
419
+ this.connectionManager = new WebSocketConnectionManager(
420
+ options.ipAddress,
421
+ options.isWifiSecure,
422
+ this.bluetoothId
423
+ );
424
+ }
425
+ }
426
+
427
+ break;
428
+ case "udp":
429
+ {
430
+ let createConnectionManager = false;
431
+ if (this.connectionType == "udp") {
432
+ const connectionManager = this
433
+ .connectionManager as UDPConnectionManager;
434
+ if (connectionManager.ipAddress != options.ipAddress) {
435
+ createConnectionManager = true;
436
+ }
437
+ this.reconnectOnDisconnection = true;
438
+ } else {
439
+ createConnectionManager = true;
440
+ }
441
+ if (createConnectionManager) {
442
+ this.connectionManager = new UDPConnectionManager(
443
+ options.ipAddress,
444
+ this.bluetoothId
445
+ );
446
+ }
447
+ }
448
+ break;
449
+ }
450
+ }
259
451
  if (!this.connectionManager) {
260
452
  this.connectionManager = Device.#DefaultConnectionManager();
261
453
  }
262
454
  this.#clear();
455
+
456
+ if (options?.type == "client") {
457
+ _console.assertWithError(
458
+ this.connectionType == "client",
459
+ "expected clientConnectionManager"
460
+ );
461
+ const clientConnectionManager = this
462
+ .connectionManager as ClientConnectionManager;
463
+ clientConnectionManager.subType = options.subType;
464
+ return clientConnectionManager.connect();
465
+ }
466
+ _console.log("connectionManager type", this.connectionManager.type);
263
467
  return this.connectionManager.connect();
264
468
  }
265
469
  #isConnected = false;
@@ -271,15 +475,54 @@ class Device {
271
475
  _console.assertWithError(this.isConnected, "notConnected");
272
476
  }
273
477
 
274
- get #hasRequiredInformation() {
275
- return RequiredInformationConnectionMessages.every((messageType) => {
276
- return this.latestConnectionMessage.has(messageType);
478
+ #didReceiveMessageTypes(messageTypes: ConnectionMessageType[]) {
479
+ return messageTypes.every((messageType) => {
480
+ const hasConnectionMessage =
481
+ this.latestConnectionMessages.has(messageType);
482
+ if (!hasConnectionMessage) {
483
+ _console.log(`didn't receive "${messageType}" message`);
484
+ }
485
+ return hasConnectionMessage;
277
486
  });
278
487
  }
488
+ get #hasRequiredInformation() {
489
+ let hasRequiredInformation = this.#didReceiveMessageTypes(
490
+ RequiredInformationConnectionMessages
491
+ );
492
+ if (hasRequiredInformation && this.sensorTypes.includes("pressure")) {
493
+ hasRequiredInformation = this.#didReceiveMessageTypes(
494
+ RequiredPressureMessageTypes
495
+ );
496
+ }
497
+ if (hasRequiredInformation && this.isWifiAvailable) {
498
+ hasRequiredInformation = this.#didReceiveMessageTypes(
499
+ RequiredWifiMessageTypes
500
+ );
501
+ }
502
+ if (hasRequiredInformation && this.fileTypes.length > 0) {
503
+ hasRequiredInformation = this.#didReceiveMessageTypes(
504
+ RequiredFileTransferMessageTypes
505
+ );
506
+ }
507
+ if (hasRequiredInformation && this.fileTypes.includes("tflite")) {
508
+ hasRequiredInformation = this.#didReceiveMessageTypes(
509
+ RequiredTfliteMessageTypes
510
+ );
511
+ }
512
+ if (hasRequiredInformation && this.hasCamera) {
513
+ hasRequiredInformation = this.#didReceiveMessageTypes(
514
+ RequiredCameraMessageTypes
515
+ );
516
+ }
517
+ return hasRequiredInformation;
518
+ }
279
519
  #requestRequiredInformation() {
280
- const messages: TxMessage[] = RequiredInformationConnectionMessages.map((messageType) => ({
281
- type: messageType,
282
- }));
520
+ _console.log("requesting required information");
521
+ const messages: TxMessage[] = RequiredInformationConnectionMessages.map(
522
+ (messageType) => ({
523
+ type: messageType,
524
+ })
525
+ );
283
526
  this.#sendTxMessages(messages);
284
527
  }
285
528
 
@@ -343,7 +586,12 @@ class Device {
343
586
  if (this.isConnected) {
344
587
  this.disconnect();
345
588
  } else if (this.canReconnect) {
346
- this.reconnect();
589
+ try {
590
+ this.reconnect();
591
+ } catch (error) {
592
+ _console.error("error trying to reconnect", error);
593
+ this.connect();
594
+ }
347
595
  } else {
348
596
  this.connect();
349
597
  }
@@ -362,14 +610,17 @@ class Device {
362
610
  }
363
611
  }
364
612
  get isConnectionBusy() {
365
- return this.connectionStatus == "connecting" || this.connectionStatus == "disconnecting";
613
+ return (
614
+ this.connectionStatus == "connecting" ||
615
+ this.connectionStatus == "disconnecting"
616
+ );
366
617
  }
367
618
 
368
619
  #onConnectionStatusUpdated(connectionStatus: ConnectionStatus) {
369
620
  _console.log({ connectionStatus });
370
621
 
371
622
  if (connectionStatus == "notConnected") {
372
- //this.#clear();
623
+ this.#clearConnection();
373
624
 
374
625
  if (this.canReconnect && this.reconnectOnDisconnection) {
375
626
  _console.log("starting reconnect interval...");
@@ -389,14 +640,18 @@ class Device {
389
640
  this.#checkConnection();
390
641
 
391
642
  if (connectionStatus == "connected" && !this.#isConnected) {
392
- this.#requestRequiredInformation();
643
+ if (this.connectionType != "client") {
644
+ this.#requestRequiredInformation();
645
+ }
393
646
  }
394
647
 
395
648
  DeviceManager.OnDeviceConnectionStatusUpdated(this, connectionStatus);
396
649
  }
397
650
 
398
651
  #dispatchConnectionEvents(includeIsConnected: boolean = false) {
399
- this.#dispatchEvent("connectionStatus", { connectionStatus: this.connectionStatus });
652
+ this.#dispatchEvent("connectionStatus", {
653
+ connectionStatus: this.connectionStatus,
654
+ });
400
655
  this.#dispatchEvent(this.connectionStatus, {});
401
656
  if (includeIsConnected) {
402
657
  this.#dispatchEvent("isConnected", { isConnected: this.isConnected });
@@ -424,13 +679,22 @@ class Device {
424
679
  }
425
680
 
426
681
  #clear() {
427
- this.connectionManager?.clear();
428
- this.latestConnectionMessage.clear();
682
+ this.#clearConnection();
429
683
  this._informationManager.clear();
430
684
  this.#deviceInformationManager.clear();
685
+ this.#tfliteManager.clear();
686
+ this.#wifiManager.clear();
687
+ this.#cameraManager.clear();
688
+ }
689
+ #clearConnection() {
690
+ this.connectionManager?.clear();
691
+ this.latestConnectionMessages.clear();
431
692
  }
432
693
 
433
- #onConnectionMessageReceived(messageType: ConnectionMessageType, dataView: DataView) {
694
+ #onConnectionMessageReceived(
695
+ messageType: ConnectionMessageType,
696
+ dataView: DataView
697
+ ) {
434
698
  _console.log({ messageType, dataView });
435
699
  switch (messageType) {
436
700
  case "batteryLevel":
@@ -440,26 +704,93 @@ class Device {
440
704
  break;
441
705
 
442
706
  default:
443
- if (FileTransferMessageTypes.includes(messageType as FileTransferMessageType)) {
444
- this.#fileTransferManager.parseMessage(messageType as FileTransferMessageType, dataView);
445
- } else if (TfliteMessageTypes.includes(messageType as TfliteMessageType)) {
446
- this.#tfliteManager.parseMessage(messageType as TfliteMessageType, dataView);
447
- } else if (SensorDataMessageTypes.includes(messageType as SensorDataMessageType)) {
448
- this.#sensorDataManager.parseMessage(messageType as SensorDataMessageType, dataView);
449
- } else if (FirmwareMessageTypes.includes(messageType as FirmwareMessageType)) {
450
- this.#firmwareManager.parseMessage(messageType as FirmwareMessageType, dataView);
451
- } else if (DeviceInformationMessageTypes.includes(messageType as DeviceInformationMessageType)) {
452
- this.#deviceInformationManager.parseMessage(messageType as DeviceInformationMessageType, dataView);
453
- } else if (InformationMessageTypes.includes(messageType as InformationMessageType)) {
454
- this._informationManager.parseMessage(messageType as InformationMessageType, dataView);
455
- } else if (SensorConfigurationMessageTypes.includes(messageType as SensorConfigurationMessageType)) {
456
- this.#sensorConfigurationManager.parseMessage(messageType as SensorConfigurationMessageType, dataView);
707
+ if (
708
+ FileTransferMessageTypes.includes(
709
+ messageType as FileTransferMessageType
710
+ )
711
+ ) {
712
+ this.#fileTransferManager.parseMessage(
713
+ messageType as FileTransferMessageType,
714
+ dataView
715
+ );
716
+ } else if (
717
+ TfliteMessageTypes.includes(messageType as TfliteMessageType)
718
+ ) {
719
+ this.#tfliteManager.parseMessage(
720
+ messageType as TfliteMessageType,
721
+ dataView
722
+ );
723
+ } else if (
724
+ SensorDataMessageTypes.includes(messageType as SensorDataMessageType)
725
+ ) {
726
+ this.#sensorDataManager.parseMessage(
727
+ messageType as SensorDataMessageType,
728
+ dataView
729
+ );
730
+ } else if (
731
+ FirmwareMessageTypes.includes(messageType as FirmwareMessageType)
732
+ ) {
733
+ this.#firmwareManager.parseMessage(
734
+ messageType as FirmwareMessageType,
735
+ dataView
736
+ );
737
+ } else if (
738
+ DeviceInformationTypes.includes(messageType as DeviceInformationType)
739
+ ) {
740
+ this.#deviceInformationManager.parseMessage(
741
+ messageType as DeviceInformationType,
742
+ dataView
743
+ );
744
+ } else if (
745
+ InformationMessageTypes.includes(
746
+ messageType as InformationMessageType
747
+ )
748
+ ) {
749
+ this._informationManager.parseMessage(
750
+ messageType as InformationMessageType,
751
+ dataView
752
+ );
753
+ } else if (
754
+ SensorConfigurationMessageTypes.includes(
755
+ messageType as SensorConfigurationMessageType
756
+ )
757
+ ) {
758
+ this.#sensorConfigurationManager.parseMessage(
759
+ messageType as SensorConfigurationMessageType,
760
+ dataView
761
+ );
762
+ } else if (
763
+ VibrationMessageTypes.includes(messageType as VibrationMessageType)
764
+ ) {
765
+ this.#vibrationManager.parseMessage(
766
+ messageType as VibrationMessageType,
767
+ dataView
768
+ );
769
+ } else if (WifiMessageTypes.includes(messageType as WifiMessageType)) {
770
+ this.#wifiManager.parseMessage(
771
+ messageType as WifiMessageType,
772
+ dataView
773
+ );
774
+ } else if (
775
+ CameraMessageTypes.includes(messageType as CameraMessageType)
776
+ ) {
777
+ this.#cameraManager.parseMessage(
778
+ messageType as CameraMessageType,
779
+ dataView
780
+ );
457
781
  } else {
458
782
  throw Error(`uncaught messageType ${messageType}`);
459
783
  }
460
784
  }
461
785
 
462
- this.latestConnectionMessage.set(messageType, dataView);
786
+ this.latestConnectionMessages.set(messageType, dataView);
787
+ if (messageType.startsWith("set")) {
788
+ this.latestConnectionMessages.set(
789
+ // @ts-expect-error
790
+ messageType.replace("set", "get"),
791
+ dataView
792
+ );
793
+ }
463
794
  this.#dispatchEvent("connectionMessage", { messageType, dataView });
464
795
  }
465
796
  #onConnectionMessagesReceived() {
@@ -472,7 +803,7 @@ class Device {
472
803
  this.#sendTxMessages();
473
804
  }
474
805
 
475
- latestConnectionMessage: Map<ConnectionMessageType, DataView> = new Map();
806
+ latestConnectionMessages: Map<ConnectionMessageType, DataView> = new Map();
476
807
 
477
808
  // DEVICE INFORMATION
478
809
  #deviceInformationManager = new DeviceInformationManager();
@@ -531,8 +862,11 @@ class Device {
531
862
  get isInsole() {
532
863
  return this._informationManager.isInsole;
533
864
  }
534
- get insoleSide() {
535
- return this._informationManager.insoleSide;
865
+ get isGlove() {
866
+ return this._informationManager.isGlove;
867
+ }
868
+ get side() {
869
+ return this._informationManager.side;
536
870
  }
537
871
 
538
872
  get mtu() {
@@ -544,7 +878,9 @@ class Device {
544
878
  return Object.keys(this.sensorConfiguration) as SensorType[];
545
879
  }
546
880
  get continuousSensorTypes() {
547
- return ContinuousSensorTypes.filter((sensorType) => this.sensorTypes.includes(sensorType));
881
+ return ContinuousSensorTypes.filter((sensorType) =>
882
+ this.sensorTypes.includes(sensorType)
883
+ );
548
884
  }
549
885
 
550
886
  // SENSOR CONFIGURATION
@@ -555,8 +891,14 @@ class Device {
555
891
  return this.#sensorConfigurationManager.configuration;
556
892
  }
557
893
 
558
- async setSensorConfiguration(newSensorConfiguration: SensorConfiguration, clearRest?: boolean) {
559
- await this.#sensorConfigurationManager.setConfiguration(newSensorConfiguration, clearRest);
894
+ async setSensorConfiguration(
895
+ newSensorConfiguration: SensorConfiguration,
896
+ clearRest?: boolean
897
+ ) {
898
+ await this.#sensorConfigurationManager.setConfiguration(
899
+ newSensorConfiguration,
900
+ clearRest
901
+ );
560
902
  }
561
903
 
562
904
  async clearSensorConfiguration() {
@@ -567,7 +909,9 @@ class Device {
567
909
  static get ClearSensorConfigurationOnLeave() {
568
910
  return this.#ClearSensorConfigurationOnLeave;
569
911
  }
570
- static set ClearSensorConfigurationOnLeave(newClearSensorConfigurationOnLeave) {
912
+ static set ClearSensorConfigurationOnLeave(
913
+ newClearSensorConfigurationOnLeave
914
+ ) {
571
915
  _console.assertTypeWithError(newClearSensorConfigurationOnLeave, "boolean");
572
916
  this.#ClearSensorConfigurationOnLeave = newClearSensorConfigurationOnLeave;
573
917
  }
@@ -593,19 +937,44 @@ class Device {
593
937
  }
594
938
 
595
939
  // VIBRATION
940
+ get vibrationLocations() {
941
+ return this.#vibrationManager.vibrationLocations;
942
+ }
943
+
596
944
  #vibrationManager = new VibrationManager();
597
- async triggerVibration(vibrationConfigurations: VibrationConfiguration[], sendImmediately?: boolean) {
598
- this.#vibrationManager.triggerVibration(vibrationConfigurations, sendImmediately);
945
+ async triggerVibration(
946
+ vibrationConfigurations: VibrationConfiguration[],
947
+ sendImmediately?: boolean
948
+ ) {
949
+ this.#vibrationManager.triggerVibration(
950
+ vibrationConfigurations,
951
+ sendImmediately
952
+ );
599
953
  }
600
954
 
601
955
  // FILE TRANSFER
602
956
  #fileTransferManager = new FileTransferManager();
603
957
 
958
+ get fileTypes() {
959
+ return this.#fileTransferManager.fileTypes;
960
+ }
604
961
  get maxFileLength() {
605
962
  return this.#fileTransferManager.maxLength;
606
963
  }
964
+ get validFileTypes() {
965
+ return FileTypes.filter((fileType) => {
966
+ if (fileType.includes("wifi") && !this.isWifiAvailable) {
967
+ return false;
968
+ }
969
+ return true;
970
+ });
971
+ }
607
972
 
608
973
  async sendFile(fileType: FileType, file: FileLike) {
974
+ _console.assertWithError(
975
+ this.validFileTypes.includes(fileType),
976
+ `invalid fileType ${fileType}`
977
+ );
609
978
  const promise = this.waitForEvent("fileTransferComplete");
610
979
  this.#fileTransferManager.send(fileType, file);
611
980
  await promise;
@@ -634,6 +1003,18 @@ class Device {
634
1003
  return this.#tfliteManager.setName;
635
1004
  }
636
1005
 
1006
+ async sendTfliteConfiguration(configuration: TfliteFileConfiguration) {
1007
+ configuration.type = "tflite";
1008
+ this.#tfliteManager.sendConfiguration(configuration, false);
1009
+ const didSendFile = await this.#fileTransferManager.send(
1010
+ configuration.type,
1011
+ configuration.file
1012
+ );
1013
+ if (!didSendFile) {
1014
+ this.#sendTxMessages();
1015
+ }
1016
+ }
1017
+
637
1018
  // TFLITE MODEL CONFIG
638
1019
  get tfliteTask() {
639
1020
  return this.#tfliteManager.task;
@@ -651,7 +1032,9 @@ class Device {
651
1032
  return this.#tfliteManager.sensorTypes;
652
1033
  }
653
1034
  get allowedTfliteSensorTypes() {
654
- return this.sensorTypes.filter((sensorType) => TfliteSensorTypes.includes(sensorType));
1035
+ return this.sensorTypes.filter((sensorType) =>
1036
+ TfliteSensorTypes.includes(sensorType as TfliteSensorType)
1037
+ );
655
1038
  }
656
1039
  get setTfliteSensorTypes() {
657
1040
  return this.#tfliteManager.setSensorTypes;
@@ -697,15 +1080,31 @@ class Device {
697
1080
 
698
1081
  #firmwareManager = new FirmwareManager();
699
1082
 
1083
+ get canUpdateFirmware() {
1084
+ return this.#connectionManager?.canUpdateFirmware;
1085
+ }
1086
+ #assertCanUpdateFirmware() {
1087
+ _console.assertWithError(this.canUpdateFirmware, "can't update firmware");
1088
+ }
1089
+
700
1090
  #sendSmpMessage(data: ArrayBuffer) {
1091
+ this.#assertCanUpdateFirmware();
701
1092
  return this.#connectionManager!.sendSmpMessage(data);
702
1093
  }
703
1094
  private sendSmpMessage = this.#sendSmpMessage.bind(this);
704
1095
 
705
1096
  get uploadFirmware() {
1097
+ this.#assertCanUpdateFirmware();
706
1098
  return this.#firmwareManager.uploadFirmware;
707
1099
  }
1100
+ get canReset() {
1101
+ return this.canUpdateFirmware;
1102
+ }
708
1103
  async reset() {
1104
+ _console.assertWithError(
1105
+ this.canReset,
1106
+ "reset is not enabled for this device"
1107
+ );
709
1108
  await this.#firmwareManager.reset();
710
1109
  return this.#connectionManager!.disconnect();
711
1110
  }
@@ -713,18 +1112,22 @@ class Device {
713
1112
  return this.#firmwareManager.status;
714
1113
  }
715
1114
  get getFirmwareImages() {
1115
+ this.#assertCanUpdateFirmware();
716
1116
  return this.#firmwareManager.getImages;
717
1117
  }
718
1118
  get firmwareImages() {
719
1119
  return this.#firmwareManager.images;
720
1120
  }
721
1121
  get eraseFirmwareImage() {
1122
+ this.#assertCanUpdateFirmware();
722
1123
  return this.#firmwareManager.eraseImage;
723
1124
  }
724
1125
  get confirmFirmwareImage() {
1126
+ this.#assertCanUpdateFirmware();
725
1127
  return this.#firmwareManager.confirmImage;
726
1128
  }
727
1129
  get testFirmwareImage() {
1130
+ this.#assertCanUpdateFirmware();
728
1131
  return this.#firmwareManager.testImage;
729
1132
  }
730
1133
 
@@ -743,6 +1146,131 @@ class Device {
743
1146
 
744
1147
  this.#fileTransferManager.isServerSide = this.isServerSide;
745
1148
  }
1149
+
1150
+ // UKATON
1151
+ get isUkaton() {
1152
+ return this.deviceInformation.modelNumber.includes("Ukaton");
1153
+ }
1154
+
1155
+ // WIFI MANAGER
1156
+ #wifiManager = new WifiManager();
1157
+ get isWifiAvailable() {
1158
+ return this.#wifiManager.isWifiAvailable;
1159
+ }
1160
+ get wifiSSID() {
1161
+ return this.#wifiManager.wifiSSID;
1162
+ }
1163
+ async setWifiSSID(newWifiSSID: string) {
1164
+ return this.#wifiManager.setWifiSSID(newWifiSSID);
1165
+ }
1166
+ get wifiPassword() {
1167
+ return this.#wifiManager.wifiPassword;
1168
+ }
1169
+ async setWifiPassword(newWifiPassword: string) {
1170
+ return this.#wifiManager.setWifiPassword(newWifiPassword);
1171
+ }
1172
+ get isWifiConnected() {
1173
+ return this.#wifiManager.isWifiConnected;
1174
+ }
1175
+ get ipAddress() {
1176
+ return this.#wifiManager.ipAddress;
1177
+ }
1178
+ get wifiConnectionEnabled() {
1179
+ return this.#wifiManager.wifiConnectionEnabled;
1180
+ }
1181
+ get enableWifiConnection() {
1182
+ return this.#wifiManager.enableWifiConnection;
1183
+ }
1184
+ get setWifiConnectionEnabled() {
1185
+ return this.#wifiManager.setWifiConnectionEnabled;
1186
+ }
1187
+ get disableWifiConnection() {
1188
+ return this.#wifiManager.disableWifiConnection;
1189
+ }
1190
+ get toggleWifiConnection() {
1191
+ return this.#wifiManager.toggleWifiConnection;
1192
+ }
1193
+ get isWifiSecure() {
1194
+ return this.#wifiManager.isWifiSecure;
1195
+ }
1196
+
1197
+ async reconnectViaWebSockets() {
1198
+ _console.assertWithError(this.isWifiConnected, "wifi is not connected");
1199
+ _console.assertWithError(
1200
+ this.connectionType != "webSocket",
1201
+ "already connected via webSockets"
1202
+ );
1203
+ _console.assertTypeWithError(this.ipAddress, "string");
1204
+ _console.log("reconnecting via websockets...");
1205
+ await this.disconnect();
1206
+ await this.connect({
1207
+ type: "webSocket",
1208
+ ipAddress: this.ipAddress!,
1209
+ isWifiSecure: this.isWifiSecure,
1210
+ });
1211
+ }
1212
+
1213
+ async reconnectViaUDP() {
1214
+ _console.assertWithError(isInNode, "udp is only available in node");
1215
+ _console.assertWithError(this.isWifiConnected, "wifi is not connected");
1216
+ _console.assertWithError(
1217
+ this.connectionType != "udp",
1218
+ "already connected via udp"
1219
+ );
1220
+ _console.assertTypeWithError(this.ipAddress, "string");
1221
+ _console.log("reconnecting via udp...");
1222
+ await this.disconnect();
1223
+ await this.connect({
1224
+ type: "udp",
1225
+ ipAddress: this.ipAddress!,
1226
+ });
1227
+ }
1228
+
1229
+ // CAMERA MANAGER
1230
+ #cameraManager = new CameraManager();
1231
+ get hasCamera() {
1232
+ return this.sensorTypes.includes("camera");
1233
+ }
1234
+ get cameraStatus() {
1235
+ return this.#cameraManager.cameraStatus;
1236
+ }
1237
+ #assertHasCamera() {
1238
+ _console.assertWithError(this.hasCamera, "camera not available");
1239
+ }
1240
+ async takePicture() {
1241
+ this.#assertHasCamera();
1242
+ await this.#cameraManager.takePicture();
1243
+ }
1244
+ async focusCamera() {
1245
+ this.#assertHasCamera();
1246
+ await this.#cameraManager.focus();
1247
+ }
1248
+ async stopCamera() {
1249
+ this.#assertHasCamera();
1250
+ await this.#cameraManager.stop();
1251
+ }
1252
+ async wakeCamera() {
1253
+ this.#assertHasCamera();
1254
+ await this.#cameraManager.wake();
1255
+ }
1256
+ async sleepCamera() {
1257
+ this.#assertHasCamera();
1258
+ await this.#cameraManager.sleep();
1259
+ }
1260
+
1261
+ get cameraConfiguration() {
1262
+ return this.#cameraManager.cameraConfiguration;
1263
+ }
1264
+ get availableCameraConfigurationTypes() {
1265
+ return this.#cameraManager.availableCameraConfigurationTypes;
1266
+ }
1267
+ get cameraConfigurationRanges() {
1268
+ return this.#cameraManager.cameraConfigurationRanges;
1269
+ }
1270
+
1271
+ get setCameraConfiguration() {
1272
+ return this.#cameraManager.setCameraConfiguration;
1273
+ }
746
1274
  }
747
1275
 
748
1276
  export default Device;