brilliantsole 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +21 -0
  3. package/build/brilliantsole.cjs +5957 -0
  4. package/build/brilliantsole.cjs.map +1 -0
  5. package/build/brilliantsole.js +5448 -0
  6. package/build/brilliantsole.js.map +1 -0
  7. package/build/brilliantsole.ls.js +4872 -0
  8. package/build/brilliantsole.ls.js.map +1 -0
  9. package/build/brilliantsole.min.js +6 -0
  10. package/build/brilliantsole.min.js.map +1 -0
  11. package/build/brilliantsole.module.d.ts +908 -0
  12. package/build/brilliantsole.module.js +5412 -0
  13. package/build/brilliantsole.module.js.map +1 -0
  14. package/build/brilliantsole.module.min.d.ts +908 -0
  15. package/build/brilliantsole.module.min.js +6 -0
  16. package/build/brilliantsole.module.min.js.map +1 -0
  17. package/build/brilliantsole.node.module.d.ts +908 -0
  18. package/build/brilliantsole.node.module.js +5906 -0
  19. package/build/brilliantsole.node.module.js.map +1 -0
  20. package/build/dts/BS.d.ts +25 -0
  21. package/build/dts/Device.d.ts +136 -0
  22. package/build/dts/DeviceInformationManager.d.ts +56 -0
  23. package/build/dts/DeviceManager.d.ts +67 -0
  24. package/build/dts/FileTransferManager.d.ts +84 -0
  25. package/build/dts/FirmwareManager.d.ts +71 -0
  26. package/build/dts/InformationManager.d.ts +66 -0
  27. package/build/dts/TfliteManager.d.ts +92 -0
  28. package/build/dts/connection/BaseConnectionManager.d.ts +59 -0
  29. package/build/dts/connection/ClientConnectionManager.d.ts +23 -0
  30. package/build/dts/connection/WebSocketClientConnectionManager.d.ts +23 -0
  31. package/build/dts/connection/bluetooth/BluetoothConnectionManager.d.ts +10 -0
  32. package/build/dts/connection/bluetooth/NobleConnectionManager.d.ts +42 -0
  33. package/build/dts/connection/bluetooth/WebBluetoothConnectionManager.d.ts +20 -0
  34. package/build/dts/connection/bluetooth/bluetoothUUIDs.d.ts +14 -0
  35. package/build/dts/connection/webSocket/ClientConnectionManager.d.ts +23 -0
  36. package/build/dts/connection/webSocket/WebSocketClientConnectionManager.d.ts +23 -0
  37. package/build/dts/devicePair/DevicePair.d.ts +60 -0
  38. package/build/dts/devicePair/DevicePairPressureSensorDataManager.d.ts +25 -0
  39. package/build/dts/devicePair/DevicePairSensorDataManager.d.ts +33 -0
  40. package/build/dts/scanner/BaseScanner.d.ts +66 -0
  41. package/build/dts/scanner/NobleScanner.d.ts +17 -0
  42. package/build/dts/scanner/Scanner.d.ts +3 -0
  43. package/build/dts/sensor/BarometerSensorDataManager.d.ts +16 -0
  44. package/build/dts/sensor/MotionSensorDataManager.d.ts +69 -0
  45. package/build/dts/sensor/PressureSensorDataManager.d.ts +36 -0
  46. package/build/dts/sensor/SensorConfigurationManager.d.ts +44 -0
  47. package/build/dts/sensor/SensorDataManager.d.ts +40 -0
  48. package/build/dts/server/BaseClient.d.ts +85 -0
  49. package/build/dts/server/BaseServer.d.ts +48 -0
  50. package/build/dts/server/ServerUtils.d.ts +23 -0
  51. package/build/dts/server/udp/UDPServer.d.ts +11 -0
  52. package/build/dts/server/udp/UDPUtils.d.ts +9 -0
  53. package/build/dts/server/websocket/WebSocketClient.d.ts +17 -0
  54. package/build/dts/server/websocket/WebSocketServer.d.ts +13 -0
  55. package/build/dts/server/websocket/WebSocketUtils.d.ts +9 -0
  56. package/build/dts/utils/ArrayBufferUtils.d.ts +7 -0
  57. package/build/dts/utils/ArrayUtils.d.ts +2 -0
  58. package/build/dts/utils/CenterOfPressureHelper.d.ts +15 -0
  59. package/build/dts/utils/Console.d.ts +34 -0
  60. package/build/dts/utils/EventDispatcher.d.ts +50 -0
  61. package/build/dts/utils/EventUtils.d.ts +6 -0
  62. package/build/dts/utils/MathUtils.d.ts +21 -0
  63. package/build/dts/utils/ParseUtils.d.ts +5 -0
  64. package/build/dts/utils/RangeHelper.d.ts +8 -0
  65. package/build/dts/utils/Text.d.ts +6 -0
  66. package/build/dts/utils/Timer.d.ts +14 -0
  67. package/build/dts/utils/TypeScriptUtils.d.ts +19 -0
  68. package/build/dts/utils/cbor.d.ts +6 -0
  69. package/build/dts/utils/checksum.d.ts +3 -0
  70. package/build/dts/utils/environment.d.ts +13 -0
  71. package/build/dts/utils/mcumgr.d.ts +88 -0
  72. package/build/dts/utils/stringUtils.d.ts +2 -0
  73. package/build/dts/vibration/VibrationManager.d.ts +45 -0
  74. package/build/dts/vibration/VibrationWaveformEffects.d.ts +2 -0
  75. package/build/index.d.ts +908 -0
  76. package/build/index.node.d.ts +908 -0
  77. package/examples/3d/index.html +109 -0
  78. package/examples/3d/scene.html +57 -0
  79. package/examples/3d/script.js +419 -0
  80. package/examples/balance/index.html +138 -0
  81. package/examples/balance/script.js +243 -0
  82. package/examples/basic/index.html +327 -0
  83. package/examples/basic/script.js +1093 -0
  84. package/examples/center-of-pressure/index.html +132 -0
  85. package/examples/center-of-pressure/script.js +207 -0
  86. package/examples/device-pair/index.html +72 -0
  87. package/examples/device-pair/script.js +187 -0
  88. package/examples/edge-impulse/index.html +94 -0
  89. package/examples/edge-impulse/script.js +1033 -0
  90. package/examples/graph/index.html +83 -0
  91. package/examples/graph/script.js +469 -0
  92. package/examples/machine-learning/index.html +366 -0
  93. package/examples/machine-learning/script.js +1774 -0
  94. package/examples/pressure/index.html +145 -0
  95. package/examples/pressure/script.js +201 -0
  96. package/examples/recording/index.html +187 -0
  97. package/examples/recording/script.js +736 -0
  98. package/examples/server/index.html +266 -0
  99. package/examples/server/script.js +925 -0
  100. package/examples/utils/aframe/fingertip-button-component.js +201 -0
  101. package/examples/utils/aframe/fingertip-collider-target-component.js +102 -0
  102. package/examples/utils/aframe/fingertip-colliders-component.js +147 -0
  103. package/examples/utils/three/three.module.min.js +24846 -0
  104. package/examples/webxr/index.html +221 -0
  105. package/examples/webxr/script.js +1127 -0
  106. package/package.json +83 -0
  107. package/src/BS.ts +68 -0
  108. package/src/Device.ts +734 -0
  109. package/src/DeviceInformationManager.ts +146 -0
  110. package/src/DeviceManager.ts +354 -0
  111. package/src/FileTransferManager.ts +452 -0
  112. package/src/FirmwareManager.ts +357 -0
  113. package/src/InformationManager.ts +283 -0
  114. package/src/TfliteManager.ts +450 -0
  115. package/src/connection/BaseConnectionManager.ts +255 -0
  116. package/src/connection/ClientConnectionManager.ts +120 -0
  117. package/src/connection/bluetooth/BluetoothConnectionManager.ts +34 -0
  118. package/src/connection/bluetooth/NobleConnectionManager.ts +302 -0
  119. package/src/connection/bluetooth/WebBluetoothConnectionManager.ts +269 -0
  120. package/src/connection/bluetooth/bluetoothUUIDs.ts +218 -0
  121. package/src/devicePair/DevicePair.ts +253 -0
  122. package/src/devicePair/DevicePairPressureSensorDataManager.ts +82 -0
  123. package/src/devicePair/DevicePairSensorDataManager.ts +90 -0
  124. package/src/scanner/BaseScanner.ts +189 -0
  125. package/src/scanner/NobleScanner.ts +195 -0
  126. package/src/scanner/Scanner.ts +16 -0
  127. package/src/sensor/BarometerSensorDataManager.ts +41 -0
  128. package/src/sensor/MotionSensorDataManager.ts +151 -0
  129. package/src/sensor/PressureSensorDataManager.ts +112 -0
  130. package/src/sensor/SensorConfigurationManager.ts +177 -0
  131. package/src/sensor/SensorDataManager.ts +166 -0
  132. package/src/server/BaseClient.ts +368 -0
  133. package/src/server/BaseServer.ts +344 -0
  134. package/src/server/ServerUtils.ts +93 -0
  135. package/src/server/udp/UDPServer.ts +229 -0
  136. package/src/server/udp/UDPUtils.ts +20 -0
  137. package/src/server/websocket/WebSocketClient.ts +179 -0
  138. package/src/server/websocket/WebSocketServer.ts +184 -0
  139. package/src/server/websocket/WebSocketUtils.ts +20 -0
  140. package/src/utils/ArrayBufferUtils.ts +88 -0
  141. package/src/utils/ArrayUtils.ts +15 -0
  142. package/src/utils/CenterOfPressureHelper.ts +39 -0
  143. package/src/utils/Console.ts +156 -0
  144. package/src/utils/EventDispatcher.ts +153 -0
  145. package/src/utils/EventUtils.ts +41 -0
  146. package/src/utils/MathUtils.ts +53 -0
  147. package/src/utils/ParseUtils.ts +46 -0
  148. package/src/utils/RangeHelper.ts +38 -0
  149. package/src/utils/Text.ts +30 -0
  150. package/src/utils/Timer.ts +72 -0
  151. package/src/utils/TypeScriptUtils.ts +22 -0
  152. package/src/utils/cbor.js +429 -0
  153. package/src/utils/checksum.ts +41 -0
  154. package/src/utils/environment.ts +46 -0
  155. package/src/utils/mcumgr.js +444 -0
  156. package/src/utils/stringUtils.ts +11 -0
  157. package/src/vibration/VibrationManager.ts +308 -0
  158. package/src/vibration/VibrationWaveformEffects.ts +128 -0
