@mentra/bluetooth-sdk 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -22
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +16 -17
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +69 -10
- package/build/BluetoothSdk.types.d.ts +86 -12
- package/build/BluetoothSdk.types.d.ts.map +1 -1
- package/build/BluetoothSdk.types.js +11 -0
- package/build/BluetoothSdk.types.js.map +1 -1
- package/build/BluetoothSdkModule.d.ts +20 -7
- package/build/BluetoothSdkModule.d.ts.map +1 -1
- package/build/BluetoothSdkModule.js +114 -0
- package/build/BluetoothSdkModule.js.map +1 -1
- package/ios/BluetoothSdkModule.swift +15 -29
- package/ios/Source/MentraBluetoothSDK.swift +63 -10
- package/package.json +1 -1
- package/src/BluetoothSdk.types.ts +89 -13
- package/src/BluetoothSdkModule.ts +207 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BluetoothSdkModule.d.ts","sourceRoot":"","sources":["../src/BluetoothSdkModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAsB,MAAM,MAAM,CAAA;AAEtD,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"BluetoothSdkModule.d.ts","sourceRoot":"","sources":["../src/BluetoothSdkModule.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,21 @@ const DEFAULT_CONNECT_OPTIONS = {
|
|
|
6
6
|
saveAsDefault: true,
|
|
7
7
|
cancelExistingConnectionAttempt: true,
|
|
8
8
|
};
|
|
9
|
+
const DEFAULT_CONNECT_FIRST_TIMEOUT_MS = 15_000;
|
|
10
|
+
const CAMERA_FOV_SETTINGS = {
|
|
11
|
+
standard: { fov: 118, roi_position: 0 },
|
|
12
|
+
wide: { fov: 118, roi_position: 0 },
|
|
13
|
+
};
|
|
14
|
+
function findSearchResult(status, model) {
|
|
15
|
+
return status.searchResults?.find((device) => device.model === model) ?? null;
|
|
16
|
+
}
|
|
17
|
+
function dashboardMenuItemToNative(item) {
|
|
18
|
+
return {
|
|
19
|
+
...(item.values ?? {}),
|
|
20
|
+
title: item.title,
|
|
21
|
+
packageName: item.packageName,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
9
24
|
function adaptConnectionStatusToNative(connection) {
|
|
10
25
|
switch (connection.state) {
|
|
11
26
|
case "connected":
|
|
@@ -78,12 +93,66 @@ const nativeGetDefaultDevice = NativeBluetoothSdkModule.getDefaultDevice.bind(Na
|
|
|
78
93
|
NativeBluetoothSdkModule.getDefaultDevice = function () {
|
|
79
94
|
return Promise.resolve(nativeGetDefaultDevice());
|
|
80
95
|
};
|
|
96
|
+
const nativeSetMicState = NativeBluetoothSdkModule.setMicState.bind(NativeBluetoothSdkModule);
|
|
97
|
+
const nativeDisplayText = NativeBluetoothSdkModule.displayText.bind(NativeBluetoothSdkModule);
|
|
81
98
|
NativeBluetoothSdkModule.updateGlasses = function (values) {
|
|
82
99
|
return this.update("glasses", adaptGlassesUpdateToNative(values));
|
|
83
100
|
};
|
|
84
101
|
NativeBluetoothSdkModule.updateBluetoothSettings = function (values) {
|
|
85
102
|
return this.update("bluetooth", values);
|
|
86
103
|
};
|
|
104
|
+
NativeBluetoothSdkModule.displayText = function (text, x, y, size) {
|
|
105
|
+
return Promise.resolve(nativeDisplayText(text, x ?? 0, y ?? 0, size ?? 24));
|
|
106
|
+
};
|
|
107
|
+
NativeBluetoothSdkModule.setBrightness = function (level, autoMode) {
|
|
108
|
+
return this.updateBluetoothSettings({
|
|
109
|
+
...(autoMode == null ? {} : { auto_brightness: autoMode }),
|
|
110
|
+
brightness: level,
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
NativeBluetoothSdkModule.setAutoBrightness = function (enabled) {
|
|
114
|
+
return this.updateBluetoothSettings({ auto_brightness: enabled });
|
|
115
|
+
};
|
|
116
|
+
NativeBluetoothSdkModule.setDashboardPosition = function (height, depth) {
|
|
117
|
+
return this.updateBluetoothSettings({
|
|
118
|
+
dashboard_height: height,
|
|
119
|
+
dashboard_depth: depth,
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
NativeBluetoothSdkModule.setDashboardMenu = function (items) {
|
|
123
|
+
return this.updateBluetoothSettings({ menu_apps: items.map(dashboardMenuItemToNative) });
|
|
124
|
+
};
|
|
125
|
+
NativeBluetoothSdkModule.setHeadUpAngle = function (angleDegrees) {
|
|
126
|
+
return this.updateBluetoothSettings({ head_up_angle: angleDegrees });
|
|
127
|
+
};
|
|
128
|
+
NativeBluetoothSdkModule.setScreenDisabled = function (disabled) {
|
|
129
|
+
return this.updateBluetoothSettings({ screen_disabled: disabled });
|
|
130
|
+
};
|
|
131
|
+
NativeBluetoothSdkModule.setButtonPhotoSettings = function (size) {
|
|
132
|
+
return this.updateBluetoothSettings({ button_photo_size: size });
|
|
133
|
+
};
|
|
134
|
+
NativeBluetoothSdkModule.setButtonVideoRecordingSettings = function (width, height, fps) {
|
|
135
|
+
return this.updateBluetoothSettings({
|
|
136
|
+
button_video_width: width,
|
|
137
|
+
button_video_height: height,
|
|
138
|
+
button_video_fps: fps,
|
|
139
|
+
});
|
|
140
|
+
};
|
|
141
|
+
NativeBluetoothSdkModule.setButtonCameraLed = function (enabled) {
|
|
142
|
+
return this.updateBluetoothSettings({ button_camera_led: enabled });
|
|
143
|
+
};
|
|
144
|
+
NativeBluetoothSdkModule.setButtonMaxRecordingTime = function (minutes) {
|
|
145
|
+
return this.updateBluetoothSettings({ button_max_recording_time: minutes });
|
|
146
|
+
};
|
|
147
|
+
NativeBluetoothSdkModule.setCameraFov = function (fov) {
|
|
148
|
+
return this.updateBluetoothSettings({ camera_fov: CAMERA_FOV_SETTINGS[fov] });
|
|
149
|
+
};
|
|
150
|
+
NativeBluetoothSdkModule.setMicState = function (enabled, useGlassesMic, bypassVad, sendTranscript, sendLc3Data) {
|
|
151
|
+
return Promise.resolve(nativeSetMicState(enabled, useGlassesMic ?? true, bypassVad ?? false, sendTranscript ?? false, sendLc3Data ?? false));
|
|
152
|
+
};
|
|
153
|
+
NativeBluetoothSdkModule.setPreferredMic = function (preferredMic) {
|
|
154
|
+
return this.updateBluetoothSettings({ preferred_mic: preferredMic });
|
|
155
|
+
};
|
|
87
156
|
NativeBluetoothSdkModule.onGlassesStatus = function (callback) {
|
|
88
157
|
const subscription = this.addListener("glasses_status", callback);
|
|
89
158
|
return () => subscription.remove();
|
|
@@ -102,5 +171,50 @@ NativeBluetoothSdkModule.connectDefault = function (options) {
|
|
|
102
171
|
NativeBluetoothSdkModule.connect = function (device, options) {
|
|
103
172
|
return this.connectWithOptions(device, { ...DEFAULT_CONNECT_OPTIONS, ...options });
|
|
104
173
|
};
|
|
174
|
+
NativeBluetoothSdkModule.connectFirst = async function (model, options) {
|
|
175
|
+
const { timeoutMs = DEFAULT_CONNECT_FIRST_TIMEOUT_MS, ...connectOptions } = options ?? {};
|
|
176
|
+
const device = await new Promise((resolve, reject) => {
|
|
177
|
+
let timeout = null;
|
|
178
|
+
let removeBluetoothListener = () => { };
|
|
179
|
+
let settled = false;
|
|
180
|
+
const cleanup = () => {
|
|
181
|
+
if (timeout) {
|
|
182
|
+
clearTimeout(timeout);
|
|
183
|
+
}
|
|
184
|
+
removeBluetoothListener();
|
|
185
|
+
};
|
|
186
|
+
const settle = (error, result) => {
|
|
187
|
+
if (settled) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
settled = true;
|
|
191
|
+
cleanup();
|
|
192
|
+
if (error) {
|
|
193
|
+
reject(error);
|
|
194
|
+
}
|
|
195
|
+
else if (result) {
|
|
196
|
+
resolve(result);
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
const handleBluetoothStatus = (status) => {
|
|
200
|
+
const result = findSearchResult(status, model);
|
|
201
|
+
if (result) {
|
|
202
|
+
settle(null, result);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
removeBluetoothListener = this.onBluetoothStatus(handleBluetoothStatus);
|
|
206
|
+
if (Number.isFinite(timeoutMs) && timeoutMs > 0) {
|
|
207
|
+
timeout = setTimeout(() => {
|
|
208
|
+
settle(new Error(`Timed out after ${timeoutMs}ms while scanning for ${model}.`));
|
|
209
|
+
}, timeoutMs);
|
|
210
|
+
}
|
|
211
|
+
Promise.resolve(this.startScan(model))
|
|
212
|
+
.then(() => this.getBluetoothStatus())
|
|
213
|
+
.then(handleBluetoothStatus)
|
|
214
|
+
.catch((error) => settle(error instanceof Error ? error : new Error(String(error))));
|
|
215
|
+
});
|
|
216
|
+
await this.connect(device, connectOptions);
|
|
217
|
+
return device;
|
|
218
|
+
};
|
|
105
219
|
export default NativeBluetoothSdkModule;
|
|
106
220
|
//# sourceMappingURL=BluetoothSdkModule.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BluetoothSdkModule.js","sourceRoot":"","sources":["../src/BluetoothSdkModule.ts"],"names":[],"mappings":"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","sourcesContent":["import {NativeModule, requireNativeModule} from \"expo\"\n\nimport {\n ConnectOptions,\n BluetoothSdkModuleEvents,\n BluetoothStatus,\n DeviceScanRequest,\n GalleryMode,\n Device,\n GlassesMediaVolumeGetResult,\n GlassesMediaVolumeSetResult,\n GlassesStatus,\n PhotoCompression,\n PhotoSize,\n RgbLedAction,\n RgbLedColor,\n StreamKeepAliveRequest,\n StreamStartRequest,\n} from \"./BluetoothSdk.types\"\n\ntype GlassesListener = (changed: Partial<GlassesStatus>) => void\ntype BluetoothStatusListener = (changed: Partial<BluetoothStatus>) => void\ntype MaybePromise<T> = T | Promise<T>\n\ndeclare class BluetoothSdkModule extends NativeModule<BluetoothSdkModuleEvents> {\n // Observable Store Functions (native)\n getGlassesStatus(): Promise<GlassesStatus>\n getBluetoothStatus(): Promise<BluetoothStatus>\n getDefaultDevice(): Promise<Device | null>\n update(category: string, values: Record<string, any>): Promise<void>\n\n // Display Commands\n displayEvent(params: Record<string, any>): Promise<void>\n displayText(params: Record<string, any>): Promise<void>\n clearDisplay(): Promise<void>\n\n // Connection Commands\n requestStatus(): Promise<void>\n connectDefault(options?: ConnectOptions): Promise<void>\n connectDefaultWithOptions(options: Required<ConnectOptions>): Promise<void>\n setDefaultDevice(device: Device | null): Promise<void>\n clearDefaultDevice(): Promise<void>\n startScan(params: DeviceScanRequest): Promise<void>\n connect(device: Device, options?: ConnectOptions): Promise<void>\n connectWithOptions(device: Device, options: Required<ConnectOptions>): Promise<void>\n cancelConnectionAttempt(): Promise<void>\n connectDefaultController(): Promise<void>\n disconnectController(): Promise<void>\n connectSimulated(): Promise<void>\n disconnect(): Promise<void>\n forget(): Promise<void>\n forgetController(): Promise<void>\n showDashboard(): Promise<void>\n ping(): Promise<void>\n dbg1(): Promise<void>\n dbg2(): Promise<void>\n\n // Incident Reporting\n sendIncidentId(incidentId: string, apiBaseUrl?: string | null): Promise<void>\n\n // WiFi Commands\n requestWifiScan(): Promise<void>\n sendWifiCredentials(ssid: string, password: string): Promise<void>\n forgetWifiNetwork(ssid: string): Promise<void>\n setHotspotState(enabled: boolean): Promise<void>\n /** Logs current WiFi frequency (MHz) and 5 GHz band to Android logcat. */\n logCurrentWifiFrequency(): Promise<void>\n\n // Gallery Commands\n setGalleryMode(mode: GalleryMode): Promise<void>\n queryGalleryStatus(): Promise<void>\n photoRequest(\n requestId: string,\n appId: string,\n size: PhotoSize,\n webhookUrl: string | null,\n authToken: string | null,\n compress: PhotoCompression,\n flash: boolean,\n sound: boolean,\n ): Promise<void>\n\n // OTA Commands\n sendOtaStart(): Promise<void>\n sendOtaQueryStatus(): Promise<void>\n\n // Version Info Commands\n requestVersionInfo(): Promise<void>\n\n // Video Recording Commands\n startVideoRecording(requestId: string, save: boolean, flash: boolean, sound: boolean): Promise<void>\n stopVideoRecording(requestId: string): Promise<void>\n\n // Stream Commands\n startStream(params: StreamStartRequest): Promise<void>\n stopStream(): Promise<void>\n keepStreamAlive(params: StreamKeepAliveRequest): Promise<void>\n\n // Microphone Commands\n setMicState(sendPcmData: boolean, sendTranscript: boolean, bypassVad: boolean): Promise<void>\n restartTranscriber(): Promise<void>\n\n // Audio Playback Monitoring\n // Notify native side when our app starts/stops playing audio\n // Used to suspend LC3 mic during audio playback to avoid MCU overload\n setOwnAppAudioPlaying(playing: boolean): Promise<void>\n\n /** Mentra Live only: K900 `cs_getvol` / `sr_getvol`. */\n getGlassesMediaVolume(): Promise<GlassesMediaVolumeGetResult>\n /** Mentra Live only: K900 `cs_vol` / `sr_vol`; level clamped 0–15 on native. */\n setGlassesMediaVolume(level: number): Promise<GlassesMediaVolumeSetResult>\n\n // RGB LED Control\n rgbLedControl(\n requestId: string,\n packageName: string | null,\n action: RgbLedAction,\n color: RgbLedColor | null,\n ontime: number,\n offtime: number,\n count: number,\n ): Promise<void>\n\n // STT Commands\n setSttModelDetails(path: string, languageCode: string): Promise<void>\n getSttModelPath(): Promise<string>\n checkSttModelAvailable(): Promise<boolean>\n validateSttModel(path: string): Promise<boolean>\n extractTarBz2(sourcePath: string, destinationPath: string): Promise<boolean>\n\n // Helper methods for type-safe observable store access\n updateGlasses(values: Partial<GlassesStatus>): Promise<void>\n updateBluetoothSettings(values: Record<string, any>): Promise<void>\n onGlassesStatus(callback: GlassesListener): () => void\n onBluetoothStatus(callback: BluetoothStatusListener): () => void\n\n // Process resident-set-size in MB. iOS-only; Android stub returns 0.\n getMemoryMB(): number\n}\n\n// This call loads the native module object from the JSI.\n// NativeModule<BluetoothSdkModuleEvents> already extends EventEmitter<BluetoothSdkModuleEvents>\nconst NativeBluetoothSdkModule = requireNativeModule<BluetoothSdkModule>(\"BluetoothSdk\")\n\nconst DEFAULT_CONNECT_OPTIONS: Required<ConnectOptions> = {\n saveAsDefault: true,\n cancelExistingConnectionAttempt: true,\n}\n\nfunction adaptConnectionStatusToNative(connection: GlassesStatus[\"connection\"]): Record<string, any> {\n switch (connection.state) {\n case \"connected\":\n return {connectionState: \"CONNECTED\", connected: true, fullyBooted: connection.fullyBooted}\n case \"scanning\":\n return {connectionState: \"SCANNING\", connected: false, fullyBooted: false}\n case \"connecting\":\n return {connectionState: \"CONNECTING\", connected: false, fullyBooted: false}\n case \"bonding\":\n return {connectionState: \"BONDING\", connected: false, fullyBooted: false}\n case \"disconnected\":\n return {connectionState: \"DISCONNECTED\", connected: false, fullyBooted: false}\n }\n}\n\nfunction adaptGlassesUpdateToNative(values: Partial<GlassesStatus>): Record<string, any> {\n const {wifi, hotspot, connection, ...rest} = values\n let update: Record<string, any> = {...rest}\n if (connection) {\n update = {\n ...update,\n ...adaptConnectionStatusToNative(connection),\n }\n }\n if (wifi?.state === \"connected\") {\n update = {\n ...update,\n wifiConnected: true,\n wifiSsid: wifi.ssid,\n wifiLocalIp: wifi.localIp ?? \"\",\n }\n } else if (wifi?.state === \"disconnected\") {\n update = {\n ...update,\n wifiConnected: false,\n wifiSsid: \"\",\n wifiLocalIp: \"\",\n }\n }\n if (hotspot?.state === \"enabled\") {\n update = {\n ...update,\n hotspotEnabled: true,\n hotspotSsid: hotspot.ssid,\n hotspotPassword: hotspot.password,\n hotspotGatewayIp: hotspot.localIp,\n }\n } else if (hotspot?.state === \"disabled\") {\n update = {\n ...update,\n hotspotEnabled: false,\n hotspotSsid: \"\",\n hotspotPassword: \"\",\n hotspotGatewayIp: \"\",\n }\n }\n return update\n}\n\n// Add helper methods to the module\nconst nativeGetGlassesStatus = NativeBluetoothSdkModule.getGlassesStatus.bind(\n NativeBluetoothSdkModule,\n) as () => MaybePromise<GlassesStatus>\nNativeBluetoothSdkModule.getGlassesStatus = function () {\n return Promise.resolve(nativeGetGlassesStatus())\n}\n\nconst nativeGetBluetoothStatus = NativeBluetoothSdkModule.getBluetoothStatus.bind(NativeBluetoothSdkModule) as () => MaybePromise<BluetoothStatus>\nNativeBluetoothSdkModule.getBluetoothStatus = function () {\n return Promise.resolve(nativeGetBluetoothStatus())\n}\n\nconst nativeGetDefaultDevice = NativeBluetoothSdkModule.getDefaultDevice.bind(\n NativeBluetoothSdkModule,\n) as () => MaybePromise<Device | null>\nNativeBluetoothSdkModule.getDefaultDevice = function () {\n return Promise.resolve(nativeGetDefaultDevice())\n}\n\nNativeBluetoothSdkModule.updateGlasses = function (values: Partial<GlassesStatus>) {\n return this.update(\"glasses\", adaptGlassesUpdateToNative(values))\n}\n\nNativeBluetoothSdkModule.updateBluetoothSettings = function (values: Record<string, any>) {\n return this.update(\"bluetooth\", values)\n}\n\nNativeBluetoothSdkModule.onGlassesStatus = function (callback: GlassesListener) {\n const subscription = this.addListener(\"glasses_status\", callback)\n return () => subscription.remove()\n}\n\nNativeBluetoothSdkModule.onBluetoothStatus = function (callback: BluetoothStatusListener) {\n const subscription = this.addListener(\"bluetooth_status\", callback)\n return () => subscription.remove()\n}\n\nconst nativeConnectDefault = NativeBluetoothSdkModule.connectDefault.bind(NativeBluetoothSdkModule)\nNativeBluetoothSdkModule.connectDefault = function (options?: ConnectOptions) {\n if (!options) {\n return nativeConnectDefault()\n }\n return this.connectDefaultWithOptions({...DEFAULT_CONNECT_OPTIONS, ...options})\n}\n\nNativeBluetoothSdkModule.connect = function (device: Device, options?: ConnectOptions) {\n return this.connectWithOptions(device, {...DEFAULT_CONNECT_OPTIONS, ...options})\n}\n\nexport default NativeBluetoothSdkModule\n"]}
|
|
1
|
+
{"version":3,"file":"BluetoothSdkModule.js","sourceRoot":"","sources":["../src/BluetoothSdkModule.ts"],"names":[],"mappings":"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","sourcesContent":["import {NativeModule, requireNativeModule} from \"expo\"\n\nimport {\n BluetoothSettingsUpdate,\n BluetoothSdkModuleEvents,\n BluetoothStatus,\n ButtonPhotoSize,\n CameraFov,\n CameraFovSetting,\n ConnectFirstOptions,\n ConnectOptions,\n DashboardMenuItem,\n Device,\n DeviceModel,\n GalleryMode,\n GlassesMediaVolumeGetResult,\n GlassesMediaVolumeSetResult,\n GlassesStatus,\n MicPreference,\n ObservableStoreCategory,\n PhotoCompression,\n PhotoSize,\n RgbLedAction,\n RgbLedColor,\n StreamKeepAliveRequest,\n StreamStartRequest,\n} from \"./BluetoothSdk.types\"\n\ntype GlassesListener = (changed: Partial<GlassesStatus>) => void\ntype BluetoothStatusListener = (changed: Partial<BluetoothStatus>) => void\ntype MaybePromise<T> = T | Promise<T>\n\ndeclare class BluetoothSdkModule extends NativeModule<BluetoothSdkModuleEvents> {\n // Observable Store Functions (native)\n getGlassesStatus(): Promise<GlassesStatus>\n getBluetoothStatus(): Promise<BluetoothStatus>\n getDefaultDevice(): Promise<Device | null>\n update(category: ObservableStoreCategory, values: object): Promise<void>\n\n // Display Commands\n displayEvent(params: Record<string, unknown>): Promise<void>\n displayText(text: string, x?: number, y?: number, size?: number): Promise<void>\n clearDisplay(): Promise<void>\n\n // Connection Commands\n requestStatus(): Promise<void>\n connectDefault(options?: ConnectOptions): Promise<void>\n connectDefaultWithOptions(options: Required<ConnectOptions>): Promise<void>\n setDefaultDevice(device: Device | null): Promise<void>\n clearDefaultDevice(): Promise<void>\n startScan(model: DeviceModel): Promise<void>\n connectFirst(model: DeviceModel, options?: ConnectFirstOptions): Promise<Device>\n connect(device: Device, options?: ConnectOptions): Promise<void>\n connectWithOptions(device: Device, options: Required<ConnectOptions>): Promise<void>\n cancelConnectionAttempt(): Promise<void>\n connectDefaultController(): Promise<void>\n disconnectController(): Promise<void>\n connectSimulated(): Promise<void>\n disconnect(): Promise<void>\n forget(): Promise<void>\n forgetController(): Promise<void>\n showDashboard(): Promise<void>\n setBrightness(level: number, autoMode?: boolean | null): Promise<void>\n setAutoBrightness(enabled: boolean): Promise<void>\n setDashboardPosition(height: number, depth: number): Promise<void>\n setDashboardMenu(items: DashboardMenuItem[]): Promise<void>\n setHeadUpAngle(angleDegrees: number): Promise<void>\n setScreenDisabled(disabled: boolean): Promise<void>\n ping(): Promise<void>\n dbg1(): Promise<void>\n dbg2(): Promise<void>\n\n // Incident Reporting\n sendIncidentId(incidentId: string, apiBaseUrl?: string | null): Promise<void>\n\n // WiFi Commands\n requestWifiScan(): Promise<void>\n sendWifiCredentials(ssid: string, password: string): Promise<void>\n forgetWifiNetwork(ssid: string): Promise<void>\n setHotspotState(enabled: boolean): Promise<void>\n /** Logs current WiFi frequency (MHz) and 5 GHz band to Android logcat. */\n logCurrentWifiFrequency(): Promise<void>\n\n // Gallery Commands\n setGalleryMode(mode: GalleryMode): Promise<void>\n setButtonPhotoSettings(size: ButtonPhotoSize): Promise<void>\n setButtonVideoRecordingSettings(width: number, height: number, fps: number): Promise<void>\n setButtonCameraLed(enabled: boolean): Promise<void>\n setButtonMaxRecordingTime(minutes: number): Promise<void>\n setCameraFov(fov: CameraFov): Promise<void>\n queryGalleryStatus(): Promise<void>\n photoRequest(\n requestId: string,\n appId: string,\n size: PhotoSize,\n webhookUrl: string | null,\n authToken: string | null,\n compress: PhotoCompression,\n flash: boolean,\n sound: boolean,\n ): Promise<void>\n\n // OTA Commands\n sendOtaStart(): Promise<void>\n sendOtaQueryStatus(): Promise<void>\n\n // Version Info Commands\n requestVersionInfo(): Promise<void>\n\n // Video Recording Commands\n startVideoRecording(requestId: string, save: boolean, flash: boolean, sound: boolean): Promise<void>\n stopVideoRecording(requestId: string): Promise<void>\n\n // Stream Commands\n startStream(params: StreamStartRequest): Promise<void>\n stopStream(): Promise<void>\n keepStreamAlive(params: StreamKeepAliveRequest): Promise<void>\n\n // Microphone Commands\n setMicState(\n enabled: boolean,\n useGlassesMic?: boolean,\n bypassVad?: boolean,\n sendTranscript?: boolean,\n sendLc3Data?: boolean,\n ): Promise<void>\n setPreferredMic(preferredMic: MicPreference): Promise<void>\n restartTranscriber(): Promise<void>\n\n // Audio Playback Monitoring\n // Notify native side when our app starts/stops playing audio\n // Used to suspend LC3 mic during audio playback to avoid MCU overload\n setOwnAppAudioPlaying(playing: boolean): Promise<void>\n\n /** Mentra Live only: K900 `cs_getvol` / `sr_getvol`. */\n getGlassesMediaVolume(): Promise<GlassesMediaVolumeGetResult>\n /** Mentra Live only: K900 `cs_vol` / `sr_vol`; level clamped 0–15 on native. */\n setGlassesMediaVolume(level: number): Promise<GlassesMediaVolumeSetResult>\n\n // RGB LED Control\n rgbLedControl(\n requestId: string,\n packageName: string | null,\n action: RgbLedAction,\n color: RgbLedColor | null,\n ontime: number,\n offtime: number,\n count: number,\n ): Promise<void>\n\n // STT Commands\n setSttModelDetails(path: string, languageCode: string): Promise<void>\n getSttModelPath(): Promise<string>\n checkSttModelAvailable(): Promise<boolean>\n validateSttModel(path: string): Promise<boolean>\n extractTarBz2(sourcePath: string, destinationPath: string): Promise<boolean>\n\n // Helper methods for type-safe observable store access\n updateGlasses(values: Partial<GlassesStatus>): Promise<void>\n updateBluetoothSettings(values: BluetoothSettingsUpdate): Promise<void>\n onGlassesStatus(callback: GlassesListener): () => void\n onBluetoothStatus(callback: BluetoothStatusListener): () => void\n\n // Process resident-set-size in MB. iOS-only; Android stub returns 0.\n getMemoryMB(): number\n}\n\n// This call loads the native module object from the JSI.\n// NativeModule<BluetoothSdkModuleEvents> already extends EventEmitter<BluetoothSdkModuleEvents>\nconst NativeBluetoothSdkModule = requireNativeModule<BluetoothSdkModule>(\"BluetoothSdk\")\n\nconst DEFAULT_CONNECT_OPTIONS: Required<ConnectOptions> = {\n saveAsDefault: true,\n cancelExistingConnectionAttempt: true,\n}\n\nconst DEFAULT_CONNECT_FIRST_TIMEOUT_MS = 15_000\n\nconst CAMERA_FOV_SETTINGS: Record<CameraFov, CameraFovSetting> = {\n standard: {fov: 118, roi_position: 0},\n wide: {fov: 118, roi_position: 0},\n}\n\nfunction findSearchResult(status: Partial<BluetoothStatus>, model: DeviceModel): Device | null {\n return status.searchResults?.find((device) => device.model === model) ?? null\n}\n\nfunction dashboardMenuItemToNative(item: DashboardMenuItem): Record<string, unknown> {\n return {\n ...(item.values ?? {}),\n title: item.title,\n packageName: item.packageName,\n }\n}\n\nfunction adaptConnectionStatusToNative(connection: GlassesStatus[\"connection\"]): Record<string, unknown> {\n switch (connection.state) {\n case \"connected\":\n return {connectionState: \"CONNECTED\", connected: true, fullyBooted: connection.fullyBooted}\n case \"scanning\":\n return {connectionState: \"SCANNING\", connected: false, fullyBooted: false}\n case \"connecting\":\n return {connectionState: \"CONNECTING\", connected: false, fullyBooted: false}\n case \"bonding\":\n return {connectionState: \"BONDING\", connected: false, fullyBooted: false}\n case \"disconnected\":\n return {connectionState: \"DISCONNECTED\", connected: false, fullyBooted: false}\n }\n}\n\nfunction adaptGlassesUpdateToNative(values: Partial<GlassesStatus>): Record<string, unknown> {\n const {wifi, hotspot, connection, ...rest} = values\n let update: Record<string, unknown> = {...rest}\n if (connection) {\n update = {\n ...update,\n ...adaptConnectionStatusToNative(connection),\n }\n }\n if (wifi?.state === \"connected\") {\n update = {\n ...update,\n wifiConnected: true,\n wifiSsid: wifi.ssid,\n wifiLocalIp: wifi.localIp ?? \"\",\n }\n } else if (wifi?.state === \"disconnected\") {\n update = {\n ...update,\n wifiConnected: false,\n wifiSsid: \"\",\n wifiLocalIp: \"\",\n }\n }\n if (hotspot?.state === \"enabled\") {\n update = {\n ...update,\n hotspotEnabled: true,\n hotspotSsid: hotspot.ssid,\n hotspotPassword: hotspot.password,\n hotspotGatewayIp: hotspot.localIp,\n }\n } else if (hotspot?.state === \"disabled\") {\n update = {\n ...update,\n hotspotEnabled: false,\n hotspotSsid: \"\",\n hotspotPassword: \"\",\n hotspotGatewayIp: \"\",\n }\n }\n return update\n}\n\n// Add helper methods to the module\nconst nativeGetGlassesStatus = NativeBluetoothSdkModule.getGlassesStatus.bind(\n NativeBluetoothSdkModule,\n) as () => MaybePromise<GlassesStatus>\nNativeBluetoothSdkModule.getGlassesStatus = function () {\n return Promise.resolve(nativeGetGlassesStatus())\n}\n\nconst nativeGetBluetoothStatus = NativeBluetoothSdkModule.getBluetoothStatus.bind(NativeBluetoothSdkModule) as () => MaybePromise<BluetoothStatus>\nNativeBluetoothSdkModule.getBluetoothStatus = function () {\n return Promise.resolve(nativeGetBluetoothStatus())\n}\n\nconst nativeGetDefaultDevice = NativeBluetoothSdkModule.getDefaultDevice.bind(\n NativeBluetoothSdkModule,\n) as () => MaybePromise<Device | null>\nNativeBluetoothSdkModule.getDefaultDevice = function () {\n return Promise.resolve(nativeGetDefaultDevice())\n}\n\nconst nativeSetMicState = NativeBluetoothSdkModule.setMicState.bind(NativeBluetoothSdkModule) as (\n enabled: boolean,\n useGlassesMic: boolean,\n bypassVad: boolean,\n sendTranscript: boolean,\n sendLc3Data: boolean,\n) => MaybePromise<void>\n\nconst nativeDisplayText = NativeBluetoothSdkModule.displayText.bind(NativeBluetoothSdkModule) as (\n text: string,\n x: number,\n y: number,\n size: number,\n) => MaybePromise<void>\n\nNativeBluetoothSdkModule.updateGlasses = function (values: Partial<GlassesStatus>) {\n return this.update(\"glasses\", adaptGlassesUpdateToNative(values))\n}\n\nNativeBluetoothSdkModule.updateBluetoothSettings = function (values: BluetoothSettingsUpdate) {\n return this.update(\"bluetooth\", values)\n}\n\nNativeBluetoothSdkModule.displayText = function (text: string, x?: number, y?: number, size?: number) {\n return Promise.resolve(nativeDisplayText(text, x ?? 0, y ?? 0, size ?? 24))\n}\n\nNativeBluetoothSdkModule.setBrightness = function (level: number, autoMode?: boolean | null) {\n return this.updateBluetoothSettings({\n ...(autoMode == null ? {} : {auto_brightness: autoMode}),\n brightness: level,\n })\n}\n\nNativeBluetoothSdkModule.setAutoBrightness = function (enabled: boolean) {\n return this.updateBluetoothSettings({auto_brightness: enabled})\n}\n\nNativeBluetoothSdkModule.setDashboardPosition = function (height: number, depth: number) {\n return this.updateBluetoothSettings({\n dashboard_height: height,\n dashboard_depth: depth,\n })\n}\n\nNativeBluetoothSdkModule.setDashboardMenu = function (items: DashboardMenuItem[]) {\n return this.updateBluetoothSettings({menu_apps: items.map(dashboardMenuItemToNative)})\n}\n\nNativeBluetoothSdkModule.setHeadUpAngle = function (angleDegrees: number) {\n return this.updateBluetoothSettings({head_up_angle: angleDegrees})\n}\n\nNativeBluetoothSdkModule.setScreenDisabled = function (disabled: boolean) {\n return this.updateBluetoothSettings({screen_disabled: disabled})\n}\n\nNativeBluetoothSdkModule.setButtonPhotoSettings = function (size: ButtonPhotoSize) {\n return this.updateBluetoothSettings({button_photo_size: size})\n}\n\nNativeBluetoothSdkModule.setButtonVideoRecordingSettings = function (width: number, height: number, fps: number) {\n return this.updateBluetoothSettings({\n button_video_width: width,\n button_video_height: height,\n button_video_fps: fps,\n })\n}\n\nNativeBluetoothSdkModule.setButtonCameraLed = function (enabled: boolean) {\n return this.updateBluetoothSettings({button_camera_led: enabled})\n}\n\nNativeBluetoothSdkModule.setButtonMaxRecordingTime = function (minutes: number) {\n return this.updateBluetoothSettings({button_max_recording_time: minutes})\n}\n\nNativeBluetoothSdkModule.setCameraFov = function (fov: CameraFov) {\n return this.updateBluetoothSettings({camera_fov: CAMERA_FOV_SETTINGS[fov]})\n}\n\nNativeBluetoothSdkModule.setMicState = function (\n enabled: boolean,\n useGlassesMic?: boolean,\n bypassVad?: boolean,\n sendTranscript?: boolean,\n sendLc3Data?: boolean,\n) {\n return Promise.resolve(\n nativeSetMicState(\n enabled,\n useGlassesMic ?? true,\n bypassVad ?? false,\n sendTranscript ?? false,\n sendLc3Data ?? false,\n ),\n )\n}\n\nNativeBluetoothSdkModule.setPreferredMic = function (preferredMic: MicPreference) {\n return this.updateBluetoothSettings({preferred_mic: preferredMic})\n}\n\nNativeBluetoothSdkModule.onGlassesStatus = function (callback: GlassesListener) {\n const subscription = this.addListener(\"glasses_status\", callback)\n return () => subscription.remove()\n}\n\nNativeBluetoothSdkModule.onBluetoothStatus = function (callback: BluetoothStatusListener) {\n const subscription = this.addListener(\"bluetooth_status\", callback)\n return () => subscription.remove()\n}\n\nconst nativeConnectDefault = NativeBluetoothSdkModule.connectDefault.bind(NativeBluetoothSdkModule)\nNativeBluetoothSdkModule.connectDefault = function (options?: ConnectOptions) {\n if (!options) {\n return nativeConnectDefault()\n }\n return this.connectDefaultWithOptions({...DEFAULT_CONNECT_OPTIONS, ...options})\n}\n\nNativeBluetoothSdkModule.connect = function (device: Device, options?: ConnectOptions) {\n return this.connectWithOptions(device, {...DEFAULT_CONNECT_OPTIONS, ...options})\n}\n\nNativeBluetoothSdkModule.connectFirst = async function (model: DeviceModel, options?: ConnectFirstOptions) {\n const {timeoutMs = DEFAULT_CONNECT_FIRST_TIMEOUT_MS, ...connectOptions} = options ?? {}\n\n const device = await new Promise<Device>((resolve, reject) => {\n let timeout: ReturnType<typeof setTimeout> | null = null\n let removeBluetoothListener = () => {}\n let settled = false\n\n const cleanup = () => {\n if (timeout) {\n clearTimeout(timeout)\n }\n removeBluetoothListener()\n }\n\n const settle = (error: Error | null, result?: Device) => {\n if (settled) {\n return\n }\n settled = true\n cleanup()\n if (error) {\n reject(error)\n } else if (result) {\n resolve(result)\n }\n }\n\n const handleBluetoothStatus = (status: Partial<BluetoothStatus>) => {\n const result = findSearchResult(status, model)\n if (result) {\n settle(null, result)\n }\n }\n\n removeBluetoothListener = this.onBluetoothStatus(handleBluetoothStatus)\n\n if (Number.isFinite(timeoutMs) && timeoutMs > 0) {\n timeout = setTimeout(() => {\n settle(new Error(`Timed out after ${timeoutMs}ms while scanning for ${model}.`))\n }, timeoutMs)\n }\n\n Promise.resolve(this.startScan(model))\n .then(() => this.getBluetoothStatus())\n .then(handleBluetoothStatus)\n .catch((error) => settle(error instanceof Error ? error : new Error(String(error))))\n })\n\n await this.connect(device, connectOptions)\n return device\n}\n\nexport default NativeBluetoothSdkModule\n"]}
|
|
@@ -108,15 +108,9 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
108
108
|
try? await sdk.displayEvent(DisplayEventRequest(values: params))
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
AsyncFunction("displayText") { (
|
|
112
|
-
let request = DisplayTextRequest(
|
|
113
|
-
text: params["text"] as? String ?? "",
|
|
114
|
-
x: intValue(params["x"], defaultValue: 0),
|
|
115
|
-
y: intValue(params["y"], defaultValue: 0),
|
|
116
|
-
size: intValue(params["size"], defaultValue: 24)
|
|
117
|
-
)
|
|
111
|
+
AsyncFunction("displayText") { (text: String, x: Int?, y: Int?, size: Int?) in
|
|
118
112
|
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
119
|
-
try? await sdk.displayText(
|
|
113
|
+
try? await sdk.displayText(text, x: x ?? 0, y: y ?? 0, size: size ?? 24)
|
|
120
114
|
}
|
|
121
115
|
|
|
122
116
|
// MARK: - Connection Commands
|
|
@@ -193,9 +187,8 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
193
187
|
}
|
|
194
188
|
}
|
|
195
189
|
|
|
196
|
-
AsyncFunction("startScan") { (
|
|
190
|
+
AsyncFunction("startScan") { (model: String) in
|
|
197
191
|
try await MainActor.run {
|
|
198
|
-
let model = params["model"] as? String ?? DeviceTypes.LIVE
|
|
199
192
|
try self.bluetoothSdk().startScan(model: DeviceModel.fromDeviceType(model))
|
|
200
193
|
}
|
|
201
194
|
}
|
|
@@ -448,14 +441,20 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
448
441
|
|
|
449
442
|
// MARK: - Microphone Commands
|
|
450
443
|
|
|
451
|
-
AsyncFunction("setMicState") { (
|
|
444
|
+
AsyncFunction("setMicState") { (
|
|
445
|
+
enabled: Bool,
|
|
446
|
+
useGlassesMic: Bool?,
|
|
447
|
+
bypassVad: Bool?,
|
|
448
|
+
sendTranscript: Bool?,
|
|
449
|
+
sendLc3Data: Bool?
|
|
450
|
+
) in
|
|
452
451
|
await MainActor.run {
|
|
453
452
|
self.bluetoothSdk().setMicState(
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
453
|
+
enabled: enabled,
|
|
454
|
+
useGlassesMic: useGlassesMic ?? true,
|
|
455
|
+
bypassVad: bypassVad ?? false,
|
|
456
|
+
sendTranscript: sendTranscript ?? false,
|
|
457
|
+
sendLc3Data: sendLc3Data ?? false
|
|
459
458
|
)
|
|
460
459
|
}
|
|
461
460
|
}
|
|
@@ -522,19 +521,6 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
522
521
|
}
|
|
523
522
|
}
|
|
524
523
|
|
|
525
|
-
private func intValue(_ value: Any?, defaultValue: Int) -> Int {
|
|
526
|
-
switch value {
|
|
527
|
-
case let value as Int:
|
|
528
|
-
return value
|
|
529
|
-
case let value as Double:
|
|
530
|
-
return Int(value)
|
|
531
|
-
case let value as NSNumber:
|
|
532
|
-
return value.intValue
|
|
533
|
-
default:
|
|
534
|
-
return defaultValue
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
|
|
538
524
|
@MainActor
|
|
539
525
|
public func mentraBluetoothSDK(_: MentraBluetoothSDK, didUpdateGlassesStatus status: GlassesStatusUpdate) {
|
|
540
526
|
sendEvent("glasses_status", status.dictionary)
|
|
@@ -2115,6 +2115,10 @@ public final class MentraBluetoothSDK {
|
|
|
2115
2115
|
DeviceManager.shared.forget()
|
|
2116
2116
|
}
|
|
2117
2117
|
|
|
2118
|
+
public func displayText(_ text: String, x: Int = 0, y: Int = 0, size: Int = 24) async throws {
|
|
2119
|
+
try await displayText(DisplayTextRequest(text: text, x: x, y: y, size: size))
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2118
2122
|
public func displayText(_ request: DisplayTextRequest) async throws {
|
|
2119
2123
|
DeviceManager.shared.displayText(request.dictionary)
|
|
2120
2124
|
}
|
|
@@ -2142,9 +2146,13 @@ public final class MentraBluetoothSDK {
|
|
|
2142
2146
|
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "auto_brightness", enabled)
|
|
2143
2147
|
}
|
|
2144
2148
|
|
|
2149
|
+
public func setDashboardPosition(height: Int, depth: Int) async throws {
|
|
2150
|
+
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "dashboard_height", height)
|
|
2151
|
+
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "dashboard_depth", depth)
|
|
2152
|
+
}
|
|
2153
|
+
|
|
2145
2154
|
public func setDashboardPosition(_ request: DashboardPositionRequest) async throws {
|
|
2146
|
-
|
|
2147
|
-
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "dashboard_depth", request.depth)
|
|
2155
|
+
try await setDashboardPosition(height: request.height, depth: request.depth)
|
|
2148
2156
|
}
|
|
2149
2157
|
|
|
2150
2158
|
public func setDashboardMenu(_ items: [DashboardMenuItem]) async throws {
|
|
@@ -2167,14 +2175,22 @@ public final class MentraBluetoothSDK {
|
|
|
2167
2175
|
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "gallery_mode", mode == .auto)
|
|
2168
2176
|
}
|
|
2169
2177
|
|
|
2178
|
+
public func setButtonPhotoSettings(size: ButtonPhotoSize) async throws {
|
|
2179
|
+
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "button_photo_size", size.rawValue)
|
|
2180
|
+
}
|
|
2181
|
+
|
|
2170
2182
|
public func setButtonPhotoSettings(_ settings: ButtonPhotoSettings) async throws {
|
|
2171
|
-
|
|
2183
|
+
try await setButtonPhotoSettings(size: settings.size)
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
public func setButtonVideoRecordingSettings(width: Int, height: Int, fps: Int) async throws {
|
|
2187
|
+
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "button_video_width", width)
|
|
2188
|
+
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "button_video_height", height)
|
|
2189
|
+
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "button_video_fps", fps)
|
|
2172
2190
|
}
|
|
2173
2191
|
|
|
2174
2192
|
public func setButtonVideoRecordingSettings(_ settings: ButtonVideoRecordingSettings) async throws {
|
|
2175
|
-
|
|
2176
|
-
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "button_video_height", settings.height)
|
|
2177
|
-
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "button_video_fps", settings.fps)
|
|
2193
|
+
try await setButtonVideoRecordingSettings(width: settings.width, height: settings.height, fps: settings.fps)
|
|
2178
2194
|
}
|
|
2179
2195
|
|
|
2180
2196
|
public func setButtonCameraLed(enabled: Bool) async throws {
|
|
@@ -2189,11 +2205,48 @@ public final class MentraBluetoothSDK {
|
|
|
2189
2205
|
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "camera_fov", fov.value)
|
|
2190
2206
|
}
|
|
2191
2207
|
|
|
2208
|
+
public func setMicState(
|
|
2209
|
+
enabled: Bool,
|
|
2210
|
+
useGlassesMic: Bool = true,
|
|
2211
|
+
bypassVad: Bool = false,
|
|
2212
|
+
sendTranscript: Bool = false,
|
|
2213
|
+
sendLc3Data: Bool = false
|
|
2214
|
+
) {
|
|
2215
|
+
if enabled {
|
|
2216
|
+
DeviceStore.shared.apply(
|
|
2217
|
+
ObservableStore.bluetoothCategory,
|
|
2218
|
+
"preferred_mic",
|
|
2219
|
+
useGlassesMic ? MicPreference.glasses.rawValue : MicPreference.phone.rawValue
|
|
2220
|
+
)
|
|
2221
|
+
}
|
|
2222
|
+
applyMicState(
|
|
2223
|
+
sendPcmData: enabled,
|
|
2224
|
+
sendTranscript: enabled && sendTranscript,
|
|
2225
|
+
bypassVad: bypassVad,
|
|
2226
|
+
sendLc3Data: enabled && sendLc3Data
|
|
2227
|
+
)
|
|
2228
|
+
}
|
|
2229
|
+
|
|
2230
|
+
@available(*, deprecated, message: "Use setMicState(enabled:useGlassesMic:bypassVad:) instead.")
|
|
2192
2231
|
public func setMicState(_ config: MicConfiguration) {
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2232
|
+
applyMicState(
|
|
2233
|
+
sendPcmData: config.sendPcmData,
|
|
2234
|
+
sendTranscript: config.sendTranscript,
|
|
2235
|
+
bypassVad: config.bypassVad,
|
|
2236
|
+
sendLc3Data: config.sendLc3Data
|
|
2237
|
+
)
|
|
2238
|
+
}
|
|
2239
|
+
|
|
2240
|
+
private func applyMicState(
|
|
2241
|
+
sendPcmData: Bool,
|
|
2242
|
+
sendTranscript: Bool,
|
|
2243
|
+
bypassVad: Bool,
|
|
2244
|
+
sendLc3Data: Bool
|
|
2245
|
+
) {
|
|
2246
|
+
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "should_send_pcm", sendPcmData)
|
|
2247
|
+
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "should_send_lc3", sendLc3Data)
|
|
2248
|
+
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "should_send_transcript", sendTranscript)
|
|
2249
|
+
DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "bypass_vad", bypassVad)
|
|
2197
2250
|
DeviceManager.shared.setMicState()
|
|
2198
2251
|
}
|
|
2199
2252
|
|
package/package.json
CHANGED
|
@@ -144,7 +144,7 @@ export type GalleryStatusEvent = {
|
|
|
144
144
|
|
|
145
145
|
export type CompatibleGlassesSearchStopEvent = {
|
|
146
146
|
type: "compatible_glasses_search_stop"
|
|
147
|
-
device_model:
|
|
147
|
+
device_model: DeviceModel
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
export type HeartbeatSentEvent = {
|
|
@@ -196,6 +196,38 @@ export type GalleryMode = "auto" | "manual"
|
|
|
196
196
|
export type PhotoSize = "small" | "medium" | "large" | "full"
|
|
197
197
|
export type ButtonPhotoSize = "small" | "medium" | "large"
|
|
198
198
|
export type PhotoCompression = "none" | "medium" | "heavy"
|
|
199
|
+
export const DeviceModels = {
|
|
200
|
+
Simulated: "Simulated Glasses",
|
|
201
|
+
G1: "Even Realities G1",
|
|
202
|
+
G2: "Even Realities G2",
|
|
203
|
+
MentraLive: "Mentra Live",
|
|
204
|
+
MentraNex: "Mentra Display",
|
|
205
|
+
Mach1: "Mentra Mach1",
|
|
206
|
+
Z100: "Vuzix Z100",
|
|
207
|
+
Frame: "Brilliant Frame",
|
|
208
|
+
R1: "Even Realities R1",
|
|
209
|
+
} as const
|
|
210
|
+
|
|
211
|
+
export type DeviceModel = (typeof DeviceModels)[keyof typeof DeviceModels]
|
|
212
|
+
export type ObservableStoreCategory = "glasses" | "bluetooth" | "core"
|
|
213
|
+
|
|
214
|
+
export type DashboardMenuItem = {
|
|
215
|
+
title: string
|
|
216
|
+
packageName: string
|
|
217
|
+
values?: Record<string, unknown>
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export type CameraFov = "standard" | "wide"
|
|
221
|
+
|
|
222
|
+
export type CameraFovSetting = {
|
|
223
|
+
fov: number
|
|
224
|
+
roi_position: number
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export type MicPreference = "auto" | "phone" | "glasses" | "bluetooth"
|
|
228
|
+
export type MicMode = "phone" | "glasses" | "btclassic" | "bt"
|
|
229
|
+
/** @deprecated Use {@link MicMode} for active/ranked mic modes or {@link MicPreference} for preferences. */
|
|
230
|
+
export type MicRanking = MicMode
|
|
199
231
|
|
|
200
232
|
export type StreamVideoConfig = {
|
|
201
233
|
width?: number
|
|
@@ -525,35 +557,33 @@ export interface GlassesStatus {
|
|
|
525
557
|
controllerSignalStrength: number
|
|
526
558
|
}
|
|
527
559
|
|
|
528
|
-
interface
|
|
560
|
+
export interface CoreDashboardMenuItem {
|
|
529
561
|
name: string
|
|
530
562
|
packageName: string
|
|
531
563
|
running: boolean
|
|
532
564
|
}
|
|
533
565
|
|
|
534
566
|
export interface CoreSettings {
|
|
535
|
-
menu_apps:
|
|
567
|
+
menu_apps: CoreDashboardMenuItem[]
|
|
536
568
|
}
|
|
537
569
|
|
|
538
|
-
export type MicRanking = "auto" | "phone" | "glasses" | "bluetooth"
|
|
539
|
-
|
|
540
570
|
export interface Device {
|
|
541
571
|
id: string
|
|
542
|
-
model:
|
|
572
|
+
model: DeviceModel
|
|
543
573
|
name: string
|
|
544
574
|
address?: string
|
|
545
575
|
rssi?: number
|
|
546
576
|
}
|
|
547
577
|
|
|
548
|
-
export interface DeviceScanRequest {
|
|
549
|
-
model: string
|
|
550
|
-
}
|
|
551
|
-
|
|
552
578
|
export interface ConnectOptions {
|
|
553
579
|
saveAsDefault?: boolean
|
|
554
580
|
cancelExistingConnectionAttempt?: boolean
|
|
555
581
|
}
|
|
556
582
|
|
|
583
|
+
export interface ConnectFirstOptions extends ConnectOptions {
|
|
584
|
+
timeoutMs?: number
|
|
585
|
+
}
|
|
586
|
+
|
|
557
587
|
export interface WifiSearchResult {
|
|
558
588
|
ssid: string
|
|
559
589
|
requiresPassword: boolean
|
|
@@ -566,12 +596,17 @@ export interface BluetoothStatus {
|
|
|
566
596
|
// state:
|
|
567
597
|
searching: boolean
|
|
568
598
|
searchingController: boolean
|
|
569
|
-
default_wearable?:
|
|
599
|
+
default_wearable?: DeviceModel | ""
|
|
600
|
+
pending_wearable?: DeviceModel | ""
|
|
570
601
|
device_name?: string
|
|
571
602
|
device_address?: string
|
|
603
|
+
default_controller?: DeviceModel | ""
|
|
604
|
+
pending_controller?: DeviceModel | ""
|
|
605
|
+
controller_device_name?: string
|
|
606
|
+
controller_address?: string
|
|
572
607
|
systemMicUnavailable: boolean
|
|
573
|
-
micRanking:
|
|
574
|
-
currentMic:
|
|
608
|
+
micRanking: MicMode[]
|
|
609
|
+
currentMic: MicMode | "" | null
|
|
575
610
|
searchResults: Device[]
|
|
576
611
|
wifiScanResults: WifiSearchResult[]
|
|
577
612
|
lastLog: string[]
|
|
@@ -579,3 +614,44 @@ export interface BluetoothStatus {
|
|
|
579
614
|
// desired settings the SDK sends to compatible connected glasses:
|
|
580
615
|
gallery_mode: boolean
|
|
581
616
|
}
|
|
617
|
+
|
|
618
|
+
export type BluetoothSettingsUpdate = Partial<{
|
|
619
|
+
auth_email: string
|
|
620
|
+
core_token: string
|
|
621
|
+
sensing_enabled: boolean
|
|
622
|
+
power_saving_mode: boolean
|
|
623
|
+
lc3_frame_size: number
|
|
624
|
+
preferred_mic: MicPreference
|
|
625
|
+
screen_disabled: boolean
|
|
626
|
+
contextual_dashboard: boolean
|
|
627
|
+
head_up_angle: number
|
|
628
|
+
brightness: number
|
|
629
|
+
auto_brightness: boolean
|
|
630
|
+
dashboard_height: number
|
|
631
|
+
dashboard_depth: number
|
|
632
|
+
menu_apps: DashboardMenuItem[] | CoreDashboardMenuItem[] | Array<Record<string, unknown>> | null
|
|
633
|
+
gallery_mode: boolean
|
|
634
|
+
button_photo_size: ButtonPhotoSize
|
|
635
|
+
button_video_settings: {width: number; height: number; fps: number}
|
|
636
|
+
button_video_width: number
|
|
637
|
+
button_video_height: number
|
|
638
|
+
button_video_fps: number
|
|
639
|
+
button_camera_led: boolean
|
|
640
|
+
button_max_recording_time: number
|
|
641
|
+
camera_fov: CameraFovSetting
|
|
642
|
+
should_send_pcm: boolean
|
|
643
|
+
should_send_lc3: boolean
|
|
644
|
+
should_send_transcript: boolean
|
|
645
|
+
bypass_vad: boolean
|
|
646
|
+
offline_mode: boolean
|
|
647
|
+
offline_captions_running: boolean
|
|
648
|
+
local_stt_fallback_active: boolean
|
|
649
|
+
pending_wearable: DeviceModel | ""
|
|
650
|
+
default_wearable: DeviceModel | ""
|
|
651
|
+
device_name: string
|
|
652
|
+
device_address: string
|
|
653
|
+
default_controller: DeviceModel | ""
|
|
654
|
+
pending_controller: DeviceModel | ""
|
|
655
|
+
controller_device_name: string
|
|
656
|
+
controller_address: string
|
|
657
|
+
}>
|