SC_SamplingSafty.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  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 'C310' 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,'C310',3,'电池电压采样断线,最高电压为{:.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 'C310' 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']=='C310'].index,['end_time']]=end_time
  73. else:
  74. pass
  75. else:
  76. pass
  77. if not 'C350' 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,'C350',3,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 'C350' 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,'C350',3,str(InVMinBatNo.values)+'号电压小于{:.2f}V,采样无效'.format(param.CellUVlmt),'返厂维修']
  86. ErrorFlg=1
  87. else:
  88. pass
  89. else:
  90. if 'C350' 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 'C251' in df_Diag_Ram['code']:
  106. VolCount=VolCount+1
  107. QuitErrCount[51]=0
  108. if VolCount>10:
  109. VolCount=11
  110. if not 'C251' 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,'C251',2,str(OutlierVolNo.values)+'号电池电压离群','技术介入诊断']
  112. ErrorFlg=1
  113. else:#如果故障发生当前故障中有该故障,则不进行操作
  114. pass
  115. else:
  116. VolCount=0
  117. if 'C251' 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']=='C251'].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 'C353' 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,'C353',3,'电池温度采样断线,最高温度为{}℃,电池编号为{},最低温度为{}℃,电池编号为{}'.format(maxCellTemp,InVMaxTempBatNo.values,minCellTemp,InVMinTempBatNo.values),'返厂维修']
  168. ErrorFlg=1
  169. else:#如果故障发生当前故障中有该故障,则不进行操作
  170. pass
  171. else:#如果没有故障,并且当前故障表中有该故障,则判断故障是否结束
  172. QuitErrCount[2]=0
  173. if 'C353' 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']=='C353'].index,['end_time']]=end_time
  180. else:
  181. pass
  182. else:
  183. pass
  184. if not 'C302' 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,'C302',3,str(InVMaxTempBatNo.values)+'号温度大于{}℃,采样无效'.format(param.PackOTlmt),'联系用户核实电池温度情况,并返厂维修']
  186. ErrorFlg=1
  187. else:
  188. pass
  189. elif len(InVMinTempBatNo):
  190. QuitErrCount[2]=0
  191. if not 'C302' 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,'C302',3,str(InVMinTempBatNo.values)+'号温度小于{}℃,采样无效'.format(param.PackUTlmt),'返厂维修']
  193. ErrorFlg=1
  194. else:
  195. pass
  196. else:
  197. if 'C302' 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']=='C302'].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 'C108' 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,'C108',1,str(OutlierTempNo.values)+'号电池异常温度离群','技术介入诊断']
  215. ErrorFlg=1
  216. else:#如果故障发生当前故障中有该故障,则不进行操作
  217. pass
  218. else:
  219. if 'C108' 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']=='C108'].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. if 'MGMLX' in sn:
  235. OtherTemp['其他温度2']=OtherTemp['其他温度1']
  236. else:
  237. pass
  238. OtherTemppP=bms_infoP[OtherTempNum]
  239. maxOtherTemp=OtherTemp.max()
  240. minOtherTemp=OtherTemp.min()
  241. MaxVoltNum=OtherTemp[maxOtherTemp==OtherTemp].index
  242. MinVoltNum=OtherTemp[minOtherTemp==OtherTemp].index
  243. InVMaxOtherTempBatNo=OtherTemp[OtherTemp>=param.OtherOTlmt].index
  244. InVMinOtherTempBatNo=OtherTemp[OtherTemp<=param.OtherUTlmt].index
  245. if param.OtherTempNums>2:
  246. AvgOtherTemp=(OtherTemp.sum()-maxOtherTemp-minOtherTemp)/(param.OtherTempNums-2)
  247. else:
  248. AvgOtherTemp=OtherTemp.mean()
  249. #——————————————————————温度无效,离群和断线判断———————————————————————
  250. if len(InVMaxOtherTempBatNo):
  251. if len(InVMinOtherTempBatNo):
  252. QuitErrCount[54]=0
  253. if not 'C354' in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
  254. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C354',3,'其他温度采样断线,最高温度为{}℃,传感器编号为{},最低温度为{}℃,传感器编号为{}'.format(maxOtherTemp,InVMaxOtherTempBatNo.values,minOtherTemp,InVMinOtherTempBatNo.values),'返厂维修']
  255. ErrorFlg=1
  256. else:#如果故障发生当前故障中有该故障,则不进行操作
  257. pass
  258. else:#如果没有故障,并且当前故障表中有该故障,则判断故障是否结束
  259. QuitErrCount[55]=0
  260. if 'C354' in df_Diag_Ram['code'].values.tolist():
  261. QuitErrCount[54]=QuitErrCount[54]+1
  262. if QuitErrCount[54]>3:
  263. QuitErrCount[54]=4
  264. end_time=datetime.datetime.now()
  265. end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
  266. df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']=='C354'].index,['end_time']]=end_time
  267. else:
  268. pass
  269. else:
  270. pass
  271. if not 'C355' in df_Diag_Ram['code'].values.tolist():
  272. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C355',3,'传感器温度大于{}℃,采样无效'.format(param.OtherOTlmt),'联系用户核实电池温度情况,并返厂维修']
  273. ErrorFlg=1
  274. else:
  275. pass
  276. elif len(InVMinTempBatNo):
  277. QuitErrCount[55]=0
  278. if not 'C355' in df_Diag_Ram['code'].values.tolist():
  279. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C355',3,'传感器温度小于{}℃,采样无效'.format(param.OtherUTlmt),'返厂维修']
  280. ErrorFlg=1
  281. else:
  282. pass
  283. else:
  284. if 'C355' in df_Diag_Ram['code'].values.tolist():
  285. QuitErrCount[55]=QuitErrCount[55]+1
  286. if QuitErrCount[55]>3:
  287. QuitErrCount[55]=4
  288. end_time=datetime.datetime.now()
  289. end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
  290. df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']=='C355'].index,['end_time']]=end_time
  291. else:
  292. pass
  293. else:
  294. pass
  295. if ErrorFlg==0:
  296. AvgOtherTempGap=abs(OtherTemp-AvgOtherTemp)
  297. OutlierOtherTempNo=AvgOtherTempGap[AvgOtherTempGap>=param.AvgOtherTempGap].index
  298. if len(OutlierOtherTempNo):
  299. QuitErrCount[56]=0
  300. if not 'C156' in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
  301. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C156',1,'传感器温度异常离群','技术介入诊断']
  302. ErrorFlg=1
  303. else:#如果故障发生当前故障中有该故障,则不进行操作
  304. pass
  305. else:
  306. if 'C156' in df_Diag_Ram['code'].values.tolist():
  307. QuitErrCount[56]=QuitErrCount[56]+1
  308. if QuitErrCount[56]>3:
  309. QuitErrCount[56]=4
  310. end_time=datetime.datetime.now()
  311. end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
  312. df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']=='C156'].index,['end_time']]=end_time
  313. else:
  314. pass
  315. else:
  316. pass
  317. if (maxOtherTemp-maxCellTemp)>param.AvgOtherTempGap and maxOtherTemp<param.OtherOTlmt and maxCellTemp<param.PackOTlmt:
  318. QuitErrCount[56]=0
  319. if not 'C156' in df_Diag_Ram['code'].values.tolist():
  320. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C156',1,'传感器温度异常离群','技术立即介入诊断']
  321. ErrorFlg=1
  322. else:
  323. if 'C156' in df_Diag_Ram['code'].values.tolist():
  324. QuitErrCount[56]=QuitErrCount[56]+1
  325. if QuitErrCount[56]>3:
  326. QuitErrCount[56]=4
  327. end_time=datetime.datetime.now()
  328. end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
  329. df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']=='C156'].index,['end_time']]=end_time
  330. if (maxCellTemp-maxOtherTemp)>param.AvgOtherTempGap and maxOtherTemp<param.OtherOTlmt and maxCellTemp<param.PackOTlmt and not 8 in df_Diag_Ram['code']:
  331. QuitErrCount[8]=0
  332. if not 'C108' in df_Diag_Ram['code'].values.tolist():
  333. df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C108',1,str(OutlierTempNo.values)+'号电芯温度异常离群','技术立即介入诊断']
  334. ErrorFlg=1
  335. else:
  336. if 'C108' in df_Diag_Ram['code'].values.tolist():
  337. QuitErrCount[8]=QuitErrCount[8]+1
  338. if QuitErrCount[8]>3:
  339. QuitErrCount[8]=4
  340. end_time=datetime.datetime.now()
  341. end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
  342. df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']=='C108'].index,['end_time']]=end_time
  343. return df_Diag_Ram