CBMSBatDiag.py 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. import pandas as pd
  2. import numpy as np
  3. import datetime
  4. from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import BatParam
  5. class BatDiag:
  6. def __init__(self,sn,celltype,df_bms,df_soh,df_uniform,df_diag_Ram): #参数初始化
  7. self.sn=sn
  8. self.celltype=celltype
  9. self.param=BatParam.BatParam(celltype)
  10. self.df_bms=df_bms
  11. self.df_soh=df_soh
  12. self.df_uniform=df_uniform
  13. self.df_diag_ram=df_diag_Ram
  14. self.packcrnt=df_bms['总电流[A]']*self.param.PackCrntDec
  15. self.packvolt=df_bms['总电压[V]']
  16. self.bms_soc=df_bms['SOC[%]']
  17. self.bmstime= pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
  18. self.bmsfault1=self.df_bms['故障代码']
  19. # self.bmsfault2=self.df_bms['alarm2'].tolist()
  20. # self.bmsfault3=self.df_bms['alarm3'].tolist()
  21. # self.bmsfault4=self.df_bms['fault'].tolist()
  22. self.cellvolt_name=['单体电压'+str(x) for x in range(1,self.param.CellVoltNums+1)]
  23. self.celltemp_name=['单体温度'+str(x) for x in range(1,self.param.CellTempNums+1)]
  24. def diag(self):
  25. if self.celltype<=50:
  26. df_res=self._ncm_diag()
  27. return df_res
  28. else:
  29. df_res=self._ncm_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 = list(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]/1000)
  41. return cellvolt
  42. #..........................................三元电池诊断功能..................................................................
  43. def _ncm_diag(self):
  44. bmssoc_st=float(self.bms_soc[0]) #SOC卡滞初始参数
  45. ah_accum=0 #SOC卡滞初始参数
  46. as_chg=0 #过流诊断初始参数
  47. as_dis=0 #过流诊断初始参数
  48. time1=self.bmstime[0] #温升速率初始参数
  49. temp1=np.array(self._celltemp_get(0)) #温升速率初始参数
  50. temprate_cnt=0
  51. end_time='0000-00-00 00:00:00'
  52. for i in range(1,len(self.df_bms)):
  53. #温度诊断功能.............................................................................................................
  54. celltemp0=self._celltemp_get(i-1)
  55. celltemp1=self._celltemp_get(i)
  56. celltempmin0=min(celltemp0)
  57. celltempmin1=min(celltemp1)
  58. celltempmax0=max(celltemp0)
  59. celltempmax1=max(celltemp1)
  60. #温度有效性判断..........................................................................
  61. if celltempmax0>self.param.CellTempUpLmt or celltempmin0<self.param.CellTempLwLmt:
  62. celltempvalid=0
  63. else:
  64. celltempvalid=1
  65. if celltempvalid==1:
  66. #过温判断.............................................................................................................
  67. if not 4 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  68. if celltempmax0>self.param.CellTempHighLv2 and celltempmax1>self.param.CellTempHighLv2: #二级高温进入
  69. time=self.bmstime[i]
  70. code=4
  71. faultlv=3
  72. faultinfo='温度{}高温二级'.format(celltemp1.index(celltempmax1)+1)
  73. faultadvice='技术介入诊断'
  74. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  75. else:
  76. pass
  77. else: #ram当前故障中有该故障,则判断是否退出该故障
  78. if celltempmax0<self.param.CellTempHighLv1-5 and celltempmax1<self.param.CellTempHighLv1-5: #二级高温恢复
  79. time=self.bmstime[i]
  80. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==4].index, 'end_time'] = time
  81. else:
  82. pass
  83. #欠温判断.................................................................................................................
  84. if not 6 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  85. if celltempmin0<self.param.CellTempLowLv2 and celltempmin1<self.param.CellTempLowLv2: #二级低温进入
  86. time=self.bmstime[i]
  87. code=6
  88. faultlv=3
  89. faultinfo='温度{}低温二级'.format(celltemp1.index(celltempmin1)+1)
  90. faultadvice='技术介入诊断'
  91. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  92. else:
  93. pass
  94. else: #ram当前故障中有该故障,则判断是否退出该故障
  95. if celltempmax0>self.param.CellTempLowLv1+2 and celltempmax1>self.param.CellTempLowLv1+2: #二级高温恢复
  96. time=self.bmstime[i]
  97. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==6].index, 'end_time'] = time
  98. else:
  99. pass
  100. #温差判断.............................................................................................................................
  101. if not 8 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  102. if (celltempmax0-celltempmin0)>self.param.CellTempDiffLv2 and (celltempmax1-celltempmin1)>self.param.CellTempDiffLv2: #二级温差进入
  103. time=self.bmstime[i]
  104. code=8
  105. faultlv=3
  106. faultinfo='温度{}和{}温差大二级'.format(celltemp1.index(celltempmax1)+1,celltemp1.index(celltempmin1)+1)
  107. faultadvice='技术介入诊断'
  108. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  109. else:
  110. pass
  111. else: #ram当前故障中有该故障,则判断是否退出该故障
  112. if (celltempmax0-celltempmin0)<self.param.CellTempDiffLv1-2 and (celltempmax1-celltempmax0)>self.param.CellTempDiffLv1-2: #二级温差恢复
  113. time=self.bmstime[i]
  114. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==8].index, 'end_time'] = time
  115. else:
  116. pass
  117. #温升判断
  118. time2=self.bmstime[i]
  119. delttime=(time2-time1).total_seconds()
  120. if delttime>20:
  121. temp2=np.array(self._celltemp_get(i))
  122. celltemp_rate=(max(temp2-temp1)*60)/delttime #计算最大温升速率
  123. temp1=temp2 #更新初始温度
  124. time1=time2 #更新初始时间
  125. if celltemp_rate>self.param.CellTempRate:
  126. temprate_cnt=temprate_cnt+1
  127. if not 9 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  128. if temprate_cnt>2: #温升故障进入
  129. time=self.bmstime[i]
  130. code=9
  131. faultlv=3
  132. faultinfo='温升速率过快:{}℃/min'.format(celltemp_rate)
  133. faultadvice='技术介入诊断'
  134. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  135. else:
  136. pass
  137. else: #ram当前故障中有该故障,则判断是否退出该故障
  138. if celltemp_rate<self.param.CellTempRate-1: #温升故障恢复
  139. time=self.bmstime[i]
  140. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==9].index, 'end_time'] = time
  141. else:
  142. pass
  143. else:
  144. pass
  145. else:
  146. pass
  147. #电压诊断功能.................................................................................................
  148. cellvolt0=self._cellvolt_get(i-1)
  149. cellvolt1=self._cellvolt_get(i)
  150. cellvoltmin0=min(cellvolt0)
  151. cellvoltmax0=max(cellvolt0)
  152. cellvoltmin1=min(cellvolt1)
  153. cellvoltmax1=max(cellvolt1)
  154. #电压断线诊断...................................................................................................
  155. if (cellvoltmin0<2 and cellvoltmax0>4.5) or cellvoltmin0<0.1 or cellvoltmax0>5:
  156. cellvoltvalid=0
  157. else:
  158. cellvoltvalid=1
  159. if cellvoltvalid==1:
  160. #过压诊断.............................................................................................................
  161. if not 12 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  162. if cellvoltmax0>self.param.CellOvLv2 and cellvoltmax1>self.param.CellOvLv2: #二级过压进入
  163. time=self.bmstime[i]
  164. code=12
  165. faultlv=4
  166. faultinfo='电芯{}过压二级'.format(cellvolt1.index(cellvoltmax1)+1)
  167. faultadvice='联系用户询问用车场景,技术介入诊断'
  168. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  169. else:
  170. pass
  171. else: #ram当前故障中有该故障,则判断是否退出该故障
  172. if cellvoltmax0<self.param.CellOvLv1-0.05 and cellvoltmax1<self.param.CellOvLv1-0.05: #二级过压故障恢复
  173. time=self.bmstime[i]
  174. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==12].index, 'end_time'] = time
  175. else:
  176. pass
  177. #欠压诊断.................................................................................................................
  178. if not 14 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  179. if cellvoltmin0<self.param.CellUvLv2 and cellvoltmin1<self.param.CellUvLv2: #二级欠压
  180. time=self.bmstime[i]
  181. code=14
  182. faultlv=3
  183. faultinfo='电芯{}欠压二级'.format(cellvolt1.index(cellvoltmin1)+1)
  184. faultadvice='联系用户询问用车场景,技术介入诊断'
  185. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  186. else:
  187. pass
  188. else:
  189. if cellvoltmin0>self.param.CellUvLv1+0.1 and cellvoltmin1>self.param.CellUvLv1+0.1:
  190. time=self.bmstime[i]
  191. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==14].index, 'end_time'] = time
  192. else:
  193. pass
  194. #电芯压差大.....................................................................................................................................................
  195. if not 16 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  196. if (cellvoltmax0-cellvoltmin0)>self.param.CellVoltDiffLv2 and (cellvoltmax1-cellvoltmin1)>self.param.CellVoltDiffLv2: #二级电芯压差
  197. time=self.bmstime[i]
  198. code=16
  199. faultlv=3
  200. faultinfo='电芯{}和{}压差大二级'.format(cellvolt1.index(cellvoltmax1)+1,cellvolt1.index(cellvoltmin1)+1)
  201. faultadvice='技术介入诊断'
  202. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  203. else:
  204. pass
  205. else:
  206. if (cellvoltmax0-cellvoltmin0)<self.param.CellVoltDiffLv1-0.05 and (cellvoltmax1-cellvoltmin1)>self.param.CellVoltDiffLv1-0.05: #二级欠压恢复
  207. time=self.bmstime[i]
  208. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==16].index, 'end_time'] = time
  209. else:
  210. pass
  211. else:
  212. pass
  213. #电池包诊断.....................................................................................................................................
  214. if not 18 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  215. if self.packvolt[i-1]>self.param.PackVoltOvLv2 and self.packvolt[i]>self.param.PackVoltOvLv2: #电池包过压二级进入
  216. time=self.bmstime[i]
  217. code=18
  218. faultlv=4
  219. faultinfo='电池包过压二级'
  220. faultadvice='联系用户询问用车场景,技术介入诊断'
  221. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  222. else:
  223. pass
  224. else:
  225. 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: #电池包过压二级恢复
  226. time=self.bmstime[i]
  227. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==18].index, 'end_time'] = time
  228. else:
  229. pass
  230. #电池包诊断.....................................................................................................................................
  231. if not 20 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  232. if self.packvolt[i-1]<self.param.PackVoltUvLv2 and self.packvolt[i]<self.param.PackVoltUvLv2: #电池包二级欠压进入
  233. time=self.bmstime[i]
  234. code=20
  235. faultlv=3
  236. faultinfo='电池包欠压二级'
  237. faultadvice='联系用户询问用车场景,技术介入诊断'
  238. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  239. else:
  240. pass
  241. else:
  242. 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: #电池包二级欠压恢复
  243. time=self.bmstime[i]
  244. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==20].index, 'end_time'] = time
  245. else:
  246. pass
  247. #电流过流诊断.......................................................................................................................
  248. step=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
  249. if step<120 and self.packcrnt[i]>self.param.PackDisOc:
  250. as_dis=as_dis+(self.packcrnt[i]-self.param.self.PackDisOc)*step #ah累计
  251. elif step<120 and self.packcrnt[i]<self.param.PackChgOc:
  252. as_chg=as_chg+(self.param.PackDisOc-self.packcrnt[i])*step #ah累计
  253. else:
  254. as_dis=0
  255. as_chg=0
  256. if not 22 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  257. if as_dis>100:
  258. time=self.bmstime[i]
  259. code=22
  260. faultlv=3
  261. faultinfo='电池包放电过流'
  262. faultadvice='联系用户询问用车场景,技术介入诊断'
  263. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  264. else:
  265. pass
  266. else:
  267. if self.packcrnt[i-1]<self.param.PackDisOc-10 and self.packcrnt[i]<self.param.PackDisOc-10:
  268. time=self.bmstime[i]
  269. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==22].index, 'end_time'] = time
  270. else:
  271. pass
  272. if not 21 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  273. if as_chg>100:
  274. time=self.bmstime[i]
  275. code=21
  276. faultlv=3
  277. faultinfo='电池包充电过流'
  278. faultadvice='联系用户询问用车场景,技术介入诊断'
  279. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  280. else:
  281. pass
  282. else:
  283. if self.packcrnt[i-1]>self.param.PackChgOc+10 and self.packcrnt[i]>self.param.PackChgOc+10:
  284. time=self.bmstime[i]
  285. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==22].index, 'end_time'] = time
  286. else:
  287. pass
  288. #SOC卡滞、跳变诊断................................................................................................
  289. step=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
  290. if step<120:
  291. ah_accum=ah_accum-self.packcrnt[i]*step/3600 #ah累计
  292. else:
  293. pass
  294. #SOC卡滞............................................................................................................
  295. if abs(ah_accum)>self.param.Capacity*0.05:
  296. bmssoc_now=float(self.bms_soc[i])
  297. if not 27 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  298. if abs(bmssoc_now-bmssoc_st)<self.param.SocClamp: #SOC卡滞故障进入
  299. time=self.bmstime[i]
  300. code=27
  301. faultlv=1
  302. faultinfo='电池SOC卡滞'
  303. faultadvice='技术介入诊断,检修电池BMS软件'
  304. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  305. else:
  306. pass
  307. else:
  308. if abs(bmssoc_now-bmssoc_st)>self.param.SocClamp: #SOC卡滞故障退出
  309. time=self.bmstime[i]
  310. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==27].index, 'end_time'] = time
  311. else:
  312. pass
  313. bmssoc_st=bmssoc_now
  314. ah_accum=0
  315. else:
  316. pass
  317. #SOC跳变....................................................................................................................
  318. if step<30:
  319. bmssoc_last=float(self.bms_soc[i-1])
  320. bmssoc_now=float(self.bms_soc[i])
  321. if not 28 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  322. if abs(bmssoc_now-bmssoc_last)>self.param.SocJump: #SOC跳变进入
  323. time=self.bmstime[i]
  324. code=28
  325. faultlv=1
  326. faultinfo='电池SOC跳变'
  327. faultadvice='技术介入诊断,检修电池BMS软件'
  328. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  329. else:
  330. pass
  331. else:
  332. if abs(bmssoc_now-bmssoc_st)<self.param.SocJump: #SOC跳变故障退出
  333. time=self.bmstime[i]
  334. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==28].index, 'end_time'] = time
  335. else:
  336. pass
  337. else:
  338. pass
  339. #SOC过低故障报警............................................................................................................
  340. if not 26 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  341. if self.bms_soc[i-1]<self.param.SocLow and self.bms_soc[i]<self.param.SocLow: #SOC过低故障进入
  342. time=self.bmstime[0]
  343. code=26
  344. faultlv=1
  345. faultinfo='电池包电量过低'
  346. faultadvice='联系用户,请立刻充电'
  347. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  348. else:
  349. pass
  350. else:
  351. if self.bms_soc[i-1]>self.param.SocLow and self.bms_soc[i]>self.param.SocLow: #SOC过低故障退出
  352. time=self.bmstime[i]
  353. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==26].index, 'end_time'] = time
  354. else:
  355. pass
  356. #BMS故障报警........................................................................................................
  357. if not 1 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  358. if self.bmsfault1[i-1] is None or self.bmsfault1[i] is None:
  359. self.bmsfault1[i-1]=0
  360. self.bmsfault1[i]=0
  361. if self.bmsfault1[i-1]>0 or self.bmsfault1[i]>0: #BMS故障进入
  362. time=self.bmstime[0]
  363. code=1
  364. faultlv=2
  365. faultinfo='BMS故障报警:{}'.format(self.bmsfault1[i-1])
  366. faultadvice='技术介入诊断'
  367. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  368. else:
  369. pass
  370. else:
  371. if self.bmsfault1[i-1]==0 and self.bmsfault1[i]==0: #BMS故恢复
  372. time=self.bmstime[i]
  373. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==1].index, 'end_time'] = time
  374. #SOC一致性故障报警..........................................................................................................
  375. if not self.df_uniform.empty:
  376. cellsoc_diff=self.df_uniform.loc[0,'cellsoc_diff']
  377. if not 25 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  378. if cellsoc_diff>self.param.SocDiff: #SOC一致性差故障进入
  379. time=self.bmstime[0]
  380. code=25
  381. faultlv=1
  382. faultinfo='电芯{}和{}SOC差过大:{}'.format(self.df_uniform.loc[0,'cellmin_num'],self.df_uniform.loc[0,'cellmax_num']),cellsoc_diff
  383. faultadvice='技术介入诊断'
  384. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  385. else:
  386. pass
  387. else:
  388. if cellsoc_diff<self.param.SocDiff: #SOC一致性差故障恢复
  389. time=self.bmstime[i]
  390. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==25].index, 'end_time'] = time
  391. else:
  392. cellsoc_diff=3
  393. #容量过低和一致性故障报警................................................................................................
  394. if not self.df_soh.empty:
  395. soh=self.df_soh.loc[0,'soh']
  396. cellsoh=eval(self.df_soh.loc[0,'cellsoh'])
  397. cellsoh=np.array(cellsoh)
  398. cellsoh_lowindex=np.argwhere(cellsoh<self.param.SohLow)
  399. cellsoh_lowindex=cellsoh_lowindex+1
  400. if self.celltype==1 or self.celltype==2 or self.celltype==3 or self.celltype==4:
  401. cellsoh_diff=max(cellsoh)-min(cellsoh)
  402. if not 23 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  403. if soh<self.param.SohLow: #soh过低故障进入
  404. time=self.bmstime[0]
  405. code=23
  406. faultlv=1
  407. faultinfo='电池包容量过低:电芯{}'.format(cellsoh_lowindex)
  408. faultadvice='检修电池,更换容量过低的电芯或模组'
  409. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  410. else:
  411. pass
  412. else:
  413. if soh>self.param.SohLow+2: #soh过低故障恢复
  414. time=self.bmstime[i]
  415. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==23].index, 'end_time'] = time
  416. else:
  417. pass
  418. if not 24 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  419. if cellsoh_diff>self.param.SohDiff:
  420. time=self.bmstime[0]
  421. code=24
  422. faultlv=1
  423. faultinfo='电池包容量一致性差:电芯{}'.format(cellsoh_lowindex)
  424. faultadvice='检修电池,更换容量过低的电芯或模组'
  425. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  426. else:
  427. pass
  428. else:
  429. if cellsoh_diff<self.param.SohDiff-2:
  430. time=self.bmstime[i]
  431. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==24].index, 'end_time'] = time
  432. else:
  433. pass
  434. else:
  435. pass
  436. else:
  437. cellsoh_diff=5
  438. # #电池健康度评分.....................................................................................................
  439. # health_state=soh*0.6+(100-cellsoh_diff)*0.2+(100-cellsoc_diff)*0.2
  440. # if health_state>100:
  441. # health_state=100
  442. # elif health_state<0:
  443. # health_state=0
  444. # else:
  445. # pass
  446. # health_state=eval(format(health_state,'.1f'))
  447. #返回诊断结果...........................................................................................................
  448. df_res=self.df_diag_ram
  449. if not df_res.empty:
  450. return df_res
  451. else:
  452. return pd.DataFrame()
  453. #............................................................内短路故障诊断.............................................................................
  454. class ShortDiag():
  455. def __init__(self,sn,celltype,df_short): #参数初始化
  456. self.sn=sn
  457. self.celltype=celltype
  458. self.param=BatParam.BatParam(celltype)
  459. self.df_short=df_short
  460. def shortdiag(self):
  461. if len(self.df_short)>1:
  462. df_res=self._short_diag()
  463. return df_res
  464. else:
  465. return pd.DataFrame()
  466. #内短路故障检测...................................................................................................................................
  467. def _short_diag(self):
  468. column_name=['start_time', 'end_time', 'product_id', 'code', 'level', 'info','advice']
  469. df_res=pd.DataFrame(columns=column_name)
  470. time=datetime.datetime.now()
  471. end_time=datetime.datetime.strftime('0000-00-00 00:00:00')
  472. end_time=datetime.datetime.strptime(end_time,'%Y-%m-%d %H:%M:%S')
  473. # if self.df_diag.empty:
  474. # health_state=100
  475. # else:
  476. # health_state=self.df_diag.loc[0,'health_state']
  477. for i in range(self.param.CellVoltNums):
  478. #将字符串分割为多列
  479. short_current=self.df_short['short_current']
  480. short_current=short_current.str.replace("[", '')
  481. short_current=short_current.str.replace("]", '')
  482. self.df_short['cellshort'+str(i+1)]=short_current.map(lambda x:x.split(',')[i])
  483. self.df_short['cellshort'+str(i+1)]=self.df_short['cellshort'+str(i+1)].map(lambda x:eval(x))
  484. #漏电流故障判断
  485. cellshort=np.array(self.df_short['cellshort'+str(i+1)])
  486. shortlv3=np.sum(cellshort>self.param.LeakCurrentLv3)
  487. shortlv2=np.sum(cellshort>self.param.LeakCurrentLv2)-shortlv3
  488. shortlv1=np.sum(cellshort>self.param.LeakCurrentLv1)-shortlv2-shortlv3
  489. shortlv=shortlv3*3 + shortlv2*2 + shortlv1
  490. if not 31 in list(self.df_diag_ram['code']): #当前故障中没有该故障,则判断是否发生该故障
  491. if shortlv>=5:
  492. time=self.bmstime[0]
  493. code=31
  494. faultlv=3
  495. faultinfo='电芯{}发生严重内短路'.format(i+1)
  496. faultadvice='禁止充放电,检修电池'
  497. self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
  498. else:
  499. pass
  500. else:
  501. if shortlv<3:
  502. time=self.bmstime[i]
  503. self.df_diag_ram[self.df_diag_ram[self.df_diag_ram['code']==31].index, 'end_time'] = time
  504. if not df_res.empty:
  505. return df_res
  506. else:
  507. return pd.DataFrame()