CBMSBatDiag.py 30 KB

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