ilabs-flir 2.1.0 → 2.1.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.
@@ -169,6 +169,28 @@ RCT_EXPORT_METHOD(startDiscovery:(RCTPromiseResolveBlock)resolve
169
169
  self.isScanning = YES;
170
170
  [self.discoveredDevices removeAllObjects];
171
171
  [self.identityMap removeAllObjects];
172
+
173
+ // Always expose emulator options to JS/UI so the user can connect even when
174
+ // physical devices are not present.
175
+ NSDictionary *emuOne = @{
176
+ @"id": @"emu:FLIR_ONE",
177
+ @"name": @"FLIR One Emulator",
178
+ @"communicationType": @"EMULATOR",
179
+ @"isEmulator": @(YES)
180
+ };
181
+ NSDictionary *emuEdge = @{
182
+ @"id": @"emu:FLIR_ONE_EDGE",
183
+ @"name": @"FLIR One Edge Emulator",
184
+ @"communicationType": @"EMULATOR",
185
+ @"isEmulator": @(YES)
186
+ };
187
+ [self.discoveredDevices addObjectsFromArray:@[ emuOne, emuEdge ]];
188
+
189
+ NSDictionary *initialDevicesBody = @{
190
+ @"devices": self.discoveredDevices,
191
+ @"count": @(self.discoveredDevices.count)
192
+ };
193
+ [[FlirEventEmitter shared] sendDeviceEvent:@"FlirDevicesFound" body:initialDevicesBody];
172
194
 
173
195
  if (!self.discovery) {
174
196
  self.discovery = [[FLIRDiscovery alloc] init];
@@ -184,6 +206,26 @@ RCT_EXPORT_METHOD(startDiscovery:(RCTPromiseResolveBlock)resolve
184
206
 
185
207
  [self emitStateChange:@"discovering"];
186
208
  RCTLogInfo(@"[FlirModule] Discovery started");
209
+
210
+ __weak typeof(self) weakSelf = self;
211
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
212
+ __strong typeof(self) strongSelf = weakSelf;
213
+ if (!strongSelf) return;
214
+ if (!strongSelf.isScanning || strongSelf.isConnected) return;
215
+
216
+ BOOL hasRealDevice = NO;
217
+ for (NSDictionary *dev in strongSelf.discoveredDevices) {
218
+ NSString *did = dev[@"id"];
219
+ if (did.length > 0 && ![did hasPrefix:@"emu:"]) {
220
+ hasRealDevice = YES;
221
+ break;
222
+ }
223
+ }
224
+ if (!hasRealDevice) {
225
+ [strongSelf emitStateChange:@"no_device_found"];
226
+ }
227
+ });
228
+
187
229
  resolve(@(YES));
188
230
  });
189
231
  #else
