ilabs-flir 2.2.32 → 2.3.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/android/Flir/src/main/java/flir/android/FlirManager.kt +68 -3
- package/android/Flir/src/main/java/flir/android/FlirModule.kt +88 -64
- package/android/Flir/src/main/java/flir/android/FlirSdkManager.java +50 -7
- package/ios/Flir/src/FlirManager.swift +92 -13
- package/ios/Flir/src/FlirModule.m +60 -30
- package/package.json +1 -1
|
@@ -71,7 +71,19 @@ object FlirManager {
|
|
|
71
71
|
fun isPreferSdkRotation(): Boolean = false
|
|
72
72
|
fun getBatteryLevel(): Int = -1
|
|
73
73
|
fun isBatteryCharging(): Boolean = false
|
|
74
|
-
fun setPalette(name: String) {
|
|
74
|
+
fun setPalette(name: String) {
|
|
75
|
+
sdkManager?.setPalette(name)
|
|
76
|
+
// Also try to update the app's global Var.cool if possible
|
|
77
|
+
try {
|
|
78
|
+
val palettes = listOf("iron", "rainbow", "grayscale", "arctic", "lava", "contrast", "hotcold", "medical")
|
|
79
|
+
val idx = palettes.indexOf(name.lowercase())
|
|
80
|
+
if (idx != -1) {
|
|
81
|
+
// If we found the index, we use the raw value.
|
|
82
|
+
// But if the name itself is passed as a number or from a loop, handle it.
|
|
83
|
+
updateAcol(idx.toFloat())
|
|
84
|
+
}
|
|
85
|
+
} catch (e: Exception) {}
|
|
86
|
+
}
|
|
75
87
|
fun getAvailablePalettes(): List<String> = emptyList()
|
|
76
88
|
|
|
77
89
|
/**
|
|
@@ -95,6 +107,7 @@ object FlirManager {
|
|
|
95
107
|
/**
|
|
96
108
|
* Start scanning
|
|
97
109
|
*/
|
|
110
|
+
@Synchronized
|
|
98
111
|
fun startDiscovery(retry: Boolean = false) {
|
|
99
112
|
if (!isInitialized && reactContext != null) {
|
|
100
113
|
init(reactContext!!)
|
|
@@ -102,6 +115,7 @@ object FlirManager {
|
|
|
102
115
|
|
|
103
116
|
if (isScanning && !retry) return
|
|
104
117
|
|
|
118
|
+
Log.i(TAG, "Starting FlirManager discovery...")
|
|
105
119
|
isScanning = true
|
|
106
120
|
emitDeviceState("discovering")
|
|
107
121
|
sdkManager?.scan()
|
|
@@ -118,7 +132,9 @@ object FlirManager {
|
|
|
118
132
|
/**
|
|
119
133
|
* Stop scanning
|
|
120
134
|
*/
|
|
135
|
+
@Synchronized
|
|
121
136
|
fun stopDiscovery() {
|
|
137
|
+
Log.i(TAG, "Stopping FlirManager discovery...")
|
|
122
138
|
sdkManager?.stopScan()
|
|
123
139
|
isScanning = false
|
|
124
140
|
}
|
|
@@ -126,7 +142,12 @@ object FlirManager {
|
|
|
126
142
|
/**
|
|
127
143
|
* Connect to a device
|
|
128
144
|
*/
|
|
129
|
-
|
|
145
|
+
@Synchronized
|
|
146
|
+
fun connectToDevice(deviceId: String?) {
|
|
147
|
+
if (deviceId == null) {
|
|
148
|
+
Log.e(TAG, "connectToDevice: deviceId is null")
|
|
149
|
+
return
|
|
150
|
+
}
|
|
130
151
|
Log.i(TAG, "connectToDevice: $deviceId")
|
|
131
152
|
|
|
132
153
|
val devices = sdkManager?.discoveredDevices ?: emptyList()
|
|
@@ -148,7 +169,9 @@ object FlirManager {
|
|
|
148
169
|
/**
|
|
149
170
|
* Disconnect
|
|
150
171
|
*/
|
|
172
|
+
@Synchronized
|
|
151
173
|
fun disconnect() {
|
|
174
|
+
Log.i(TAG, "Disconnecting FlirManager...")
|
|
152
175
|
shouldProcessFrames.set(false)
|
|
153
176
|
sdkManager?.disconnect()
|
|
154
177
|
isConnected = false
|
|
@@ -160,11 +183,19 @@ object FlirManager {
|
|
|
160
183
|
/**
|
|
161
184
|
* Stop everything
|
|
162
185
|
*/
|
|
186
|
+
@Synchronized
|
|
163
187
|
fun stop() {
|
|
188
|
+
Log.i(TAG, "Stopping FlirManager completely...")
|
|
164
189
|
shouldProcessFrames.set(false)
|
|
190
|
+
|
|
191
|
+
// Clear callbacks first to prevent any more frames/updates from hitting Java/RN
|
|
192
|
+
textureCallback = null
|
|
193
|
+
temperatureCallback = null
|
|
194
|
+
|
|
165
195
|
disconnect()
|
|
166
196
|
stopDiscovery()
|
|
167
197
|
latestBitmap = null
|
|
198
|
+
Log.i(TAG, "FlirManager stopped")
|
|
168
199
|
}
|
|
169
200
|
|
|
170
201
|
// Stub legacy methods
|
|
@@ -208,6 +239,13 @@ object FlirManager {
|
|
|
208
239
|
}
|
|
209
240
|
|
|
210
241
|
/**
|
|
242
|
+
* Capture a high-fidelity radiometric snapshot (saves thermal data)
|
|
243
|
+
*/
|
|
244
|
+
fun captureRadiometricSnapshot(path: String) {
|
|
245
|
+
sdkManager?.captureRadiometricSnapshot(path)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
211
249
|
* Get latest frame as file path (for RN)
|
|
212
250
|
*/
|
|
213
251
|
fun getLatestFramePath(): String? {
|
|
@@ -382,6 +420,33 @@ object FlirManager {
|
|
|
382
420
|
fun enableEmulatorMode() = startDiscovery()
|
|
383
421
|
fun forceEmulatorMode(type: String = "FLIR_ONE_EDGE") { startDiscovery() }
|
|
384
422
|
fun setPreferredEmulatorType(type: String) { }
|
|
385
|
-
fun updateAcol(value: Float) {
|
|
423
|
+
fun updateAcol(value: Float) {
|
|
424
|
+
Log.d(TAG, "updateAcol: $value")
|
|
425
|
+
// Use reflection to update ilabs.libs.io.data.Var.cool to avoid circular dependency
|
|
426
|
+
try {
|
|
427
|
+
val varClass = Class.forName("ilabs.libs.io.data.Var")
|
|
428
|
+
val coolField = varClass.getField("cool")
|
|
429
|
+
|
|
430
|
+
// Modular logic for palettes: if index > 7, wrap around (17 mod 8)
|
|
431
|
+
// But we keep shader variants (14, 15, 16) as-is if within that range
|
|
432
|
+
val rawIdx = value.toInt()
|
|
433
|
+
var shaderIdx = rawIdx
|
|
434
|
+
if (shaderIdx > 16) {
|
|
435
|
+
shaderIdx = shaderIdx % 16 // Shader loop
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
coolField.set(null, shaderIdx)
|
|
439
|
+
Log.d(TAG, "Updated Var.cool to $shaderIdx via reflection (raw=$rawIdx)")
|
|
440
|
+
|
|
441
|
+
// If we are in FLIR mode, also notify the SDK palette with modular loop
|
|
442
|
+
val palettes = listOf("iron", "rainbow", "grayscale", "arctic", "lava", "contrast", "hotcold", "medical")
|
|
443
|
+
val paletteIdx = rawIdx % palettes.size
|
|
444
|
+
val safeIdx = if (paletteIdx < 0) paletteIdx + palettes.size else paletteIdx
|
|
445
|
+
sdkManager?.setPalette(palettes[safeIdx])
|
|
446
|
+
|
|
447
|
+
} catch (e: Exception) {
|
|
448
|
+
Log.w(TAG, "Could not update Var.cool via reflection: ${e.message}")
|
|
449
|
+
}
|
|
450
|
+
}
|
|
386
451
|
fun destroy() { stop() }
|
|
387
452
|
}
|
|
@@ -34,7 +34,7 @@ class FlirModule(private val reactContext: ReactApplicationContext) : ReactConte
|
|
|
34
34
|
// Simple placeholder conversion: converts an ARGB color to a pseudo-temperature value.
|
|
35
35
|
// Replace with SDK call when integrating thermalsdk APIs.
|
|
36
36
|
@ReactMethod
|
|
37
|
-
fun getTemperatureFromColor(color: Int, promise: Promise) {
|
|
37
|
+
fun getTemperatureFromColor(color: Int, promise: Promise?) {
|
|
38
38
|
try {
|
|
39
39
|
val r = (color shr 16) and 0xFF
|
|
40
40
|
val g = (color shr 8) and 0xFF
|
|
@@ -42,81 +42,81 @@ class FlirModule(private val reactContext: ReactApplicationContext) : ReactConte
|
|
|
42
42
|
// Luminance-like value scaled to a plausible temperature range (0°C - 400°C)
|
|
43
43
|
val lum = 0.2126 * r + 0.7152 * g + 0.0722 * b
|
|
44
44
|
val temp = 0.0 + (lum / 255.0) * 400.0
|
|
45
|
-
promise
|
|
45
|
+
promise?.resolve(temp)
|
|
46
46
|
} catch (e: Exception) {
|
|
47
|
-
promise
|
|
47
|
+
promise?.reject("ERR_FLIR_CONVERT", e)
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
@ReactMethod
|
|
52
|
-
fun getLatestFramePath(promise: Promise) {
|
|
52
|
+
fun getLatestFramePath(promise: Promise?) {
|
|
53
53
|
try {
|
|
54
54
|
val path = FlirFrameCache.latestFramePath
|
|
55
|
-
if (path != null) promise
|
|
55
|
+
if (path != null) promise?.resolve(path) else promise?.resolve(null)
|
|
56
56
|
} catch (e: Exception) {
|
|
57
|
-
promise
|
|
57
|
+
promise?.reject("ERR_FLIR_PATH", e)
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
@ReactMethod
|
|
62
|
-
fun getTemperatureAt(x: Int, y: Int, promise: Promise) {
|
|
62
|
+
fun getTemperatureAt(x: Int, y: Int, promise: Promise?) {
|
|
63
63
|
try {
|
|
64
64
|
val temp = FlirManager.getTemperatureAt(x, y)
|
|
65
|
-
if (temp != null) promise
|
|
65
|
+
if (temp != null) promise?.resolve(temp) else promise?.reject("ERR_NO_DATA", "No temperature data available")
|
|
66
66
|
} catch (e: Exception) {
|
|
67
|
-
promise
|
|
67
|
+
promise?.reject("ERR_FLIR_SAMPLE", e)
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
@ReactMethod
|
|
72
|
-
fun getTemperatureAtNormalized(nx: Double, ny: Double, promise: Promise) {
|
|
72
|
+
fun getTemperatureAtNormalized(nx: Double, ny: Double, promise: Promise?) {
|
|
73
73
|
try {
|
|
74
74
|
val temp = FlirManager.getTemperatureAtNormalized(nx, ny)
|
|
75
|
-
if (temp != null) promise
|
|
75
|
+
if (temp != null) promise?.resolve(temp) else promise?.resolve(null)
|
|
76
76
|
} catch (e: Exception) {
|
|
77
|
-
promise
|
|
77
|
+
promise?.reject("ERR_FLIR_TEMP_NORM", e)
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
@ReactMethod
|
|
82
|
-
fun isEmulator(promise: Promise) {
|
|
82
|
+
fun isEmulator(promise: Promise?) {
|
|
83
83
|
try {
|
|
84
|
-
promise
|
|
84
|
+
promise?.resolve(FlirManager.isEmulator())
|
|
85
85
|
} catch (e: Exception) {
|
|
86
|
-
promise
|
|
86
|
+
promise?.reject("ERR_FLIR_EMULATOR_CHECK", e)
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
@ReactMethod
|
|
91
|
-
fun isDeviceConnected(promise: Promise) {
|
|
91
|
+
fun isDeviceConnected(promise: Promise?) {
|
|
92
92
|
try {
|
|
93
|
-
promise
|
|
93
|
+
promise?.resolve(FlirManager.isDeviceConnected())
|
|
94
94
|
} catch (e: Exception) {
|
|
95
|
-
promise
|
|
95
|
+
promise?.reject("ERR_FLIR_DEVICE_CHECK", e)
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
@ReactMethod
|
|
100
|
-
fun getConnectedDeviceInfo(promise: Promise) {
|
|
100
|
+
fun getConnectedDeviceInfo(promise: Promise?) {
|
|
101
101
|
try {
|
|
102
|
-
promise
|
|
102
|
+
promise?.resolve(FlirManager.getConnectedDeviceInfo())
|
|
103
103
|
} catch (e: Exception) {
|
|
104
|
-
promise
|
|
104
|
+
promise?.reject("ERR_FLIR_DEVICE_INFO", e)
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
@ReactMethod
|
|
109
|
-
fun isSDKDownloaded(promise: Promise) {
|
|
109
|
+
fun isSDKDownloaded(promise: Promise?) {
|
|
110
110
|
try {
|
|
111
111
|
val available = FlirSDKLoader.isSDKAvailable(reactContext)
|
|
112
|
-
promise
|
|
112
|
+
promise?.resolve(available)
|
|
113
113
|
} catch (e: Exception) {
|
|
114
|
-
promise
|
|
114
|
+
promise?.reject("ERR_FLIR_SDK_CHECK", e)
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
@ReactMethod
|
|
119
|
-
fun getSDKStatus(promise: Promise) {
|
|
119
|
+
fun getSDKStatus(promise: Promise?) {
|
|
120
120
|
try {
|
|
121
121
|
val available = FlirSDKLoader.isSDKAvailable(reactContext)
|
|
122
122
|
val arch = FlirSDKLoader.getDeviceArch()
|
|
@@ -131,14 +131,14 @@ class FlirModule(private val reactContext: ReactApplicationContext) : ReactConte
|
|
|
131
131
|
result.putBoolean("dexExists", dexPath?.exists() == true)
|
|
132
132
|
result.putBoolean("nativeLibsExist", nativeLibDir?.exists() == true)
|
|
133
133
|
|
|
134
|
-
promise
|
|
134
|
+
promise?.resolve(result)
|
|
135
135
|
} catch (e: Exception) {
|
|
136
|
-
promise
|
|
136
|
+
promise?.reject("ERR_FLIR_SDK_STATUS", e)
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
@ReactMethod
|
|
141
|
-
fun getDiscoveredDevices(promise: Promise) {
|
|
141
|
+
fun getDiscoveredDevices(promise: Promise?) {
|
|
142
142
|
try {
|
|
143
143
|
val devices = FlirManager.getDiscoveredDevices()
|
|
144
144
|
val result = com.facebook.react.bridge.Arguments.createArray()
|
|
@@ -152,129 +152,153 @@ class FlirModule(private val reactContext: ReactApplicationContext) : ReactConte
|
|
|
152
152
|
result.pushMap(deviceMap)
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
promise
|
|
155
|
+
promise?.resolve(result)
|
|
156
156
|
} catch (e: Exception) {
|
|
157
|
-
promise
|
|
157
|
+
promise?.reject("ERR_FLIR_DEVICES", e)
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
@ReactMethod
|
|
162
|
-
fun setPreferSdkRotation(prefer: Boolean, promise: Promise) {
|
|
162
|
+
fun setPreferSdkRotation(prefer: Boolean, promise: Promise?) {
|
|
163
163
|
try {
|
|
164
164
|
FlirManager.setPreferSdkRotation(prefer)
|
|
165
|
-
promise
|
|
165
|
+
promise?.resolve(true)
|
|
166
166
|
} catch (e: Exception) {
|
|
167
|
-
promise
|
|
167
|
+
promise?.reject("ERR_FLIR_SET_ROTATION_PREF", e)
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
@ReactMethod
|
|
172
|
-
fun isPreferSdkRotation(promise: Promise) {
|
|
172
|
+
fun isPreferSdkRotation(promise: Promise?) {
|
|
173
173
|
try {
|
|
174
174
|
val v = FlirManager.isPreferSdkRotation()
|
|
175
|
-
promise
|
|
175
|
+
promise?.resolve(v)
|
|
176
176
|
} catch (e: Exception) {
|
|
177
|
-
promise
|
|
177
|
+
promise?.reject("ERR_FLIR_GET_ROTATION_PREF", e)
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
@ReactMethod
|
|
182
|
-
fun getBatteryLevel(promise: Promise) {
|
|
182
|
+
fun getBatteryLevel(promise: Promise?) {
|
|
183
183
|
try {
|
|
184
184
|
val level = FlirManager.getBatteryLevel()
|
|
185
|
-
promise
|
|
185
|
+
promise?.resolve(level)
|
|
186
186
|
} catch (e: Exception) {
|
|
187
|
-
promise
|
|
187
|
+
promise?.reject("ERR_FLIR_GET_BATTERY", e)
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
@ReactMethod
|
|
192
|
-
fun isBatteryCharging(promise: Promise) {
|
|
192
|
+
fun isBatteryCharging(promise: Promise?) {
|
|
193
193
|
try {
|
|
194
194
|
val v = FlirManager.isBatteryCharging()
|
|
195
|
-
promise
|
|
195
|
+
promise?.resolve(v)
|
|
196
196
|
} catch (e: Exception) {
|
|
197
|
-
promise
|
|
197
|
+
promise?.reject("ERR_FLIR_CHARGING", e)
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
@ReactMethod
|
|
202
|
-
fun startEmulator(emulatorType: String
|
|
202
|
+
fun startEmulator(emulatorType: String?, promise: Promise?) {
|
|
203
203
|
try {
|
|
204
204
|
// Ensure SDK is initialized with context before starting discovery
|
|
205
205
|
FlirManager.init(reactContext)
|
|
206
206
|
// With simplified API, just start discovery - emulators are discovered like any device
|
|
207
207
|
FlirManager.startDiscovery(true)
|
|
208
|
-
promise
|
|
208
|
+
promise?.resolve(true)
|
|
209
209
|
} catch (e: Exception) {
|
|
210
|
-
promise
|
|
210
|
+
promise?.reject("ERR_FLIR_EMULATOR", e)
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
@ReactMethod
|
|
215
|
-
fun connectToDevice(deviceId: String
|
|
215
|
+
fun connectToDevice(deviceId: String?, promise: Promise?) {
|
|
216
216
|
try {
|
|
217
217
|
// Ensure SDK is initialized with context before connecting
|
|
218
218
|
FlirManager.init(reactContext)
|
|
219
|
-
|
|
220
|
-
|
|
219
|
+
if (deviceId != null) {
|
|
220
|
+
FlirManager.connectToDevice(deviceId)
|
|
221
|
+
}
|
|
222
|
+
promise?.resolve(true)
|
|
221
223
|
} catch (e: Exception) {
|
|
222
|
-
promise
|
|
224
|
+
promise?.reject("ERR_FLIR_CONNECT", e)
|
|
223
225
|
}
|
|
224
226
|
}
|
|
225
227
|
|
|
226
228
|
@ReactMethod
|
|
227
|
-
fun startDiscovery(promise: Promise) {
|
|
229
|
+
fun startDiscovery(promise: Promise?) {
|
|
228
230
|
try {
|
|
229
231
|
// Ensure SDK is initialized with context before starting discovery
|
|
230
232
|
FlirManager.init(reactContext)
|
|
231
233
|
FlirManager.startDiscovery(true)
|
|
232
|
-
promise
|
|
234
|
+
promise?.resolve(true)
|
|
233
235
|
} catch (e: Exception) {
|
|
234
|
-
promise
|
|
236
|
+
promise?.reject("ERR_FLIR_DISCOVERY", e)
|
|
235
237
|
}
|
|
236
238
|
}
|
|
237
239
|
|
|
238
240
|
@ReactMethod
|
|
239
|
-
fun stopDiscovery(promise: Promise) {
|
|
241
|
+
fun stopDiscovery(promise: Promise?) {
|
|
240
242
|
try {
|
|
241
243
|
FlirManager.stopDiscovery()
|
|
242
|
-
promise
|
|
244
|
+
promise?.resolve(true)
|
|
243
245
|
} catch (e: Exception) {
|
|
244
|
-
promise
|
|
246
|
+
promise?.reject("ERR_FLIR_STOP_DISCOVERY", e)
|
|
245
247
|
}
|
|
246
248
|
}
|
|
247
249
|
|
|
248
250
|
@ReactMethod
|
|
249
|
-
fun stopFlir(promise: Promise) {
|
|
251
|
+
fun stopFlir(promise: Promise?) {
|
|
250
252
|
try {
|
|
251
253
|
FlirManager.stop()
|
|
252
|
-
promise
|
|
254
|
+
promise?.resolve(true)
|
|
255
|
+
} catch (e: Exception) {
|
|
256
|
+
promise?.reject("ERR_FLIR_STOP", e)
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
@ReactMethod
|
|
261
|
+
fun updateAcol(value: Float, promise: Promise?) {
|
|
262
|
+
try {
|
|
263
|
+
FlirManager.updateAcol(value)
|
|
264
|
+
promise?.resolve(true)
|
|
265
|
+
} catch (e: Exception) {
|
|
266
|
+
promise?.reject("ERR_FLIR_ACOL", e)
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
@ReactMethod
|
|
271
|
+
fun setPalette(name: String?, promise: Promise?) {
|
|
272
|
+
try {
|
|
273
|
+
if (name != null) {
|
|
274
|
+
FlirManager.setPalette(name)
|
|
275
|
+
}
|
|
276
|
+
promise?.resolve(true)
|
|
253
277
|
} catch (e: Exception) {
|
|
254
|
-
promise
|
|
278
|
+
promise?.reject("ERR_FLIR_PALETTE", e)
|
|
255
279
|
}
|
|
256
280
|
}
|
|
257
281
|
|
|
258
282
|
@ReactMethod
|
|
259
|
-
fun initializeSDK(promise: Promise) {
|
|
283
|
+
fun initializeSDK(promise: Promise?) {
|
|
260
284
|
try {
|
|
261
285
|
FlirManager.init(reactContext)
|
|
262
286
|
|
|
263
287
|
val result = com.facebook.react.bridge.Arguments.createMap()
|
|
264
288
|
result.putBoolean("initialized", true)
|
|
265
289
|
result.putString("message", "SDK initialized successfully")
|
|
266
|
-
promise
|
|
290
|
+
promise?.resolve(result)
|
|
267
291
|
} catch (e: Exception) {
|
|
268
292
|
val result = com.facebook.react.bridge.Arguments.createMap()
|
|
269
293
|
result.putBoolean("initialized", false)
|
|
270
294
|
result.putString("error", e.message ?: "Unknown error")
|
|
271
295
|
result.putString("errorType", e.javaClass.simpleName)
|
|
272
|
-
promise
|
|
296
|
+
promise?.resolve(result)
|
|
273
297
|
}
|
|
274
298
|
}
|
|
275
299
|
|
|
276
300
|
@ReactMethod
|
|
277
|
-
fun getDebugInfo(promise: Promise) {
|
|
301
|
+
fun getDebugInfo(promise: Promise?) {
|
|
278
302
|
try {
|
|
279
303
|
val result = com.facebook.react.bridge.Arguments.createMap()
|
|
280
304
|
|
|
@@ -299,9 +323,9 @@ class FlirModule(private val reactContext: ReactApplicationContext) : ReactConte
|
|
|
299
323
|
result.putBoolean("isStreaming", FlirManager.isStreaming())
|
|
300
324
|
result.putString("connectedDevice", FlirManager.getConnectedDeviceInfo())
|
|
301
325
|
|
|
302
|
-
promise
|
|
326
|
+
promise?.resolve(result)
|
|
303
327
|
} catch (e: Exception) {
|
|
304
|
-
promise
|
|
328
|
+
promise?.reject("ERR_DEBUG_INFO", e)
|
|
305
329
|
}
|
|
306
330
|
}
|
|
307
331
|
}
|
|
@@ -8,7 +8,10 @@ import android.util.Log;
|
|
|
8
8
|
import com.flir.thermalsdk.ErrorCode;
|
|
9
9
|
import com.flir.thermalsdk.androidsdk.ThermalSdkAndroid;
|
|
10
10
|
import com.flir.thermalsdk.androidsdk.image.BitmapAndroid;
|
|
11
|
+
import com.flir.thermalsdk.image.Palette;
|
|
12
|
+
import com.flir.thermalsdk.image.PaletteManager;
|
|
11
13
|
import com.flir.thermalsdk.image.Point;
|
|
14
|
+
import com.flir.thermalsdk.image.ThermalImage;
|
|
12
15
|
import com.flir.thermalsdk.image.ThermalValue;
|
|
13
16
|
import com.flir.thermalsdk.live.AuthenticationResponse;
|
|
14
17
|
import com.flir.thermalsdk.live.Camera;
|
|
@@ -48,8 +51,10 @@ public class FlirSdkManager {
|
|
|
48
51
|
private Stream activeStream;
|
|
49
52
|
private final List<Identity> discoveredDevices = Collections.synchronizedList(new ArrayList<>());
|
|
50
53
|
private volatile Bitmap latestBitmap;
|
|
54
|
+
private volatile String currentPaletteName = "iron";
|
|
51
55
|
private final AtomicBoolean isProcessingFrame = new AtomicBoolean(false);
|
|
52
56
|
private boolean useHalfScale = false;
|
|
57
|
+
private String pendingSnapshotPath = null;
|
|
53
58
|
|
|
54
59
|
// Listener
|
|
55
60
|
private Listener listener;
|
|
@@ -337,14 +342,42 @@ public class FlirSdkManager {
|
|
|
337
342
|
if (streamer != null && activeStream != null) {
|
|
338
343
|
streamer.update();
|
|
339
344
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
345
|
+
final String paletteToApply = currentPaletteName;
|
|
346
|
+
final String snapshotPath = pendingSnapshotPath;
|
|
347
|
+
pendingSnapshotPath = null;
|
|
348
|
+
|
|
349
|
+
streamer.withThermalImage(thermalImage -> {
|
|
350
|
+
// 1. Apply Palette
|
|
351
|
+
if (paletteToApply != null) {
|
|
352
|
+
Palette palette =
|
|
353
|
+
PaletteManager.getDefaultPalettes().stream()
|
|
354
|
+
.filter(p -> p.name.equalsIgnoreCase(paletteToApply))
|
|
355
|
+
.findFirst()
|
|
356
|
+
.orElse(null);
|
|
357
|
+
if (palette != null) {
|
|
358
|
+
thermalImage.setPalette(palette);
|
|
359
|
+
}
|
|
346
360
|
}
|
|
347
|
-
|
|
361
|
+
|
|
362
|
+
// 2. Save Radiometric Snapshot if requested
|
|
363
|
+
if (snapshotPath != null) {
|
|
364
|
+
try {
|
|
365
|
+
thermalImage.saveAs(snapshotPath);
|
|
366
|
+
Log.i(TAG, "Radiometric snapshot saved to: " + snapshotPath);
|
|
367
|
+
} catch (java.io.IOException e) {
|
|
368
|
+
Log.e(TAG, "Failed to save radiometric snapshot", e);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// 3. Generate Bitmap for display
|
|
373
|
+
Bitmap bitmap = BitmapAndroid.createBitmap(thermalImage.getImage()).getBitMap();
|
|
374
|
+
if (bitmap != null) {
|
|
375
|
+
latestBitmap = bitmap;
|
|
376
|
+
if (listener != null) {
|
|
377
|
+
listener.onFrame(bitmap);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
});
|
|
348
381
|
}
|
|
349
382
|
} catch (Exception e) {
|
|
350
383
|
Log.e(TAG, "Frame processing error", e);
|
|
@@ -423,6 +456,16 @@ public class FlirSdkManager {
|
|
|
423
456
|
}
|
|
424
457
|
|
|
425
458
|
// ==================== LISTENERS ====================
|
|
459
|
+
|
|
460
|
+
public void setPalette(String paletteName) {
|
|
461
|
+
this.currentPaletteName = paletteName;
|
|
462
|
+
Log.d(TAG, "Requested palette: " + paletteName);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
public void captureRadiometricSnapshot(String path) {
|
|
466
|
+
this.pendingSnapshotPath = path;
|
|
467
|
+
Log.d(TAG, "Pending radiometric snapshot: " + path);
|
|
468
|
+
}
|
|
426
469
|
|
|
427
470
|
private final DiscoveryEventListener discoveryListener = new DiscoveryEventListener() {
|
|
428
471
|
@Override
|
|
@@ -63,6 +63,13 @@ import ThermalSDK
|
|
|
63
63
|
private var connectedDeviceId: String?
|
|
64
64
|
private var connectedDeviceName: String?
|
|
65
65
|
|
|
66
|
+
// Internal synchronization
|
|
67
|
+
private let stateLock = NSObject()
|
|
68
|
+
|
|
69
|
+
// Palette and Snapshot state
|
|
70
|
+
private var currentPaletteName: String = "iron"
|
|
71
|
+
private var pendingSnapshotPath: String?
|
|
72
|
+
|
|
66
73
|
// Dedicated render queue for frame processing (matches sample app pattern)
|
|
67
74
|
private let renderQueue = DispatchQueue(label: "com.flir.render")
|
|
68
75
|
|
|
@@ -122,6 +129,7 @@ import ThermalSDK
|
|
|
122
129
|
}
|
|
123
130
|
|
|
124
131
|
@objc public func stopDiscovery() {
|
|
132
|
+
objc_sync_enter(stateLock); defer { objc_sync_exit(stateLock) }
|
|
125
133
|
NSLog("[FlirManager] stopDiscovery")
|
|
126
134
|
|
|
127
135
|
#if FLIR_ENABLED
|
|
@@ -133,6 +141,7 @@ import ThermalSDK
|
|
|
133
141
|
// MARK: - Connection
|
|
134
142
|
|
|
135
143
|
@objc public func connectToDevice(_ deviceId: String) {
|
|
144
|
+
objc_sync_enter(stateLock); defer { objc_sync_exit(stateLock) }
|
|
136
145
|
NSLog("[FlirManager] connectToDevice: \(deviceId)")
|
|
137
146
|
|
|
138
147
|
#if FLIR_ENABLED
|
|
@@ -270,10 +279,11 @@ import ThermalSDK
|
|
|
270
279
|
}
|
|
271
280
|
|
|
272
281
|
@objc public func disconnect() {
|
|
282
|
+
objc_sync_enter(stateLock); defer { objc_sync_exit(stateLock) }
|
|
273
283
|
NSLog("[FlirManager] disconnect")
|
|
274
284
|
|
|
275
285
|
#if FLIR_ENABLED
|
|
276
|
-
|
|
286
|
+
stopStreamInternalSync()
|
|
277
287
|
camera?.disconnect()
|
|
278
288
|
camera = nil
|
|
279
289
|
_isConnected = false
|
|
@@ -289,9 +299,36 @@ import ThermalSDK
|
|
|
289
299
|
}
|
|
290
300
|
|
|
291
301
|
@objc public func stop() {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
302
|
+
objc_sync_enter(stateLock); defer { objc_sync_exit(stateLock) }
|
|
303
|
+
stopStreamInternalSync()
|
|
304
|
+
disconnectInternalSync()
|
|
305
|
+
stopDiscoveryInternalSync()
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
private func stopDiscoveryInternalSync() {
|
|
309
|
+
NSLog("[FlirManager] stopDiscovery")
|
|
310
|
+
#if FLIR_ENABLED
|
|
311
|
+
discovery?.stop()
|
|
312
|
+
emitStateChange("idle")
|
|
313
|
+
#endif
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
private func disconnectInternalSync() {
|
|
317
|
+
NSLog("[FlirManager] disconnect")
|
|
318
|
+
#if FLIR_ENABLED
|
|
319
|
+
stopStreamInternalSync()
|
|
320
|
+
camera?.disconnect()
|
|
321
|
+
camera = nil
|
|
322
|
+
_isConnected = false
|
|
323
|
+
connectedDeviceId = nil
|
|
324
|
+
connectedDeviceName = nil
|
|
325
|
+
_latestImage = nil
|
|
326
|
+
|
|
327
|
+
DispatchQueue.main.async { [weak self] in
|
|
328
|
+
self?.delegate?.onDeviceDisconnected()
|
|
329
|
+
self?.emitStateChange("disconnected")
|
|
330
|
+
}
|
|
331
|
+
#endif
|
|
295
332
|
}
|
|
296
333
|
|
|
297
334
|
// MARK: - Streaming
|
|
@@ -345,13 +382,18 @@ import ThermalSDK
|
|
|
345
382
|
#endif
|
|
346
383
|
|
|
347
384
|
@objc public func stopStream() {
|
|
385
|
+
objc_sync_enter(stateLock); defer { objc_sync_exit(stateLock) }
|
|
386
|
+
stopStreamInternalSync()
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
private func stopStreamInternalSync() {
|
|
348
390
|
NSLog("[FlirManager] stopStream")
|
|
349
391
|
|
|
350
392
|
#if FLIR_ENABLED
|
|
393
|
+
_isStreaming = false
|
|
351
394
|
stream?.stop()
|
|
352
395
|
stream = nil
|
|
353
396
|
streamer = nil
|
|
354
|
-
_isStreaming = false
|
|
355
397
|
_latestImage = nil
|
|
356
398
|
|
|
357
399
|
if _isConnected {
|
|
@@ -468,11 +510,22 @@ import ThermalSDK
|
|
|
468
510
|
}
|
|
469
511
|
|
|
470
512
|
@objc public func setPalette(_ name: String) {
|
|
471
|
-
|
|
513
|
+
self.currentPaletteName = name
|
|
514
|
+
NSLog("[FlirManager] Requested palette: \(name)")
|
|
472
515
|
}
|
|
473
516
|
|
|
474
517
|
@objc public func setPaletteFromAcol(_ acol: Float) {
|
|
475
|
-
//
|
|
518
|
+
// Map acol (0..7) to palette names
|
|
519
|
+
let palettes = ["iron", "rainbow", "grayscale", "arctic", "lava", "contrast", "hotcold", "medical"]
|
|
520
|
+
let idx = Int(acol)
|
|
521
|
+
if idx >= 0 && idx < palettes.count {
|
|
522
|
+
setPalette(palettes[idx])
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
@objc public func captureRadiometricSnapshot(_ path: String) {
|
|
527
|
+
self.pendingSnapshotPath = path
|
|
528
|
+
NSLog("[FlirManager] Pending radiometric snapshot: \(path)")
|
|
476
529
|
}
|
|
477
530
|
|
|
478
531
|
@objc public func retainClient(_ clientId: String) {
|
|
@@ -637,14 +690,40 @@ extension FlirManager: FLIRStreamDelegate {
|
|
|
637
690
|
|
|
638
691
|
NSLog("[FLIR-TRACE 2️⃣] Processing on renderQueue")
|
|
639
692
|
|
|
693
|
+
objc_sync_enter(self.stateLock)
|
|
694
|
+
let currentStreamer = self.streamer
|
|
695
|
+
let streaming = self._isStreaming
|
|
696
|
+
objc_sync_exit(self.stateLock)
|
|
697
|
+
|
|
698
|
+
guard streaming, let streamer = currentStreamer else {
|
|
699
|
+
return
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
let paletteToApply = self.currentPaletteName
|
|
703
|
+
let snapshotPath = self.pendingSnapshotPath
|
|
704
|
+
self.pendingSnapshotPath = nil
|
|
705
|
+
|
|
640
706
|
do {
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
707
|
+
try streamer.update()
|
|
708
|
+
|
|
709
|
+
streamer.withThermalImage { thermalImage in
|
|
710
|
+
// 1. Apply Palette
|
|
711
|
+
if let palette = thermalImage.paletteManager.getDefaultPalettes().first(where: { $0.name.lowercased() == paletteToApply.lowercased() }) {
|
|
712
|
+
thermalImage.palette = palette
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
// 2. Save Radiometric Snapshot if requested
|
|
716
|
+
if let path = snapshotPath {
|
|
717
|
+
do {
|
|
718
|
+
try thermalImage.save(to: path)
|
|
719
|
+
NSLog("[FlirManager] Radiometric snapshot saved to: \(path)")
|
|
720
|
+
} catch {
|
|
721
|
+
NSLog("[FlirManager] Failed to save radiometric snapshot: \(error)")
|
|
722
|
+
}
|
|
723
|
+
}
|
|
647
724
|
}
|
|
725
|
+
|
|
726
|
+
NSLog("[FLIR-TRACE 3️⃣] Streamer updated successfully")
|
|
648
727
|
} catch {
|
|
649
728
|
NSLog("[FLIR-TRACE ❌] Streamer update failed: \(error)")
|
|
650
729
|
return
|
|
@@ -161,7 +161,7 @@ RCT_EXPORT_METHOD(setNetworkDiscoveryEnabled : (BOOL)enabled resolver : (
|
|
|
161
161
|
setBool:enabled
|
|
162
162
|
forKey:@"ilabsFlir.networkDiscoveryEnabled"];
|
|
163
163
|
}
|
|
164
|
-
resolve(@(YES));
|
|
164
|
+
if (resolve) resolve(@(YES));
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
RCT_EXPORT_METHOD(startDiscovery : (RCTPromiseResolveBlock)
|
|
@@ -178,7 +178,7 @@ RCT_EXPORT_METHOD(startDiscovery : (RCTPromiseResolveBlock)
|
|
|
178
178
|
NSLog(@"[FlirModule] [%@] ⏱ FlirManager.startDiscovery returned",
|
|
179
179
|
[NSDate date]);
|
|
180
180
|
}
|
|
181
|
-
resolve(@(YES));
|
|
181
|
+
if (resolve) resolve(@(YES));
|
|
182
182
|
});
|
|
183
183
|
}
|
|
184
184
|
|
|
@@ -191,7 +191,7 @@ RCT_EXPORT_METHOD(stopDiscovery : (RCTPromiseResolveBlock)
|
|
|
191
191
|
((void (*)(id, SEL))objc_msgSend)(manager,
|
|
192
192
|
sel_registerName("stopDiscovery"));
|
|
193
193
|
}
|
|
194
|
-
resolve(@(YES));
|
|
194
|
+
if (resolve) resolve(@(YES));
|
|
195
195
|
});
|
|
196
196
|
}
|
|
197
197
|
|
|
@@ -211,12 +211,16 @@ RCT_EXPORT_METHOD(getDiscoveredDevices : (RCTPromiseResolveBlock)
|
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
|
-
resolve(arr);
|
|
214
|
+
if (resolve) resolve(arr);
|
|
215
215
|
});
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
RCT_EXPORT_METHOD(connectToDevice : (NSString *)deviceId resolver : (
|
|
219
219
|
RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
220
|
+
if (!deviceId) {
|
|
221
|
+
if (reject) reject(@"ERR_INVALID_ARGS", @"deviceId is required", nil);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
220
224
|
NSLog(@"[FlirModule] [%@] ⏱ RN->connectToDevice called for: %@",
|
|
221
225
|
[NSDate date], deviceId);
|
|
222
226
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
@@ -242,10 +246,10 @@ RCT_EXPORT_METHOD(connectToDevice : (NSString *)deviceId resolver : (
|
|
|
242
246
|
[NSDate date]);
|
|
243
247
|
|
|
244
248
|
// Resolve immediately - connection status will come via events
|
|
245
|
-
resolve(@(YES));
|
|
249
|
+
if (resolve) resolve(@(YES));
|
|
246
250
|
} else {
|
|
247
251
|
NSLog(@"[FlirModule] [%@] ❌ FlirManager not found", [NSDate date]);
|
|
248
|
-
reject(@"ERR_NO_MANAGER", @"FlirManager not found", nil);
|
|
252
|
+
if (reject) reject(@"ERR_NO_MANAGER", @"FlirManager not found", nil);
|
|
249
253
|
}
|
|
250
254
|
});
|
|
251
255
|
}
|
|
@@ -261,7 +265,7 @@ RCT_EXPORT_METHOD(disconnect : (RCTPromiseResolveBlock)
|
|
|
261
265
|
((void (*)(id, SEL))objc_msgSend)(manager,
|
|
262
266
|
sel_registerName("disconnect"));
|
|
263
267
|
}
|
|
264
|
-
resolve(@(YES));
|
|
268
|
+
if (resolve) resolve(@(YES));
|
|
265
269
|
});
|
|
266
270
|
}
|
|
267
271
|
|
|
@@ -274,7 +278,7 @@ RCT_EXPORT_METHOD(stopFlir : (RCTPromiseResolveBlock)
|
|
|
274
278
|
[[FlirState shared] reset];
|
|
275
279
|
((void (*)(id, SEL))objc_msgSend)(manager, sel_registerName("stop"));
|
|
276
280
|
}
|
|
277
|
-
resolve(@(YES));
|
|
281
|
+
if (resolve) resolve(@(YES));
|
|
278
282
|
});
|
|
279
283
|
}
|
|
280
284
|
|
|
@@ -295,13 +299,13 @@ RCT_EXPORT_METHOD(startEmulator : (NSString *)emulatorType resolver : (
|
|
|
295
299
|
|
|
296
300
|
// Initiate emulator start asynchronously
|
|
297
301
|
((void (*)(id, SEL, id))objc_msgSend)(
|
|
298
|
-
manager, sel_registerName("startEmulatorWithType:"), emulatorType);
|
|
302
|
+
manager, sel_registerName("startEmulatorWithType:"), emulatorType ?: @"FLIR_ONE_EDGE");
|
|
299
303
|
|
|
300
304
|
// Resolve immediately - connection status will come via events
|
|
301
|
-
resolve(@(YES));
|
|
305
|
+
if (resolve) resolve(@(YES));
|
|
302
306
|
} else {
|
|
303
307
|
// Fallback if selector assumption wrong/mismatch
|
|
304
|
-
reject(@"ERR_NOT_IMPL",
|
|
308
|
+
if (reject) reject(@"ERR_NOT_IMPL",
|
|
305
309
|
@"startEmulator not implemented or signature mismatch", nil);
|
|
306
310
|
self.connectResolve = nil;
|
|
307
311
|
self.connectReject = nil;
|
|
@@ -323,9 +327,9 @@ RCT_EXPORT_METHOD(getTemperatureAt : (nonnull NSNumber *)x y : (
|
|
|
323
327
|
[y intValue]);
|
|
324
328
|
}
|
|
325
329
|
if (isnan(temp)) {
|
|
326
|
-
resolve([NSNull null]);
|
|
330
|
+
if (resolve) resolve([NSNull null]);
|
|
327
331
|
} else {
|
|
328
|
-
resolve(@(temp));
|
|
332
|
+
if (resolve) resolve(@(temp));
|
|
329
333
|
}
|
|
330
334
|
});
|
|
331
335
|
}
|
|
@@ -346,9 +350,9 @@ RCT_EXPORT_METHOD(getTemperatureAtNormalized : (nonnull NSNumber *)nx y : (
|
|
|
346
350
|
[nx doubleValue], [ny doubleValue]);
|
|
347
351
|
}
|
|
348
352
|
if (isnan(temp)) {
|
|
349
|
-
resolve([NSNull null]);
|
|
353
|
+
if (resolve) resolve([NSNull null]);
|
|
350
354
|
} else {
|
|
351
|
-
resolve(@(temp));
|
|
355
|
+
if (resolve) resolve(@(temp));
|
|
352
356
|
}
|
|
353
357
|
});
|
|
354
358
|
}
|
|
@@ -360,7 +364,7 @@ RCT_EXPORT_METHOD(getTemperatureFromColor : (NSInteger)color resolver : (
|
|
|
360
364
|
int b = color & 0xFF;
|
|
361
365
|
double lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
362
366
|
double temp = (lum / 255.0) * 400.0;
|
|
363
|
-
resolve(@(temp));
|
|
367
|
+
if (resolve) resolve(@(temp));
|
|
364
368
|
}
|
|
365
369
|
|
|
366
370
|
RCT_EXPORT_METHOD(isEmulator : (RCTPromiseResolveBlock)
|
|
@@ -373,7 +377,7 @@ RCT_EXPORT_METHOD(isEmulator : (RCTPromiseResolveBlock)
|
|
|
373
377
|
isEm = ((BOOL (*)(id, SEL))objc_msgSend)(manager,
|
|
374
378
|
sel_registerName("isEmulator"));
|
|
375
379
|
}
|
|
376
|
-
resolve(@(isEm));
|
|
380
|
+
if (resolve) resolve(@(isEm));
|
|
377
381
|
});
|
|
378
382
|
}
|
|
379
383
|
|
|
@@ -384,15 +388,15 @@ RCT_EXPORT_METHOD(getLatestFrameBitmap : (RCTPromiseResolveBlock)
|
|
|
384
388
|
if (!manager ||
|
|
385
389
|
![manager
|
|
386
390
|
respondsToSelector:sel_registerName("latestFrameBitmapBase64")]) {
|
|
387
|
-
resolve([NSNull null]);
|
|
391
|
+
if (resolve) resolve([NSNull null]);
|
|
388
392
|
return;
|
|
389
393
|
}
|
|
390
394
|
NSDictionary *dict = ((NSDictionary * (*)(id, SEL)) objc_msgSend)(
|
|
391
395
|
manager, sel_registerName("latestFrameBitmapBase64"));
|
|
392
396
|
if (!dict) {
|
|
393
|
-
resolve([NSNull null]);
|
|
397
|
+
if (resolve) resolve([NSNull null]);
|
|
394
398
|
} else {
|
|
395
|
-
resolve(dict);
|
|
399
|
+
if (resolve) resolve(dict);
|
|
396
400
|
}
|
|
397
401
|
});
|
|
398
402
|
}
|
|
@@ -407,7 +411,7 @@ RCT_EXPORT_METHOD(isDeviceConnected : (RCTPromiseResolveBlock)
|
|
|
407
411
|
isC = ((BOOL (*)(id, SEL))objc_msgSend)(manager,
|
|
408
412
|
sel_registerName("isConnected"));
|
|
409
413
|
}
|
|
410
|
-
resolve(@(isC));
|
|
414
|
+
if (resolve) resolve(@(isC));
|
|
411
415
|
});
|
|
412
416
|
}
|
|
413
417
|
|
|
@@ -421,19 +425,17 @@ RCT_EXPORT_METHOD(getConnectedDeviceInfo : (RCTPromiseResolveBlock)
|
|
|
421
425
|
info = ((NSString * (*)(id, SEL)) objc_msgSend)(
|
|
422
426
|
manager, sel_registerName("getConnectedDeviceInfo"));
|
|
423
427
|
}
|
|
424
|
-
resolve(info);
|
|
428
|
+
if (resolve) resolve(info);
|
|
425
429
|
});
|
|
426
430
|
}
|
|
427
431
|
|
|
428
|
-
RCT_EXPORT_METHOD(isSDKDownloaded : (RCTPromiseResolveBlock)
|
|
429
|
-
resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
430
432
|
// Assuming integrated SDK
|
|
431
|
-
resolve(@(YES));
|
|
433
|
+
if (resolve) resolve(@(YES));
|
|
432
434
|
}
|
|
433
435
|
|
|
434
436
|
RCT_EXPORT_METHOD(getSDKStatus : (RCTPromiseResolveBlock)
|
|
435
437
|
resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
436
|
-
resolve(@{@"available" : @(YES), @"arch" : @"arm64", @"platform" : @"iOS"});
|
|
438
|
+
if (resolve) resolve(@{@"available" : @(YES), @"arch" : @"arm64", @"platform" : @"iOS"});
|
|
437
439
|
}
|
|
438
440
|
|
|
439
441
|
RCT_EXPORT_METHOD(getBatteryLevel : (RCTPromiseResolveBlock)
|
|
@@ -446,7 +448,7 @@ RCT_EXPORT_METHOD(getBatteryLevel : (RCTPromiseResolveBlock)
|
|
|
446
448
|
level = ((int (*)(id, SEL))objc_msgSend)(
|
|
447
449
|
manager, sel_registerName("getBatteryLevel"));
|
|
448
450
|
}
|
|
449
|
-
resolve(@(level));
|
|
451
|
+
if (resolve) resolve(@(level));
|
|
450
452
|
});
|
|
451
453
|
}
|
|
452
454
|
|
|
@@ -460,7 +462,7 @@ RCT_EXPORT_METHOD(isBatteryCharging : (RCTPromiseResolveBlock)
|
|
|
460
462
|
ch = ((BOOL (*)(id, SEL))objc_msgSend)(
|
|
461
463
|
manager, sel_registerName("isBatteryCharging"));
|
|
462
464
|
}
|
|
463
|
-
resolve(@(ch));
|
|
465
|
+
if (resolve) resolve(@(ch));
|
|
464
466
|
});
|
|
465
467
|
}
|
|
466
468
|
|
|
@@ -473,7 +475,35 @@ RCT_EXPORT_METHOD(setPreferSdkRotation : (BOOL)prefer resolver : (
|
|
|
473
475
|
((void (*)(id, SEL, BOOL))objc_msgSend)(
|
|
474
476
|
manager, sel_registerName("setPreferSdkRotation:"), prefer);
|
|
475
477
|
}
|
|
476
|
-
resolve(@(YES));
|
|
478
|
+
if (resolve) resolve(@(YES));
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
RCT_EXPORT_METHOD(setPalette : (NSString *)name resolver : (RCTPromiseResolveBlock)
|
|
483
|
+
resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
484
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
485
|
+
id manager = flir_manager_shared();
|
|
486
|
+
if (manager &&
|
|
487
|
+
[manager respondsToSelector:sel_registerName("setPalette:")]) {
|
|
488
|
+
((void (*)(id, SEL, id))objc_msgSend)(manager,
|
|
489
|
+
sel_registerName("setPalette:"),
|
|
490
|
+
name);
|
|
491
|
+
}
|
|
492
|
+
if (resolve) resolve(@(YES));
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
RCT_EXPORT_METHOD(captureRadiometricSnapshot : (NSString *)path resolver : (RCTPromiseResolveBlock)
|
|
497
|
+
resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
498
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
499
|
+
id manager = flir_manager_shared();
|
|
500
|
+
if (manager &&
|
|
501
|
+
[manager respondsToSelector:sel_registerName("captureRadiometricSnapshot:")]) {
|
|
502
|
+
((void (*)(id, SEL, id))objc_msgSend)(manager,
|
|
503
|
+
sel_registerName("captureRadiometricSnapshot:"),
|
|
504
|
+
path);
|
|
505
|
+
}
|
|
506
|
+
if (resolve) resolve(@(YES));
|
|
477
507
|
});
|
|
478
508
|
}
|
|
479
509
|
|
|
@@ -487,7 +517,7 @@ RCT_EXPORT_METHOD(isPreferSdkRotation : (RCTPromiseResolveBlock)
|
|
|
487
517
|
v = ((BOOL (*)(id, SEL))objc_msgSend)(
|
|
488
518
|
manager, sel_registerName("isPreferSdkRotation"));
|
|
489
519
|
}
|
|
490
|
-
resolve(@(v));
|
|
520
|
+
if (resolve) resolve(@(v));
|
|
491
521
|
});
|
|
492
522
|
}
|
|
493
523
|
|