ilabs-flir 2.2.32 → 2.3.0
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.
|
@@ -95,6 +95,7 @@ object FlirManager {
|
|
|
95
95
|
/**
|
|
96
96
|
* Start scanning
|
|
97
97
|
*/
|
|
98
|
+
@Synchronized
|
|
98
99
|
fun startDiscovery(retry: Boolean = false) {
|
|
99
100
|
if (!isInitialized && reactContext != null) {
|
|
100
101
|
init(reactContext!!)
|
|
@@ -102,6 +103,7 @@ object FlirManager {
|
|
|
102
103
|
|
|
103
104
|
if (isScanning && !retry) return
|
|
104
105
|
|
|
106
|
+
Log.i(TAG, "Starting FlirManager discovery...")
|
|
105
107
|
isScanning = true
|
|
106
108
|
emitDeviceState("discovering")
|
|
107
109
|
sdkManager?.scan()
|
|
@@ -118,7 +120,9 @@ object FlirManager {
|
|
|
118
120
|
/**
|
|
119
121
|
* Stop scanning
|
|
120
122
|
*/
|
|
123
|
+
@Synchronized
|
|
121
124
|
fun stopDiscovery() {
|
|
125
|
+
Log.i(TAG, "Stopping FlirManager discovery...")
|
|
122
126
|
sdkManager?.stopScan()
|
|
123
127
|
isScanning = false
|
|
124
128
|
}
|
|
@@ -126,7 +130,12 @@ object FlirManager {
|
|
|
126
130
|
/**
|
|
127
131
|
* Connect to a device
|
|
128
132
|
*/
|
|
129
|
-
|
|
133
|
+
@Synchronized
|
|
134
|
+
fun connectToDevice(deviceId: String?) {
|
|
135
|
+
if (deviceId == null) {
|
|
136
|
+
Log.e(TAG, "connectToDevice: deviceId is null")
|
|
137
|
+
return
|
|
138
|
+
}
|
|
130
139
|
Log.i(TAG, "connectToDevice: $deviceId")
|
|
131
140
|
|
|
132
141
|
val devices = sdkManager?.discoveredDevices ?: emptyList()
|
|
@@ -148,7 +157,9 @@ object FlirManager {
|
|
|
148
157
|
/**
|
|
149
158
|
* Disconnect
|
|
150
159
|
*/
|
|
160
|
+
@Synchronized
|
|
151
161
|
fun disconnect() {
|
|
162
|
+
Log.i(TAG, "Disconnecting FlirManager...")
|
|
152
163
|
shouldProcessFrames.set(false)
|
|
153
164
|
sdkManager?.disconnect()
|
|
154
165
|
isConnected = false
|
|
@@ -160,11 +171,19 @@ object FlirManager {
|
|
|
160
171
|
/**
|
|
161
172
|
* Stop everything
|
|
162
173
|
*/
|
|
174
|
+
@Synchronized
|
|
163
175
|
fun stop() {
|
|
176
|
+
Log.i(TAG, "Stopping FlirManager completely...")
|
|
164
177
|
shouldProcessFrames.set(false)
|
|
178
|
+
|
|
179
|
+
// Clear callbacks first to prevent any more frames/updates from hitting Java/RN
|
|
180
|
+
textureCallback = null
|
|
181
|
+
temperatureCallback = null
|
|
182
|
+
|
|
165
183
|
disconnect()
|
|
166
184
|
stopDiscovery()
|
|
167
185
|
latestBitmap = null
|
|
186
|
+
Log.i(TAG, "FlirManager stopped")
|
|
168
187
|
}
|
|
169
188
|
|
|
170
189
|
// Stub legacy methods
|
|
@@ -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,131 @@ 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)
|
|
253
255
|
} catch (e: Exception) {
|
|
254
|
-
promise
|
|
256
|
+
promise?.reject("ERR_FLIR_STOP", e)
|
|
255
257
|
}
|
|
256
258
|
}
|
|
257
259
|
|
|
258
260
|
@ReactMethod
|
|
259
|
-
fun initializeSDK(promise: Promise) {
|
|
261
|
+
fun initializeSDK(promise: Promise?) {
|
|
260
262
|
try {
|
|
261
263
|
FlirManager.init(reactContext)
|
|
262
264
|
|
|
263
265
|
val result = com.facebook.react.bridge.Arguments.createMap()
|
|
264
266
|
result.putBoolean("initialized", true)
|
|
265
267
|
result.putString("message", "SDK initialized successfully")
|
|
266
|
-
promise
|
|
268
|
+
promise?.resolve(result)
|
|
267
269
|
} catch (e: Exception) {
|
|
268
270
|
val result = com.facebook.react.bridge.Arguments.createMap()
|
|
269
271
|
result.putBoolean("initialized", false)
|
|
270
272
|
result.putString("error", e.message ?: "Unknown error")
|
|
271
273
|
result.putString("errorType", e.javaClass.simpleName)
|
|
272
|
-
promise
|
|
274
|
+
promise?.resolve(result)
|
|
273
275
|
}
|
|
274
276
|
}
|
|
275
277
|
|
|
276
278
|
@ReactMethod
|
|
277
|
-
fun getDebugInfo(promise: Promise) {
|
|
279
|
+
fun getDebugInfo(promise: Promise?) {
|
|
278
280
|
try {
|
|
279
281
|
val result = com.facebook.react.bridge.Arguments.createMap()
|
|
280
282
|
|
|
@@ -299,9 +301,9 @@ class FlirModule(private val reactContext: ReactApplicationContext) : ReactConte
|
|
|
299
301
|
result.putBoolean("isStreaming", FlirManager.isStreaming())
|
|
300
302
|
result.putString("connectedDevice", FlirManager.getConnectedDeviceInfo())
|
|
301
303
|
|
|
302
|
-
promise
|
|
304
|
+
promise?.resolve(result)
|
|
303
305
|
} catch (e: Exception) {
|
|
304
|
-
promise
|
|
306
|
+
promise?.reject("ERR_DEBUG_INFO", e)
|
|
305
307
|
}
|
|
306
308
|
}
|
|
307
309
|
}
|
|
@@ -63,6 +63,9 @@ 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
|
+
|
|
66
69
|
// Dedicated render queue for frame processing (matches sample app pattern)
|
|
67
70
|
private let renderQueue = DispatchQueue(label: "com.flir.render")
|
|
68
71
|
|
|
@@ -122,6 +125,7 @@ import ThermalSDK
|
|
|
122
125
|
}
|
|
123
126
|
|
|
124
127
|
@objc public func stopDiscovery() {
|
|
128
|
+
objc_sync_enter(stateLock); defer { objc_sync_exit(stateLock) }
|
|
125
129
|
NSLog("[FlirManager] stopDiscovery")
|
|
126
130
|
|
|
127
131
|
#if FLIR_ENABLED
|
|
@@ -133,6 +137,7 @@ import ThermalSDK
|
|
|
133
137
|
// MARK: - Connection
|
|
134
138
|
|
|
135
139
|
@objc public func connectToDevice(_ deviceId: String) {
|
|
140
|
+
objc_sync_enter(stateLock); defer { objc_sync_exit(stateLock) }
|
|
136
141
|
NSLog("[FlirManager] connectToDevice: \(deviceId)")
|
|
137
142
|
|
|
138
143
|
#if FLIR_ENABLED
|
|
@@ -270,10 +275,11 @@ import ThermalSDK
|
|
|
270
275
|
}
|
|
271
276
|
|
|
272
277
|
@objc public func disconnect() {
|
|
278
|
+
objc_sync_enter(stateLock); defer { objc_sync_exit(stateLock) }
|
|
273
279
|
NSLog("[FlirManager] disconnect")
|
|
274
280
|
|
|
275
281
|
#if FLIR_ENABLED
|
|
276
|
-
|
|
282
|
+
stopStreamInternalSync()
|
|
277
283
|
camera?.disconnect()
|
|
278
284
|
camera = nil
|
|
279
285
|
_isConnected = false
|
|
@@ -289,9 +295,36 @@ import ThermalSDK
|
|
|
289
295
|
}
|
|
290
296
|
|
|
291
297
|
@objc public func stop() {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
298
|
+
objc_sync_enter(stateLock); defer { objc_sync_exit(stateLock) }
|
|
299
|
+
stopStreamInternalSync()
|
|
300
|
+
disconnectInternalSync()
|
|
301
|
+
stopDiscoveryInternalSync()
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
private func stopDiscoveryInternalSync() {
|
|
305
|
+
NSLog("[FlirManager] stopDiscovery")
|
|
306
|
+
#if FLIR_ENABLED
|
|
307
|
+
discovery?.stop()
|
|
308
|
+
emitStateChange("idle")
|
|
309
|
+
#endif
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
private func disconnectInternalSync() {
|
|
313
|
+
NSLog("[FlirManager] disconnect")
|
|
314
|
+
#if FLIR_ENABLED
|
|
315
|
+
stopStreamInternalSync()
|
|
316
|
+
camera?.disconnect()
|
|
317
|
+
camera = nil
|
|
318
|
+
_isConnected = false
|
|
319
|
+
connectedDeviceId = nil
|
|
320
|
+
connectedDeviceName = nil
|
|
321
|
+
_latestImage = nil
|
|
322
|
+
|
|
323
|
+
DispatchQueue.main.async { [weak self] in
|
|
324
|
+
self?.delegate?.onDeviceDisconnected()
|
|
325
|
+
self?.emitStateChange("disconnected")
|
|
326
|
+
}
|
|
327
|
+
#endif
|
|
295
328
|
}
|
|
296
329
|
|
|
297
330
|
// MARK: - Streaming
|
|
@@ -345,13 +378,18 @@ import ThermalSDK
|
|
|
345
378
|
#endif
|
|
346
379
|
|
|
347
380
|
@objc public func stopStream() {
|
|
381
|
+
objc_sync_enter(stateLock); defer { objc_sync_exit(stateLock) }
|
|
382
|
+
stopStreamInternalSync()
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
private func stopStreamInternalSync() {
|
|
348
386
|
NSLog("[FlirManager] stopStream")
|
|
349
387
|
|
|
350
388
|
#if FLIR_ENABLED
|
|
389
|
+
_isStreaming = false
|
|
351
390
|
stream?.stop()
|
|
352
391
|
stream = nil
|
|
353
392
|
streamer = nil
|
|
354
|
-
_isStreaming = false
|
|
355
393
|
_latestImage = nil
|
|
356
394
|
|
|
357
395
|
if _isConnected {
|
|
@@ -637,14 +675,18 @@ extension FlirManager: FLIRStreamDelegate {
|
|
|
637
675
|
|
|
638
676
|
NSLog("[FLIR-TRACE 2️⃣] Processing on renderQueue")
|
|
639
677
|
|
|
678
|
+
objc_sync_enter(self.stateLock)
|
|
679
|
+
let currentStreamer = self.streamer
|
|
680
|
+
let streaming = self._isStreaming
|
|
681
|
+
objc_sync_exit(self.stateLock)
|
|
682
|
+
|
|
683
|
+
guard streaming, let streamer = currentStreamer else {
|
|
684
|
+
return
|
|
685
|
+
}
|
|
686
|
+
|
|
640
687
|
do {
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
try streamer.update()
|
|
644
|
-
NSLog("[FLIR-TRACE 3️⃣] Streamer updated successfully")
|
|
645
|
-
} else {
|
|
646
|
-
return
|
|
647
|
-
}
|
|
688
|
+
try streamer.update()
|
|
689
|
+
NSLog("[FLIR-TRACE 3️⃣] Streamer updated successfully")
|
|
648
690
|
} catch {
|
|
649
691
|
NSLog("[FLIR-TRACE ❌] Streamer update failed: \(error)")
|
|
650
692
|
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,7 @@ 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));
|
|
477
479
|
});
|
|
478
480
|
}
|
|
479
481
|
|
|
@@ -487,7 +489,7 @@ RCT_EXPORT_METHOD(isPreferSdkRotation : (RCTPromiseResolveBlock)
|
|
|
487
489
|
v = ((BOOL (*)(id, SEL))objc_msgSend)(
|
|
488
490
|
manager, sel_registerName("isPreferSdkRotation"));
|
|
489
491
|
}
|
|
490
|
-
resolve(@(v));
|
|
492
|
+
if (resolve) resolve(@(v));
|
|
491
493
|
});
|
|
492
494
|
}
|
|
493
495
|
|