// // ELMeatProbeScreenBoxBleParser.m // Pods // // Created by Larry Zhang on 2024/2/26. // #import "ELMeatProbeScreenBoxBleParser.h" #import "ELMeatProbeScreenBoxBleBBQParamModel.h" @interface ELMeatProbeScreenBoxBleParser() @end @implementation ELMeatProbeScreenBoxBleParser - (void)parseA7Payload:(nonnull NSData *)payload { NSLog(@"#### parseA7Payload payload:%@", payload.debugDescription); Byte *bytes = (Byte *)payload.bytes; Byte cmd = bytes[0]; switch (cmd) { case ELMeatProbeScreenBoxCMDMcuUploadStatus_Type02: [self parseStatusData:payload]; break; case ELMeatProbeScreenBoxCCMDAppSwitchUnit_Type03: { UInt8 unit = bytes[1]; if (self.delegate && [self.delegate respondsToSelector:@selector(meatProbeScreenBoxBleParser:unit:)]) { [self.delegate meatProbeScreenBoxBleParser:self unit:unit]; } } break; // case ELMeatProbeScreenBoxCCMDAppSwitchUnitResponse_Type04: // break; case ELMeatProbeScreenBoxCMDStartAlarmState_Type05: { Byte i = 1; Byte macBytes[6] = { bytes[i+5], bytes[i+4], bytes[i+3], bytes[i+2], bytes[i+1], bytes[i] }; NSData *macData = [NSData dataWithBytes:macBytes length:6]; i += 6; Byte state = bytes[i]; if (self.delegate && [self.delegate respondsToSelector:@selector(meatProbeScreenBoxBleParser:startAlarmWithState:macData:mac:)]) { [self.delegate meatProbeScreenBoxBleParser:self startAlarmWithState:state macData:macData mac:[self macDataToString:macData]]; } } break; // case ELMeatProbeScreenBoxCMDStartAlarmStateResponse_Type06: // break; case ELMeatProbeScreenBoxCMDStoplAlarm_Type07: { Byte i = 1; Byte macBytes[6] = { bytes[i+5], bytes[i+4], bytes[i+3], bytes[i+2], bytes[i+1], bytes[i] }; NSData *macData = [NSData dataWithBytes:macBytes length:6]; if (self.delegate && [self.delegate respondsToSelector:@selector(meatProbeScreenBoxBleParser:stopAlarmWithMacData:mac:)]) { [self.delegate meatProbeScreenBoxBleParser:self stopAlarmWithMacData:macData mac:[self macDataToString:macData]]; } } break; // case ELMeatProbeScreenBoxCMDStoplAlarmResponse_Type08: // break; case ELMeatProbeScreenBoxCMDSetInfo_Type09: case ELMeatProbeScreenBoxCMDSetInfoResponse_Type0A: { [self parseSetInfoParamData:payload]; } break; default: break; } } - (NSString *)macDataToString:(NSData *)macData { if (macData == nil || macData.length != 6) { return nil; } Byte *bytes = (Byte *)macData.bytes; NSString *str = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0]]; return str; } - (void)parseSetInfoParamData:(NSData *)payload { NSLog(@"##### parseSetInfoParamData payload:%@", payload.debugDescription); if (payload.length != 72) { return; } Byte *bytes = (Byte *)payload.bytes; Byte i = 1; Byte option = bytes[i]; i = 2; Byte supportProbe = bytes[i]; i = 3; NSMutableArray *arr = [NSMutableArray array]; while (i < payload.length) { //探针 1 ELMeatProbeScreenBoxBleBBQParamModel *param = [[ELMeatProbeScreenBoxBleBBQParamModel alloc] init]; param.timestamp = [NSDate date].timeIntervalSince1970; param.macData = [payload subdataWithRange:NSMakeRange(i, 6)]; i += 6; param.state = bytes[i]; i += 1; param.foodType = bytes[i];//if (param.foodType == 0xFF) param.foodType = 0xFE; i += 1; param.targetTemperatureRaw_C = (bytes[i] << 0) | (bytes[i+1] << 8); i += 2; param.targetTemperatureRaw_F = (bytes[i] << 0) | (bytes[i+1] << 8); i += 2; param.ambientMaxTemperatureRaw_C = (bytes[i] << 0) | (bytes[i+1] << 8); i += 2; param.ambientMaxTemperatureRaw_F = (bytes[i] << 0) | (bytes[i+1] << 8); i += 2; param.ambientMinTemperatureRaw_C = (bytes[i] << 0) | (bytes[i+1] << 8); i += 2; param.ambientMinTemperatureRaw_F = (bytes[i] << 0) | (bytes[i+1] << 8); i += 2; param.cookingId = (bytes[i] << 0) | (bytes[i+1] << 8) | (bytes[i+2] << 16) | (bytes[i+3] << 24); i += 4; param.workTime = (bytes[i] << 0) | (bytes[i+1] << 8) | (bytes[i+2] << 16) | (bytes[i+3] << 24); i += 4; param.timerCount = (bytes[i] << 0) | (bytes[i+1] << 8) | (bytes[i+2] << 16) | (bytes[i+3] << 24); i += 4; UInt32 alarmTemperaturePercentU32 = (bytes[i] << 0) | (bytes[i+1] << 8) | (bytes[i+2] << 16) | (bytes[i+3] << 24); float alarmTemperaturePercent = 0; memcpy(&alarmTemperaturePercent, &alarmTemperaturePercentU32, sizeof(UInt32)); param.alarmTemperaturePercent = alarmTemperaturePercent; i += 4; param.foodRawness = bytes[i]; i += 1; param.remarkData = [payload subdataWithRange:NSMakeRange(i, 32)]; i += 32; if (param.state == 0) { [param clearAll]; } [arr addObject:param]; } if (self.delegate && [self.delegate respondsToSelector:@selector(meatProbeScreenBoxBleParser:option:supportProbe:params:)]) { [self.delegate meatProbeScreenBoxBleParser:self option:option supportProbe:supportProbe params:arr.copy]; } } - (void)parseStatusData:(NSData *)payload { if (payload.length != 25) { return; } Byte *bytes = (Byte *)payload.bytes; ELMeatProbeScreenBoxStatusModel *boxStatus = [[ELMeatProbeScreenBoxStatusModel alloc] init]; boxStatus.timestamp = [NSDate date].timeIntervalSince1970; Byte i = 1; boxStatus.version = bytes[i]; i = 2; boxStatus.probeMaxCount = bytes[i]; i = 3; boxStatus.probeCount = bytes[i]; i = 4; boxStatus.batteryStatus = bytes[i] >> 7; boxStatus.batteryPercent = bytes[i] & 0x7F; i = 5; boxStatus.unit = bytes[i]; i = 9; NSMutableArray *arr = [NSMutableArray array]; { ELMeatProbeScreenBoxProbeStatusModel *probeStatus = [[ELMeatProbeScreenBoxProbeStatusModel alloc] init]; probeStatus.timestamp = boxStatus.timestamp; probeStatus.index = bytes[i]; i += 1; NSData *macData = [payload subdataWithRange:NSMakeRange(i, 6)]; probeStatus.macData = macData; i += 6; probeStatus.internalTemperatureRaw = (bytes[i] << 0) | (bytes[i+1] << 8); i += 2; probeStatus.ambientTemperatureRaw = (bytes[i] << 0) | (bytes[i+1] << 8); // 凸(艹皿艹 ) //0x639F (25503) if (probeStatus.ambientTemperatureRaw == 25503) { probeStatus.ambientTemperatureRaw = 0xFFFF; } i += 2; probeStatus.batteryStatus = bytes[i] >> 7; probeStatus.batteryPercent = bytes[i] & 0x7F; probeStatus.batteryRaw = bytes[i]; i += 1; probeStatus.insertStatusRaw = bytes[i]; i += 1; probeStatus.connectState = bytes[i]; i += 3; [arr addObject:probeStatus]; } boxStatus.probeStatusArray = arr.copy; if (self.delegate && [self.delegate respondsToSelector:@selector(meatProbeScreenBoxBleParser:boxStatus:)]) { [self.delegate meatProbeScreenBoxBleParser:self boxStatus:boxStatus]; } } @end @implementation ELMeatProbeScreenBoxStatusModel @end @implementation ELMeatProbeScreenBoxProbeStatusModel - (NSString *)macString { if (self.macData == nil || self.macData.length != 6) { return nil; } Byte *bytes = (Byte *)self.macData.bytes; NSString *str = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0]]; return str; } - (NSInteger)internalTemperature_C { if (self.internalTemperatureRaw == 0xFFFF) { return 0xFFFF; } if (self.internalTemperatureUnit == ELDeviceTemperatureUnit_C) { return self.internalTemperature; } return [self convertF2C:self.internalTemperature]; } - (NSInteger)internalTemperature_F { if (self.internalTemperatureRaw == 0xFFFF) { return 0xFFFF; } if (self.internalTemperatureUnit == ELDeviceTemperatureUnit_F) { return self.internalTemperature; } return [self convertC2F:self.internalTemperature]; } - (NSInteger)internalTemperature { NSInteger value = self.internalTemperatureRaw & 0x3FFF; if (self.internalTemperatureRaw & 0x4000) { value = -value; } return value; } - (ELDeviceTemperatureUnit)internalTemperatureUnit { return self.internalTemperatureRaw >> 15; } - (NSInteger)ambientTemperature_C { if (self.ambientTemperatureRaw == 0xFFFF) { return 0xFFFF; } if (self.ambientTemperatureUnit == ELDeviceTemperatureUnit_C) { return self.ambientTemperature; } return [self convertF2C:self.ambientTemperature]; } - (NSInteger)ambientTemperature_F { if (self.ambientTemperatureRaw == 0xFFFF) { return 0xFFFF; } if (self.ambientTemperatureUnit == ELDeviceTemperatureUnit_F) { return self.ambientTemperature; } return [self convertC2F:self.ambientTemperature]; } - (NSInteger)ambientTemperature { NSInteger value = self.ambientTemperatureRaw & 0x3FFF; if (self.ambientTemperatureRaw & 0x4000) { value = -value; } return value; } - (ELDeviceTemperatureUnit)ambientTemperatureUnit { return self.ambientTemperatureRaw >> 15; } //温度换算 - (float)convertF2C:(float)fahrenheit { return round((fahrenheit - 32) / 1.8); } - (float)convertC2F:(float)celsius { return round(celsius * 1.8 + 32); } @end