brilliantsole 0.0.27 → 0.0.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/3d/anchor.glb +0 -0
- package/assets/3d/coin.glb +0 -0
- package/assets/3d/glasses.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/build/brilliantsole.cjs +3091 -741
- package/build/brilliantsole.cjs.map +1 -1
- package/build/brilliantsole.js +2759 -709
- package/build/brilliantsole.js.map +1 -1
- package/build/brilliantsole.ls.js +2602 -543
- 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 +295 -65
- package/build/brilliantsole.module.js +2749 -710
- package/build/brilliantsole.module.js.map +1 -1
- package/build/brilliantsole.module.min.d.ts +295 -65
- package/build/brilliantsole.module.min.js +1 -1
- package/build/brilliantsole.module.min.js.map +1 -1
- package/build/brilliantsole.node.module.d.ts +289 -62
- package/build/brilliantsole.node.module.js +3080 -742
- 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 -8
- package/build/dts/CameraManager.d.ts +72 -0
- package/build/dts/Device.d.ts +64 -13
- package/build/dts/DeviceInformationManager.d.ts +4 -4
- package/build/dts/DeviceManager.d.ts +2 -0
- package/build/dts/FileTransferManager.d.ts +18 -8
- package/build/dts/InformationManager.d.ts +2 -0
- package/build/dts/MicrophoneManager.d.ts +88 -0
- package/build/dts/TfliteManager.d.ts +22 -2
- package/build/dts/WifiManager.d.ts +61 -0
- package/build/dts/connection/BaseConnectionManager.d.ts +35 -3
- package/build/dts/connection/ClientConnectionManager.d.ts +7 -2
- package/build/dts/connection/bluetooth/NobleConnectionManager.d.ts +2 -1
- package/build/dts/connection/bluetooth/WebBluetoothConnectionManager.d.ts +1 -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 +5 -5
- 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 +5 -3
- package/build/dts/server/ServerUtils.d.ts +1 -1
- package/build/dts/server/websocket/WebSocketUtils.d.ts +1 -1
- package/build/dts/utils/AudioUtils.d.ts +2 -0
- package/build/dts/utils/Console.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 +292 -62
- package/build/index.node.d.ts +286 -59
- package/examples/3d/scene.html +19 -5
- package/examples/3d-generic/index.html +144 -0
- package/examples/3d-generic/script.js +266 -0
- package/examples/basic/index.html +267 -17
- package/examples/basic/script.js +958 -105
- package/examples/camera/barcode-detector.js +109 -0
- package/examples/camera/depth-estimation.js +71 -0
- package/examples/camera/face-detector.js +119 -0
- package/examples/camera/face-landmark.js +111 -0
- package/examples/camera/gesture-recognition.js +97 -0
- package/examples/camera/hand-landmark.js +74 -0
- package/examples/camera/image-segmentation.js +98 -0
- package/examples/camera/image-to-text.js +43 -0
- package/examples/camera/image-upscale.js +75 -0
- package/examples/camera/index.html +129 -0
- package/examples/camera/object-detection.js +98 -0
- package/examples/camera/pose-landmark.js +60 -0
- package/examples/camera/script.js +316 -0
- package/examples/camera/utils.js +165 -0
- package/examples/camera/yolo-tiny.js +54 -0
- package/examples/camera/yolo.js +119 -0
- package/examples/edge-impulse/script.js +157 -48
- 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/glasses-gestures/README.md +11 -0
- package/examples/glasses-gestures/edge-impulse-standalone.js +7228 -0
- package/examples/glasses-gestures/edge-impulse-standalone.wasm +0 -0
- package/examples/glasses-gestures/index.html +69 -0
- package/examples/glasses-gestures/run-impulse.js +135 -0
- package/examples/glasses-gestures/script.js +226 -0
- package/examples/gloves/edge-impulse-standalone.js +7228 -0
- package/examples/gloves/edge-impulse-standalone.wasm +0 -0
- package/examples/gloves/index.html +4 -1
- package/examples/gloves/run-impulse.js +135 -0
- package/examples/gloves/script.js +367 -51
- package/examples/graph/script.js +94 -37
- package/examples/microphone/gender.js +54 -0
- package/examples/microphone/index.html +102 -0
- package/examples/microphone/script.js +394 -0
- package/examples/microphone/utils.js +45 -0
- package/examples/microphone/whisper-realtime.js +166 -0
- package/examples/microphone/whisper.js +132 -0
- package/examples/punch/index.html +135 -0
- package/examples/punch/punch.tflite +0 -0
- package/examples/punch/script.js +169 -0
- package/examples/server/index.html +98 -22
- package/examples/server/script.js +317 -109
- 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-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/examples/webxr-3/components/bs-camera.js +65 -0
- package/examples/webxr-3/index.html +134 -0
- package/examples/webxr-3/script.js +432 -0
- package/package.json +2 -1
- package/src/.prettierrc +4 -0
- package/src/BS.ts +79 -8
- package/src/CameraManager.ts +497 -0
- package/src/Device.ts +691 -86
- package/src/DeviceInformationManager.ts +19 -10
- package/src/DeviceManager.ts +85 -25
- package/src/FileTransferManager.ts +145 -20
- package/src/InformationManager.ts +40 -15
- package/src/MicrophoneManager.ts +599 -0
- package/src/TfliteManager.ts +171 -25
- package/src/WifiManager.ts +323 -0
- package/src/connection/BaseConnectionManager.ts +130 -30
- package/src/connection/ClientConnectionManager.ts +34 -10
- package/src/connection/bluetooth/BluetoothConnectionManager.ts +8 -2
- package/src/connection/bluetooth/NobleConnectionManager.ts +147 -41
- package/src/connection/bluetooth/WebBluetoothConnectionManager.ts +99 -34
- 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 +95 -25
- package/src/devicePair/DevicePairPressureSensorDataManager.ts +27 -7
- package/src/scanner/BaseScanner.ts +49 -11
- package/src/scanner/NobleScanner.ts +76 -14
- package/src/sensor/MotionSensorDataManager.ts +21 -6
- package/src/sensor/PressureSensorDataManager.ts +37 -8
- package/src/sensor/SensorConfigurationManager.ts +73 -22
- package/src/sensor/SensorDataManager.ts +109 -23
- package/src/server/BaseClient.ts +150 -36
- package/src/server/BaseServer.ts +50 -2
- package/src/server/ServerUtils.ts +39 -9
- package/src/server/udp/UDPServer.ts +73 -22
- package/src/server/udp/UDPUtils.ts +9 -2
- package/src/server/websocket/WebSocketClient.ts +27 -7
- package/src/server/websocket/WebSocketUtils.ts +4 -2
- package/src/utils/AudioUtils.ts +65 -0
- package/src/utils/Console.ts +62 -9
- package/src/utils/ParseUtils.ts +24 -5
- package/src/utils/ThrottleUtils.ts +62 -0
- package/src/utils/Timer.ts +1 -1
- package/src/vibration/VibrationManager.ts +166 -40
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { dataToArrayBuffer } from "../../utils/ArrayBufferUtils.ts";
|
|
2
2
|
import { createConsole } from "../../utils/Console.ts";
|
|
3
3
|
import { isInNode } from "../../utils/environment.ts";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
addEventListeners,
|
|
6
|
+
removeEventListeners,
|
|
7
|
+
BoundGenericEventListeners,
|
|
8
|
+
} from "../../utils/EventUtils.ts";
|
|
5
9
|
import {
|
|
6
10
|
allServiceUUIDs,
|
|
7
11
|
getServiceNameFromUUID,
|
|
@@ -17,20 +21,27 @@ const _console = createConsole("NobleConnectionManager", { log: false });
|
|
|
17
21
|
import type * as noble from "@abandonware/noble";
|
|
18
22
|
/** NODE_END */
|
|
19
23
|
|
|
20
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
BluetoothCharacteristicName,
|
|
26
|
+
BluetoothServiceName,
|
|
27
|
+
} from "./bluetoothUUIDs.ts";
|
|
21
28
|
import { ConnectionType } from "../BaseConnectionManager.ts";
|
|
22
29
|
import NobleScanner from "../../scanner/NobleScanner.ts";
|
|
23
30
|
|
|
24
31
|
interface HasConnectionManager {
|
|
25
32
|
connectionManager: NobleConnectionManager | undefined;
|
|
26
33
|
}
|
|
27
|
-
export interface NoblePeripheral
|
|
34
|
+
export interface NoblePeripheral
|
|
35
|
+
extends noble.Peripheral,
|
|
36
|
+
HasConnectionManager {
|
|
28
37
|
scanner: NobleScanner;
|
|
29
38
|
}
|
|
30
39
|
interface NobleService extends noble.Service, HasConnectionManager {
|
|
31
40
|
name: BluetoothServiceName;
|
|
32
41
|
}
|
|
33
|
-
interface NobleCharacteristic
|
|
42
|
+
interface NobleCharacteristic
|
|
43
|
+
extends noble.Characteristic,
|
|
44
|
+
HasConnectionManager {
|
|
34
45
|
name: BluetoothCharacteristicName;
|
|
35
46
|
}
|
|
36
47
|
|
|
@@ -63,16 +74,27 @@ class NobleConnectionManager extends BluetoothConnectionManager {
|
|
|
63
74
|
await this.#noblePeripheral!.disconnectAsync();
|
|
64
75
|
}
|
|
65
76
|
|
|
66
|
-
async writeCharacteristic(
|
|
77
|
+
async writeCharacteristic(
|
|
78
|
+
characteristicName: BluetoothCharacteristicName,
|
|
79
|
+
data: ArrayBuffer
|
|
80
|
+
) {
|
|
67
81
|
const characteristic = this.#characteristics.get(characteristicName)!;
|
|
68
|
-
_console.assertWithError(
|
|
82
|
+
_console.assertWithError(
|
|
83
|
+
characteristic,
|
|
84
|
+
`no characteristic found with name "${characteristicName}"`
|
|
85
|
+
);
|
|
69
86
|
// if (data instanceof DataView) {
|
|
70
87
|
// data = data.buffer;
|
|
71
88
|
// }
|
|
72
89
|
const properties = getCharacteristicProperties(characteristicName);
|
|
73
90
|
const buffer = Buffer.from(data);
|
|
74
91
|
const writeWithoutResponse = properties.writeWithoutResponse;
|
|
75
|
-
_console.log(
|
|
92
|
+
_console.log(
|
|
93
|
+
`writing to ${characteristicName} ${
|
|
94
|
+
writeWithoutResponse ? "without" : "with"
|
|
95
|
+
} response`,
|
|
96
|
+
buffer
|
|
97
|
+
);
|
|
76
98
|
await characteristic.writeAsync(buffer, writeWithoutResponse);
|
|
77
99
|
if (characteristic.properties.includes("read")) {
|
|
78
100
|
await characteristic.readAsync();
|
|
@@ -84,32 +106,39 @@ class NobleConnectionManager extends BluetoothConnectionManager {
|
|
|
84
106
|
}
|
|
85
107
|
async reconnect() {
|
|
86
108
|
await super.reconnect();
|
|
87
|
-
|
|
88
|
-
this.connect();
|
|
109
|
+
await this.#noblePeripheral!.connectAsync();
|
|
89
110
|
}
|
|
90
111
|
|
|
91
112
|
// NOBLE
|
|
92
|
-
#noblePeripheral
|
|
93
|
-
get noblePeripheral()
|
|
113
|
+
#noblePeripheral?: NoblePeripheral;
|
|
114
|
+
get noblePeripheral() {
|
|
94
115
|
return this.#noblePeripheral;
|
|
95
116
|
}
|
|
96
|
-
set noblePeripheral(newNoblePeripheral
|
|
97
|
-
|
|
117
|
+
set noblePeripheral(newNoblePeripheral) {
|
|
118
|
+
if (newNoblePeripheral) {
|
|
119
|
+
_console.assertTypeWithError(newNoblePeripheral, "object");
|
|
120
|
+
}
|
|
98
121
|
if (this.noblePeripheral == newNoblePeripheral) {
|
|
99
122
|
_console.log("attempted to assign duplicate noblePeripheral");
|
|
100
123
|
return;
|
|
101
124
|
}
|
|
102
125
|
|
|
103
|
-
_console.log("newNoblePeripheral", newNoblePeripheral
|
|
126
|
+
_console.log("newNoblePeripheral", newNoblePeripheral?.id);
|
|
104
127
|
|
|
105
128
|
if (this.#noblePeripheral) {
|
|
106
|
-
removeEventListeners(
|
|
129
|
+
removeEventListeners(
|
|
130
|
+
this.#noblePeripheral,
|
|
131
|
+
this.#unboundNoblePeripheralListeners
|
|
132
|
+
);
|
|
107
133
|
delete this.#noblePeripheral!.connectionManager;
|
|
108
134
|
}
|
|
109
135
|
|
|
110
136
|
if (newNoblePeripheral) {
|
|
111
137
|
newNoblePeripheral.connectionManager = this;
|
|
112
|
-
addEventListeners(
|
|
138
|
+
addEventListeners(
|
|
139
|
+
newNoblePeripheral,
|
|
140
|
+
this.#unboundNoblePeripheralListeners
|
|
141
|
+
);
|
|
113
142
|
}
|
|
114
143
|
|
|
115
144
|
this.#noblePeripheral = newNoblePeripheral;
|
|
@@ -127,9 +156,15 @@ class NobleConnectionManager extends BluetoothConnectionManager {
|
|
|
127
156
|
await this.connectionManager!.onNoblePeripheralConnect(this);
|
|
128
157
|
}
|
|
129
158
|
async onNoblePeripheralConnect(noblePeripheral: NoblePeripheral) {
|
|
130
|
-
_console.log(
|
|
159
|
+
_console.log(
|
|
160
|
+
"onNoblePeripheralConnect",
|
|
161
|
+
noblePeripheral.id,
|
|
162
|
+
noblePeripheral.state
|
|
163
|
+
);
|
|
131
164
|
if (noblePeripheral.state == "connected") {
|
|
132
|
-
await this.#noblePeripheral!.discoverServicesAsync(
|
|
165
|
+
await this.#noblePeripheral!.discoverServicesAsync(
|
|
166
|
+
allServiceUUIDs as string[]
|
|
167
|
+
);
|
|
133
168
|
}
|
|
134
169
|
// this gets called when it connects and disconnects, so we use the noblePeripheral's "state" property instead
|
|
135
170
|
await this.#onNoblePeripheralState();
|
|
@@ -144,7 +179,11 @@ class NobleConnectionManager extends BluetoothConnectionManager {
|
|
|
144
179
|
}
|
|
145
180
|
|
|
146
181
|
async #onNoblePeripheralState() {
|
|
147
|
-
_console.log(
|
|
182
|
+
_console.log(
|
|
183
|
+
`noblePeripheral ${this.bluetoothId} state ${
|
|
184
|
+
this.#noblePeripheral!.state
|
|
185
|
+
}`
|
|
186
|
+
);
|
|
148
187
|
|
|
149
188
|
switch (this.#noblePeripheral!.state) {
|
|
150
189
|
case "connected":
|
|
@@ -164,7 +203,9 @@ class NobleConnectionManager extends BluetoothConnectionManager {
|
|
|
164
203
|
_console.error("noblePeripheral error");
|
|
165
204
|
break;
|
|
166
205
|
default:
|
|
167
|
-
_console.log(
|
|
206
|
+
_console.log(
|
|
207
|
+
`uncaught noblePeripheral state ${this.#noblePeripheral!.state}`
|
|
208
|
+
);
|
|
168
209
|
break;
|
|
169
210
|
}
|
|
170
211
|
}
|
|
@@ -180,7 +221,10 @@ class NobleConnectionManager extends BluetoothConnectionManager {
|
|
|
180
221
|
_console.log(
|
|
181
222
|
`removing listeners from characteristic "${characteristic.name}" has ${characteristic.listeners.length} listeners`
|
|
182
223
|
);
|
|
183
|
-
removeEventListeners(
|
|
224
|
+
removeEventListeners(
|
|
225
|
+
characteristic,
|
|
226
|
+
this.#unboundNobleCharacteristicListeners
|
|
227
|
+
);
|
|
184
228
|
});
|
|
185
229
|
this.#characteristics.clear();
|
|
186
230
|
}
|
|
@@ -188,15 +232,27 @@ class NobleConnectionManager extends BluetoothConnectionManager {
|
|
|
188
232
|
async #onNoblePeripheralRssiUpdate(this: NoblePeripheral, rssi: number) {
|
|
189
233
|
await this.connectionManager!.onNoblePeripheralRssiUpdate(this, rssi);
|
|
190
234
|
}
|
|
191
|
-
async onNoblePeripheralRssiUpdate(
|
|
235
|
+
async onNoblePeripheralRssiUpdate(
|
|
236
|
+
noblePeripheral: NoblePeripheral,
|
|
237
|
+
rssi: number
|
|
238
|
+
) {
|
|
192
239
|
_console.log("onNoblePeripheralRssiUpdate", noblePeripheral.id, rssi);
|
|
193
|
-
//
|
|
240
|
+
// TODO: - can this be useful?
|
|
194
241
|
}
|
|
195
242
|
|
|
196
|
-
async #onNoblePeripheralServicesDiscover(
|
|
197
|
-
|
|
243
|
+
async #onNoblePeripheralServicesDiscover(
|
|
244
|
+
this: NoblePeripheral,
|
|
245
|
+
services: NobleService[]
|
|
246
|
+
) {
|
|
247
|
+
await this.connectionManager!.onNoblePeripheralServicesDiscover(
|
|
248
|
+
this,
|
|
249
|
+
services
|
|
250
|
+
);
|
|
198
251
|
}
|
|
199
|
-
async onNoblePeripheralServicesDiscover(
|
|
252
|
+
async onNoblePeripheralServicesDiscover(
|
|
253
|
+
noblePeripheral: NoblePeripheral,
|
|
254
|
+
services: NobleService[]
|
|
255
|
+
) {
|
|
200
256
|
_console.log(
|
|
201
257
|
"onNoblePeripheralServicesDiscover",
|
|
202
258
|
noblePeripheral.id,
|
|
@@ -206,7 +262,10 @@ class NobleConnectionManager extends BluetoothConnectionManager {
|
|
|
206
262
|
const service = services[index];
|
|
207
263
|
_console.log("service", service.uuid);
|
|
208
264
|
const serviceName = getServiceNameFromUUID(service.uuid)!;
|
|
209
|
-
_console.assertWithError(
|
|
265
|
+
_console.assertWithError(
|
|
266
|
+
serviceName,
|
|
267
|
+
`no name found for service uuid "${service.uuid}"`
|
|
268
|
+
);
|
|
210
269
|
_console.log({ serviceName });
|
|
211
270
|
this.#services.set(serviceName, service);
|
|
212
271
|
service.name = serviceName;
|
|
@@ -223,10 +282,19 @@ class NobleConnectionManager extends BluetoothConnectionManager {
|
|
|
223
282
|
characteristicsDiscover: this.#onNobleServiceCharacteristicsDiscover,
|
|
224
283
|
};
|
|
225
284
|
|
|
226
|
-
async #onNobleServiceCharacteristicsDiscover(
|
|
227
|
-
|
|
285
|
+
async #onNobleServiceCharacteristicsDiscover(
|
|
286
|
+
this: NobleService,
|
|
287
|
+
characteristics: NobleCharacteristic[]
|
|
288
|
+
) {
|
|
289
|
+
await this.connectionManager!.onNobleServiceCharacteristicsDiscover(
|
|
290
|
+
this,
|
|
291
|
+
characteristics
|
|
292
|
+
);
|
|
228
293
|
}
|
|
229
|
-
async onNobleServiceCharacteristicsDiscover(
|
|
294
|
+
async onNobleServiceCharacteristicsDiscover(
|
|
295
|
+
service: NobleService,
|
|
296
|
+
characteristics: NobleCharacteristic[]
|
|
297
|
+
) {
|
|
230
298
|
_console.log(
|
|
231
299
|
"onNobleServiceCharacteristicsDiscover",
|
|
232
300
|
service.uuid,
|
|
@@ -236,7 +304,9 @@ class NobleConnectionManager extends BluetoothConnectionManager {
|
|
|
236
304
|
for (const index in characteristics) {
|
|
237
305
|
const characteristic = characteristics[index];
|
|
238
306
|
_console.log("characteristic", characteristic.uuid);
|
|
239
|
-
const characteristicName = getCharacteristicNameFromUUID(
|
|
307
|
+
const characteristicName = getCharacteristicNameFromUUID(
|
|
308
|
+
characteristic.uuid
|
|
309
|
+
)!;
|
|
240
310
|
_console.assertWithError(
|
|
241
311
|
Boolean(characteristicName),
|
|
242
312
|
`no name found for characteristic uuid "${characteristic.uuid}"`
|
|
@@ -248,7 +318,10 @@ class NobleConnectionManager extends BluetoothConnectionManager {
|
|
|
248
318
|
_console.log(
|
|
249
319
|
`adding listeners to characteristic "${characteristic.name}" (currently has ${characteristic.listeners.length} listeners)`
|
|
250
320
|
);
|
|
251
|
-
addEventListeners(
|
|
321
|
+
addEventListeners(
|
|
322
|
+
characteristic,
|
|
323
|
+
this.#unboundNobleCharacteristicListeners
|
|
324
|
+
);
|
|
252
325
|
if (characteristic.properties.includes("read")) {
|
|
253
326
|
await characteristic.readAsync();
|
|
254
327
|
}
|
|
@@ -269,7 +342,8 @@ class NobleConnectionManager extends BluetoothConnectionManager {
|
|
|
269
342
|
notify: this.#onNobleCharacteristicNotify,
|
|
270
343
|
};
|
|
271
344
|
|
|
272
|
-
#characteristics: Map<BluetoothCharacteristicName, NobleCharacteristic> =
|
|
345
|
+
#characteristics: Map<BluetoothCharacteristicName, NobleCharacteristic> =
|
|
346
|
+
new Map();
|
|
273
347
|
|
|
274
348
|
get #hasAllCharacteristics() {
|
|
275
349
|
return allCharacteristicNames.every((characteristicName) => {
|
|
@@ -280,11 +354,28 @@ class NobleConnectionManager extends BluetoothConnectionManager {
|
|
|
280
354
|
});
|
|
281
355
|
}
|
|
282
356
|
|
|
283
|
-
#onNobleCharacteristicData(
|
|
284
|
-
this
|
|
357
|
+
#onNobleCharacteristicData(
|
|
358
|
+
this: NobleCharacteristic,
|
|
359
|
+
data: Buffer,
|
|
360
|
+
isNotification: boolean
|
|
361
|
+
) {
|
|
362
|
+
this.connectionManager!.onNobleCharacteristicData(
|
|
363
|
+
this,
|
|
364
|
+
data,
|
|
365
|
+
isNotification
|
|
366
|
+
);
|
|
285
367
|
}
|
|
286
|
-
onNobleCharacteristicData(
|
|
287
|
-
|
|
368
|
+
onNobleCharacteristicData(
|
|
369
|
+
characteristic: NobleCharacteristic,
|
|
370
|
+
data: Buffer,
|
|
371
|
+
isNotification: boolean
|
|
372
|
+
) {
|
|
373
|
+
_console.log(
|
|
374
|
+
"onNobleCharacteristicData",
|
|
375
|
+
characteristic.uuid,
|
|
376
|
+
data,
|
|
377
|
+
isNotification
|
|
378
|
+
);
|
|
288
379
|
const dataView = new DataView(dataToArrayBuffer(data));
|
|
289
380
|
|
|
290
381
|
const characteristicName: BluetoothCharacteristicName = characteristic.name;
|
|
@@ -301,14 +392,29 @@ class NobleConnectionManager extends BluetoothConnectionManager {
|
|
|
301
392
|
}
|
|
302
393
|
onNobleCharacteristicWrite(characteristic: NobleCharacteristic) {
|
|
303
394
|
_console.log("onNobleCharacteristicWrite", characteristic.uuid);
|
|
304
|
-
//
|
|
395
|
+
// TODO: - can this be useful?
|
|
305
396
|
}
|
|
306
397
|
|
|
307
|
-
#onNobleCharacteristicNotify(
|
|
398
|
+
#onNobleCharacteristicNotify(
|
|
399
|
+
this: NobleCharacteristic,
|
|
400
|
+
isSubscribed: boolean
|
|
401
|
+
) {
|
|
308
402
|
this.connectionManager!.onNobleCharacteristicNotify(this, isSubscribed);
|
|
309
403
|
}
|
|
310
|
-
onNobleCharacteristicNotify(
|
|
311
|
-
|
|
404
|
+
onNobleCharacteristicNotify(
|
|
405
|
+
characteristic: NobleCharacteristic,
|
|
406
|
+
isSubscribed: boolean
|
|
407
|
+
) {
|
|
408
|
+
_console.log(
|
|
409
|
+
"onNobleCharacteristicNotify",
|
|
410
|
+
characteristic.uuid,
|
|
411
|
+
isSubscribed
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
remove() {
|
|
416
|
+
super.remove();
|
|
417
|
+
this.noblePeripheral = undefined;
|
|
312
418
|
}
|
|
313
419
|
}
|
|
314
420
|
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { createConsole } from "../../utils/Console.ts";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
isInNode,
|
|
4
|
+
isInBrowser,
|
|
5
|
+
isInBluefy,
|
|
6
|
+
isInWebBLE,
|
|
7
|
+
} from "../../utils/environment.ts";
|
|
8
|
+
import {
|
|
9
|
+
addEventListeners,
|
|
10
|
+
removeEventListeners,
|
|
11
|
+
} from "../../utils/EventUtils.ts";
|
|
4
12
|
import {
|
|
5
13
|
serviceUUIDs,
|
|
6
14
|
optionalServiceUUIDs,
|
|
@@ -9,7 +17,10 @@ import {
|
|
|
9
17
|
getCharacteristicProperties,
|
|
10
18
|
} from "./bluetoothUUIDs.ts";
|
|
11
19
|
import BluetoothConnectionManager from "./BluetoothConnectionManager.ts";
|
|
12
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
BluetoothCharacteristicName,
|
|
22
|
+
BluetoothServiceName,
|
|
23
|
+
} from "./bluetoothUUIDs.ts";
|
|
13
24
|
import { ConnectionType } from "../BaseConnectionManager.ts";
|
|
14
25
|
|
|
15
26
|
const _console = createConsole("WebBluetoothConnectionManager", { log: false });
|
|
@@ -46,12 +57,15 @@ class WebBluetoothConnectionManager extends BluetoothConnectionManager {
|
|
|
46
57
|
return this.#characteristics.has("smp");
|
|
47
58
|
}
|
|
48
59
|
|
|
49
|
-
#boundBluetoothCharacteristicEventListeners: {
|
|
60
|
+
#boundBluetoothCharacteristicEventListeners: {
|
|
61
|
+
[eventType: string]: EventListener;
|
|
62
|
+
} = {
|
|
50
63
|
characteristicvaluechanged: this.#onCharacteristicvaluechanged.bind(this),
|
|
51
64
|
};
|
|
52
|
-
#boundBluetoothDeviceEventListeners: { [eventType: string]: EventListener } =
|
|
53
|
-
|
|
54
|
-
|
|
65
|
+
#boundBluetoothDeviceEventListeners: { [eventType: string]: EventListener } =
|
|
66
|
+
{
|
|
67
|
+
gattserverdisconnected: this.#onGattserverdisconnected.bind(this),
|
|
68
|
+
};
|
|
55
69
|
|
|
56
70
|
static get isSupported() {
|
|
57
71
|
return Boolean(bluetooth);
|
|
@@ -60,7 +74,7 @@ class WebBluetoothConnectionManager extends BluetoothConnectionManager {
|
|
|
60
74
|
return "webBluetooth";
|
|
61
75
|
}
|
|
62
76
|
|
|
63
|
-
#device
|
|
77
|
+
#device?: BluetoothDevice;
|
|
64
78
|
get device() {
|
|
65
79
|
return this.#device;
|
|
66
80
|
}
|
|
@@ -70,7 +84,10 @@ class WebBluetoothConnectionManager extends BluetoothConnectionManager {
|
|
|
70
84
|
return;
|
|
71
85
|
}
|
|
72
86
|
if (this.#device) {
|
|
73
|
-
removeEventListeners(
|
|
87
|
+
removeEventListeners(
|
|
88
|
+
this.#device,
|
|
89
|
+
this.#boundBluetoothDeviceEventListeners
|
|
90
|
+
);
|
|
74
91
|
}
|
|
75
92
|
if (newDevice) {
|
|
76
93
|
addEventListeners(newDevice, this.#boundBluetoothDeviceEventListeners);
|
|
@@ -86,7 +103,8 @@ class WebBluetoothConnectionManager extends BluetoothConnectionManager {
|
|
|
86
103
|
}
|
|
87
104
|
|
|
88
105
|
#services: Map<BluetoothServiceName, BluetoothService> = new Map();
|
|
89
|
-
#characteristics: Map<BluetoothCharacteristicName, BluetoothCharacteristic> =
|
|
106
|
+
#characteristics: Map<BluetoothCharacteristicName, BluetoothCharacteristic> =
|
|
107
|
+
new Map();
|
|
90
108
|
|
|
91
109
|
async connect() {
|
|
92
110
|
await super.connect();
|
|
@@ -129,7 +147,10 @@ class WebBluetoothConnectionManager extends BluetoothConnectionManager {
|
|
|
129
147
|
const service = services[serviceIndex] as BluetoothService;
|
|
130
148
|
_console.log({ service });
|
|
131
149
|
const serviceName = getServiceNameFromUUID(service.uuid)!;
|
|
132
|
-
_console.assertWithError(
|
|
150
|
+
_console.assertWithError(
|
|
151
|
+
serviceName,
|
|
152
|
+
`no name found for service uuid "${service.uuid}"`
|
|
153
|
+
);
|
|
133
154
|
_console.log(`got "${serviceName}" service`);
|
|
134
155
|
service.name = serviceName;
|
|
135
156
|
this.#services.set(serviceName, service);
|
|
@@ -137,20 +158,33 @@ class WebBluetoothConnectionManager extends BluetoothConnectionManager {
|
|
|
137
158
|
const characteristics = await service.getCharacteristics();
|
|
138
159
|
_console.log(`got characteristics for "${serviceName}" service`);
|
|
139
160
|
for (const characteristicIndex in characteristics) {
|
|
140
|
-
const characteristic = characteristics[
|
|
161
|
+
const characteristic = characteristics[
|
|
162
|
+
characteristicIndex
|
|
163
|
+
] as BluetoothCharacteristic;
|
|
141
164
|
_console.log({ characteristic });
|
|
142
|
-
const characteristicName = getCharacteristicNameFromUUID(
|
|
165
|
+
const characteristicName = getCharacteristicNameFromUUID(
|
|
166
|
+
characteristic.uuid
|
|
167
|
+
)!;
|
|
143
168
|
_console.assertWithError(
|
|
144
169
|
Boolean(characteristicName),
|
|
145
170
|
`no name found for characteristic uuid "${characteristic.uuid}" in "${serviceName}" service`
|
|
146
171
|
);
|
|
147
|
-
_console.log(
|
|
172
|
+
_console.log(
|
|
173
|
+
`got "${characteristicName}" characteristic in "${serviceName}" service`
|
|
174
|
+
);
|
|
148
175
|
characteristic.name = characteristicName;
|
|
149
176
|
this.#characteristics.set(characteristicName, characteristic);
|
|
150
|
-
addEventListeners(
|
|
151
|
-
|
|
177
|
+
addEventListeners(
|
|
178
|
+
characteristic,
|
|
179
|
+
this.#boundBluetoothCharacteristicEventListeners
|
|
180
|
+
);
|
|
181
|
+
const characteristicProperties =
|
|
182
|
+
characteristic.properties ||
|
|
183
|
+
getCharacteristicProperties(characteristicName);
|
|
152
184
|
if (characteristicProperties.notify) {
|
|
153
|
-
_console.log(
|
|
185
|
+
_console.log(
|
|
186
|
+
`starting notifications for "${characteristicName}" characteristic`
|
|
187
|
+
);
|
|
154
188
|
await characteristic.startNotifications();
|
|
155
189
|
}
|
|
156
190
|
if (characteristicProperties.read) {
|
|
@@ -165,18 +199,30 @@ class WebBluetoothConnectionManager extends BluetoothConnectionManager {
|
|
|
165
199
|
}
|
|
166
200
|
async #removeEventListeners() {
|
|
167
201
|
if (this.device) {
|
|
168
|
-
removeEventListeners(
|
|
202
|
+
removeEventListeners(
|
|
203
|
+
this.device,
|
|
204
|
+
this.#boundBluetoothDeviceEventListeners
|
|
205
|
+
);
|
|
169
206
|
}
|
|
170
207
|
|
|
171
|
-
const promises = Array.from(this.#characteristics.keys()).map(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
208
|
+
const promises = Array.from(this.#characteristics.keys()).map(
|
|
209
|
+
(characteristicName) => {
|
|
210
|
+
const characteristic = this.#characteristics.get(characteristicName)!;
|
|
211
|
+
removeEventListeners(
|
|
212
|
+
characteristic,
|
|
213
|
+
this.#boundBluetoothCharacteristicEventListeners
|
|
214
|
+
);
|
|
215
|
+
const characteristicProperties =
|
|
216
|
+
characteristic.properties ||
|
|
217
|
+
getCharacteristicProperties(characteristicName);
|
|
218
|
+
if (characteristicProperties.notify) {
|
|
219
|
+
_console.log(
|
|
220
|
+
`stopping notifications for "${characteristicName}" characteristic`
|
|
221
|
+
);
|
|
222
|
+
return characteristic.stopNotifications();
|
|
223
|
+
}
|
|
178
224
|
}
|
|
179
|
-
|
|
225
|
+
);
|
|
180
226
|
|
|
181
227
|
return Promise.allSettled(promises);
|
|
182
228
|
}
|
|
@@ -203,10 +249,18 @@ class WebBluetoothConnectionManager extends BluetoothConnectionManager {
|
|
|
203
249
|
`no name found for characteristic with uuid "${characteristic.uuid}"`
|
|
204
250
|
);
|
|
205
251
|
|
|
206
|
-
_console.log(
|
|
252
|
+
_console.log(
|
|
253
|
+
`oncharacteristicvaluechanged for "${characteristicName}" characteristic`
|
|
254
|
+
);
|
|
207
255
|
const dataView = characteristic.value!;
|
|
208
|
-
_console.assertWithError(
|
|
209
|
-
|
|
256
|
+
_console.assertWithError(
|
|
257
|
+
dataView,
|
|
258
|
+
`no data found for "${characteristicName}" characteristic`
|
|
259
|
+
);
|
|
260
|
+
_console.log(
|
|
261
|
+
`data for "${characteristicName}" characteristic`,
|
|
262
|
+
Array.from(new Uint8Array(dataView.buffer))
|
|
263
|
+
);
|
|
210
264
|
|
|
211
265
|
try {
|
|
212
266
|
this.onCharacteristicValueChanged(characteristicName, dataView);
|
|
@@ -215,13 +269,21 @@ class WebBluetoothConnectionManager extends BluetoothConnectionManager {
|
|
|
215
269
|
}
|
|
216
270
|
}
|
|
217
271
|
|
|
218
|
-
async writeCharacteristic(
|
|
272
|
+
async writeCharacteristic(
|
|
273
|
+
characteristicName: BluetoothCharacteristicName,
|
|
274
|
+
data: ArrayBuffer
|
|
275
|
+
) {
|
|
219
276
|
super.writeCharacteristic(characteristicName, data);
|
|
220
277
|
|
|
221
278
|
const characteristic = this.#characteristics.get(characteristicName)!;
|
|
222
|
-
_console.assertWithError(
|
|
279
|
+
_console.assertWithError(
|
|
280
|
+
characteristic,
|
|
281
|
+
`${characteristicName} characteristic not found`
|
|
282
|
+
);
|
|
223
283
|
_console.log("writing characteristic", characteristic, data);
|
|
224
|
-
const characteristicProperties =
|
|
284
|
+
const characteristicProperties =
|
|
285
|
+
characteristic.properties ||
|
|
286
|
+
getCharacteristicProperties(characteristicName);
|
|
225
287
|
if (characteristicProperties.writeWithoutResponse) {
|
|
226
288
|
_console.log("writing without response");
|
|
227
289
|
await characteristic.writeValueWithoutResponse(data);
|
|
@@ -250,8 +312,6 @@ class WebBluetoothConnectionManager extends BluetoothConnectionManager {
|
|
|
250
312
|
}
|
|
251
313
|
async reconnect() {
|
|
252
314
|
await super.reconnect();
|
|
253
|
-
_console.log("attempting to reconnect...");
|
|
254
|
-
this.status = "connecting";
|
|
255
315
|
try {
|
|
256
316
|
await this.server!.connect();
|
|
257
317
|
} catch (error) {
|
|
@@ -268,6 +328,11 @@ class WebBluetoothConnectionManager extends BluetoothConnectionManager {
|
|
|
268
328
|
this.status = "notConnected";
|
|
269
329
|
}
|
|
270
330
|
}
|
|
331
|
+
|
|
332
|
+
remove() {
|
|
333
|
+
super.remove();
|
|
334
|
+
this.device = undefined;
|
|
335
|
+
}
|
|
271
336
|
}
|
|
272
337
|
|
|
273
338
|
export default WebBluetoothConnectionManager;
|
|
@@ -15,11 +15,16 @@ if (isInBrowser) {
|
|
|
15
15
|
|
|
16
16
|
function generateBluetoothUUID(value: string): BluetoothServiceUUID {
|
|
17
17
|
_console.assertTypeWithError(value, "string");
|
|
18
|
-
_console.assertWithError(
|
|
19
|
-
|
|
18
|
+
_console.assertWithError(
|
|
19
|
+
value.length == 4,
|
|
20
|
+
"value must be 4 characters long"
|
|
21
|
+
);
|
|
22
|
+
return `ea6d${value}-a725-4f9b-893d-c3913e33b39f`;
|
|
20
23
|
}
|
|
21
24
|
|
|
22
|
-
function stringToCharacteristicUUID(
|
|
25
|
+
function stringToCharacteristicUUID(
|
|
26
|
+
identifier: string
|
|
27
|
+
): BluetoothCharacteristicUUID {
|
|
23
28
|
return BluetoothUUID?.getCharacteristic?.(identifier);
|
|
24
29
|
}
|
|
25
30
|
|
|
@@ -27,19 +32,32 @@ function stringToServiceUUID(identifier: string): BluetoothServiceUUID {
|
|
|
27
32
|
return BluetoothUUID?.getService?.(identifier);
|
|
28
33
|
}
|
|
29
34
|
|
|
30
|
-
export type BluetoothServiceName =
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
export type BluetoothServiceName =
|
|
36
|
+
| "deviceInformation"
|
|
37
|
+
| "battery"
|
|
38
|
+
| "main"
|
|
39
|
+
| "smp";
|
|
40
|
+
import { DeviceInformationType } from "../../DeviceInformationManager.ts";
|
|
41
|
+
export type BluetoothCharacteristicName =
|
|
42
|
+
| DeviceInformationType
|
|
43
|
+
| "batteryLevel"
|
|
44
|
+
| "rx"
|
|
45
|
+
| "tx"
|
|
46
|
+
| "smp";
|
|
33
47
|
|
|
34
48
|
interface BluetoothCharacteristicInformation {
|
|
35
49
|
uuid: BluetoothCharacteristicUUID;
|
|
36
50
|
}
|
|
37
51
|
interface BluetoothServiceInformation {
|
|
38
52
|
uuid: BluetoothServiceUUID;
|
|
39
|
-
characteristics: {
|
|
53
|
+
characteristics: {
|
|
54
|
+
[characteristicName in BluetoothCharacteristicName]?: BluetoothCharacteristicInformation;
|
|
55
|
+
};
|
|
40
56
|
}
|
|
41
57
|
interface BluetoothServicesInformation {
|
|
42
|
-
services: {
|
|
58
|
+
services: {
|
|
59
|
+
[serviceName in BluetoothServiceName]: BluetoothServiceInformation;
|
|
60
|
+
};
|
|
43
61
|
}
|
|
44
62
|
const bluetoothUUIDs: BluetoothServicesInformation = Object.freeze({
|
|
45
63
|
services: {
|
|
@@ -101,9 +119,13 @@ export const optionalServiceUUIDs = [
|
|
|
101
119
|
];
|
|
102
120
|
export const allServiceUUIDs = [...serviceUUIDs, ...optionalServiceUUIDs];
|
|
103
121
|
|
|
104
|
-
export function getServiceNameFromUUID(
|
|
122
|
+
export function getServiceNameFromUUID(
|
|
123
|
+
serviceUUID: BluetoothServiceUUID
|
|
124
|
+
): BluetoothServiceName | undefined {
|
|
105
125
|
serviceUUID = serviceUUID.toString().toLowerCase();
|
|
106
|
-
const serviceNames = Object.keys(
|
|
126
|
+
const serviceNames = Object.keys(
|
|
127
|
+
bluetoothUUIDs.services
|
|
128
|
+
) as BluetoothServiceName[];
|
|
107
129
|
return serviceNames.find((serviceName) => {
|
|
108
130
|
const serviceInfo = bluetoothUUIDs.services[serviceName];
|
|
109
131
|
let serviceInfoUUID = serviceInfo.uuid.toString();
|
|
@@ -127,7 +149,9 @@ Object.values(bluetoothUUIDs.services).forEach((serviceInfo) => {
|
|
|
127
149
|
if (!serviceInfo.characteristics) {
|
|
128
150
|
return;
|
|
129
151
|
}
|
|
130
|
-
const characteristicNames = Object.keys(
|
|
152
|
+
const characteristicNames = Object.keys(
|
|
153
|
+
serviceInfo.characteristics
|
|
154
|
+
) as BluetoothCharacteristicName[];
|
|
131
155
|
characteristicNames.forEach((characteristicName) => {
|
|
132
156
|
const characteristicInfo = serviceInfo.characteristics[characteristicName]!;
|
|
133
157
|
if (serviceUUIDs.includes(serviceInfo.uuid)) {
|
|
@@ -148,9 +172,12 @@ export function getCharacteristicNameFromUUID(
|
|
|
148
172
|
characteristicUUID = characteristicUUID.toString().toLowerCase();
|
|
149
173
|
var characteristicName: BluetoothCharacteristicName | undefined;
|
|
150
174
|
Object.values(bluetoothUUIDs.services).some((serviceInfo) => {
|
|
151
|
-
const characteristicNames = Object.keys(
|
|
175
|
+
const characteristicNames = Object.keys(
|
|
176
|
+
serviceInfo.characteristics
|
|
177
|
+
) as BluetoothCharacteristicName[];
|
|
152
178
|
characteristicName = characteristicNames.find((_characteristicName) => {
|
|
153
|
-
const characteristicInfo =
|
|
179
|
+
const characteristicInfo =
|
|
180
|
+
serviceInfo.characteristics[_characteristicName]!;
|
|
154
181
|
let characteristicInfoUUID = characteristicInfo.uuid.toString();
|
|
155
182
|
if (characteristicUUID.length == 4) {
|
|
156
183
|
characteristicInfoUUID = characteristicInfoUUID.slice(4, 8);
|