/****************************************************************************** * @file protocol_mqtt_bcu.c * @brief protocol_mqtt_bcu * @version V1.0 * @author Gary * @copyright ******************************************************************************/ #include "protocol_mqtt_bcu.h" #include "iso_check.h" #include "soc_calculate.h" #include "sop_calculate.h" #include "version_manager.h" #include "dido_manager.h" #include "fault_manager.h" #include "flash_manager.h" #include "comm_manager.h" #include "hv_adc_manager.h" #include "eeprom_manager.h" #include "signal_manager.h" #include "statistic_manager.h" #include "bmu_manager.h" #include "protocol_comm.h" uint32_t bms_get_baseInfo(uint16_t input) { uint32_t tmp; uint16_t bms_stu = 0; if(bms_get_run_status() == kRunStatus_Init) { bms_stu = 0; } else if(bms_get_run_status() == kRunStatus_Standby) { bms_stu |= 0x1; } else if(bms_get_run_status() == kRunStatus_Chg) { bms_stu |= 0x2; } else if(bms_get_run_status() == kRunStatus_Dis) { bms_stu |= 0x3; } if(bms_get_signal(kSignalIdx_ForbidChg) == kSignalStatus_High) { bms_stu |= 0x10; } if(bms_get_signal(kSignalIdx_ForbidDis) == kSignalStatus_High) { bms_stu |= 0x20; } switch(input) { case 1: tmp = bms_get_statistic_data(kStatisticData_TotalVolt); return tmp; case 2: tmp = bms_get_show_current(); return tmp; case 3: tmp = bms_get_soc() / 100; return tmp; case 4: tmp = bms_get_soh() / 100; return tmp; case 5: tmp = bms_get_soc() / 100; return tmp; case 6: tmp = get_eeprom_data(kEep_RatedTotalVolt,kEepromDataType_Full); return tmp; case 7: tmp = get_eeprom_data(kEep_RatedCapacity,kEepromDataType_Full); return tmp; case 8: tmp = (uint32_t)bms_get_soc()*get_eeprom_data(kEep_RatedCapacity, kEepromDataType_Full)/10000; return tmp; case 9: tmp = get_eeprom_data(kEep_RatedCapacity, kEepromDataType_Full)*get_eeprom_data(kEep_RatedTotalVolt, kEepromDataType_Full)/10000; return tmp; case 10: tmp = (uint32_t)bms_get_soc() * get_eeprom_data(kEep_RatedCapacity, kEepromDataType_Full)/10000*get_eeprom_data(kEep_RatedTotalVolt, kEepromDataType_Full)/10000; return tmp; case 11: tmp = bms_get_bmu_num(); return tmp; case 12: tmp = bms_get_bmu_online_num(); return tmp; case 13: tmp = get_eeprom_data(kEep_CellNum, kEepromDataType_Full); return tmp; case 14: tmp = bms_get_statistic_data(kStatisticData_OnlineCellNum); return tmp; case 15: tmp = get_eeprom_data(kEep_TempNum, kEepromDataType_Full); return tmp; case 16: tmp = bms_get_statistic_data(kStatisticData_OnlineTempNum); return tmp; case 17: tmp = bms_get_sop_data(kSopData_DisCur); return tmp; case 18: tmp = (uint32_t)bms_get_sop_data(kSopData_DisCur)*get_eeprom_data(kEep_RatedTotalVolt, kEepromDataType_Full)/10000; return tmp; case 19: tmp = bms_get_sop_data(kSopData_ChgCur); return tmp; case 20: tmp = (uint32_t)bms_get_sop_data(kSopData_ChgCur)*get_eeprom_data(kEep_RatedTotalVolt, kEepromDataType_Full)/10000; return tmp; case 21: tmp = bms_get_iso_data(kIsoData_PosRes); return tmp; case 22: tmp = bms_get_iso_data(kIsoData_NegRes); return tmp; case 23: tmp = bms_get_statistic_data(kStatisticData_AvgVolt); return tmp; case 24: tmp = bms_get_statistic_data(kStatisticData_VoltDiff); return tmp; case 25: tmp = bms_get_statistic_data(kStatisticData_MaxVolt); return tmp; case 26: tmp = bms_get_statistic_data(kStatisticData_MaxVoltBmuIdx) + 1; return tmp; case 27: tmp = bms_get_statistic_data(kStatisticData_MaxVoltIdx) + 1; return tmp; case 28: tmp = bms_get_statistic_data(kStatisticData_MinVolt); return tmp; case 29: tmp = bms_get_statistic_data(kStatisticData_MinVoltBmuIdx) + 1; return tmp; case 30: tmp = bms_get_statistic_data(kStatisticData_MinVoltIdx) + 1; return tmp; case 31: tmp = bms_get_statistic_data(kStatisticData_AvgTemp); return tmp; case 32: tmp = bms_get_statistic_data(kStatisticData_TempDiff); return tmp; case 33: tmp = bms_get_statistic_data(kStatisticData_MaxTemp); return tmp; case 34: tmp = bms_get_statistic_data(kStatisticData_MaxTempBmuIdx) + 1; return tmp; case 35: tmp = bms_get_statistic_data(kStatisticData_MaxTempIdx) + 1; return tmp; case 36: tmp = bms_get_statistic_data(kStatisticData_MinTemp); return tmp; case 37: tmp = bms_get_statistic_data(kStatisticData_MinTempBmuIdx) + 1; return tmp; case 38: tmp = bms_get_statistic_data(kStatisticData_MinTempIdx) + 1; return tmp; case 39: tmp = (uint16_t)bms_get_cumulate_data(kCumulateData_DayChgCap); return tmp; case 40: tmp = (uint16_t)bms_get_cumulate_data(kCumulateData_DayChgEnergy); return tmp; case 41: tmp = (uint16_t)bms_get_cumulate_data(kCumulateData_DayDisCap); return tmp; case 42: tmp = (uint16_t)bms_get_cumulate_data(kCumulateData_DayDisEnergy); return tmp; case 43: tmp = (uint16_t)bms_get_cumulate_data(kCumulateData_DayChgTime); return tmp; case 44: tmp = (uint16_t)bms_get_cumulate_data(kCumulateData_DayDisTime); return tmp; case 45: tmp = bms_get_cumulate_data(kCumulateData_AccChgCap); return tmp; case 46: tmp = bms_get_cumulate_data(kCumulateData_AccChgEnergy); return tmp; case 47: tmp = bms_get_cumulate_data(kCumulateData_AccDisCap); return tmp; case 48: tmp = bms_get_cumulate_data(kCumulateData_AccDisEnergy); return tmp; case 49: tmp = bms_get_cumulate_data(kCumulateData_AccChgTime); return tmp; case 50: tmp = bms_get_cumulate_data(kCumulateData_AccDisTime); return tmp; case 51: tmp = bms_stu; return tmp; default: return 0; } } uint32_t bms_get_fault_level_1(uint16_t input) { uint32_t tmp = 0; switch(input) { case 1: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_First), 2)) //一级单体过压 { tmp = 1; } else { tmp = 0; } return tmp; case 2: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_First), 3)) //一级单体欠压 { tmp = 1; } else { tmp = 0; } return tmp; case 3: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_First), 4)) //一级单体过温 { tmp = 1; } else { tmp = 0; } return tmp; case 4: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_First), 5)) //一级单体低温 { tmp = 1; } else { tmp = 0; } return tmp; case 5: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_First), 6)) //一级单体压差 { tmp = 1; } else { tmp = 0; } return tmp; case 6: if (bms_get_run_status() == kRunStatus_Chg) { if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_First), 8)) //一级充电电流过大 { tmp = 1; } else { tmp = 0; } } return tmp; case 7: if (bms_get_run_status() == kRunStatus_Dis) { if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_First), 8)) //一级放电电流过大 { tmp = 1; } else { tmp = 0; } } return tmp; case 8: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_First), 14)) //一级SOC过低 { tmp = 1; } else { tmp = 0; } return tmp; case 9: tmp = 0; //一级SOC差异过大 return tmp; case 10: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_First), 15)) //一级绝缘过低 { tmp = 1; } else { tmp = 0; } return tmp; case 11: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_First), 0)) //一级总压过压--组端过压 { tmp = 1; } else { tmp = 0; } return tmp; case 12: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_First), 1)) //一级总压欠压--组端欠压 { tmp = 1; } else { tmp = 0; } case 13: if (KIT_GET_BIT_32(bms_get_fault_single_bit(1, kFaultLevel_First), 12)) //1级极柱过温 { tmp = 1; } else { tmp = 0; } return tmp; case 14: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_First), 9)) //高压异常 { tmp = 1; } else { tmp = 0; } return tmp; case 15: tmp = get_eeprom_data(kEep_TempNum, kEepromDataType_Full); return tmp; case 16: tmp = bms_get_statistic_data(kStatisticData_OnlineTempNum); break; default: return 0; } } uint32_t bms_get_fault_level_2(uint16_t input) { uint32_t tmp = 0; switch(input) { case 1: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Second), 2)) //2级单体过压 { tmp = 1; } else { tmp = 0; } return tmp; case 2: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Second), 3)) //2级单体欠压 { tmp = 1; } else { tmp = 0; } return tmp; case 3: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Second), 4)) //2级单体过温 { tmp = 1; } else { tmp = 0; } return tmp; case 4: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Second), 5)) //2级单体低温 { tmp = 1; } else { tmp = 0; } return tmp; case 5: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Second), 6)) //2级单体压差 { tmp = 1; } else { tmp = 0; } return tmp; case 6: if (bms_get_run_status() == kRunStatus_Chg) { if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Second), 8)) //2级充电电流过大 { tmp = 1; } else { tmp = 0; } } return tmp; case 7: if (bms_get_run_status() == kRunStatus_Dis) { if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Second), 8)) //2级放电电流过大 { tmp = 1; } else { tmp = 0; } } return tmp; case 8: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Second), 14)) //2级SOC过低 { tmp = 1; } else { tmp = 0; } return tmp; case 9: tmp = 0; //一级SOC差异过大 return tmp; case 10: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Second), 15)) //2级绝缘过低 { tmp = 1; } else { tmp = 0; } return tmp; case 11: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Second), 0)) //2级总压过压--组端过压 { tmp = 1; } else { tmp = 0; } return tmp; case 12: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Second), 1)) //2级总压欠压--组端欠压 { tmp = 1; } else { tmp = 0; } case 13: if (KIT_GET_BIT_32(bms_get_fault_single_bit(1, kFaultLevel_Second), 12)) //2级极柱过温 { tmp = 1; } else { tmp = 0; } return tmp; case 14: tmp = bms_get_statistic_data(kStatisticData_OnlineCellNum); return tmp; case 15: tmp = get_eeprom_data(kEep_TempNum, kEepromDataType_Full); return tmp; case 16: tmp = bms_get_statistic_data(kStatisticData_OnlineTempNum); break; default: return 0; } } uint32_t bms_get_fault_level_3(uint16_t input) { uint32_t tmp = 0; switch(input) { case 1: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Third), 2)) //3级单体过压 { tmp = 1; } else { tmp = 0; } return tmp; case 2: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Third), 3)) //3级单体欠压 { tmp = 1; } else { tmp = 0; } return tmp; case 3: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Third), 4)) //3级单体过温 { tmp = 1; } else { tmp = 0; } return tmp; case 4: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Third), 5)) //3级单体低温 { tmp = 1; } else { tmp = 0; } return tmp; case 5: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Third), 6)) //3级单体压差 { tmp = 1; } else { tmp = 0; } return tmp; case 6: if (bms_get_run_status() == kRunStatus_Chg) { if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Third), 8)) //3级充电电流过大 { tmp = 1; } else { tmp = 0; } } return tmp; case 7: if (bms_get_run_status() == kRunStatus_Dis) { if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Third), 8)) //3级放电电流过大 { tmp = 1; } else { tmp = 0; } } return tmp; case 8: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Third), 14)) //3级SOC过低 { tmp = 1; } else { tmp = 0; } return tmp; case 9: tmp = 0; //一级SOC差异过大 return tmp; case 10: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Third), 15)) //3级绝缘过低 { tmp = 1; } else { tmp = 0; } return tmp; case 11: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Third), 0)) //3级总压过压--组端过压 { tmp = 1; } else { tmp = 0; } return tmp; case 12: if (KIT_GET_BIT_32(bms_get_fault_single_bit(0, kFaultLevel_Third), 1)) //3级总压欠压--组端欠压 { tmp = 1; } else { tmp = 0; } case 13: if (KIT_GET_BIT_32(bms_get_fault_single_bit(1, kFaultLevel_Third), 12)) //3级极柱过温 { tmp = 1; } else { tmp = 0; } return tmp; case 14: if (KIT_GET_BIT_32(bms_get_fault_single_bit(1, kFaultLevel_Third), 0)) //继电器粘连 { tmp = 1; } else { tmp = 0; } case 15: if (KIT_GET_BIT_32(bms_get_fault_single_bit(2, kFaultLevel_Third), 9)) //极限故障 { tmp = 1; } else { tmp = 0; } case 16: if (KIT_GET_BIT_32(bms_get_fault_single_bit(1, kFaultLevel_Third), 1)) //预充故障 { tmp = 1; } else { tmp = 0; } case 17: if (KIT_GET_BIT_32(bms_get_fault_single_bit(2, kFaultLevel_Third), 10)) //开路故障 { tmp = 1; } else { tmp = 0; } default: return 0; } } //把这个请按照数据模型填充完毕 const devPointMap bms_points[] = { {"BCU_2", 0, 0, bms_get_total_alarm}, // 总告警 {"BCU_3", 0, 0, bms_get_total_fault}, // 总故障 {"BCU_4", 0, 1, bms_get_fault_level_1}, // 单体过压告警一级 {"BCU_5", 0, 2, bms_get_fault_level_1}, // 单体欠压告警一级 {"BCU_6", 0, 3, bms_get_fault_level_1}, // 单体过温告警一级 {"BCU_7", 0, 4, bms_get_fault_level_1}, // 单体低温告警一级 {"BCU_8", 0, 5, bms_get_fault_level_1}, // 单体压差告警一级 {"BCU_9", 0, 6, bms_get_fault_level_1}, // 充电过流告警一级 {"BCU_10", 0, 7, bms_get_fault_level_1}, // 放电过流告警一级 {"BCU_11", 0, 8, bms_get_fault_level_1}, // SOC过低告警一级 {"BCU_12", 0, 9, bms_get_fault_level_1}, // SOC差异过大告警一级 {"BCU_13", 0, 10, bms_get_fault_level_1}, // 绝缘过低告警一级 {"BCU_14", 0, 1, bms_get_fault_level_2}, // 单体过压告警二级 {"BCU_15", 0, 2, bms_get_fault_level_2}, // 单体欠压告警二级 {"BCU_16", 0, 3, bms_get_fault_level_2}, // 单体过温告警二级 {"BCU_17", 0, 4, bms_get_fault_level_2}, // 单体低温告警二级 {"BCU_18", 0, 5, bms_get_fault_level_2}, // 单体压差告警二级 {"BCU_19", 0, 6, bms_get_fault_level_2}, // 充电过流告警二级 {"BCU_20", 0, 7, bms_get_fault_level_2}, // 放电过流告警二级 {"BCU_21", 0, 8, bms_get_fault_level_2}, // SOC过低告警二级 {"BCU_22", 0, 9, bms_get_fault_level_2}, // SOC差异过大告警二级 {"BCU_23", 0, 10, bms_get_fault_level_2}, // 绝缘过低告警二级 {"BCU_24", 0, 1, bms_get_fault_level_3}, // 单体过压告警三级 {"BCU_25", 0, 2, bms_get_fault_level_3}, // 单体欠压告警三级 {"BCU_26", 0, 3, bms_get_fault_level_3}, // 单体过温告警三级 {"BCU_27", 0, 4, bms_get_fault_level_3}, // 单体低温告警三级 {"BCU_28", 0, 5, bms_get_fault_level_3}, // 单体压差告警三级 {"BCU_29", 0, 6, bms_get_fault_level_3}, // 充电过流告警三级 {"BCU_30", 0, 7, bms_get_fault_level_3}, // 放电过流告警三级 {"BCU_31", 0, 8, bms_get_fault_level_3}, // SOC过低告警三级 {"BCU_32", 0, 9, bms_get_fault_level_3}, // SOC差异过大告警三级 {"BCU_33", 0, 10, bms_get_fault_level_3}, // 绝缘过低告警三级 {"BCU_34", 0, 0, NULL}, // 电芯温度极限告警 {"BCU_35", 0, 0, NULL}, // 电芯电压极限告警 {"BCU_36", 0, 0, NULL}, // 簇间环流1级告警 {"BCU_37", 0, 0, NULL}, // 簇间环流2级告警 {"BCU_38", 0, 0, NULL}, // 簇间环流3级告警 {"BCU_39", 0, 0, NULL}, // 簇间电流差1级告警 {"BCU_40", 0, 0, NULL}, // 簇间电流差2级告警 {"BCU_41", 0, 0, NULL}, // 簇间电流差3级告警 {"BCU_42", 1, 11, bms_get_fault_level_1}, // 组端过压1级告警 {"BCU_43", 1, 11, bms_get_fault_level_2}, // 组端过压2级告警 {"BCU_44", 1, 11, bms_get_fault_level_3}, // 组端过压3级告警 {"BCU_45", 1, 12, bms_get_fault_level_1}, // 组端欠压1级告警 {"BCU_46", 1, 12, bms_get_fault_level_2}, // 组端欠压2级告警 {"BCU_47", 1, 12, bms_get_fault_level_3}, // 组端欠压3级告警 {"BCU_48", 1, 13, bms_get_fault_level_1}, // 极柱过温1级告警 {"BCU_49", 1, 13, bms_get_fault_level_2}, // 极柱过温2级告警 {"BCU_50", 1, 13, bms_get_fault_level_3}, // 极柱过温3级告警 {"BCU_51", 1, 0, NULL}, // AFE温感排线异常 {"BCU_52", 1, 0, NULL}, // AFE电压排线异常 {"BCU_53", 1, 0, NULL}, // 与电池簇通信告警 {"BCU_54", 1, 0, NULL}, // 主从通讯告警 {"BCU_55", 1, 14, bms_get_fault_level_3}, // 继电器粘连告警 {"BCU_56", 1, 15, bms_get_fault_level_3}, // 电池极限故障 {"BCU_57", 1, 0, NULL}, // 熔丝故障 {"BCU_58", 1, 0, NULL}, // 断路器故障 {"BCU_59", 1, 0, NULL}, // 空调故障 {"BCU_60", 1, 0, NULL}, // 消防设备故障 {"BCU_61", 1, 0, NULL}, // 消防火警 {"BCU_62", 1, 0, NULL}, // 消防喷洒 {"BCU_63", 1, 0, NULL}, // AFE故障 {"BCU_64", 1, 14, bms_get_fault_level_1}, // 高压异常 {"BCU_65", 1, 16, bms_get_fault_level_3}, // 预充告警 {"BCU_66", 1, 17, bms_get_fault_level_3}, // 开路故障 {"BCU_67", 1, 1, bms_get_baseInfo}, // 总压 {"BCU_68", 1, 2, bms_get_baseInfo}, // 总电流 {"BCU_69", 1, 3, bms_get_baseInfo}, // SOC {"BCU_70", 1, 4, bms_get_baseInfo}, // SOH {"BCU_71", 1, 5, bms_get_baseInfo}, // SOE {"BCU_72", 1, 6, bms_get_baseInfo}, // 额定总压 {"BCU_73", 1, 7, bms_get_baseInfo}, // 额定容量 {"BCU_74", 1, 8, bms_get_baseInfo}, // 剩余容量 {"BCU_75", 1, 9, bms_get_baseInfo}, // 额定电量 {"BCU_76", 1, 10, bms_get_baseInfo}, // 剩余电量 {"BCU_77", 1, 11, bms_get_baseInfo}, // 从机总数(BMU) {"BCU_78", 1, 12, bms_get_baseInfo}, // 在线从机总数(BMU) {"BCU_79", 1, 13, bms_get_baseInfo}, // 电池总数 {"BCU_80", 1, 14, bms_get_baseInfo}, // 在线电池总数 {"BCU_81", 1, 15, bms_get_baseInfo}, // 温感总数 {"BCU_82", 2, 16, bms_get_baseInfo}, // 在线温感总数 {"BCU_83", 2, 17, bms_get_baseInfo}, // 最大允许放电电流 {"BCU_84", 2, 18, bms_get_baseInfo}, // 最大允许放电功率 {"BCU_85", 2, 19, bms_get_baseInfo}, // 最大允许充电电流 {"BCU_86", 2, 20, bms_get_baseInfo}, // 最大允许充电功率 {"BCU_87", 2, 21, bms_get_baseInfo}, // 正极绝缘阻值 {"BCU_88", 2, 22, bms_get_baseInfo}, // 负极绝缘阻值 {"BCU_89", 2, 23, bms_get_baseInfo}, // 单体平均电压 {"BCU_90", 2, 24, bms_get_baseInfo}, // 单体最大压差 {"BCU_91", 2, 25, bms_get_baseInfo}, // 最高单体电压 {"BCU_92", 2, 26, bms_get_baseInfo}, // 最高单体电压从机号 {"BCU_93", 2, 27, bms_get_baseInfo}, // 最高单体电压编号 {"BCU_94", 2, 28, bms_get_baseInfo}, // 最低单体电压 {"BCU_95", 2, 29, bms_get_baseInfo}, // 最低单体电压从机号 {"BCU_96", 2, 30, bms_get_baseInfo}, // 最低单体电压编号 {"BCU_97", 2, 31, bms_get_baseInfo}, // 单体平均温度 {"BCU_98", 2, 32, bms_get_baseInfo}, // 最大温差 {"BCU_99", 2, 33, bms_get_baseInfo}, // 最高单体温度 {"BCU_100", 2, 34, bms_get_baseInfo}, // 最高单体温度从机号 {"BCU_101", 2, 35, bms_get_baseInfo}, // 最高单体温度编号 {"BCU_102", 2, 36, bms_get_baseInfo}, // 最低单体温度 {"BCU_103", 2, 37, bms_get_baseInfo}, // 最低单体温度从机号 {"BCU_104", 2, 38, bms_get_baseInfo}, // 最低单体温度编号 {"BCU_105", 2, 39, bms_get_baseInfo}, // 日充电容量 {"BCU_106", 2, 40, bms_get_baseInfo}, // 日充电电量 {"BCU_107", 2, 41, bms_get_baseInfo}, // 日放电容量 {"BCU_108", 2, 42, bms_get_baseInfo}, // 日放电电量 {"BCU_109", 2, 43, bms_get_baseInfo}, // 日充电时间 {"BCU_110", 2, 44, bms_get_baseInfo}, // 日放电时间 {"BCU_111", 2, 45, bms_get_baseInfo}, // 累计充电容量 {"BCU_112", 2, 46, bms_get_baseInfo}, // 累计充电电量 {"BCU_113", 2, 47, bms_get_baseInfo}, // 累计放电容量 {"BCU_114", 2, 48, bms_get_baseInfo}, // 累计放电电量 {"BCU_115", 2, 49, bms_get_baseInfo}, // 累计充电时间 {"BCU_116", 2, 50, bms_get_baseInfo}, // 累计放电时间 {"BCU_117", 2, 51, bms_get_baseInfo}, // BCU工作状态 }; const int bms_point_count = sizeof(bms_points) / sizeof(bms_points[0]); /* const char* key; // JSON 中的键,比如 "BCU_"后面不带数字,数据后面通过BCU_pointId组合 uint16_t pointId; // 用于记录开始的测点号,见bcu模型 uint16_t startCellIndex; // 开始的电压序号(入参) uint16_t endCellIndex; // 结束的电压序号(入参) uint32_t (*get_val)(uint16_t); // 对应值的获取函数 */ const devCellPointMap bms_volt_points[] = { {"BCU_", 191, 0, 39,bms_get_baseInfo}, // 1号~40号电池电压 {"BCU_", 191, 40, 79,bms_get_baseInfo}, // 41号~80号电池电压 {"BCU_", 191, 80, 119,bms_get_baseInfo}, // 81号~120号电池电压 {"BCU_", 191, 120, 159,bms_get_baseInfo}, // 121号~160号电池电压 {"BCU_", 191, 160, 199,bms_get_baseInfo}, // 161号~200号电池电压 {"BCU_", 191, 200, 239,bms_get_baseInfo}, // 201号~240号电池电压 {"BCU_", 191, 240, 279,bms_get_baseInfo}, // 241号~280号电池电压 {"BCU_", 191, 280, 319,bms_get_baseInfo}, // 281号~320号电池电压 {"BCU_", 191, 320, 359,bms_get_baseInfo}, // 321号~360号电池电压 {"BCU_", 191, 360, 399,bms_get_baseInfo}, // 361号~400号电池电压 }; const devCellPointMap bms_temp_points[] = { {"BCU_", 611, 0, 39,bms_get_baseInfo}, // 1号~40号电池温度 {"BCU_", 611, 40, 79,bms_get_baseInfo}, // 41号~80号电池温度 {"BCU_", 611, 80, 119,bms_get_baseInfo}, // 81号~120号电池温度 {"BCU_", 611, 120, 159,bms_get_baseInfo}, // 121号~160号电池温度 {"BCU_", 611, 160, 199,bms_get_baseInfo}, // 161号~200号电池温度 }; const int bms_volt_count = sizeof(bms_volt_points) / sizeof(devCellPointMap); const int bms_temp_count = sizeof(bms_temp_points) / sizeof(devCellPointMap); void protocol_build_json(uint16_t groupId) { int val = 0; cJSON* root = cJSON_CreateObject(); cJSON_AddNumberToObject(root, "timeStamp", drv_rtc_get_tick()); // devData 数组 cJSON* devDataArr = cJSON_CreateArray(); cJSON_AddItemToObject(root, "devData", devDataArr); // 构建每一个设备项 cJSON* deviceObj = cJSON_CreateObject(); cJSON_AddItemToArray(devDataArr, deviceObj); cJSON_AddStringToObject(deviceObj, "devType", "4"); cJSON_AddStringToObject(deviceObj, "devName", "BCU"); cJSON_AddStringToObject(deviceObj, "devId", "001"); cJSON_AddStringToObject(deviceObj, "sn", "SN123456"); // 构建 data 对象 cJSON* dataObj = cJSON_CreateObject(); cJSON_AddItemToObject(deviceObj, "data", dataObj); for (int i = 0; i < bms_point_count; ++i) { const devPointMap* point = &bms_points[i]; if(point->groupId == groupId) { if (bms_points[i].get_val != NULL) { val = point->get_val(point->input); } else { val = 0; // 默认值 } } cJSON_AddNumberToObject(dataObj, point->key, val); } // 转为 JSON 字符串 char* json_str = cJSON_PrintUnformatted(root); if (json_str) { drv_mqtt_publish(json_str, strlen(json_str)); cJSON_free(json_str); } cJSON_Delete(root); } void protocol_build_volt_json(devCellPointMap* item) { int val = 0; char key[10] = {0}; cJSON* root = cJSON_CreateObject(); cJSON_AddNumberToObject(root, "timeStamp", drv_rtc_get_tick()); // devData 数组 cJSON* devDataArr = cJSON_CreateArray(); cJSON_AddItemToObject(root, "devData", devDataArr); // 构建每一个设备项 cJSON* deviceObj = cJSON_CreateObject(); cJSON_AddItemToArray(devDataArr, deviceObj); cJSON_AddStringToObject(deviceObj, "devType", "4"); cJSON_AddStringToObject(deviceObj, "devName", "BCU"); cJSON_AddStringToObject(deviceObj, "devId", "001"); cJSON_AddStringToObject(deviceObj, "sn", "SN123456"); // 构建 data 对象 cJSON* dataObj = cJSON_CreateObject(); cJSON_AddItemToObject(deviceObj, "data", dataObj); for (int i = item->startCellIndex; i <= item->endCellIndex; ++i) { const devPointMap* point = item->get_val(i); if (bms_points[i].get_val != NULL) { val = point->get_val(point->input); } else { val = 0; // 默认值 } cJSON_AddNumberToObject(dataObj, point->key, val); } // 转为 JSON 字符串 char* json_str = cJSON_PrintUnformatted(root); if (json_str) { drv_mqtt_publish(json_str, strlen(json_str)); cJSON_free(json_str); } cJSON_Delete(root); } void publish_all_bms_groups(void) { uint8_t max_group = 0; for (size_t i = 0; i < bms_point_count; i++) { if (bms_points[i].groupId > max_group) { max_group = bms_points[i].groupId; } } for (uint8_t g = 0; g <= max_group; g++) { protocol_build_json(g); } } void mqtt_publish_bms_data(uint32_t basetime) { static uint32_t mqtt_cycle_tick = 0; static uint8_t groupMax = 0; uint16_t i = 0; mqtt_cycle_tick += basetime; if(mqtt_cycle_tick > 60000) { mqtt_cycle_tick = 0; publish_all_bms_groups(); } }