123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699 |
- import pandas as pd
- import numpy as np
- import datetime
- from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import BatParam
- class BatDiag:
- def __init__(self,sn,celltype,df_bms,df_diag_ram_sn,df_bms_ram_sn,df_soh,df_uniform): #参数初始化
- self.sn=sn
- self.celltype=celltype
- self.param=BatParam.BatParam(celltype)
- self.df_bms=df_bms
- self.df_uniform=df_uniform
- self.df_soh=df_soh
- self.df_bms_ram=df_bms_ram_sn.copy()
- self.df_diag_ram=df_diag_ram_sn.copy()
- df_bms['时间戳']=pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
- if not df_bms_ram_sn.empty:
- self.df_bms=self.df_bms[self.df_bms['时间戳'] > df_bms_ram_sn.iloc[-1]['time']] #滤除原始数据中的重复数据
- self.df_bms.reset_index(inplace=True,drop=True) #重置索引
-
- self.packcrnt=df_bms['总电流[A]']*self.param.PackCrntDec
- self.packvolt=df_bms['总电压[V]']
- self.bmstime= df_bms['时间戳']
- self.bms_soc=df_bms['SOC[%]']
- self.cellvolt_name=['单体电压'+str(x) for x in range(1,self.param.CellVoltNums+1)]
- # othertemp=['其他温度'+str(x) for x in range(1,self.param.OtherTempNums+1)]
- self.celltemp_name=['单体温度'+str(x) for x in range(1,self.param.CellTempNums+1)]
- # self.celltemp_name=celltemp+othertemp
-
- def diag(self):
- if self.celltype<=50:
- df_res1,df_res2=self._bat_diag()
- return df_res1,df_res2
- else:
- df_res1,df_res2=self._bat_diag()
- return df_res1,df_res2
-
- #寻找当前行数据的所有温度值...................................................................................
- def _celltemp_get(self,num):
- celltemp = list(self.df_bms.loc[num,self.celltemp_name])
- return celltemp
- #获取当前行所有电压数据............................................................................................
- def _cellvolt_get(self,num):
- cellvolt = list(self.df_bms.loc[num,self.cellvolt_name]/1000)
- return cellvolt
- #..........................................电池诊断功能..................................................................
- def _bat_diag(self):
- column_name=['start_time', 'end_time', 'product_id', 'code', 'level', 'info','advice']
- df_res=pd.DataFrame(columns=column_name)
- end_time='0000-00-00 00:00:00'
- ah_accum=0 #SOC卡滞初始参数
- as_chg=0 #过流诊断初始参数
- as_dis=0 #过流诊断初始参数
- cellvoltvalid=1
- voltdsc_time=0
- voltdsc_count=0
- voltfail_time=0
- voltfail_count=0
- voltloose_time=0
- voltloose_count=0
- voltover_time=0
- voltunder_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
-
- for i in range(len(self.df_bms)):
-
- #电压诊断功能.........................................................................................................................................
- if i<1:
- cellvolt2=self._cellvolt_get(i)
- cellvoltmin2=min(cellvolt2)
- cellvoltmax2=max(cellvolt2)
- cellvoltmin_index2=cellvolt2.index(cellvoltmin2)
- cellvoltmax_index2=cellvolt2.index(cellvoltmax2)
- if not self.df_bms_ram.empty:
- time1=self.df_bms_ram.iloc[-1]['time']
- time2=self.bmstime[i]
- cellvolt1=self.df_bms_ram.iloc[-1]['cellvolt']
- cellvoltmin1=min(cellvolt1)
- cellvoltmax1=max(cellvolt1)
- cellvoltmin_index1=cellvolt1.index(cellvoltmin1)
- cellvoltmax_index1=cellvolt1.index(cellvoltmax1)
- else:
- cellvolt1=cellvolt2
- time1=self.bmstime[i]
- time2=self.bmstime[i]
- cellvoltmin1=cellvoltmin2
- cellvoltmax1=cellvoltmax2
- cellvoltmin_index1=cellvoltmin_index2
- cellvoltmax_index1=cellvoltmax_index2
- else:
- time1=self.bmstime[i-1]
- time2=self.bmstime[i]
- cellvolt2=self._cellvolt_get(i)
- cellvoltmin2=min(cellvolt2)
- cellvoltmax2=max(cellvolt2)
- cellvoltmin_index2=cellvolt2.index(cellvoltmin2)
- cellvoltmax_index2=cellvolt2.index(cellvoltmax2)
- cellvolt1=self._cellvolt_get(i-1)
- cellvoltmin1=min(cellvolt1)
- cellvoltmax1=max(cellvolt1)
- cellvoltmin_index1=cellvolt1.index(cellvoltmin1)
- cellvoltmax_index1=cellvolt1.index(cellvoltmax1)
- #电压采样断线..........................................................................................................................................
- if not 'C308' in list(self.df_diag_ram['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>self.param.volt_time: #持续时间
- time=self.bmstime[i]
- code='C308'
- faultlv=3
- faultinfo='电芯{}和{}电压采样断线'.format(cellvoltmin_index2+1, cellvoltmax_index2+1)
- faultadvice='通知用户更换电池,电池返厂维修'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- 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_count=voltdsc_count+1
- if voltdsc_count>=3:
- time=self.bmstime[i]
- code='C308'
- faultlv=3
- faultinfo='电芯{}和{}电压采样断线'.format(cellvoltmin_index2+1, cellvoltmax_index2+1)
- faultadvice='通知用户更换电池,电池返厂维修'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- voltdsc_time=0
- else:
- cellvoltvalid=0
- if cellvoltmin2>2 and cellvoltmax2<4.5 and cellvoltmin1>2 and cellvoltmax1<4.5:
- cellvoltvalid=1
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C308'].index, 'end_time'] = time
- else:
- pass
-
- #电压采样系统失效.............................................................................................................
- if not 'C309' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if (cellvoltmin2<1 and cellvoltmin1<1) or (cellvoltmax2>5 and cellvoltmax1>5):
- cellvoltvalid=0
- voltfail_time=voltfail_time+(time2-time1).total_seconds()
- if voltfail_time>self.param.volt_time: #持续时间
- time=self.bmstime[i]
- code='C309'
- faultlv=3
- faultinfo='电芯电压采样系统失效'
- faultadvice='通知用户更换电池,电池返厂维修'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- elif (cellvoltmin2<1 and cellvoltmin1>2.5) or (cellvoltmax2>5 and cellvoltmax1<4.5): #连续跳变
- cellvoltvalid=0
- voltfail_count=voltfail_count+1
- if voltfail_count>=3:
- time=self.bmstime[i]
- code='C309'
- faultlv=3
- faultinfo='电芯电压采样系统失效'
- faultadvice='通知用户更换电池,电池返厂维修'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- voltfail_time=0
- else:
- cellvoltvalid=0
- if cellvoltmin2>2.5 and cellvoltmax2<4.5 and cellvoltmin1>2.5 and cellvoltmax1<4.5:
- cellvoltvalid=1
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C309'].index, 'end_time'] = time
- else:
- pass
-
- #电压采样线松动.................................................................................................................
- if not 'C208' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if cellvoltmin2>2 and cellvoltmax2<4.5 and cellvoltmin1>2 and cellvoltmax1<4.5:
- cellvolt1_std=np.std(cellvolt1)
- cellvolt1_mean=np.mean(cellvolt1)
- cellvolt1_3sigma=(np.array(cellvolt1)-cellvolt1_mean)/cellvolt1_std
- cellvolt2_std=np.std(cellvolt2)
- cellvolt2_mean=np.mean(cellvolt2)
- cellvolt2_3sigma=(np.array(cellvolt2)-cellvolt2_mean)/cellvolt2_std
- if (min(cellvolt1_3sigma)<-3 and max(cellvolt1_3sigma)>3) and (min(cellvolt2_3sigma)<-3 and max(cellvolt2_3sigma)>3): #连续发生
- cellvoltvalid=0
- voltloose_time=voltloose_time+(time2-time1).total_seconds()
- if voltloose_time>self.param.volt_time:
- time=self.bmstime[i]
- code='C208'
- faultlv=3
- faultinfo='电芯电压{}和{}采样松动'.format(cellvoltmin_index2+1, cellvoltmax_index2+1)
- faultadvice='通知技术人员介入诊断'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- elif (min(cellvolt1_3sigma)>-3 and max(cellvolt1_3sigma)<3) and (min(cellvolt2_3sigma)<-3 and max(cellvolt2_3sigma)>3): #连续跳变
- cellvoltvalid=0
- voltloose_count=voltloose_count+1
- if voltloose_count>=3:
- time=self.bmstime[i]
- code='C208'
- faultlv=3
- faultinfo='电芯电压{}和{}采样松动'.format(cellvoltmin_index2+1, cellvoltmax_index2+1)
- faultadvice='通知技术人员介入诊断'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- voltloose_time=0
- else:
- voltloose_time=0
- else:
- cellvoltvalid=0
- cellvolt1_std=np.std(cellvolt1)
- cellvolt1_mean=np.mean(cellvolt1)
- cellvolt1_3sigma=(np.array(cellvolt1)-cellvolt1_mean)/cellvolt1_std
- cellvolt2_std=np.std(cellvolt2)
- cellvolt2_mean=np.mean(cellvolt2)
- cellvolt2_3sigma=(np.array(cellvolt2)-cellvolt2_mean)/cellvolt2_std
- if(min(cellvolt1_3sigma)>-3 or max(cellvolt1_3sigma)<3) and (min(cellvolt2_3sigma)>-3 or max(cellvolt2_3sigma)<3):
- cellvoltvalid=1
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C208'].index, 'end_time'] = time
- else:
- pass
-
- if cellvoltvalid==1:
- #继电器粘连.............................................................................................................................................
- if not 'C310' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if cellvoltmax2>self.param.CellOvLv2 and cellvoltmax1>self.param.CellOvLv2 and self.packcrnt[i]<0:
- voltover_time=voltover_time+(time2-time1).total_seconds()
- if voltover_time>self.param.volt_time:
- time=self.bmstime[i]
- code='C310'
- faultlv=3
- faultinfo='充电继电器粘连'
- faultadvice='通知技术人员介入诊断'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- voltover_time=0
- else:
- if cellvoltmax2<self.param.CellOvLv2-0.05 and cellvoltmax1<self.param.CellOvLv2-0.05:
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C310'].index, 'end_time'] = time
- else:
- pass
-
- if not 'C311' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if cellvoltmin2<self.param.CellUvLv2 and cellvoltmin1<self.param.CellUvLv2 and self.packcrnt[i]>0:
- voltunder_time=voltunder_time+(time2-time1).total_seconds()
- if voltunder_time>self.param.volt_time:
- time=self.bmstime[i]
- code='C311'
- faultlv=3
- faultinfo='放电继电器粘连'
- faultadvice='通知技术人员介入诊断'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- voltunder_time=0
- else:
- if cellvoltmin2>self.param.CellUvLv2+0.05 and cellvoltmin1>self.param.CellOvLv2+0.05:
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C311'].index, 'end_time'] = time
- else:
- pass
-
- #电芯过压.............................................................................................................................................
- if not 'C501' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if cellvoltmax2>self.param.CellOvLv2 and cellvoltmax1>self.param.CellOvLv2 and self.packcrnt[i]<0: #二级过压进入
- cov_time=cov_time+(time2-time1).total_seconds()
- if cov_time>self.param.volt_time:
- time=self.bmstime[i]
- code='C501'
- faultlv=5
- faultinfo='电芯{}过压'.format(cellvolt1.index(cellvoltmax1)+1)
- faultadvice='联系用户立即停止充电,并通知技术运维人员'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- cov_time=0
- else: #ram当前故障中有该故障,则判断是否退出该故障
- if cellvoltmax2<self.param.CellOvLv1-0.05 and cellvoltmax1<self.param.CellOvLv1-0.05: #二级过压故障恢复
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C501'].index, 'end_time'] = time
- else:
- pass
-
- #欠压诊断.................................................................................................................
- if not 'C202' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if cellvoltmin2<self.param.CellUvLv2 and cellvoltmin1<self.param.CellUvLv2: #二级欠压
- cuv_time=cuv_time+(time2-time1).total_seconds()
- if cuv_time>self.param.volt_time:
- time=self.bmstime[i]
- code='C202'
- faultlv=2
- faultinfo='电芯{}欠压'.format(cellvolt1.index(cellvoltmin1)+1)
- faultadvice='联系用户询问用车场景,技术介入诊断'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- cuv_time=0
- else:
- if cellvoltmin2>self.param.CellUvLv1+0.1 and cellvoltmin1>self.param.CellUvLv1+0.1:
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C202'].index, 'end_time'] = time
- else:
- pass
-
- #电芯压差大.....................................................................................................................................................
- if not 'C104' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if (cellvoltmax2-cellvoltmin2)>self.param.CellVoltDiffLv2 and (cellvoltmax1-cellvoltmin1)>self.param.CellVoltDiffLv2: #二级电芯压差
- cdv_time=cdv_time+(time2-time1).total_seconds()
- if cdv_time>self.param.volt_time:
- time=self.bmstime[i]
- code='C104'
- faultlv=0
- faultinfo='电芯{}和{}压差大'.format(cellvolt1.index(cellvoltmax1)+1,cellvolt1.index(cellvoltmin1)+1)
- faultadvice='技术介入诊断'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- cdv_time=0
- else:
- if (cellvoltmax2-cellvoltmin2)<self.param.CellVoltDiffLv1-0.05 and (cellvoltmax1-cellvoltmin1)<self.param.CellVoltDiffLv1-0.05: #二级欠压恢复
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C104'].index, 'end_time'] = time
- else:
- pass
- else:
- cov_time=0
- cuv_time=0
- cdv_time=0
-
- #电池包诊断.....................................................................................................................................
- if i<1:
- if not self.df_bms_ram.empty:
- packvolt1=self.df_bms_ram.iloc[-1]['packvolt']
- packvolt2=self.packvolt[i]
- time1=self.df_bms_ram.iloc[-1]['time']
- time2=self.bmstime[i]
- else:
- packvolt1=self.packvolt[i]
- packvolt2=self.packvolt[i]
- time1=self.bmstime[i]
- time2=self.bmstime[i]
- else:
- packvolt1=self.packvolt[i-1]
- packvolt2=self.packvolt[i]
- time1=self.bmstime[i-1]
- time2=self.bmstime[i]
- if packvolt1<2*self.param.CellVoltNums or packvolt2>4.5*self.param.CellVoltNums: #电池包电压有效性
- packvoltvalid=0
- else:
- packvoltvalid=1
- if packvoltvalid==1:
- if not 'C502' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if packvolt1>self.param.PackVoltOvLv2 and packvolt2>self.param.PackVoltOvLv2 and self.packcrnt[i]<0: #电池包过压二级进入
- pov_time=pov_time+(time2-time1).total_seconds()
- if pov_time>self.param.volt_time:
- time=self.bmstime[i]
- code='C502'
- faultlv=5
- faultinfo='电池包过压'
- faultadvice='联系用户立即停止充电,并通知技术运维人员'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- pov_time=0
- else:
- if packvolt1<self.param.PackVoltOvLv1-0.05*self.param.CellVoltNums and packvolt2<self.param.PackVoltOvLv1-0.05*self.param.CellVoltNums: #电池包过压二级恢复
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C502'].index, 'end_time'] = time
- else:
- pass
-
- if not 'C203' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if packvolt1<self.param.PackVoltUvLv2 and packvolt2<self.param.PackVoltUvLv2: #电池包二级欠压进入
- puv_time=puv_time+(time2-time1).total_seconds()
- if puv_time>self.param.volt_time:
- time=self.bmstime[i]
- code='C203'
- faultlv=2
- faultinfo='电池包欠压'
- faultadvice='联系用户询问用车场景,技术介入诊断'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- puv_time=0
- else:
- if packvolt1>self.param.PackVoltUvLv1+0.1*self.param.CellVoltNums and packvolt2>self.param.PackVoltUvLv1+0.1*self.param.CellVoltNums: #电池包二级欠压恢复
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C203'].index, 'end_time'] = time
- else:
- pass
- else:
- pov_time=0
- puv_time=0
-
- #温度诊断功能.............................................................................................................
- if i<1:
- if not self.df_bms_ram.empty:
- celltemp1=self.df_bms_ram.iloc[-1]['celltemp']
- celltemp2=self._celltemp_get(i)
- time1=self.df_bms_ram.iloc[-1]['time']
- time2=self.bmstime[i]
- else:
- celltemp1=self._celltemp_get(i)
- celltemp2=self._celltemp_get(i)
- time1=self.bmstime[i]
- time2=self.bmstime[i]
- else:
- celltemp1=self._celltemp_get(i-1)
- celltemp2=self._celltemp_get(i)
- time1=self.bmstime[i-1]
- time2=self.bmstime[i]
- celltempmin1=min(celltemp1)
- celltempmin2=min(celltemp2)
- celltempmax1=max(celltemp1)
- celltempmax2=max(celltemp2)
- #温度有效性判断..........................................................................
- if celltempmax1>self.param.CellTempUpLmt or celltempmin1<self.param.CellTempLwLmt:
- celltempvalid=0
- else:
- celltempvalid=1
-
- if celltempvalid==1:
- #过温判断.............................................................................................................
- if not 'C302' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if celltempmax1>self.param.CellTempHighLv2 and celltempmax2>self.param.CellTempHighLv2: #二级高温进入
- ot_time=ot_time+(time2-time1).total_seconds()
- if ot_time>self.param.temp_time:
- time=self.bmstime[i]
- code='C302'
- faultlv=3
- faultinfo='温度{}高温'.format(celltemp1.index(celltempmax1)+1)
- faultadvice='技术介入诊断'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- ot_time=0
- else: #ram当前故障中有该故障,则判断是否退出该故障
- if celltempmax1<self.param.CellTempHighLv1-5 and celltempmax2<self.param.CellTempHighLv1-5: #二级高温恢复
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C302'].index, 'end_time'] = time
- else:
- pass
-
- #欠温判断.................................................................................................................
- if not 'C102' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if celltempmin1<self.param.CellTempLowLv2 and celltempmin2<self.param.CellTempLowLv2: #二级低温进入
- ut_time=ut_time+(time2-time1).total_seconds()
- if ut_time>self.param.temp_time:
- time=self.bmstime[i]
- code='C102'
- faultlv=1
- faultinfo='温度{}低温'.format(celltemp1.index(celltempmin1)+1)
- faultadvice='技术介入诊断'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- ut_time=0
- else: #ram当前故障中有该故障,则判断是否退出该故障
- if celltempmax1>self.param.CellTempLowLv1+2 and celltempmax2>self.param.CellTempLowLv1+2: #二级高温恢复
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C102'].index, 'end_time'] = time
- else:
- pass
-
- #温差判断.............................................................................................................................
- if not 'C103' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if (celltempmax1-celltempmin1)>self.param.CellTempDiffLv2 and (celltempmax2-celltempmin2)>self.param.CellTempDiffLv2: #二级温差进入
- dt_time=dt_time+(time2-time1).total_seconds()
- if dt_time>self.param.temp_time:
- time=self.bmstime[i]
- code='C103'
- faultlv=1
- faultinfo='温度{}和{}温差大'.format(celltemp1.index(celltempmax1)+1,celltemp1.index(celltempmin1)+1)
- faultadvice='技术介入诊断'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- dt_time=0
- else: #ram当前故障中有该故障,则判断是否退出该故障
- if (celltempmax1-celltempmin1)<self.param.CellTempDiffLv1-2 and (celltempmax2-celltempmin2)>self.param.CellTempDiffLv1-2: #二级温差恢复
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C103'].index, 'end_time'] = time
- else:
- pass
-
- else:
- ot_time=0
- ut_time=0
- dt_time=0
-
- #电流过流诊断.......................................................................................................................
- if i>0.5:
- step=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
- if step<120 and self.packcrnt[i]>self.param.PackDisOc and self.packcrnt[i-1]>self.param.PackDisOc:
- as_dis=as_dis+(self.packcrnt[i]-self.param.PackDisOc)*step #ah累计
- elif step<120 and self.packcrnt[i]<self.param.PackChgOc and self.packcrnt[i-1]<self.param.PackChgOc:
- as_chg=as_chg+(self.param.PackDisOc-self.packcrnt[i])*step #ah累计
- else:
- as_dis=0
- as_chg=0
-
- if not 'C306' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if as_dis>100:
- time=self.bmstime[i]
- code='C306'
- faultlv=3
- faultinfo='电池包放电过流'
- faultadvice='联系用户询问用车场景,技术介入诊断'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- if self.packcrnt[i]<self.param.PackDisOc-10:
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C306'].index, 'end_time'] = time
- else:
- pass
-
- if not 'C305' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if as_chg>100:
- time=self.bmstime[i]
- code='C305'
- faultlv=3
- faultinfo='电池包充电过流'
- faultadvice='联系用户询问用车场景,技术介入诊断'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- if self.packcrnt[i]>self.param.PackChgOc+10:
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C305'].index, 'end_time'] = time
- else:
- pass
-
- #SOC卡滞、跳变诊断................................................................................................
- if i<1:
- bmssoc_st=float(self.bms_soc[i])
- bmssoc_last=float(self.bms_soc[i])
- bmssoc_now=float(self.bms_soc[i])
- else:
- step=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
- if step<120:
- ah_accum=ah_accum-self.packcrnt[i]*step/3600 #ah累计
- else:
- pass
- #SOC卡滞............................................................................................................
- if abs(ah_accum)>self.param.Capacity*0.1:
- bmssoc_now=float(self.bms_soc[i])
- if not 'C106' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if abs(bmssoc_now-bmssoc_st)<self.param.SocClamp: #SOC卡滞故障进入
- time=self.bmstime[i]
- code='C106'
- faultlv=0
- faultinfo='电池SOC卡滞'
- faultadvice='技术介入诊断,检修电池BMS软件'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- if abs(bmssoc_now-bmssoc_st)>self.param.SocClamp: #SOC卡滞故障退出
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C106'].index, 'end_time'] = time
- else:
- pass
- bmssoc_st=bmssoc_now
- ah_accum=0
- else:
- pass
- #SOC跳变....................................................................................................................
- bmssoc_last=float(self.bms_soc[i-1])
- bmssoc_now=float(self.bms_soc[i])
- if not 'C107' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if step<70 and abs(bmssoc_now-bmssoc_last)>self.param.SocJump: #SOC跳变进入
- time=self.bmstime[i]
- code='C107'
- faultlv=0
- faultinfo='电池SOC跳变{}%'.format(bmssoc_now-bmssoc_last)
- faultadvice='技术介入诊断,检修电池BMS软件'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- if abs(bmssoc_now-bmssoc_st)<self.param.SocJump: #SOC跳变故障退出
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C107'].index, 'end_time'] = time
- else:
- pass
-
- #SOC一致性故障报警..........................................................................................................
- if not self.df_uniform.empty:
- cellsoc_diff=self.df_uniform.loc[0,'cellsoc_diff']
- if not 'C201' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if cellsoc_diff>self.param.SocDiff: #SOC一致性差故障进入
- time=self.bmstime[0]
- 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)
- faultadvice='技术介入诊断'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- if cellsoc_diff<self.param.SocDiff: #SOC一致性差故障恢复
- time=self.bmstime[0]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C201'].index, 'end_time'] = time
- else:
- cellsoc_diff=3
- #容量过低和一致性故障报警................................................................................................
- if not self.df_soh.empty:
- soh=self.df_soh.loc[0,'soh']
- cellsoh=eval(self.df_soh.loc[0,'cellsoh'])
- cellsoh=np.array(cellsoh)
- cellsoh_lowindex=np.argwhere(cellsoh<self.param.SohLow)
- cellsoh_lowindex=cellsoh_lowindex+1
- if self.celltype==1 or self.celltype==2 or self.celltype==3 or self.celltype==4:
- cellsoh_diff=np.max(cellsoh)-np.min(cellsoh)
- if not 'C204' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if soh<self.param.SohLow: #soh过低故障进入
- time=self.bmstime[0]
- code='C204'
- faultlv=2
- faultinfo='电池包容量过低:电芯{}'.format(cellsoh_lowindex)
- faultadvice='检修电池,更换容量过低的电芯或模组'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- if soh>self.param.SohLow+2: #soh过低故障恢复
- time=self.bmstime[0]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C204'].index, 'end_time'] = time
- else:
- pass
- if not 'C205' in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
- if cellsoh_diff>self.param.SohDiff:
- time=self.bmstime[0]
- code='C205'
- faultlv=2
- faultinfo='电池包容量一致性差:电芯{}'.format(cellsoh_lowindex)
- faultadvice='检修电池,更换容量过低的电芯或模组'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- if cellsoh_diff<self.param.SohDiff-2:
- time=self.bmstime[0]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C205'].index, 'end_time'] = time
- else:
- pass
- else:
- pass
- else:
- cellsoh_diff=5
-
- #ram更新.......................................................................
- df_bms_ram=pd.DataFrame(columns=['time', 'sn', 'packvolt', 'cellvolt', 'celltemp'])
- df_bms_ram.loc[0]=[self.bmstime[0], self.sn, packvolt2, cellvolt2, celltemp2]
- return self.df_diag_ram, df_bms_ram
|