You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1318 lines
67 KiB

//
// 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 <CoreLocation/CoreLocation.h>
#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;
}
// 闹钟 525bytes
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) {
// 首条开始时间若是在0900 - 2100之内,则设置为2100
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) {
// 最后的结束时间处理(结束时间大于900,默认900
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(@"bytes16进制数为:%@",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<nSize; i++) {
value |= (src[i] & 0xff) << (8 * (nSize - i - 1));
}
return value;
}
/**
* 16进制字符串转10进制数字
*
* @param hexString 16进制字符串
*
* @return 十进制数据
*/
+ (NSString *)intFromHexSrting:(NSString *)hexString {
NSString * temp10 = [NSString stringWithFormat:@"%lu",strtoul([hexString UTF8String],0,16)];
return temp10;
}
/**
将周期int类型转成位字符串(十进制转二进制字符串)
*/
+ (NSString *)cycleIntToString:(int)cycle {
NSMutableString *cycleStr = [[NSMutableString alloc] init];
for (int i = 0; i < 7; i ++ ) {
int temp = cycle;
temp = temp & (1<<i);
temp = temp >> 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