import pandas as pd import numpy as np import bisect import datetime import BatParam class BatDiag: def __init__(self, df_bms): #参数初始化 self.df_bms=df_bms self.vin=df_bms['VIN'] self.model=df_bms['VehModel'] self.sn=df_bms['SN'] self.packcrnt=df_bms['PackCrnt'] self.packvolt=df_bms['PackVolt'] self.bmssoc=df_bms['PackSoc'] self.isor=df_bms['InsulationRss'] self.enmtemp=df_bms['EnmTemp'] self.bmsstate=df_bms['BMSSta'].fillna(0) self.bmstime= pd.to_datetime(df_bms['Time'], format='%Y-%m-%d %H:%M:%S') CellVoltNums=df_bms['CellVoltTotalCount'] CellTempNums=df_bms['CellMinTempNum'] self.cellvolt_name=['CellVolt'+str(x) for x in range(1,CellVoltNums+1)] self.celltemp_name=['CellTemp'+str(x) for x in range(1,CellTempNums+1)] #寻找当前行数据的所有温度值................................................................................... def _celltemp_get(self,num): celltemp = np.array(self.df_bms.loc[num,self.celltemp_name]) return celltemp #获取当前行所有电压数据............................................................................................ def _cellvolt_get(self,num): cellvolt = np.array(self.df_bms.loc[num,self.cellvolt_name]/1000) return cellvolt #..........................................................电池故障诊断功能.................................................................. def diag(self, df_diag_ram, df_soh, df_sor, df_adjust_param, df_pack_param, df_algo_param): # df_res=pd.DataFrame(columns=['start_time', 'end_time', 'vin', 'sn', 'model', 'fault_code', 'fault_reason', 'fault_advice', 'fault_location']) bmssoc_st=self.bmssoc[0] celltemp_stnum=0 end_time='0000-00-00 00:00:00' ah_accum=0 #SOC卡滞初始参数 cellvoltvalid=1 voltdsc_time=0 voltfail_time=0 voltloose_time=0 voltstray_time=0 tempstray_time=0 packvoltvalid_time=0 tempvalid_time=0 cov_time=0 cuv_time=0 cdv_time=0 pov_time=0 puv_time=0 ot_time=0 ut_time=0 dt_time=0 rt_time=0 disoc_time=0 chgoc_time=0 isor_time=0 sor=eval(df_sor.loc[0,'sor']) sor_mean=np.mean(sor) for i in range(1,len(self.df_volt)-1): df_diag_now=df_diag_ram[df_diag_ram['end_time']=='0000-00-00 00:00:00'] #电压诊断功能......................................................................................................................................... if i<=1: time1=self.bmstime[i-1] time2=self.bmstime[i] cellvolt2=self._cellvolt_get(i) cellvoltmin2=min(cellvolt2) cellvoltmax2=max(cellvolt2) cellvoltmin_index2=list(cellvolt2).index(cellvoltmin2) cellvoltmax_index2=list(cellvolt2).index(cellvoltmax2) cellvolt1=self._cellvolt_get(i-1) cellvoltmin1=min(cellvolt1) cellvoltmax1=max(cellvolt1) cellvoltmin_index1=list(cellvolt1).index(cellvoltmin1) cellvoltmax_index1=list(cellvolt1).index(cellvoltmax1) cellvolt1_std=np.std(cellvolt1) cellvolt1_mean=np.mean(cellvolt1) cellvolt1_3sigma=(cellvolt1-cellvolt1_mean)/cellvolt1_std cellvolt2_std=np.std(cellvolt2) cellvolt2_mean=np.mean(cellvolt2) cellvolt2_3sigma=(cellvolt2-cellvolt2_mean)/cellvolt2_std celltemp1=self._celltemp_get(i-1) celltemp2=self._celltemp_get(i) celltempmin1=min(celltemp1) celltempmin2=min(celltemp2) celltempmax1=max(celltemp1) celltempmax2=max(celltemp2) celltemp1_std=np.std(celltemp1) celltemp1_mean=np.mean(celltemp1) celltemp1_3sigma=(np.array(celltemp1)-celltemp1_mean)/celltemp1_std celltemp2_std=np.std(celltemp2) celltemp2_mean=np.mean(celltemp2) celltemp2_3sigma=(np.array(celltemp2)-celltemp2_mean)/celltemp2_std else: time1=self.bmstime[i-1] time2=self.bmstime[i] cellvolt1=cellvolt2 cellvoltmin1=cellvoltmin2 cellvoltmax1=cellvoltmax2 cellvoltmin_index1=cellvoltmin_index2 cellvoltmax_index1=cellvoltmax_index2 cellvolt2=self._cellvolt_get(i) cellvoltmin2=min(cellvolt2) cellvoltmax2=max(cellvolt2) cellvoltmin_index2=list(cellvolt2).index(cellvoltmin2) cellvoltmax_index2=list(cellvolt2).index(cellvoltmax2) cellvolt1_std=cellvolt2_std cellvolt1_mean=cellvolt2_mean cellvolt1_3sigma=cellvolt2_3sigma cellvolt2_std=np.std(cellvolt2) cellvolt2_mean=np.mean(cellvolt2) cellvolt2_3sigma=(cellvolt2-cellvolt2_mean)/cellvolt2_std #电芯电压无效-1.......................................................................................................................................... if not 'C309' in list(df_diag_now['fault_code']): #当前故障中没有该故障,则判断是否发生该故障 #电芯电压断线 if (cellvoltmin2<2 and cellvoltmax2>4.5 and abs(cellvoltmax_index2-cellvoltmin_index2)==1) and (cellvoltmin1<2 and cellvoltmax1>4.5 and abs(cellvoltmax_index1-cellvoltmin_index1)==1): #电压断线故障进入 cellvoltvalid=0 voltdsc_time=voltdsc_time+(time2-time1).total_seconds() if voltdsc_time>df_adjust_param.loc[1,'confirm_time']: #持续时间 fault_code='C309' # faultlv=3 # faultinfo='电芯电压无效' fault_reason='电芯电压采样线断线' fault_location='电芯{}'.format([cellvoltmin_index2+1, cellvoltmax_index2+1]) fault_advice='召回电池包,进行检修' # influence='失去对电芯电压监测' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] voltdsc_time=0 else: pass elif (cellvoltmin2<2 and cellvoltmax2>4.5 and abs(cellvoltmax_index2-cellvoltmin_index2)==1) and (cellvoltmin1>2.5 and cellvoltmax1<4.3): #连续跳变 cellvoltvalid=0 voltdsc_time=voltdsc_time+(time2-time1).total_seconds() if voltdsc_time>df_adjust_param.loc[1,'confirm_time']: fault_code='C309' # faultlv=3 # faultinfo='电芯电压无效' fault_reason='电芯电压采样线断线' fault_location='电芯{}'.format([cellvoltmin_index2+1, cellvoltmax_index2+1]) fault_advice='召回电池包,进行检修' # influence='失去对电芯电压监测' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] voltdsc_time=0 else: pass #电芯电压超限 elif ((cellvoltmin2<1 and cellvoltmin1<1) or (cellvoltmax2>5 and cellvoltmax1>5)): cellvoltvalid=0 voltdsc_time=0 voltfail_time=voltfail_time+(time2-time1).total_seconds() if voltfail_time>df_adjust_param.loc[1,'confirm_time']: #持续时间 fault_code='C309' # faultlv=3 # faultinfo='电芯电压无效' fault_reason='电芯电压采样电路异常' fault_location='电芯{}'.format(list(np.argwhere(cellvolt2<1)+1)+list(np.argwhere(cellvolt2>5)+1)) fault_advice='召回电池包,进行检修' # influence='失去对电芯电压监测' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] voltfail_time=0 else: pass elif (cellvoltmin2<1 and cellvoltmin1>2.5) or (cellvoltmax2>5 and cellvoltmax1<4.5): #连续跳变 cellvoltvalid=0 voltdsc_time=0 voltfail_count=voltfail_count+1 if voltfail_count>=3: fault_code='C309' # faultlv=3 # faultinfo='电芯电压无效' fault_reason='数据通讯异常' fault_location='电芯{}'.format(list(np.argwhere(cellvolt2<1)+1)+list(np.argwhere(cellvolt2>5)+1)) fault_advice='检修数据传输链路' # influence='失去对电芯电压监测' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] voltfail_time=0 else: pass #电芯电压松动 elif cellvoltmin2>2 and cellvoltmax2<4.5 and cellvoltmin1>2 and cellvoltmax1<4.5: voltdsc_time=0 voltfail_time=0 if (min(cellvolt1_3sigma)<-4 and max(cellvolt1_3sigma)>4) and (min(cellvolt2_3sigma)<-4 and max(cellvolt2_3sigma)>4) and (cellvoltmax2-cellvoltmin2)>0.15 and (cellvoltmax1-cellvoltmin1)>0.15: #连续发生 cellvoltvalid=0 voltloose_time=voltloose_time+(time2-time1).total_seconds() if voltloose_time>df_adjust_param.loc[1,'confirm_time']: fault_code='C309' # faultlv=3 # faultinfo='电芯电压无效' fault_reason='电芯电压采样线松动' fault_location='电芯{}'.format([cellvoltmin_index2+1, cellvoltmax_index2+1]) fault_advice='召回电池包,进行检修' # influence='失去对电芯电压监测' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] voltloose_time=0 else: pass else: voltloose_time=0 else: voltdsc_time=0 voltfail_time=0 voltloose_time=0 else: cellvoltvalid=0 if cellvoltmin2>2 and cellvoltmax2<4.5 and cellvoltmin1>2 and cellvoltmax1<4.5 and (min(cellvolt1_3sigma)>-4 and max(cellvolt1_3sigma)<4) and (min(cellvolt2_3sigma)>-4 and max(cellvolt2_3sigma)<4): voltfail_time=voltfail_time+(time2-time1).total_seconds() if voltfail_time>df_adjust_param.loc[1,'remove_time']: cellvoltvalid=1 df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C309'].index[-1], 'end_time'] = time2 voltfail_time=0 else: voltfail_time=0 #电芯电压诊断............................................................................................................................................ if cellvoltvalid==1: #电芯过压-2............................................................................................................................................. if not 'C401' in list(df_diag_now['fault_code']): #当前故障中没有该故障,则判断是否发生该故障 if cellvoltmax2>df_adjust_param.loc[2,'threshold'] and cellvoltmax1>df_adjust_param.loc[2,'threshold']: #二级过压进入 cov_time=cov_time+(time2-time1).total_seconds() if cov_time>df_adjust_param.loc[2,'confirm_time']: fault_code='C401' # faultlv=4 # faultinfo='电芯过压' fault_location='电芯{}'.format(list(np.argwhere(cellvolt2>df_adjust_param.loc[2,'threshold'])+1)) # influence='长时间过压会导致电池析锂,存在电池安全与寿命衰减过快风险' cellocvmax=cellvoltmax2-self.packcrnt[i]*sor_mean*2 #内阻反推OCV cellsocmax=np.interp(cellocvmax,df_pack_param.iloc[0]['charge_ocv_v'],df_pack_param.iloc[0]['charge_ocv_soc']) #ocv反查表得到SOC if self.bmssoc[i]<90 and self.packcrnt[i]>-df_pack_param.iloc[0]['capacity']/10 and self.packcrnt[i-1]>-df_pack_param.iloc[0]['capacity']/10: fault_reason='BMS计算SOC偏低' fault_advice='优化SOC算法' elif self.bmssoc[i]df_adjust_param.loc[2,'confirm_time']: df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C401'].index[-1], 'end_time'] = time2 cov_time=0 else: pass else: cov_time=0 #欠压诊断-3................................................................................................................. if not 'C202' in list(df_diag_now['fault_code']): #当前故障中没有该故障,则判断是否发生该故障 if cellvoltmin2df_adjust_param.loc[3,'confirm_time']: fault_code='C202' # faultlv=2 # faultinfo='电芯{}欠压' fault_location='电芯{}'.format(list(np.argwhere(cellvolt210 and self.packcrnt[i]cellsocmin+10: fault_reason='BMS计算SOC偏高' fault_advice='优化SOC算法' elif self.packcrnt[i-1]>df_pack_param.iloc[0]['capacity']/2 or self.packcrnt[i]>df_pack_param.iloc[0]['capacity']/2: fault_reason='放电电流过大' fault_advice='优化充放电功率限值' else: fault_reason='1.BMS软件策略BUG,2.继电器粘连' fault_advice='检修电池包' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] cuv_time=0 else: pass else: cuv_time=0 else: if cellvoltmin2>df_adjust_param.loc[3,'threshold']+0.1 and cellvoltmin1>df_adjust_param.loc[3,'threshold']+0.1: cuv_time=cuv_time+(time2-time1).total_seconds() if cuv_time>df_adjust_param.loc[3,'confirm_time']: df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C202'].index[-1], 'end_time'] = time2 cuv_time=0 else: pass else: cuv_time=0 #电芯压差大-4..................................................................................................................................................... if not 'C104' in list(df_diag_now['fault_code']): #当前故障中没有该故障,则判断是否发生该故障 if (cellvoltmax2-cellvoltmin2)>df_adjust_param.loc[4,'threshold'] and (cellvoltmax1-cellvoltmin1)>df_adjust_param.loc[4,'threshold']: #二级电芯压差 cdv_time=cdv_time+(time2-time1).total_seconds() if cdv_time>df_adjust_param.loc[4,'confirm_time']: fault_code='C104' # faultlv=1 # faultinfo='电芯电压一致性差' fault_location='电芯{}'.format([cellvoltmin_index2+1, cellvoltmax_index2+1]) fault_advice='更换模组' # influence='容量/内阻/自放电不一致,影响电池充放电性能' if (not df_soh.empty) and (df_soh.loc[0,'cellsohmax']-df_soh.loc[0,'cellsohmin'])>5: fault_reason='电芯容量一致性差' elif ('C316' in list(df_diag_now['fault_code'])) or ('C317' in list(df_diag_now['fault_code'])): fault_reason='电芯内阻一致性差' elif 'C490' in list(df_diag_now['fault_code']): fault_reason='电芯自放电异常' elif celltempmin1<-5 and celltempmin2<-5 and abs(self.packcrnt[i-1])>df_pack_param.iloc[0]['capacity']/10 and abs(self.packcrnt[i])>df_pack_param.iloc[0]['capacity']/10: fault_reason='电芯低温性能差' fault_advice='优化电芯低温性能' elif self.bmssoc[i-1]<3 and self.self.bmssoc[i]<3: fault_reason='SOC过低' fault_advice='通知用户充电' else: fault_reason='BMS均衡逻辑异常' fault_advice='优化均衡策略' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] cdv_time=0 else: pass else: cdv_time=0 else: if (cellvoltmax2-cellvoltmin2)df_adjust_param.loc[4,'confirm_time']: df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C104'].index[-1], 'end_time'] = time2 cdv_time=0 else: pass else: cdv_time=0 #电芯电压离群-5....................................................................................................................................... if not 'C206' in list(df_diag_now['fault_code']): if (min(cellvolt1_3sigma)<-4 and min(cellvolt2_3sigma)<-4 and cellvolt2_mean-cellvoltmin2>0.02) or (max(cellvolt1_3sigma)>4 and max(cellvolt2_3sigma)>4 and cellvoltmax2-cellvolt2_mean>0.02): voltstray_time=voltstray_time+(time2-time1).total_seconds() if voltstray_time>df_adjust_param.loc[5,'confirm_time']: fault_code='C206' # faultlv=2 # faultinfo='电芯电压离群' fault_location='电芯{}'.format([cellvoltmin_index2+1, cellvoltmax_index2+1]) fault_advice='更换模组' # influence='容量/内阻/自放电不一致,影响电池充放电性能' if (not df_soh.empty) and (df_soh.loc[0,'cellsohmax']-df_soh.loc[0,'cellsohmin'])>5: fault_reason='电芯容量一致性差' elif ('C316' in list(df_diag_now['fault_code'])) or ('C317' in list(df_diag_now['fault_code'])): fault_reason='电芯内阻一致性差' elif 'C490' in list(df_diag_now['fault_code']): fault_reason='电芯自放电异常' elif celltempmin1<-5 and celltempmin2<-5 and abs(self.packcrnt[i-1])>df_pack_param.iloc[0]['capacity']/10 and abs(self.packcrnt[i])>df_pack_param.iloc[0]['capacity']/10: fault_reason='电芯低温性能差' fault_advice='优化电芯低温性能' elif self.bmssoc[i-1]<3 and self.self.bmssoc[i]<3: fault_reason='SOC过低' fault_advice='通知用户充电' else: fault_reason='BMS均衡逻辑异常' fault_advice='优化均衡策略' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] voltstray_time=0 else: pass else: voltstray_time=0 else: if min(cellvolt1_3sigma)>-3 and min(cellvolt2_3sigma)>-3 and max(cellvolt1_3sigma)<3 and max(cellvolt2_3sigma)<3: voltstray_time=voltstray_time+(time2-time1).total_seconds() if voltstray_time>df_adjust_param.loc[4,'confirm_time']: df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C206'].index[-1], 'end_time'] = time2 voltstray_time=0 else: pass else: voltstray_time=0 else: cov_time=0 cuv_time=0 cdv_time=0 voltstray_time=0 #电池包诊断-6..................................................................................................................................... packvolt1=self.packvolt[i-1] packvolt2=self.packvolt[i] if not 'C304' in list(df_diag_now['fault_code']): if packvolt2<2*df_pack_param.iloc[0]['cellvoltnum'] or packvolt2>4.5*df_pack_param.iloc[0]['cellvoltnum'] or (cellvoltvalid==1 and abs(packvolt2-sum(cellvolt2))>10): #电池包电压有效性 packvoltvalid=0 packvoltvalid_time=packvoltvalid_time+(time2-time1).total_seconds() if packvoltvalid_time>df_adjust_param.loc[6,'confirm_time']: fault_code='304' # faultlv=3 # faultinfo='电池包电压无效' fault_reason='1.电池包电压采样电路异常,2.数据通讯异常' fault_location='电池包电压' fault_advice='召回电池包,进行检修' # influence='失去对电池包电压监测' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] packvoltvalid_time=0 else: pass else: packvoltvalid=1 packvoltvalid_time=0 else: packvoltvalid=0 if packvolt1>2.2*df_pack_param.iloc[0]['cellvoltnum'] and packvolt2<4.3*df_pack_param.iloc[0]['cellvoltnum']: packvoltvalid_time=packvoltvalid_time+(time2-time1).total_seconds() if packvoltvalid_time>df_adjust_param.loc[6,'confirm_time']: packvoltvalid=1 df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C304'].index[-1], 'end_time'] = time2 packvoltvalid_time=0 else: pass else: packvoltvalid_time=0 if packvoltvalid==1: #电池包过压-7................................................................................................... if not 'C402' in list(df_diag_now['fault_code']): #当前故障中没有该故障,则判断是否发生该故障 if packvolt1>df_adjust_param.loc[7,'threshold'] and packvolt2>df_adjust_param.loc[7,'threshold']: #电池包过压二级进入 pov_time=pov_time+(time2-time1).total_seconds() if pov_time>df_adjust_param.loc[7,'confirm_time']: fault_code='C402' # faultlv=4 # faultinfo='电池包过压' fault_location='电池包电压' # influence='长时间过压会导致电池析锂,存在电池安全与寿命衰减过快风险' cellocvmax=cellvoltmax2-self.packcrnt[i]*sor_mean*2 #内阻反推OCV cellsocmax=np.interp(cellocvmax,df_pack_param.iloc[0]['charge_ocv_v'],df_pack_param.iloc[0]['charge_ocv_soc']) #ocv反查表得到SOC if self.bmssoc[i]<90 and self.packcrnt[i]>-df_pack_param.iloc[0]['capacity']/10 and self.packcrnt[i-1]>-df_pack_param.iloc[0]['capacity']/10: fault_reason='BMS计算SOC偏低' fault_advice='优化SOC算法' elif self.bmssoc[i]df_adjust_param.loc[7,'confirm_time']: df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C402'].index[-1], 'end_time'] = time2 pov_time=0 else: pass else: pov_time=0 #电池包欠压-8....................................................................................................................................... if not 'C203' in list(df_diag_now['fault_code']): #当前故障中没有该故障,则判断是否发生该故障 if packvolt1df_adjust_param.loc[8,'confirm_time']: fault_code='C203' # faultlv=2 # faultinfo='电池包欠压' fault_location='电池包电压' # influence='欠压可能导致电池过放,严重过放会导致负极集流体溶解,进而发生内短路风险' cellocvmin=cellvoltmin2+-self.packcrnt[i]*sor_mean*2 #内阻反推OCV cellsocmin=np.interp(cellocvmin,df_pack_param.iloc[0]['discharge_ocv_v'],df_pack_param.iloc[0]['discharge_ocv_soc']) #ocv反查表得到SOC if self.bmssoc[i]>10 and self.packcrnt[i]cellsocmin+10: fault_reason='BMS计算SOC偏高' fault_advice='优化SOC算法' elif self.packcrnt[i-1]>df_pack_param.iloc[0]['capacity']/2 or self.packcrnt[i]>df_pack_param.iloc[0]['capacity']/2: fault_reason='放电电流过大' fault_advice='优化充放电功率限值' else: fault_reason='1.BMS软件策略BUG,2.继电器粘连' fault_advice='检修电池包' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] puv_time=0 else: pass else: puv_time=0 else: if packvolt1>df_adjust_param.loc[8,'threshold']+10 and packvolt2>df_adjust_param.loc[8,'threshold']+10: puv_time=puv_time+(time2-time1).total_seconds() if puv_time>df_adjust_param.loc[8,'remove_time']: df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C203'].index[-1], 'end_time'] = time2 puv_time=0 else: pass else: puv_time=0 else: pov_time=0 puv_time=0 packvoltvalid_time=0 #温度有效性判断-9................................................................................................................................................ if not 'C301' in list(df_diag_now['fault_code']): if celltempmax2>int(eval(df_algo_param.loc[9,'global_param'])['tempuplmt']) or celltempmin2df_adjust_param.loc[9,'confirm_time']: fault_code='301' # faultlv=3 # faultinfo='电芯温度无效' fault_reason='1.温度采样电路异常,2.数据通讯异常' fault_location='温度探针{}'.format(list(np.argwhere(np.array(celltemp2)int(eval(df_algo_param.loc[9,'global_param'])['tempuplmt']))+1)) fault_advice='召回电池包,进行检修' # influence='失去对电池温度监测' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] tempvalid_time=0 else: pass else: celltempvalid=1 tempvalid_time=0 else: celltempvalid=0 if -25df_adjust_param.loc[9,'remove_time']: df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C304'].index[-1], 'end_time'] = time2 tempvalid_time=0 else: pass else: tempvalid_time=0 if celltempvalid==1: #过温判断-10............................................................................................................. if not 'C302' in list(df_diag_now['fault_code']): #当前故障中没有该故障,则判断是否发生该故障 if celltempmax1>df_adjust_param.loc[10,'threshold'] and celltempmax2>df_adjust_param.loc[10,'threshold']: #二级高温进入 ot_time=ot_time+(time2-time1).total_seconds() if ot_time>df_adjust_param.loc[10,'confirm_time']: fault_code='C302' # faultlv=3 # faultinfo='电芯温度过高' fault_location='温度探针{}'.format(list(np.argwhere(np.array(celltemp2)>df_adjust_param.loc[10,'threshold'])+1)) fault_advice='禁止充放电,并开启电池冷却功能' # influence='高温下充放电,SEI膜增长加速,导致容量衰减过快,温度过高则存在热失控风险' if max(celltemp1_3sigma)>3 and max(celltemp2_3sigma)>3: fault_reason='Busbar连接异常' fault_advice='检修电池包' elif sum(self.packcrnt[:i]*self.packvolt[:i])/(1000*(i+1))>50: fault_reason='电池持续输出大功率' fault_advice='优化电池充放电功率限值' else: fault_reason='1.冷却液温度过高,2.冷却水泵异常,3.Busbar连接异常' fault_advice='检修电池包' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] ot_time=0 else: pass else: ot_time=0 else: #ram当前故障中有该故障,则判断是否退出该故障 if celltempmax1df_adjust_param.loc[10,'remove_time']: df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C302'].index[-1], 'end_time'] = time2 ot_time=0 else: pass else: ot_time=0 #欠温判断-11................................................................................................................. if not 'C102' in list(df_diag_now['fault_code']): #当前故障中没有该故障,则判断是否发生该故障 if celltempmin1df_adjust_param.loc[11,'confirm_time']: fault_code='C102' # faultlv=1 # faultinfo='电芯温度过低' fault_location='温度探针{}'.format(list(np.argwhere(np.array(celltemp2)10 and self.enmtemp[i]-celltempmin2>10: fault_reason='温度检测系统异常' fault_advice='检修电池包' elif self.bmssoc[i-1]<5 and self.bmssoc[i]<5: fault_reason='电池包SOC过低' fault_advice='通知用户进行充电' else: fault_reason='PTC加热系统异常' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] ut_time=0 else: pass else: ut_time=0 else: #ram当前故障中有该故障,则判断是否退出该故障 if celltempmax1>df_adjust_param.loc[11,'threshold']+2 and celltempmax2>df_adjust_param.loc[11,'threshold']+2: #二级高温恢复 ut_time=ut_time+(time2-time1).total_seconds() if ut_time>df_adjust_param.loc[11,'remove_time']: df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C102'].index[-1], 'end_time'] = time2 ut_time=0 else: pass else: ut_time=0 #温差判断-12............................................................................................................................. if not 'C103' in list(df_diag_now['fault_code']): #当前故障中没有该故障,则判断是否发生该故障 if (celltempmax1-celltempmin1)>df_adjust_param.loc[12,'threshold'] and (celltempmax2-celltempmin2)>df_adjust_param.loc[12,'threshold']: #二级温差进入 dt_time=dt_time+(time2-time1).total_seconds() if dt_time>df_adjust_param.loc[12,'confirm_time']: fault_code='C103' # faultlv=1 # faultinfo='电芯温差过大' fault_location='温度探针{}'.format([list(celltemp2).index(celltempmin2)+1,list(celltemp2).index(celltempmax2)+1]) # influence='存在电芯的老化速率不一致的风险' if self.enmtemp[i-1]>0 and self.enmtemp>0 and (('C316' in list(df_diag_now['fault_code'])) or ('C317' in list(df_diag_now['fault_code']))): fault_reason='电芯内阻不一致' fault_advice='更换模组' elif self.enmtemp[i-1]>10 and self.enmtemp>10: fault_reason='Busbar连接异常' fault_advice='检修电池包' elif self.enmtemp[i-1]<-10 and self.enmtemp<-10: fault_reason='环境温度过低' fault_advice='合理优化低温充放电功率限值,并开启水泵' else: fault_reason='电池包冷却/加热系统设计不合理' fault_advice='合理优化电池包冷却/加热系统' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] dt_time=0 else: pass else: dt_time=0 else: #ram当前故障中有该故障,则判断是否退出该故障 if (celltempmax1-celltempmin1)df_adjust_param.loc[12,'threshold']-5: #二级温差恢复 dt_time=dt_time+(time2-time1).total_seconds() if dt_time>df_adjust_param.loc[12,'remove_time']: df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C103'].index[-1], 'end_time'] = time2 dt_time=0 else: pass else: dt_time=0 #温度离群判断-13............................................................................................................................. if not 'C105' in list(df_diag_now['fault_code']): #当前故障中没有该故障,则判断是否发生该故障 if (max(celltemp1_3sigma)>3 and max(celltemp2_3sigma)>3) or (min(celltemp1_3sigma)<-3 and min(celltemp2_3sigma)<-3): tempstray_time=tempstray_time+(time2-time1).total_seconds() if tempstray_time>df_adjust_param.loc[13,'confirm_time']: fault_code='C105' # faultlv=1 # faultinfo='电芯温度离群' fault_location='温度探针{}'.format([list(celltemp2).index(celltempmax2)+1,list(celltemp2).index(celltempmin2)+1]) # influence='存在电芯的老化速率不一致的风险' if self.enmtemp[i-1]>0 and self.enmtemp>0 and (('C316' in list(df_diag_now['fault_code'])) or ('C317' in list(df_diag_now['fault_code']))): fault_reason='电芯内阻不一致' fault_advice='更换模组' elif self.enmtemp[i-1]>10 and self.enmtemp>10: fault_reason='Busbar连接异常' fault_advice='检修电池包' elif self.enmtemp[i-1]<-10 and self.enmtemp<-10: fault_reason='环境温度过低' fault_advice='合理优化低温充放电功率限值,并开启水泵' else: fault_reason='电池包冷却/加热系统设计不合理' fault_advice='合理优化电池包冷却/加热系统' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] tempstray_time=0 else: tempstray_time=0 else: #ram当前故障中有该故障,则判断是否退出该故障 if (max(celltemp1_3sigma)<3 and max(celltemp2_3sigma)<3) or (min(celltemp1_3sigma)>-3 and min(celltemp2_3sigma)>-3): tempstray_time=tempstray_time+(time2-time1).total_seconds() if tempstray_time>df_adjust_param.loc[13,'remove_time']: df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C105'].index[-1], 'end_time'] = time2 tempstray_time=0 else: pass else: tempstray_time=0 #温升速率-14............................................................................................................................... rtac_time=(time2-self.bmstime[celltemp_stnum]).total_seconds() if rtac_time>60: celltemp_st=np.array(self._celltemp_get(celltemp_stnum)) celltemprate=(np.array(celltemp2)-celltemp_st)/(rtac_time*60) celltemp_stnum=celltemp_stnum+1 if not 'C303' in list(df_diag_now['fault_code']): #当前故障中没有该故障,则判断是否发生该故障 if max(celltemprate)>df_adjust_param.loc[14,'threshold']: rt_time=rt_time+(time2-time1).total_seconds() if rt_time>df_adjust_param.loc[14,'confirm_time']: fault_code='C303' # faultlv=3 # faultinfo='电芯温升过快' fault_location='温度探针{}'.format((np.argwhere(celltemp_st>df_adjust_param.loc[14,'threshold'])+1).tolist()) # influence='温升速率过快,存在热失控风险' if max(celltemp1_3sigma)>3 and max(celltemp2_3sigma)>3: fault_reason='Busbar连接异常' fault_advice='检修电池包' elif sum(self.packcrnt[:i]*self.packvolt[:i])/(1000*(i+1))>50: fault_reason='电池持续输出大功率' fault_advice='优化电池充放电功率限值' else: fault_reason='1.冷却液温度过高,2.冷却水泵异常,3.Busbar连接异常' fault_advice='检修电池包' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] rt_time=0 else: pass else: rt_time=0 else: #ram当前故障中有该故障,则判断是否退出该故障 if max(celltemprate)<2: rt_time=rt_time+(time2-time1).total_seconds() if rt_timedf_adjust_param.loc[16,'threshold'] and self.packcrnt[i-1]>df_adjust_param.loc[16,'threshold']: disoc_time=disoc_time+(time2-time1).total_seconds() if disoc_time>df_adjust_param.loc[16,'confirm_time']: fault_code='C306' # faultlv=3 # faultinfo='电池放电过流' fault_location='电池包' # influence='长时间过流会导致电池欠压及温升过快' if cellvoltmin1df_adjust_param.loc[16,'remove_time']: df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C306'].index[-1], 'end_time'] = time2 disoc_time=0 else: pass else: disoc_time=0 #充电过流-15................................................................................. if not 'C305' in list(df_diag_now['fault_code']): #当前故障中没有该故障,则判断是否发生该故障 if self.packcrnt[i]df_adjust_param.loc[15,'confirm_time']: fault_code='C305' # faultlv=3 # faultinfo='电池充电过流' fault_location='电池包' # influence='过流会导致电池析锂,存在电池安全与寿命衰减过快风险' if cellvoltmax1>df_adjust_param.loc[2,'threshold']-0.1 and cellvoltmax2>df_adjust_param.loc[2,'threshold']-0.1: fault_reason='BMS控制策略异常' fault_advice='优化BMS控制策略' else: fault_reason='1.充电器异常,2.继电器粘连' fault_advice='停止放电' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] chgoc_time=0 else: pass else: if self.packcrnt[i]>df_adjust_param.loc[15,'threshold']+10 and self.packcrnt[i-1]>df_adjust_param.loc[15,'threshold']+10: chgoc_time=chgoc_time+(time2-time1).total_seconds() if chgoc_time>df_adjust_param.loc[15,'remove_time']: df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C305'].index[-1], 'end_time'] = time2 chgoc_time=0 else: pass else: chgoc_time=0 #SOC故障诊断........................................................................................................................ #SOC卡滞-18 if not 'C106' in list(df_diag_now['fault_code']): #当前故障中没有该故障,则判断是否发生该故障 step=(time2-time1).total_seconds() if step<120: ah_accum=ah_accum-self.packcrnt[i]*step/3600 #ah累计 if abs(ah_accum)>df_pack_param.iloc[0]['capacity']*0.1: bmssoc_now=self.bmssoc[i] if abs(bmssoc_now-bmssoc_st)df_adjust_param.loc[18,'threshold']: #SOC卡滞故障退出 df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C106'].index[-1], 'end_time'] = time2 else: pass #SOC跳变-17.................................................................................................................... bmssoc_last=self.bmssoc[i-1] bmssoc_now=self.bmssoc[i] if not 'C107' in list(df_diag_now['fault_code']): #当前故障中没有该故障,则判断是否发生该故障 if step<70 and abs(bmssoc_now-bmssoc_last)>df_adjust_param.loc[17,'threshold']: #SOC跳变进入 fault_code='C107' # faultlv=1 # faultinfo='电池SOC跳变' fault_location='电池包SOC' if cellvoltvalid==0: fault_reason='电压采样异常' fault_advice='检查电芯电压采样系统' else: fault_reason='BMS软件SOC估算异常' fault_advice='检修BMS软件' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] else: pass else: if abs(bmssoc_now-bmssoc_last)df_adjust_param.loc[19,'confirm_time']: fault_code='C315' # faultlv=3 # faultinfo='绝缘异常' fault_advice='召回车辆,检修高压线路/接插件' if self.isor[i-1]<5 and self.isor[i]<5: fault_reason='绝缘检测系统异常' fault_location='绝缘检测系统' elif self.bmsstate[i-1]==2 or self.bmsstate[i-1]==3: fault_reason='充电桩绝缘异常' fault_location='充电桩' fault_advice='通知用户使用其他充电桩进行充电' elif self.vehstate[i-1]!=2 and self.vehstate[i]!=2: fault_reason='电池包内高压线路/接插件异常' fault_location='电池包内高压线路/接插件' else: fault_reason='电池包外高压线路/接插件异常' fault_location='电池包外高压线路/接插件' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] isor_time=0 else: pass else: isor_time=0 else: if self.isor[i-1]>df_adjust_param.loc[19,'threshold']+100 and self.isor[i]>df_adjust_param.loc[19,'threshold']+100: isor_time=isor_time+(time2-time1).total_seconds() if isor_time>df_adjust_param.loc[19,'remove_time']: df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C315'].index[-1], 'end_time'] = time2 isor_time=0 else: pass else: isor_time=0 # #SOC一致性故障报警.......................................................................................................... # if not self.df_uniform.empty: # cellsoc_diff=self.df_uniform.loc[0,'cellsoc_diff'] # if not 'C201' in list(df_diag_now['fault_code']): #当前故障中没有该故障,则判断是否发生该故障 # if cellsoc_diff>self.param.SocDiff: #SOC一致性差故障进入 # time=self.bmstime[0] # fault_code='C201' # faultlv=0 # faultinfo='电芯{}和{}SOC差过大:{}'.format(int(self.df_uniform.loc[0,'cellmin_num']),int(self.df_uniform.loc[0,'cellmax_num']),cellsoc_diff) # fault_advice='技术介入诊断' # df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.sn, fault_code, faultlv, faultinfo, fault_advice] # else: # pass # else: # if cellsoc_diffdf_adjust_param.loc[20,'threshold']+2: #soh过低故障恢复 df_diag_ram.loc[df_diag_ram[df_diag_ram['fault_code']=='C204'].index[-1], 'end_time'] = time2 else: pass if not 'C205' in list(df_diag_now['fault_code']): #当前故障中没有该故障,则判断是否发生该故障 if cellsoh_diff>df_adjust_param.loc[21,'threshold']: fault_code='C205' # faultlv=2 # faultinfo='电池包容量一致性差' fault_advice='检修电池,更换容量过低的电芯或模组' fault_location='电芯{}'.format(cellsoh_lowindex) fault_advice='更换容量过低的模组/电池包' fault_reason='' df_diag_ram.loc[len(df_diag_ram)]=[time2, end_time, self.vin, self.sn, self.model, fault_code, fault_reason, fault_advice, fault_location] else: pass else: if cellsoh_diff