@@ -219,6 +261,36 @@ RCT_EXPORT_METHOD(connectToDevice:(NSString *)deviceId
219
261
  rejecter:(RCTPromiseRejectBlock)reject) {
220
262
  #if FLIR_SDK_AVAILABLE
221
263
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
264
+ // Synthetic emulator ids exposed during discovery.
265
+ if ([deviceId hasPrefix:@"emu:"]) {
266
+ NSString *typePart = [deviceId substringFromIndex:4];
267
+ FLIRCameraType cameraType = FLIRCameraType_flirOne;
268
+ if ([typePart.lowercaseString containsString:@"edge"]) {
269
+ cameraType = FLIRCameraType_flirOneEdge;
270
+ }
271
+
272
+ FLIRIdentity *emulatorIdentity = [[FLIRIdentity alloc] initWithEmulatorType:cameraType];
273
+ if (!emulatorIdentity) {
274
+ dispatch_async(dispatch_get_main_queue(), ^{
275
+ reject(@"ERR_EMULATOR_INIT", @"Failed to create emulator identity", nil);
276
+ });
277
+ return;
278
+ }
279
+
280
+ self.identityMap[[emulatorIdentity deviceId]] = emulatorIdentity;
281
+
282
+ [self performConnectionWithIdentity:emulatorIdentity completion:^(BOOL success, NSError *error) {
283
+ dispatch_async(dispatch_get_main_queue(), ^{
284
+ if (success) {
285
+ resolve(@(YES));
286
+ } else {
287
+ reject(@"ERR_CONNECTION_FAILED", error.localizedDescription ?: @"Connection failed", error);
288
+ }
289
+ });
290
+ }];
291
+ return;
292
+ }
293
+
222
294
  FLIRIdentity *identity = self.identityMap[deviceId];
223
295
  if (!identity) {
224
296
  dispatch_async(dispatch_get_main_queue(), ^{
@@ -269,7 +341,15 @@ RCT_EXPORT_METHOD(connectToDevice:(NSString *)deviceId
269
341
  if (connected) {
270
342
  self.connectedIdentity = identity;
271
343
  self.connectedDeviceId = [identity deviceId];
272
- self.connectedDeviceName = [identity deviceId];
344
+ NSString *displayName = [identity deviceId];
345
+ if ([identity communicationInterface] == FLIRCommunicationInterfaceEmulator) {
346
+ if ([identity cameraType] == FLIRCameraType_flirOneEdge || [identity cameraType] == FLIRCameraType_flirOneEdgePro) {
347
+ displayName = @"FLIR One Edge Emulator";
348
+ } else {
349
+ displayName = @"FLIR One Emulator";
350
+ }
351
+ }
352
+ self.connectedDeviceName = displayName;
273
353
  self.isConnected = YES;
274
354
 
275
355
  RCTLogInfo(@"[FlirModule] Connected to: %@", [identity deviceId]);
@@ -284,7 +364,6 @@ RCT_EXPORT_METHOD(connectToDevice:(NSString *)deviceId
284
364
 
285
365
  dispatch_async(dispatch_get_main_queue(), ^{
286
366
  [self emitDeviceConnected];
287
- [self emitStateChange:@"connected"];
288
367
  });
289
368
 
290
369
  if (completion) completion(YES, nil);
@@ -613,23 +692,20 @@ RCT_EXPORT_METHOD(isPreferSdkRotation:(RCTPromiseResolveBlock)resolve
613
692
  #pragma mark - Helper Methods
614
693
 
615
694
  - (void)emitDeviceConnected {
616
- BOOL isEmu = [self.connectedDeviceName.lowercaseString containsString:@"emulator"];
617
-
618
- NSDictionary *body = @{
619
- @"identity": @{
620
- @"deviceId": self.connectedDeviceId ?: @"Unknown",
621
- @"isEmulator": @(isEmu)
622
- },
623
- @"deviceType": isEmu ? @"emulator" : @"device",
624
- @"isEmulator": @(isEmu),
625
- @"state": @"connected"
626
- };
627
-
628
- [[FlirEventEmitter shared] sendDeviceEvent:@"FlirDeviceConnected" body:body];
695
+ [self emitStateChange:@"connected"];
629
696
  }
630
697
 
631
698
  - (void)emitStateChange:(NSString *)state {
632
- BOOL isEmu = [self.connectedDeviceName.lowercaseString containsString:@"emulator"];
699
+ BOOL isEmu = NO;
700
+ #if FLIR_SDK_AVAILABLE
701
+ if (self.connectedIdentity) {
702
+ isEmu = ([self.connectedIdentity communicationInterface] == FLIRCommunicationInterfaceEmulator);
703
+ } else {
704
+ isEmu = [self.connectedDeviceName.lowercaseString containsString:@"emulator"];
705
+ }
706
+ #else
707
+ isEmu = [self.connectedDeviceName.lowercaseString containsString:@"emulator"];
708
+ #endif
633
709
 
634
710
  NSDictionary *body = @{
635
711
  @"state": state,
@@ -637,9 +713,17 @@ RCT_EXPORT_METHOD(isPreferSdkRotation:(RCTPromiseResolveBlock)resolve
637
713
  @"isStreaming": @(self.isStreaming),
638
714
  @"isEmulator": @(isEmu),
639
715
  @"deviceName": self.connectedDeviceName ?: @"",
640
- @"deviceId": self.connectedDeviceId ?: @""
716
+ @"deviceId": self.connectedDeviceId ?: @"",
717
+ @"identity": @{
718
+ @"deviceId": self.connectedDeviceId ?: @"",
719
+ @"isEmulator": @(isEmu)
720
+ }
641
721
  };
642
-
722
+
723
+ // App JS listens for FlirDeviceConnected state transitions.
724
+ [[FlirEventEmitter shared] sendDeviceEvent:@"FlirDeviceConnected" body:body];
725
+
726
+ // Keep legacy event for backwards compatibility.
643
727
  [[FlirEventEmitter shared] sendDeviceEvent:@"FlirStateChanged" body:body];
644
728
  }
645
729
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ilabs-flir",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "FLIR Thermal SDK for React Native - iOS & Android (bundled at compile time via postinstall)",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",