@mentra/bluetooth-sdk 0.1.9 → 0.1.10
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 +116 -18
- package/android/build.gradle +289 -16
- package/android/gradle.properties.example +9 -0
- package/android/lc3Lib/build.gradle +95 -6
- package/android/settings.gradle +3 -0
- package/android/silero/LICENSE.md +17 -0
- package/android/silero/build.gradle +42 -0
- package/android/silero/proguard-rules.pro +24 -0
- package/android/silero/src/androidTest/assets/hello.wav +0 -0
- package/android/silero/src/androidTest/java/com/konovalov/vad/silero/VadSileroTest.kt +79 -0
- package/android/silero/src/main/assets/LICENSE +21 -0
- package/android/silero/src/main/assets/silero_vad.onnx +0 -0
- package/android/silero/src/main/java/com/konovalov/vad/silero/Vad.kt +160 -0
- package/android/silero/src/main/java/com/konovalov/vad/silero/VadSilero.kt +449 -0
- package/android/silero/src/main/java/com/konovalov/vad/silero/config/FrameSize.kt +15 -0
- package/android/silero/src/main/java/com/konovalov/vad/silero/config/Mode.kt +14 -0
- package/android/silero/src/main/java/com/konovalov/vad/silero/config/SampleRate.kt +12 -0
- package/android/silero/src/main/java/com/konovalov/vad/silero/utils/AudioUtils.kt +47 -0
- package/android/silero/src/main/java/com/konovalov/vad/silero/utils/TensorMap.kt +41 -0
- package/android/silero/src/test/java/com/konovalov/vad/silero/utils/AudioUtilsTest.kt +44 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkDefaults.kt +6 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +165 -27
- package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +89 -21
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +189 -16
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +22 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +787 -85
- package/android/src/main/java/com/mentra/bluetoothsdk/audio/AudioModels.kt +6 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/camera/CameraModels.kt +123 -10
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/ControllerManager.kt +12 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/R1.kt +8 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/debug/BleTraceLogger.kt +33 -17
- package/android/src/main/java/com/mentra/bluetoothsdk/events/BluetoothEvents.kt +101 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/internal/MapParsing.kt +8 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/photoreceiver/LocalPhotoReceiverRegistry.java +108 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/photoreceiver/LocalPhotoUploadServer.kt +399 -74
- package/android/src/main/java/com/mentra/bluetoothsdk/photoreceiver/MentraPhotoReceiverModule.kt +100 -17
- package/android/src/main/java/com/mentra/bluetoothsdk/requests/DisplayRequests.kt +17 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.java +2 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +569 -220
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Mach1.java +2 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.java +271 -66
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +176 -104
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraosBle.java +12753 -27036
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +54 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +16 -4
- package/android/src/main/java/com/mentra/bluetoothsdk/status/DeviceStatus.kt +60 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/streaming/StreamModels.kt +12 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/stt/STTTools.kt +87 -36
- package/android/src/main/java/com/mentra/bluetoothsdk/stt/SherpaOnnxTranscriber.kt +13 -4
- package/android/src/main/java/com/mentra/bluetoothsdk/stt/VadGateSpeechPolicy.kt +229 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/tts/TTSTools.kt +180 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/AvifExifStripper.java +573 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/BlePhotoUploadService.java +488 -50
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/HeifExifTagReader.java +199 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/MessageChunkReassembler.java +18 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/MessageChunker.java +64 -18
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/NexSGCUtils.kt +48 -39
- package/android/src/test/java/com/mentra/bluetoothsdk/camera/PhotoRequestTest.kt +23 -0
- package/android/src/test/java/com/mentra/bluetoothsdk/photoreceiver/LocalPhotoReceiverRegistryTest.java +75 -0
- package/android/src/test/java/com/mentra/bluetoothsdk/utils/AvifExifStripperTest.java +30 -0
- package/android/src/test/java/com/mentra/bluetoothsdk/utils/BlePhotoUploadServiceTest.java +98 -0
- package/android/src/test/resources/avif_with_exif.avif +0 -0
- package/build/BluetoothSdk.types.d.ts +241 -43
- package/build/BluetoothSdk.types.d.ts.map +1 -1
- package/build/BluetoothSdk.types.js +11 -10
- package/build/BluetoothSdk.types.js.map +1 -1
- package/build/_private/BluetoothSdkModule.d.ts +36 -23
- package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
- package/build/_private/BluetoothSdkModule.js +30 -52
- package/build/_private/BluetoothSdkModule.js.map +1 -1
- package/build/_private/photoRequestPayload.d.ts +4 -0
- package/build/_private/photoRequestPayload.d.ts.map +1 -0
- package/build/_private/photoRequestPayload.js +25 -0
- package/build/_private/photoRequestPayload.js.map +1 -0
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +23 -0
- package/build/index.js.map +1 -1
- package/build/react/useMentraBluetooth.d.ts +2 -2
- package/build/react/useMentraBluetooth.d.ts.map +1 -1
- package/build/react/useMentraBluetooth.js +3 -3
- package/build/react/useMentraBluetooth.js.map +1 -1
- package/ios/BluetoothSdkModule.swift +174 -70
- package/ios/LocalPhotoUploadServer.swift +370 -105
- package/ios/MentraBluetoothSDK.podspec +3 -1
- package/ios/MentraPhotoReceiverModule.swift +62 -10
- package/ios/Packages/CoreObjC/include/PcmConverter.h +22 -0
- package/ios/Packages/SherpaOnnx/SherpaOnnx.swift +668 -26
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Info.plist +13 -9
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/Headers/sherpa-onnx/c-api/c-api.h +4551 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/Headers/sherpa-onnx/c-api/cxx-api.h +1745 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/libsherpa-onnx.a +0 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/Headers/sherpa-onnx/c-api/c-api.h +4551 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/Headers/sherpa-onnx/c-api/cxx-api.h +1745 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/libsherpa-onnx.a +0 -0
- package/ios/Source/BluetoothSdkDefaults.swift +6 -0
- package/ios/Source/Bridge.swift +58 -19
- package/ios/Source/DeviceManager.swift +149 -17
- package/ios/Source/DeviceStore.swift +16 -6
- package/ios/Source/MentraBluetoothSDK.swift +803 -47
- package/ios/Source/ObservableStore.swift +6 -0
- package/ios/Source/{Audio → audio}/AudioModels.swift +9 -7
- package/ios/Source/{Camera → camera}/CameraModels.swift +225 -16
- package/ios/Source/controllers/ControllerManager.swift +4 -3
- package/ios/Source/controllers/R1.swift +3 -3
- package/ios/Source/{Events → events}/BluetoothEvents.swift +183 -1
- package/ios/Source/{Internal → internal}/ValueParsing.swift +10 -1
- package/ios/Source/{Requests → requests}/DisplayRequests.swift +28 -4
- package/ios/Source/services/PhoneMic.swift +1 -0
- package/ios/Source/sgcs/G1.swift +2 -2
- package/ios/Source/sgcs/G2.swift +645 -403
- package/ios/Source/sgcs/Mach1.swift +2 -2
- package/ios/Source/sgcs/MentraLive.swift +812 -319
- package/ios/Source/sgcs/MentraNex.swift +412 -182
- package/ios/Source/sgcs/SGCManager.swift +57 -3
- package/ios/Source/sgcs/Simulated.swift +7 -3
- package/ios/Source/sgcs/mentraos_ble.pb.swift +3073 -3134
- package/ios/Source/status/DeviceStatus.swift +974 -0
- package/ios/Source/{Status → status}/WifiHotspotStatus.swift +4 -4
- package/ios/Source/{Streaming → streaming}/StreamModels.swift +24 -9
- package/ios/Source/stt/STTTools.swift +27 -12
- package/ios/Source/stt/SherpaOnnxTranscriber.swift +31 -8
- package/ios/Source/tts/TTSTools.swift +164 -0
- package/ios/Source/utils/JSCExperiment.swift +7 -7
- package/ios/Source/utils/MessageChunkReassembler.swift +20 -1
- package/ios/Source/utils/MessageChunker.swift +78 -21
- package/ios/Source/utils/TarBz2Extractor.swift +53 -2
- package/package.json +1 -1
- package/plugin/build/withAndroid.js +68 -4
- package/src/BluetoothSdk.types.ts +331 -59
- package/src/_private/BluetoothSdkModule.ts +113 -102
- package/src/_private/photoRequestPayload.ts +28 -0
- package/src/index.ts +58 -15
- package/src/react/useMentraBluetooth.ts +6 -4
- package/android/.project +0 -28
- package/android/lc3Lib/.project +0 -28
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/cargs.h +0 -162
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/sherpa-onnx/c-api/c-api.h +0 -1852
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/sherpa-onnx/c-api/cxx-api.h +0 -674
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/sherpa-onnx.a +0 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/sherpa-onnx.a +0 -0
- package/ios/Source/Status/DeviceStatus.swift +0 -471
- /package/ios/Source/{Connection → connection}/ScanSession.swift +0 -0
- /package/ios/Source/{Errors → errors}/BluetoothError.swift +0 -0
- /package/ios/Source/{Internal → internal}/BluetoothAvailability.swift +0 -0
- /package/ios/Source/{Status → status}/RuntimeState.swift +0 -0
- /package/ios/Source/{Types → types}/DeviceModels.swift +0 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
package com.mentra.bluetoothsdk.utils;
|
|
2
|
+
|
|
3
|
+
import static org.assertj.core.api.Assertions.assertThat;
|
|
4
|
+
|
|
5
|
+
import android.graphics.Bitmap;
|
|
6
|
+
import android.graphics.Color;
|
|
7
|
+
|
|
8
|
+
import androidx.exifinterface.media.ExifInterface;
|
|
9
|
+
|
|
10
|
+
import org.json.JSONObject;
|
|
11
|
+
import org.junit.Rule;
|
|
12
|
+
import org.junit.Test;
|
|
13
|
+
import org.junit.rules.TemporaryFolder;
|
|
14
|
+
import org.junit.runner.RunWith;
|
|
15
|
+
import org.robolectric.RobolectricTestRunner;
|
|
16
|
+
import org.robolectric.annotation.Config;
|
|
17
|
+
|
|
18
|
+
import java.io.File;
|
|
19
|
+
import java.io.FileOutputStream;
|
|
20
|
+
|
|
21
|
+
@RunWith(RobolectricTestRunner.class)
|
|
22
|
+
@Config(sdk = 31)
|
|
23
|
+
public class BlePhotoUploadServiceTest {
|
|
24
|
+
|
|
25
|
+
@Rule public TemporaryFolder tempFolder = new TemporaryFolder();
|
|
26
|
+
|
|
27
|
+
@Test
|
|
28
|
+
public void describeContainer_detectsJpegAndAvifBrands() {
|
|
29
|
+
byte[] jpegHeader = {(byte) 0xFF, (byte) 0xD8, 0x00};
|
|
30
|
+
assertThat(BlePhotoUploadService.describeContainer(jpegHeader)).isEqualTo("jpeg");
|
|
31
|
+
|
|
32
|
+
byte[] avif =
|
|
33
|
+
new byte[] {
|
|
34
|
+
0, 0, 0, 0,
|
|
35
|
+
'f', 't', 'y', 'p',
|
|
36
|
+
'a', 'v', 'i', 'f',
|
|
37
|
+
};
|
|
38
|
+
assertThat(BlePhotoUploadService.describeContainer(avif)).isEqualTo("iso_bmff/ftyp=avif");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@Test
|
|
42
|
+
public void containsExifMarkerInBytes_findsExifHeader() {
|
|
43
|
+
byte[] withExif = new byte[] {0, 1, 'E', 'x', 'i', 'f', 0, 0, 2};
|
|
44
|
+
assertThat(BlePhotoUploadService.containsExifMarkerInBytes(withExif)).isTrue();
|
|
45
|
+
assertThat(BlePhotoUploadService.containsExifMarkerInBytes(new byte[] {0, 1, 2, 3})).isFalse();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@Test
|
|
49
|
+
public void readImuJsonFromBleImage_parsesTiffUserCommentInAvif() throws Exception {
|
|
50
|
+
byte[] avif =
|
|
51
|
+
java.nio.file.Files.readAllBytes(
|
|
52
|
+
new File("src/test/resources/avif_with_exif.avif").toPath());
|
|
53
|
+
File temp = tempFolder.newFile("ble.avif");
|
|
54
|
+
java.nio.file.Files.write(temp.toPath(), avif);
|
|
55
|
+
String json = BlePhotoUploadService.readImuJsonFromBleImage(avif, temp.getAbsolutePath());
|
|
56
|
+
assertThat(json).isNotNull();
|
|
57
|
+
assertThat(new JSONObject(json).getInt("sampleCount")).isEqualTo(5);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@Test
|
|
61
|
+
public void convertToJpegPreservesUserComment() throws Exception {
|
|
62
|
+
File input = tempFolder.newFile("input.jpg");
|
|
63
|
+
writeMinimalJpeg(input);
|
|
64
|
+
JSONObject payload = new JSONObject();
|
|
65
|
+
payload.put("version", 1);
|
|
66
|
+
payload.put("sampleCount", 2);
|
|
67
|
+
payload.put("samplingRateHz", 100);
|
|
68
|
+
payload.put("startTimeNs", 1000L);
|
|
69
|
+
payload.put("durationMs", 20);
|
|
70
|
+
payload.put("samples", new org.json.JSONArray());
|
|
71
|
+
ExifInterface inputExif = new ExifInterface(input.getAbsolutePath());
|
|
72
|
+
inputExif.setAttribute(ExifInterface.TAG_USER_COMMENT, payload.toString());
|
|
73
|
+
inputExif.saveAttributes();
|
|
74
|
+
|
|
75
|
+
byte[] inputBytes = java.nio.file.Files.readAllBytes(input.toPath());
|
|
76
|
+
byte[] outputBytes = BlePhotoUploadService.convertToJpegPreservingExif(inputBytes);
|
|
77
|
+
|
|
78
|
+
File output = tempFolder.newFile("out.jpg");
|
|
79
|
+
try (FileOutputStream fos = new FileOutputStream(output)) {
|
|
80
|
+
fos.write(outputBytes);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
ExifInterface exif = new ExifInterface(output.getAbsolutePath());
|
|
84
|
+
String comment = exif.getAttribute(ExifInterface.TAG_USER_COMMENT);
|
|
85
|
+
assertThat(comment).isNotNull();
|
|
86
|
+
assertThat(new JSONObject(comment).getInt("sampleCount")).isEqualTo(2);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private static void writeMinimalJpeg(File dest) throws Exception {
|
|
90
|
+
Bitmap bitmap = Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888);
|
|
91
|
+
bitmap.eraseColor(Color.BLACK);
|
|
92
|
+
try (FileOutputStream fos = new FileOutputStream(dest)) {
|
|
93
|
+
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
|
|
94
|
+
} finally {
|
|
95
|
+
bitmap.recycle();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
Binary file
|
|
@@ -3,7 +3,6 @@ export type GlassesNotReadyEvent = {
|
|
|
3
3
|
message: string;
|
|
4
4
|
};
|
|
5
5
|
export type ButtonPressEvent = {
|
|
6
|
-
type: "button_press";
|
|
7
6
|
buttonId: string;
|
|
8
7
|
pressType: "long" | "short";
|
|
9
8
|
timestamp: number;
|
|
@@ -21,6 +20,7 @@ export type VoiceActivityDetectionStatusEvent = {
|
|
|
21
20
|
type: "voice_activity_detection_status";
|
|
22
21
|
voiceActivityDetectionEnabled: boolean;
|
|
23
22
|
};
|
|
23
|
+
export declare const DEFAULT_VOICE_ACTIVITY_DETECTION_ENABLED = false;
|
|
24
24
|
export type SpeakingStatusEvent = {
|
|
25
25
|
type: "speaking_status";
|
|
26
26
|
speaking: boolean;
|
|
@@ -33,19 +33,19 @@ export type BatteryStatusEvent = {
|
|
|
33
33
|
timestamp: number;
|
|
34
34
|
};
|
|
35
35
|
export type GlassesConnectionStatus = {
|
|
36
|
-
state:
|
|
36
|
+
state: "disconnected";
|
|
37
37
|
} | {
|
|
38
|
-
state:
|
|
38
|
+
state: "scanning";
|
|
39
39
|
} | {
|
|
40
|
-
state:
|
|
40
|
+
state: "connecting";
|
|
41
41
|
} | {
|
|
42
|
-
state:
|
|
42
|
+
state: "bonding";
|
|
43
43
|
} | {
|
|
44
|
-
state:
|
|
44
|
+
state: "connected";
|
|
45
45
|
fullyBooted: boolean;
|
|
46
46
|
};
|
|
47
47
|
export type ConnectedGlassesConnectionStatus = Extract<GlassesConnectionStatus, {
|
|
48
|
-
state:
|
|
48
|
+
state: "connected";
|
|
49
49
|
}>;
|
|
50
50
|
export declare function isConnectedGlassesConnectionStatus(status: GlassesConnectionStatus): status is ConnectedGlassesConnectionStatus;
|
|
51
51
|
export declare function isReadyGlassesConnectionStatus(status: GlassesConnectionStatus): boolean;
|
|
@@ -69,29 +69,29 @@ export type LogEvent = {
|
|
|
69
69
|
message: string;
|
|
70
70
|
};
|
|
71
71
|
export type WifiStatus = {
|
|
72
|
-
state:
|
|
72
|
+
state: "disconnected";
|
|
73
73
|
} | {
|
|
74
|
-
state:
|
|
74
|
+
state: "connected";
|
|
75
75
|
ssid: string;
|
|
76
76
|
localIp?: string;
|
|
77
77
|
};
|
|
78
78
|
export type ConnectedWifiStatus = Extract<WifiStatus, {
|
|
79
|
-
state:
|
|
79
|
+
state: "connected";
|
|
80
80
|
}>;
|
|
81
81
|
export declare function isConnectedWifiStatus(status: WifiStatus): status is ConnectedWifiStatus;
|
|
82
82
|
export type WifiStatusChangeEvent = WifiStatus & {
|
|
83
83
|
type: "wifi_status_change";
|
|
84
84
|
};
|
|
85
85
|
export type HotspotStatus = {
|
|
86
|
-
state:
|
|
86
|
+
state: "disabled";
|
|
87
87
|
} | {
|
|
88
|
-
state:
|
|
88
|
+
state: "enabled";
|
|
89
89
|
ssid: string;
|
|
90
90
|
password: string;
|
|
91
91
|
localIp: string;
|
|
92
92
|
};
|
|
93
93
|
export type EnabledHotspotStatus = Extract<HotspotStatus, {
|
|
94
|
-
state:
|
|
94
|
+
state: "enabled";
|
|
95
95
|
}>;
|
|
96
96
|
export declare function isEnabledHotspotStatus(status: HotspotStatus): status is EnabledHotspotStatus;
|
|
97
97
|
export type HotspotStatusChangeEvent = HotspotStatus & {
|
|
@@ -102,11 +102,33 @@ export type HotspotErrorEvent = {
|
|
|
102
102
|
errorMessage: string;
|
|
103
103
|
timestamp: number;
|
|
104
104
|
};
|
|
105
|
+
export type VersionInfoResult = {
|
|
106
|
+
androidVersion: string;
|
|
107
|
+
firmwareVersion: string;
|
|
108
|
+
besFirmwareVersion: string;
|
|
109
|
+
mtkFirmwareVersion: string;
|
|
110
|
+
buildNumber: string;
|
|
111
|
+
systemTimeMs?: number;
|
|
112
|
+
otaVersionUrl: string;
|
|
113
|
+
appVersion: string;
|
|
114
|
+
};
|
|
115
|
+
export type VersionInfoEvent = VersionInfoResult & {
|
|
116
|
+
type: "version_info";
|
|
117
|
+
};
|
|
118
|
+
export type WifiScanResultEvent = {
|
|
119
|
+
type: "wifi_scan_result";
|
|
120
|
+
networks: WifiSearchResult[];
|
|
121
|
+
scanComplete?: boolean;
|
|
122
|
+
};
|
|
105
123
|
export type PhotoResponseEvent = {
|
|
106
124
|
type: "photo_response";
|
|
107
125
|
state: "success";
|
|
108
126
|
requestId: string;
|
|
109
127
|
uploadUrl: string;
|
|
128
|
+
photoUrl?: string;
|
|
129
|
+
statusUrl?: string;
|
|
130
|
+
contentType?: string;
|
|
131
|
+
fileSizeBytes?: number;
|
|
110
132
|
timestamp: number;
|
|
111
133
|
} | {
|
|
112
134
|
type: "photo_response";
|
|
@@ -116,7 +138,10 @@ export type PhotoResponseEvent = {
|
|
|
116
138
|
errorCode?: string;
|
|
117
139
|
errorMessage: string;
|
|
118
140
|
};
|
|
119
|
-
export type
|
|
141
|
+
export type PhotoSuccessResponseEvent = Extract<PhotoResponseEvent, {
|
|
142
|
+
state: "success";
|
|
143
|
+
}>;
|
|
144
|
+
export type PhotoStatusState = "accepted" | "queued" | "configuring" | "capturing" | "captured" | "compressing" | "ble_fallback_compression" | "uploading" | "uploaded" | "ready_for_transfer" | "transferring" | "failed";
|
|
120
145
|
export type PhotoResolvedConfig = {
|
|
121
146
|
format?: "jpeg" | string;
|
|
122
147
|
width?: number;
|
|
@@ -130,15 +155,80 @@ export type PhotoResolvedConfig = {
|
|
|
130
155
|
exposureTimeNs?: number;
|
|
131
156
|
iso?: number;
|
|
132
157
|
};
|
|
158
|
+
export type PhotoFpsRange = {
|
|
159
|
+
min?: number;
|
|
160
|
+
max?: number;
|
|
161
|
+
};
|
|
162
|
+
export type PhotoRequestedCaptureConfig = {
|
|
163
|
+
manual?: boolean;
|
|
164
|
+
exposureTimeNs?: number;
|
|
165
|
+
iso?: number;
|
|
166
|
+
frameDurationNs?: number;
|
|
167
|
+
aeMode?: number;
|
|
168
|
+
aeLock?: boolean;
|
|
169
|
+
aeExposureCompensation?: number;
|
|
170
|
+
aeTargetFpsRange?: PhotoFpsRange;
|
|
171
|
+
noiseReductionMode?: number;
|
|
172
|
+
edgeMode?: number;
|
|
173
|
+
afMode?: number;
|
|
174
|
+
zsl?: boolean;
|
|
175
|
+
};
|
|
176
|
+
export type PhotoMeteredPreview = {
|
|
177
|
+
exposureTimeNs?: number;
|
|
178
|
+
iso?: number;
|
|
179
|
+
totalLightProxy?: number;
|
|
180
|
+
};
|
|
181
|
+
export type PhotoCaptureMetadata = {
|
|
182
|
+
manual?: boolean;
|
|
183
|
+
exposureTimeNs?: number;
|
|
184
|
+
iso?: number;
|
|
185
|
+
frameDurationNs?: number;
|
|
186
|
+
aeMode?: number;
|
|
187
|
+
aeState?: number;
|
|
188
|
+
aeStateName?: string;
|
|
189
|
+
noiseReductionMode?: number;
|
|
190
|
+
edgeMode?: number;
|
|
191
|
+
zsl?: boolean;
|
|
192
|
+
sensorTimestampNs?: number;
|
|
193
|
+
totalLightProxy?: number;
|
|
194
|
+
mfnrLikely?: boolean;
|
|
195
|
+
};
|
|
133
196
|
export type PhotoStatusEvent = {
|
|
134
197
|
type: "photo_status";
|
|
135
198
|
requestId: string;
|
|
136
199
|
status: PhotoStatusState | string;
|
|
137
200
|
timestamp: number;
|
|
138
201
|
resolvedConfig?: PhotoResolvedConfig;
|
|
202
|
+
requestedCaptureConfig?: PhotoRequestedCaptureConfig;
|
|
203
|
+
meteredPreview?: PhotoMeteredPreview;
|
|
204
|
+
captureMetadata?: PhotoCaptureMetadata;
|
|
139
205
|
errorCode?: string;
|
|
140
206
|
errorMessage?: string;
|
|
141
207
|
};
|
|
208
|
+
export type VideoRecordingStatusEvent = {
|
|
209
|
+
type: "video_recording_status";
|
|
210
|
+
requestId?: string;
|
|
211
|
+
success: boolean;
|
|
212
|
+
status: VideoRecordingStatusState;
|
|
213
|
+
details?: string | null;
|
|
214
|
+
timestamp: number;
|
|
215
|
+
data?: {
|
|
216
|
+
recording?: boolean;
|
|
217
|
+
duration_ms?: number;
|
|
218
|
+
duration_formatted?: string;
|
|
219
|
+
[key: string]: unknown;
|
|
220
|
+
};
|
|
221
|
+
};
|
|
222
|
+
export type VideoRecordingStatusState = "recording_started" | "recording_status" | "already_recording" | "recording_stopped" | "not_recording" | "request_id_mismatch" | "service_unavailable" | "json_error" | "battery_low" | "camera_busy" | "storage_unavailable" | "integrity_failed" | "error";
|
|
223
|
+
export type VideoRecordingStartedStatusEvent = Omit<VideoRecordingStatusEvent, "success" | "status"> & {
|
|
224
|
+
success: true;
|
|
225
|
+
status: "recording_started";
|
|
226
|
+
};
|
|
227
|
+
export type VideoRecordingStoppedStatusEvent = Omit<VideoRecordingStatusEvent, "success" | "status"> & {
|
|
228
|
+
success: true;
|
|
229
|
+
status: "recording_stopped";
|
|
230
|
+
};
|
|
231
|
+
export type VideoRecordingSuccessStatusEvent = VideoRecordingStartedStatusEvent | VideoRecordingStoppedStatusEvent;
|
|
142
232
|
export type GalleryStatusEvent = {
|
|
143
233
|
type: "gallery_status";
|
|
144
234
|
photos: number;
|
|
@@ -147,6 +237,7 @@ export type GalleryStatusEvent = {
|
|
|
147
237
|
totalSize?: number;
|
|
148
238
|
hasContent: boolean;
|
|
149
239
|
cameraBusy: boolean;
|
|
240
|
+
cameraBusyReason?: "video" | "stream" | (string & {});
|
|
150
241
|
};
|
|
151
242
|
export type CompatibleGlassesSearchStopEvent = {
|
|
152
243
|
type: "compatible_glasses_search_stop";
|
|
@@ -185,11 +276,49 @@ export type RgbLedControlResponseEvent = {
|
|
|
185
276
|
requestId: string;
|
|
186
277
|
errorCode: string;
|
|
187
278
|
};
|
|
279
|
+
export type RgbLedControlSuccessResponseEvent = Extract<RgbLedControlResponseEvent, {
|
|
280
|
+
state: "success";
|
|
281
|
+
}>;
|
|
282
|
+
export type SettingsAckStatus = "applied" | "ready" | "error" | "failed" | "failure" | "rejected";
|
|
283
|
+
export type SettingsAckSetting = "gallery_mode" | "button_photo" | "button_video_recording" | "button_camera_led" | "button_max_recording_time" | "camera_fov";
|
|
284
|
+
export type SettingsAckEvent = {
|
|
285
|
+
type: "settings_ack";
|
|
286
|
+
requestId: string;
|
|
287
|
+
setting: SettingsAckSetting;
|
|
288
|
+
status: SettingsAckStatus;
|
|
289
|
+
timestamp: number;
|
|
290
|
+
fov?: number;
|
|
291
|
+
roiPosition?: CameraRoiPositionValue;
|
|
292
|
+
hardwareApplied?: boolean;
|
|
293
|
+
active?: boolean;
|
|
294
|
+
size?: ButtonPhotoSize | string;
|
|
295
|
+
width?: number;
|
|
296
|
+
height?: number;
|
|
297
|
+
fps?: number;
|
|
298
|
+
enabled?: boolean;
|
|
299
|
+
minutes?: number;
|
|
300
|
+
errorCode?: string;
|
|
301
|
+
errorMessage?: string;
|
|
302
|
+
};
|
|
303
|
+
export type SettingsAckSuccessStatus = Exclude<SettingsAckStatus, "error" | "failed" | "failure" | "rejected">;
|
|
304
|
+
export type SettingsAckSuccessEvent = Omit<SettingsAckEvent, "status"> & {
|
|
305
|
+
status: SettingsAckSuccessStatus;
|
|
306
|
+
};
|
|
188
307
|
export type RgbLedAction = "on" | "off";
|
|
189
308
|
export type RgbLedColor = "red" | "green" | "blue" | "orange" | "white";
|
|
190
309
|
export type PhotoSize = "small" | "medium" | "large" | "full";
|
|
191
310
|
export type ButtonPhotoSize = "small" | "medium" | "large";
|
|
192
311
|
export type PhotoCompression = "none" | "medium" | "heavy";
|
|
312
|
+
/**
|
|
313
|
+
* Optional per-recording video settings for {@link startVideoRecording}. When
|
|
314
|
+
* omitted, the glasses fall back to their saved button-video settings. Any
|
|
315
|
+
* field left undefined is omitted from the BLE command (glasses default applies).
|
|
316
|
+
*/
|
|
317
|
+
export interface VideoRecordingSettings {
|
|
318
|
+
width?: number;
|
|
319
|
+
height?: number;
|
|
320
|
+
fps?: number;
|
|
321
|
+
}
|
|
193
322
|
export declare const DeviceModels: {
|
|
194
323
|
readonly Simulated: "Simulated Glasses";
|
|
195
324
|
readonly G1: "Even Realities G1";
|
|
@@ -208,21 +337,31 @@ export type DashboardMenuItem = {
|
|
|
208
337
|
packageName: string;
|
|
209
338
|
values?: Record<string, unknown>;
|
|
210
339
|
};
|
|
211
|
-
export declare const CAMERA_FOV_MIN =
|
|
340
|
+
export declare const CAMERA_FOV_MIN = 62;
|
|
212
341
|
export declare const CAMERA_FOV_MAX = 118;
|
|
213
342
|
export declare const CAMERA_FOV_DEFAULT = 102;
|
|
214
|
-
export type CameraRoiPosition =
|
|
215
|
-
export type
|
|
343
|
+
export type CameraRoiPosition = "center" | "bottom" | "top";
|
|
344
|
+
export type CameraRoiPositionValue = 0 | 1 | 2;
|
|
345
|
+
export type CameraFovPreset = "narrow" | "standard" | "wide";
|
|
346
|
+
export type CameraFovRequest = {
|
|
216
347
|
fov: number;
|
|
217
348
|
roiPosition?: CameraRoiPosition;
|
|
349
|
+
} | {
|
|
350
|
+
preset: CameraFovPreset;
|
|
218
351
|
};
|
|
219
|
-
export type
|
|
352
|
+
export type CameraFovResult = {
|
|
353
|
+
requestId: string;
|
|
220
354
|
fov: number;
|
|
221
355
|
roiPosition: CameraRoiPosition;
|
|
356
|
+
timestamp: number;
|
|
357
|
+
};
|
|
358
|
+
export type CameraFovSetting = {
|
|
359
|
+
fov: number;
|
|
360
|
+
roiPosition: CameraRoiPositionValue;
|
|
222
361
|
};
|
|
223
362
|
type NativeCameraFovSetting = {
|
|
224
363
|
fov: number;
|
|
225
|
-
roi_position:
|
|
364
|
+
roi_position: CameraRoiPositionValue;
|
|
226
365
|
};
|
|
227
366
|
export type MicPreference = "auto" | "phone" | "glasses" | "bluetooth";
|
|
228
367
|
export type MicMode = "phone" | "glasses" | "bluetoothClassic" | "bluetooth";
|
|
@@ -233,6 +372,7 @@ export type PhotoRequestParams = {
|
|
|
233
372
|
webhookUrl: string | null;
|
|
234
373
|
authToken: string | null;
|
|
235
374
|
compress: PhotoCompression;
|
|
375
|
+
save?: boolean;
|
|
236
376
|
sound: boolean;
|
|
237
377
|
exposureTimeNs?: number | null;
|
|
238
378
|
/** Sensor ISO for this capture only. Only used when exposureTimeNs enables manual exposure. */
|
|
@@ -317,18 +457,27 @@ export type MicLc3Event = {
|
|
|
317
457
|
export type StreamStatusLifecycleState = "initializing" | "streaming" | "stopping" | "stopped";
|
|
318
458
|
export type StreamStatusReconnectState = "reconnecting" | "reconnected" | "reconnect_failed";
|
|
319
459
|
export type StreamStatusState = StreamStatusLifecycleState | StreamStatusReconnectState | "error";
|
|
460
|
+
/** Effective stream settings reported by the glasses after defaults and clamps. */
|
|
320
461
|
export type StreamResolvedConfig = {
|
|
321
462
|
transport?: "rtmp" | "srt" | "whip";
|
|
322
463
|
video?: {
|
|
464
|
+
/** Encoded output width sent to the stream endpoint. */
|
|
323
465
|
width: number;
|
|
466
|
+
/** Encoded output height sent to the stream endpoint. */
|
|
324
467
|
height: number;
|
|
468
|
+
/** Native camera buffer width selected before crop/downscale. */
|
|
325
469
|
captureWidth?: number;
|
|
470
|
+
/** Native camera buffer height selected before crop/downscale. */
|
|
326
471
|
captureHeight?: number;
|
|
472
|
+
/** Encoded video bitrate in bits per second. */
|
|
327
473
|
bitrate: number;
|
|
474
|
+
/** Resolved capture/encode frame rate. */
|
|
328
475
|
fps: number;
|
|
329
476
|
};
|
|
330
477
|
audio?: {
|
|
478
|
+
/** Encoded audio bitrate in bits per second. */
|
|
331
479
|
bitrate?: number;
|
|
480
|
+
/** Audio sample rate in Hz. */
|
|
332
481
|
sampleRate?: number;
|
|
333
482
|
echoCancellation?: boolean;
|
|
334
483
|
noiseSuppression?: boolean;
|
|
@@ -407,13 +556,14 @@ export type OtaStatusEvent = {
|
|
|
407
556
|
session_id: string;
|
|
408
557
|
total_steps: number;
|
|
409
558
|
current_step: number;
|
|
410
|
-
step_type:
|
|
411
|
-
phase:
|
|
559
|
+
step_type: "apk" | "mtk" | "bes";
|
|
560
|
+
phase: "download" | "install";
|
|
412
561
|
step_percent: number;
|
|
413
562
|
overall_percent: number;
|
|
414
|
-
status:
|
|
563
|
+
status: "in_progress" | "step_complete" | "complete" | "failed" | "idle";
|
|
415
564
|
error_message?: string;
|
|
416
565
|
};
|
|
566
|
+
export type OtaQueryResult = OtaUpdateAvailableEvent | OtaStatusEvent;
|
|
417
567
|
/** Nex BLE protobuf trace (NexEventUtils); payload matches native Map keys. */
|
|
418
568
|
export type BleCommandTraceEvent = {
|
|
419
569
|
command: string;
|
|
@@ -442,10 +592,12 @@ export type BluetoothSdkModuleEvents = {
|
|
|
442
592
|
battery_status: (event: BatteryStatusEvent) => void;
|
|
443
593
|
local_transcription: (event: LocalTranscriptionEvent) => void;
|
|
444
594
|
wifi_status_change: (event: WifiStatusChangeEvent) => void;
|
|
595
|
+
wifi_scan_result: (event: WifiScanResultEvent) => void;
|
|
445
596
|
hotspot_status_change: (event: HotspotStatusChangeEvent) => void;
|
|
446
597
|
hotspot_error: (event: HotspotErrorEvent) => void;
|
|
447
598
|
photo_response: (event: PhotoResponseEvent) => void;
|
|
448
599
|
photo_status: (event: PhotoStatusEvent) => void;
|
|
600
|
+
video_recording_status: (event: VideoRecordingStatusEvent) => void;
|
|
449
601
|
gallery_status: (event: GalleryStatusEvent) => void;
|
|
450
602
|
compatible_glasses_search_stop: (event: CompatibleGlassesSearchStopEvent) => void;
|
|
451
603
|
heartbeat_sent: (event: HeartbeatSentEvent) => void;
|
|
@@ -453,6 +605,7 @@ export type BluetoothSdkModuleEvents = {
|
|
|
453
605
|
swipe_volume_status: (event: SwipeVolumeStatusEvent) => void;
|
|
454
606
|
switch_status: (event: SwitchStatusEvent) => void;
|
|
455
607
|
rgb_led_control_response: (event: RgbLedControlResponseEvent) => void;
|
|
608
|
+
settings_ack: (event: SettingsAckEvent) => void;
|
|
456
609
|
pair_failure: (event: PairFailureEvent) => void;
|
|
457
610
|
audio_pairing_needed: (event: AudioPairingNeededEvent) => void;
|
|
458
611
|
audio_connected: (event: AudioConnectedEvent) => void;
|
|
@@ -468,10 +621,17 @@ export type BluetoothSdkModuleEvents = {
|
|
|
468
621
|
ota_update_available: (event: OtaUpdateAvailableEvent) => void;
|
|
469
622
|
ota_start_ack: (event: OtaStartAckEvent) => void;
|
|
470
623
|
ota_status: (event: OtaStatusEvent) => void;
|
|
624
|
+
version_info: (event: VersionInfoEvent) => void;
|
|
471
625
|
send_command_to_ble: (event: BleCommandTraceEvent) => void;
|
|
472
626
|
receive_command_from_ble: (event: BleCommandTraceEvent) => void;
|
|
473
627
|
miniapp_selected: (event: MiniappSelectedEvent) => void;
|
|
628
|
+
extraction_progress: (event: ExtractionProgressEvent) => void;
|
|
474
629
|
};
|
|
630
|
+
export interface ExtractionProgressEvent {
|
|
631
|
+
percentage: number;
|
|
632
|
+
bytesRead: number;
|
|
633
|
+
totalBytes: number;
|
|
634
|
+
}
|
|
475
635
|
export type PublicGlassesStatus = Omit<GlassesStatus, "otaUpdateAvailable" | "otaProgress" | "otaInProgress" | "otaVersionUrl">;
|
|
476
636
|
export type PublicBluetoothStatus = Pick<BluetoothStatus, "searching" | "searchingController" | "systemMicUnavailable" | "micRanking" | "currentMic" | "searchResults" | "wifiScanResults" | "lastLog" | "otherBtConnected" | "galleryModeEnabled">;
|
|
477
637
|
export type BluetoothSdkEventMap = {
|
|
@@ -489,15 +649,18 @@ export type BluetoothSdkEventMap = {
|
|
|
489
649
|
battery_status: BatteryStatusEvent;
|
|
490
650
|
local_transcription: LocalTranscriptionEvent;
|
|
491
651
|
wifi_status_change: WifiStatusChangeEvent;
|
|
652
|
+
wifi_scan_result: WifiScanResultEvent;
|
|
492
653
|
hotspot_status_change: HotspotStatusChangeEvent;
|
|
493
654
|
hotspot_error: HotspotErrorEvent;
|
|
494
655
|
photo_response: PhotoResponseEvent;
|
|
495
656
|
photo_status: PhotoStatusEvent;
|
|
657
|
+
video_recording_status: VideoRecordingStatusEvent;
|
|
496
658
|
gallery_status: GalleryStatusEvent;
|
|
497
659
|
compatible_glasses_search_stop: CompatibleGlassesSearchStopEvent;
|
|
498
660
|
swipe_volume_status: SwipeVolumeStatusEvent;
|
|
499
661
|
switch_status: SwitchStatusEvent;
|
|
500
662
|
rgb_led_control_response: RgbLedControlResponseEvent;
|
|
663
|
+
settings_ack: SettingsAckEvent;
|
|
501
664
|
pair_failure: PairFailureEvent;
|
|
502
665
|
audio_pairing_needed: AudioPairingNeededEvent;
|
|
503
666
|
audio_connected: AudioConnectedEvent;
|
|
@@ -505,6 +668,11 @@ export type BluetoothSdkEventMap = {
|
|
|
505
668
|
mic_pcm: MicPcmEvent;
|
|
506
669
|
mic_lc3: MicLc3Event;
|
|
507
670
|
stream_status: StreamStatusEvent;
|
|
671
|
+
ota_update_available: OtaUpdateAvailableEvent;
|
|
672
|
+
ota_start_ack: OtaStartAckEvent;
|
|
673
|
+
ota_status: OtaStatusEvent;
|
|
674
|
+
version_info: VersionInfoEvent;
|
|
675
|
+
extraction_progress: ExtractionProgressEvent;
|
|
508
676
|
};
|
|
509
677
|
export type BluetoothSdkEventName = keyof BluetoothSdkEventMap;
|
|
510
678
|
export type BluetoothSdkEventListener<EventName extends BluetoothSdkEventName> = (event: BluetoothSdkEventMap[EventName]) => void;
|
|
@@ -532,30 +700,48 @@ export interface BluetoothSdkPublicModule {
|
|
|
532
700
|
setDashboardPosition(height: number, depth: number): Promise<void>;
|
|
533
701
|
setHeadUpAngle(angleDegrees: number): Promise<void>;
|
|
534
702
|
setScreenDisabled(disabled: boolean): Promise<void>;
|
|
535
|
-
requestWifiScan(): Promise<
|
|
536
|
-
sendWifiCredentials(ssid: string, password: string): Promise<
|
|
537
|
-
forgetWifiNetwork(ssid: string): Promise<
|
|
538
|
-
setHotspotState(enabled: boolean): Promise<
|
|
539
|
-
setGalleryModeEnabled(enabled: boolean): Promise<
|
|
703
|
+
requestWifiScan(): Promise<WifiSearchResult[]>;
|
|
704
|
+
sendWifiCredentials(ssid: string, password: string): Promise<WifiStatusChangeEvent>;
|
|
705
|
+
forgetWifiNetwork(ssid: string): Promise<WifiStatusChangeEvent>;
|
|
706
|
+
setHotspotState(enabled: boolean): Promise<HotspotStatusChangeEvent>;
|
|
707
|
+
setGalleryModeEnabled(enabled: boolean): Promise<SettingsAckSuccessEvent>;
|
|
540
708
|
setVoiceActivityDetectionEnabled(enabled: boolean): Promise<void>;
|
|
541
|
-
setButtonPhotoSettings(size: ButtonPhotoSize): Promise<
|
|
542
|
-
setButtonVideoRecordingSettings(width: number, height: number, fps: number): Promise<
|
|
543
|
-
setButtonCameraLed(enabled: boolean): Promise<
|
|
544
|
-
setButtonMaxRecordingTime(minutes: number): Promise<
|
|
545
|
-
setCameraFov(
|
|
546
|
-
queryGalleryStatus(): Promise<
|
|
547
|
-
requestPhoto(params: PhotoRequestParams): Promise<
|
|
548
|
-
startVideoRecording(requestId: string, save: boolean, sound: boolean): Promise<
|
|
549
|
-
stopVideoRecording(requestId: string): Promise<
|
|
550
|
-
startStream(params: StreamStartRequest): Promise<
|
|
551
|
-
stopStream(): Promise<
|
|
709
|
+
setButtonPhotoSettings(size: ButtonPhotoSize): Promise<SettingsAckSuccessEvent>;
|
|
710
|
+
setButtonVideoRecordingSettings(width: number, height: number, fps: number): Promise<SettingsAckSuccessEvent>;
|
|
711
|
+
setButtonCameraLed(enabled: boolean): Promise<SettingsAckSuccessEvent>;
|
|
712
|
+
setButtonMaxRecordingTime(minutes: number): Promise<SettingsAckSuccessEvent>;
|
|
713
|
+
setCameraFov(request: CameraFovRequest): Promise<CameraFovResult>;
|
|
714
|
+
queryGalleryStatus(): Promise<GalleryStatusEvent>;
|
|
715
|
+
requestPhoto(params: PhotoRequestParams): Promise<PhotoSuccessResponseEvent>;
|
|
716
|
+
startVideoRecording(requestId: string, save: boolean, sound: boolean, settings?: VideoRecordingSettings): Promise<VideoRecordingStartedStatusEvent>;
|
|
717
|
+
stopVideoRecording(requestId: string): Promise<VideoRecordingStoppedStatusEvent>;
|
|
718
|
+
startStream(params: StreamStartRequest): Promise<StreamStatusEvent>;
|
|
719
|
+
stopStream(): Promise<StreamStatusEvent>;
|
|
552
720
|
setMicState(enabled: boolean, useGlassesMic?: boolean, sendTranscript?: boolean, sendLc3Data?: boolean): Promise<void>;
|
|
553
721
|
setPreferredMic(preferredMic: MicPreference): Promise<void>;
|
|
554
722
|
setOwnAppAudioPlaying(playing: boolean): Promise<void>;
|
|
555
723
|
getGlassesMediaVolume(): Promise<GlassesMediaVolumeGetResult>;
|
|
556
724
|
setGlassesMediaVolume(level: number): Promise<GlassesMediaVolumeSetResult>;
|
|
557
|
-
rgbLedControl(requestId: string, packageName: string | null, action: RgbLedAction, color: RgbLedColor | null, onDurationMs: number, offDurationMs: number, count: number): Promise<
|
|
558
|
-
requestVersionInfo(): Promise<
|
|
725
|
+
rgbLedControl(requestId: string, packageName: string | null, action: RgbLedAction, color: RgbLedColor | null, onDurationMs: number, offDurationMs: number, count: number): Promise<RgbLedControlSuccessResponseEvent>;
|
|
726
|
+
requestVersionInfo(): Promise<VersionInfoResult>;
|
|
727
|
+
/** Ask connected Mentra Live glasses to check/report OTA availability and status. */
|
|
728
|
+
checkForOtaUpdate(): Promise<OtaQueryResult>;
|
|
729
|
+
/** Start the OTA flow after your app has presented the available update to the user. */
|
|
730
|
+
startOtaUpdate(): Promise<OtaStartAckEvent>;
|
|
731
|
+
/** Re-run the glasses-side OTA version check, mainly after correcting clock skew/TLS failures. */
|
|
732
|
+
retryOtaVersionCheck(): Promise<OtaQueryResult>;
|
|
733
|
+
setSttModelDetails(path: string, languageCode: string): Promise<void>;
|
|
734
|
+
getSttModelPath(): Promise<string>;
|
|
735
|
+
checkSttModelAvailable(): Promise<boolean>;
|
|
736
|
+
validateSttModel(path: string): Promise<boolean>;
|
|
737
|
+
extractTarBz2(sourcePath: string, destinationPath: string): Promise<boolean>;
|
|
738
|
+
restartTranscriber(): Promise<void>;
|
|
739
|
+
setTtsModelDetails(path: string, languageCode: string): Promise<void>;
|
|
740
|
+
getTtsModelPath(): Promise<string>;
|
|
741
|
+
getTtsModelLanguage(): Promise<string>;
|
|
742
|
+
checkTtsModelAvailable(): Promise<boolean>;
|
|
743
|
+
validateTtsModel(path: string): Promise<boolean>;
|
|
744
|
+
generateTtsAudio(text: string, modelPath: string, outputPath: string, speakerId: number, speed: number): Promise<boolean>;
|
|
559
745
|
}
|
|
560
746
|
export type OtaStage = "download" | "install";
|
|
561
747
|
export type OtaProgressStatus = "STARTED" | "PROGRESS" | "FINISHED" | "FAILED";
|
|
@@ -563,11 +749,11 @@ export interface OtaStatus {
|
|
|
563
749
|
sessionId: string;
|
|
564
750
|
totalSteps: number;
|
|
565
751
|
currentStep: number;
|
|
566
|
-
stepType:
|
|
567
|
-
phase:
|
|
752
|
+
stepType: "apk" | "mtk" | "bes";
|
|
753
|
+
phase: "download" | "install";
|
|
568
754
|
stepPercent: number;
|
|
569
755
|
overallPercent: number;
|
|
570
|
-
status:
|
|
756
|
+
status: "in_progress" | "step_complete" | "complete" | "failed" | "idle";
|
|
571
757
|
error?: string;
|
|
572
758
|
}
|
|
573
759
|
export interface OtaUpdateInfo {
|
|
@@ -604,6 +790,8 @@ export interface GlassesStatus {
|
|
|
604
790
|
leftMacAddress: string;
|
|
605
791
|
rightMacAddress: string;
|
|
606
792
|
buildNumber: string;
|
|
793
|
+
/** Glasses System.currentTimeMillis() from last version_info (clock skew detection). */
|
|
794
|
+
systemTimeMs?: number;
|
|
607
795
|
otaVersionUrl: string;
|
|
608
796
|
appVersion: string;
|
|
609
797
|
bluetoothName: string;
|
|
@@ -632,8 +820,15 @@ export interface CoreDashboardMenuItem {
|
|
|
632
820
|
packageName: string;
|
|
633
821
|
running: boolean;
|
|
634
822
|
}
|
|
823
|
+
export interface CalendarEvent {
|
|
824
|
+
title: string;
|
|
825
|
+
location?: string;
|
|
826
|
+
time: string;
|
|
827
|
+
endDate: number;
|
|
828
|
+
}
|
|
635
829
|
export interface CoreSettings {
|
|
636
830
|
menu_apps: CoreDashboardMenuItem[];
|
|
831
|
+
calendar_events: CalendarEvent[];
|
|
637
832
|
}
|
|
638
833
|
export interface Device {
|
|
639
834
|
/**
|
|
@@ -714,6 +909,9 @@ export type BluetoothSettingsUpdate = Partial<{
|
|
|
714
909
|
dashboard_height: number;
|
|
715
910
|
dashboard_depth: number;
|
|
716
911
|
menu_apps: DashboardMenuItem[] | CoreDashboardMenuItem[] | Array<Record<string, unknown>> | null;
|
|
912
|
+
calendar_events: CalendarEvent[];
|
|
913
|
+
metric_system: boolean;
|
|
914
|
+
twelve_hour_time: boolean;
|
|
717
915
|
gallery_mode: boolean;
|
|
718
916
|
voice_activity_detection_enabled: boolean;
|
|
719
917
|
button_photo_size: ButtonPhotoSize;
|