// // ELMeatProbeBoxBleParser.m // AILinkBleSDK // // Created by LarryZhang on 2023/2/16. // #import "ELMeatProbeBoxBleParser.h" #import "ELMeatProbeBoxBleHeader.h" #import @interface ELMeatProbeBoxBleParser () @property (nonatomic, strong) ELMeatProbeBoxBleBoxStatusModel *boxStatusModel; @property (nonatomic, strong) ELMeatProbeBoxBleProbeStatusModel *probeStatusModel; @end @implementation ELMeatProbeBoxBleParser - (instancetype)init { if (self = [super init]) { _boxStatusModel = [[ELMeatProbeBoxBleBoxStatusModel alloc] init]; _probeStatusModel = [[ELMeatProbeBoxBleProbeStatusModel alloc] init]; } return self; } #pragma mark - 解析包 - (void)parseA7Payload:(NSData *)payloadData { UInt8 *bytes = (Byte *)payloadData.bytes; // UInt8 len = payloadData.length; UInt8 cmd = bytes[0]; switch (cmd) { case ELMeatProbeBoxCMDMcuUploadStatus_Type02: [self handelMcuUploadStatus:payloadData]; break; case ELMeatProbeBoxCMDCustomData_Type03: [self handelCustomData:payloadData]; break; case ELMeatProbeBoxCMDAppSwitchUnit_Type04: [self handelSwitchUnit:payloadData]; break; default: break; } } - (void)handelCustomData:(NSData *)payloadData { UInt8 *bytes = (Byte *)payloadData.bytes; UInt8 len = payloadData.length; BOOL state = bytes[1]; NSData *mac = [payloadData subdataWithRange:NSMakeRange(2, 6)]; Byte *bytesMac = (Byte *)mac.bytes; NSString *macString = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", bytesMac[5], bytesMac[4], bytesMac[3], bytesMac[2], bytesMac[1], bytesMac[0]]; NSData *customData = [payloadData subdataWithRange:NSMakeRange(8, len - 8)]; if (self.delegate && [self.delegate respondsToSelector:@selector(meatProbeBoxBleParser:state:mac:customData:)]) { [self.delegate meatProbeBoxBleParser:self state:state mac:macString customData:customData]; } } - (void)handelSwitchUnit:(NSData *)payloadData { UInt8 *bytes = (Byte *)payloadData.bytes; //UInt8 len = payloadData.length; ELDeviceTemperatureUnit unit = bytes[1]; if (self.delegate && [self.delegate respondsToSelector:@selector(meatProbeBoxBleParser:unit:)]) { [self.delegate meatProbeBoxBleParser:self unit:unit]; } } - (void)handelMcuUploadStatus:(NSData *)payloadData { UInt8 *bytes = (Byte *)payloadData.bytes; UInt8 len = payloadData.length; _boxStatusModel.version = bytes[1]; UInt8 probeMaxCount = bytes[2]; if (probeMaxCount < 1) { return;//探针数排错 } _boxStatusModel.probeMaxCount = probeMaxCount; UInt8 probeCount = bytes[3]; if (probeCount > probeMaxCount) { return;//探针数排错 } if (len < 1 + 8 + 16 * probeCount) { return;//数据长度排错 } _boxStatusModel.probeCount = probeCount; _boxStatusModel.batteryStatus = bytes[4] >> 7; _boxStatusModel.batteryPercent = bytes[4] & 0x7F; _boxStatusModel.unit = bytes[5]; UInt8 reserved = bytes[6]; reserved = bytes[7]; reserved = bytes[8]; double timestamp = [[NSDate date] timeIntervalSince1970]; _boxStatusModel.timestamp = timestamp; // for (int i=0, j=9+16*i; i= probeCount) { [_probeStatusModel makeInvalid]; _probeStatusModel.timestamp = timestamp; if (self.delegate && [self.delegate respondsToSelector:@selector(meatProbeBoxBleParser:boxStatus:probeStatus:offline:)]) { [self.delegate meatProbeBoxBleParser:self boxStatus:_boxStatusModel probeStatus:_probeStatusModel offline:YES]; } continue; } UInt16 temp = (bytes[j+7] << 8) | bytes[j+8]; _probeStatusModel.internalTemperatureRaw = temp; _probeStatusModel.internalTemperatureUnit = (temp & 0x8000) ? ELDeviceTemperatureUnit_F : ELDeviceTemperatureUnit_C; _probeStatusModel.internalTemperature = (temp & 0x4000) ? -(temp & 0x3FFF) : (temp & 0x3FFF); temp = (bytes[j+9] << 8) | bytes[j+10]; _probeStatusModel.ambientTemperatureRaw = temp; _probeStatusModel.ambientTemperatureUnit = (temp & 0x8000) ? ELDeviceTemperatureUnit_F : ELDeviceTemperatureUnit_C; _probeStatusModel.ambientTemperature = (temp & 0x4000) ? -(temp & 0x3FFF) : (temp & 0x3FFF); #if DEBUG // _probeStatusModel.ambientTemperature += 40; #endif UInt8 battery = bytes[j+11]; _probeStatusModel.batteryRaw = battery; _probeStatusModel.batteryStatus = battery >> 7; _probeStatusModel.batteryPercent = battery & 0x7F; _probeStatusModel.insertStatusRaw = bytes[j+12]; _probeStatusModel.timestamp = timestamp; if (self.delegate && [self.delegate respondsToSelector:@selector(meatProbeBoxBleParser:boxStatus:probeStatus:offline:)]) { [self.delegate meatProbeBoxBleParser:self boxStatus:_boxStatusModel probeStatus:_probeStatusModel offline:NO]; } } } @end @implementation ELMeatProbeBoxBleBoxStatusModel #pragma mark ---- description - (NSString *)description { NSMutableString *desc = [NSStringFromClass([self class]) stringByAppendingString:@": {\n"].mutableCopy; unsigned int count; Ivar *ivar = class_copyIvarList([self class], &count); for (int i = 0 ; i < count ; i++) { Ivar iv = ivar[i]; const char *name = ivar_getName(iv); NSString *strName = [NSString stringWithUTF8String:name]; //利用KVC取值 id value = [self valueForKey:strName]; [desc appendString:[NSString stringWithFormat:@" %@: %@,\n", strName, value]]; } free(ivar); [desc appendString:@"}"]; return desc; } - (NSString *)debugDescription { return [self description]; } @end @implementation ELMeatProbeBoxBleProbeStatusModel //数据无效 - (void)makeInvalid { self.internalTemperatureRaw = 0xFFFF; self.internalTemperatureUnit = 0; self.internalTemperature = 0; self.ambientTemperatureRaw = 0xFFFF; self.ambientTemperatureUnit = 0; self.ambientTemperature = 0; self.batteryRaw = 0xFF; self.batteryStatus = 0; self.batteryPercent = 0; self.insertStatusRaw = 0; } #pragma mark ---- description - (NSString *)description { NSMutableString *desc = [NSStringFromClass([self class]) stringByAppendingString:@": {\n"].mutableCopy; unsigned int count; Ivar *ivar = class_copyIvarList([self class], &count); for (int i = 0 ; i < count ; i++) { Ivar iv = ivar[i]; const char *name = ivar_getName(iv); NSString *strName = [NSString stringWithUTF8String:name]; //利用KVC取值 id value = [self valueForKey:strName]; [desc appendString:[NSString stringWithFormat:@" %@: %@,\n", strName, value]]; } free(ivar); [desc appendString:@"}"]; return desc; } - (NSString *)debugDescription { return [self description]; } @end