ilabs-flir 1.0.2 → 1.0.4
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/Flir.podspec +31 -31
- package/README.md +1271 -1271
- package/android/Flir/build.gradle.kts +85 -80
- package/android/Flir/libs/flir-stubs.jar +0 -0
- package/android/Flir/src/main/AndroidManifest.xml +31 -31
- package/android/Flir/src/main/java/com/flir/thermalsdk/ErrorCode.java +13 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/ErrorCodeException.java +14 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/ThermalSdkAndroid.java +16 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/androidsdk/image/BitmapAndroid.java +20 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/image/ImageBuffer.java +11 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/image/JavaImageBuffer.java +35 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/image/Palette.java +15 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/image/PaletteManager.java +16 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/image/Point.java +11 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/image/ThermalImage.java +23 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/image/ThermalValue.java +9 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/Camera.java +26 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/CameraType.java +8 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/CommunicationInterface.java +16 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/ConnectParameters.java +16 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/Identity.java +23 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/IpSettings.java +9 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/RemoteControl.java +16 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/connectivity/ConnectionStatusListener.java +7 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/discovery/DiscoveryEventListener.java +14 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/discovery/DiscoveryFactory.java +33 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/remote/OnReceived.java +5 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/remote/OnRemoteError.java +7 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/streaming/Stream.java +8 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/streaming/ThermalStreamer.java +28 -0
- package/android/Flir/src/main/java/com/flir/thermalsdk/live/streaming/VisualStreamer.java +18 -0
- package/android/Flir/src/main/java/flir/android/FlirCommands.java +136 -0
- package/android/Flir/src/main/java/flir/android/FlirDownloadManager.kt +76 -75
- package/android/Flir/src/main/java/flir/android/FlirDownloadPackage.kt +16 -16
- package/android/Flir/src/main/java/flir/android/FlirFrameCache.kt +6 -6
- package/android/Flir/src/main/java/flir/android/FlirManager.kt +477 -248
- package/android/Flir/src/main/java/flir/android/FlirModule.kt +74 -74
- package/android/Flir/src/main/java/flir/android/FlirPackage.kt +19 -19
- package/android/Flir/src/main/java/flir/android/FlirSDKLoader.kt +165 -117
- package/android/Flir/src/main/java/flir/android/FlirSdkManager.java +1511 -0
- package/android/Flir/src/main/java/flir/android/FlirStatus.kt +12 -12
- package/android/Flir/src/main/java/flir/android/FlirView.kt +48 -48
- package/android/Flir/src/main/java/flir/android/FlirViewManager.kt +13 -13
- package/app.plugin.js +264 -264
- package/expo-module.config.json +5 -5
- package/ios/Flir/Framework/ThermalSDK/FLIRBattery.h +76 -76
- package/ios/Flir/Framework/ThermalSDK/FLIRCalibration.h +108 -108
- package/ios/Flir/Framework/ThermalSDK/FLIRCamera.h +156 -156
- package/ios/Flir/Framework/ThermalSDK/FLIRCameraDeviceInfo.h +53 -53
- package/ios/Flir/Framework/ThermalSDK/FLIRCameraEvent.h +132 -132
- package/ios/Flir/Framework/ThermalSDK/FLIRCameraImport.h +204 -204
- package/ios/Flir/Framework/ThermalSDK/FLIRColorDistributionSettings.h +204 -204
- package/ios/Flir/Framework/ThermalSDK/FLIRColorizer.h +82 -82
- package/ios/Flir/Framework/ThermalSDK/FLIRDiscoveredCamera.h +44 -44
- package/ios/Flir/Framework/ThermalSDK/FLIRDiscovery.h +132 -132
- package/ios/Flir/Framework/ThermalSDK/FLIRDisplaySettings.h +29 -29
- package/ios/Flir/Framework/ThermalSDK/FLIRFocus.h +70 -70
- package/ios/Flir/Framework/ThermalSDK/FLIRFusion.h +192 -192
- package/ios/Flir/Framework/ThermalSDK/FLIRFusionController.h +136 -136
- package/ios/Flir/Framework/ThermalSDK/FLIRFusionTransformation.h +35 -35
- package/ios/Flir/Framework/ThermalSDK/FLIRIdentity.h +264 -264
- package/ios/Flir/Framework/ThermalSDK/FLIRImageBase.h +196 -196
- package/ios/Flir/Framework/ThermalSDK/FLIRImageColorizer.h +26 -26
- package/ios/Flir/Framework/ThermalSDK/FLIRImageStatistics.h +61 -61
- package/ios/Flir/Framework/ThermalSDK/FLIRIsotherms.h +208 -208
- package/ios/Flir/Framework/ThermalSDK/FLIRMeasurementArea.h +38 -38
- package/ios/Flir/Framework/ThermalSDK/FLIRMeasurementCollection.h +147 -147
- package/ios/Flir/Framework/ThermalSDK/FLIRMeasurementDelta.h +62 -62
- package/ios/Flir/Framework/ThermalSDK/FLIRMeasurementDimensions.h +33 -33
- package/ios/Flir/Framework/ThermalSDK/FLIRMeasurementEllipse.h +49 -49
- package/ios/Flir/Framework/ThermalSDK/FLIRMeasurementLine.h +66 -66
- package/ios/Flir/Framework/ThermalSDK/FLIRMeasurementMarker.h +69 -69
- package/ios/Flir/Framework/ThermalSDK/FLIRMeasurementParameters.h +41 -41
- package/ios/Flir/Framework/ThermalSDK/FLIRMeasurementRectangle.h +36 -36
- package/ios/Flir/Framework/ThermalSDK/FLIRMeasurementReference.h +27 -27
- package/ios/Flir/Framework/ThermalSDK/FLIRMeasurementShape.h +46 -46
- package/ios/Flir/Framework/ThermalSDK/FLIRMeasurementSpot.h +33 -33
- package/ios/Flir/Framework/ThermalSDK/FLIRMeasurementsController.h +160 -160
- package/ios/Flir/Framework/ThermalSDK/FLIRMeterLinkSensorPoll.h +247 -247
- package/ios/Flir/Framework/ThermalSDK/FLIROverlayController.h +27 -27
- package/ios/Flir/Framework/ThermalSDK/FLIRPalette.h +60 -60
- package/ios/Flir/Framework/ThermalSDK/FLIRPaletteController.h +36 -36
- package/ios/Flir/Framework/ThermalSDK/FLIRPaletteManager.h +97 -97
- package/ios/Flir/Framework/ThermalSDK/FLIRQuantification.h +55 -55
- package/ios/Flir/Framework/ThermalSDK/FLIRRemoteControl.h +393 -393
- package/ios/Flir/Framework/ThermalSDK/FLIRRenderer.h +35 -35
- package/ios/Flir/Framework/ThermalSDK/FLIRRendererImpl.h +17 -17
- package/ios/Flir/Framework/ThermalSDK/FLIRScale.h +99 -99
- package/ios/Flir/Framework/ThermalSDK/FLIRScaleController.h +44 -44
- package/ios/Flir/Framework/ThermalSDK/FLIRStream.h +109 -109
- package/ios/Flir/Framework/ThermalSDK/FLIRStreamer.h +124 -124
- package/ios/Flir/Framework/ThermalSDK/FLIRSystem.h +40 -40
- package/ios/Flir/Framework/ThermalSDK/FLIRTemperatureRange.h +43 -43
- package/ios/Flir/Framework/ThermalSDK/FLIRThermalDelta.h +77 -77
- package/ios/Flir/Framework/ThermalSDK/FLIRThermalImage.h +331 -331
- package/ios/Flir/Framework/ThermalSDK/FLIRThermalImageFile.h +56 -56
- package/ios/Flir/Framework/ThermalSDK/FLIRThermalParameters.h +31 -31
- package/ios/Flir/Framework/ThermalSDK/FLIRThermalValue.h +92 -92
- package/ios/Flir/Framework/ThermalSDK/FLIRWirelessCameraDetails.h +88 -88
- package/ios/Flir/Framework/ThermalSDK/ThermalSDK.h +73 -73
- package/ios/Flir/SDKLoader/FlirSDKLoader.m +13 -13
- package/ios/Flir/SDKLoader/FlirSDKLoader.swift +175 -175
- package/ios/Flir/src/FlirEventEmitter.h +12 -12
- package/ios/Flir/src/FlirEventEmitter.m +33 -33
- package/ios/Flir/src/FlirModule.h +10 -10
- package/ios/Flir/src/FlirModule.m +381 -381
- package/ios/Flir/src/FlirPreviewView.h +13 -13
- package/ios/Flir/src/FlirPreviewView.m +24 -24
- package/ios/Flir/src/FlirState.h +20 -20
- package/ios/Flir/src/FlirState.m +79 -79
- package/ios/Flir/src/FlirViewManager.h +9 -9
- package/ios/Flir/src/FlirViewManager.m +16 -16
- package/package.json +60 -60
- package/react-native.config.js +14 -14
- package/scripts/copy_ios_libs.sh +32 -32
- package/scripts/create_stubs.py +174 -174
- package/scripts/download-sdk.js +62 -62
- package/scripts/prepare-binaries.sh +171 -171
- package/sdk-manifest.json +37 -30
- package/src/FlirDownload.ts +78 -78
- package/src/index.d.ts +17 -17
- package/src/index.js +7 -7
- package/src/index.ts +7 -7
- package/android/Flir/src/main/java/flir/android/CameraHandler.java +0 -194
- package/android/Flir/src/main/java/flir/android/FlirController.kt +0 -11
- package/android/Flir/src/main/java/flir/android/FrameDataHolder.java +0 -14
|
@@ -1,248 +1,477 @@
|
|
|
1
|
-
package flir.android
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import android.graphics.Bitmap
|
|
5
|
-
import android.
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import com.facebook.react.bridge.
|
|
9
|
-
import com.facebook.react.
|
|
10
|
-
import com.facebook.react.
|
|
11
|
-
import
|
|
12
|
-
import java.io.
|
|
13
|
-
import java.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
private
|
|
19
|
-
private val lastEmitMs = AtomicLong(0)
|
|
20
|
-
private val minEmitIntervalMs = 333L // ~3 fps
|
|
21
|
-
private var discoveryStarted = false
|
|
22
|
-
private var reactContext: ThemedReactContext? = null
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
private var
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
fun
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
*
|
|
72
|
-
*/
|
|
73
|
-
fun
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
} catch (
|
|
247
|
-
|
|
248
|
-
|
|
1
|
+
package flir.android
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.graphics.Bitmap
|
|
5
|
+
import android.util.Log
|
|
6
|
+
import com.facebook.react.bridge.Arguments
|
|
7
|
+
import com.facebook.react.bridge.WritableArray
|
|
8
|
+
import com.facebook.react.bridge.WritableMap
|
|
9
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
10
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
11
|
+
import java.io.File
|
|
12
|
+
import java.io.FileOutputStream
|
|
13
|
+
import java.util.concurrent.atomic.AtomicLong
|
|
14
|
+
|
|
15
|
+
object FlirManager {
|
|
16
|
+
private val TAG = "FlirManager"
|
|
17
|
+
private val FLOW_TAG = "FLIR_FLOW" // Matching FlirSdkManager flow tag
|
|
18
|
+
private var sdkManager: FlirSdkManager? = null
|
|
19
|
+
private val lastEmitMs = AtomicLong(0)
|
|
20
|
+
private val minEmitIntervalMs = 333L // ~3 fps
|
|
21
|
+
private var discoveryStarted = false
|
|
22
|
+
private var reactContext: ThemedReactContext? = null
|
|
23
|
+
private var appContext: Context? = null
|
|
24
|
+
private var frameCount = 0 // For tracking first frame
|
|
25
|
+
|
|
26
|
+
// Emulator and device state tracking
|
|
27
|
+
private var isEmulatorMode = false
|
|
28
|
+
private var isPhysicalDeviceConnected = false
|
|
29
|
+
private var connectedDeviceName: String? = null
|
|
30
|
+
private var connectedDeviceId: String? = null
|
|
31
|
+
private var isStreaming = false
|
|
32
|
+
|
|
33
|
+
// Current emulator type preference
|
|
34
|
+
private var preferredEmulatorType = FlirSdkManager.EmulatorType.FLIR_ONE_EDGE
|
|
35
|
+
|
|
36
|
+
// Discovered devices cache
|
|
37
|
+
private var discoveredDevices: List<FlirSdkManager.DeviceInfo> = emptyList()
|
|
38
|
+
|
|
39
|
+
// GL texture callback support for native filters
|
|
40
|
+
interface TextureUpdateCallback {
|
|
41
|
+
fun onTextureUpdate(bitmap: Bitmap, textureUnit: Int)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface TemperatureCallback {
|
|
45
|
+
fun onTemperatureData(temperature: Double, x: Int, y: Int)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private var textureCallback: TextureUpdateCallback? = null
|
|
49
|
+
private var temperatureCallback: TemperatureCallback? = null
|
|
50
|
+
private var latestBitmap: Bitmap? = null
|
|
51
|
+
|
|
52
|
+
fun setTextureCallback(callback: TextureUpdateCallback?) {
|
|
53
|
+
textureCallback = callback
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
fun setTemperatureCallback(callback: TemperatureCallback?) {
|
|
57
|
+
temperatureCallback = callback
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
fun getLatestBitmap(): Bitmap? = latestBitmap
|
|
61
|
+
|
|
62
|
+
fun getTemperatureAtPoint(x: Int, y: Int): Double? {
|
|
63
|
+
return try {
|
|
64
|
+
sdkManager?.getTemperatureAtPoint(x, y)?.takeIf { !it.isNaN() }
|
|
65
|
+
} catch (t: Throwable) {
|
|
66
|
+
null
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Check if currently running in emulator mode (no physical FLIR device)
|
|
72
|
+
*/
|
|
73
|
+
fun isEmulator(): Boolean = isEmulatorMode
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Check if a physical FLIR device is connected
|
|
77
|
+
*/
|
|
78
|
+
fun isDeviceConnected(): Boolean = isPhysicalDeviceConnected || isEmulatorMode
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Check if currently streaming
|
|
82
|
+
*/
|
|
83
|
+
fun isStreaming(): Boolean = isStreaming
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Get list of discovered devices
|
|
87
|
+
*/
|
|
88
|
+
fun getDiscoveredDevices(): List<FlirSdkManager.DeviceInfo> = discoveredDevices
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Get information about the connected device
|
|
92
|
+
*/
|
|
93
|
+
fun getConnectedDeviceInfo(): String {
|
|
94
|
+
return when {
|
|
95
|
+
connectedDeviceName == null -> "Not connected"
|
|
96
|
+
isEmulatorMode -> "Emulator ($connectedDeviceName)"
|
|
97
|
+
else -> "Physical device ($connectedDeviceName)"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Set preferred emulator type (FLIR_ONE_EDGE or FLIR_ONE)
|
|
103
|
+
*/
|
|
104
|
+
fun setPreferredEmulatorType(type: String) {
|
|
105
|
+
preferredEmulatorType = when (type.uppercase()) {
|
|
106
|
+
"FLIR_ONE" -> FlirSdkManager.EmulatorType.FLIR_ONE
|
|
107
|
+
else -> FlirSdkManager.EmulatorType.FLIR_ONE_EDGE
|
|
108
|
+
}
|
|
109
|
+
Log.d(TAG, "Preferred emulator type set to: $preferredEmulatorType")
|
|
110
|
+
sdkManager?.setEmulatorType(preferredEmulatorType)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
fun init(context: Context) {
|
|
114
|
+
// Avoid re-initialization if already done
|
|
115
|
+
if (sdkManager != null) {
|
|
116
|
+
Log.i(FLOW_TAG, "[FlirManager] init() called but already initialized, skipping")
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
appContext = context.applicationContext
|
|
121
|
+
Log.i(FLOW_TAG, "[FlirManager] init() called - initializing SDK Manager")
|
|
122
|
+
try {
|
|
123
|
+
// Initialize SDK manager with listener matching FlirSdkManager.Listener interface
|
|
124
|
+
sdkManager = FlirSdkManager(object : FlirSdkManager.Listener {
|
|
125
|
+
override fun onFrame(bitmap: Bitmap) {
|
|
126
|
+
latestBitmap = bitmap
|
|
127
|
+
if (frameCount == 0) {
|
|
128
|
+
Log.i(FLOW_TAG, "[FlirManager] FIRST FRAME received: ${bitmap.width}x${bitmap.height}")
|
|
129
|
+
}
|
|
130
|
+
frameCount++
|
|
131
|
+
textureCallback?.onTextureUpdate(bitmap, 0)
|
|
132
|
+
emitFrameToReactNative(bitmap)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
override fun onTemperature(temp: Double, x: Int, y: Int) {
|
|
136
|
+
temperatureCallback?.onTemperatureData(temp, x, y)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
override fun onDeviceFound(deviceId: String, deviceName: String, isEmulator: Boolean) {
|
|
140
|
+
Log.i(FLOW_TAG, "[FlirManager] Device found: $deviceName (id=$deviceId, emulator=$isEmulator)")
|
|
141
|
+
Log.d(TAG, "Device found: $deviceName (id=$deviceId, emulator=$isEmulator)")
|
|
142
|
+
discoveryCallback?.onDeviceFound(deviceName)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
override fun onDeviceListUpdated(devices: MutableList<FlirSdkManager.DeviceInfo>) {
|
|
146
|
+
discoveredDevices = devices.toList()
|
|
147
|
+
Log.i(FLOW_TAG, "[FlirManager] Device list updated: ${devices.size} devices")
|
|
148
|
+
Log.i(TAG, "Device list updated: ${devices.size} devices")
|
|
149
|
+
devices.forEach {
|
|
150
|
+
Log.d(TAG, " - ${it.deviceName} (${it.commInterface}, emu=${it.isEmulator})")
|
|
151
|
+
}
|
|
152
|
+
emitDevicesFound(devices)
|
|
153
|
+
|
|
154
|
+
// Auto-connect to first device if available
|
|
155
|
+
if (devices.isNotEmpty()) {
|
|
156
|
+
val first = devices[0]
|
|
157
|
+
connectedDeviceName = first.deviceName
|
|
158
|
+
connectedDeviceId = first.deviceId
|
|
159
|
+
isEmulatorMode = first.isEmulator
|
|
160
|
+
isPhysicalDeviceConnected = !first.isEmulator
|
|
161
|
+
|
|
162
|
+
Log.i(FLOW_TAG, "[FlirManager] Auto-connecting to first device: ${first.deviceName}")
|
|
163
|
+
// Connect to the device
|
|
164
|
+
sdkManager?.connectToDevice(first.deviceId)
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
override fun onDeviceConnected(deviceId: String, deviceName: String, isEmulator: Boolean) {
|
|
169
|
+
connectedDeviceId = deviceId
|
|
170
|
+
connectedDeviceName = deviceName
|
|
171
|
+
this@FlirManager.isEmulatorMode = isEmulator
|
|
172
|
+
isPhysicalDeviceConnected = !isEmulator
|
|
173
|
+
|
|
174
|
+
Log.i(TAG, "Device connected: $deviceName (id=$deviceId, emulator=$isEmulator)")
|
|
175
|
+
emitDeviceState("connected", !isEmulator)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
override fun onDeviceDisconnected() {
|
|
179
|
+
Log.i(TAG, "Device disconnected")
|
|
180
|
+
isPhysicalDeviceConnected = false
|
|
181
|
+
isEmulatorMode = false
|
|
182
|
+
isStreaming = false
|
|
183
|
+
connectedDeviceId = null
|
|
184
|
+
connectedDeviceName = null
|
|
185
|
+
emitDeviceState("disconnected", false)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
override fun onDiscoveryStarted() {
|
|
189
|
+
Log.i(TAG, "Discovery started")
|
|
190
|
+
emitDeviceState("discovering", false)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
override fun onDiscoveryTimeout() {
|
|
194
|
+
Log.w(TAG, "Discovery timeout - no devices found")
|
|
195
|
+
discoveryCallback?.onDiscoveryTimeout()
|
|
196
|
+
emitDeviceState("discovery_timeout", false)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
override fun onStreamStarted(streamType: String) {
|
|
200
|
+
isStreaming = true
|
|
201
|
+
Log.i(TAG, "Streaming started: $streamType")
|
|
202
|
+
emitDeviceState("streaming", isPhysicalDeviceConnected)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
override fun onError(error: String) {
|
|
206
|
+
Log.e(TAG, "SDK Error: $error")
|
|
207
|
+
emitError(error)
|
|
208
|
+
}
|
|
209
|
+
}, context)
|
|
210
|
+
|
|
211
|
+
// Set emulator type preference
|
|
212
|
+
sdkManager?.setEmulatorType(preferredEmulatorType)
|
|
213
|
+
|
|
214
|
+
Log.i(TAG, "FlirManager initialized with comprehensive SDK manager")
|
|
215
|
+
} catch (t: Throwable) {
|
|
216
|
+
Log.e(TAG, "FlirManager init failed", t)
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Start discovery with the specified parameters
|
|
222
|
+
* @param isEmuMode If true, immediately start emulator without physical device discovery
|
|
223
|
+
*/
|
|
224
|
+
fun startDiscoveryAndConnect(context: ThemedReactContext, isEmuMode: Boolean = false) {
|
|
225
|
+
Log.i(FLOW_TAG, "[FlirManager] startDiscoveryAndConnect called: isEmuMode=$isEmuMode, discoveryStarted=$discoveryStarted, preferredEmulatorType=$preferredEmulatorType")
|
|
226
|
+
|
|
227
|
+
if (discoveryStarted && !isEmuMode) {
|
|
228
|
+
Log.i(FLOW_TAG, "[FlirManager] Discovery already started, skipping")
|
|
229
|
+
return
|
|
230
|
+
}
|
|
231
|
+
discoveryStarted = true
|
|
232
|
+
reactContext = context
|
|
233
|
+
frameCount = 0 // Reset frame counter
|
|
234
|
+
|
|
235
|
+
emitDeviceState("discovering", false)
|
|
236
|
+
|
|
237
|
+
try {
|
|
238
|
+
// Set emulator type preference before discovery
|
|
239
|
+
Log.i(FLOW_TAG, "[FlirManager] Setting emulator type: $preferredEmulatorType")
|
|
240
|
+
sdkManager?.setEmulatorType(preferredEmulatorType)
|
|
241
|
+
|
|
242
|
+
// Start discovery (forceEmulator=isEmuMode)
|
|
243
|
+
Log.i(FLOW_TAG, "[FlirManager] Calling sdkManager.startDiscovery(forceEmulator=$isEmuMode)")
|
|
244
|
+
Log.i(TAG, "Starting discovery (forceEmulator=$isEmuMode)")
|
|
245
|
+
sdkManager?.startDiscovery(isEmuMode)
|
|
246
|
+
} catch (t: Throwable) {
|
|
247
|
+
Log.e(FLOW_TAG, "[FlirManager] startDiscoveryAndConnect failed: ${t.message}")
|
|
248
|
+
Log.e(TAG, "startDiscoveryAndConnect failed", t)
|
|
249
|
+
emitDeviceState("error", false)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Legacy overload for backward compatibility
|
|
255
|
+
*/
|
|
256
|
+
fun startDiscoveryAndConnect(context: ThemedReactContext) {
|
|
257
|
+
startDiscoveryAndConnect(context, isEmuMode = false)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Switch to a specific device by ID
|
|
262
|
+
*/
|
|
263
|
+
fun switchToDevice(deviceId: String) {
|
|
264
|
+
if (deviceId == connectedDeviceId) {
|
|
265
|
+
Log.d(TAG, "Already connected to device: $deviceId")
|
|
266
|
+
return
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
Log.i(TAG, "Switching to device: $deviceId")
|
|
270
|
+
sdkManager?.connectToDevice(deviceId)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Start emulator mode
|
|
275
|
+
*/
|
|
276
|
+
fun startEmulator(type: FlirSdkManager.EmulatorType = preferredEmulatorType) {
|
|
277
|
+
Log.i(TAG, "Starting emulator: $type")
|
|
278
|
+
sdkManager?.setEmulatorType(type)
|
|
279
|
+
sdkManager?.startDiscovery(true) // forceEmulator = true
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
fun stop() {
|
|
283
|
+
Log.i(TAG, "Stopping FlirManager")
|
|
284
|
+
|
|
285
|
+
// Stop the SDK manager
|
|
286
|
+
sdkManager?.stop()
|
|
287
|
+
|
|
288
|
+
// Reset state
|
|
289
|
+
discoveryStarted = false
|
|
290
|
+
isPhysicalDeviceConnected = false
|
|
291
|
+
isEmulatorMode = false
|
|
292
|
+
isStreaming = false
|
|
293
|
+
connectedDeviceName = null
|
|
294
|
+
connectedDeviceId = null
|
|
295
|
+
latestBitmap = null
|
|
296
|
+
discoveredDevices = emptyList()
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
fun getLatestFramePath(): String? {
|
|
300
|
+
val bitmap = latestBitmap ?: return null
|
|
301
|
+
return try {
|
|
302
|
+
val file = File.createTempFile("flir_frame_", ".jpg")
|
|
303
|
+
FileOutputStream(file).use { out ->
|
|
304
|
+
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out)
|
|
305
|
+
}
|
|
306
|
+
file.absolutePath
|
|
307
|
+
} catch (t: Throwable) {
|
|
308
|
+
null
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
fun getTemperatureAt(x: Int, y: Int): Double? {
|
|
313
|
+
return getTemperatureAtPoint(x, y)
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
private fun emitFrameToReactNative(bitmap: Bitmap) {
|
|
317
|
+
val now = System.currentTimeMillis()
|
|
318
|
+
if (now - lastEmitMs.get() < minEmitIntervalMs) return
|
|
319
|
+
lastEmitMs.set(now)
|
|
320
|
+
|
|
321
|
+
val ctx = reactContext ?: return
|
|
322
|
+
try {
|
|
323
|
+
val params = Arguments.createMap()
|
|
324
|
+
params.putInt("width", bitmap.width)
|
|
325
|
+
params.putInt("height", bitmap.height)
|
|
326
|
+
params.putDouble("timestamp", now.toDouble())
|
|
327
|
+
|
|
328
|
+
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
329
|
+
.emit("FlirFrameReceived", params)
|
|
330
|
+
} catch (e: Exception) {
|
|
331
|
+
// Silently ignore
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
private fun emitDeviceState(state: String, isPhysical: Boolean) {
|
|
336
|
+
val ctx = reactContext ?: return
|
|
337
|
+
try {
|
|
338
|
+
val params = Arguments.createMap()
|
|
339
|
+
params.putString("state", state)
|
|
340
|
+
params.putBoolean("isPhysical", isPhysical)
|
|
341
|
+
params.putBoolean("isEmulator", isEmulatorMode)
|
|
342
|
+
params.putBoolean("isConnected", isPhysicalDeviceConnected || isEmulatorMode)
|
|
343
|
+
params.putBoolean("isStreaming", isStreaming)
|
|
344
|
+
|
|
345
|
+
connectedDeviceName?.let {
|
|
346
|
+
params.putString("deviceName", it)
|
|
347
|
+
}
|
|
348
|
+
connectedDeviceId?.let {
|
|
349
|
+
params.putString("deviceId", it)
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
353
|
+
.emit("FlirDeviceConnected", params)
|
|
354
|
+
} catch (e: Exception) {
|
|
355
|
+
Log.e(TAG, "Failed to emit device state", e)
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
private fun emitDevicesFound(devices: List<FlirSdkManager.DeviceInfo>) {
|
|
360
|
+
val ctx = reactContext ?: return
|
|
361
|
+
try {
|
|
362
|
+
val params = Arguments.createMap()
|
|
363
|
+
val devicesArray: WritableArray = Arguments.createArray()
|
|
364
|
+
|
|
365
|
+
devices.forEach { device ->
|
|
366
|
+
val deviceMap: WritableMap = Arguments.createMap()
|
|
367
|
+
deviceMap.putString("id", device.deviceId)
|
|
368
|
+
deviceMap.putString("name", device.deviceName)
|
|
369
|
+
deviceMap.putString("communicationType", device.commInterface.name)
|
|
370
|
+
deviceMap.putBoolean("isEmulator", device.isEmulator)
|
|
371
|
+
devicesArray.pushMap(deviceMap)
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
params.putArray("devices", devicesArray)
|
|
375
|
+
params.putInt("count", devices.size)
|
|
376
|
+
|
|
377
|
+
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
378
|
+
.emit("FlirDevicesFound", params)
|
|
379
|
+
} catch (e: Exception) {
|
|
380
|
+
Log.e(TAG, "Failed to emit devices found", e)
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
private fun emitError(message: String) {
|
|
385
|
+
val ctx = reactContext ?: return
|
|
386
|
+
try {
|
|
387
|
+
val params = Arguments.createMap()
|
|
388
|
+
params.putString("error", message)
|
|
389
|
+
|
|
390
|
+
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
391
|
+
.emit("FlirError", params)
|
|
392
|
+
} catch (e: Exception) {
|
|
393
|
+
Log.e(TAG, "Failed to emit error", e)
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Compatibility for Java / FlirHelper
|
|
398
|
+
@JvmStatic
|
|
399
|
+
fun getInstance(): FlirManager = this
|
|
400
|
+
|
|
401
|
+
interface DiscoveryCallback {
|
|
402
|
+
fun onDeviceFound(deviceName: String)
|
|
403
|
+
fun onDiscoveryTimeout()
|
|
404
|
+
fun onEmulatorEnabled()
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
private var discoveryCallback: DiscoveryCallback? = null
|
|
408
|
+
|
|
409
|
+
fun setDiscoveryCallback(callback: DiscoveryCallback?) {
|
|
410
|
+
discoveryCallback = callback
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
fun setPalette(name: String) {
|
|
414
|
+
sdkManager?.setPalette(name)
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
fun setEmulatorMode(enabled: Boolean) {
|
|
418
|
+
if (enabled) {
|
|
419
|
+
isEmulatorMode = true
|
|
420
|
+
discoveryCallback?.onEmulatorEnabled()
|
|
421
|
+
startEmulator(preferredEmulatorType)
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
fun updateAcol(value: Float) {
|
|
426
|
+
// No-op for now - palette changes handled by setPalette
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
fun startDiscovery(retry: Boolean) {
|
|
430
|
+
Log.i(FLOW_TAG, "[FlirManager] startDiscovery($retry) called, sdkManager=${if (sdkManager != null) "present" else "NULL"}, appContext=${if (appContext != null) "present" else "NULL"}")
|
|
431
|
+
|
|
432
|
+
// Auto-init if not initialized
|
|
433
|
+
if (sdkManager == null && appContext != null) {
|
|
434
|
+
Log.i(FLOW_TAG, "[FlirManager] Auto-initializing from startDiscovery()")
|
|
435
|
+
init(appContext!!)
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
val ctx = reactContext
|
|
439
|
+
if (ctx != null) {
|
|
440
|
+
// Reset discovery state if retrying
|
|
441
|
+
if (retry) {
|
|
442
|
+
discoveryStarted = false
|
|
443
|
+
}
|
|
444
|
+
startDiscoveryAndConnect(ctx, isEmuMode = false)
|
|
445
|
+
} else if (appContext != null) {
|
|
446
|
+
// Fallback: try to start discovery without React context
|
|
447
|
+
try {
|
|
448
|
+
Log.w(TAG, "Starting discovery without React context")
|
|
449
|
+
Log.i(FLOW_TAG, "[FlirManager] Calling sdkManager.startDiscovery(false) without React context")
|
|
450
|
+
sdkManager?.startDiscovery(false)
|
|
451
|
+
} catch (t: Throwable) {
|
|
452
|
+
Log.e(TAG, "startDiscovery failed", t)
|
|
453
|
+
Log.e(FLOW_TAG, "[FlirManager] startDiscovery failed: ${t.message}")
|
|
454
|
+
}
|
|
455
|
+
} else {
|
|
456
|
+
Log.e(FLOW_TAG, "[FlirManager] Cannot startDiscovery - no context available! Call init(context) first.")
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
fun enableEmulatorMode() {
|
|
461
|
+
setEmulatorMode(true)
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Force start with emulator (useful for testing)
|
|
466
|
+
*/
|
|
467
|
+
fun forceEmulatorMode(type: String = "FLIR_ONE_EDGE") {
|
|
468
|
+
setPreferredEmulatorType(type)
|
|
469
|
+
val ctx = reactContext
|
|
470
|
+
if (ctx != null) {
|
|
471
|
+
discoveryStarted = false
|
|
472
|
+
startDiscoveryAndConnect(ctx, isEmuMode = true)
|
|
473
|
+
} else {
|
|
474
|
+
startEmulator(preferredEmulatorType)
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|