CBMSSafetyAlarm.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. import pandas as pd
  2. import numpy as np
  3. import datetime
  4. import BatParam
  5. class SafetyAlarm:
  6. def __init__(self,sn,celltype,df_bms,df_bms_ram_sn,df_alarm_ram_sn): #参数初始化
  7. self.sn=sn
  8. self.celltype=celltype
  9. self.param=BatParam.BatParam(celltype)
  10. self.df_bms=df_bms
  11. self.df_ram_bms=df_bms_ram_sn.copy()
  12. df_bms['time']=pd.to_datetime(df_bms['time'], format='%Y-%m-%d %H:%M:%S')
  13. self.df_ram_alarm=df_alarm_ram_sn.copy()
  14. if (not df_bms_ram_sn.empty) and (not self.df_bms.empty):
  15. self.df_bms=self.df_bms[self.df_bms['time'] > df_bms_ram_sn.iloc[-1]['time']] #滤除原始数据中的重复数据
  16. self.df_bms.reset_index(inplace=True,drop=True) #重置索引
  17. self.packcrnt=df_bms['PackCrnt']*self.param.PackCrntDec
  18. self.packvolt=df_bms['PackCrnt']
  19. self.bmstime= df_bms['time']
  20. self.cellvolt_name=['CellVolt'+str(x) for x in range(1,self.param.CellVoltNums+1)]
  21. # othertemp=['其他温度'+str(x) for x in range(1,self.param.OtherTempNums+1)]
  22. self.celltemp_name=['CellTemp'+str(x) for x in range(1,self.param.CellTempNums+1)]
  23. # self.celltemp_name=celltemp+othertemp
  24. def safety_alarm_diag(self):
  25. if self.celltype<=50:
  26. df_res=self._alarm_diag()
  27. return df_res
  28. else:
  29. df_res=self._alarm_diag()
  30. return df_res
  31. #定义滑动滤波函数.............................................................................................
  32. def _np_move_avg(self,a, n, mode="same"):
  33. return (np.convolve(a, np.ones((n,)) / n, mode=mode))
  34. #寻找当前行数据的所有温度值...................................................................................
  35. def _celltemp_get(self,num):
  36. celltemp = np.array(self.df_bms.loc[num,self.celltemp_name])
  37. return celltemp
  38. #获取当前行所有电压数据............................................................................................
  39. def _cellvolt_get(self,num):
  40. cellvolt = np.array(self.df_bms.loc[num,self.cellvolt_name])
  41. return cellvolt
  42. #..........................................三元电池诊断功能..................................................................
  43. def _alarm_diag(self):
  44. column_name=['time_st','time_sp','sn','faultcode','faultlv','faultinfo','faultadvice']
  45. df_res=pd.DataFrame(columns=column_name)
  46. end_time='0000-00-00 00:00:00'
  47. time_now=datetime.datetime.now()
  48. celltemprise=0
  49. celltemphigh=0
  50. cellvoltfall=0
  51. packvoltfall=0
  52. if not self.df_ram_alarm.empty:
  53. safetywarning1=self.df_ram_alarm.iloc[-1]['safetywarning1']
  54. safetywarning2=self.df_ram_alarm.iloc[-1]['safetywarning2']
  55. else:
  56. safetywarning1=0
  57. safetywarning2=0
  58. if not self.df_bms.empty:
  59. #温升参数初始化
  60. if not self.df_ram_bms.empty:
  61. time_temp_st=self.df_ram_bms.iloc[-1]['time']
  62. temp_st=self.df_ram_bms.iloc[-1]['celltemp']
  63. else:
  64. time_temp_st=self.bmstime[0]
  65. temp_st=self._celltemp_get(0)
  66. for i in range(len(self.df_bms)):
  67. #温度诊断功能.............................................................................................................
  68. if i<1:
  69. if not self.df_ram_bms.empty:
  70. temp1=self.df_ram_bms.iloc[-1]['celltemp']
  71. temp2=self._celltemp_get(i)
  72. time1=self.df_ram_bms.iloc[-1]['time']
  73. time2=self.bmstime[i]
  74. else:
  75. temp1=self._celltemp_get(i)
  76. temp2=self._celltemp_get(i)
  77. time1=self.bmstime[i]-datetime.timedelta(seconds=10)
  78. time2=self.bmstime[i]
  79. else:
  80. temp1=self._celltemp_get(i-1)
  81. temp2=self._celltemp_get(i)
  82. time1=self.bmstime[i-1]
  83. time2=self.bmstime[i]
  84. temp1=temp1[np.where((temp1<self.param.CellTempUpLmt) & (temp1>self.param.CellTempLwLmt))]
  85. temp2=temp2[np.where((temp2<self.param.CellTempUpLmt) & (temp2>self.param.CellTempLwLmt))]
  86. #温度有效性判断...........................................................................
  87. if len(temp1)>0.5 and len(temp2)>0.5 and len(temp1)==len(temp2):
  88. celltempvalid=1
  89. else: #不作处理
  90. celltempvalid=0
  91. if celltempvalid==1:
  92. celltempmax=max(temp2)
  93. #过温判断............................................................................................................................
  94. if celltempmax>self.param.TrwTempHigh:
  95. celltemphigh=1
  96. else:
  97. pass
  98. #温升判断.............................................................................................................................
  99. delttime=(time2-time_temp_st).total_seconds()
  100. if delttime>5:
  101. celltemp_rate=(max(temp2-temp_st))/delttime #计算最大温升速率
  102. temp_st=temp2
  103. time_temp_st=time2
  104. if celltemp_rate>self.param.TrwTempRate and self.param.CellTempLwLmt<min(temp1) and max(temp1)<self.param.CellTempUpLmt:
  105. celltemprise=celltemprise+1
  106. else:
  107. pass
  108. else:
  109. pass
  110. #电压诊断功能.........................................................................................................................................
  111. if i<1:
  112. cellvolt2=self._cellvolt_get(i)
  113. time2=self.bmstime[i]
  114. if not self.df_ram_bms.empty:
  115. cellvolt1=self.df_ram_bms.iloc[-1]['cellvolt']
  116. time1=self.df_ram_bms.iloc[-1]['time']
  117. else:
  118. cellvolt1=cellvolt2
  119. time1=time2
  120. else:
  121. cellvolt2=self._cellvolt_get(i)
  122. cellvolt1=self._cellvolt_get(i-1)
  123. time2=self.bmstime[i]
  124. time1=self.bmstime[i-1]
  125. #电压有效性..........................................................................................................................................
  126. cellvoltmin2=min(cellvolt2)
  127. cellvoltmax2=max(cellvolt2)
  128. cellvoltmin_index2=list(cellvolt2).index(cellvoltmin2)
  129. cellvoltmax_index2=list(cellvolt2).index(cellvoltmax2)
  130. cellvoltmin1=min(cellvolt1)
  131. cellvoltmax1=max(cellvolt1)
  132. cellvoltmin_index1=list(cellvolt1).index(cellvoltmin1)
  133. cellvoltmax_index1=list(cellvolt1).index(cellvoltmax1)
  134. 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): #电压断线故障进入
  135. cellvoltvalid=0
  136. else:
  137. cellvolt1=cellvolt1[np.where((cellvolt1>0.01) & (cellvolt1<4.5))]
  138. cellvolt2=cellvolt2[np.where((cellvolt2>0.01) & (cellvolt2<4.5))]
  139. if len(cellvolt1)>1 and len(cellvolt2)>1 and len(cellvolt1)==len(cellvolt2):
  140. cellvoltvalid=1
  141. else:
  142. cellvoltvalid=0
  143. if cellvoltvalid==1:
  144. #单体电压跌落诊断...........................................................................................................................
  145. delttime=(time2-time1).total_seconds()
  146. if delttime<360:
  147. if self.packcrnt[i]<0.5 and max(cellvolt1-cellvolt2)>self.param.TrwCellVoltFall:
  148. cellvoltfall=cellvoltfall+1
  149. elif self.packcrnt[i]>0.5 and max(cellvolt1-cellvolt2)-self.packcrnt[i]*0.01>self.param.TrwCellVoltFall:
  150. cellvoltfall=cellvoltfall+1
  151. else:
  152. pass
  153. else:
  154. pass
  155. else:
  156. pass
  157. #电池包诊断.....................................................................................................................................
  158. packvolt2=self.packvolt[i]
  159. #电池包电压有效性............................................................................................................................
  160. if self.param.CellVoltNums<packvolt2<self.param.CellVoltNums*4.5:
  161. packvoltvalid=1
  162. else:
  163. packvoltvalid=0
  164. if packvoltvalid==1:
  165. if i<1:
  166. if not self.df_ram_bms.empty:
  167. time1=self.df_ram_bms.iloc[-1]['time']
  168. time2=self.bmstime[i]
  169. delttime=(time2-time1).total_seconds()
  170. packvolt1=self.df_ram_bms.iloc[-1]['packvolt']
  171. if delttime<360:
  172. if self.packcrnt[i]<5 and (packvolt1-packvolt2)>self.param.TrwPackVoltFall and self.param.CellVoltNums<packvolt1<self.param.CellVoltNums*4.5:
  173. packvoltfall=packvoltfall+1
  174. else:
  175. pass
  176. else:
  177. pass
  178. else:
  179. pass
  180. else:
  181. packvolt1=self.packvolt[i-1]
  182. if self.packcrnt[i]<5 and (packvolt1-packvolt2)>self.param.TrwPackVoltFall and self.param.CellVoltNums<packvolt1<self.param.CellVoltNums*4.5:
  183. packvoltfall=packvoltfall+1
  184. else:
  185. pass
  186. else:
  187. pass
  188. #热失控故障判断........................................................................................................................
  189. df_bms_ram=pd.DataFrame(columns=['time', 'sn', 'packvolt', 'cellvolt', 'celltemp'])
  190. temp2=self._celltemp_get(len(self.bmstime)-1)
  191. df_bms_ram.loc[0]=[self.bmstime[0], self.sn, packvolt2, cellvolt2, temp2]
  192. df_ram_alarm=self.df_ram_alarm
  193. trwtemp=max(celltemprise,celltemphigh)
  194. trwcellvolt=cellvoltfall
  195. trwpackvolt=packvoltfall
  196. trw_array=np.array([trwtemp, trwcellvolt, trwpackvolt])
  197. if np.sum(trw_array)>3.5 and np.sum(trw_array>0.5)>1.5:
  198. fltcode=119
  199. df_res.loc[0]=[self.bmstime[len(self.bmstime)-1], end_time, self.sn, fltcode, 5, '电池发生热失控', '断开继电器,远离电池,立刻消防处理,并通知技术人员介入']
  200. df_ram_alarm=pd.DataFrame(columns=['sn','time','safetywarning1','safetywarning2'])
  201. elif safetywarning1>2.5 and np.sum(trw_array)>1.5 and np.sum(trw_array>0.5)>1.5:
  202. fltcode=119
  203. df_res.loc[0]=[self.bmstime[len(self.bmstime)-1], end_time, self.sn, fltcode, 5, '电池发生热失控', '断开继电器,远离电池,立刻消防处理,并通知技术人员介入']
  204. df_ram_alarm=pd.DataFrame(columns=['sn','time','safetywarning1','safetywarning2'])
  205. else:
  206. df_res=pd.DataFrame()
  207. #更新df_ram_alarm信息
  208. if np.sum(trw_array)>1.5 and np.sum(trw_array>0.5)>1.5:
  209. safetywarning1=3
  210. df_ram_alarm.loc[0]=[self.sn,time2,safetywarning1,safetywarning2]
  211. else:
  212. safetywarning1=0
  213. df_ram_alarm=pd.DataFrame(columns=['sn','time','safetywarning1','safetywarning2'])
  214. if max(cellvolt2)>5 or min(cellvolt2)<1:
  215. safetywarning2=3
  216. df_ram_alarm.loc[0]=[self.sn,time2,safetywarning1,safetywarning2]
  217. elif max(cellvolt2)<4.5 and min(cellvolt2)>2.5:
  218. safetywarning2=0
  219. if safetywarning1==0:
  220. df_ram_alarm=pd.DataFrame(columns=['sn','time','safetywarning1','safetywarning2'])
  221. else:
  222. df_ram_alarm.loc[0]=[self.sn,time2,safetywarning1,safetywarning2]
  223. else:
  224. df_ram_alarm.loc[0]=[self.sn,time2,safetywarning1,safetywarning2]
  225. return df_res, df_bms_ram, df_ram_alarm
  226. else:
  227. df_ram_alarm=self.df_ram_alarm
  228. df_ram_bms=self.df_ram_bms
  229. if (safetywarning1>2.5 or safetywarning2>2.5) and (time_now-df_ram_alarm.loc[0,'time']).total_seconds()>60:
  230. fltcode=119
  231. time_now=time_now.strftime('%Y-%m-%d %H:%M:%S')
  232. time_now=datetime.datetime.strptime(time_now,'%Y-%m-%d %H:%M:%S')
  233. df_res.loc[0]=[time_now, end_time, self.sn, fltcode, 5, '电池发生热失控', '断开继电器,远离电池,立刻消防处理,并通知技术人员介入']
  234. df_ram_alarm=pd.DataFrame(columns=['sn','time','safetywarning1','safetywarning2'])
  235. else:
  236. df_res=pd.DataFrame()
  237. return df_res, df_ram_bms, df_ram_alarm