123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488 |
- 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_soh,df_uniform,df_diag_Ram):
- self.sn=sn
- self.celltype=celltype
- self.param=BatParam.BatParam(celltype)
- self.df_bms=df_bms
- self.df_soh=df_soh
- self.df_uniform=df_uniform
- self.df_diag_ram=df_diag_Ram
- self.packcrnt=df_bms['总电流[A]']*self.param.PackCrntDec
- self.packvolt=df_bms['总电压[V]']
- self.bms_soc=df_bms['SOC[%]']
- self.bmstime= pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
- self.bmsfault1=self.df_bms['故障代码']
-
-
-
- self.cellvolt_name=['单体电压'+str(x) for x in range(1,self.param.CellVoltNums+1)]
- self.celltemp_name=['单体温度'+str(x) for x in range(1,self.param.CellTempNums+1)]
-
- def diag(self):
- if self.celltype<=50:
- df_res=self._ncm_diag()
- return df_res
- else:
- df_res=self._ncm_diag()
- return df_res
-
-
- def _np_move_avg(self,a, n, mode="same"):
- return (np.convolve(a, np.ones((n,)) / n, mode=mode))
-
-
- 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 _ncm_diag(self):
- bmssoc_st=float(self.bms_soc[0])
- ah_accum=0
- as_chg=0
- as_dis=0
- time1=self.bmstime[0]
- temp1=np.array(self._celltemp_get(0))
- temprate_cnt=0
-
- end_time='0000-00-00 00:00:00'
-
- for i in range(1,len(self.df_bms)):
-
-
- celltemp0=self._celltemp_get(i-1)
- celltemp1=self._celltemp_get(i)
- celltempmin0=min(celltemp0)
- celltempmin1=min(celltemp1)
- celltempmax0=max(celltemp0)
- celltempmax1=max(celltemp1)
-
- if celltempmax0>self.param.CellTempUpLmt or celltempmin0<self.param.CellTempLwLmt:
- celltempvalid=0
- else:
- celltempvalid=1
-
- if celltempvalid==1:
-
- if not 4 in list(self.df_diag_ram['code']):
- if celltempmax0>self.param.CellTempHighLv2 and celltempmax1>self.param.CellTempHighLv2:
- time=self.bmstime[i]
- code=4
- 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:
- if celltempmax0<self.param.CellTempHighLv1-5 and celltempmax1<self.param.CellTempHighLv1-5:
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']==4].index, 'end_time'] = time
- else:
- pass
-
-
- if not 6 in list(self.df_diag_ram['code']):
- if celltempmin0<self.param.CellTempLowLv2 and celltempmin1<self.param.CellTempLowLv2:
- time=self.bmstime[i]
- code=6
- faultlv=3
- 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:
- if celltempmax0>self.param.CellTempLowLv1+2 and celltempmax1>self.param.CellTempLowLv1+2:
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']==6].index, 'end_time'] = time
- else:
- pass
-
-
- if not 8 in list(self.df_diag_ram['code']):
- if (celltempmax0-celltempmin0)>self.param.CellTempDiffLv2 and (celltempmax1-celltempmin1)>self.param.CellTempDiffLv2:
- time=self.bmstime[i]
- code=8
- faultlv=3
- 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:
- if (celltempmax0-celltempmin0)<self.param.CellTempDiffLv1-2 and (celltempmax1-celltempmax0)>self.param.CellTempDiffLv1-2:
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']==8].index, 'end_time'] = time
- else:
- pass
-
- time2=self.bmstime[i]
- delttime=(time2-time1).total_seconds()
- if delttime>20:
- temp2=np.array(self._celltemp_get(i))
- celltemp_rate=round((max(temp2-temp1)*60)/delttime,2)
- temp1=temp2
- time1=time2
- if not 9 in list(self.df_diag_ram['code']):
- if celltemp_rate>self.param.CellTempRate:
- temprate_cnt=temprate_cnt+1
- if temprate_cnt>2:
- time=self.bmstime[i]
- code=9
- faultlv=3
- faultinfo='温升速率过快:{}℃/min'.format(celltemp_rate)
- faultadvice='技术介入诊断'
- self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
- else:
- pass
- else:
- pass
- else:
- if celltemp_rate<self.param.CellTempRate-1:
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']==9].index, 'end_time'] = time
- else:
- pass
-
- else:
- pass
-
-
- cellvolt0=self._cellvolt_get(i-1)
- cellvolt1=self._cellvolt_get(i)
- cellvoltmin0=min(cellvolt0)
- cellvoltmax0=max(cellvolt0)
- cellvoltmin1=min(cellvolt1)
- cellvoltmax1=max(cellvolt1)
-
- if (cellvoltmin0<2 and cellvoltmax0>4.5) or cellvoltmin0<0.1 or cellvoltmax0>5:
- cellvoltvalid=0
- else:
- cellvoltvalid=1
-
- if cellvoltvalid==1:
-
- if not 12 in list(self.df_diag_ram['code']):
- if cellvoltmax0>self.param.CellOvLv2 and cellvoltmax1>self.param.CellOvLv2:
- time=self.bmstime[i]
- code=12
- faultlv=4
- 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:
- if cellvoltmax0<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']==12].index, 'end_time'] = time
- else:
- pass
-
-
- if not 14 in list(self.df_diag_ram['code']):
- if cellvoltmin0<self.param.CellUvLv2 and cellvoltmin1<self.param.CellUvLv2:
- time=self.bmstime[i]
- code=14
- faultlv=3
- 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:
- if cellvoltmin0>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']==14].index, 'end_time'] = time
- else:
- pass
-
-
- if not 16 in list(self.df_diag_ram['code']):
- if (cellvoltmax0-cellvoltmin0)>self.param.CellVoltDiffLv2 and (cellvoltmax1-cellvoltmin1)>self.param.CellVoltDiffLv2:
- time=self.bmstime[i]
- code=16
- faultlv=3
- 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:
- if (cellvoltmax0-cellvoltmin0)<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']==16].index, 'end_time'] = time
- else:
- pass
- else:
- pass
-
-
- if not 18 in list(self.df_diag_ram['code']):
- if self.packvolt[i-1]>self.param.PackVoltOvLv2 and self.packvolt[i]>self.param.PackVoltOvLv2:
- time=self.bmstime[i]
- code=18
- faultlv=4
- 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.packvolt[i-1]<self.param.PackVoltOvLv1-0.05*self.param.CellVoltNums and self.packvolt[i]<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']==18].index, 'end_time'] = time
- else:
- pass
-
-
- if not 20 in list(self.df_diag_ram['code']):
- if self.packvolt[i-1]<self.param.PackVoltUvLv2 and self.packvolt[i]<self.param.PackVoltUvLv2:
- time=self.bmstime[i]
- code=20
- 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.packvolt[i-1]>self.param.PackVoltUvLv1+0.1*self.param.CellVoltNums and self.packvolt[i]>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']==20].index, 'end_time'] = time
- else:
- pass
-
-
- 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
- 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
- else:
- as_dis=0
- as_chg=0
-
- if not 22 in list(self.df_diag_ram['code']):
- if as_dis>100:
- time=self.bmstime[i]
- code=22
- 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']==22].index, 'end_time'] = time
- else:
- pass
-
- if not 21 in list(self.df_diag_ram['code']):
- if as_chg>100:
- time=self.bmstime[i]
- code=21
- 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']==21].index, 'end_time'] = time
- else:
- pass
-
- step=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
- if step<120:
- ah_accum=ah_accum-self.packcrnt[i]*step/3600
- else:
- pass
-
- if abs(ah_accum)>self.param.Capacity*0.05:
- bmssoc_now=float(self.bms_soc[i])
- if not 27 in list(self.df_diag_ram['code']):
- if abs(bmssoc_now-bmssoc_st)<self.param.SocClamp:
- time=self.bmstime[i]
- code=27
- faultlv=1
- 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:
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']==27].index, 'end_time'] = time
- else:
- pass
- bmssoc_st=bmssoc_now
- ah_accum=0
- else:
- pass
-
- bmssoc_last=float(self.bms_soc[i-1])
- bmssoc_now=float(self.bms_soc[i])
- if not 28 in list(self.df_diag_ram['code']):
- if step<30 and abs(bmssoc_now-bmssoc_last)>self.param.SocJump:
- time=self.bmstime[i]
- code=28
- faultlv=1
- 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.SocJump:
- time=self.bmstime[i]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']==28].index, 'end_time'] = time
- else:
- pass
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- if not self.df_uniform.empty:
- cellsoc_diff=self.df_uniform.loc[0,'cellsoc_diff']
- if not 25 in list(self.df_diag_ram['code']):
- if cellsoc_diff>self.param.SocDiff:
- time=self.bmstime[0]
- code=25
- faultlv=1
- faultinfo='电芯{}和{}SOC差过大:{}'.format(self.df_uniform.loc[0,'cellmin_num'],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:
- time=self.bmstime[0]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']==25].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 23 in list(self.df_diag_ram['code']):
- if soh<self.param.SohLow:
- time=self.bmstime[0]
- code=23
- faultlv=1
- 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:
- time=self.bmstime[0]
- self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']==23].index, 'end_time'] = time
- else:
- pass
- if not 24 in list(self.df_diag_ram['code']):
- if cellsoh_diff>self.param.SohDiff:
- time=self.bmstime[0]
- code=24
- faultlv=1
- 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']==24].index, 'end_time'] = time
- else:
- pass
- else:
- pass
- else:
- cellsoh_diff=5
-
-
-
-
-
-
-
-
-
-
-
- df_res=self.df_diag_ram
- if not df_res.empty:
- return df_res
- else:
- return pd.DataFrame()
|