SC_SamplingSafty.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. import sys
  2. import numpy as np
  3. import pandas as pd
  4. import string
  5. import os
  6. from pandas import Series
  7. from matplotlib import pyplot as plt
  8. from pandas.core.frame import DataFrame
  9. from pandas.core.indexes.base import Index
  10. from LIB.BACKEND import DBManager
  11. import datetime
  12. import time
  13. import string
  14. import re
  15. class SamplingSafty:
  16. def __init__(self):
  17. pass
  18. def main(sn,param,bms_info,df_Diag_Ram_in):
  19. df_Diag_Ram_Update_inside=DataFrame(columns=['start_time', 'end_time', 'product_id', 'code', 'level', 'info','advice'])
  20. df_Diag_Ram_Update_inside=df_Diag_Ram_Update_inside.append(df_Diag_Ram_in)
  21. global QuitErrCount
  22. VolStarkCount=[0 for i in range(param.CellVoltNums)]
  23. VolCount=0
  24. QuitErrCount=[0 for i in range(param.FaultCount)]
  25. #--------------该电池的所有当前故障-------------
  26. for i in range(0,len(bms_info)):
  27. if i==0:
  28. bms_infoP=bms_info.loc[i]
  29. elif len(bms_info)>=1:
  30. bms_infoP=bms_info.loc[i-1]
  31. df_Diag_Ram_Update_inside,VolStarkCount,VolCount=SamplingSafty.VoltSamplingDiag(sn,bms_info.loc[i],bms_infoP,param,VolStarkCount,VolCount,df_Diag_Ram_Update_inside)
  32. df_Diag_Ram_Update_inside=SamplingSafty.TempSamplingDiag(sn,bms_info.loc[i],bms_infoP,param,df_Diag_Ram_Update_inside)
  33. # FltInfo=SamplingSafty.CrntSamplingDiag(sn,bms_info.loc[i],FltInfo,param)
  34. return df_Diag_Ram_Update_inside
  35. def VoltSamplingDiag(sn,bms_infoN,bms_infoP,param,VolStarkCount,VolCount,df_Diag_Ram):
  36. InVMaxBatNo=[]
  37. InVMinBatNo=[]
  38. StackVolNo=[]
  39. OutlierVolNo=[]
  40. ErrorFlg=0
  41. #——————————————————————取最高最低电压————————————————————————————————
  42. VoltageNum=['单体电压'+str(i) for i in range(1,param.CellVoltNums+1)]
  43. CellVoltage=bms_infoN[VoltageNum]/1000
  44. CellVoltageP=bms_infoP[VoltageNum]/1000
  45. MaxVolt=CellVoltage.max()
  46. MinVolt=CellVoltage.min()
  47. MaxVoltNum=CellVoltage[MaxVolt==CellVoltage].index
  48. MinVoltNum=CellVoltage[MinVolt==CellVoltage].index
  49. InVMaxBatNo=CellVoltage[CellVoltage>=param.CellOVlmt].index
  50. InVMinBatNo=CellVoltage[CellVoltage<=param.CellUVlmt].index
  51. if param.CellVoltNums>2:
  52. AvgVol=(CellVoltage.sum()-MaxVolt-MinVolt)/(param.CellVoltNums-2)
  53. else:
  54. AvgVol=CellVoltage.mean()
  55. #—————————————————————————————电压无效和断线判断———————————————————————
  56. if len(InVMaxBatNo):
  57. if len(InVMinBatNo):
  58. QuitErrCount[10]=0
  59. if not 10 in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
  60. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,10,2,'电池电压采样断线,最高电压为{:.2f}V,电池编号为{},最低电压为{:.2f}V,电池编号为{}'.format(MaxVolt,InVMaxBatNo.values,MinVolt,InVMinBatNo.values),'返厂维修']
  61. ErrorFlg=1
  62. else:#如果故障发生当前故障中有该故障,则不进行操作
  63. pass
  64. else:#如果没有故障,并且当前故障表中有该故障,则判断故障是否结束
  65. QuitErrCount[50]=0
  66. if 10 in df_Diag_Ram['code'].values.tolist():
  67. QuitErrCount[10]=QuitErrCount[10]+1
  68. if QuitErrCount[10]>3:
  69. QuitErrCount[10]=4
  70. end_time=datetime.datetime.now()
  71. end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
  72. df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==10].index,['end_time']]=end_time
  73. else:
  74. pass
  75. else:
  76. pass
  77. if not 50 in df_Diag_Ram['code'].values.tolist():
  78. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,50,2,str(InVMaxBatNo.values)+'号电压大于{:.2f}V,采样无效'.format(param.CellOVlmt),'返厂维修']
  79. ErrorFlg=1
  80. else:
  81. pass
  82. elif len(InVMinBatNo):
  83. QuitErrCount[50]=0
  84. if not 50 in df_Diag_Ram['code'].values.tolist():
  85. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,50,2,str(InVMinBatNo.values)+'号电压小于{:.2f}V,采样无效'.format(param.CellUVlmt),'返厂维修']
  86. ErrorFlg=1
  87. else:
  88. pass
  89. else:
  90. if 50 in df_Diag_Ram['code'].values.tolist():
  91. QuitErrCount[50]=QuitErrCount[50]+1
  92. if QuitErrCount[50]>3:
  93. QuitErrCount[50]=4
  94. end_time=datetime.datetime.now()
  95. end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
  96. df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==50].index,['end_time']]=end_time
  97. else:
  98. pass
  99. else:
  100. pass
  101. #——————————————————————————————————电压卡滞和离群判断—————————————————————————
  102. if ErrorFlg==0:
  103. AvgVolGap=CellVoltage-AvgVol
  104. OutlierVolNo=AvgVolGap[AvgVolGap>=param.AvgVolGap].index
  105. if len(OutlierVolNo) and abs(bms_infoN['总电流[A]'])<2 and not 51 in df_Diag_Ram['code']:
  106. VolCount=VolCount+1
  107. QuitErrCount[51]=0
  108. if VolCount>10:
  109. VolCount=11
  110. if not 51 in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
  111. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,51,2,str(OutlierVolNo.values)+'号电池电压离群','技术介入诊断']
  112. ErrorFlg=1
  113. else:#如果故障发生当前故障中有该故障,则不进行操作
  114. pass
  115. else:
  116. VolCount=0
  117. if 51 in df_Diag_Ram['code'].values.tolist():
  118. QuitErrCount[51]=QuitErrCount[51]+1
  119. if QuitErrCount[51]>3:
  120. QuitErrCount[51]=4
  121. end_time=datetime.datetime.now()
  122. end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
  123. df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==51].index,['end_time']]=end_time
  124. else:
  125. pass
  126. else:
  127. pass
  128. # -------------------卡滞逻辑未加-------------------------------------
  129. # if (abs(float(bms_infoN['总电流[A]']))>=10 and not 'PK504' in sn) or (abs(float(bms_infoN['总电流[A]']))>=15 and 'PK504' in sn):
  130. # StackVolNo=CellVoltage[abs(CellVoltage-CellVoltageP)<=0.0001].index
  131. # NotStackVolNo=CellVoltage[abs(CellVoltage-CellVoltageP)>0.0001].index
  132. # if len(StackVolNo) and not 52 in df_Diag_Ram['code']:
  133. # StackVolNo=[int(s) for s in StackVolNo.str.replace(r'[^0-9]','').tolist()]
  134. # NotStackVolNo=[int(s) for s in NotStackVolNo.str.replace(r'[^0-9]','').tolist()]
  135. # for i in StackVolNo:
  136. # VolStarkCount[i-1]=VolStarkCount[i-1]+1
  137. # for i in NotStackVolNo:
  138. # VolStarkCount[i-1]=0
  139. # if [s for s in VolStarkCount]>10:
  140. # StacVolNo=
  141. return df_Diag_Ram,VolStarkCount,VolCount
  142. def TempSamplingDiag(sn,bms_infoN,bms_infoP,param,df_Diag_Ram):
  143. InVMaxBatNo=[]
  144. InVMinBatNo=[]
  145. StackVolNo=[]
  146. OutlierVolNo=[]
  147. ErrorFlg=0
  148. #——————————————————————Cell取最高最低温度————————————————————————————————
  149. TempNum=['单体温度'+str(i) for i in range(1,param.CellTempNums+1)]
  150. CellTemp=bms_infoN[TempNum]
  151. CellTempP=bms_infoP[TempNum]
  152. maxCellTemp=CellTemp.max()
  153. minCellTemp=CellTemp.min()
  154. MaxVoltNum=CellTemp[maxCellTemp==CellTemp].index
  155. MinVoltNum=CellTemp[minCellTemp==CellTemp].index
  156. InVMaxTempBatNo=CellTemp[CellTemp>=param.PackOTlmt].index
  157. InVMinTempBatNo=CellTemp[CellTemp<=param.PackUTlmt].index
  158. if param.CellTempNums>2:
  159. AvgCellTemp=(CellTemp.sum()-maxCellTemp-minCellTemp)/(param.CellTempNums-2)
  160. else:
  161. AvgCellTemp=CellTemp.mean()
  162. #——————————————————————温度无效,离群和断线判断———————————————————————
  163. if len(InVMaxTempBatNo):
  164. if len(InVMinTempBatNo):
  165. QuitErrCount[53]=0
  166. if not 53 in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
  167. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,53,2,'电池温度采样断线,最高温度为{}℃,电池编号为{},最低温度为{}℃,电池编号为{}'.format(maxCellTemp,InVMaxTempBatNo.values,minCellTemp,InVMinTempBatNo.values),'返厂维修']
  168. ErrorFlg=1
  169. else:#如果故障发生当前故障中有该故障,则不进行操作
  170. pass
  171. else:#如果没有故障,并且当前故障表中有该故障,则判断故障是否结束
  172. QuitErrCount[2]=0
  173. if 53 in df_Diag_Ram['code'].values.tolist():
  174. QuitErrCount[53]=QuitErrCount[53]+1
  175. if QuitErrCount[53]>3:
  176. QuitErrCount[53]=4
  177. end_time=datetime.datetime.now()
  178. end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
  179. df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==53].index,['end_time']]=end_time
  180. else:
  181. pass
  182. else:
  183. pass
  184. if not 2 in df_Diag_Ram['code'].values.tolist():
  185. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,2,2,str(InVMaxTempBatNo.values)+'号温度大于{}℃,采样无效'.format(param.PackOTlmt),'联系用户核实电池温度情况,并返厂维修']
  186. ErrorFlg=1
  187. else:
  188. pass
  189. elif len(InVMinTempBatNo):
  190. QuitErrCount[2]=0
  191. if not 2 in df_Diag_Ram['code'].values.tolist():
  192. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,2,2,str(InVMinTempBatNo.values)+'号温度小于{}℃,采样无效'.format(param.PackUTlmt),'返厂维修']
  193. ErrorFlg=1
  194. else:
  195. pass
  196. else:
  197. if 2 in df_Diag_Ram['code'].values.tolist():
  198. QuitErrCount[2]=QuitErrCount[2]+1
  199. if QuitErrCount[2]>3:
  200. QuitErrCount[2]=4
  201. end_time=datetime.datetime.now()
  202. end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
  203. df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==2].index,['end_time']]=end_time
  204. else:
  205. pass
  206. else:
  207. pass
  208. if ErrorFlg==0:
  209. AvgCellTempGap=abs(CellTemp-AvgCellTemp)
  210. OutlierTempNo=AvgCellTempGap[AvgCellTempGap>=param.AvgCellTempGap].index
  211. if len(OutlierTempNo):
  212. QuitErrCount[8]=0
  213. if not 8 in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
  214. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,8,2,str(OutlierTempNo.values)+'号电池异常温度离群','技术介入诊断']
  215. ErrorFlg=1
  216. else:#如果故障发生当前故障中有该故障,则不进行操作
  217. pass
  218. else:
  219. if 8 in df_Diag_Ram['code'].values.tolist():
  220. QuitErrCount[8]=QuitErrCount[8]+1
  221. if QuitErrCount[8]>3:
  222. QuitErrCount[8]=4
  223. end_time=datetime.datetime.now()
  224. end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
  225. df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==8].index,['end_time']]=end_time
  226. else:
  227. pass
  228. else:
  229. pass
  230. #——————————————————————————————————OtherTemp————————————————————————————————————
  231. if param.OtherTempNums>0:
  232. OtherTempNum=['其他温度'+str(i) for i in range(1,param.OtherTempNums+1)]
  233. OtherTemp=bms_infoN[OtherTempNum]
  234. OtherTemppP=bms_infoP[OtherTempNum]
  235. maxOtherTemp=OtherTemp.max()
  236. minOtherTemp=OtherTemp.min()
  237. MaxVoltNum=OtherTemp[maxOtherTemp==OtherTemp].index
  238. MinVoltNum=OtherTemp[minOtherTemp==OtherTemp].index
  239. InVMaxOtherTempBatNo=OtherTemp[OtherTemp>=param.OtherOTlmt].index
  240. InVMinOtherTempBatNo=OtherTemp[OtherTemp<=param.OtherUTlmt].index
  241. if param.OtherTempNums>2:
  242. AvgOtherTemp=(OtherTemp.sum()-maxOtherTemp-minOtherTemp)/(param.OtherTempNums-2)
  243. else:
  244. AvgOtherTemp=OtherTemp.mean()
  245. #——————————————————————温度无效,离群和断线判断———————————————————————
  246. if len(InVMaxOtherTempBatNo):
  247. if len(InVMinOtherTempBatNo):
  248. QuitErrCount[54]=0
  249. if not 54 in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
  250. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,54,2,'其他温度采样断线,最高温度为{}℃,传感器编号为{},最低温度为{}℃,传感器编号为{}'.format(maxOtherTemp,InVMaxOtherTempBatNo.values,minOtherTemp,InVMinOtherTempBatNo.values),'返厂维修']
  251. ErrorFlg=1
  252. else:#如果故障发生当前故障中有该故障,则不进行操作
  253. pass
  254. else:#如果没有故障,并且当前故障表中有该故障,则判断故障是否结束
  255. QuitErrCount[55]=0
  256. if 54 in df_Diag_Ram['code'].values.tolist():
  257. QuitErrCount[54]=QuitErrCount[54]+1
  258. if QuitErrCount[54]>3:
  259. QuitErrCount[54]=4
  260. end_time=datetime.datetime.now()
  261. end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
  262. df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==54].index,['end_time']]=end_time
  263. else:
  264. pass
  265. else:
  266. pass
  267. if not 55 in df_Diag_Ram['code'].values.tolist():
  268. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,55,2,'传感器温度大于{}℃,采样无效'.format(param.OtherOTlmt),'联系用户核实电池温度情况,并返厂维修']
  269. ErrorFlg=1
  270. else:
  271. pass
  272. elif len(InVMinTempBatNo):
  273. QuitErrCount[55]=0
  274. if not 55 in df_Diag_Ram['code'].values.tolist():
  275. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,55,2,'传感器温度小于{}℃,采样无效'.format(param.OtherUTlmt),'返厂维修']
  276. ErrorFlg=1
  277. else:
  278. pass
  279. else:
  280. if 55 in df_Diag_Ram['code'].values.tolist():
  281. QuitErrCount[55]=QuitErrCount[55]+1
  282. if QuitErrCount[55]>3:
  283. QuitErrCount[55]=4
  284. end_time=datetime.datetime.now()
  285. end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
  286. df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==55].index,['end_time']]=end_time
  287. else:
  288. pass
  289. else:
  290. pass
  291. if ErrorFlg==0:
  292. AvgOtherTempGap=abs(OtherTemp-AvgOtherTemp)
  293. OutlierOtherTempNo=AvgOtherTempGap[AvgOtherTempGap>=param.AvgOtherTempGap].index
  294. if len(OutlierOtherTempNo):
  295. QuitErrCount[56]=0
  296. if not 56 in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
  297. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,56,2,'传感器温度异常离群','技术介入诊断']
  298. ErrorFlg=1
  299. else:#如果故障发生当前故障中有该故障,则不进行操作
  300. pass
  301. else:
  302. if 56 in df_Diag_Ram['code'].values.tolist():
  303. QuitErrCount[56]=QuitErrCount[56]+1
  304. if QuitErrCount[56]>3:
  305. QuitErrCount[56]=4
  306. end_time=datetime.datetime.now()
  307. end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
  308. df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==56].index,['end_time']]=end_time
  309. else:
  310. pass
  311. else:
  312. pass
  313. if (maxOtherTemp-maxCellTemp)>param.AvgOtherTempGap and maxOtherTemp<param.OtherOTlmt and maxCellTemp<param.PackOTlmt:
  314. QuitErrCount[56]=0
  315. if not 56 in df_Diag_Ram['code'].values.tolist():
  316. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,56,2,'传感器温度异常离群','技术立即介入诊断']
  317. ErrorFlg=1
  318. else:
  319. if 56 in df_Diag_Ram['code'].values.tolist():
  320. QuitErrCount[56]=QuitErrCount[56]+1
  321. if QuitErrCount[56]>3:
  322. QuitErrCount[56]=4
  323. end_time=datetime.datetime.now()
  324. end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
  325. df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==56].index,['end_time']]=end_time
  326. if (maxCellTemp-maxOtherTemp)>param.AvgOtherTempGap and maxOtherTemp<param.OtherOTlmt and maxCellTemp<param.PackOTlmt and not 8 in df_Diag_Ram['code']:
  327. QuitErrCount[8]=0
  328. if not 8 in df_Diag_Ram['code'].values.tolist():
  329. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,8,2,str(OutlierTempNo.values)+'号电芯温度异常离群','技术立即介入诊断']
  330. ErrorFlg=1
  331. else:
  332. if 8 in df_Diag_Ram['code'].values.tolist():
  333. QuitErrCount[8]=QuitErrCount[8]+1
  334. if QuitErrCount[8]>3:
  335. QuitErrCount[8]=4
  336. end_time=datetime.datetime.now()
  337. end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
  338. df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==8].index,['end_time']]=end_time
  339. return df_Diag_Ram