|
@@ -4,18 +4,19 @@ import datetime
|
|
|
from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import BatParam
|
|
|
|
|
|
class SafetyAlarm:
|
|
|
- def __init__(self,sn,celltype,df_bms,df_bms_ram): #参数初始化
|
|
|
+ def __init__(self,sn,celltype,df_bms,df_bms_ram_sn,df_alarm_ram_sn): #参数初始化
|
|
|
|
|
|
self.sn=sn
|
|
|
self.celltype=celltype
|
|
|
self.param=BatParam.BatParam(celltype)
|
|
|
self.df_bms=df_bms
|
|
|
- self.df_bms_ram=df_bms_ram
|
|
|
+ self.df_ram_bms=df_bms_ram_sn.copy()
|
|
|
df_bms['时间戳']=pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
|
|
|
+ self.df_ram_alarm=df_alarm_ram_sn.copy()
|
|
|
|
|
|
- if not df_bms_ram.empty:
|
|
|
- self.df_bms=self.df_bms[self.df_bms['时间戳'] > df_bms_ram.iloc[-1]['time']] #滤除原始数据中的重复数据
|
|
|
- self.df_bms.reset_index(inplace=True,drop=True) #重置索引
|
|
|
+ if (not df_bms_ram_sn.empty) and (not self.df_bms.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]']
|
|
@@ -27,12 +28,12 @@ class SafetyAlarm:
|
|
|
# self.celltemp_name=celltemp+othertemp
|
|
|
|
|
|
|
|
|
- def diag(self):
|
|
|
+ def safety_alarm_diag(self):
|
|
|
if self.celltype<=50:
|
|
|
- df_res=self._ncm_diag()
|
|
|
+ df_res=self._alarm_diag()
|
|
|
return df_res
|
|
|
else:
|
|
|
- df_res=self._ncm_diag()
|
|
|
+ df_res=self._alarm_diag()
|
|
|
return df_res
|
|
|
|
|
|
|
|
@@ -47,200 +48,195 @@ class SafetyAlarm:
|
|
|
|
|
|
#获取当前行所有电压数据............................................................................................
|
|
|
def _cellvolt_get(self,num):
|
|
|
- cellvolt = list(self.df_bms.loc[num,self.cellvolt_name]/1000)
|
|
|
+ cellvolt = np.array(self.df_bms.loc[num,self.cellvolt_name]/1000)
|
|
|
return cellvolt
|
|
|
|
|
|
#..........................................三元电池诊断功能..................................................................
|
|
|
- def _ncm_diag(self):
|
|
|
+ def _alarm_diag(self):
|
|
|
|
|
|
- column_name=['start_time', 'end_time', 'product_id', 'code', 'level', 'info','advice']
|
|
|
- df_res=pd.DataFrame(columns=column_name)
|
|
|
+ df_res=pd.DataFrame(columns=['start_time', 'end_time', 'product_id', 'code', 'level', 'info','advice'])
|
|
|
|
|
|
end_time='0000-00-00 00:00:00'
|
|
|
+ time_now=datetime.datetime.now()
|
|
|
celltemprise=0
|
|
|
celltemphigh=0
|
|
|
cellvoltfall=0
|
|
|
- cellvoltdiff=0
|
|
|
packvoltfall=0
|
|
|
-
|
|
|
- for i in range(len(self.df_bms)):
|
|
|
-
|
|
|
- #温度诊断功能.............................................................................................................
|
|
|
- temp2=np.array(self._celltemp_get(i))
|
|
|
- celltempmin=min(temp2)
|
|
|
- celltempmax=max(temp2)
|
|
|
- #温度有效性判断...........................................................................
|
|
|
- if celltempmax>self.param.CellTempUpLmt or celltempmin<self.param.CellTempLwLmt:
|
|
|
- celltempvalid=0
|
|
|
- else: #不作处理
|
|
|
- celltempvalid=1
|
|
|
|
|
|
- if celltempvalid==1:
|
|
|
-
|
|
|
- #过温判断............................................................................................................................
|
|
|
- if celltempmax>self.param.TrwTempHigh:
|
|
|
- celltemphigh=1
|
|
|
- else:
|
|
|
- pass
|
|
|
-
|
|
|
-
|
|
|
- #温升判断.............................................................................................................................
|
|
|
+ if not self.df_ram_alarm.empty:
|
|
|
+ if (time_now-self.df_ram_alarm.loc[0,'time']).total_seconds()<300:
|
|
|
+ safetywarning=self.df_ram_alarm['safetywarning']
|
|
|
+ else:
|
|
|
+ self.df_ram_alarm=pd.DataFrame(columns=['time','sn','safetywarning'])
|
|
|
+ safetywarning=0
|
|
|
+ else:
|
|
|
+ self.df_ram_alarm=pd.DataFrame(columns=['time','sn','safetywarning'])
|
|
|
+ safetywarning=0
|
|
|
+
|
|
|
+ if not self.df_bms.empty:
|
|
|
+ for i in range(len(self.df_bms)):
|
|
|
+ #温度诊断功能.............................................................................................................
|
|
|
if i<1:
|
|
|
- if not self.df_bms_ram.empty:
|
|
|
- time1=self.df_bms_ram.iloc[-1]['time']
|
|
|
+ if not self.df_ram_bms.empty:
|
|
|
+ temp1=self.df_ram_bms.iloc[-1]['celltemp']
|
|
|
+ temp2=self._celltemp_get(i)
|
|
|
+ time1=self.df_ram_bms.iloc[-1]['time']
|
|
|
time2=self.bmstime[i]
|
|
|
- temp1=np.array(self.df_bms_ram.iloc[-1]['celltemp'])
|
|
|
-
|
|
|
- delttime=(time2-time1).total_seconds()
|
|
|
- celltemp_rate=(max(temp2-temp1)*60)/delttime #计算最大温升速率
|
|
|
- if celltemp_rate>self.param.TrwTempRate and self.param.CellTempLwLmt<min(temp1) and max(temp1)<self.param.CellTempUpLmt and max(temp2-temp1)>3:
|
|
|
- celltemprise=1
|
|
|
- else:
|
|
|
- pass
|
|
|
else:
|
|
|
- pass
|
|
|
+ temp1=self._celltemp_get(i)
|
|
|
+ temp2=self._celltemp_get(i)
|
|
|
+ time1=self.bmstime[i]-datetime.timedelta(seconds=10)
|
|
|
+ time2=self.bmstime[i]
|
|
|
else:
|
|
|
+ temp1=self._celltemp_get(i-1)
|
|
|
+ temp2=self._celltemp_get(i)
|
|
|
time1=self.bmstime[i-1]
|
|
|
time2=self.bmstime[i]
|
|
|
- temp1=np.array(self._celltemp_get(i-1))
|
|
|
-
|
|
|
+
|
|
|
+ temp1=temp1[np.where((temp1<self.param.CellTempUpLmt) & (temp1>self.param.CellTempLwLmt))]
|
|
|
+ temp2=temp2[np.where((temp2<self.param.CellTempUpLmt) & (temp2>self.param.CellTempLwLmt))]
|
|
|
+
|
|
|
+ #温度有效性判断...........................................................................
|
|
|
+ if len(temp1)>0.5 and len(temp2)>0.5 and len(temp1)==len(temp2):
|
|
|
+ celltempvalid=1
|
|
|
+ else: #不作处理
|
|
|
+ celltempvalid=0
|
|
|
+
|
|
|
+ if celltempvalid==1:
|
|
|
+ celltempmax=max(temp2)
|
|
|
+ #过温判断............................................................................................................................
|
|
|
+ if celltempmax>self.param.TrwTempHigh:
|
|
|
+ celltemphigh=1
|
|
|
+ else:
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+ #温升判断.............................................................................................................................
|
|
|
delttime=(time2-time1).total_seconds()
|
|
|
celltemp_rate=(max(temp2-temp1)*60)/delttime #计算最大温升速率
|
|
|
if celltemp_rate>self.param.TrwTempRate and self.param.CellTempLwLmt<min(temp1) and max(temp1)<self.param.CellTempUpLmt:
|
|
|
- celltemprise=1
|
|
|
+ celltemprise=celltemprise+1
|
|
|
else:
|
|
|
pass
|
|
|
-
|
|
|
- else:
|
|
|
- pass
|
|
|
-
|
|
|
- #电压诊断功能.........................................................................................................................................
|
|
|
- if i<1:
|
|
|
- cellvolt2=self._cellvolt_get(i)
|
|
|
- cellvoltmin2=min(cellvolt2)
|
|
|
- cellvoltmax2=max(cellvolt2)
|
|
|
- cellvoltmin_index2=list(cellvolt2).index(cellvoltmin2)
|
|
|
- cellvoltmax_index2=list(cellvolt2).index(cellvoltmax2)
|
|
|
- if not self.df_bms_ram.empty:
|
|
|
- cellvolt1=np.array(self.df_bms_ram.iloc[-1]['cellvolt'])
|
|
|
- cellvoltmin1=min(cellvolt1)
|
|
|
- cellvoltmax1=max(cellvolt1)
|
|
|
- cellvoltmin_index1=list(cellvolt1).index(cellvoltmin1)
|
|
|
- cellvoltmax_index1=list(cellvolt1).index(cellvoltmax1)
|
|
|
+
|
|
|
else:
|
|
|
- cellvoltmin1=cellvoltmin2
|
|
|
- cellvoltmax1=cellvoltmax2
|
|
|
- cellvoltmin_index1=cellvoltmin_index2
|
|
|
- cellvoltmax_index1=cellvoltmax_index2
|
|
|
- else:
|
|
|
- cellvolt2=self._cellvolt_get(i)
|
|
|
+ pass
|
|
|
+
|
|
|
+ #电压诊断功能.........................................................................................................................................
|
|
|
+ if i<1:
|
|
|
+ cellvolt2=self._cellvolt_get(i)
|
|
|
+ time2=self.bmstime[i]
|
|
|
+ if not self.df_ram_bms.empty:
|
|
|
+ cellvolt1=self.df_ram_bms.iloc[-1]['cellvolt']
|
|
|
+ time1=self.df_ram_bms.iloc[-1]['time']
|
|
|
+ else:
|
|
|
+ cellvolt1=cellvolt2
|
|
|
+ time1=time2
|
|
|
+ else:
|
|
|
+ cellvolt2=self._cellvolt_get(i)
|
|
|
+ cellvolt1=self._cellvolt_get(i-1)
|
|
|
+ time2=self.bmstime[i]
|
|
|
+ time1=self.bmstime[i-1]
|
|
|
+
|
|
|
+
|
|
|
+ #电压有效性..........................................................................................................................................
|
|
|
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)
|
|
|
-
|
|
|
- #电压有效性..........................................................................................................................................
|
|
|
- if (cellvoltmin2<2 and cellvoltmax2>4.5 and abs(cellvoltmax_index2-cellvoltmin_index2)==1) or cellvoltmin2<0.01 or (cellvoltmin1<2 and cellvoltmax1>4.5 and abs(cellvoltmax_index1-cellvoltmin_index1)==1) or cellvoltmin1<0.01: #电压断线故障进入
|
|
|
- cellvoltvalid=0
|
|
|
- else:
|
|
|
- cellvoltvalid=1
|
|
|
-
|
|
|
- if cellvoltvalid==1:
|
|
|
- #单体电压跌落诊断...........................................................................................................................
|
|
|
- if i<1:
|
|
|
- if not self.df_bms_ram.empty:
|
|
|
- time1=self.df_bms_ram.iloc[-1]['time']
|
|
|
- time2=self.bmstime[i]
|
|
|
- delttime=(time2-time1).total_seconds()
|
|
|
- if delttime<310:
|
|
|
- if self.packcrnt[i]<0.5 and max(cellvolt1-cellvolt2)>self.param.TrwCellVoltFall:
|
|
|
- cellvoltfall=1
|
|
|
- elif self.packcrnt[i]>0.5 and max(cellvolt1-cellvolt2)-self.packcrnt[i]*0.01>self.param.TrwCellVoltFall:
|
|
|
- cellvoltfall=1
|
|
|
- else:
|
|
|
- pass
|
|
|
- else:
|
|
|
- if min(cellvolt2)<self.param.TrwCellVoltLow: #电压跌落至<1.5V
|
|
|
- cellvoltfall=1
|
|
|
- else:
|
|
|
- pass
|
|
|
- else:
|
|
|
- pass
|
|
|
+
|
|
|
+ if (cellvoltmin2<2 and cellvoltmax2>4.5 and abs(cellvoltmax_index2-cellvoltmin_index2)==1) or (cellvoltmin1<2 and cellvoltmax1>4.5 and abs(cellvoltmax_index1-cellvoltmin_index1)==1): #电压断线故障进入
|
|
|
+ cellvoltvalid=0
|
|
|
else:
|
|
|
- delttime=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
|
|
|
- cellvolt1=np.array(self._cellvolt_get(i-1))
|
|
|
- if self.packcrnt[i]<0.5 and max(cellvolt1-cellvolt2)>self.param.TrwCellVoltFall:
|
|
|
- cellvoltfall=1
|
|
|
- elif self.packcrnt[i]>0.5 and max(cellvolt1-cellvolt2)-self.packcrnt[i]*0.01>self.param.TrwCellVoltFall:
|
|
|
- cellvoltfall=1
|
|
|
+ cellvolt1=cellvolt1[np.where((cellvolt1>0.01) & (cellvolt1<4.5))]
|
|
|
+ cellvolt2=cellvolt2[np.where((cellvolt2>0.01) & (cellvolt2<4.5))]
|
|
|
+ if len(cellvolt1)>1 and len(cellvolt2)>1 and len(cellvolt1)==len(cellvolt2):
|
|
|
+ cellvoltvalid=1
|
|
|
else:
|
|
|
- pass
|
|
|
+ cellvoltvalid=0
|
|
|
|
|
|
- #压差诊断........................................................................................................................................
|
|
|
- if (max(cellvolt2)-min(cellvolt2))>self.param.TrwCellVoltDiff:
|
|
|
- cellvoltdiff=1
|
|
|
+ if cellvoltvalid==1:
|
|
|
+ #单体电压跌落诊断...........................................................................................................................
|
|
|
+ delttime=(time2-time1).total_seconds()
|
|
|
+ if delttime<360:
|
|
|
+ if self.packcrnt[i]<0.5 and max(cellvolt1-cellvolt2)>self.param.TrwCellVoltFall:
|
|
|
+ cellvoltfall=cellvoltfall+1
|
|
|
+ elif self.packcrnt[i]>0.5 and max(cellvolt1-cellvolt2)-self.packcrnt[i]*0.01>self.param.TrwCellVoltFall:
|
|
|
+ cellvoltfall=cellvoltfall+1
|
|
|
+ else:
|
|
|
+ pass
|
|
|
+ else:
|
|
|
+ pass
|
|
|
else:
|
|
|
pass
|
|
|
-
|
|
|
- else:
|
|
|
- pass
|
|
|
-
|
|
|
- #电池包诊断.....................................................................................................................................
|
|
|
- packvolt2=self.packvolt[i]
|
|
|
- #电池包电压有效性............................................................................................................................
|
|
|
- if self.param.CellVoltNums<packvolt2<self.param.CellVoltNums*4.5:
|
|
|
- packvoltvalid=1
|
|
|
- else:
|
|
|
- packvoltvalid=0
|
|
|
-
|
|
|
-
|
|
|
- if packvoltvalid==1:
|
|
|
- if i<1:
|
|
|
- if not self.df_bms_ram.empty:
|
|
|
- time1=self.df_bms_ram.iloc[-1]['time']
|
|
|
- time2=self.bmstime[i]
|
|
|
- delttime=(time2-time1).total_seconds()
|
|
|
- packvolt1=self.df_bms_ram.iloc[-1]['packvolt']
|
|
|
|
|
|
- if delttime<310:
|
|
|
- if self.packcrnt[i]<5 and (packvolt1-packvolt2)>self.param.TrwPackVoltFall and self.param.CellVoltNums<packvolt1<self.param.CellVoltNums*4.5:
|
|
|
- packvoltfall=1
|
|
|
+ #电池包诊断.....................................................................................................................................
|
|
|
+ packvolt2=self.packvolt[i]
|
|
|
+ #电池包电压有效性............................................................................................................................
|
|
|
+ if self.param.CellVoltNums<packvolt2<self.param.CellVoltNums*4.5:
|
|
|
+ packvoltvalid=1
|
|
|
+ else:
|
|
|
+ packvoltvalid=0
|
|
|
+
|
|
|
+ if packvoltvalid==1:
|
|
|
+ if i<1:
|
|
|
+ if not self.df_ram_bms.empty:
|
|
|
+ time1=self.df_ram_bms.iloc[-1]['time']
|
|
|
+ time2=self.bmstime[i]
|
|
|
+ delttime=(time2-time1).total_seconds()
|
|
|
+ packvolt1=self.df_ram_bms.iloc[-1]['packvolt']
|
|
|
+
|
|
|
+ if delttime<360:
|
|
|
+ if self.packcrnt[i]<5 and (packvolt1-packvolt2)>self.param.TrwPackVoltFall and self.param.CellVoltNums<packvolt1<self.param.CellVoltNums*4.5:
|
|
|
+ packvoltfall=packvoltfall+1
|
|
|
+ else:
|
|
|
+ pass
|
|
|
else:
|
|
|
pass
|
|
|
else:
|
|
|
pass
|
|
|
else:
|
|
|
- pass
|
|
|
+ packvolt1=self.packvolt[i-1]
|
|
|
+ if self.packcrnt[i]<5 and (packvolt1-packvolt2)>self.param.TrwPackVoltFall and self.param.CellVoltNums<packvolt1<self.param.CellVoltNums*4.5:
|
|
|
+ packvoltfall=packvoltfall+1
|
|
|
+ else:
|
|
|
+ pass
|
|
|
else:
|
|
|
- packvolt1=self.packvolt[i-1]
|
|
|
- if self.packcrnt[i]<5 and (packvolt1-packvolt2)>self.param.TrwPackVoltFall and self.param.CellVoltNums<packvolt1<self.param.CellVoltNums*4.5:
|
|
|
- packvoltfall=1
|
|
|
- else:
|
|
|
- pass
|
|
|
+ pass
|
|
|
+
|
|
|
+ #热失控故障判断........................................................................................................................
|
|
|
+ df_bms_ram=pd.DataFrame(columns=['time', 'sn', 'packvolt', 'cellvolt', 'celltemp'])
|
|
|
+ df_bms_ram.loc[0]=[self.bmstime[0], self.sn, packvolt2, cellvolt2, temp2]
|
|
|
+ df_ram_alarm=self.df_ram_alarm
|
|
|
+ trwtemp=max(celltemprise,celltemphigh)
|
|
|
+ trwcellvolt=cellvoltfall
|
|
|
+ trwpackvolt=packvoltfall
|
|
|
+ trw_array=np.array([trwtemp, trwcellvolt, trwpackvolt])
|
|
|
+
|
|
|
+ if np.sum(trw_array)>3.5 and np.sum(trw_array>0.5)>1.5:
|
|
|
+ fltcode='C599'
|
|
|
+ df_res.loc[0]=[self.bmstime[len(self.bmstime)-1], end_time, self.sn, fltcode, 5, '电池发生热失控', '联系用户立即远离电池,并通知技术人员介入']
|
|
|
+ return df_res, df_bms_ram, df_ram_alarm
|
|
|
+ elif safetywarning>2.5 and np.sum(trw_array)>1.5 and np.sum(trw_array>0.5)>1.5:
|
|
|
+ fltcode='C599'
|
|
|
+ df_res.loc[0]=[self.bmstime[len(self.bmstime)-1], end_time, self.sn, fltcode, 5, '电池发生热失控', '联系用户立即远离电池,并通知技术人员介入']
|
|
|
+ return df_res, df_bms_ram, df_ram_alarm
|
|
|
else:
|
|
|
- pass
|
|
|
-
|
|
|
- #热失控故障判断........................................................................................................................
|
|
|
- df_bms_ram=pd.DataFrame(columns=['time', 'sn', 'packvolt', 'cellvolt', 'celltemp'])
|
|
|
- df_bms_ram.loc[0]=[self.bmstime[0], self.sn, packvolt2, list(cellvolt2), list(temp2)]
|
|
|
- if celltemprise==1 or celltemphigh==1:
|
|
|
- trwtemp=1
|
|
|
- else:
|
|
|
- trwtemp=0
|
|
|
-
|
|
|
- if cellvoltfall==1 or cellvoltdiff==1:
|
|
|
- trwcellvolt=1
|
|
|
- else:
|
|
|
- trwcellvolt=0
|
|
|
+ if np.sum(trw_array)>1.5 and np.sum(trw_array>0.5)>1.5:
|
|
|
+ safetywarning=3
|
|
|
+ df_ram_alarm.loc[0]=[self.bmstime[len(self.bmstime)-1], self.sn, safetywarning]
|
|
|
+ else:
|
|
|
+ pass
|
|
|
+ return pd.DataFrame(), df_bms_ram, df_ram_alarm
|
|
|
|
|
|
- if trwtemp+trwcellvolt+packvoltfall>1.5:
|
|
|
- fltcode=119
|
|
|
- df_res.loc[0]=[self.bmstime[0], end_time, self.sn, fltcode, 5, '电池发生热失控', '立刻远离电池']
|
|
|
- return df_res, df_bms_ram
|
|
|
else:
|
|
|
- return pd.DataFrame(), df_bms_ram
|
|
|
+ if safetywarning>2.5:
|
|
|
+ fltcode='C599'
|
|
|
+ df_res.loc[0]=[time_now, end_time, self.sn, fltcode, 5, '电池发生热失控', '联系用户立即远离电池,并通知技术人员介入']
|
|
|
+ return df_res, self.df_ram_bms, self.df_ram_alarm
|
|
|
+ else:
|
|
|
+ return pd.DataFrame(), self.df_ram_bms, self.df_ram_alarm
|