ilabs-flir 2.2.14 → 2.2.16
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.
|
@@ -53,6 +53,16 @@ object FlirManager {
|
|
|
53
53
|
fun setTextureCallback(callback: TextureUpdateCallback?) {
|
|
54
54
|
textureCallback = callback
|
|
55
55
|
}
|
|
56
|
+
|
|
57
|
+
interface TemperatureUpdateCallback {
|
|
58
|
+
fun onTemperatureUpdate(temperature: Double)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private var temperatureCallback: TemperatureUpdateCallback? = null
|
|
62
|
+
|
|
63
|
+
fun setTemperatureCallback(callback: TemperatureUpdateCallback?) {
|
|
64
|
+
temperatureCallback = callback
|
|
65
|
+
}
|
|
56
66
|
|
|
57
67
|
fun getLatestBitmap(): Bitmap? = latestBitmap
|
|
58
68
|
|
|
@@ -130,6 +140,10 @@ object FlirManager {
|
|
|
130
140
|
emitError("Device not found: $deviceId")
|
|
131
141
|
}
|
|
132
142
|
}
|
|
143
|
+
|
|
144
|
+
fun switchToDevice(deviceId: String) {
|
|
145
|
+
connectToDevice(deviceId)
|
|
146
|
+
}
|
|
133
147
|
|
|
134
148
|
/**
|
|
135
149
|
* Disconnect
|
|
@@ -241,6 +255,13 @@ object FlirManager {
|
|
|
241
255
|
return
|
|
242
256
|
}
|
|
243
257
|
|
|
258
|
+
// THROTTLE: Limit to ~15 FPS to prevent UI thread flooding
|
|
259
|
+
val now = System.currentTimeMillis()
|
|
260
|
+
if (now - lastEmitMs.get() < 66) { // 66ms ~= 15 FPS
|
|
261
|
+
return
|
|
262
|
+
}
|
|
263
|
+
lastEmitMs.set(now)
|
|
264
|
+
|
|
244
265
|
latestBitmap = bitmap
|
|
245
266
|
|
|
246
267
|
// If this is the first frame, notify JS that we are now streaming
|
|
@@ -249,16 +270,18 @@ object FlirManager {
|
|
|
249
270
|
emitDeviceState("streaming")
|
|
250
271
|
}
|
|
251
272
|
|
|
252
|
-
// NON-BLOCKING TEXTURE UPDATE
|
|
273
|
+
// NON-BLOCKING TEXTURE UPDATE
|
|
253
274
|
if (textureCallback != null) {
|
|
275
|
+
// We use try-lock to ensure we don't pile up parallel calls,
|
|
276
|
+
// though usually onFrame is serial.
|
|
254
277
|
if (isUpdatingTexture.compareAndSet(false, true)) {
|
|
255
278
|
try {
|
|
256
279
|
textureCallback?.onTextureUpdate(bitmap, 0)
|
|
280
|
+
} catch (e: Exception) {
|
|
281
|
+
Log.e(TAG, "Texture update failed", e)
|
|
257
282
|
} finally {
|
|
258
283
|
isUpdatingTexture.set(false)
|
|
259
284
|
}
|
|
260
|
-
} else {
|
|
261
|
-
// Log.v(TAG, "Dropping frame - texture update busy")
|
|
262
285
|
}
|
|
263
286
|
}
|
|
264
287
|
|
|
@@ -52,6 +52,10 @@ import ThermalSDK
|
|
|
52
52
|
@objc public class FlirManager: NSObject {
|
|
53
53
|
@objc public static let shared = FlirManager()
|
|
54
54
|
|
|
55
|
+
// MARK: - Singleton
|
|
56
|
+
|
|
57
|
+
@objc public static let shared = FlirManager()
|
|
58
|
+
|
|
55
59
|
// MARK: - Properties
|
|
56
60
|
@objc public weak var delegate: FlirManagerDelegate?
|
|
57
61
|
|
|
@@ -307,10 +311,13 @@ import ThermalSDK
|
|
|
307
311
|
|
|
308
312
|
if let measurements = thermalImage.measurements,
|
|
309
313
|
let spot = try? measurements.addSpot(CGPoint(x: cx, y: cy)) {
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
+
|
|
315
|
+
// getValue() returns non-optional in some SDK versions, or optional in others.
|
|
316
|
+
// Compiler says it is NOT optional here, so direct assignment.
|
|
317
|
+
let value = spot.getValue()
|
|
318
|
+
result = value.value
|
|
319
|
+
|
|
320
|
+
try? measurements.remove(spot)
|
|
314
321
|
}
|
|
315
322
|
}
|
|
316
323
|
return result
|
|
@@ -361,9 +368,35 @@ import ThermalSDK
|
|
|
361
368
|
|
|
362
369
|
// MARK: - Battery (stub - not needed per user)
|
|
363
370
|
|
|
371
|
+
// MARK: - Battery (stub - not needed per user)
|
|
372
|
+
|
|
364
373
|
@objc public func getBatteryLevel() -> Int { return -1 }
|
|
365
374
|
@objc public func isBatteryCharging() -> Bool { return false }
|
|
366
375
|
|
|
376
|
+
// MARK: - Shim Compatibility
|
|
377
|
+
|
|
378
|
+
@objc public static var isSDKAvailable: Bool {
|
|
379
|
+
return true
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
@objc public func setPalette(_ name: String) {
|
|
383
|
+
// stub
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
@objc public func setPaletteFromAcol(_ acol: Float) {
|
|
387
|
+
// stub
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
@objc public func retainClient(_ clientId: String) {
|
|
391
|
+
// simplified manager doesn't track retain counts per client yet
|
|
392
|
+
startDiscovery()
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
@objc public func releaseClient(_ clientId: String) {
|
|
396
|
+
// simplified manager doesn't track retain counts per client yet
|
|
397
|
+
// stopDiscovery() // Optional: could stop if count == 0
|
|
398
|
+
}
|
|
399
|
+
|
|
367
400
|
// MARK: - Helpers
|
|
368
401
|
|
|
369
402
|
private func emitStateChange(_ state: String) {
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
//
|
|
8
8
|
|
|
9
9
|
#import "FlirModule.h"
|
|
10
|
+
|
|
10
11
|
#import "FlirEventEmitter.h"
|
|
11
12
|
#import "FlirState.h"
|
|
12
13
|
#import <React/RCTBridge.h>
|
|
@@ -309,7 +310,8 @@ RCT_EXPORT_METHOD(getTemperatureAt : (nonnull NSNumber *)x y : (
|
|
|
309
310
|
nonnull NSNumber *)y resolver : (RCTPromiseResolveBlock)
|
|
310
311
|
resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
311
312
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
312
|
-
double temp =
|
|
313
|
+
double temp = [[FLIRManager shared] getTemperatureAtPoint:[x intValue]
|
|
314
|
+
y:[y intValue]];
|
|
313
315
|
if (isnan(temp)) {
|
|
314
316
|
resolve([NSNull null]);
|
|
315
317
|
} else {
|
|
@@ -404,7 +406,7 @@ RCT_EXPORT_METHOD(getSDKStatus : (RCTPromiseResolveBlock)
|
|
|
404
406
|
RCT_EXPORT_METHOD(getBatteryLevel : (RCTPromiseResolveBlock)
|
|
405
407
|
resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
406
408
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
407
|
-
int level =
|
|
409
|
+
int level = [[FLIRManager shared] getBatteryLevel];
|
|
408
410
|
resolve(@(level));
|
|
409
411
|
});
|
|
410
412
|
}
|
|
@@ -412,7 +414,7 @@ RCT_EXPORT_METHOD(getBatteryLevel : (RCTPromiseResolveBlock)
|
|
|
412
414
|
RCT_EXPORT_METHOD(isBatteryCharging : (RCTPromiseResolveBlock)
|
|
413
415
|
resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
414
416
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
415
|
-
BOOL ch =
|
|
417
|
+
BOOL ch = [[FLIRManager shared] isBatteryCharging];
|
|
416
418
|
resolve(@(ch));
|
|
417
419
|
});
|
|
418
420
|
}
|
|
@@ -420,7 +422,7 @@ RCT_EXPORT_METHOD(isBatteryCharging : (RCTPromiseResolveBlock)
|
|
|
420
422
|
RCT_EXPORT_METHOD(setPreferSdkRotation : (BOOL)prefer resolver : (
|
|
421
423
|
RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
422
424
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
423
|
-
|
|
425
|
+
[[FLIRManager shared] setPreferSdkRotation:prefer];
|
|
424
426
|
resolve(@(YES));
|
|
425
427
|
});
|
|
426
428
|
}
|
|
@@ -428,7 +430,7 @@ RCT_EXPORT_METHOD(setPreferSdkRotation : (BOOL)prefer resolver : (
|
|
|
428
430
|
RCT_EXPORT_METHOD(isPreferSdkRotation : (RCTPromiseResolveBlock)
|
|
429
431
|
resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
430
432
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
431
|
-
BOOL v =
|
|
433
|
+
BOOL v = [[FLIRManager shared] isPreferSdkRotation];
|
|
432
434
|
resolve(@(v));
|
|
433
435
|
});
|
|
434
436
|
}
|
package/package.json
CHANGED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
// ObjC shim to expose `FLIRManager` from the npm package and forward to `FlirManager` at runtime
|
|
2
|
-
#import <Foundation/Foundation.h>
|
|
3
|
-
#import <UIKit/UIKit.h>
|
|
4
|
-
|
|
5
|
-
NS_ASSUME_NONNULL_BEGIN
|
|
6
|
-
|
|
7
|
-
@interface FLIRManager : NSObject
|
|
8
|
-
|
|
9
|
-
+ (instancetype)shared;
|
|
10
|
-
|
|
11
|
-
- (BOOL)isAvailable;
|
|
12
|
-
- (double)getTemperatureAtPoint:(int)x y:(int)y;
|
|
13
|
-
- (double)getTemperatureAtNormalized:(double)nx y:(double)ny;
|
|
14
|
-
- (int)getBatteryLevel;
|
|
15
|
-
- (BOOL)isBatteryCharging;
|
|
16
|
-
- (void)setPreferSdkRotation:(BOOL)prefer;
|
|
17
|
-
- (BOOL)isPreferSdkRotation;
|
|
18
|
-
- (nullable UIImage *)latestFrameImage;
|
|
19
|
-
- (void)startDiscovery;
|
|
20
|
-
- (void)stopDiscovery;
|
|
21
|
-
|
|
22
|
-
@end
|
|
23
|
-
|
|
24
|
-
NS_ASSUME_NONNULL_END
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
// ObjC shim implementation forwarding to Swift `FlirManager` via runtime selectors
|
|
2
|
-
#import "FLIRManager.h"
|
|
3
|
-
#import <objc/message.h>
|
|
4
|
-
|
|
5
|
-
@implementation FLIRManager
|
|
6
|
-
|
|
7
|
-
+ (instancetype)shared {
|
|
8
|
-
Class cls = NSClassFromString(@"FlirManager");
|
|
9
|
-
if (!cls) return nil;
|
|
10
|
-
SEL sel = sel_registerName("shared");
|
|
11
|
-
if (![cls respondsToSelector:sel]) return nil;
|
|
12
|
-
id (*msgSend0)(id, SEL) = (id (*)(id, SEL))objc_msgSend;
|
|
13
|
-
return msgSend0((id)cls, sel);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
- (BOOL)isAvailable {
|
|
17
|
-
Class cls = NSClassFromString(@"FlirManager");
|
|
18
|
-
SEL sel = sel_registerName("isSDKAvailable");
|
|
19
|
-
if (!cls || ![cls respondsToSelector:sel]) return NO;
|
|
20
|
-
BOOL (*msgSend0)(id, SEL) = (BOOL (*)(id, SEL))objc_msgSend;
|
|
21
|
-
return msgSend0((id)cls, sel);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
- (double)getTemperatureAtPoint:(int)x y:(int)y {
|
|
25
|
-
id inst = [[self class] shared];
|
|
26
|
-
SEL sel = sel_registerName("getTemperatureAt: y:");
|
|
27
|
-
// Swift method name mangling may differ; fall back to method used by FlirModule
|
|
28
|
-
SEL selAlt = sel_registerName("getTemperatureAtPoint:y:");
|
|
29
|
-
SEL use = NULL;
|
|
30
|
-
if (inst && [inst respondsToSelector:sel]) use = sel;
|
|
31
|
-
if (inst && [inst respondsToSelector:selAlt]) use = selAlt;
|
|
32
|
-
if (!inst || !use) return NAN;
|
|
33
|
-
double (*msgSend2)(id, SEL, int, int) = (double (*)(id, SEL, int, int))objc_msgSend;
|
|
34
|
-
return msgSend2(inst, use, x, y);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
- (double)getTemperatureAtNormalized:(double)nx y:(double)ny {
|
|
38
|
-
id inst = [[self class] shared];
|
|
39
|
-
SEL sel = sel_registerName("getTemperatureAtNormalized:y:");
|
|
40
|
-
if (!inst || ![inst respondsToSelector:sel]) return NAN;
|
|
41
|
-
double (*msgSend2)(id, SEL, double, double) = (double (*)(id, SEL, double, double))objc_msgSend;
|
|
42
|
-
return msgSend2(inst, sel, nx, ny);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
- (int)getBatteryLevel {
|
|
46
|
-
id inst = [[self class] shared];
|
|
47
|
-
SEL sel = sel_registerName("getBatteryLevel");
|
|
48
|
-
if (!inst || ![inst respondsToSelector:sel]) return -1;
|
|
49
|
-
int (*msgSend0)(id, SEL) = (int (*)(id, SEL))objc_msgSend;
|
|
50
|
-
return msgSend0(inst, sel);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
- (BOOL)isBatteryCharging {
|
|
54
|
-
id inst = [[self class] shared];
|
|
55
|
-
SEL sel = sel_registerName("isBatteryCharging");
|
|
56
|
-
if (!inst || ![inst respondsToSelector:sel]) return NO;
|
|
57
|
-
BOOL (*msgSend0)(id, SEL) = (BOOL (*)(id, SEL))objc_msgSend;
|
|
58
|
-
return msgSend0(inst, sel);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
- (void)setPreferSdkRotation:(BOOL)prefer {
|
|
62
|
-
id inst = [[self class] shared];
|
|
63
|
-
SEL sel = sel_registerName("setPreferSdkRotation:");
|
|
64
|
-
if (!inst || ![inst respondsToSelector:sel]) return;
|
|
65
|
-
void (*msgSend1)(id, SEL, BOOL) = (void (*)(id, SEL, BOOL))objc_msgSend;
|
|
66
|
-
msgSend1(inst, sel, prefer);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
- (BOOL)isPreferSdkRotation {
|
|
70
|
-
id inst = [[self class] shared];
|
|
71
|
-
SEL sel = sel_registerName("isPreferSdkRotation");
|
|
72
|
-
if (!inst || ![inst respondsToSelector:sel]) return NO;
|
|
73
|
-
BOOL (*msgSend0)(id, SEL) = (BOOL (*)(id, SEL))objc_msgSend;
|
|
74
|
-
return msgSend0(inst, sel);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
- (nullable NSString *)latestFrameBase64 {
|
|
78
|
-
id inst = [[self class] shared];
|
|
79
|
-
SEL sel = sel_registerName("latestFrameBase64");
|
|
80
|
-
if (!inst || ![inst respondsToSelector:sel]) return nil;
|
|
81
|
-
id (*msgSend0)(id, SEL) = (id (*)(id, SEL))objc_msgSend;
|
|
82
|
-
return (NSString *)msgSend0(inst, sel);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
- (void)retainClient:(NSString *)clientId {
|
|
86
|
-
id inst = [[self class] shared];
|
|
87
|
-
SEL sel = sel_registerName("retainClient:");
|
|
88
|
-
if (!inst || ![inst respondsToSelector:sel]) return;
|
|
89
|
-
void (*msgSend1)(id, SEL, id) = (void (*)(id, SEL, id))objc_msgSend;
|
|
90
|
-
msgSend1(inst, sel, clientId);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
- (void)releaseClient:(NSString *)clientId {
|
|
94
|
-
id inst = [[self class] shared];
|
|
95
|
-
SEL sel = sel_registerName("releaseClient:");
|
|
96
|
-
if (!inst || ![inst respondsToSelector:sel]) return;
|
|
97
|
-
void (*msgSend1)(id, SEL, id) = (void (*)(id, SEL, id))objc_msgSend;
|
|
98
|
-
msgSend1(inst, sel, clientId);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
- (void)setPalette:(NSString *)paletteName {
|
|
102
|
-
id inst = [[self class] shared];
|
|
103
|
-
SEL sel = sel_registerName("setPalette:");
|
|
104
|
-
if (!inst || ![inst respondsToSelector:sel]) return;
|
|
105
|
-
void (*msgSend1)(id, SEL, id) = (void (*)(id, SEL, id))objc_msgSend;
|
|
106
|
-
msgSend1(inst, sel, paletteName);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
- (void)setPaletteFromAcol:(double)acol {
|
|
110
|
-
id inst = [[self class] shared];
|
|
111
|
-
SEL sel = sel_registerName("setPaletteFromAcol:");
|
|
112
|
-
if (!inst || ![inst respondsToSelector:sel]) return;
|
|
113
|
-
void (*msgSend1)(id, SEL, double) = (void (*)(id, SEL, double))objc_msgSend;
|
|
114
|
-
msgSend1(inst, sel, acol);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
- (nullable NSString *)getPaletteNameFromAcol:(double)acol {
|
|
118
|
-
Class cls = NSClassFromString(@"FlirManager");
|
|
119
|
-
SEL sel = sel_registerName("getPaletteNameFromAcol:");
|
|
120
|
-
if (!cls || ![cls respondsToSelector:sel]) return nil;
|
|
121
|
-
id (*msgSend1)(id, SEL, double) = (id (*)(id, SEL, double))objc_msgSend;
|
|
122
|
-
return (NSString *)msgSend1((id)cls, sel, acol);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
- (nullable UIImage *)latestFrameImage {
|
|
126
|
-
id inst = [[self class] shared];
|
|
127
|
-
SEL sel = sel_registerName("latestImage");
|
|
128
|
-
SEL selAlt = sel_registerName("latestFrameImage");
|
|
129
|
-
SEL use = NULL;
|
|
130
|
-
if (inst && [inst respondsToSelector:selAlt]) use = selAlt;
|
|
131
|
-
else if (inst && [inst respondsToSelector:sel]) use = sel;
|
|
132
|
-
if (!inst || !use) return nil;
|
|
133
|
-
id (*msgSend0)(id, SEL) = (id (*)(id, SEL))objc_msgSend;
|
|
134
|
-
return (UIImage *)msgSend0(inst, use);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
- (void)startDiscovery {
|
|
138
|
-
id inst = [[self class] shared];
|
|
139
|
-
SEL sel = sel_registerName("startDiscovery");
|
|
140
|
-
if (!inst || ![inst respondsToSelector:sel]) return;
|
|
141
|
-
void (*msgSend0)(id, SEL) = (void (*)(id, SEL))objc_msgSend;
|
|
142
|
-
msgSend0(inst, sel);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
- (void)stopDiscovery {
|
|
146
|
-
id inst = [[self class] shared];
|
|
147
|
-
SEL sel = sel_registerName("stopDiscovery");
|
|
148
|
-
if (!inst || ![inst respondsToSelector:sel]) return;
|
|
149
|
-
void (*msgSend0)(id, SEL) = (void (*)(id, SEL))objc_msgSend;
|
|
150
|
-
msgSend0(inst, sel);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
@end
|