// // L2DataParse.m // BluetoothDemo // // Created by mac on 17/3/23. // Copyright © 2017å¹´ . All rights reserved. // #import "L2DataParse.h" #import "BLEConst.h" #import "BluetoothTool.h" #import #import "JZLocationConverter.h" #import "NSString+methods.h" #import "BLETools.h" // 各种数据请求返回字典数据的KEY #define DIALTYPE @"DIALTYPE" // 表盘类型 #define WATCHWIFI @"WATCHWIFI" // 手表端WIFI #define SPORT_MODEL @"SPORT_MODEL"// 运动模式 #define SPORT_HEARTRATE_SPEED_STEPRATE @"SPORT_HEARTRATE_SPEED_STEPRATE" // 心率 速度 步频 #define SPORT_PACES @"SPORT_PACES" // 配速 #define SPORT_TRACK @"SPORT_TRACK" // 轨迹 #define SPORT_BASIC @"SPORT_BASIC" // 基础数据 // 健康数据返回 #define KEY_SLEEP 0XA2 // 睡眠 #define KEY_STEP 0XA3 // 计步 #define KEY_HEARTRATE 0xA4 // 心率 #define KEY_BLOODPRESSURE 0xA6 // 血压 #define KEY_BLOODOXYGEN 0xA7 // 血氧 #define KEY_SPORTMODEL 0xA5 // 运动模式 #define KEY_TEMPERATURE 0xA8 // 体温 // 运动数据新格式 #define KEY_SPORTMODEL_SPORT 0xAA #define KEY_SPORTMODEL_GPS 0xB0 #define KEY_SPORTMODEL_KM 0xB1 #define KEY_SPORTMODEL_STEP 0xB2 #define KEY_SPORTMODEL_HRS 0xB3 #define KEY_SPORTMODEL_SWIM 0xB4 // 实时数据返回 #define KEY_REAL_STEP 0xB3 #define KEY_REAL_HEARTRATE 0xB4 #define KEY_REAL_BLOODPRESSURE 0xB6 #define KEY_REAL_BLOODOXYGEN 0xB7 #define KEY_REAL_TEMPERATURE 0xB8 @implementation L2DataParse + (NSDictionary *)L2_ParseData:(NSData *)data type:(BleCMD)cmd { NSMutableDictionary *mutableDict = [[NSMutableDictionary alloc]init]; // 是否存在内容 BOOL isContent = data.length > 13 ? YES:NO; if (!isContent) { return mutableDict; } switch (cmd) { // 手环表盘推送的数据解析 case BleCMD_braceletPialPush: { //NSString *version = [[NSString alloc] initWithFormat:@"%d.%d.%d",buffer[13],buffer[14],buffer[15]]; Byte *buffer = (Byte *)[data bytes]; int dialType = buffer[13]; [mutableDict setObject:@(dialType) forKey:@"DialType"]; if (dialType == 0) { int dialStatus = buffer[14]; int dialOffset = [[[self class] intFromHexSrting:[NSString stringWithFormat:@"%02x%02x%02x%02x",buffer[15],buffer[16],buffer[17],buffer[18]]] intValue]; [mutableDict setObject:@(dialStatus) forKey:@"DialStatus"]; [mutableDict setObject:@(dialOffset) forKey:@"DialOffset"]; } else if (dialType == 1) { } else if (dialType == 2) { int dialStatus = buffer[14]; [mutableDict setObject:@(dialStatus) forKey:@"DialStatus"]; } } break; // 绑定设备返回的数据 case BleCMD_bindingDevice: { NSString *dataString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(13, data.length - 13)] encoding:NSUTF8StringEncoding]; NSArray *arr = [dataString componentsSeparatedByString:@"#"]; [mutableDict setObject:arr forKey:DIALTYPE]; } break; // 手表wifi数据 // case BleCMD_watchWifi: // { // NSString *dataString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(13, data.length - 13)] encoding:NSUTF8StringEncoding]; // id object= [[self class] parseJSONStringToNSDictionary:dataString]; // if ([object isKindOfClass:[NSArray class]]) { // NSArray *arr = (NSArray *)object; // [mutableDict setObject:arr forKey:WATCHWIFI]; // } // } break; // 同步健康数据 case BleCMD_syncHealth: { mutableDict = [self p_parseBraceletData_syncHealthWith:data]; } break; // 固件信息 case BleCMD_firmwareVersion: { if (data.length < 46) { return mutableDict; } Byte *buffer = (Byte *)[data bytes]; NSString *deviceName = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(13, 10)] encoding:NSASCIIStringEncoding]; NSInteger platform = [[[NSString alloc] initWithFormat:@"%2d",buffer[23]] integerValue]; NSString *macID = [BluetoothTool getPositiveSequenceMacWithData:[data subdataWithRange:NSMakeRange(24, 6)]]; NSInteger adapterNumber = [[[self class] HexToUnsignedInt:data dataRange:NSMakeRange(30, 3)] integerValue]; NSString *protocolVersion = [[NSString alloc] initWithFormat:@"%d.%d",buffer[33],buffer[34]]; NSString *firmwareVersion = [[NSString alloc] initWithFormat:@"%d.%d.%ld",buffer[35],buffer[36],[[self class] HexToUnsignedNSInteger:[data subdataWithRange:NSMakeRange(37, 2)]]]; [mutableDict setObject:deviceName forKey:@"deviceName"]; [mutableDict setObject:@(platform) forKey:@"platform"]; [mutableDict setObject:macID forKey:@"macID"]; [mutableDict setObject:@(adapterNumber) forKey:@"adapterNumber"]; [mutableDict setObject:protocolVersion forKey:@"protocolVersion"]; [mutableDict setObject:firmwareVersion forKey:@"firmwareVersion"]; } break; // 电量返回 case BleCMD_requestBattery: { Byte *buffer = (Byte *)[data bytes]; NSInteger power = [[[NSString alloc] initWithFormat:@"%02d",buffer[13]] integerValue]; NSInteger status = [[[NSString alloc] initWithFormat:@"%02d",buffer[14]] integerValue]; [mutableDict setObject:@(power) forKey:@"power"]; [mutableDict setObject:@(status) forKey:@"status"]; } break; // 当天数据 case BleCMD_realTimesync: { Byte *buffer = (Byte *)[data bytes]; Byte key = buffer[10]; if (key == KEY_REAL_STEP) { // 实时步数 NSDateFormatter *formatter = [[NSDateFormatter alloc]init]; formatter.dateFormat = @"yyyy-MM-dd-HH-mm"; NSString *dateStr = [formatter stringFromDate:[NSDate date]]; long long timestamp = [NSString changeTimeToMinutes:dateStr]; NSString *steps = [[self class] intFromHexSrting:[NSString stringWithFormat:@"%02x%02x%02x%02x",buffer[13],buffer[14],buffer[15],buffer[16]]]; Byte btValue[4]; btValue[0] = buffer[20]; btValue[1] = buffer[19]; btValue[2] = buffer[18]; btValue[3] = buffer[17]; float result; result=*((float *)btValue); NSString *calories = [NSString stringWithFormat:@"%.1f",result]; btValue[0] = buffer[24]; btValue[1] = buffer[23]; btValue[2] = buffer[22]; btValue[3] = buffer[21]; result=*((float *)btValue); [mutableDict setObject:@(timestamp) forKey:@"timestamp"]; NSString *distance = [NSString stringWithFormat:@"%.0f",result*1000]; [mutableDict setObject:@(steps.intValue) forKey:@"stepNumber"]; [mutableDict setObject:@(calories.floatValue) forKey:@"stepCalorie"]; [mutableDict setObject:@(distance.intValue) forKey:@"stepDistance"]; [mutableDict setObject:@(BleCMD_realStep) forKey:@"DataType"]; }else if(key == KEY_REAL_HEARTRATE){ // 实时心率 NSDateFormatter *formatter = [[NSDateFormatter alloc]init]; formatter.dateFormat = @"yyyy-MM-dd-HH-mm"; NSString *dateStr = [formatter stringFromDate:[NSDate date]]; long long timestamp = [NSString changeTimeToMinutes:dateStr]; NSString *heartRate = [NSString stringWithFormat:@"%02d",buffer[13]]; [mutableDict setObject:@(timestamp) forKey:@"timestamp"]; [mutableDict setObject:@(heartRate.intValue) forKey:@"heartRate"]; [mutableDict setObject:@(BleCMD_realHeartData) forKey:@"DataType"]; }else if(key == KEY_REAL_TEMPERATURE){ // 实时体温 NSDateFormatter *formatter = [[NSDateFormatter alloc]init]; formatter.dateFormat = @"yyyy-MM-dd-HH-mm"; NSString *dateStr = [formatter stringFromDate:[NSDate date]]; long long timestamp = [NSString changeTimeToMinutes:dateStr]; NSString *temperature = [NSString stringWithFormat:@"%02d.%d",buffer[13], buffer[14]]; [mutableDict setObject:@(timestamp) forKey:@"timestamp"]; [mutableDict setObject:@(temperature.floatValue) forKey:@"temperature"]; [mutableDict setObject:@(BleCMD_realTemperature) forKey:@"DataType"]; }else if(key == KEY_REAL_BLOODPRESSURE) { // 实时血压 NSDateFormatter *formatter = [[NSDateFormatter alloc]init]; formatter.dateFormat = @"yyyy-MM-dd-HH-mm"; NSString *dateStr = [formatter stringFromDate:[NSDate date]]; long long timestamp = [NSString changeTimeToMinutes:dateStr]; NSString *sbp = [NSString stringWithFormat:@"%02d",buffer[13]]; NSString *dbp = [NSString stringWithFormat:@"%02d",buffer[14]]; [mutableDict setObject:@(timestamp) forKey:@"timestamp"]; [mutableDict setObject:@(sbp.intValue) forKey:@"sbp"]; [mutableDict setObject:@(dbp.intValue) forKey:@"dbp"]; [mutableDict setObject:@(BleCMD_realBloodPressure) forKey:@"DataType"]; }else if(key == KEY_REAL_BLOODOXYGEN) { // 实时血氧 NSDateFormatter *formatter = [[NSDateFormatter alloc]init]; formatter.dateFormat = @"yyyy-MM-dd-HH-mm"; NSString *dateStr = [formatter stringFromDate:[NSDate date]]; long long timestamp = [NSString changeTimeToMinutes:dateStr]; NSString *bloodOxygen = [NSString stringWithFormat:@"%02d",buffer[13]]; [mutableDict setObject:@(timestamp) forKey:@"timestamp"]; [mutableDict setObject:@(bloodOxygen.intValue) forKey:@"bloodOxygen"]; [mutableDict setObject:@(BleCMD_realBloodOxygen) forKey:@"DataType"]; } } break; case BleCMD_readBraceletSet: // 读取手环设置请求 { if (data.length == 19) { // 返回mac地址 NSData *MACData = [data subdataWithRange:NSMakeRange(13, 6)]; NSString *MACString = [BluetoothTool getPositiveSequenceMacWithData:MACData]; [mutableDict setObject:MACString forKey:@"MACString"]; } } break; case BleCMD_readProfile: // 读取手环配置请求 { if (data.length < 106) { NSLog(@"BleCMD_readProfile 长度不够 %ld",data.length); return mutableDict; } // 闹钟 5组25bytes Byte *alarmClockByte = (Byte *)[[data subdataWithRange:NSMakeRange(13, 25)] bytes]; NSMutableArray *alarmClockArr = [[NSMutableArray alloc] init]; for (NSInteger i = 0; i < 5; i ++) { NSMutableDictionary *alarmClockDict = [[NSMutableDictionary alloc] init]; NSString *hour = [NSString stringWithFormat:@"%02d",alarmClockByte[0 + i * 5]]; NSString *minutes = [NSString stringWithFormat:@"%02d",alarmClockByte[1 + i * 5]]; NSString *cycle = [[self class] cycleIntToString:alarmClockByte[2 + i * 5]]; NSString *label = [NSString stringWithFormat:@"%d",alarmClockByte[3 + i * 5]]; NSString *isOpen = [NSString stringWithFormat:@"%d",alarmClockByte[4 + i * 5]]; [alarmClockDict setObject:hour forKey:@"Hour"]; [alarmClockDict setObject:minutes forKey:@"Minutes"]; [alarmClockDict setObject:cycle forKey:@"Cycle"]; [alarmClockDict setObject:label forKey:@"Label"]; [alarmClockDict setObject:isOpen forKey:@"IsOpen"]; [alarmClockArr addObject:alarmClockDict]; } [mutableDict setObject:alarmClockArr forKey:@"AlarmClock"]; // 久坐提醒 8bytes Byte *sedentaryByte = (Byte *)[[data subdataWithRange:NSMakeRange(38, 8)] bytes]; NSMutableDictionary *sedentaryDict = [[NSMutableDictionary alloc] init]; NSString *isOpen = [NSString stringWithFormat:@"%d",sedentaryByte[0]]; NSString *startHour = [NSString stringWithFormat:@"%02d",sedentaryByte[1]]; NSString *endHour = [NSString stringWithFormat:@"%02d",sedentaryByte[2]]; NSString *cycle = [[self class] cycleIntToString:sedentaryByte[3]]; NSString *sittingTime = [[self class]HexToUnsignedInt:data dataRange:NSMakeRange(42, 2)]; NSString *sittingThreshold = [[self class]HexToUnsignedInt:data dataRange:NSMakeRange(44, 2)]; [sedentaryDict setObject:isOpen forKey:@"IsOpen"]; [sedentaryDict setObject:startHour forKey:@"StartHour"]; [sedentaryDict setObject:endHour forKey:@"EndHour"]; [sedentaryDict setObject:cycle forKey:@"Cycle"]; [sedentaryDict setObject:sittingTime forKey:@"SittingTime"]; [sedentaryDict setObject:sittingThreshold forKey:@"SittingThreshold"]; [mutableDict setObject:sedentaryDict forKey:@"Sedentary"]; // 用户信息 8bytes Byte *userInfoByte = (Byte *)[[data subdataWithRange:NSMakeRange(46, 8)] bytes]; NSMutableDictionary *userInfoDict = [[NSMutableDictionary alloc] init]; NSString *gender = [NSString stringWithFormat:@"%d",userInfoByte[0]]; NSString *age = [NSString stringWithFormat:@"%d",userInfoByte[1]]; NSString *height = [NSString stringWithFormat:@"%d",userInfoByte[2]]; NSString *weight = [NSString stringWithFormat:@"%d",userInfoByte[3]]; NSString *goal = [[self class]HexToUnsignedInt:data dataRange:NSMakeRange(50, 3)]; NSString *sportMode = [NSString stringWithFormat:@"%d",userInfoByte[7]]; [userInfoDict setObject:gender forKey:@"Gender"]; [userInfoDict setObject:age forKey:@"Age"]; [userInfoDict setObject:height forKey:@"Height"]; [userInfoDict setObject:weight forKey:@"Weight"]; [userInfoDict setObject:goal forKey:@"Goal"]; [userInfoDict setObject:sportMode forKey:@"SportMode"]; [mutableDict setObject:userInfoDict forKey:@"UserInfo"]; // 提醒模式 1bytes Byte *remindModeByte = (Byte *)[[data subdataWithRange:NSMakeRange(54, 1)] bytes]; NSMutableDictionary *remindModeDict = [[NSMutableDictionary alloc] init]; NSString *remindType = [NSString stringWithFormat:@"%d",remindModeByte[0]]; [remindModeDict setObject:@(remindType.intValue) forKey:@"RemindType"]; [mutableDict setObject:remindModeDict forKey:@"RemindMode"]; // 免打扰设置 5bytes Byte *notDisturbByte = (Byte *)[[data subdataWithRange:NSMakeRange(55, 5)] bytes]; NSMutableDictionary *notDisturbDict = [[NSMutableDictionary alloc] init]; NSString *isON = [NSString stringWithFormat:@"%d",notDisturbByte[0]]; NSString *startTime = [NSString stringWithFormat:@"%@:%@",[NSString stringWithFormat:@"%02d",notDisturbByte[1]],[NSString stringWithFormat:@"%02d",notDisturbByte[2]]]; NSString *endTime = [NSString stringWithFormat:@"%@:%@",[NSString stringWithFormat:@"%02d",notDisturbByte[3]],[NSString stringWithFormat:@"%02d",notDisturbByte[4]]]; [notDisturbDict setObject:isON forKey:@"IsOpen"]; [notDisturbDict setObject:startTime forKey:@"StartTime"]; [notDisturbDict setObject:endTime forKey:@"EndTime"]; [mutableDict setObject:notDisturbDict forKey:@"NotDisturb"]; // 心率检测 6bytes Byte *heartRateByte = (Byte *)[[data subdataWithRange:NSMakeRange(60, 6)] bytes]; NSMutableDictionary *heartRateDict = [[NSMutableDictionary alloc] init]; NSString *ONOFF = [NSString stringWithFormat:@"%d",heartRateByte[0]]; NSString *heartStartTime = [NSString stringWithFormat:@"%@:%@",[NSString stringWithFormat:@"%02d",heartRateByte[1]],[NSString stringWithFormat:@"%02d",heartRateByte[2]]]; NSString *heartEndTime = [NSString stringWithFormat:@"%@:%@",[NSString stringWithFormat:@"%02d",heartRateByte[3]],[NSString stringWithFormat:@"%02d",heartRateByte[4]]]; NSString *interval = [NSString stringWithFormat:@"%d",heartRateByte[5]]; [heartRateDict setObject:ONOFF forKey:@"IsOpen"]; [heartRateDict setObject:heartStartTime forKey:@"StartTime"]; [heartRateDict setObject:heartEndTime forKey:@"EndTime"]; [heartRateDict setObject:interval forKey:@"Interval"]; [mutableDict setObject:heartRateDict forKey:@"HeartRate"]; // 系统设置 4bytes(不处理) // 喝水提醒 8bytes Byte *drinkRemindByte = (Byte *)[[data subdataWithRange:NSMakeRange(70, 8)] bytes]; NSMutableDictionary *drinkRemindDict = [[NSMutableDictionary alloc] init]; NSString *isONOFF = [NSString stringWithFormat:@"%d",drinkRemindByte[0]]; NSString *drinkStartTime = [NSString stringWithFormat:@"%@:%@",[NSString stringWithFormat:@"%02d",drinkRemindByte[1]],[NSString stringWithFormat:@"%02d",drinkRemindByte[2]]]; NSString *drinkEndTime = [NSString stringWithFormat:@"%@:%@",[NSString stringWithFormat:@"%02d",drinkRemindByte[3]],[NSString stringWithFormat:@"%02d",drinkRemindByte[4]]]; NSString *drinkCycle = [[self class] cycleIntToString:drinkRemindByte[5]]; NSString *drinkInterval = [[self class]HexToUnsignedInt:data dataRange:NSMakeRange(76, 2)]; [drinkRemindDict setObject:isONOFF forKey:@"IsOpen"]; [drinkRemindDict setObject:drinkStartTime forKey:@"StartTime"]; [drinkRemindDict setObject:drinkEndTime forKey:@"EndTime"]; [drinkRemindDict setObject:drinkCycle forKey:@"Cycle"]; [drinkRemindDict setObject:drinkInterval forKey:@"Interval"]; [mutableDict setObject:drinkRemindDict forKey:@"DrinkRemind"]; // 消息推送 2bytes NSMutableDictionary *setPushDict = [[NSMutableDictionary alloc] init]; NSString *pushIsON = [[self class]HexToUnsignedInt:data dataRange:NSMakeRange(78, 2)]; [setPushDict setObject:@(pushIsON.intValue) forKey:@"IsOpen"]; [mutableDict setObject:setPushDict forKey:@"SetPush"]; // 运动目标 4bytes Byte *targetByte = (Byte *)[[data subdataWithRange:NSMakeRange(80, 4)] bytes]; NSMutableDictionary *targetDict = [[NSMutableDictionary alloc] init]; NSString *targetSteps = [[self class]HexToUnsignedInt:data dataRange:NSMakeRange(80, 3)]; NSString *targetSportMode = [NSString stringWithFormat:@"%d",targetByte[3]]; [targetDict setObject:targetSteps forKey:@"TargetSteps"]; [targetDict setObject:targetSportMode forKey:@"SportMode"]; [mutableDict setObject:targetDict forKey:@"TargetDict"]; // 抬手亮屏 3bytes Byte *gesturesByte = (Byte *)[[data subdataWithRange:NSMakeRange(84, 3)] bytes]; NSMutableDictionary *gesturesDict = [[NSMutableDictionary alloc] init]; NSString *hand = [NSString stringWithFormat:@"%d",gesturesByte[0]]; NSString *raise = [NSString stringWithFormat:@"%d",gesturesByte[1]]; NSString *flip = [NSString stringWithFormat:@"%d",gesturesByte[2]]; [gesturesDict setObject:hand forKey:@"Hand"]; [gesturesDict setObject:raise forKey:@"Raise"]; [gesturesDict setObject:flip forKey:@"Flip"]; [mutableDict setObject:gesturesDict forKey:@"GesturesDict"]; // 体温检测 6bytes Byte *temperatureByte = (Byte *)[[data subdataWithRange:NSMakeRange(100, 6)] bytes]; NSMutableDictionary *temperatureDict = [[NSMutableDictionary alloc] init]; NSString *temperatureONOFF = [NSString stringWithFormat:@"%d",temperatureByte[0]]; NSString *temperatureStartTime = [NSString stringWithFormat:@"%@:%@",[NSString stringWithFormat:@"%02d",temperatureByte[1]],[NSString stringWithFormat:@"%02d",temperatureByte[2]]]; NSString *temperatureEndTime = [NSString stringWithFormat:@"%@:%@",[NSString stringWithFormat:@"%02d",temperatureByte[3]],[NSString stringWithFormat:@"%02d",temperatureByte[4]]]; NSString *temperatureInterval = [NSString stringWithFormat:@"%d",temperatureByte[5]]; [temperatureDict setObject:temperatureONOFF forKey:@"IsOpen"]; [temperatureDict setObject:temperatureStartTime forKey:@"StartTime"]; [temperatureDict setObject:temperatureEndTime forKey:@"EndTime"]; [temperatureDict setObject:temperatureInterval forKey:@"Interval"]; [mutableDict setObject:temperatureDict forKey:@"Temperature"]; } break; // 表盘数据 0X4F case BleCMD_dialRequest: { } break; default: break; } return mutableDict; } /** 将手环健康数据解析 */ + (NSMutableDictionary*)p_parseBraceletData_syncHealthWith:(NSData *)data { NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary]; Byte *bytes = (Byte *)[data bytes]; Byte key = bytes[10]; if (key == KEY_STEP) { // 计步数据 NSArray *dataArr = [[self class] sepratorData:data]; NSMutableData *completeData = [NSMutableData dataWithData:dataArr.firstObject]; if (dataArr.count == 2) { NSData *lastData = dataArr.lastObject; [completeData appendData:[lastData subdataWithRange:NSMakeRange(13, lastData.length - 13)]]; } NSMutableDictionary *stepDict = [[NSMutableDictionary alloc] init]; NSInteger step_number = 0; CGFloat step_distance = 0.0; CGFloat step_calorie = 0.0; NSInteger step_duration = 0; NSMutableArray *stepDetailsArray = [[NSMutableArray alloc] init]; NSString *year = [NSString stringWithFormat:@"%ld",[NSString stringWithFormat:@"%02d",bytes[13]].integerValue + 2000]; NSString *month = [NSString stringWithFormat:@"%02d",bytes[14]]; NSString *day = [NSString stringWithFormat:@"%02d",bytes[15]]; NSString *step_times = [NSString stringWithFormat:@"%@-%@-%@",year,month,day]; // 分段数据处理 NSInteger count = (completeData.length - 17) / 12; NSString *tempSteps = @"0"; NSString *tempCalorie= @"0"; NSString *tempDistance = @"0"; for (int i = 0; i < count; i ++) { NSData *stepData = [completeData subdataWithRange:NSMakeRange(17+i*12, 12)]; NSString *steps = [[self class] HexToUnsignedInt:stepData dataRange:NSMakeRange(0, 4)]; NSString *calorie = [[self class] HexToUnsignedInt:stepData dataRange:NSMakeRange(4, 4)]; NSString *distance = [[self class] HexToUnsignedInt:stepData dataRange:NSMakeRange(8, 4)]; // 记录该时段的步数(分段数据:step|cal|km|时段,) if (steps.integerValue < tempSteps.integerValue) { steps = tempSteps; } NSString *currenSteps = [NSString stringWithFormat:@"%ld",steps.integerValue - tempSteps.integerValue]; tempSteps = steps; if (calorie.integerValue < tempCalorie.integerValue) { calorie = tempCalorie; } NSString *currenCalorie = [NSString stringWithFormat:@"%ld",calorie.integerValue - tempCalorie.integerValue]; tempCalorie = calorie; if (distance.integerValue < tempDistance.integerValue) { distance = tempDistance; } NSString *currenDistance = [NSString stringWithFormat:@"%ld",distance.integerValue - tempDistance.integerValue]; tempDistance = distance; // 计步详情 NSString *stepDetails = [NSString stringWithFormat:@"%@|%@|%@|%d",currenSteps, currenCalorie, currenDistance, i]; [stepDetailsArray addObject:stepDetails]; // 当前步数 || 计步卡路里 || 计步距离 || 计步时长(1km==15分钟,四舍五入) if (i == count - 1) { step_number = steps.integerValue; step_calorie = [calorie doubleValue]; step_distance = [distance doubleValue]; step_duration = (step_distance / 1000.0) * 15 + 0.5; } } [stepDict setObject:@(step_number) forKey:@"stepNumber"]; [stepDict setObject:@(step_distance)forKey:@"stepDistance"]; [stepDict setObject:@(step_calorie) forKey:@"stepCalorie"]; [stepDict setObject:@(step_duration) forKey:@"stepDuration"]; [stepDict setObject:[stepDetailsArray componentsJoinedByString:@","] forKey:@"stepDetails"]; [stepDict setObject:step_times forKey:@"dataDate"]; if (stepDict) { [mutableDict setObject:stepDict forKey:@"STEP"]; } }else if (key == 0xA2) { // 睡眠数据拼接 NSMutableDictionary *sleepdict = [[NSMutableDictionary alloc] init]; NSInteger deepsleep_duration = 0; NSInteger lightsleep_duration = 0; NSInteger awake_duration = 0; NSInteger awakeNumber = 0; NSString *fallingsleep_times = [[NSString alloc] init]; NSString *awake_times = [[NSString alloc] init]; NSString *sleep_times = [[NSString alloc] init]; // 睡眠详情数组 NSMutableArray *sleepDetailArr = [[NSMutableArray alloc]init]; // 睡眠数据处理 NSData *contonData = [data subdataWithRange:NSMakeRange(13, data.length - 13)]; Byte *buffer = (Byte *)[contonData bytes]; NSString *year = [NSString stringWithFormat:@"%ld",[NSString stringWithFormat:@"%02d",buffer[0]].integerValue + 2000]; NSString *month = [NSString stringWithFormat:@"%02d",buffer[1]]; NSString *day = [NSString stringWithFormat:@"%02d",buffer[2]]; sleep_times = [NSString stringWithFormat:@"%@-%@-%@",year,month,day]; // 睡眠数据个数 NSInteger count = contonData.length / 3 - 1; for (int i = 0; i < count; i ++) { // 取出第一条睡眠数据,第二条睡眠数据 NSData *sleepData = [contonData subdataWithRange:NSMakeRange(3 + i * 3, 3)]; NSData *nextData = [[NSData alloc] init]; if (i < count - 1) { nextData = [contonData subdataWithRange:NSMakeRange(3 + ((i + 1)* 3), 3)]; }else { // 最后一条数据或仅一条数据不处理 break; } // 获取开始小时,结束时间 NSString *startHour = [NSString stringWithFormat:@"%02d",((Byte*)([sleepData bytes]))[1]]; NSString *startMinute = [NSString stringWithFormat:@"%02d",((Byte*)([sleepData bytes]))[2]]; NSString *endHour = [NSString stringWithFormat:@"%02d",((Byte*)([nextData bytes]))[1]]; NSString *endMinute = [NSString stringWithFormat:@"%02d",((Byte*)([nextData bytes]))[2]]; if (i == 0) { // 首条开始时间若是在09:00 - 21:00之内,则设置为21:00 if (startHour.integerValue < 21) { if (startHour.integerValue > 9) { startHour = @"21"; startMinute = @"00"; } else { // MARK: 21--09 [21--23] 数据日期 +1 update by lsz 2022-5-26 if (startHour.intValue >= 21 && startHour.intValue <= 23 && startHour.intValue > endHour.intValue) { NSString *time = [[self class] getTimestampWithTime:[NSString stringWithFormat:@"%@-%@-%@",year,month,day]]; NSArray *timeArr = [[BLETools nsdateToTime:[time integerValue] + 86400 formatStr:@"yyyy-MM-dd"] componentsSeparatedByString:@"-"]; year = timeArr[0]; month = timeArr[1]; day = timeArr[2]; } /** ************************************旧逻辑******************************************** // 若首条数据小时为小于9点,则数据日期+1天 NSString *time = [[self class] getTimestampWithTime:[NSString stringWithFormat:@"%@-%@-%@",year,month,day]]; NSArray *timeArr = [[BLETools nsdateToTime:[time integerValue] + 86400 formatStr:@"yyyy-MM-dd"] componentsSeparatedByString:@"-"]; year = timeArr[0]; month = timeArr[1]; day = timeArr[2]; */ } } // 记录入睡时间 fallingsleep_times = [NSString stringWithFormat:@"%@-%@-%@ %@:%@",year,month,day,startHour,startMinute]; } // 当前时段开始时间 NSString *startSleepTime = [NSString stringWithFormat:@"%@-%@-%@-%@-%@",year,month,day,startHour,startMinute]; // 处理跨天的数据 if ([endHour integerValue] < [startHour integerValue]) { NSString *endTime = [[self class] getTimestampWithTime:[NSString stringWithFormat:@"%@-%@-%@-%@-%@",year,month,day,endHour,endMinute]]; NSArray *timeArr = [[BLETools nsdateToTime:[endTime integerValue] + 86400 formatStr:@"yyyy-MM-dd-HH-mm"] componentsSeparatedByString:@"-"]; // 重新赋值年月日 year = timeArr[0]; month = timeArr[1]; day = timeArr[2]; } // 当前时段结束时间 NSString *endSleepTime = [NSString stringWithFormat:@"%@-%@-%@-%@-%@",year,month,day,endHour,endMinute]; if (i == count - 2) { // 最后的结束时间处理(结束时间大于9:00,默认9:00) if (endHour.integerValue > 9 || (endHour.integerValue >=9 && endMinute.integerValue > 0)) { endSleepTime = [NSString stringWithFormat:@"%@-%@-%@-09-00",year,month,day]; } // 记录睡来时间 NSArray *endtimeArr = [endSleepTime componentsSeparatedByString:@"-"]; awake_times = [NSString stringWithFormat:@"%@-%@-%@ %@:%@",endtimeArr[0],endtimeArr[1],endtimeArr[2],endtimeArr[3],endtimeArr[4]]; } // 睡眠类型 NSInteger sleepType = ((Byte*)([sleepData bytes]))[0]; // 睡眠详情数据(睡眠类型|开始时间戳|持续时长|结束时间戳,..) long long startSleep = [NSString changeTimeToMinutes:startSleepTime]; long long endSleep = [NSString changeTimeToMinutes:endSleepTime]; // 睡眠持续时间 NSInteger sleepTime = endSleep - startSleep; if (sleepTime <= 0) { continue; } sleepTime = sleepTime / 60; NSString *sleepDetail = [NSString stringWithFormat:@"%ld|%lld|%ld|%lld",sleepType,startSleep,sleepTime,endSleep]; [sleepDetailArr addObject:sleepDetail]; // 记录睡来时间 NSArray *endtimeArr = [endSleepTime componentsSeparatedByString:@"-"]; awake_times = [NSString stringWithFormat:@"%@-%@-%@ %@:%@",endtimeArr[0],endtimeArr[1],endtimeArr[2],endtimeArr[3],endtimeArr[4]]; switch (sleepType) { case 0: awake_duration += sleepTime; awakeNumber += 1; break; case 1: lightsleep_duration += sleepTime; break; case 2: deepsleep_duration += sleepTime; break; default: break; } } NSInteger totalSleepDuration = deepsleep_duration + lightsleep_duration; if (totalSleepDuration > 0) { //总睡眠时长大于0的睡眠才有效 [sleepdict setObject:@(deepsleep_duration) forKey:@"deepSleepDuration"]; [sleepdict setObject:@(lightsleep_duration) forKey:@"lightSleepDuration"]; [sleepdict setObject:@(awake_duration) forKey:@"awakeDuration"]; [sleepdict setObject:@(awakeNumber) forKey:@"awakeNumber"]; [sleepdict setObject:@(totalSleepDuration) forKey:@"totalSleepDuration"]; NSString *sleepDetailStr = [sleepDetailArr componentsJoinedByString:@","]; [sleepdict setObject:sleepDetailStr forKey:@"sleepDetails"]; [sleepdict setObject:fallingsleep_times forKey:@"fallingSleepTimes"]; [sleepdict setObject:awake_times forKey:@"awakeTimes"]; [sleepdict setObject:sleep_times forKey:@"dataDate"]; [mutableDict setObject:sleepdict forKey:@"SLEEP"]; } }else if(key == KEY_HEARTRATE){ // 心率数据 NSMutableDictionary *heartRateDict = [[NSMutableDictionary alloc] init]; NSArray *dataArr = [[self class] sepratorData:data]; // 合并一天完整心率数据 NSMutableData *completeData = [NSMutableData dataWithData:dataArr.firstObject]; for (NSInteger i = 1; i < dataArr.count; i ++) { NSData *hrData = dataArr[i]; [completeData appendData:[hrData subdataWithRange:NSMakeRange(13, hrData.length - 13)]]; } // 心率日期 NSString *year = [NSString stringWithFormat:@"%ld",[NSString stringWithFormat:@"%02d",bytes[13]].integerValue + 2000]; NSString *month = [NSString stringWithFormat:@"%02d",bytes[14]]; NSString *day = [NSString stringWithFormat:@"%02d",bytes[15]]; NSString *heartDate = [NSString stringWithFormat:@"%@-%@-%@",year,month,day]; NSMutableString *heartDetails = [[NSMutableString alloc] init]; NSInteger heartMax = 0; NSInteger heartMin = 0; NSInteger heartAvg = 0; NSInteger tampTotalHeart = 0; // 手环心率详情数据拼接 NSInteger count = (completeData.length - 13) / 7; for (int i = 0; i < count; i ++) { NSData *contonData = [completeData subdataWithRange:NSMakeRange(13 + i * 7, 7)]; Byte *buffer = (Byte *)[contonData bytes]; NSString *hour = [NSString stringWithFormat:@"%02d",buffer[3]]; NSString *minute = [NSString stringWithFormat:@"%02d",buffer[4]]; NSString *second = [NSString stringWithFormat:@"%02d",buffer[5]]; NSString *heartRate = [NSString stringWithFormat:@"%02d",buffer[6]]; //(心率值|时间戳,..) long long timeStamp = [NSString changeTimeToMinutes:[NSString stringWithFormat:@"%@-%@-%@-%@-%@-%@",year,month,day,hour,minute,second]]; [heartDetails appendString:[NSString stringWithFormat:@"%@|%lld",heartRate,timeStamp]]; if (i < count - 1) { [heartDetails appendString:@","]; } if (heartRate.integerValue > heartMax) { heartMax = heartRate.integerValue; } if (heartRate.integerValue < heartMin || heartMin == 0) { heartMin = heartRate.integerValue; } tampTotalHeart += heartRate.integerValue; } heartAvg = tampTotalHeart / count; [heartRateDict setObject:heartDate forKey:@"dataDate"]; [heartRateDict setObject:@(heartMax) forKey:@"heartMax"]; [heartRateDict setObject:@(heartMin) forKey:@"heartMin"]; [heartRateDict setObject:@(heartAvg) forKey:@"heartAvg"]; [heartRateDict setObject:heartDetails forKey:@"heartDetails"]; [mutableDict setObject:heartRateDict forKey:@"HEARTRATE"]; }else if(key == KEY_TEMPERATURE){ // 体温数据 NSMutableDictionary *temperatureDict = [[NSMutableDictionary alloc] init]; NSArray *dataArr = [[self class] sepratorData:data]; // 合并一天完整体温数据 NSMutableData *completeData = [NSMutableData dataWithData:dataArr.firstObject]; for (NSInteger i = 1; i < dataArr.count; i ++) { NSData *tempData = dataArr[i]; [completeData appendData:[tempData subdataWithRange:NSMakeRange(13, tempData.length - 13)]]; } // 体温日期 NSString *year = [NSString stringWithFormat:@"%ld",[NSString stringWithFormat:@"%02d",bytes[13]].integerValue + 2000]; NSString *month = [NSString stringWithFormat:@"%02d",bytes[14]]; NSString *day = [NSString stringWithFormat:@"%02d",bytes[15]]; NSString *temperatureDate = [NSString stringWithFormat:@"%@-%@-%@",year,month,day]; NSMutableString *temperatureDetails = [[NSMutableString alloc] init]; double temperatureMax = 0; double temperatureMin = 0; double temperatureAvg = 0; double tampTotaltemperature = 0; // 手环体温详情数据拼接 NSInteger count = (completeData.length - 13) / 8; for (int i = 0; i < count; i ++) { NSData *contonData = [completeData subdataWithRange:NSMakeRange(13 + i * 8, 8)]; Byte *buffer = (Byte *)[contonData bytes]; NSString *hour = [NSString stringWithFormat:@"%02d",buffer[3]]; NSString *minute = [NSString stringWithFormat:@"%02d",buffer[4]]; NSString *second = [NSString stringWithFormat:@"%02d",buffer[5]]; NSString *temperature = [NSString stringWithFormat:@"%02d.%d",buffer[6], buffer[7]]; //(体温值|时间戳,..) long long timeStamp = [NSString changeTimeToMinutes:[NSString stringWithFormat:@"%@-%@-%@-%@-%@-%@",year,month,day,hour,minute,second]]; [temperatureDetails appendString:[NSString stringWithFormat:@"%@|%lld",temperature,timeStamp]]; if (i < count - 1) { [temperatureDetails appendString:@","]; } if (temperature.doubleValue > temperatureMax) { temperatureMax = temperature.doubleValue; } if (temperature.doubleValue < temperatureMin || temperatureMin == 0) { temperatureMin = temperature.doubleValue; } tampTotaltemperature += temperature.doubleValue; } temperatureAvg = tampTotaltemperature / count; [temperatureDict setObject:temperatureDate forKey:@"dataDate"]; [temperatureDict setObject:@(temperatureMax) forKey:@"temperatureMax"]; [temperatureDict setObject:@(temperatureMin) forKey:@"temperatureMin"]; [temperatureDict setObject:@(temperatureAvg) forKey:@"temperatureAvg"]; [temperatureDict setObject:temperatureDetails forKey:@"temperatureDetails"]; [mutableDict setObject:temperatureDict forKey:@"TEMPERATURE"]; }else if (key == KEY_BLOODPRESSURE) { // 血压数据 NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; NSArray *dataArr = [[self class] sepratorData:data]; // 合并一天完整数据 NSMutableData *completeData = [NSMutableData dataWithData:dataArr.firstObject]; for (NSInteger i = 1; i < dataArr.count; i ++) { NSData *itemData = dataArr[i]; [completeData appendData:[itemData subdataWithRange:NSMakeRange(13, itemData.length - 13)]]; } // 日期 NSString *year = [NSString stringWithFormat:@"%ld",[NSString stringWithFormat:@"%02d",bytes[13]].integerValue + 2000]; NSString *month = [NSString stringWithFormat:@"%02d",bytes[14]]; NSString *day = [NSString stringWithFormat:@"%02d",bytes[15]]; NSString *dataDate = [NSString stringWithFormat:@"%@-%@-%@",year,month,day]; NSMutableString *details = [[NSMutableString alloc] init]; NSInteger sbpMax = 0; NSInteger sbpMin = 0; NSInteger sbpAvg = 0; NSInteger sbpTempTotal = 0; NSInteger dbpMax = 0; NSInteger dbpMin = 0; NSInteger dbpAvg = 0; NSInteger dbpTempTotal = 0; // 详情数据拼接 NSInteger count = (completeData.length - 13) / 8; for (int i = 0; i < count; i ++) { NSData *contonData = [completeData subdataWithRange:NSMakeRange(13 + i * 8, 8)]; Byte *buffer = (Byte *)[contonData bytes]; NSString *hour = [NSString stringWithFormat:@"%02d",buffer[3]]; NSString *minute = [NSString stringWithFormat:@"%02d",buffer[4]]; NSString *second = [NSString stringWithFormat:@"%02d",buffer[5]]; NSString *sbp = [NSString stringWithFormat:@"%02d",buffer[6]]; NSString *dbp = [NSString stringWithFormat:@"%02d",buffer[7]]; //(收缩压值|舒张压值|时间戳,...) long long timeStamp = [NSString changeTimeToMinutes:[NSString stringWithFormat:@"%@-%@-%@-%@-%@-%@",year,month,day,hour,minute,second]]; [details appendString:[NSString stringWithFormat:@"%@|%@|%lld",sbp,dbp,timeStamp]]; if (i < count - 1) { [details appendString:@","]; } if (sbp.integerValue > sbpMax) { sbpMax = sbp.integerValue; } if (sbp.integerValue < sbpMin || sbpMin == 0) { sbpMin = sbp.integerValue; } sbpTempTotal += sbp.integerValue; if (dbp.integerValue > dbpMax) { dbpMax = dbp.integerValue; } if (dbp.integerValue < dbpMin || dbpMin == 0) { dbpMin = dbp.integerValue; } dbpTempTotal += dbp.integerValue; } sbpAvg = sbpTempTotal / count; dbpAvg = dbpTempTotal / count; [dict setObject:dataDate forKey:@"dataDate"]; [dict setObject:@(sbpMax) forKey:@"sbpMax"]; [dict setObject:@(sbpMin) forKey:@"sbpMin"]; [dict setObject:@(sbpAvg) forKey:@"sbpAvg"]; [dict setObject:@(dbpMax) forKey:@"dbpMax"]; [dict setObject:@(dbpMin) forKey:@"dbpMin"]; [dict setObject:@(dbpAvg) forKey:@"dbpAvg"]; [dict setObject:details forKey:@"details"]; [mutableDict setObject:dict forKey:@"BLOODPRESSURE"]; }else if (key == KEY_BLOODOXYGEN) { // 血氧数据 NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; NSArray *dataArr = [[self class] sepratorData:data]; // 合并一天完整数据 NSMutableData *completeData = [NSMutableData dataWithData:dataArr.firstObject]; for (NSInteger i = 1; i < dataArr.count; i ++) { NSData *itemData = dataArr[i]; [completeData appendData:[itemData subdataWithRange:NSMakeRange(13, itemData.length - 13)]]; } // 日期 NSString *year = [NSString stringWithFormat:@"%ld",[NSString stringWithFormat:@"%02d",bytes[13]].integerValue + 2000]; NSString *month = [NSString stringWithFormat:@"%02d",bytes[14]]; NSString *day = [NSString stringWithFormat:@"%02d",bytes[15]]; NSString *dataDate = [NSString stringWithFormat:@"%@-%@-%@",year,month,day]; NSMutableString *details = [[NSMutableString alloc] init]; NSInteger bloodOxygenMax = 0; NSInteger bloodOxygenMin = 0; NSInteger bloodOxygenAvg = 0; NSInteger tempTotal = 0; // 详情数据拼接 NSInteger count = (completeData.length - 13) / 7; for (int i = 0; i < count; i ++) { NSData *contonData = [completeData subdataWithRange:NSMakeRange(13 + i * 7, 7)]; Byte *buffer = (Byte *)[contonData bytes]; NSString *hour = [NSString stringWithFormat:@"%02d",buffer[3]]; NSString *minute = [NSString stringWithFormat:@"%02d",buffer[4]]; NSString *second = [NSString stringWithFormat:@"%02d",buffer[5]]; NSString *value = [NSString stringWithFormat:@"%02d",buffer[6]]; //(血氧值|时间戳,..) long long timeStamp = [NSString changeTimeToMinutes:[NSString stringWithFormat:@"%@-%@-%@-%@-%@-%@",year,month,day,hour,minute,second]]; [details appendString:[NSString stringWithFormat:@"%@|%lld",value,timeStamp]]; if (i < count - 1) { [details appendString:@","]; } if (value.integerValue > bloodOxygenMax) { bloodOxygenMax = value.integerValue; } if (value.integerValue < bloodOxygenMin || bloodOxygenMin == 0) { bloodOxygenMin = value.integerValue; } tempTotal += value.integerValue; } bloodOxygenAvg = tempTotal / count; [dict setObject:dataDate forKey:@"dataDate"]; [dict setObject:@(bloodOxygenMax) forKey:@"bloodOxygenMax"]; [dict setObject:@(bloodOxygenMin) forKey:@"bloodOxygenMin"]; [dict setObject:@(bloodOxygenAvg) forKey:@"bloodOxygenAvg"]; [dict setObject:details forKey:@"details"]; [mutableDict setObject:dict forKey:@"BLOODOXYGEN"]; } else if (key == KEY_SPORTMODEL) { // 1.分割手环GPS运动模式数据处理 NSArray *dataArr = [[self class] sepratorData:data]; // 2.分别合并成完整包 NSMutableArray *completeDataArr = [[NSMutableArray alloc] init]; [completeDataArr addObject:dataArr.firstObject]; NSMutableData *tempCompleteData = [[NSMutableData alloc] init]; NSData *temptimeData = nil; for (NSInteger i = 1; i < dataArr.count; i ++) { NSData *data = dataArr[i]; // 无数据不做拼接 if (data.length <= 13) { continue; } // 比较运动时间判断是否为同一条数据 NSData *timeData = [data subdataWithRange:NSMakeRange(13+3, 6)]; BOOL isNewKey = ![temptimeData isEqualToData:timeData]; if (isNewKey) { tempCompleteData = [[NSMutableData alloc] init]; [tempCompleteData appendData:data]; [completeDataArr addObject:tempCompleteData]; }else { [tempCompleteData appendData:[data subdataWithRange:NSMakeRange(13, data.length - 13)]]; [completeDataArr replaceObjectAtIndex:completeDataArr.count - 1 withObject:tempCompleteData]; } temptimeData = timeData; } // 3.拆分多条运动每条为二维数组 NSMutableArray *perSportCompleteDataArr = [[NSMutableArray alloc] init]; NSMutableArray *perTempArr = [[NSMutableArray alloc] init]; for (NSInteger i = 0; i < completeDataArr.count; i ++) { NSData *completeData = completeDataArr[i]; NSData *sportData = [completeData subdataWithRange:NSMakeRange(13, completeData.length - 13)]; Byte *buffer = (Byte *)[sportData bytes]; NSInteger sportKey = [[NSString stringWithFormat:@"%02d",buffer[0]] integerValue]; if (sportKey == KEY_SPORTMODEL_SPORT) { if (perTempArr.count > 0) { [perSportCompleteDataArr addObject:perTempArr]; perTempArr = [[NSMutableArray alloc] init]; } [perTempArr addObject:completeData]; }else { [perTempArr addObject:completeData]; } if (i == completeDataArr.count - 1 && perTempArr.count > 0) { [perSportCompleteDataArr addObject:perTempArr]; } } // 4.遍历解析不同运动完整包 & 合并完整运动模型 NSMutableArray *sportDictArr = [[NSMutableArray alloc] init]; for (NSArray *completeDataArr in perSportCompleteDataArr) { NSMutableDictionary *sportDict = [[NSMutableDictionary alloc] init]; for (NSData *completeData in completeDataArr) { NSData *sportData = [completeData subdataWithRange:NSMakeRange(13, completeData.length - 13)]; Byte *buffer = (Byte *)[sportData bytes]; [L2DataParse hexStringFromData:sportData]; NSInteger sportKey = [[NSString stringWithFormat:@"%02d",buffer[0]] integerValue]; if (sportKey == KEY_SPORTMODEL_SPORT && sportData.length >= 58) { NSInteger version = [[NSString stringWithFormat:@"%02d",buffer[1]] integerValue]; NSInteger sportType = [[NSString stringWithFormat:@"%02d",buffer[2]] integerValue]; NSString *year = [NSString stringWithFormat:@"%ld",[NSString stringWithFormat:@"%02d",buffer[3]].integerValue + 2000]; NSString *month = [NSString stringWithFormat:@"%02d",buffer[4]]; NSString *day = [NSString stringWithFormat:@"%02d",buffer[5]]; NSString *hour = [NSString stringWithFormat:@"%02d",buffer[6]]; NSString *minute = [NSString stringWithFormat:@"%02d",buffer[7]]; NSString *second = [NSString stringWithFormat:@"%02d",buffer[8]]; NSString *dataDate = [NSString stringWithFormat:@"%@-%@-%@ %@:%@:%@",year,month,day,hour,minute,second]; NSInteger duration = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(9, 4)] integerValue]; NSInteger distance = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(13, 4)] integerValue]; NSInteger calorie = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(17, 4)] integerValue]; NSInteger stepNumber = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(21, 4)] integerValue]; NSInteger heartMax = [[NSString stringWithFormat:@"%02d",buffer[25]] integerValue]; NSInteger heartMin = [[NSString stringWithFormat:@"%02d",buffer[26]] integerValue]; NSInteger heartAvg = [[NSString stringWithFormat:@"%02d",buffer[27]] integerValue]; NSInteger stepFrequencyMax = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(28, 2)] integerValue]; NSInteger stepFrequencyAvg = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(30, 2)] integerValue]; NSInteger stepFrequencyMin = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(32, 2)] integerValue]; NSInteger paceMax = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(34, 2)] integerValue]; NSInteger paceAvg = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(36, 2)] integerValue]; NSInteger paceMin = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(38, 2)] integerValue]; NSInteger startAltitude = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(40, 2)] integerValue]; NSInteger endAltitude = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(42, 2)] integerValue]; NSInteger gpsCount = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(44, 4)] integerValue]; NSInteger kmCount = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(48, 2)] integerValue]; NSInteger stepCount = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(50, 2)] integerValue]; NSInteger heartCount = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(52, 4)] integerValue]; NSInteger trainDetailCount = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(56, 2)] integerValue]; [sportDict setObject:@(version) forKey:@"version"]; [sportDict setObject:@(sportType) forKey:@"sportType"]; [sportDict setObject:dataDate forKey:@"dataDate"]; [sportDict setObject:@(duration) forKey:@"duration"]; [sportDict setObject:@(distance) forKey:@"distance"]; CGFloat calorieKcal = calorie / 1000.0; [sportDict setObject:@(calorieKcal) forKey:@"calorie"]; [sportDict setObject:@(stepNumber) forKey:@"stepNumber"]; [sportDict setObject:@(heartMax) forKey:@"heartMax"]; [sportDict setObject:@(heartMin) forKey:@"heartMin"]; [sportDict setObject:@(heartAvg) forKey:@"heartAvg"]; [sportDict setObject:@(stepFrequencyMax) forKey:@"stepFrequencyMax"]; [sportDict setObject:@(stepFrequencyAvg) forKey:@"stepFrequencyAvg"]; [sportDict setObject:@(stepFrequencyMin) forKey:@"stepFrequencyMin"]; [sportDict setObject:@(paceMax) forKey:@"paceMax"]; [sportDict setObject:@(paceAvg) forKey:@"paceAvg"]; [sportDict setObject:@(paceMin) forKey:@"paceMin"]; [sportDict setObject:@(startAltitude) forKey:@"startAltitude"]; [sportDict setObject:@(endAltitude) forKey:@"endAltitude"]; [sportDict setObject:@(gpsCount) forKey:@"gpsCount"]; [sportDict setObject:@(kmCount) forKey:@"kmCount"]; [sportDict setObject:@(stepCount) forKey:@"stepCount"]; [sportDict setObject:@(heartCount) forKey:@"heartCount"]; [sportDict setObject:@(trainDetailCount) forKey:@"trainDetailCount"]; } // GPS数据解析 if (sportKey == KEY_SPORTMODEL_GPS && sportData.length >= (6 + 11)) { NSInteger count = [[NSString stringWithFormat:@"%02d",buffer[1]] integerValue]; NSInteger timestamp = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(2, 4)] integerValue]; NSString *dataDate = [BLETools nsdateToTime:timestamp formatStr:@"yyyy-MM-dd-HH-mm"]; NSMutableString *gpsDeatail = [[NSMutableString alloc] init]; NSInteger realCount = (sportData.length - 6) / 11; for (int i = 0; i < realCount; i ++) { NSData *contonData = [sportData subdataWithRange:NSMakeRange(6 + i * 11, 11)]; Byte *buffer = (Byte *)[contonData bytes]; NSInteger interval = [[NSString stringWithFormat:@"%02d",buffer[0]] integerValue]; NSInteger latitude = [[[self class]HexToUnsignedInt:contonData dataRange:NSMakeRange(1, 4)] integerValue]; NSInteger longitude = [[[self class]HexToUnsignedInt:contonData dataRange:NSMakeRange(5, 4)] integerValue]; NSInteger altitude = [[[self class]HexToUnsignedInt:contonData dataRange:NSMakeRange(9, 2)] integerValue]; /// GPS数组(时间差|纬度|经度|海拔,...) [gpsDeatail appendFormat:@"%ld|%.6lf|%.6lf|%ld",interval, latitude / 1000000.0, longitude / 1000000.0, altitude]; if (i < realCount - 1) { [gpsDeatail appendString:@","]; } } [sportDict setObject:@(timestamp) forKey:@"gpsTimestamp"]; [sportDict setObject:gpsDeatail forKey:@"gpsDeatail"]; } // 心率数据解析 if (sportKey == KEY_SPORTMODEL_HRS && sportData.length >= (6 + 2)) { NSInteger count = [[NSString stringWithFormat:@"%02d",buffer[1]] integerValue]; NSInteger timestamp = [[[self class]HexToUnsignedInt:sportData dataRange:NSMakeRange(2, 4)] integerValue]; NSString *dataDate = [BLETools nsdateToTime:timestamp formatStr:@"yyyy-MM-dd-HH-mm"]; NSMutableString *hrsDetail = [[NSMutableString alloc] init]; NSInteger realCount = (sportData.length - 6) / 2; for (int i = 0; i < realCount; i ++) { NSData *contonData = [sportData subdataWithRange:NSMakeRange(6 + i * 2, 2)]; Byte *buffer = (Byte *)[contonData bytes]; NSInteger interval = [[NSString stringWithFormat:@"%02d",buffer[0]] integerValue]; NSInteger hrvalue = [[NSString stringWithFormat:@"%02d",buffer[1]] integerValue]; /// GPS数组(时间差|纬度|经度|海拔,...) [hrsDetail appendFormat:@"%ld|%ld",interval, hrvalue]; if (i < realCount - 1) { [hrsDetail appendString:@","]; } } [sportDict setObject:@(timestamp) forKey:@"hrsTimestamp"]; [sportDict setObject:hrsDetail forKey:@"hrsDetail"]; } } [sportDictArr addObject:sportDict]; } [mutableDict setObject:sportDictArr forKey:@"SPORT"]; // 其他分组数据 // #define KEY_SPORTMODEL_GPS 0xB0 // #define KEY_SPORTMODEL_KM 0xB1 // #define KEY_SPORTMODEL_STEP 0xB2 // #define KEY_SPORTMODEL_HRS 0xB3 // #define KEY_SPORTMODEL_SWIM 0xB4 } return mutableDict; } + (NSString *)hexStringFromString:(NSString *)string{ NSData *myD = [string dataUsingEncoding:NSUTF8StringEncoding]; Byte *bytes = (Byte *)[myD bytes]; NSString *hexStr=@""; for(int i=0;i<[myD length];i++) { NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];///16进制数 if([newHexStr length]==1) hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr]; else hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr]; } return hexStr; } + (NSString *)hexStringFromData:(NSData *)data { if (!data) { return @""; } Byte *bytes = (Byte *)[data bytes]; //下面是Byte转换为16进制。 NSString *hexStr=@""; for(int i=0;i<[data length];i++) { NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];///16进制数 if([newHexStr length]==1) hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr]; else hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr]; } NSLog(@"bytes 的16进制数为:%@",hexStr); return hexStr; } /** 分割数据 @param data 数据源 @return 包含分割后data的数组 */ + (NSArray *)sepratorData:(NSData *)data { NSMutableArray *mutableArr = [[NSMutableArray alloc]init]; NSData *seprator = [DataSeparator dataUsingEncoding:NSUTF8StringEncoding]; // 新建索引优化分割数据流的性能 modify by fangtao 2018.12.01 const int nSeparatorSize = 4; NSUInteger currentLocation = 0; // 当前遍历到的字节流的位置 while (currentLocation < data.length) { // 在copyData中查找是否有"!@#$" 分隔字节流 NSRange sepratorRange = [data rangeOfData:seprator options:0 range:NSMakeRange(currentLocation, data.length - currentLocation)]; NSData *subData = nil; if (sepratorRange.length == nSeparatorSize) { subData = [data subdataWithRange:NSMakeRange(currentLocation, sepratorRange.location - currentLocation)]; // 变更循环条件 currentLocation = sepratorRange.location + nSeparatorSize; } else { subData = [data subdataWithRange:NSMakeRange(currentLocation, data.length - currentLocation)]; // 变更循环条件 currentLocation = data.length; } // 子字节流长度大于0 才加入到字节流数组中 if (subData.length > 0) { [mutableArr addObject:subData]; } } return mutableArr; } /** JSON格式字符串转数组或字典 @param JSONString 字符串 @return 数组或字典 */ + (id)parseJSONStringToNSDictionary:(NSString *)JSONString { NSData *JSONData = [JSONString dataUsingEncoding:NSUTF8StringEncoding]; NSError *err; id object = [NSJSONSerialization JSONObjectWithData:JSONData options:NSJSONReadingMutableLeaves error:&err]; if (err) { NSLog(@"错误:不是JSON格式的字符串"); return nil; } return object; } /** 16进账转单精度 @param data 16进制数据 @param range 范围 @return 单精度 */ + (NSString *)HexToFloat:(NSData *)data dataRange:(NSRange)range { NSData *tempData = [data subdataWithRange:range]; float f = *((float *)tempData.bytes); return [NSString stringWithFormat:@"%.3f",f]; } /** 16进制转双精度 @param data 16进制数据 @param range 范围 @return 双精度 */ + (NSString *)HexToDouble:(NSData *)data dataRange:(NSRange)range { NSData *tempData = [data subdataWithRange:range]; double df = *((double *)tempData.bytes); return [NSString stringWithFormat:@"%lf",df]; } /** * 16进制转10进制数字(手环经纬度坐标转换使用) * * @param data data * * @return 十进制数据 */ + (double)HexToCoordinates:(NSData *)data dataRange:(NSRange)range { NSData *tempData = [data subdataWithRange:range]; NSString *tempDataStr = [tempData.description substringWithRange:NSMakeRange(1, tempData.length *2 )]; double decimalism= (int)strtoll([tempDataStr UTF8String],0,16) / pow(10, 6); return decimalism; } /** * 16进制转10进制数字(有符号) * * @param data data * * @return 十进制数据 */ + (NSString *)HexToInt:(NSData *)data dataRange:(NSRange)range { NSData *tempData = [data subdataWithRange:range]; Byte *bytes = (Byte *)[tempData bytes]; int len = (int)tempData.length; int res = bytesToInt(bytes, len); if (len == 2) { return [NSString stringWithFormat:@"%d", (short)res]; } return [NSString stringWithFormat:@"%d", res]; // NSString *tempDataStr = [tempData.description substringWithRange:NSMakeRange(1, tempData.length *2 )]; // NSString *tempStr = [NSString stringWithFormat:@"%lu",strtoul([tempDataStr UTF8String],0,16)]; // int decimalism = tempStr.intValue; // if (tempData.length == 2) { // // 2字节有符号 // short temp = (short)decimalism; // return [NSString stringWithFormat:@"%d",temp]; // } // return [NSString stringWithFormat:@"%d",decimalism]; } /** * 16进制转10进制数字 (无符号) * * @param data data * * @return 十进制数据 */ + (NSString *)HexToUnsignedInt:(NSData *)data dataRange:(NSRange)range { NSData *tempData = [data subdataWithRange:range]; Byte *bytes = (Byte *)[tempData bytes]; return [NSString stringWithFormat:@"%u", bytesToInt(bytes, (int)tempData.length)]; // unsigned int decimal = *((unsigned int *)tempData.bytes); // NSString *deciamlism = [NSString stringWithFormat:@"%d", decimal]; // // NSString *tempDataStr = [tempData.description substringWithRange:NSMakeRange(1, tempData.length *2 )]; // // 转无符号长整形 // NSString *decimalism=[NSString stringWithFormat:@"%lu",strtoul([tempDataStr UTF8String],0,16)]; // return decimalism; } /** 16进制转10进制数字 (无符号/小端) @param data data @return NSUInteger 十进制数据 */ + (NSInteger)HexToUnsignedNSInteger:(NSData *)data { NSUInteger value = (*(NSUInteger*)([data bytes])); return value; } /** byte数组转成无符号整数 add by fangtao 2018.12.01 @param src byte数组 @param nSize 数组长度 @return unsigned数值 */ int bytesToInt(Byte *src, int nSize) { int value = 0; for (int i = 0; i> i; [cycleStr appendString:[NSString stringWithFormat:@"%d",temp]]; } return cycleStr; } /** 十进制转二进制字符串(逆序) */ + (NSString *)cycleIntToReverseString:(int)cycle { int n = 7; int mask = 1<<(n-1); NSMutableString *cycleStr = [[NSMutableString alloc]init]; for (int i = 1; i<=n; i++) { [cycleStr insertString:[NSString stringWithFormat:@"%d", (cycle & mask)==0?0:1] atIndex:0]; cycle <<= 1; } return cycleStr; } /** 获取时间戳字符串 @param time 2017-01-01-01-01格式的时间 @return 时间戳字符串 */ + (NSString *)getTimestampWithTime:(NSString *)time { if (!time.length) { return @""; } NSArray *arr = [time componentsSeparatedByString:@"-"]; NSDateFormatter *inputFormatter = [[NSDateFormatter alloc] init]; [inputFormatter setCalendar: [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]]; [inputFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]]; switch (arr.count) { case 3: [inputFormatter setDateFormat:@"yy-MM-dd"]; break; case 4: [inputFormatter setDateFormat:@"yy-MM-dd-HH"]; break; case 5: [inputFormatter setDateFormat:@"yy-MM-dd-HH-mm"]; break; case 6: [inputFormatter setDateFormat:@"yy-MM-dd-HH-mm-ss"]; break; default: break; } NSDate* inputDate = [inputFormatter dateFromString:time]; NSString *timestamp = [NSString stringWithFormat:@"%ld",(long)[inputDate timeIntervalSince1970]]; return timestamp; } //获取16进制字符串 + (NSString *)data2HexString: (NSData *) data { NSString *string = data.description; string = [string stringByReplacingOccurrencesOfString:@"<" withString:@""]; string = [string stringByReplacingOccurrencesOfString:@">" withString:@""]; string = [string stringByReplacingOccurrencesOfString:@" " withString:@""]; return string; } @end