From d6d9a09d505d11148599a95a5be3e1351edbe0ac Mon Sep 17 00:00:00 2001 From: hc Date: Mon, 13 Apr 2026 15:17:52 +0800 Subject: Local iHealth SDK, device detail screen, iOS event fixes --- .../ios/ReactNativeIOSLibrary/BG5SModule.m | 529 +++++++++++++++++++++ 1 file changed, 529 insertions(+) create mode 100644 libs/ihealth-sdk/ios/ReactNativeIOSLibrary/BG5SModule.m (limited to 'libs/ihealth-sdk/ios/ReactNativeIOSLibrary/BG5SModule.m') diff --git a/libs/ihealth-sdk/ios/ReactNativeIOSLibrary/BG5SModule.m b/libs/ihealth-sdk/ios/ReactNativeIOSLibrary/BG5SModule.m new file mode 100644 index 0000000..0857956 --- /dev/null +++ b/libs/ihealth-sdk/ios/ReactNativeIOSLibrary/BG5SModule.m @@ -0,0 +1,529 @@ +// +// BG5SModule.m +// ReactNativeIOSLibrary +// +// Created by soso on 2019/4/24. +// Copyright © 2019 daiqingquan. All rights reserved. +// + +#import "BG5SModule.h" + +#import "BG5SProfileModule.h" +#import "BGMacroFile.h" +#import "BG5SController.h" +#import "BG5S.h" +#import "ManageDeviceController.h" + + +#define EVENT_NOTIFY @"event_notify_bg5s" +#define kMAC_KEY @"mac" +#define kACTION_KEY @"action" + +#define kFUNCTION_BatteryValue @"batteryValue" +#define kFUNCTION_DeviceDate @"deviceDate" +#define kFUNCTION_DeviceTimeZone @"deviceTimeZone" +#define kFUNCTION_StripUsedValue @"stripUsedValue" +#define kFUNCTION_OfflineDataQuantity @"offlineDataQuantity" +#define kFUNCTION_BloodCodeVersion @"bloodCodeVersion" +#define kFUNCTION_CtlCodeVersion @"ctlCodeVersion" +#define kFUNCTION_Unit @"unit" + + +@interface BG5SModule () +@property (nonatomic, assign) BOOL isMeasuring; + +@end +@implementation BG5SModule +RCT_EXPORT_MODULE() +- (NSArray *)supportedEvents { + return @[@"event_notify", @"event_scan_device", @"event_scan_finish", + @"event_device_connected", @"event_device_connect_failed", + @"event_device_disconnect", @"event_authenticate_result", + @"event_notify_ts28b", @"event_notify_bg1", + @"action_connect_result_for_bg1"]; +} + + +- (NSDictionary *)constantsToExport +{ + return @{ @"Event_Notify": EVENT_NOTIFY }; +} + ++ (BOOL)requiresMainQueueSetup +{ + return YES; +} + + +-(BG5S*)getDeviceWithMac:(NSString*)mac{ + + BG5SController *controller = [BG5SController sharedController]; + NSArray *bgDeviceArray = [controller getAllCurrentInstace]; + + for(BG5S *tempDevice in bgDeviceArray){ + if([mac isEqualToString:tempDevice.serialNumber]){ + tempDevice.delegate = self; + return tempDevice; + } + } + return nil; +} + +RCT_EXPORT_METHOD(getAllConnectedDevices){ + + + NSArray*bgDeviceArray= [[BG5SController sharedController] getAllCurrentInstace]; + + NSMutableArray*deviceMacArray=[NSMutableArray array]; + + for (int i=0; i<[bgDeviceArray count]; i++) { + + BG5S *bg5s = [bgDeviceArray objectAtIndex:i]; + + [deviceMacArray addObject:bg5s.serialNumber]; + + } + + NSDictionary* deviceInfo = @{kACTION_KEY:@"ACTION_GET_ALL_CONNECTED_DEVICES",@"devices":deviceMacArray}; + + [self sendEventWithName:EVENT_NOTIFY body:deviceInfo]; +} + + +//综合查询 +RCT_EXPORT_METHOD(getStatusInfo:(nonnull NSString *)mac){ + + if ([self getDeviceWithMac:mac]!=nil) { + __weak typeof(self) weakSelf = self; + [[self getDeviceWithMac:mac] queryStateInfoWithSuccess:^(BG5SStateInfo *stateInfo) { + + + NSDateFormatter *mydateFormatter = [[NSDateFormatter alloc] init]; + [mydateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; + NSString *dateStr = [mydateFormatter stringFromDate:stateInfo.deviceDate]; + + NSDictionary* response = @{ + kMAC_KEY:mac, + kACTION_KEY:kACTION_GET_STATUS_INFO, + INFO_BATTERY_LEVEL:@(stateInfo.batteryValue), + INFO_TIME:dateStr, + INFO_TIMEZONE:@(stateInfo.deviceTimeZone), + INFO_USED_STRIP:@(stateInfo.stripUsedValue), + INFO_OFFLINE_DATA_NUM:@(stateInfo.offlineDataQuantity), + INFO_CODE_VERSION_BLOOD:@(stateInfo.bloodCodeVersion), + INFO_CODE_VERSION_CTL:@(stateInfo.ctlCodeVersion), + INFO_UNIT:(stateInfo.unit == BGUnit_mmolPL)?@"mmol":((stateInfo.unit == BGUnit_mgPmL)?@"mg":@"unknown"), + }; + + [weakSelf sendEventWithName:EVENT_NOTIFY body:response]; + + + } errorBlock:^(BG5SError error, NSString *detailInfo) { + [weakSelf sendMeasureErrorEventWithMac:mac errorId:error]; + }]; + }else{ + [self sendNoMatchedDeviceEventWithMac:mac]; + } +} + +//同步时间 +RCT_EXPORT_METHOD(setTime:(nonnull NSString *)mac date:(nonnull NSString *)date timezone:(nonnull NSNumber *)timezone){ + if ([self getDeviceWithMac:mac]) { + + + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + + [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; + + NSDate*mydate=[dateFormatter dateFromString:date]; + + + __weak typeof(self) weakSelf = self; + [[self getDeviceWithMac:mac] setTimeWithDate:mydate timezone:[timezone floatValue] successBlock:^{ + [weakSelf sendEventWithName:EVENT_NOTIFY body:@{ + kMAC_KEY:mac, + kACTION_KEY:kACTION_SET_TIME, + }]; + } errorBlock:^(BG5SError error, NSString *detailInfo) { + [weakSelf sendMeasureErrorEventWithMac:mac errorId:error]; + }]; + }else{ + [self sendNoMatchedDeviceEventWithMac:mac]; + } +} + +////同步时间 +//RCT_EXPORT_METHOD(setTime:(nonnull NSString *)mac){ +// if ([self getDeviceWithMac:mac]) { +// +// __weak typeof(self) weakSelf = self; +// +// NSString *zone = [[NSTimeZone systemTimeZone] description]; +// NSString *time = [[zone componentsSeparatedByString:@"offset "] objectAtIndex:1]; +// float floatTimeZone = time.floatValue/3600; +// +// [[self getDeviceWithMac:mac] setTimeWithDate:[NSDate date] timezone:floatTimeZone successBlock:^{ +// [weakSelf sendEventWithName:EVENT_NOTIFY body:@{ +// kMAC_KEY:mac, +// kACTION_KEY:kACTION_SET_TIME, +// }]; +// } errorBlock:^(BG5SError error, NSString *detailInfo) { +// [weakSelf sendMeasureErrorEventWithMac:mac errorId:error]; +// }]; +// }else{ +// [self sendNoMatchedDeviceEventWithMac:mac]; +// } +//} + +//设置单位 +RCT_EXPORT_METHOD(setUnit:(nonnull NSString *)mac type:(nonnull NSNumber *)type){ + if ([self getDeviceWithMac:mac]) { + + BGUnit tempUnit = BGUnit_mmolPL; + if ([type isEqual:@(BGUnit_mmolPL)]) { + tempUnit = BGUnit_mmolPL; + } else if([type isEqual:@(BGUnit_mgPmL)]) { + tempUnit = BGUnit_mgPmL; + } else { + [self sendNoMatchedDeviceEventWithMac:mac]; + return; + } + __weak typeof(self) weakSelf = self; + + [[self getDeviceWithMac:mac] setUnit:tempUnit successBlock:^{ + [weakSelf sendEventWithName:EVENT_NOTIFY body:@{ + kMAC_KEY:mac, + kACTION_KEY:kACTION_SET_UNIT, + }]; + } errorBlock:^(BG5SError error, NSString *detailInfo) { + [weakSelf sendMeasureErrorEventWithMac:mac errorId:error]; + + }]; + + }else{ + [self sendNoMatchedDeviceEventWithMac:mac]; + } +} + +//设置离线模式 Is offline measurement allowed 0:allowed 1:Offline measurement is not allowed +RCT_EXPORT_METHOD(setOfflineModel:(nonnull NSString *)mac type:(nonnull NSNumber *)type){ + if ([self getDeviceWithMac:mac]) { + + BOOL modelType=YES; + + if ([type intValue]==0) { + modelType=NO; + }else{ + + modelType=YES; + } + + + __weak typeof(self) weakSelf = self; + + + [[self getDeviceWithMac:mac] setIsOfflineMeasurementAllowed:modelType successBlock:^{ + [weakSelf sendEventWithName:EVENT_NOTIFY body:@{ + kMAC_KEY:mac, + kACTION_KEY:kACTION_SET_OFFINEMODEL, + }]; + } errorBlock:^(BG5SError error, NSString *detailInfo) { + + [weakSelf sendMeasureErrorEventWithMac:mac errorId:error]; + }]; + + }else{ + [self sendNoMatchedDeviceEventWithMac:mac]; + } +} + + +//删除试条使用条数 +RCT_EXPORT_METHOD(deleteUsedStrip:(nonnull NSString *)mac){ + if ([self getDeviceWithMac:mac]) { + __weak typeof(self) weakSelf = self; + [[self getDeviceWithMac:mac] deleteStripUsedInfoWithSuccessBlock:^{ + [self sendEventWithName:EVENT_NOTIFY body:@{ + kMAC_KEY:mac, + kACTION_KEY:kACTION_DELETE_USED_STRIP, + }]; + } errorBlock:^(BG5SError error, NSString *detailInfo) { + [weakSelf sendMeasureErrorEventWithMac:mac errorId:error]; + }]; + }else{ + [self sendNoMatchedDeviceEventWithMac:mac]; + } +} + +//删除离线数据 +RCT_EXPORT_METHOD(deleteOfflineData:(nonnull NSString *)mac){ + if ([self getDeviceWithMac:mac]) { + __weak typeof(self) weakSelf = self; + [[self getDeviceWithMac:mac] deleteRecordWithSuccessBlock:^{ + [self sendEventWithName:EVENT_NOTIFY body:@{ + kMAC_KEY:mac, + kACTION_KEY:kACTION_DELETE_OFFLINE_DATA, + }]; + } errorBlock:^(BG5SError error, NSString *detailInfo) { + [weakSelf sendMeasureErrorEventWithMac:mac errorId:error]; + + }]; + }else{ + [self sendNoMatchedDeviceEventWithMac:mac]; + } +} + + +//同步离线数据 +RCT_EXPORT_METHOD(getOfflineData:(nonnull NSString *)mac){ + + if ([self getDeviceWithMac:mac]) { + __weak typeof(self) weakSelf = self; + [[self getDeviceWithMac:mac] queryRecordWithSuccessBlock:^(NSArray *array) { + + NSMutableArray * tempArr = [[NSMutableArray alloc]init]; + + for(BG5SRecordModel *model in array) { + NSDate *tempDate = model.measureDate; + BOOL flag = model.canCorrect; + + //将时间格式转化成字符串,适配plugin和react native + NSDateFormatter *mydateFormatter = [[NSDateFormatter alloc] init]; + [mydateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; + NSString *dateStr = [mydateFormatter stringFromDate:tempDate]; + + NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:dateStr,@"data_measure_time",@(model.value),@"data_value",model.dataID,@"dataID",@(model.timeZone),@"data_measure_timezone",flag,@"data_time_proof", nil]; + + [tempArr addObject:dic]; + } + + NSDictionary*hisDic=[NSDictionary dictionaryWithObjectsAndKeys:tempArr,@"history", nil]; + + + NSDictionary *deviceInfo = @{@"mac":mac,@"action":kACTION_GET_OFFLINE_DATA,kGET_OFFLINEDATA:hisDic,@"type":@"BG5S"}; + + [weakSelf sendEventWithName:EVENT_NOTIFY body:deviceInfo]; + + } errorBlock:^(BG5SError error, NSString *detailInfo) { + [weakSelf sendMeasureErrorEventWithMac:mac errorId:error]; + }]; + }else{ + [self sendNoMatchedDeviceEventWithMac:mac]; + + } +} + + +//开始测量 +RCT_EXPORT_METHOD(startMeasure:(nonnull NSString *)mac type:(nonnull NSNumber *)type){ + if ([self getDeviceWithMac:mac]) { + __weak typeof(self) weakSelf = self; + + BGMeasureMode measureMode = BGMeasureMode_Blood; + if ([type isEqual:@(BGMeasureMode_Blood)]) { + measureMode = BGMeasureMode_Blood; + } else if([type isEqual:@(BGMeasureMode_NoBlood)]) { + measureMode = BGMeasureMode_NoBlood; + } else { + [self sendNoMatchedDeviceEventWithMac:mac]; + return; + } + + [[self getDeviceWithMac:mac] startMeasure:measureMode withSuccessBlock:^{ + [weakSelf sendEventWithName:EVENT_NOTIFY body:@{ + kMAC_KEY:mac, + kACTION_KEY:kACTION_START_MEASURE, + }]; + } errorBlock:^(BG5SError error, NSString *detailInfo) { + [weakSelf sendMeasureErrorEventWithMac:mac errorId:error]; + + }]; + }else{ + [self sendNoMatchedDeviceEventWithMac:mac]; + } +} + +- (void)device:(BG5S *)device occurError:(BG5SError)error errorDescription:(NSString *)errorDescription{ + NSLog(@"下位机主发的错误信息:%d",(int)error); + [self sendMeasureErrorEventWithMac:device.serialNumber errorId:error]; + +} +- (void)device:(BG5S *)device stripStateDidUpdate:(BG5SStripState)state{ + NSLog(@"试条状态:%@",(state == BG5SStripState_Insert)?@"插入":@"拔出"); + + if (state == BG5SStripState_Insert) { + [self sendEventWithName:EVENT_NOTIFY body:@{ + kMAC_KEY:device.serialNumber, + kACTION_KEY:kACTION_STRIP_IN, + }]; + }else{ + [self sendEventWithName:EVENT_NOTIFY body:@{ + kMAC_KEY:device.serialNumber, + kACTION_KEY:kACTION_STRIP_OUT, + }]; + } + + +} +- (void)deviceDropBlood:(BG5S *)device{ + NSLog(@"滴血"); + [self sendEventWithName:EVENT_NOTIFY body:@{ + kMAC_KEY:device.serialNumber, + kACTION_KEY:kACTION_GET_BLOOD, + }]; +} +- (void)device:(BG5S *)device dataID:(NSString *)dataID measureReult:(NSInteger)result{ + NSLog(@"结果:%d",(int)result); +// NSDictionary *resultDic = [NSDictionary dictionaryWithObjectsAndKeys:@(result),@"value",dataID,@"dataID", nil]; + + [self sendEventWithName:EVENT_NOTIFY body:@{ + kMAC_KEY:device.serialNumber, + RESULT_VALUE:@(result), + kDATA_ID:dataID, + + kACTION_KEY:kACTION_RESULT, + }]; +} +- (void)device:(BG5S *)device chargeStateDidUpdate:(BG5SChargeState)state{ + NSLog(@"充电线状态:%@",(state == BG5SChargeState_Charging)?@"插入":@"拔出"); + + if (state == BG5SChargeState_Charging) { + [self sendEventWithName:EVENT_NOTIFY body:@{ + kMAC_KEY:device.serialNumber, + kACTION_KEY:kACTION_ENTER_CHARGED_STATE, + }]; + }else{ + [self sendEventWithName:EVENT_NOTIFY body:@{ + kMAC_KEY:device.serialNumber, + kACTION_KEY:kACTION_LEAVE_CHARGED_STATE, + }]; + + } + +} + + +//断开连接 +RCT_EXPORT_METHOD(disConnect:(nonnull NSString *)mac){ + if ([self getDeviceWithMac:mac]!=nil) { + + [[self getDeviceWithMac:mac] disconnectDevice]; + }else{ + + } +} + +//开始离线数据修正 +RCT_EXPORT_METHOD(adjustOfflineData:(nonnull NSString *)mac timeString:(nonnull NSString *)timeString array:(nonnull NSArray *)array ){ + if ([self getDeviceWithMac:mac]!=nil) { + + if (array.count > 0 ) { + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; + NSDate *date = [formatter dateFromString:timeString]; + + NSArray *correctArray = [[self getDeviceWithMac:mac] processData:array deviceDate:date]; + } + + [self sendEventWithName:EVENT_NOTIFY body:@{ + kMAC_KEY:mac, + kACTION_KEY:kACTION_ADJUST_OFFLINE_DATA, + }]; + + }else{ + [self sendNoMatchedDeviceEventWithMac:mac]; + + } +} + +- (void)sendMeasureErrorEventWithMac:(NSString *)mac errorId:(BG5SError)errorId{ + + + NSString *errorDescription = @""; + + switch (errorId) { + case 0: + errorDescription = @"Only showed in BG5S's screen and need charging."; + break; + case 1: + errorDescription = @"Strip removed in the middle of reading, repeat the test with a new strip."; + break; + case 2: + errorDescription = @"Reference voltage error, not normal measurement, please repeat the test."; + break; + case 3: + errorDescription = @"Strip is used or unknown moisture detected, discard the test strip and repeat the test with a new strip."; + break; + case 4: + errorDescription = @"Reading transmission error. Repeat the test with a new test strip. If the problem persists, contact iHealth customer service for assistance."; + break; + case 5: + errorDescription = @"The environmental temperature is beyond normal range, place the meter at room temperature for at least 30 minutes, then repeat the test."; + break; + case 6: + errorDescription = @"The environmental temperature is beyond normal range, place the meter at room temperature for at least 30 minutes, then repeat the test."; + break; + case 7: + errorDescription = @"Only showed in BG5S's screen."; + break; + case 8: + errorDescription = @"Glucose test result is low."; + break; + case 9: + errorDescription = @"Glucose test result is high."; + break; + case 10: + errorDescription = @"Reset and if the problem persists, contact iHealth customer service for assistance."; + break; + case 400: + errorDescription = @"arameter input error."; + break; + case 401: + errorDescription = @"Quantity not match"; + break; + case 402: + errorDescription = @"Single packet is not full."; + break; + case 403: + errorDescription = @"Packet index not match."; + break; + case 500: + errorDescription = @"Command timeout"; + break; + case 501: + errorDescription = @"Command is not supported for current device."; + break; + default: + break; + } + + [self sendEventWithName:EVENT_NOTIFY body:@{ + kMAC_KEY:mac, + kACTION_KEY:kACTION_ERROR_BG, + kERROR_NUM_BG:@(errorId), + kERROR_DESCRIPTION_BG:errorDescription + }]; +} + + +- (void)sendNoMatchedDeviceEventWithMac:(NSString *)mac{ + if (mac && mac.length > 0) { + [self sendEventWithName:EVENT_NOTIFY body:@{ + kMAC_KEY:mac, + kACTION_KEY:kACTION_ERROR_BG, + kERROR_NUM_BG:@100 + }]; + } else { + [self sendEventWithName:EVENT_NOTIFY body:@{ + kACTION_KEY:kACTION_ERROR_BG, + + kERROR_NUM_BG:@100, + kERROR_DESCRIPTION_BG:@"Device disconnect." + + }]; + } +} + + + +@end -- cgit