@@ -0,0 +1,83 @@
1
+ <html>
2
+ <head>
3
+ <title>Graph | BrilliantSole JavaScript SDK</title>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
5
+ <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
6
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.min.js"></script>
7
+ <script type="module" src="./script.js"></script>
8
+ </head>
9
+
10
+ <style>
11
+ #charts {
12
+ display: grid;
13
+ grid-template-columns: 1fr 1fr;
14
+ width: 100%;
15
+ }
16
+
17
+ .chart {
18
+ position: relative;
19
+ border: solid black thin;
20
+ box-sizing: border-box;
21
+ }
22
+
23
+ @media screen and (max-width: 1000px) {
24
+ #charts {
25
+ grid-template-columns: 1fr 1fr;
26
+ }
27
+ }
28
+
29
+ @media screen and (max-width: 800px) {
30
+ #charts {
31
+ grid-template-columns: 1fr;
32
+ }
33
+ }
34
+ </style>
35
+
36
+ <body>
37
+ <nav>
38
+ <a href="../../">home</a>
39
+ </nav>
40
+
41
+ <h1>Graph | BrilliantSole JavaScript SDK</h1>
42
+
43
+ <button id="toggleServerConnection">connect to server</button>
44
+
45
+ <div>
46
+ <h2>available devices</h2>
47
+ <div id="availableDevices">
48
+ <template id="availableDeviceTemplate">
49
+ <div class="availableDevice">
50
+ <ul>
51
+ <li><b>name: </b> <span class="name"></span></li>
52
+ <li><b>type: </b> <span class="type"></span></li>
53
+ <li><button class="toggleConnection">connect</button></li>
54
+ </ul>
55
+ </div>
56
+ </template>
57
+ </div>
58
+ </div>
59
+
60
+ <br />
61
+
62
+ <div>
63
+ <button id="toggleConnection">connect</button>
64
+ </div>
65
+
66
+ <div>
67
+ <template id="sensorTypeConfigurationTemplate">
68
+ <label class="sensorTypeConfiguration">
69
+ <b class="sensorType"></b>
70
+ <input class="sensorRate" type="number" min="0" value="" disabled />
71
+ </label>
72
+ </template>
73
+ </div>
74
+
75
+ <div id="charts">
76
+ <template id="chartTemplate">
77
+ <div class="chart">
78
+ <canvas></canvas>
79
+ </div>
80
+ </template>
81
+ </div>
82
+ </body>
83
+ </html>
@@ -0,0 +1,469 @@
1
+ import * as BS from "../../build/brilliantsole.module.js";
2
+ import * as THREE from "https://cdnjs.cloudflare.com/ajax/libs/three.js/0.162.0/three.module.min.js";
3
+
4
+ window.BS = BS;
5
+ console.log({ BS });
6
+ //BS.setAllConsoleLevelFlags({ log: true });
7
+
8
+ let device = new BS.Device();
9
+ console.log({ device });
10
+ window.device = device;
11
+
12
+ // GET DEVICES
13
+
14
+ /** @type {HTMLTemplateElement} */
15
+ const availableDeviceTemplate = document.getElementById("availableDeviceTemplate");
16
+ const availableDevicesContainer = document.getElementById("availableDevices");
17
+ /** @param {BS.Device[]} availableDevices */
18
+ function onAvailableDevices(availableDevices) {
19
+ availableDevicesContainer.innerHTML = "";
20
+ if (availableDevices.length == 0) {
21
+ availableDevicesContainer.innerText = "no devices available";
22
+ } else {
23
+ availableDevices.forEach((availableDevice) => {
24
+ const availableDeviceContainer = availableDeviceTemplate.content
25
+ .cloneNode(true)
26
+ .querySelector(".availableDevice");
27
+ availableDeviceContainer.querySelector(".name").innerText = availableDevice.name;
28
+ availableDeviceContainer.querySelector(".type").innerText = availableDevice.type;
29
+
30
+ /** @type {HTMLButtonElement} */
31
+ const toggleConnectionButton = availableDeviceContainer.querySelector(".toggleConnection");
32
+ toggleConnectionButton.addEventListener("click", () => {
33
+ device.connectionManager = availableDevice.connectionManager;
34
+ device.reconnect();
35
+ });
36
+ device.addEventListener("connectionStatus", () => {
37
+ toggleConnectionButton.disabled = device.connectionStatus != "notConnected";
38
+ });
39
+ toggleConnectionButton.disabled = device.connectionStatus != "notConnected";
40
+
41
+ availableDevicesContainer.appendChild(availableDeviceContainer);
42
+ });
43
+ }
44
+ }
45
+ async function getDevices() {
46
+ const availableDevices = await BS.DeviceManager.GetDevices();
47
+ if (!availableDevices) {
48
+ return;
49
+ }
50
+ onAvailableDevices(availableDevices);
51
+ }
52
+
53
+ BS.DeviceManager.AddEventListener("availableDevices", (event) => {
54
+ const devices = event.message.availableDevices;
55
+ onAvailableDevices(devices);
56
+ });
57
+ getDevices();
58
+
59
+ // CONNECTION
60
+
61
+ /** @type {HTMLButtonElement} */
62
+ const toggleConnectionButton = document.getElementById("toggleConnection");
63
+ toggleConnectionButton.addEventListener("click", () => {
64
+ switch (device.connectionStatus) {
65
+ case "notConnected":
66
+ device.connect();
67
+ break;
68
+ case "connected":
69
+ device.disconnect();
70
+ break;
71
+ }
72
+ });
73
+ device.addEventListener("connectionStatus", () => {
74
+ switch (device.connectionStatus) {
75
+ case "connected":
76
+ case "notConnected":
77
+ toggleConnectionButton.disabled = false;
78
+ toggleConnectionButton.innerText = device.isConnected ? "disconnect" : "connect";
79
+ break;
80
+ case "connecting":
81
+ case "disconnecting":
82
+ toggleConnectionButton.disabled = true;
83
+ toggleConnectionButton.innerText = device.connectionStatus;
84
+ break;
85
+ }
86
+ });
87
+
88
+ /** @param {BS.Device} connectedDevice */
89
+ function onConnectedDevice(connectedDevice) {
90
+ device = connectedDevice;
91
+ device.addEventListener("getSensorConfiguration", () => {
92
+ onSensorConfiguration(device);
93
+ });
94
+ updateSensorRateInputs(device);
95
+ onSensorConfiguration(device);
96
+ addSensorDataEventListeners(device);
97
+ }
98
+
99
+ // SENSOR CONFIGURATION
100
+
101
+ /** @type {HTMLTemplateElement} */
102
+ const sensorTypeConfigurationTemplate = document.getElementById("sensorTypeConfigurationTemplate");
103
+ BS.ContinuousSensorTypes.forEach((sensorType) => {
104
+ const sensorTypeConfigurationContainer = sensorTypeConfigurationTemplate.content
105
+ .cloneNode(true)
106
+ .querySelector(".sensorTypeConfiguration");
107
+ sensorTypeConfigurationContainer.querySelector(".sensorType").innerText = sensorType;
108
+
109
+ /** @type {HTMLInputElement} */
110
+ const sensorRateInput = sensorTypeConfigurationContainer.querySelector(".sensorRate");
111
+ sensorRateInput.value = 0;
112
+ sensorRateInput.max = BS.MaxSensorRate;
113
+ sensorRateInput.step = BS.SensorRateStep;
114
+ sensorRateInput.addEventListener("input", () => {
115
+ const sensorRate = Number(sensorRateInput.value);
116
+ console.log({ sensorType, sensorRate });
117
+ device.setSensorConfiguration({ [sensorType]: sensorRate });
118
+ });
119
+
120
+ sensorTypeConfigurationTemplate.parentElement.appendChild(sensorTypeConfigurationContainer);
121
+ sensorTypeConfigurationContainer.dataset.sensorType = sensorType;
122
+ });
123
+ /** @param {BS.Device} device */
124
+ function onSensorConfiguration(device) {
125
+ for (const sensorType in device.sensorConfiguration) {
126
+ const sensorRate = device.sensorConfiguration[sensorType];
127
+ /** @type {HTMLInputElement?} */
128
+ const input = document.querySelector(`.sensorTypeConfiguration[data-sensor-type="${sensorType}"] input`);
129
+ if (input) {
130
+ input.value = sensorRate;
131
+ }
132
+ const chartContainer = chartContainers[sensorType];
133
+ if (chartContainer) {
134
+ const _chartContainers = [chartContainer];
135
+ switch (sensorType) {
136
+ case "gameRotation":
137
+ case "rotation":
138
+ _chartContainers.push(chartContainers[`${sensorType}.euler`]);
139
+ break;
140
+ case "pressure":
141
+ _chartContainers.push(chartContainers["pressureMetadata"]);
142
+ break;
143
+ }
144
+ _chartContainers.forEach((chartContainer) => {
145
+ const display = sensorRate == 0 ? "none" : "";
146
+ chartContainer.style.display = display;
147
+ });
148
+ }
149
+ }
150
+ }
151
+ /** @param {BS.Device} device */
152
+ function updateSensorRateInputs(device) {
153
+ for (const sensorType in device.sensorConfiguration) {
154
+ /** @type {HTMLInputElement?} */
155
+ const input = document.querySelector(`[data-sensor-type="${sensorType}"] input`);
156
+ if (input) {
157
+ input.disabled = !device.isConnected;
158
+ }
159
+ }
160
+ }
161
+
162
+ // GRAPHING
163
+
164
+ let borderWidth = 5;
165
+
166
+ const charts = {};
167
+ window.charts = charts;
168
+
169
+ /**
170
+ * @typedef range
171
+ * @type {object}
172
+ * @property {number} min
173
+ * @property {number} max
174
+ */
175
+
176
+ window.maxTicks = 100;
177
+ /**
178
+ * @param {HTMLCanvasElement} canvas
179
+ * @param {string} title
180
+ * @param {string[]?} axesLabels
181
+ * @param {range} yRange
182
+ */
183
+ function createChart(canvas, title, axesLabels, yRange) {
184
+ const data = {
185
+ labels: new Array(window.maxTicks).fill(0),
186
+ datasets: [],
187
+ };
188
+
189
+ axesLabels?.forEach((label) => {
190
+ data.datasets.push({
191
+ label,
192
+ data: new Array(window.maxTicks).fill(0),
193
+ radius: 0,
194
+ borderWidth,
195
+ });
196
+ });
197
+
198
+ const scales = {
199
+ y: {
200
+ display: false,
201
+ },
202
+ x: {
203
+ display: false,
204
+ },
205
+ };
206
+ if (yRange) {
207
+ Object.assign(scales.y, yRange);
208
+ }
209
+
210
+ const config = {
211
+ type: "line",
212
+ data,
213
+ options: {
214
+ responsive: true,
215
+ plugins: {
216
+ legend: {
217
+ position: "top",
218
+ labels: {
219
+ font: {
220
+ //size: 20,
221
+ },
222
+ },
223
+ },
224
+ title: {
225
+ display: true,
226
+ text: title,
227
+ font: {
228
+ //size: 20,
229
+ },
230
+ },
231
+ },
232
+ scales,
233
+ },
234
+ };
235
+
236
+ const chart = new Chart(canvas, config);
237
+ charts[title] = chart;
238
+
239
+ const appendData = (timestamp, data) => {
240
+ console.log({ timestamp, data });
241
+ chart.data.labels.push(timestamp);
242
+
243
+ if (chart.data.datasets.length == 0) {
244
+ data.forEach((_, index) => {
245
+ chart.data.datasets.push({
246
+ label: index,
247
+ data: new Array(window.maxTicks).fill(0),
248
+ radius: 0,
249
+ borderWidth,
250
+ });
251
+ });
252
+ }
253
+
254
+ chart.data.datasets.forEach((dataset) => {
255
+ dataset.data.push(data[dataset.label]);
256
+ });
257
+
258
+ while (chart.data.labels.length > window.maxTicks) {
259
+ chart.data.labels.shift();
260
+ chart.data.datasets.forEach((dataset) => {
261
+ dataset.data.shift();
262
+ });
263
+ }
264
+
265
+ chart.update("none");
266
+ };
267
+ chart._appendData = appendData;
268
+ return appendData;
269
+ }
270
+
271
+ const chartsContainer = document.getElementById("charts");
272
+ /** @type {Object<string, HTMLElement>} */
273
+ const chartContainers = {};
274
+ window.chartContainers = chartContainers;
275
+
276
+ /** @type {HTMLTemplateElement} */
277
+ const chartTemplate = document.getElementById("chartTemplate");
278
+ BS.ContinuousSensorTypes.forEach((sensorType) => {
279
+ const chartContainer = chartTemplate.content.cloneNode(true).querySelector(".chart");
280
+ chartsContainer.appendChild(chartContainer);
281
+ chartContainers[sensorType] = chartContainer;
282
+
283
+ /** @type {string[]?} */
284
+ let axesLabels;
285
+ switch (sensorType) {
286
+ case "pressure":
287
+ break;
288
+ case "acceleration":
289
+ case "gravity":
290
+ case "linearAcceleration":
291
+ case "magnetometer":
292
+ axesLabels = ["x", "y", "z"];
293
+ break;
294
+ case "gyroscope":
295
+ axesLabels = ["x", "y", "z"];
296
+ //axesLabels = ["pitch", "yaw", "roll"];
297
+ break;
298
+ case "gameRotation":
299
+ case "rotation":
300
+ axesLabels = ["x", "y", "z", "w"];
301
+ break;
302
+ default:
303
+ console.warn(`uncaught sensorType "${sensorType}"`);
304
+ return;
305
+ }
306
+
307
+ /** @type {range?} */
308
+ let yRange;
309
+ switch (sensorType) {
310
+ case "pressure":
311
+ yRange = { min: 0, max: 1 };
312
+ break;
313
+ case "acceleration":
314
+ yRange = { min: -2, max: 2 };
315
+ break;
316
+ case "gravity":
317
+ yRange = { min: -1, max: 1 };
318
+ break;
319
+ case "linearAcceleration":
320
+ yRange = { min: -1, max: 1 };
321
+ break;
322
+ case "gyroscope":
323
+ yRange = { min: -360, max: 360 };
324
+ break;
325
+ case "magnetometer":
326
+ // FILL
327
+ break;
328
+ case "gameRotation":
329
+ case "rotation":
330
+ yRange = { min: -1, max: 1 };
331
+ break;
332
+ }
333
+
334
+ switch (sensorType) {
335
+ case "gameRotation":
336
+ case "rotation":
337
+ {
338
+ const eulerChartContainer = chartTemplate.content.cloneNode(true).querySelector(".chart");
339
+ chartsContainer.appendChild(eulerChartContainer);
340
+ chartContainers[`${sensorType}.euler`] = eulerChartContainer;
341
+ createChart(eulerChartContainer.querySelector("canvas"), sensorType + "Euler", ["yaw", "pitch", "roll"], {
342
+ min: -Math.PI,
343
+ max: Math.PI,
344
+ });
345
+ }
346
+ break;
347
+ case "pressure":
348
+ {
349
+ const pressureMetadataChartContainer = chartTemplate.content.cloneNode(true).querySelector(".chart");
350
+ chartsContainer.appendChild(pressureMetadataChartContainer);
351
+ chartContainers["pressureMetadata"] = pressureMetadataChartContainer;
352
+ createChart(pressureMetadataChartContainer.querySelector("canvas"), "pressureMetadata", ["sum", "x", "y"], {
353
+ min: 0,
354
+ max: 1,
355
+ });
356
+ }
357
+ break;
358
+ }
359
+
360
+ const quaternion = new THREE.Quaternion();
361
+ const euler = new THREE.Euler();
362
+ euler.reorder("YXZ");
363
+
364
+ createChart(chartContainer.querySelector("canvas"), sensorType, axesLabels, yRange);
365
+ });
366
+
367
+ /** @param {BS.Device} device */
368
+ function addSensorDataEventListeners(device) {
369
+ BS.ContinuousSensorTypes.forEach((sensorType) => {
370
+ const chart = charts[sensorType];
371
+ if (!chart) {
372
+ return;
373
+ }
374
+ const appendData = chart._appendData;
375
+ device.addEventListener(sensorType, (event) => {
376
+ let { timestamp, [sensorType]: data } = event.message;
377
+
378
+ if (sensorType == "pressure") {
379
+ /** @type {BS.PressureData} */
380
+ let pressure = data;
381
+ data = pressure.sensors.map((sensor) => sensor.normalizedValue);
382
+ }
383
+ appendData(timestamp, data);
384
+
385
+ switch (sensorType) {
386
+ case "gameRotation":
387
+ case "rotation":
388
+ quaternion.copy(data);
389
+ euler.setFromQuaternion(quaternion);
390
+ charts[sensorType + "Euler"]._appendData(timestamp, {
391
+ pitch: euler.x,
392
+ yaw: euler.y,
393
+ roll: euler.z,
394
+ });
395
+ break;
396
+ case "pressure":
397
+ {
398
+ /** @type {BS.PressureData} */
399
+ let pressure = event.message.pressure;
400
+ charts.pressureMetadata._appendData(timestamp, {
401
+ sum: pressure.normalizedSum,
402
+ x: pressure.normalizedCenter?.x || 0,
403
+ y: pressure.normalizedCenter?.y || 0,
404
+ });
405
+ }
406
+ break;
407
+ }
408
+ });
409
+ });
410
+ }
411
+
412
+ // TESTING
413
+
414
+ /**
415
+ * @param {number} min
416
+ * @param {number} max
417
+ */
418
+ function randomValueBetween(min, max) {
419
+ const range = max - min;
420
+ return min + Math.random() * range;
421
+ }
422
+
423
+ let interval = 10;
424
+ let timestamp = 0;
425
+ if (false)
426
+ window.setInterval(() => {
427
+ charts.acceleration._appendData(timestamp, {
428
+ x: randomValueBetween(-1, 1),
429
+ y: randomValueBetween(-1, 1),
430
+ z: randomValueBetween(-1, 1),
431
+ });
432
+
433
+ timestamp += interval;
434
+ }, interval);
435
+
436
+ // SERVER
437
+
438
+ const websocketClient = new BS.WebSocketClient();
439
+ /** @type {HTMLButtonElement} */
440
+ const toggleServerConnectionButton = document.getElementById("toggleServerConnection");
441
+ toggleServerConnectionButton.addEventListener("click", () => {
442
+ websocketClient.toggleConnection();
443
+ });
444
+ websocketClient.addEventListener("isConnected", () => {
445
+ toggleServerConnectionButton.innerText = websocketClient.isConnected ? "disconnect from server" : "connect to server";
446
+ });
447
+ websocketClient.addEventListener("connectionStatus", () => {
448
+ let disabled;
449
+ switch (websocketClient.connectionStatus) {
450
+ case "notConnected":
451
+ case "connected":
452
+ disabled = false;
453
+ break;
454
+ case "connecting":
455
+ case "disconnecting":
456
+ disabled = true;
457
+ break;
458
+ }
459
+ toggleServerConnectionButton.disabled = disabled;
460
+ });
461
+
462
+ BS.DeviceManager.AddEventListener("connectedDevices", (event) => {
463
+ const { connectedDevices } = event.message;
464
+ const connectedDevice = connectedDevices[0];
465
+ if (!connectedDevice) {
466
+ return;
467
+ }
468
+ onConnectedDevice(connectedDevice);
469
+ });