ilabs-flir 2.0.8 → 2.0.9
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.
|
@@ -111,7 +111,7 @@ import ThermalSDK
|
|
|
111
111
|
#if FLIR_ENABLED
|
|
112
112
|
guard let streamer = streamer else { return nil }
|
|
113
113
|
var result: [String: Any]? = nil
|
|
114
|
-
streamer.withThermalImage { thermalImage in
|
|
114
|
+
streamer.withThermalImage { [weak self] thermalImage in
|
|
115
115
|
// Attempt to extract per-pixel measurements if available
|
|
116
116
|
if let measurements = thermalImage.measurements as? [NSNumber],
|
|
117
117
|
measurements.count > 0,
|
|
@@ -127,8 +127,8 @@ import ThermalSDK
|
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
// Fallback: use lastTemperature if set
|
|
130
|
-
if result == nil
|
|
131
|
-
result = ["temperature": lastTemperature]
|
|
130
|
+
if result == nil, let s = self, !s.lastTemperature.isNaN {
|
|
131
|
+
result = ["temperature": s.lastTemperature]
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
return result
|
|
@@ -227,17 +227,35 @@ import ThermalSDK
|
|
|
227
227
|
return
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
230
|
+
// Use runtime-safe APIs to find and set palette to avoid compile-time
|
|
231
|
+
// coupling to specific SDK versions. Try FLIRPaletteManager.defaultPalettes
|
|
232
|
+
// via ObjC runtime, then attempt a KVC set on the returned image if possible.
|
|
233
|
+
if let pmClass = NSClassFromString("FLIRPaletteManager") as AnyObject?, pmClass.responds(to: Selector(("default"))) {
|
|
234
|
+
if let pmInstance = pmClass.perform(Selector(("default")))?.takeUnretainedValue() as? NSObject,
|
|
235
|
+
pmInstance.responds(to: Selector(("getDefaultPalettes"))) {
|
|
236
|
+
if let arr = pmInstance.perform(Selector(("getDefaultPalettes")))?.takeUnretainedValue() as? NSArray {
|
|
237
|
+
for palette in arr {
|
|
238
|
+
if let p = palette as? NSObject,
|
|
239
|
+
let name = p.value(forKey: "name") as? String,
|
|
240
|
+
name.lowercased() == paletteName.lowercased() {
|
|
241
|
+
if let imgObj = thermalImage as? NSObject {
|
|
242
|
+
// Try both 'palette' and 'Palette' keys depending on SDK
|
|
243
|
+
if imgObj.responds(to: Selector(("setPalette:"))) {
|
|
244
|
+
imgObj.perform(Selector(("setPalette:")), with: p)
|
|
245
|
+
} else {
|
|
246
|
+
imgObj.setValue(p, forKey: "Palette")
|
|
247
|
+
}
|
|
248
|
+
NSLog("[FlirManager] ✅ Palette set to: \(paletteName)")
|
|
249
|
+
return
|
|
250
|
+
}
|
|
251
|
+
}
|
|
236
252
|
}
|
|
253
|
+
NSLog("[FlirManager] Palette not found: \(paletteName)")
|
|
254
|
+
} else {
|
|
255
|
+
NSLog("[FlirManager] Palette manager returned unexpected type")
|
|
237
256
|
}
|
|
238
|
-
NSLog("[FlirManager] Palette not found: \(paletteName)")
|
|
239
257
|
} else {
|
|
240
|
-
NSLog("[FlirManager] SDK not available - cannot set palette")
|
|
258
|
+
NSLog("[FlirManager] SDK palette APIs not available - cannot set palette")
|
|
241
259
|
}
|
|
242
260
|
#else
|
|
243
261
|
NSLog("[FlirManager] SDK not available - cannot set palette")
|
|
@@ -366,15 +384,34 @@ import ThermalSDK
|
|
|
366
384
|
}
|
|
367
385
|
}
|
|
368
386
|
|
|
369
|
-
// Connect
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
387
|
+
// Connect (support multiple SDK signatures via ObjC runtime)
|
|
388
|
+
var connectedOK = false
|
|
389
|
+
if let cam = camera {
|
|
390
|
+
if cam.responds(to: Selector(("connect:error:"))) {
|
|
391
|
+
// Call connect:identity error:nil (ignore NSError pointer for compatibility)
|
|
392
|
+
_ = cam.perform(Selector(("connect:error:")), with: identity, with: nil)
|
|
393
|
+
connectedOK = true
|
|
394
|
+
} else if cam.responds(to: Selector(("connect:"))) {
|
|
395
|
+
_ = cam.perform(Selector(("connect:")), with: identity)
|
|
396
|
+
connectedOK = true
|
|
397
|
+
} else {
|
|
398
|
+
NSLog("[FlirManager] No compatible connect API on FLIRCamera")
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if connectedOK {
|
|
403
|
+
connectedIdentity = identity
|
|
404
|
+
connectedDeviceId = identity.deviceId()
|
|
405
|
+
connectedDeviceName = identity.deviceId()
|
|
406
|
+
_isConnected = true
|
|
407
|
+
NSLog("[FlirManager] Connected to: \(identity.deviceId())")
|
|
408
|
+
} else {
|
|
409
|
+
NSLog("[FlirManager] Connection failed: no compatible connect API")
|
|
410
|
+
DispatchQueue.main.async { [weak self] in
|
|
411
|
+
self?.delegate?.onError("Connection failed: unsupported SDK API")
|
|
412
|
+
}
|
|
413
|
+
return
|
|
414
|
+
}
|
|
378
415
|
|
|
379
416
|
// Get streams
|
|
380
417
|
if let streams = camera?.getStreams(), !streams.isEmpty {
|
|
@@ -424,7 +461,7 @@ import ThermalSDK
|
|
|
424
461
|
if iface.contains(.network) { return "NETWORK" }
|
|
425
462
|
if iface.contains(.flirOneWireless) { return "WIRELESS" }
|
|
426
463
|
if iface.contains(.emulator) { return "EMULATOR" }
|
|
427
|
-
if iface.contains(
|
|
464
|
+
if String(describing: iface).lowercased().contains("usb") { return "USB" }
|
|
428
465
|
return "UNKNOWN"
|
|
429
466
|
}
|
|
430
467
|
#endif
|
|
@@ -736,10 +773,23 @@ extension FlirManager: FLIRStreamDelegate {
|
|
|
736
773
|
if let image = streamer.getImage() {
|
|
737
774
|
_latestImage = image
|
|
738
775
|
|
|
739
|
-
// Get temperature from thermal image
|
|
776
|
+
// Get temperature from thermal image (use runtime selectors to be resilient across SDK versions)
|
|
740
777
|
streamer.withThermalImage { [weak self] thermalImage in
|
|
741
|
-
|
|
742
|
-
|
|
778
|
+
var tempVal: Double = Double.nan
|
|
779
|
+
// Try getImageStatistics then fallback to getStatistics (different SDK versions)
|
|
780
|
+
if let statsObj = (thermalImage.perform(Selector(("getImageStatistics")))?.takeUnretainedValue() as? NSObject) ?? (thermalImage.perform(Selector(("getStatistics")))?.takeUnretainedValue() as? NSObject) {
|
|
781
|
+
if statsObj.responds(to: Selector(("getMax"))) {
|
|
782
|
+
if let maxObj = statsObj.perform(Selector(("getMax")))?.takeUnretainedValue() as? NSObject,
|
|
783
|
+
let val = maxObj.value(forKey: "value") as? Double {
|
|
784
|
+
tempVal = val
|
|
785
|
+
}
|
|
786
|
+
} else if let maxVal = statsObj.value(forKey: "max") as? NSObject,
|
|
787
|
+
let val = maxVal.value(forKey: "value") as? Double {
|
|
788
|
+
tempVal = val
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
if !tempVal.isNaN {
|
|
792
|
+
self?.lastTemperature = tempVal
|
|
743
793
|
}
|
|
744
794
|
}
|
|
745
795
|
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
#import <React/RCTLog.h>
|
|
13
13
|
#import <React/RCTBridge.h>
|
|
14
14
|
#import <objc/message.h>
|
|
15
|
+
#import <objc/runtime.h>
|
|
15
16
|
|
|
16
17
|
#if __has_include(<ThermalSDK/ThermalSDK.h>)
|
|
17
18
|
#define FLIR_SDK_AVAILABLE 1
|
|
@@ -796,7 +797,13 @@ RCT_EXPORT_METHOD(isPreferSdkRotation:(RCTPromiseResolveBlock)resolve
|
|
|
796
797
|
|
|
797
798
|
// Get temperature from thermal image if available
|
|
798
799
|
[self.streamer withThermalImage:^(FLIRThermalImage *thermalImage) {
|
|
799
|
-
|
|
800
|
+
// Some SDK versions call getImageStatistics(), try both selectors
|
|
801
|
+
FLIRImageStatistics *stats = nil;
|
|
802
|
+
if ([thermalImage respondsToSelector:sel_registerName("getImageStatistics")]) {
|
|
803
|
+
stats = ((id (*)(id, SEL))objc_msgSend)((id)thermalImage, sel_registerName("getImageStatistics"));
|
|
804
|
+
} else if ([thermalImage respondsToSelector:sel_registerName("getStatistics")]) {
|
|
805
|
+
stats = ((id (*)(id, SEL))objc_msgSend)((id)thermalImage, sel_registerName("getStatistics"));
|
|
806
|
+
}
|
|
800
807
|
if (stats) {
|
|
801
808
|
self.lastTemperature = [[stats getMax] value];
|
|
802
809
|
[FlirState shared].lastTemperature = self.lastTemperature;
|