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.
- package/README.md +16 -10
- package/assets/3d/anchor.glb +0 -0
- package/assets/3d/coin.glb +0 -0
- package/assets/3d/glasses.glb +0 -0
- package/assets/3d/rightHand.glb +0 -0
- package/assets/audio/bounceMedium.wav +0 -0
- package/assets/audio/bounceStrong.wav +0 -0
- package/assets/audio/bounceWeak.wav +0 -0
- package/assets/audio/coin.wav +0 -0
- package/assets/audio/getUp.wav +0 -0
- package/assets/audio/grab.wav +0 -0
- package/assets/audio/kick.wav +0 -0
- package/assets/audio/platterFadeIn old.wav +0 -0
- package/assets/audio/platterFadeIn.wav +0 -0
- package/assets/audio/platterFadeOut.wav +0 -0
- package/assets/audio/punch.wav +0 -0
- package/assets/audio/punchSqueak.wav +0 -0
- package/assets/audio/purr.wav +0 -0
- package/assets/audio/purrFadeOut.wav +0 -0
- package/assets/audio/release.wav +0 -0
- package/assets/audio/splat.wav +0 -0
- package/assets/audio/stomp.wav +0 -0
- package/assets/images/ukaton-pressure-0.svg +9 -0
- package/assets/images/ukaton-pressure-1.svg +9 -0
- package/assets/images/ukaton-pressure-10.svg +9 -0
- package/assets/images/ukaton-pressure-11.svg +9 -0
- package/assets/images/ukaton-pressure-12.svg +9 -0
- package/assets/images/ukaton-pressure-13.svg +9 -0
- package/assets/images/ukaton-pressure-14.svg +9 -0
- package/assets/images/ukaton-pressure-15.svg +9 -0
- package/assets/images/ukaton-pressure-2.svg +9 -0
- package/assets/images/ukaton-pressure-3.svg +9 -0
- package/assets/images/ukaton-pressure-4.svg +9 -0
- package/assets/images/ukaton-pressure-5.svg +9 -0
- package/assets/images/ukaton-pressure-6.svg +9 -0
- package/assets/images/ukaton-pressure-7.svg +9 -0
- package/assets/images/ukaton-pressure-8.svg +9 -0
- package/assets/images/ukaton-pressure-9.svg +9 -0
- package/assets/images/ukaton-right-insole.svg +798 -0
- package/build/brilliantsole.cjs +2870 -882
- package/build/brilliantsole.cjs.map +1 -1
- package/build/brilliantsole.js +2477 -782
- package/build/brilliantsole.js.map +1 -1
- package/build/brilliantsole.ls.js +2260 -592
- package/build/brilliantsole.ls.js.map +1 -1
- package/build/brilliantsole.min.js +1 -1
- package/build/brilliantsole.min.js.map +1 -1
- package/build/brilliantsole.module.d.ts +302 -116
- package/build/brilliantsole.module.js +2468 -782
- package/build/brilliantsole.module.js.map +1 -1
- package/build/brilliantsole.module.min.d.ts +302 -116
- package/build/brilliantsole.module.min.js +1 -1
- package/build/brilliantsole.module.min.js.map +1 -1
- package/build/brilliantsole.node.module.d.ts +295 -113
- package/build/brilliantsole.node.module.js +2860 -882
- package/build/brilliantsole.node.module.js.map +1 -1
- package/build/dts/BS-output.d.ts +10 -0
- package/build/dts/BS.d.ts +21 -9
- package/build/dts/CameraManager.d.ts +72 -0
- package/build/dts/Device.d.ts +53 -16
- package/build/dts/DeviceInformationManager.d.ts +4 -4
- package/build/dts/DeviceManager.d.ts +3 -0
- package/build/dts/FileTransferManager.d.ts +18 -8
- package/build/dts/InformationManager.d.ts +8 -5
- package/build/dts/TfliteManager.d.ts +22 -2
- package/build/dts/WifiManager.d.ts +61 -0
- package/build/dts/connection/BaseConnectionManager.d.ts +37 -3
- package/build/dts/connection/ClientConnectionManager.d.ts +11 -2
- package/build/dts/connection/bluetooth/BluetoothConnectionManager.d.ts +1 -0
- package/build/dts/connection/bluetooth/NobleConnectionManager.d.ts +3 -1
- package/build/dts/connection/bluetooth/WebBluetoothConnectionManager.d.ts +2 -0
- package/build/dts/connection/bluetooth/bluetoothUUIDs.d.ts +2 -2
- package/build/dts/connection/udp/UDPConnectionManager.d.ts +28 -0
- package/build/dts/connection/webSocket/WebSocketConnectionManager.d.ts +25 -0
- package/build/dts/devicePair/DevicePair.d.ts +14 -10
- package/build/dts/devicePair/DevicePairPressureSensorDataManager.d.ts +8 -4
- package/build/dts/devicePair/DevicePairSensorDataManager.d.ts +2 -2
- package/build/dts/scanner/BaseScanner.d.ts +4 -1
- package/build/dts/scanner/NobleScanner.d.ts +2 -1
- package/build/dts/sensor/MotionSensorDataManager.d.ts +5 -2
- package/build/dts/sensor/SensorDataManager.d.ts +5 -4
- package/build/dts/server/BaseClient.d.ts +6 -3
- package/build/dts/server/ServerUtils.d.ts +1 -1
- package/build/dts/server/websocket/WebSocketUtils.d.ts +1 -1
- package/build/dts/utils/CenterOfPressureHelper.d.ts +2 -2
- package/build/dts/utils/Console.d.ts +2 -0
- package/build/dts/utils/MathUtils.d.ts +2 -0
- package/build/dts/utils/ThrottleUtils.d.ts +2 -0
- package/build/dts/vibration/VibrationManager.d.ts +19 -2
- package/build/index.d.ts +299 -113
- package/build/index.node.d.ts +292 -110
- package/examples/3d/scene.html +19 -5
- package/examples/3d/script.js +90 -17
- package/examples/3d-generic/index.html +144 -0
- package/examples/3d-generic/script.js +266 -0
- package/examples/balance/script.js +2 -1
- package/examples/basic/index.html +232 -18
- package/examples/basic/script.js +746 -106
- package/examples/bottango/index.html +11 -1
- package/examples/bottango/script.js +2 -2
- package/examples/center-of-pressure/index.html +114 -114
- package/examples/center-of-pressure/script.js +1 -1
- package/examples/device-pair/index.html +58 -58
- package/examples/device-pair/script.js +12 -8
- package/examples/edge-impulse/script.js +135 -44
- package/examples/edge-impulse-test/README.md +11 -0
- package/examples/edge-impulse-test/edge-impulse-standalone.js +7228 -0
- package/examples/edge-impulse-test/edge-impulse-standalone.wasm +0 -0
- package/examples/edge-impulse-test/index.html +75 -0
- package/examples/edge-impulse-test/run-impulse.js +135 -0
- package/examples/edge-impulse-test/script.js +200 -0
- package/examples/gloves/edge-impulse-standalone.js +7228 -0
- package/examples/gloves/edge-impulse-standalone.wasm +0 -0
- package/examples/gloves/index.html +119 -0
- package/examples/gloves/run-impulse.js +135 -0
- package/examples/gloves/scene.html +124 -0
- package/examples/gloves/script.js +931 -0
- package/examples/graph/index.html +11 -1
- package/examples/graph/script.js +94 -37
- package/examples/pressure/index.html +180 -12
- package/examples/pressure/script.js +144 -7
- package/examples/punch/index.html +135 -0
- package/examples/punch/punch.tflite +0 -0
- package/examples/punch/script.js +169 -0
- package/examples/recording/index.html +191 -183
- package/examples/server/index.html +109 -23
- package/examples/server/script.js +322 -111
- package/examples/ukaton-firmware-update/index.html +20 -0
- package/examples/ukaton-firmware-update/manifest.json +11 -0
- package/examples/ukaton-firmware-update/merged-firmware.bin +0 -0
- package/examples/utils/aframe/aframe-master.min.js +2 -0
- package/examples/utils/aframe/bs-vibration.js +150 -0
- package/examples/utils/aframe/force-pushable.js +80 -0
- package/examples/utils/aframe/grabbable-anchor.js +46 -0
- package/examples/utils/aframe/grabbable-listener.js +31 -0
- package/examples/utils/aframe/grabbable-physics-body.js +190 -0
- package/examples/utils/aframe/grow-shrink.js +25 -0
- package/examples/utils/aframe/hand-punch.js +119 -0
- package/examples/utils/aframe/my-obb-collider.js +293 -0
- package/examples/utils/aframe/occlude-hand-tracking-controls.js +47 -0
- package/examples/utils/aframe/occlude-mesh.js +42 -0
- package/examples/utils/aframe/palm-up-detector.js +47 -0
- package/examples/utils/aframe/shadow-material.js +20 -0
- package/examples/utils/aframe/soft-shadow-light.js +9 -0
- package/examples/webxr/script.js +3 -3
- package/examples/webxr-2/assets/3d/soccerBall.glb +0 -0
- package/examples/webxr-2/assets/audio/shellBounce.wav +0 -0
- package/examples/webxr-2/assets/audio/shellHit.wav +0 -0
- package/examples/webxr-2/assets/audio/shellKick.wav +0 -0
- package/examples/webxr-2/assets/audio/soccerBounce.wav +0 -0
- package/examples/webxr-2/assets/audio/soccerKick.mp3 +0 -0
- package/examples/webxr-2/assets/images/shellTexture.png +0 -0
- package/examples/webxr-2/components/bs-ankle.js +337 -0
- package/examples/webxr-2/components/coin.js +84 -0
- package/examples/webxr-2/components/custom-wrap.js +17 -0
- package/examples/webxr-2/components/goomba.js +3250 -0
- package/examples/webxr-2/components/init-shell-material.js +215 -0
- package/examples/webxr-2/components/platter.js +172 -0
- package/examples/webxr-2/components/shell.js +374 -0
- package/examples/webxr-2/components/soccer-ball.js +250 -0
- package/examples/webxr-2/components/squashed-goomba.js +249 -0
- package/examples/webxr-2/edge-impulse-standalone.js +7228 -0
- package/examples/webxr-2/edge-impulse-standalone.wasm +0 -0
- package/examples/webxr-2/index.html +996 -0
- package/examples/webxr-2/kick.tflite +0 -0
- package/examples/webxr-2/kick2.tflite +0 -0
- package/examples/webxr-2/run-impulse.js +135 -0
- package/examples/webxr-2/script.js +384 -0
- package/package.json +2 -1
- package/src/.prettierrc +4 -0
- package/src/BS.ts +66 -9
- package/src/CameraManager.ts +499 -0
- package/src/Device.ts +620 -92
- package/src/DeviceInformationManager.ts +22 -11
- package/src/DeviceManager.ts +94 -25
- package/src/FileTransferManager.ts +146 -21
- package/src/FirmwareManager.ts +1 -1
- package/src/InformationManager.ts +62 -20
- package/src/TfliteManager.ts +172 -26
- package/src/WifiManager.ts +323 -0
- package/src/connection/BaseConnectionManager.ts +145 -30
- package/src/connection/ClientConnectionManager.ts +47 -11
- package/src/connection/bluetooth/BluetoothConnectionManager.ts +14 -3
- package/src/connection/bluetooth/NobleConnectionManager.ts +155 -42
- package/src/connection/bluetooth/WebBluetoothConnectionManager.ts +104 -35
- package/src/connection/bluetooth/bluetoothUUIDs.ts +40 -13
- package/src/connection/udp/UDPConnectionManager.ts +356 -0
- package/src/connection/websocket/WebSocketConnectionManager.ts +282 -0
- package/src/devicePair/DevicePair.ts +145 -49
- package/src/devicePair/DevicePairPressureSensorDataManager.ts +72 -24
- package/src/devicePair/DevicePairSensorDataManager.ts +5 -5
- package/src/scanner/BaseScanner.ts +49 -11
- package/src/scanner/NobleScanner.ts +81 -17
- package/src/sensor/BarometerSensorDataManager.ts +1 -1
- package/src/sensor/MotionSensorDataManager.ts +22 -7
- package/src/sensor/PressureSensorDataManager.ts +47 -13
- package/src/sensor/SensorConfigurationManager.ts +75 -24
- package/src/sensor/SensorDataManager.ts +107 -26
- package/src/server/BaseClient.ts +192 -37
- package/src/server/BaseServer.ts +201 -43
- package/src/server/ServerUtils.ts +39 -9
- package/src/server/udp/UDPServer.ts +74 -23
- package/src/server/udp/UDPUtils.ts +9 -2
- package/src/server/websocket/WebSocketClient.ts +30 -9
- package/src/server/websocket/WebSocketServer.ts +1 -1
- package/src/server/websocket/WebSocketUtils.ts +4 -2
- package/src/utils/CenterOfPressureHelper.ts +5 -5
- package/src/utils/Console.ts +62 -9
- package/src/utils/MathUtils.ts +31 -1
- package/src/utils/ParseUtils.ts +25 -6
- package/src/utils/ThrottleUtils.ts +62 -0
- package/src/utils/Timer.ts +1 -1
- package/src/utils/checksum.ts +1 -1
- package/src/utils/mcumgr.js +1 -1
- package/src/vibration/VibrationManager.ts +166 -40
package/examples/basic/script.js
CHANGED
|
@@ -11,7 +11,9 @@ window.device = device;
|
|
|
11
11
|
|
|
12
12
|
// GET DEVICES
|
|
13
13
|
/** @type {HTMLTemplateElement} */
|
|
14
|
-
const availableDeviceTemplate = document.getElementById(
|
|
14
|
+
const availableDeviceTemplate = document.getElementById(
|
|
15
|
+
"availableDeviceTemplate"
|
|
16
|
+
);
|
|
15
17
|
const availableDevicesContainer = document.getElementById("availableDevices");
|
|
16
18
|
/** @param {BS.Device[]} availableDevices */
|
|
17
19
|
function onAvailableDevices(availableDevices) {
|
|
@@ -23,19 +25,24 @@ function onAvailableDevices(availableDevices) {
|
|
|
23
25
|
const availableDeviceContainer = availableDeviceTemplate.content
|
|
24
26
|
.cloneNode(true)
|
|
25
27
|
.querySelector(".availableDevice");
|
|
26
|
-
availableDeviceContainer.querySelector(".name").innerText =
|
|
27
|
-
|
|
28
|
+
availableDeviceContainer.querySelector(".name").innerText =
|
|
29
|
+
availableDevice.name;
|
|
30
|
+
availableDeviceContainer.querySelector(".type").innerText =
|
|
31
|
+
availableDevice.type;
|
|
28
32
|
|
|
29
33
|
/** @type {HTMLButtonElement} */
|
|
30
|
-
const toggleConnectionButton =
|
|
34
|
+
const toggleConnectionButton =
|
|
35
|
+
availableDeviceContainer.querySelector(".toggleConnection");
|
|
31
36
|
toggleConnectionButton.addEventListener("click", () => {
|
|
32
37
|
device.connectionManager = availableDevice.connectionManager;
|
|
33
38
|
device.reconnect();
|
|
34
39
|
});
|
|
35
40
|
device.addEventListener("connectionStatus", () => {
|
|
36
|
-
toggleConnectionButton.disabled =
|
|
41
|
+
toggleConnectionButton.disabled =
|
|
42
|
+
device.connectionStatus != "notConnected";
|
|
37
43
|
});
|
|
38
|
-
toggleConnectionButton.disabled =
|
|
44
|
+
toggleConnectionButton.disabled =
|
|
45
|
+
device.connectionStatus != "notConnected";
|
|
39
46
|
|
|
40
47
|
availableDevicesContainer.appendChild(availableDeviceContainer);
|
|
41
48
|
});
|
|
@@ -84,7 +91,9 @@ device.addEventListener("connectionStatus", () => {
|
|
|
84
91
|
case "connected":
|
|
85
92
|
case "notConnected":
|
|
86
93
|
toggleConnectionButton.disabled = false;
|
|
87
|
-
toggleConnectionButton.innerText = device.isConnected
|
|
94
|
+
toggleConnectionButton.innerText = device.isConnected
|
|
95
|
+
? "disconnect"
|
|
96
|
+
: "connect";
|
|
88
97
|
break;
|
|
89
98
|
case "connecting":
|
|
90
99
|
case "disconnecting":
|
|
@@ -95,7 +104,29 @@ device.addEventListener("connectionStatus", () => {
|
|
|
95
104
|
});
|
|
96
105
|
|
|
97
106
|
/** @type {HTMLInputElement} */
|
|
98
|
-
const
|
|
107
|
+
const connectIpAddressInput = document.getElementById("connectIpAddress");
|
|
108
|
+
connectIpAddressInput.addEventListener("input", () => {
|
|
109
|
+
const isValid = connectIpAddressInput.checkValidity();
|
|
110
|
+
connectViaIpAddressButton.disabled = !isValid;
|
|
111
|
+
});
|
|
112
|
+
/** @type {HTMLButtonElement} */
|
|
113
|
+
const connectViaIpAddressButton = document.getElementById(
|
|
114
|
+
"connectViaIpAddress"
|
|
115
|
+
);
|
|
116
|
+
connectViaIpAddressButton.addEventListener("click", () => {
|
|
117
|
+
connectViaIpAddressButton.disabled = true;
|
|
118
|
+
console.log(`connecting via ipAddress "${connectIpAddressInput.value}"`);
|
|
119
|
+
device.connect({ type: "webSocket", ipAddress: connectIpAddressInput.value });
|
|
120
|
+
});
|
|
121
|
+
device.addEventListener("isConnected", () => {
|
|
122
|
+
connectIpAddressInput.disabled = device.isConnected;
|
|
123
|
+
connectViaIpAddressButton.disabled = device.isConnected;
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
/** @type {HTMLInputElement} */
|
|
127
|
+
const reconnectOnDisconnectionCheckbox = document.getElementById(
|
|
128
|
+
"reconnectOnDisconnection"
|
|
129
|
+
);
|
|
99
130
|
reconnectOnDisconnectionCheckbox.addEventListener("input", () => {
|
|
100
131
|
device.reconnectOnDisconnection = reconnectOnDisconnectionCheckbox.checked;
|
|
101
132
|
});
|
|
@@ -103,7 +134,7 @@ reconnectOnDisconnectionCheckbox.addEventListener("input", () => {
|
|
|
103
134
|
/** @type {HTMLButtonElement} */
|
|
104
135
|
const resetDeviceButton = document.getElementById("resetDevice");
|
|
105
136
|
device.addEventListener("isConnected", () => {
|
|
106
|
-
resetDeviceButton.disabled = !device.isConnected;
|
|
137
|
+
resetDeviceButton.disabled = !device.isConnected || !device.canReset;
|
|
107
138
|
});
|
|
108
139
|
resetDeviceButton.addEventListener("click", () => {
|
|
109
140
|
device.reset();
|
|
@@ -114,7 +145,17 @@ resetDeviceButton.addEventListener("click", () => {
|
|
|
114
145
|
/** @type {HTMLPreElement} */
|
|
115
146
|
const deviceInformationPre = document.getElementById("deviceInformationPre");
|
|
116
147
|
device.addEventListener("deviceInformation", () => {
|
|
117
|
-
deviceInformationPre.textContent = JSON.stringify(
|
|
148
|
+
deviceInformationPre.textContent = JSON.stringify(
|
|
149
|
+
device.deviceInformation,
|
|
150
|
+
null,
|
|
151
|
+
2
|
|
152
|
+
);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// MTU
|
|
156
|
+
const deviceMtuSpan = document.getElementById("mtu");
|
|
157
|
+
device.addEventListener("getMtu", () => {
|
|
158
|
+
deviceMtuSpan.innerText = device.mtu;
|
|
118
159
|
});
|
|
119
160
|
|
|
120
161
|
// BATTERY LEVEL
|
|
@@ -141,7 +182,9 @@ device.addEventListener("getBatteryCurrent", () => {
|
|
|
141
182
|
});
|
|
142
183
|
|
|
143
184
|
/** @type {HTMLButtonElement} */
|
|
144
|
-
const updateBatteryCurrentButton = document.getElementById(
|
|
185
|
+
const updateBatteryCurrentButton = document.getElementById(
|
|
186
|
+
"updateBatteryCurrent"
|
|
187
|
+
);
|
|
145
188
|
device.addEventListener("isConnected", () => {
|
|
146
189
|
updateBatteryCurrentButton.disabled = !device.isConnected;
|
|
147
190
|
});
|
|
@@ -225,22 +268,33 @@ setTypeButton.addEventListener("click", () => {
|
|
|
225
268
|
// SENSOR CONFIGURATION
|
|
226
269
|
|
|
227
270
|
/** @type {HTMLPreElement} */
|
|
228
|
-
const sensorConfigurationPre = document.getElementById(
|
|
271
|
+
const sensorConfigurationPre = document.getElementById(
|
|
272
|
+
"sensorConfigurationPre"
|
|
273
|
+
);
|
|
229
274
|
device.addEventListener("getSensorConfiguration", () => {
|
|
230
|
-
sensorConfigurationPre.textContent = JSON.stringify(
|
|
275
|
+
sensorConfigurationPre.textContent = JSON.stringify(
|
|
276
|
+
device.sensorConfiguration,
|
|
277
|
+
null,
|
|
278
|
+
2
|
|
279
|
+
);
|
|
231
280
|
});
|
|
232
281
|
|
|
233
282
|
/** @type {HTMLTemplateElement} */
|
|
234
|
-
const sensorTypeConfigurationTemplate = document.getElementById(
|
|
283
|
+
const sensorTypeConfigurationTemplate = document.getElementById(
|
|
284
|
+
"sensorTypeConfigurationTemplate"
|
|
285
|
+
);
|
|
235
286
|
BS.SensorTypes.forEach((sensorType) => {
|
|
236
287
|
/** @type {HTMLElement} */
|
|
237
|
-
const sensorTypeConfigurationContainer =
|
|
238
|
-
.
|
|
239
|
-
|
|
240
|
-
|
|
288
|
+
const sensorTypeConfigurationContainer =
|
|
289
|
+
sensorTypeConfigurationTemplate.content
|
|
290
|
+
.cloneNode(true)
|
|
291
|
+
.querySelector(".sensorTypeConfiguration");
|
|
292
|
+
sensorTypeConfigurationContainer.querySelector(".sensorType").innerText =
|
|
293
|
+
sensorType;
|
|
241
294
|
|
|
242
295
|
/** @type {HTMLInputElement} */
|
|
243
|
-
const sensorRateInput =
|
|
296
|
+
const sensorRateInput =
|
|
297
|
+
sensorTypeConfigurationContainer.querySelector(".sensorRate");
|
|
244
298
|
sensorRateInput.value = 0;
|
|
245
299
|
sensorRateInput.max = BS.MaxSensorRate;
|
|
246
300
|
sensorRateInput.step = BS.SensorRateStep;
|
|
@@ -258,27 +312,44 @@ BS.SensorTypes.forEach((sensorType) => {
|
|
|
258
312
|
}
|
|
259
313
|
});
|
|
260
314
|
|
|
261
|
-
sensorTypeConfigurationTemplate.parentElement.appendChild(
|
|
315
|
+
sensorTypeConfigurationTemplate.parentElement.appendChild(
|
|
316
|
+
sensorTypeConfigurationContainer
|
|
317
|
+
);
|
|
262
318
|
sensorTypeConfigurationContainer.dataset.sensorType = sensorType;
|
|
263
319
|
});
|
|
264
320
|
device.addEventListener("getSensorConfiguration", () => {
|
|
265
321
|
for (const sensorType in device.sensorConfiguration) {
|
|
266
|
-
document.querySelector(
|
|
267
|
-
|
|
322
|
+
document.querySelector(
|
|
323
|
+
`.sensorTypeConfiguration[data-sensor-type="${sensorType}"] .input`
|
|
324
|
+
).value = device.sensorConfiguration[sensorType];
|
|
268
325
|
}
|
|
269
326
|
});
|
|
270
327
|
device.addEventListener("isConnected", () => {
|
|
271
328
|
for (const sensorType in device.sensorConfiguration) {
|
|
272
|
-
document.querySelector(
|
|
329
|
+
document.querySelector(
|
|
330
|
+
`[data-sensor-type="${sensorType}"] .input`
|
|
331
|
+
).disabled = !device.isConnected;
|
|
273
332
|
}
|
|
274
333
|
});
|
|
275
334
|
|
|
335
|
+
// PRESSURE RANGE
|
|
336
|
+
|
|
337
|
+
/** @type {HTMLButtonElement} */
|
|
338
|
+
const resetPressureRangeButton = document.getElementById("resetPressureRange");
|
|
339
|
+
resetPressureRangeButton.addEventListener("click", () => {
|
|
340
|
+
device.resetPressureRange();
|
|
341
|
+
});
|
|
342
|
+
|
|
276
343
|
// SENSOR DATA
|
|
277
344
|
|
|
278
345
|
/** @type {HTMLTemplateElement} */
|
|
279
|
-
const sensorTypeDataTemplate = document.getElementById(
|
|
346
|
+
const sensorTypeDataTemplate = document.getElementById(
|
|
347
|
+
"sensorTypeDataTemplate"
|
|
348
|
+
);
|
|
280
349
|
BS.SensorTypes.forEach((sensorType) => {
|
|
281
|
-
const sensorTypeDataContainer = sensorTypeDataTemplate.content
|
|
350
|
+
const sensorTypeDataContainer = sensorTypeDataTemplate.content
|
|
351
|
+
.cloneNode(true)
|
|
352
|
+
.querySelector(".sensorTypeData");
|
|
282
353
|
sensorTypeDataContainer.querySelector(".sensorType").innerText = sensorType;
|
|
283
354
|
|
|
284
355
|
/** @type {HTMLPreElement} */
|
|
@@ -297,38 +368,52 @@ BS.SensorTypes.forEach((sensorType) => {
|
|
|
297
368
|
const vibrationTemplate = document.getElementById("vibrationTemplate");
|
|
298
369
|
{
|
|
299
370
|
/** @type {HTMLInputElement} */
|
|
300
|
-
const waveformEffectSequenceLoopCountInput =
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
371
|
+
const waveformEffectSequenceLoopCountInput =
|
|
372
|
+
vibrationTemplate.content.querySelector(
|
|
373
|
+
".waveformEffect .sequenceLoopCount"
|
|
374
|
+
);
|
|
375
|
+
waveformEffectSequenceLoopCountInput.max =
|
|
376
|
+
BS.MaxVibrationWaveformEffectSequenceLoopCount;
|
|
304
377
|
}
|
|
305
378
|
/** @type {HTMLTemplateElement} */
|
|
306
|
-
const vibrationLocationTemplate = document.getElementById(
|
|
379
|
+
const vibrationLocationTemplate = document.getElementById(
|
|
380
|
+
"vibrationLocationTemplate"
|
|
381
|
+
);
|
|
307
382
|
|
|
308
383
|
/** @type {HTMLTemplateElement} */
|
|
309
|
-
const waveformEffectSegmentTemplate = document.getElementById(
|
|
384
|
+
const waveformEffectSegmentTemplate = document.getElementById(
|
|
385
|
+
"waveformEffectSegmentTemplate"
|
|
386
|
+
);
|
|
310
387
|
{
|
|
311
388
|
/** @type {HTMLSelectElement} */
|
|
312
|
-
const waveformEffectSelect =
|
|
389
|
+
const waveformEffectSelect =
|
|
390
|
+
waveformEffectSegmentTemplate.content.querySelector(".effect");
|
|
313
391
|
const waveformEffectOptgroup = waveformEffectSelect.querySelector("optgroup");
|
|
314
392
|
BS.VibrationWaveformEffects.forEach((waveformEffect) => {
|
|
315
393
|
waveformEffectOptgroup.appendChild(new Option(waveformEffect));
|
|
316
394
|
});
|
|
317
395
|
|
|
318
396
|
/** @type {HTMLInputElement} */
|
|
319
|
-
const waveformEffectSegmentDelayInput =
|
|
320
|
-
|
|
397
|
+
const waveformEffectSegmentDelayInput =
|
|
398
|
+
waveformEffectSegmentTemplate.content.querySelector(".delay");
|
|
399
|
+
waveformEffectSegmentDelayInput.max =
|
|
400
|
+
BS.MaxVibrationWaveformEffectSegmentDelay;
|
|
321
401
|
|
|
322
402
|
/** @type {HTMLInputElement} */
|
|
323
|
-
const waveformEffectLoopCountInput =
|
|
324
|
-
|
|
403
|
+
const waveformEffectLoopCountInput =
|
|
404
|
+
waveformEffectSegmentTemplate.content.querySelector(".loopCount");
|
|
405
|
+
waveformEffectLoopCountInput.max =
|
|
406
|
+
BS.MaxVibrationWaveformEffectSegmentLoopCount;
|
|
325
407
|
}
|
|
326
408
|
|
|
327
409
|
/** @type {HTMLTemplateElement} */
|
|
328
|
-
const waveformSegmentTemplate = document.getElementById(
|
|
410
|
+
const waveformSegmentTemplate = document.getElementById(
|
|
411
|
+
"waveformSegmentTemplate"
|
|
412
|
+
);
|
|
329
413
|
{
|
|
330
414
|
/** @type {HTMLInputElement} */
|
|
331
|
-
const waveformDurationSegmentInput =
|
|
415
|
+
const waveformDurationSegmentInput =
|
|
416
|
+
waveformSegmentTemplate.content.querySelector(".duration");
|
|
332
417
|
waveformDurationSegmentInput.max = BS.MaxVibrationWaveformSegmentDuration;
|
|
333
418
|
}
|
|
334
419
|
|
|
@@ -336,7 +421,9 @@ const waveformSegmentTemplate = document.getElementById("waveformSegmentTemplate
|
|
|
336
421
|
const addVibrationButton = document.getElementById("addVibration");
|
|
337
422
|
addVibrationButton.addEventListener("click", () => {
|
|
338
423
|
/** @type {HTMLElement} */
|
|
339
|
-
const vibrationContainer = vibrationTemplate.content
|
|
424
|
+
const vibrationContainer = vibrationTemplate.content
|
|
425
|
+
.cloneNode(true)
|
|
426
|
+
.querySelector(".vibration");
|
|
340
427
|
|
|
341
428
|
/** @type {HTMLButtonElement} */
|
|
342
429
|
const deleteButton = vibrationContainer.querySelector(".delete");
|
|
@@ -346,25 +433,33 @@ addVibrationButton.addEventListener("click", () => {
|
|
|
346
433
|
});
|
|
347
434
|
|
|
348
435
|
/** @type {HTMLUListElement} */
|
|
349
|
-
const vibrationLocationsContainer =
|
|
350
|
-
|
|
436
|
+
const vibrationLocationsContainer =
|
|
437
|
+
vibrationContainer.querySelector(".locations");
|
|
438
|
+
device.vibrationLocations.forEach((vibrationLocation) => {
|
|
351
439
|
const vibrationLocationContainer = vibrationLocationTemplate.content
|
|
352
440
|
.cloneNode(true)
|
|
353
441
|
.querySelector(".vibrationLocation");
|
|
354
|
-
vibrationLocationContainer.querySelector("span").innerText =
|
|
355
|
-
|
|
442
|
+
vibrationLocationContainer.querySelector("span").innerText =
|
|
443
|
+
vibrationLocation;
|
|
444
|
+
vibrationLocationContainer.querySelector(
|
|
445
|
+
"input"
|
|
446
|
+
).dataset.vibrationLocation = vibrationLocation;
|
|
356
447
|
vibrationLocationsContainer.appendChild(vibrationLocationContainer);
|
|
357
448
|
});
|
|
358
449
|
|
|
359
450
|
/** @type {HTMLElement} */
|
|
360
|
-
const waveformEffectContainer =
|
|
451
|
+
const waveformEffectContainer =
|
|
452
|
+
vibrationContainer.querySelector(".waveformEffect");
|
|
361
453
|
/** @type {HTMLUListElement} */
|
|
362
|
-
const waveformEffectSegmentsContainer =
|
|
454
|
+
const waveformEffectSegmentsContainer =
|
|
455
|
+
waveformEffectContainer.querySelector(".segments");
|
|
363
456
|
/** @type {HTMLButtonElement} */
|
|
364
|
-
const addWaveformEffectSegmentButton =
|
|
457
|
+
const addWaveformEffectSegmentButton =
|
|
458
|
+
waveformEffectContainer.querySelector(".add");
|
|
365
459
|
const updateAddWaveformEffectSegmentButton = () => {
|
|
366
460
|
addWaveformEffectSegmentButton.disabled =
|
|
367
|
-
waveformEffectSegmentsContainer.children.length >=
|
|
461
|
+
waveformEffectSegmentsContainer.children.length >=
|
|
462
|
+
BS.MaxNumberOfVibrationWaveformEffectSegments;
|
|
368
463
|
};
|
|
369
464
|
addWaveformEffectSegmentButton.addEventListener("click", () => {
|
|
370
465
|
/** @type {HTMLElement} */
|
|
@@ -372,11 +467,14 @@ addVibrationButton.addEventListener("click", () => {
|
|
|
372
467
|
.cloneNode(true)
|
|
373
468
|
.querySelector(".waveformEffectSegment");
|
|
374
469
|
|
|
375
|
-
const effectContainer =
|
|
376
|
-
|
|
470
|
+
const effectContainer =
|
|
471
|
+
waveformEffectSegmentContainer.querySelector(".effect").parentElement;
|
|
472
|
+
const delayContainer =
|
|
473
|
+
waveformEffectSegmentContainer.querySelector(".delay").parentElement;
|
|
377
474
|
|
|
378
475
|
/** @type {HTMLSelectElement} */
|
|
379
|
-
const waveformEffectTypeSelect =
|
|
476
|
+
const waveformEffectTypeSelect =
|
|
477
|
+
waveformEffectSegmentContainer.querySelector(".type");
|
|
380
478
|
waveformEffectTypeSelect.addEventListener("input", () => {
|
|
381
479
|
let shouldShowEffectContainer = false;
|
|
382
480
|
let shouldShowDelayContainer = false;
|
|
@@ -389,7 +487,9 @@ addVibrationButton.addEventListener("click", () => {
|
|
|
389
487
|
shouldShowDelayContainer = true;
|
|
390
488
|
break;
|
|
391
489
|
default:
|
|
392
|
-
throw Error(
|
|
490
|
+
throw Error(
|
|
491
|
+
`uncaught waveformEffectTypeSelect value "${waveformEffectTypeSelect.value}"`
|
|
492
|
+
);
|
|
393
493
|
}
|
|
394
494
|
|
|
395
495
|
effectContainer.style.display = shouldShowEffectContainer ? "" : "none";
|
|
@@ -397,10 +497,12 @@ addVibrationButton.addEventListener("click", () => {
|
|
|
397
497
|
});
|
|
398
498
|
waveformEffectTypeSelect.dispatchEvent(new Event("input"));
|
|
399
499
|
|
|
400
|
-
waveformEffectSegmentContainer
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
500
|
+
waveformEffectSegmentContainer
|
|
501
|
+
.querySelector(".delete")
|
|
502
|
+
.addEventListener("click", () => {
|
|
503
|
+
waveformEffectSegmentContainer.remove();
|
|
504
|
+
updateAddWaveformEffectSegmentButton();
|
|
505
|
+
});
|
|
404
506
|
|
|
405
507
|
waveformEffectSegmentsContainer.appendChild(waveformEffectSegmentContainer);
|
|
406
508
|
updateAddWaveformEffectSegmentButton();
|
|
@@ -409,22 +511,28 @@ addVibrationButton.addEventListener("click", () => {
|
|
|
409
511
|
/** @type {HTMLElement} */
|
|
410
512
|
const waveformContainer = vibrationContainer.querySelector(".waveform");
|
|
411
513
|
/** @type {HTMLUListElement} */
|
|
412
|
-
const waveformSegmentsContainer =
|
|
514
|
+
const waveformSegmentsContainer =
|
|
515
|
+
waveformContainer.querySelector(".segments");
|
|
413
516
|
|
|
414
517
|
/** @type {HTMLButtonElement} */
|
|
415
518
|
const addWaveformSegmentButton = waveformContainer.querySelector(".add");
|
|
416
519
|
const updateAddWaveformSegmentButton = () => {
|
|
417
520
|
addWaveformSegmentButton.disabled =
|
|
418
|
-
waveformSegmentsContainer.children.length >=
|
|
521
|
+
waveformSegmentsContainer.children.length >=
|
|
522
|
+
BS.MaxNumberOfVibrationWaveformSegments;
|
|
419
523
|
};
|
|
420
524
|
addWaveformSegmentButton.addEventListener("click", () => {
|
|
421
525
|
/** @type {HTMLElement} */
|
|
422
|
-
const waveformSegmentContainer = waveformSegmentTemplate.content
|
|
526
|
+
const waveformSegmentContainer = waveformSegmentTemplate.content
|
|
527
|
+
.cloneNode(true)
|
|
528
|
+
.querySelector(".waveformSegment");
|
|
423
529
|
|
|
424
|
-
waveformSegmentContainer
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
530
|
+
waveformSegmentContainer
|
|
531
|
+
.querySelector(".delete")
|
|
532
|
+
.addEventListener("click", () => {
|
|
533
|
+
waveformSegmentContainer.remove();
|
|
534
|
+
updateAddWaveformSegmentButton();
|
|
535
|
+
});
|
|
428
536
|
|
|
429
537
|
waveformSegmentsContainer.appendChild(waveformSegmentContainer);
|
|
430
538
|
updateAddWaveformSegmentButton();
|
|
@@ -433,7 +541,8 @@ addVibrationButton.addEventListener("click", () => {
|
|
|
433
541
|
/** @type {HTMLSelectElement} */
|
|
434
542
|
const vibrationTypeSelect = vibrationContainer.querySelector(".type");
|
|
435
543
|
/** @type {HTMLOptGroupElement} */
|
|
436
|
-
const vibrationTypeSelectOptgroup =
|
|
544
|
+
const vibrationTypeSelectOptgroup =
|
|
545
|
+
vibrationTypeSelect.querySelector("optgroup");
|
|
437
546
|
BS.VibrationTypes.forEach((vibrationType) => {
|
|
438
547
|
vibrationTypeSelectOptgroup.appendChild(new Option(vibrationType));
|
|
439
548
|
});
|
|
@@ -455,7 +564,9 @@ addVibrationButton.addEventListener("click", () => {
|
|
|
455
564
|
throw Error(`invalid vibrationType "${vibrationType}"`);
|
|
456
565
|
}
|
|
457
566
|
|
|
458
|
-
waveformEffectContainer.style.display = showWaveformEffectContainer
|
|
567
|
+
waveformEffectContainer.style.display = showWaveformEffectContainer
|
|
568
|
+
? ""
|
|
569
|
+
: "none";
|
|
459
570
|
waveformContainer.style.display = showWaveformContainer ? "" : "none";
|
|
460
571
|
});
|
|
461
572
|
vibrationTypeSelect.dispatchEvent(new Event("input"));
|
|
@@ -470,40 +581,60 @@ triggerVibrationsButton.addEventListener("click", () => {
|
|
|
470
581
|
/** @type {BS.VibrationConfiguration[]} */
|
|
471
582
|
let vibrationConfigurations = [];
|
|
472
583
|
Array.from(vibrationTemplate.parentElement.querySelectorAll(".vibration"))
|
|
473
|
-
.filter(
|
|
584
|
+
.filter(
|
|
585
|
+
(vibrationContainer) =>
|
|
586
|
+
vibrationContainer.querySelector(".shouldTrigger").checked
|
|
587
|
+
)
|
|
474
588
|
.forEach((vibrationContainer) => {
|
|
475
589
|
/** @type {BS.VibrationConfiguration} */
|
|
476
590
|
const vibrationConfiguration = {
|
|
477
591
|
locations: [],
|
|
478
592
|
};
|
|
479
|
-
Array.from(
|
|
593
|
+
Array.from(
|
|
594
|
+
vibrationContainer.querySelectorAll(`[data-vibration-location]`)
|
|
595
|
+
)
|
|
480
596
|
.filter((input) => input.checked)
|
|
481
597
|
.forEach((input) => {
|
|
482
|
-
vibrationConfiguration.locations.push(
|
|
598
|
+
vibrationConfiguration.locations.push(
|
|
599
|
+
input.dataset.vibrationLocation
|
|
600
|
+
);
|
|
483
601
|
});
|
|
484
602
|
if (vibrationConfiguration.locations.length == 0) {
|
|
485
603
|
return;
|
|
486
604
|
}
|
|
487
605
|
|
|
488
|
-
vibrationConfiguration.type =
|
|
606
|
+
vibrationConfiguration.type =
|
|
607
|
+
vibrationContainer.querySelector("select.type").value;
|
|
489
608
|
switch (vibrationConfiguration.type) {
|
|
490
609
|
case "waveformEffect":
|
|
491
610
|
vibrationConfiguration.segments = Array.from(
|
|
492
|
-
vibrationContainer.querySelectorAll(
|
|
611
|
+
vibrationContainer.querySelectorAll(
|
|
612
|
+
".waveformEffect .waveformEffectSegment"
|
|
613
|
+
)
|
|
493
614
|
).map((waveformEffectSegmentContainer) => {
|
|
494
615
|
/** @type {BS.VibrationWaveformEffectSegment} */
|
|
495
616
|
const waveformEffectSegment = {
|
|
496
|
-
loopCount: Number(
|
|
617
|
+
loopCount: Number(
|
|
618
|
+
waveformEffectSegmentContainer.querySelector(".loopCount").value
|
|
619
|
+
),
|
|
497
620
|
};
|
|
498
|
-
if (
|
|
499
|
-
|
|
621
|
+
if (
|
|
622
|
+
waveformEffectSegmentContainer.querySelector(".type").value ==
|
|
623
|
+
"effect"
|
|
624
|
+
) {
|
|
625
|
+
waveformEffectSegment.effect =
|
|
626
|
+
waveformEffectSegmentContainer.querySelector(".effect").value;
|
|
500
627
|
} else {
|
|
501
|
-
waveformEffectSegment.delay = Number(
|
|
628
|
+
waveformEffectSegment.delay = Number(
|
|
629
|
+
waveformEffectSegmentContainer.querySelector(".delay").value
|
|
630
|
+
);
|
|
502
631
|
}
|
|
503
632
|
return waveformEffectSegment;
|
|
504
633
|
});
|
|
505
634
|
vibrationConfiguration.loopCount = Number(
|
|
506
|
-
vibrationContainer.querySelector(
|
|
635
|
+
vibrationContainer.querySelector(
|
|
636
|
+
".waveformEffect .sequenceLoopCount"
|
|
637
|
+
).value
|
|
507
638
|
);
|
|
508
639
|
break;
|
|
509
640
|
case "waveform":
|
|
@@ -511,8 +642,12 @@ triggerVibrationsButton.addEventListener("click", () => {
|
|
|
511
642
|
vibrationContainer.querySelectorAll(".waveform .waveformSegment")
|
|
512
643
|
).map((waveformSegmentContainer) => {
|
|
513
644
|
return {
|
|
514
|
-
amplitude: Number(
|
|
515
|
-
|
|
645
|
+
amplitude: Number(
|
|
646
|
+
waveformSegmentContainer.querySelector(".amplitude").value
|
|
647
|
+
),
|
|
648
|
+
duration: Number(
|
|
649
|
+
waveformSegmentContainer.querySelector(".duration").value
|
|
650
|
+
),
|
|
516
651
|
};
|
|
517
652
|
});
|
|
518
653
|
break;
|
|
@@ -532,7 +667,8 @@ device.addEventListener("isConnected", () => {
|
|
|
532
667
|
|
|
533
668
|
function updateTriggerVibrationsButtonDisabled() {
|
|
534
669
|
triggerVibrationsButton.disabled =
|
|
535
|
-
!device.isConnected ||
|
|
670
|
+
!device.isConnected ||
|
|
671
|
+
vibrationTemplate.parentElement.querySelectorAll(".vibration").length == 0;
|
|
536
672
|
}
|
|
537
673
|
|
|
538
674
|
// FILE TRANSFER
|
|
@@ -573,14 +709,28 @@ fileTransferTypesSelect.addEventListener("input", () => {
|
|
|
573
709
|
case "tflite":
|
|
574
710
|
fileInput.accept = ".tflite";
|
|
575
711
|
break;
|
|
712
|
+
case "wifiServerCert":
|
|
713
|
+
fileInput.accept = ".crt";
|
|
714
|
+
break;
|
|
715
|
+
case "wifiServerKey":
|
|
716
|
+
fileInput.accept = ".key";
|
|
717
|
+
break;
|
|
576
718
|
}
|
|
577
719
|
});
|
|
578
720
|
/** @type {HTMLOptGroupElement} */
|
|
579
|
-
const fileTransferTypesOptgroup =
|
|
721
|
+
const fileTransferTypesOptgroup =
|
|
722
|
+
fileTransferTypesSelect.querySelector("optgroup");
|
|
580
723
|
BS.FileTypes.forEach((fileType) => {
|
|
581
724
|
fileTransferTypesOptgroup.appendChild(new Option(fileType));
|
|
582
725
|
});
|
|
583
726
|
fileTransferTypesSelect.dispatchEvent(new Event("input"));
|
|
727
|
+
device.addEventListener("connected", () => {
|
|
728
|
+
fileTransferTypesSelect.querySelectorAll("option").forEach((option) => {
|
|
729
|
+
option.hidden =
|
|
730
|
+
BS.FileTypes.includes(option.value) &&
|
|
731
|
+
!device.fileTypes.includes(option.value);
|
|
732
|
+
});
|
|
733
|
+
});
|
|
584
734
|
|
|
585
735
|
/** @type {HTMLProgressElement} */
|
|
586
736
|
const fileTransferProgress = document.getElementById("fileTransferProgress");
|
|
@@ -613,7 +763,8 @@ toggleFileTransferButton.addEventListener("click", async () => {
|
|
|
613
763
|
}
|
|
614
764
|
});
|
|
615
765
|
const updateToggleFileTransferButton = () => {
|
|
616
|
-
const enabled =
|
|
766
|
+
const enabled =
|
|
767
|
+
device.isConnected && (file || fileTransferDirection == "receive");
|
|
617
768
|
toggleFileTransferButton.disabled = !enabled;
|
|
618
769
|
|
|
619
770
|
/** @type {String} */
|
|
@@ -641,7 +792,9 @@ device.addEventListener("fileTransferStatus", () => {
|
|
|
641
792
|
/** @type {BS.FileTransferDirection} */
|
|
642
793
|
let fileTransferDirection;
|
|
643
794
|
/** @type {HTMLSelectElement} */
|
|
644
|
-
const fileTransferDirectionSelect = document.getElementById(
|
|
795
|
+
const fileTransferDirectionSelect = document.getElementById(
|
|
796
|
+
"fileTransferDirection"
|
|
797
|
+
);
|
|
645
798
|
fileTransferDirectionSelect.addEventListener("input", () => {
|
|
646
799
|
fileTransferDirection = fileTransferDirectionSelect.value;
|
|
647
800
|
console.log({ fileTransferDirection });
|
|
@@ -745,9 +898,13 @@ device.addEventListener("getTfliteInferencingEnabled", () => {
|
|
|
745
898
|
/** @type {HTMLSpanElement} */
|
|
746
899
|
const tfliteSampleRateSpan = document.getElementById("tfliteSampleRate");
|
|
747
900
|
/** @type {HTMLInputElement} */
|
|
748
|
-
const setTfliteSampleRateInput = document.getElementById(
|
|
901
|
+
const setTfliteSampleRateInput = document.getElementById(
|
|
902
|
+
"setTfliteSampleRateInput"
|
|
903
|
+
);
|
|
749
904
|
/** @type {HTMLButtonElement} */
|
|
750
|
-
const setTfliteSampleRateButton = document.getElementById(
|
|
905
|
+
const setTfliteSampleRateButton = document.getElementById(
|
|
906
|
+
"setTfliteSampleRateButton"
|
|
907
|
+
);
|
|
751
908
|
|
|
752
909
|
device.addEventListener("isConnected", () => {
|
|
753
910
|
const disabled = !device.isConnected;
|
|
@@ -779,16 +936,22 @@ device.addEventListener("getTfliteInferencingEnabled", () => {
|
|
|
779
936
|
|
|
780
937
|
const tfliteSensorTypesContainer = document.getElementById("tfliteSensorTypes");
|
|
781
938
|
/** @type {HTMLTemplateElement} */
|
|
782
|
-
const tfliteSensorTypeTemplate = document.getElementById(
|
|
939
|
+
const tfliteSensorTypeTemplate = document.getElementById(
|
|
940
|
+
"tfliteSensorTypeTemplate"
|
|
941
|
+
);
|
|
783
942
|
/** @type {Object.<string, HTMLElement>} */
|
|
784
943
|
const tfliteSensorTypeContainers = {};
|
|
785
944
|
/** @type {BS.SensorType[]} */
|
|
786
945
|
let tfliteSensorTypes = [];
|
|
787
946
|
/** @type {HTMLButtonElement} */
|
|
788
|
-
const setTfliteSensorTypesButton = document.getElementById(
|
|
947
|
+
const setTfliteSensorTypesButton = document.getElementById(
|
|
948
|
+
"setTfliteSensorTypes"
|
|
949
|
+
);
|
|
789
950
|
|
|
790
951
|
BS.TfliteSensorTypes.forEach((sensorType) => {
|
|
791
|
-
const sensorTypeContainer = tfliteSensorTypeTemplate.content
|
|
952
|
+
const sensorTypeContainer = tfliteSensorTypeTemplate.content
|
|
953
|
+
.cloneNode(true)
|
|
954
|
+
.querySelector(".sensorType");
|
|
792
955
|
sensorTypeContainer.querySelector(".name").innerText = sensorType;
|
|
793
956
|
|
|
794
957
|
/** @type {HTMLInputElement} */
|
|
@@ -803,7 +966,8 @@ BS.TfliteSensorTypes.forEach((sensorType) => {
|
|
|
803
966
|
});
|
|
804
967
|
|
|
805
968
|
device.addEventListener("getTfliteSensorTypes", () => {
|
|
806
|
-
isSensorEnabledInput.checked =
|
|
969
|
+
isSensorEnabledInput.checked =
|
|
970
|
+
device.tfliteSensorTypes.includes(sensorType);
|
|
807
971
|
});
|
|
808
972
|
isSensorEnabledInput.checked = device.tfliteSensorTypes.includes(sensorType);
|
|
809
973
|
|
|
@@ -838,9 +1002,13 @@ device.addEventListener("tfliteIsReady", () => {
|
|
|
838
1002
|
/** @type {HTMLSpanElement} */
|
|
839
1003
|
const tfliteThresholdSpan = document.getElementById("tfliteThreshold");
|
|
840
1004
|
/** @type {HTMLInputElement} */
|
|
841
|
-
const setTfliteThresholdInput = document.getElementById(
|
|
1005
|
+
const setTfliteThresholdInput = document.getElementById(
|
|
1006
|
+
"setTfliteThresholdInput"
|
|
1007
|
+
);
|
|
842
1008
|
/** @type {HTMLButtonElement} */
|
|
843
|
-
const setTfliteThresholdButton = document.getElementById(
|
|
1009
|
+
const setTfliteThresholdButton = document.getElementById(
|
|
1010
|
+
"setTfliteThresholdButton"
|
|
1011
|
+
);
|
|
844
1012
|
|
|
845
1013
|
device.addEventListener("isConnected", () => {
|
|
846
1014
|
const disabled = !device.isConnected;
|
|
@@ -870,9 +1038,13 @@ setTfliteThresholdButton.addEventListener("click", () => {
|
|
|
870
1038
|
/** @type {HTMLSpanElement} */
|
|
871
1039
|
const tfliteCaptureDelaySpan = document.getElementById("tfliteCaptureDelay");
|
|
872
1040
|
/** @type {HTMLInputElement} */
|
|
873
|
-
const setTfliteCaptureDelayInput = document.getElementById(
|
|
1041
|
+
const setTfliteCaptureDelayInput = document.getElementById(
|
|
1042
|
+
"setTfliteCaptureDelayInput"
|
|
1043
|
+
);
|
|
874
1044
|
/** @type {HTMLButtonElement} */
|
|
875
|
-
const setTfliteCaptureDelayButton = document.getElementById(
|
|
1045
|
+
const setTfliteCaptureDelayButton = document.getElementById(
|
|
1046
|
+
"setTfliteCaptureDelayButton"
|
|
1047
|
+
);
|
|
876
1048
|
|
|
877
1049
|
device.addEventListener("isConnected", () => {
|
|
878
1050
|
const disabled = !device.isConnected;
|
|
@@ -900,18 +1072,23 @@ setTfliteCaptureDelayButton.addEventListener("click", () => {
|
|
|
900
1072
|
});
|
|
901
1073
|
|
|
902
1074
|
/** @type {HTMLInputElement} */
|
|
903
|
-
const tfliteInferencingEnabledInput = document.getElementById(
|
|
1075
|
+
const tfliteInferencingEnabledInput = document.getElementById(
|
|
1076
|
+
"tfliteInferencingEnabled"
|
|
1077
|
+
);
|
|
904
1078
|
/** @type {HTMLButtonElement} */
|
|
905
|
-
const toggleTfliteInferencingEnabledButton = document.getElementById(
|
|
1079
|
+
const toggleTfliteInferencingEnabledButton = document.getElementById(
|
|
1080
|
+
"toggleTfliteInferencingEnabled"
|
|
1081
|
+
);
|
|
906
1082
|
|
|
907
1083
|
device.addEventListener("tfliteIsReady", () => {
|
|
908
1084
|
toggleTfliteInferencingEnabledButton.disabled = !device.tfliteIsReady;
|
|
909
1085
|
});
|
|
910
1086
|
device.addEventListener("getTfliteInferencingEnabled", () => {
|
|
911
1087
|
tfliteInferencingEnabledInput.checked = device.tfliteInferencingEnabled;
|
|
912
|
-
toggleTfliteInferencingEnabledButton.innerText =
|
|
913
|
-
|
|
914
|
-
|
|
1088
|
+
toggleTfliteInferencingEnabledButton.innerText =
|
|
1089
|
+
device.tfliteInferencingEnabled
|
|
1090
|
+
? "disable inferencing"
|
|
1091
|
+
: "enable inferencing";
|
|
915
1092
|
});
|
|
916
1093
|
|
|
917
1094
|
toggleTfliteInferencingEnabledButton.addEventListener("click", () => {
|
|
@@ -944,7 +1121,8 @@ device.addEventListener("tfliteInference", (event) => {
|
|
|
944
1121
|
tfliteInferencePre.textContent = JSON.stringify(tfliteInference, null, 2);
|
|
945
1122
|
|
|
946
1123
|
if (device.tfliteTask == "classification") {
|
|
947
|
-
topInferenceClassElement.innerText =
|
|
1124
|
+
topInferenceClassElement.innerText =
|
|
1125
|
+
inferenceClasses[tfliteInference.maxIndex - 1] ?? "";
|
|
948
1126
|
}
|
|
949
1127
|
});
|
|
950
1128
|
|
|
@@ -960,7 +1138,9 @@ firmwareInput.addEventListener("input", () => {
|
|
|
960
1138
|
updateToggleFirmwareUploadButton();
|
|
961
1139
|
});
|
|
962
1140
|
/** @type {HTMLButtonElement} */
|
|
963
|
-
const toggleFirmwareUploadButton = document.getElementById(
|
|
1141
|
+
const toggleFirmwareUploadButton = document.getElementById(
|
|
1142
|
+
"toggleFirmwareUpload"
|
|
1143
|
+
);
|
|
964
1144
|
toggleFirmwareUploadButton.addEventListener("click", () => {
|
|
965
1145
|
device.uploadFirmware(firmware);
|
|
966
1146
|
});
|
|
@@ -973,20 +1153,28 @@ device.addEventListener("isConnected", () => {
|
|
|
973
1153
|
});
|
|
974
1154
|
|
|
975
1155
|
/** @type {HTMLProgressElement} */
|
|
976
|
-
const firmwareUploadProgress = document.getElementById(
|
|
1156
|
+
const firmwareUploadProgress = document.getElementById(
|
|
1157
|
+
"firmwareUploadProgress"
|
|
1158
|
+
);
|
|
977
1159
|
/** @type {HTMLSpanElement} */
|
|
978
|
-
const firmwareUploadProgressPercentageSpan = document.getElementById(
|
|
1160
|
+
const firmwareUploadProgressPercentageSpan = document.getElementById(
|
|
1161
|
+
"firmwareUploadProgressPercentage"
|
|
1162
|
+
);
|
|
979
1163
|
device.addEventListener("firmwareUploadProgress", (event) => {
|
|
980
1164
|
const progress = event.message.progress;
|
|
981
1165
|
firmwareUploadProgress.value = progress;
|
|
982
|
-
firmwareUploadProgressPercentageSpan.innerText = `${Math.floor(
|
|
1166
|
+
firmwareUploadProgressPercentageSpan.innerText = `${Math.floor(
|
|
1167
|
+
100 * progress
|
|
1168
|
+
)}%`;
|
|
983
1169
|
});
|
|
984
1170
|
device.addEventListener("firmwareUploadComplete", () => {
|
|
985
1171
|
firmwareUploadProgress.value = 0;
|
|
986
1172
|
});
|
|
987
1173
|
device.addEventListener("firmwareStatus", () => {
|
|
988
1174
|
const isUploading = device.firmwareStatus == "uploading";
|
|
989
|
-
firmwareUploadProgressPercentageSpan.style.display = isUploading
|
|
1175
|
+
firmwareUploadProgressPercentageSpan.style.display = isUploading
|
|
1176
|
+
? ""
|
|
1177
|
+
: "none";
|
|
990
1178
|
});
|
|
991
1179
|
|
|
992
1180
|
/** @type {HTMLPreElement} */
|
|
@@ -1000,7 +1188,7 @@ device.addEventListener("firmwareImages", () => {
|
|
|
1000
1188
|
});
|
|
1001
1189
|
|
|
1002
1190
|
device.addEventListener("isConnected", () => {
|
|
1003
|
-
if (device.isConnected) {
|
|
1191
|
+
if (device.isConnected && device.canUpdateFirmware) {
|
|
1004
1192
|
device.getFirmwareImages();
|
|
1005
1193
|
}
|
|
1006
1194
|
});
|
|
@@ -1026,7 +1214,7 @@ resetButton.addEventListener("click", () => {
|
|
|
1026
1214
|
const updateResetButton = () => {
|
|
1027
1215
|
const status = device.firmwareStatus;
|
|
1028
1216
|
const enabled = status == "pending" || status == "testing";
|
|
1029
|
-
resetButton.disabled = !enabled;
|
|
1217
|
+
resetButton.disabled = !enabled || !device.canReset;
|
|
1030
1218
|
};
|
|
1031
1219
|
|
|
1032
1220
|
/** @type {HTMLButtonElement} */
|
|
@@ -1040,12 +1228,15 @@ const updateTestFirmwareImageButton = () => {
|
|
|
1040
1228
|
};
|
|
1041
1229
|
|
|
1042
1230
|
/** @type {HTMLButtonElement} */
|
|
1043
|
-
const confirmFirmwareImageButton = document.getElementById(
|
|
1231
|
+
const confirmFirmwareImageButton = document.getElementById(
|
|
1232
|
+
"confirmFirmwareImage"
|
|
1233
|
+
);
|
|
1044
1234
|
confirmFirmwareImageButton.addEventListener("click", () => {
|
|
1045
1235
|
device.confirmFirmwareImage(selectedImageIndex);
|
|
1046
1236
|
});
|
|
1047
1237
|
const updateConfirmFirmwareImageButton = () => {
|
|
1048
|
-
const enabled =
|
|
1238
|
+
const enabled =
|
|
1239
|
+
device.firmwareStatus == "testing" || device.firmwareStatus == "uploaded";
|
|
1049
1240
|
confirmFirmwareImageButton.disabled = !enabled;
|
|
1050
1241
|
};
|
|
1051
1242
|
|
|
@@ -1066,7 +1257,10 @@ const imageSelectionOptGroup = imageSelectionSelect.querySelector("optgroup");
|
|
|
1066
1257
|
device.addEventListener("firmwareImages", () => {
|
|
1067
1258
|
imageSelectionOptGroup.innerHTML = "";
|
|
1068
1259
|
device.firmwareImages.forEach((firmwareImage, index) => {
|
|
1069
|
-
const option = new Option(
|
|
1260
|
+
const option = new Option(
|
|
1261
|
+
`${firmwareImage.version} (slot ${index})`,
|
|
1262
|
+
index
|
|
1263
|
+
);
|
|
1070
1264
|
option.disabled = firmwareImage.empty;
|
|
1071
1265
|
imageSelectionOptGroup.appendChild(option);
|
|
1072
1266
|
});
|
|
@@ -1091,3 +1285,449 @@ function updateSelectImageSelect() {
|
|
|
1091
1285
|
}
|
|
1092
1286
|
imageSelectionSelect.disabled = !enabled;
|
|
1093
1287
|
}
|
|
1288
|
+
|
|
1289
|
+
// WIFI
|
|
1290
|
+
|
|
1291
|
+
/** @type {HTMLSpanElement} */
|
|
1292
|
+
const isWifiAvailableSpan = document.getElementById("isWifiAvailable");
|
|
1293
|
+
device.addEventListener("isWifiAvailable", (event) => {
|
|
1294
|
+
isWifiAvailableSpan.innerText = event.message.isWifiAvailable;
|
|
1295
|
+
});
|
|
1296
|
+
|
|
1297
|
+
/** @type {HTMLSpanElement} */
|
|
1298
|
+
const wifiSSIDSpan = document.getElementById("wifiSSID");
|
|
1299
|
+
device.addEventListener("getWifiSSID", (event) => {
|
|
1300
|
+
wifiSSIDSpan.innerText = event.message.wifiSSID;
|
|
1301
|
+
});
|
|
1302
|
+
/** @type {HTMLInputElement} */
|
|
1303
|
+
const setWifiSSIDInput = document.getElementById("setWifiSSIDInput");
|
|
1304
|
+
setWifiSSIDInput.min = BS.MinWifiSSIDLength;
|
|
1305
|
+
setWifiSSIDInput.max = BS.MaxWifiSSIDLength;
|
|
1306
|
+
setWifiSSIDInput.addEventListener("input", () => {
|
|
1307
|
+
setWifiSSIDButton.disabled = !(
|
|
1308
|
+
setWifiSSIDInput.value.length > BS.MinWifiSSIDLength &&
|
|
1309
|
+
setWifiSSIDInput.value.length < BS.MaxWifiSSIDLength
|
|
1310
|
+
);
|
|
1311
|
+
});
|
|
1312
|
+
/** @type {HTMLButtonElement} */
|
|
1313
|
+
const setWifiSSIDButton = document.getElementById("setWifiSSIDButton");
|
|
1314
|
+
setWifiSSIDButton.addEventListener("click", async () => {
|
|
1315
|
+
setWifiSSIDButton.disabled = true;
|
|
1316
|
+
setWifiSSIDButton.innerText = "setting wifi ssid";
|
|
1317
|
+
await device.setWifiSSID(setWifiSSIDInput.value);
|
|
1318
|
+
setWifiSSIDInput.value = "";
|
|
1319
|
+
setWifiSSIDButton.disabled = false;
|
|
1320
|
+
setWifiSSIDButton.innerText = "set wifi ssid";
|
|
1321
|
+
});
|
|
1322
|
+
|
|
1323
|
+
/** @type {HTMLSpanElement} */
|
|
1324
|
+
const wifiPasswordSpan = document.getElementById("wifiPassword");
|
|
1325
|
+
device.addEventListener("getWifiPassword", (event) => {
|
|
1326
|
+
wifiPasswordSpan.innerText = event.message.wifiPassword;
|
|
1327
|
+
});
|
|
1328
|
+
/** @type {HTMLInputElement} */
|
|
1329
|
+
const setWifiPasswordInput = document.getElementById("setWifiPasswordInput");
|
|
1330
|
+
setWifiPasswordInput.min = BS.MinWifiPasswordLength;
|
|
1331
|
+
setWifiPasswordInput.max = BS.MaxWifiPasswordLength;
|
|
1332
|
+
setWifiPasswordInput.addEventListener("input", () => {
|
|
1333
|
+
const length = setWifiPasswordInput.value.length;
|
|
1334
|
+
setWifiPasswordButton.disabled = !(
|
|
1335
|
+
length == 0 ||
|
|
1336
|
+
(length > BS.MinWifiPasswordLength && length < BS.MaxWifiPasswordLength)
|
|
1337
|
+
);
|
|
1338
|
+
});
|
|
1339
|
+
/** @type {HTMLButtonElement} */
|
|
1340
|
+
const setWifiPasswordButton = document.getElementById("setWifiPasswordButton");
|
|
1341
|
+
setWifiPasswordButton.addEventListener("click", async () => {
|
|
1342
|
+
setWifiPasswordButton.disabled = true;
|
|
1343
|
+
setWifiPasswordButton.innerText = "setting wifi password";
|
|
1344
|
+
await device.setWifiPassword(setWifiPasswordInput.value);
|
|
1345
|
+
setWifiPasswordInput.value = "";
|
|
1346
|
+
setWifiPasswordButton.disabled = false;
|
|
1347
|
+
setWifiPasswordButton.innerText = "set wifi password";
|
|
1348
|
+
});
|
|
1349
|
+
|
|
1350
|
+
const updateWifiInputs = () => {
|
|
1351
|
+
const enabled =
|
|
1352
|
+
device.isConnected &&
|
|
1353
|
+
device.isWifiAvailable &&
|
|
1354
|
+
!device.wifiConnectionEnabled;
|
|
1355
|
+
const disabled = !enabled;
|
|
1356
|
+
|
|
1357
|
+
setWifiPasswordInput.disabled = disabled;
|
|
1358
|
+
setWifiPasswordButton.disabled = disabled;
|
|
1359
|
+
|
|
1360
|
+
setWifiSSIDInput.disabled = disabled;
|
|
1361
|
+
setWifiSSIDButton.disabled = disabled;
|
|
1362
|
+
|
|
1363
|
+
toggleWifiConnectionButton.disabled = !(
|
|
1364
|
+
device.isConnected && device.isWifiAvailable
|
|
1365
|
+
);
|
|
1366
|
+
};
|
|
1367
|
+
device.addEventListener("isConnected", () => {
|
|
1368
|
+
updateWifiInputs();
|
|
1369
|
+
});
|
|
1370
|
+
device.addEventListener("getWifiConnectionEnabled", () => {
|
|
1371
|
+
updateWifiInputs();
|
|
1372
|
+
});
|
|
1373
|
+
|
|
1374
|
+
/** @type {HTMLSpanElement} */
|
|
1375
|
+
const wifiConnectionEnabledSpan = document.getElementById(
|
|
1376
|
+
"wifiConnectionEnabled"
|
|
1377
|
+
);
|
|
1378
|
+
device.addEventListener("getWifiConnectionEnabled", (event) => {
|
|
1379
|
+
wifiConnectionEnabledSpan.innerText = event.message.wifiConnectionEnabled;
|
|
1380
|
+
});
|
|
1381
|
+
|
|
1382
|
+
/** @type {HTMLSpanElement} */
|
|
1383
|
+
const isWifiConnectedSpan = document.getElementById("isWifiConnected");
|
|
1384
|
+
device.addEventListener("isWifiConnected", (event) => {
|
|
1385
|
+
isWifiConnectedSpan.innerText = event.message.isWifiConnected;
|
|
1386
|
+
});
|
|
1387
|
+
|
|
1388
|
+
/** @type {HTMLSpanElement} */
|
|
1389
|
+
const ipAddressSpan = document.getElementById("ipAddress");
|
|
1390
|
+
device.addEventListener("ipAddress", (event) => {
|
|
1391
|
+
ipAddressSpan.innerText = event.message.ipAddress || "none";
|
|
1392
|
+
});
|
|
1393
|
+
|
|
1394
|
+
/** @type {HTMLButtonElement} */
|
|
1395
|
+
const toggleWifiConnectionButton = document.getElementById(
|
|
1396
|
+
"toggleWifiConnection"
|
|
1397
|
+
);
|
|
1398
|
+
toggleWifiConnectionButton.addEventListener("click", async () => {
|
|
1399
|
+
toggleWifiConnectionButton.disabled = true;
|
|
1400
|
+
await device.toggleWifiConnection();
|
|
1401
|
+
toggleWifiConnectionButton.disabled = false;
|
|
1402
|
+
});
|
|
1403
|
+
device.addEventListener("getWifiConnectionEnabled", (event) => {
|
|
1404
|
+
toggleWifiConnectionButton.innerText = event.message.wifiConnectionEnabled
|
|
1405
|
+
? "disable wifi connection"
|
|
1406
|
+
: "enable wifi connection";
|
|
1407
|
+
});
|
|
1408
|
+
|
|
1409
|
+
/** @type {HTMLButtonElement} */
|
|
1410
|
+
const connectViaWebSocketsButton = document.getElementById(
|
|
1411
|
+
"connectViaWebSockets"
|
|
1412
|
+
);
|
|
1413
|
+
connectViaWebSocketsButton.addEventListener("click", async () => {
|
|
1414
|
+
toggleWifiConnectionButton.disabled = true;
|
|
1415
|
+
device.reconnectViaWebSockets();
|
|
1416
|
+
});
|
|
1417
|
+
const updateConnectViaWebSocketsButton = () => {
|
|
1418
|
+
const enabled =
|
|
1419
|
+
device.isConnected &&
|
|
1420
|
+
device.connectionType == "webBluetooth" &&
|
|
1421
|
+
device.isWifiConnected;
|
|
1422
|
+
console.log({ enabled });
|
|
1423
|
+
connectViaWebSocketsButton.disabled = !enabled;
|
|
1424
|
+
};
|
|
1425
|
+
device.addEventListener("isWifiConnected", () =>
|
|
1426
|
+
updateConnectViaWebSocketsButton()
|
|
1427
|
+
);
|
|
1428
|
+
device.addEventListener("isConnected", () =>
|
|
1429
|
+
updateConnectViaWebSocketsButton()
|
|
1430
|
+
);
|
|
1431
|
+
|
|
1432
|
+
// CAMERA
|
|
1433
|
+
/** @type {HTMLSpanElement} */
|
|
1434
|
+
const isCameraAvailableSpan = document.getElementById("isCameraAvailable");
|
|
1435
|
+
device.addEventListener("connected", () => {
|
|
1436
|
+
isCameraAvailableSpan.innerText = device.hasCamera;
|
|
1437
|
+
});
|
|
1438
|
+
|
|
1439
|
+
/** @type {HTMLSpanElement} */
|
|
1440
|
+
const cameraStatusSpan = document.getElementById("cameraStatus");
|
|
1441
|
+
device.addEventListener("cameraStatus", () => {
|
|
1442
|
+
cameraStatusSpan.innerText = device.cameraStatus;
|
|
1443
|
+
});
|
|
1444
|
+
|
|
1445
|
+
/** @type {HTMLButtonElement} */
|
|
1446
|
+
const takePictureButton = document.getElementById("takePicture");
|
|
1447
|
+
takePictureButton.addEventListener("click", () => {
|
|
1448
|
+
if (device.cameraStatus == "idle") {
|
|
1449
|
+
device.takePicture();
|
|
1450
|
+
} else {
|
|
1451
|
+
device.stopCamera();
|
|
1452
|
+
}
|
|
1453
|
+
});
|
|
1454
|
+
device.addEventListener("connected", () => {
|
|
1455
|
+
updateTakePictureButton();
|
|
1456
|
+
});
|
|
1457
|
+
device.addEventListener("getSensorConfiguration", () => {
|
|
1458
|
+
updateTakePictureButton();
|
|
1459
|
+
});
|
|
1460
|
+
const updateTakePictureButton = () => {
|
|
1461
|
+
takePictureButton.disabled =
|
|
1462
|
+
!device.isConnected ||
|
|
1463
|
+
device.sensorConfiguration.camera == 0 ||
|
|
1464
|
+
device.cameraStatus != "idle";
|
|
1465
|
+
};
|
|
1466
|
+
device.addEventListener("cameraStatus", () => {
|
|
1467
|
+
updateTakePictureButton();
|
|
1468
|
+
});
|
|
1469
|
+
|
|
1470
|
+
/** @type {HTMLButtonElement} */
|
|
1471
|
+
const focusCameraButton = document.getElementById("focusCamera");
|
|
1472
|
+
focusCameraButton.addEventListener("click", () => {
|
|
1473
|
+
if (device.cameraStatus == "idle") {
|
|
1474
|
+
device.focusCamera();
|
|
1475
|
+
} else {
|
|
1476
|
+
device.stopCamera();
|
|
1477
|
+
}
|
|
1478
|
+
});
|
|
1479
|
+
device.addEventListener("connected", () => {
|
|
1480
|
+
updateFocusCameraButton();
|
|
1481
|
+
});
|
|
1482
|
+
device.addEventListener("getSensorConfiguration", () => {
|
|
1483
|
+
updateFocusCameraButton();
|
|
1484
|
+
});
|
|
1485
|
+
const updateFocusCameraButton = () => {
|
|
1486
|
+
focusCameraButton.disabled =
|
|
1487
|
+
!device.isConnected ||
|
|
1488
|
+
device.sensorConfiguration.camera == 0 ||
|
|
1489
|
+
device.cameraStatus != "idle";
|
|
1490
|
+
};
|
|
1491
|
+
device.addEventListener("cameraStatus", (event) => {
|
|
1492
|
+
updateFocusCameraButton();
|
|
1493
|
+
if (
|
|
1494
|
+
device.cameraStatus == "idle" &&
|
|
1495
|
+
event.message.previousCameraStatus == "focusing"
|
|
1496
|
+
) {
|
|
1497
|
+
device.takePicture();
|
|
1498
|
+
}
|
|
1499
|
+
});
|
|
1500
|
+
|
|
1501
|
+
/** @type {HTMLButtonElement} */
|
|
1502
|
+
const sleepCameraButton = document.getElementById("sleepCamera");
|
|
1503
|
+
sleepCameraButton.addEventListener("click", () => {
|
|
1504
|
+
if (device.cameraStatus == "asleep") {
|
|
1505
|
+
device.wakeCamera();
|
|
1506
|
+
} else {
|
|
1507
|
+
device.sleepCamera();
|
|
1508
|
+
}
|
|
1509
|
+
});
|
|
1510
|
+
device.addEventListener("connected", () => {
|
|
1511
|
+
updateSleepCameraButton();
|
|
1512
|
+
});
|
|
1513
|
+
device.addEventListener("getSensorConfiguration", () => {
|
|
1514
|
+
updateSleepCameraButton();
|
|
1515
|
+
});
|
|
1516
|
+
const updateSleepCameraButton = () => {
|
|
1517
|
+
let disabled = !device.isConnected || !device.hasCamera;
|
|
1518
|
+
switch (device.cameraStatus) {
|
|
1519
|
+
case "asleep":
|
|
1520
|
+
sleepCameraButton.innerText = "wake camera";
|
|
1521
|
+
break;
|
|
1522
|
+
case "idle":
|
|
1523
|
+
sleepCameraButton.innerText = "sleep camera";
|
|
1524
|
+
break;
|
|
1525
|
+
default:
|
|
1526
|
+
disabled = true;
|
|
1527
|
+
break;
|
|
1528
|
+
}
|
|
1529
|
+
sleepCameraButton.disabled = disabled;
|
|
1530
|
+
};
|
|
1531
|
+
device.addEventListener("cameraStatus", () => {
|
|
1532
|
+
updateSleepCameraButton();
|
|
1533
|
+
});
|
|
1534
|
+
|
|
1535
|
+
/** @type {HTMLImageElement} */
|
|
1536
|
+
const cameraImage = document.getElementById("cameraImage");
|
|
1537
|
+
device.addEventListener("cameraImage", (event) => {
|
|
1538
|
+
cameraImage.src = event.message.url;
|
|
1539
|
+
});
|
|
1540
|
+
|
|
1541
|
+
/** @type {HTMLProgressElement} */
|
|
1542
|
+
const cameraImageProgress = document.getElementById("cameraImageProgress");
|
|
1543
|
+
device.addEventListener("cameraImageProgress", (event) => {
|
|
1544
|
+
if (event.message.type == "image") {
|
|
1545
|
+
cameraImageProgress.value = event.message.progress;
|
|
1546
|
+
}
|
|
1547
|
+
});
|
|
1548
|
+
|
|
1549
|
+
/** @type {HTMLInputElement} */
|
|
1550
|
+
const autoPictureCheckbox = document.getElementById("autoPicture");
|
|
1551
|
+
let autoPicture = autoPictureCheckbox.checked;
|
|
1552
|
+
autoPictureCheckbox.addEventListener("input", () => {
|
|
1553
|
+
autoPicture = autoPictureCheckbox.checked;
|
|
1554
|
+
});
|
|
1555
|
+
device.addEventListener("cameraImage", () => {
|
|
1556
|
+
if (autoPicture) {
|
|
1557
|
+
device.takePicture();
|
|
1558
|
+
}
|
|
1559
|
+
});
|
|
1560
|
+
|
|
1561
|
+
/** @type {HTMLPreElement} */
|
|
1562
|
+
const cameraConfigurationPre = document.getElementById(
|
|
1563
|
+
"cameraConfigurationPre"
|
|
1564
|
+
);
|
|
1565
|
+
device.addEventListener("getCameraConfiguration", () => {
|
|
1566
|
+
cameraConfigurationPre.textContent = JSON.stringify(
|
|
1567
|
+
device.cameraConfiguration,
|
|
1568
|
+
null,
|
|
1569
|
+
2
|
|
1570
|
+
);
|
|
1571
|
+
});
|
|
1572
|
+
|
|
1573
|
+
const cameraConfigurationContainer = document.getElementById(
|
|
1574
|
+
"cameraConfiguration"
|
|
1575
|
+
);
|
|
1576
|
+
/** @type {HTMLTemplateElement} */
|
|
1577
|
+
const cameraConfigurationTypeTemplate = document.getElementById(
|
|
1578
|
+
"cameraConfigurationTypeTemplate"
|
|
1579
|
+
);
|
|
1580
|
+
BS.CameraConfigurationTypes.forEach((cameraConfigurationType) => {
|
|
1581
|
+
const cameraConfigurationTypeContainer =
|
|
1582
|
+
cameraConfigurationTypeTemplate.content
|
|
1583
|
+
.cloneNode(true)
|
|
1584
|
+
.querySelector(".cameraConfigurationType");
|
|
1585
|
+
|
|
1586
|
+
cameraConfigurationContainer.appendChild(cameraConfigurationTypeContainer);
|
|
1587
|
+
|
|
1588
|
+
cameraConfigurationTypeContainer.querySelector(".type").innerText =
|
|
1589
|
+
cameraConfigurationType;
|
|
1590
|
+
|
|
1591
|
+
/** @type {HTMLInputElement} */
|
|
1592
|
+
const input = cameraConfigurationTypeContainer.querySelector("input");
|
|
1593
|
+
|
|
1594
|
+
/** @type {HTMLSpanElement} */
|
|
1595
|
+
const span = cameraConfigurationTypeContainer.querySelector("span");
|
|
1596
|
+
|
|
1597
|
+
device.addEventListener("isConnected", () => {
|
|
1598
|
+
updateisInputDisabled();
|
|
1599
|
+
});
|
|
1600
|
+
device.addEventListener("cameraStatus", () => {
|
|
1601
|
+
updateisInputDisabled();
|
|
1602
|
+
});
|
|
1603
|
+
const updateisInputDisabled = () => {
|
|
1604
|
+
input.disabled =
|
|
1605
|
+
!device.isConnected || !device.hasCamera || device.cameraStatus != "idle";
|
|
1606
|
+
};
|
|
1607
|
+
|
|
1608
|
+
const updateInput = () => {
|
|
1609
|
+
const value = device.cameraConfiguration[cameraConfigurationType];
|
|
1610
|
+
span.innerText = value;
|
|
1611
|
+
input.value = value;
|
|
1612
|
+
};
|
|
1613
|
+
|
|
1614
|
+
device.addEventListener("connected", () => {
|
|
1615
|
+
if (!device.hasCamera) {
|
|
1616
|
+
return;
|
|
1617
|
+
}
|
|
1618
|
+
const range = device.cameraConfigurationRanges[cameraConfigurationType];
|
|
1619
|
+
input.min = range.min;
|
|
1620
|
+
input.max = range.max;
|
|
1621
|
+
|
|
1622
|
+
updateInput();
|
|
1623
|
+
});
|
|
1624
|
+
|
|
1625
|
+
device.addEventListener("getCameraConfiguration", () => {
|
|
1626
|
+
updateInput();
|
|
1627
|
+
});
|
|
1628
|
+
|
|
1629
|
+
input.addEventListener("change", () => {
|
|
1630
|
+
const value = Number(input.value);
|
|
1631
|
+
// console.log(`updating ${cameraConfigurationType} to ${value}`);
|
|
1632
|
+
device.setCameraConfiguration({
|
|
1633
|
+
[cameraConfigurationType]: value,
|
|
1634
|
+
});
|
|
1635
|
+
if (takePictureAfterUpdate) {
|
|
1636
|
+
device.addEventListener(
|
|
1637
|
+
"getCameraConfiguration",
|
|
1638
|
+
() => {
|
|
1639
|
+
setTimeout(() => device.takePicture()), 100;
|
|
1640
|
+
},
|
|
1641
|
+
{ once: true }
|
|
1642
|
+
);
|
|
1643
|
+
}
|
|
1644
|
+
});
|
|
1645
|
+
});
|
|
1646
|
+
|
|
1647
|
+
/** @type {HTMLInputElement} */
|
|
1648
|
+
const takePictureAfterUpdateCheckbox = document.getElementById(
|
|
1649
|
+
"takePictureAfterUpdate"
|
|
1650
|
+
);
|
|
1651
|
+
let takePictureAfterUpdate = false;
|
|
1652
|
+
takePictureAfterUpdateCheckbox.addEventListener("input", () => {
|
|
1653
|
+
takePictureAfterUpdate = takePictureAfterUpdateCheckbox.checked;
|
|
1654
|
+
console.log({ takePictureAfterUpdate });
|
|
1655
|
+
});
|
|
1656
|
+
|
|
1657
|
+
let barcodeDetector;
|
|
1658
|
+
BarcodeDetector.getSupportedFormats().then((supportedFormats) => {
|
|
1659
|
+
console.log({ supportedFormats });
|
|
1660
|
+
// create new detector
|
|
1661
|
+
barcodeDetector = new BarcodeDetector({
|
|
1662
|
+
formats: supportedFormats,
|
|
1663
|
+
});
|
|
1664
|
+
});
|
|
1665
|
+
cameraImage.addEventListener("load", () => {
|
|
1666
|
+
if (barcodeDetector) {
|
|
1667
|
+
barcodeDetector
|
|
1668
|
+
.detect(cameraImage)
|
|
1669
|
+
.then((barcodes) => {
|
|
1670
|
+
barcodes.forEach((barcode) => console.log(barcode.rawValue));
|
|
1671
|
+
})
|
|
1672
|
+
.catch((err) => {
|
|
1673
|
+
console.log(err);
|
|
1674
|
+
});
|
|
1675
|
+
}
|
|
1676
|
+
});
|
|
1677
|
+
|
|
1678
|
+
/** @type {HTMLInputElement} */
|
|
1679
|
+
const cameraWhiteBalanceInput = document.getElementById("cameraWhiteBalance");
|
|
1680
|
+
const updateWhiteBalance = BS.ThrottleUtils.throttle(
|
|
1681
|
+
(config) => {
|
|
1682
|
+
if (device.cameraStatus != "idle") {
|
|
1683
|
+
return;
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
device.setCameraConfiguration(config);
|
|
1687
|
+
|
|
1688
|
+
if (takePictureAfterUpdate) {
|
|
1689
|
+
device.addEventListener(
|
|
1690
|
+
"getCameraConfiguration",
|
|
1691
|
+
() => {
|
|
1692
|
+
setTimeout(() => device.takePicture()), 100;
|
|
1693
|
+
},
|
|
1694
|
+
{ once: true }
|
|
1695
|
+
);
|
|
1696
|
+
}
|
|
1697
|
+
},
|
|
1698
|
+
200,
|
|
1699
|
+
true
|
|
1700
|
+
);
|
|
1701
|
+
cameraWhiteBalanceInput.addEventListener("input", () => {
|
|
1702
|
+
let [redGain, greenGain, blueGain] = cameraWhiteBalanceInput.value
|
|
1703
|
+
.replace("#", "")
|
|
1704
|
+
.match(/.{1,2}/g)
|
|
1705
|
+
.map((value) => Number(`0x${value}`))
|
|
1706
|
+
.map((value) => value / 255)
|
|
1707
|
+
.map((value) => value * device.cameraConfigurationRanges.blueGain.max)
|
|
1708
|
+
.map((value) => Math.round(value));
|
|
1709
|
+
|
|
1710
|
+
updateWhiteBalance({ redGain, greenGain, blueGain });
|
|
1711
|
+
});
|
|
1712
|
+
const updateCameraWhiteBalanceInput = () => {
|
|
1713
|
+
if (!device.hasCamera) {
|
|
1714
|
+
return;
|
|
1715
|
+
}
|
|
1716
|
+
cameraWhiteBalanceInput.disabled =
|
|
1717
|
+
!device.isConnected || !device.hasCamera || device.cameraStatus != "idle";
|
|
1718
|
+
|
|
1719
|
+
const { redGain, blueGain, greenGain } = device.cameraConfiguration;
|
|
1720
|
+
|
|
1721
|
+
cameraWhiteBalanceInput.value = `#${[redGain, blueGain, greenGain]
|
|
1722
|
+
.map((value) => value / device.cameraConfigurationRanges.redGain.max)
|
|
1723
|
+
.map((value) => value * 255)
|
|
1724
|
+
.map((value) => Math.round(value))
|
|
1725
|
+
.map((value) => value.toString(16))
|
|
1726
|
+
.join("")}`;
|
|
1727
|
+
};
|
|
1728
|
+
device.addEventListener("connected", () => {
|
|
1729
|
+
updateCameraWhiteBalanceInput();
|
|
1730
|
+
});
|
|
1731
|
+
device.addEventListener("getCameraConfiguration", () => {
|
|
1732
|
+
updateCameraWhiteBalanceInput();
|
|
1733
|
+
});
|