CBMSBatInterShort.py 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. import pandas as pd
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. # from pymysql import paramstyle
  5. from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import BatParam
  6. class BatInterShort():
  7. def __init__(self,sn,celltype,df_bms,df_soh): #参数初始化
  8. self.sn=sn
  9. self.celltype=celltype
  10. self.param=BatParam.BatParam(celltype)
  11. self.df_bms=df_bms
  12. self.packcrnt=df_bms['总电流[A]']*self.param.PackCrntDec
  13. self.packvolt=df_bms['总电压[V]']
  14. self.bms_soc=df_bms['SOC[%]']
  15. self.bmstime= pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
  16. self.df_soh=df_soh
  17. self.cellvolt_name=['单体电压'+str(x) for x in range(1,self.param.CellVoltNums+1)]
  18. self.celltemp_name=['单体温度'+str(x) for x in range(1,self.param.CellTempNums+1)]
  19. def intershort(self):
  20. if self.celltype<50:
  21. df_res=self._ncm_intershort()
  22. return df_res
  23. elif self.celltype>50:
  24. df_res=self._lfp_intershort()
  25. return df_res
  26. else:
  27. return pd.DataFrame()
  28. #定义滑动滤波函数....................................................................................
  29. def _np_move_avg(self,a, n, mode="same"):
  30. return (np.convolve(a, np.ones((n,)) / n, mode=mode))
  31. #寻找当前行数据的最小温度值.............................................................................
  32. def _celltemp_weight(self,num):
  33. celltemp = list(self.df_bms.loc[num,self.celltemp_name])
  34. celltemp=np.mean(celltemp)
  35. self.celltemp=celltemp
  36. if self.celltype==99:
  37. if celltemp>=20:
  38. self.tempweight=1
  39. self.StandardStandingTime=3600
  40. elif celltemp>=10:
  41. self.tempweight=0.6
  42. self.StandardStandingTime=7200
  43. elif celltemp>=5:
  44. self.tempweight=0.
  45. self.StandardStandingTime=7200
  46. else:
  47. self.tempweight=0.1
  48. self.StandardStandingTime=10800
  49. else:
  50. if celltemp>=20:
  51. self.tempweight=1
  52. self.StandardStandingTime=3600
  53. elif celltemp>=10:
  54. self.tempweight=0.8
  55. self.StandardStandingTime=3600
  56. elif celltemp>=5:
  57. self.tempweight=0.6
  58. self.StandardStandingTime=7200
  59. else:
  60. self.tempweight=0.2
  61. self.StandardStandingTime=10800
  62. #获取当前行所有电压数据........................................................................................
  63. def _cellvolt_get(self,num):
  64. cellvolt = np.array(self.df_bms.loc[num,self.cellvolt_name])/1000
  65. return cellvolt
  66. #获取当前行所有soc差...........................................................................................
  67. def _celldeltsoc_get(self,num,dict_baltime,capacity):
  68. cellsoc=[]
  69. celldeltsoc=[]
  70. for j in range(1, self.param.CellVoltNums+1): #获取每个电芯电压对应的SOC值
  71. cellvolt=self.df_bms.loc[num,'单体电压' + str(j)]/1000
  72. ocv_soc=np.interp(cellvolt,self.param.LookTab_OCV,self.param.LookTab_SOC)
  73. if j in dict_baltime.keys():
  74. ocv_soc=ocv_soc+dict_baltime[j]*self.param.BalCurrent/(capacity*3600) #补偿均衡电流
  75. else:
  76. pass
  77. cellsoc.append(ocv_soc)
  78. if self.celltype==1 or self.celltype==2:
  79. consum_num=7
  80. cellsoc1=cellsoc[:self.param.CellVoltNums-consum_num] #切片,将bms耗电的电芯和非耗电的电芯分离开
  81. cellsocmean1=(sum(cellsoc1)-max(cellsoc1)-min(cellsoc1))/(len(cellsoc1)-2)
  82. cellsoc2=cellsoc[self.param.CellVoltNums-consum_num:]
  83. cellsocmean2=(sum(cellsoc2)-max(cellsoc2)-min(cellsoc2))/(len(cellsoc2)-2)
  84. for j in range(len(cellsoc)): #计算每个电芯的soc差
  85. if j<self.param.CellVoltNums-consum_num:
  86. celldeltsoc.append(cellsoc[j]-cellsocmean1)
  87. else:
  88. celldeltsoc.append(cellsoc[j]-cellsocmean2)
  89. return np.array(celldeltsoc)
  90. else:
  91. cellsocmean=(sum(cellsoc)-max(cellsoc)-min(cellsoc))/(len(cellsoc)-2)
  92. for j in range(len(cellsoc)): #计算每个电芯的soc差
  93. celldeltsoc.append(cellsoc[j]-cellsocmean)
  94. return np.array(celldeltsoc)
  95. #获取所有电芯的As差
  96. def _cellDeltAs_get(self,chrg_st,chrg_end,dict_baltime):
  97. cellAs=[]
  98. celldeltAs=[]
  99. for j in range(1, self.param.CellVoltNums+1): #获取每个电芯电压>峰值电压的充入As数
  100. if j in dict_baltime.keys(): #补偿均衡电流
  101. As=-self.param.BalCurrent*dict_baltime[j]
  102. else:
  103. As=0
  104. As_tatol=0
  105. symbol=0
  106. for m in range(chrg_st+1,chrg_end):
  107. As=As-self.packcrnt[m]*(self.bmstime[m]-self.bmstime[m-1]).total_seconds()
  108. if symbol<5:
  109. if self.df_bms.loc[m,'单体电压'+str(j)]/1000>self.param.PeakCellVolt[symbol]:
  110. As_tatol=As_tatol+As
  111. symbol=symbol+1
  112. else:
  113. continue
  114. else:
  115. cellAs.append(As_tatol/5)
  116. break
  117. if self.celltype==99:
  118. consum_num=10
  119. cellAs1=cellAs[:self.param.CellVoltNums-consum_num] #切片,将bms耗电的电芯和非耗电的电芯分离开
  120. cellAsmean1=(sum(cellAs1)-max(cellAs1)-min(cellAs1))/(len(cellAs1)-2)
  121. cellAs2=cellAs[self.param.CellVoltNums-consum_num:]
  122. cellAsmean2=(sum(cellAs2)-max(cellAs2)-min(cellAs2))/(len(cellAs2)-2)
  123. for j in range(len(cellAs)): #计算每个电芯的soc差
  124. if j<self.param.CellVoltNums-consum_num:
  125. celldeltAs.append(cellAs[j]-cellAsmean1)
  126. else:
  127. celldeltAs.append(cellAs[j]-cellAsmean2)
  128. else:
  129. cellAsmean=(sum(cellAs)-max(cellAs)-min(cellAs))/(len(cellAs)-2)
  130. for j in range(len(cellAs)): #计算每个电芯的soc差
  131. celldeltAs.append(cellAs[j]-cellAsmean)
  132. return np.array(celldeltAs)
  133. #计算每个电芯的均衡时长..........................................................................................................................
  134. def _bal_time(self,dict_bal):
  135. dict_baltime={}
  136. dict_baltime1={}
  137. for key in dict_bal:
  138. count=1
  139. x=eval(key)
  140. while x>0:
  141. if x & 1==1: #判断最后一位是否为1
  142. if count in dict_baltime.keys():
  143. dict_baltime[count] = dict_baltime[count] + dict_bal[key]
  144. else:
  145. dict_baltime[count] = dict_bal[key]
  146. else:
  147. pass
  148. count += 1
  149. x >>= 1 #右移一位
  150. dict_baltime=dict(sorted(dict_baltime.items(),key=lambda dict_baltime:dict_baltime[0]))
  151. for key in dict_baltime: #解析均衡的电芯编号
  152. if self.celltype==1: #科易6040
  153. if key<14:
  154. dict_baltime1[key]=dict_baltime[key]
  155. elif key<18:
  156. dict_baltime1[key-1]=dict_baltime[key]
  157. else:
  158. dict_baltime1[key-3]=dict_baltime[key]
  159. elif self.celltype==1: #科易4840
  160. if key<4:
  161. dict_baltime1[key-1]=dict_baltime[key]
  162. elif key<8:
  163. dict_baltime1[key-1]=dict_baltime[key]
  164. elif key<14:
  165. dict_baltime1[key-3]=dict_baltime[key]
  166. elif key<18:
  167. dict_baltime1[key-4]=dict_baltime[key]
  168. else:
  169. dict_baltime1[key-6]=dict_baltime[key]
  170. else:
  171. dict_baltime1=dict_baltime
  172. return dict_baltime1
  173. #三元电池的内短路电流计算...........................................................................................................................................................
  174. def _ncm_intershort(self):
  175. column_name=['time_st', 'time_sp', 'sn', 'method','short_current','baltime']
  176. df_res=pd.DataFrame(columns=column_name)
  177. if not self.df_bms.empty:
  178. if self.df_soh.empty:
  179. batsoh=self.df_bms.loc[0,'SOH[%]']
  180. capacity=self.param.Capacity*batsoh/100
  181. else:
  182. batsoh=self.df_soh.loc[len(self.df_soh)-1,'soh']
  183. capacity=self.param.Capacity*batsoh/100
  184. standingtime=0
  185. standingtime1=0
  186. firsttime=1
  187. firsttime1=1
  188. dict_bal={}
  189. dict_bal1={}
  190. for i in range(2,len(self.df_bms)-2):
  191. if firsttime1==0: #满电静置算法--计算均衡状态对应的均衡时间
  192. try:
  193. balstat=int(self.df_bms.loc[i,'单体均衡状态'])
  194. if balstat>0.5:
  195. bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds() #均衡步长
  196. bal_step=int(bal_step)
  197. if str(balstat) in dict_bal1.keys():
  198. dict_bal1[str(balstat)]=dict_bal1[str(balstat)]+bal_step
  199. else:
  200. dict_bal1[str(balstat)]=bal_step
  201. else:
  202. pass
  203. except:
  204. dict_bal1={}
  205. else:
  206. pass
  207. if abs(self.packcrnt[i]) < 0.1 and abs(self.packcrnt[i-1]) < 0.1 and abs(self.packcrnt[i+1]) < 0.1:
  208. delttime=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
  209. standingtime=standingtime+delttime
  210. standingtime1=standingtime1+delttime
  211. self._celltemp_weight(i)
  212. #静置法计算内短路-开始.....................................................................................................................................
  213. if firsttime==1:
  214. if standingtime>self.StandardStandingTime*2: #静置时间满足要求
  215. standingtime=0
  216. cellvolt_now=self._cellvolt_get(i)
  217. cellvolt_min=min(cellvolt_now)
  218. cellvolt_max=max(cellvolt_now)
  219. cellvolt_last=self._cellvolt_get(i-1)
  220. deltvolt=max(abs(cellvolt_now-cellvolt_last))
  221. if 2<cellvolt_min<4.5 and 2<cellvolt_max<4.5 and deltvolt<0.005:
  222. dict_baltime=self._bal_time(dict_bal) #获取每个电芯的均衡时间
  223. deltsoc_last=self._celldeltsoc_get(i,dict_baltime,capacity)
  224. time_last=self.bmstime[i]
  225. firsttime=0
  226. else:
  227. pass
  228. elif standingtime>3600*10:
  229. standingtime=0
  230. cellvolt_now=self._cellvolt_get(i)
  231. cellvolt_min=min(cellvolt_now)
  232. cellvolt_max=max(cellvolt_now)
  233. cellvolt_last=self._cellvolt_get(i-1)
  234. deltvolt=max(abs(cellvolt_now-cellvolt_last))
  235. if 2<cellvolt_min<4.5 and 2<cellvolt_max<4.5 and deltvolt<0.005:
  236. dict_baltime=self._bal_time(dict_bal) #获取每个电芯的均衡时间
  237. deltsoc_now=self._celldeltsoc_get(i,dict_baltime,capacity)
  238. time_now=self.bmstime[i]
  239. list_sub=deltsoc_now-deltsoc_last
  240. list_pud=0.01*capacity*3600*1000/(time_now-time_last).total_seconds()
  241. leak_current=list_sub*list_pud
  242. # leak_current=np.array(leak_current)
  243. leak_current=np.round(leak_current,3)
  244. leak_current=list(leak_current)
  245. df_res.loc[len(df_res)]=[time_last,time_now,self.sn,1,str(leak_current),str(dict_baltime)] #计算结果存入Dataframe
  246. time_last=time_now #更新时间
  247. deltsoc_last=deltsoc_now #更新soc差
  248. dict_bal={}
  249. else:
  250. try:
  251. balstat=int(self.df_bms.loc[i,'单体均衡状态'])
  252. if balstat>0.5:
  253. bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds() #均衡步长
  254. bal_step=int(bal_step)
  255. if str(balstat) in dict_bal.keys():
  256. dict_bal[str(balstat)]=dict_bal[str(balstat)]+bal_step
  257. else:
  258. dict_bal[str(balstat)]=bal_step
  259. else:
  260. pass
  261. except:
  262. dict_bal={}
  263. #满电静置法计算内短路-开始.....................................................................................................................................................
  264. if self.StandardStandingTime<standingtime1:
  265. standingtime1=0
  266. cellvolt_now1=self._cellvolt_get(i)
  267. cellvolt_max1=max(cellvolt_now1)
  268. cellvolt_min1=min(cellvolt_now1)
  269. cellvolt_last1=self._cellvolt_get(i-1)
  270. deltvolt1=max(abs(cellvolt_now1-cellvolt_last1))
  271. cellsoc_now1=np.interp(cellvolt_max1,self.param.LookTab_OCV,self.param.LookTab_SOC)
  272. if cellsoc_now1>=self.param.FullChrgSoc-10 and 2<cellvolt_min1<4.5 and 2<cellvolt_max1<4.5 and deltvolt1<0.005:
  273. if firsttime1==1:
  274. dict_baltime1=self._bal_time(dict_bal1) #获取每个电芯的均衡时间
  275. deltsoc_last1=self._celldeltsoc_get(i,dict_baltime1,capacity)
  276. time_last1=self.bmstime[i]
  277. firsttime1=0
  278. else:
  279. dict_baltime1=self._bal_time(dict_bal1) #获取每个电芯的均衡时间
  280. time_now1=self.bmstime[i]
  281. if (time_now1-time_last1).total_seconds()>3600*12:
  282. deltsoc_now1=self._celldeltsoc_get(i,dict_baltime1,capacity)
  283. list_sub1=deltsoc_now1-deltsoc_last1
  284. list_pud1=0.01*capacity*3600*1000/(time_now1-time_last1).total_seconds()
  285. leak_current1=list_sub1*list_pud1
  286. # leak_current1=np.array(leak_current1)
  287. leak_current1=np.round(leak_current1,3)
  288. leak_current1=list(leak_current1)
  289. df_res.loc[len(df_res)]=[time_last1,time_now1,self.sn,2,str(leak_current1),str(dict_baltime1)] #计算结果存入Dataframe
  290. time_last1=time_now1 #更新时间
  291. deltsoc_last1=deltsoc_now1 #更新soc差
  292. dict_bal1={}
  293. else:
  294. pass
  295. else:
  296. pass
  297. else:
  298. pass
  299. else:
  300. dict_bal={}
  301. firsttime=1
  302. standingtime=0
  303. standingtime1=0
  304. pass
  305. if df_res.empty: #返回计算结果
  306. return pd.DataFrame()
  307. else:
  308. return df_res
  309. #磷酸铁锂电池内短路计算程序.............................................................................................................................
  310. def _lfp_intershort(self):
  311. column_name=['time_st', 'time_sp', 'sn', 'method','short_current','baltime']
  312. df_res=pd.DataFrame(columns=column_name)
  313. if not self.df_bms.empty:
  314. if self.df_soh.empty:
  315. batsoh=self.df_bms.loc[0,'SOH[%]']
  316. capacity=self.param.Capacity*batsoh/100
  317. else:
  318. batsoh=self.df_soh.loc[len(self.df_soh)-1,'soh']
  319. capacity=self.param.Capacity*batsoh/100
  320. standingtime=0
  321. standingtime1=0
  322. firsttime=1
  323. firsttime1=1
  324. dict_bal={}
  325. dict_bal1={}
  326. chrg_start=[]
  327. chrg_end=[]
  328. dict_bal_list=[]
  329. charging=0
  330. dict_bal3={}
  331. for i in range(3,len(self.df_bms)-3):
  332. #静置法计算内短路..........................................................................................................................
  333. if firsttime1==0: #满电静置算法--计算均衡状态对应的均衡时间
  334. try:
  335. balstat=int(self.df_bms.loc[i,'单体均衡状态'])
  336. if balstat>0.5:
  337. bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds() #均衡步长
  338. bal_step=int(bal_step)
  339. if str(balstat) in dict_bal1.keys():
  340. dict_bal1[str(balstat)]=dict_bal1[str(balstat)]+bal_step
  341. else:
  342. dict_bal1[str(balstat)]=bal_step
  343. else:
  344. pass
  345. except:
  346. dict_bal1={}
  347. else:
  348. pass
  349. if abs(self.packcrnt[i]) < 0.1 and abs(self.packcrnt[i-1]) < 0.1 and abs(self.packcrnt[i+1]) < 0.1:
  350. delttime=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
  351. standingtime=standingtime+delttime
  352. standingtime1=standingtime1+delttime
  353. self._celltemp_weight(i)
  354. #静置法计算内短路-开始.....................................................................................................................................
  355. if firsttime==1:
  356. if standingtime>self.StandardStandingTime: #静置时间满足要求
  357. standingtime=0
  358. cellvolt_now=self._cellvolt_get(i)
  359. cellvolt_min=min(cellvolt_now)
  360. cellvolt_max=max(cellvolt_now)
  361. cellvolt_last=self._cellvolt_get(i-1)
  362. deltvolt=max(abs(cellvolt_now-cellvolt_last))
  363. if 2<cellvolt_max<self.param.OcvInflexionBelow-0.002 and 2<cellvolt_min<4.5 and abs(deltvolt)<0.003:
  364. dict_baltime=self._bal_time(dict_bal) #获取每个电芯的均衡时间
  365. deltsoc_last=self._celldeltsoc_get(i,dict_baltime,capacity)
  366. time_last=self.bmstime[i]
  367. firsttime=0
  368. else:
  369. pass
  370. else:
  371. pass
  372. elif standingtime>3600*12:
  373. standingtime=0
  374. cellvolt_now=np.array(self._cellvolt_get(i))
  375. cellvolt_min=min(cellvolt_now)
  376. cellvolt_max=max(cellvolt_now)
  377. cellvolt_last=np.array(self._cellvolt_get(i-1))
  378. deltvolt=max(abs(cellvolt_now-cellvolt_last))
  379. if 2<cellvolt_max<self.param.OcvInflexionBelow-0.002 and 2<cellvolt_min<4.5 and abs(deltvolt)<0.003:
  380. dict_baltime=self._bal_time(dict_bal) #获取每个电芯的均衡时间
  381. deltsoc_now=self._celldeltsoc_get(i, dict_baltime,capacity) #获取每个电芯的SOC差
  382. time_now=self.bmstime[i]
  383. list_sub=deltsoc_now-deltsoc_last
  384. list_pud=0.01*capacity*3600*1000/(time_now-time_last).total_seconds()
  385. leak_current=list_sub*list_pud
  386. # leak_current=np.array(leak_current)
  387. leak_current=np.round(leak_current,3)
  388. leak_current=list(leak_current)
  389. df_res.loc[len(df_res)]=[time_last,time_now,self.sn,1,str(leak_current),str(dict_baltime)] #计算结果存入Dataframe
  390. time_last=time_now #更新时间
  391. deltsoc_last=deltsoc_now #更新soc差
  392. dict_bal={}
  393. else:
  394. pass
  395. else:
  396. try:
  397. balstat=int(self.df_bms.loc[i,'单体均衡状态'])
  398. if balstat>0.5:
  399. bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds() #均衡步长
  400. bal_step=int(bal_step)
  401. if str(balstat) in dict_bal.keys():
  402. dict_bal[str(balstat)]=dict_bal[str(balstat)]+bal_step
  403. else:
  404. dict_bal[str(balstat)]=bal_step
  405. else:
  406. pass
  407. except:
  408. dict_bal={}
  409. #非平台区间静置法计算内短路-开始.....................................................................................................................................................
  410. if standingtime1>self.StandardStandingTime:
  411. if abs(self.packcrnt[i+2]) >= 0.1:
  412. standingtime1=0
  413. cellvolt_now1=self._cellvolt_get(i)
  414. cellvolt_max1=max(cellvolt_now1)
  415. cellvolt_min1=min(cellvolt_now1)
  416. cellvolt_last1=self._cellvolt_get(i-1)
  417. deltvolt1=max(abs(cellvolt_now1-cellvolt_last1))
  418. if 2<cellvolt_max1<self.param.OcvInflexionBelow-0.002 and 2<cellvolt_min1<4.5 and deltvolt1<0.005:
  419. if firsttime1==1:
  420. dict_baltime1=self._bal_time(dict_bal1) #获取每个电芯的均衡时间
  421. deltsoc_last1=self._celldeltsoc_get(i,dict_baltime1,capacity)
  422. time_last1=self.bmstime[i]
  423. firsttime1=0
  424. else:
  425. dict_baltime1=self._bal_time(dict_bal1) #获取每个电芯的均衡时间
  426. deltsoc_now1=self._celldeltsoc_get(i,dict_baltime1,capacity)
  427. time_now1=self.bmstime[i]
  428. time_now1=self.bmstime[i]
  429. if abs(max(deltsoc_now1)-max(deltsoc_last1))<10 and (time_now1-time_last1).total_seconds()>3600*24:
  430. list_sub1=deltsoc_now1-deltsoc_last1
  431. list_pud1=0.01*capacity*3600*1000/(time_now1-time_last1).total_seconds()
  432. leak_current1=list_sub1*list_pud1
  433. # leak_current1=np.array(leak_current1)
  434. leak_current1=np.round(leak_current1,3)
  435. leak_current1=list(leak_current1)
  436. df_res.loc[len(df_res)]=[time_last1,time_now1,self.sn,2,str(leak_current1),str(dict_baltime1)] #计算结果存入Dataframe
  437. time_last1=time_now1 #更新时间
  438. deltsoc_last1=deltsoc_now1 #更新soc差
  439. dict_bal1={}
  440. else:
  441. pass
  442. else:
  443. pass
  444. else:
  445. pass
  446. else:
  447. pass
  448. else:
  449. dict_bal={}
  450. firsttime=1
  451. standingtime=0
  452. standingtime1=0
  453. pass
  454. #获取充电数据——开始..............................................................................................................
  455. try:
  456. balstat=int(self.df_bms.loc[i,'单体均衡状态']) #统计均衡状态
  457. if balstat>0.5:
  458. bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds() #均衡步长
  459. bal_step=int(bal_step)
  460. if str(balstat) in dict_bal3.keys():
  461. dict_bal3[str(balstat)]=dict_bal3[str(balstat)]+bal_step
  462. else:
  463. dict_bal3[str(balstat)]=bal_step
  464. else:
  465. pass
  466. except:
  467. dict_bal3={}
  468. if charging==0:
  469. if self.packcrnt[i]<=-1 and self.packcrnt[i+1]<=-1 and self.packcrnt[i+2]<=-1 and self.bms_soc[i]<40: #判断充电开始
  470. cellvolt_now=self._cellvolt_get(i)
  471. if min(cellvolt_now)<self.param.CellFullChrgVolt-0.15:
  472. charging=1
  473. if len(chrg_start)>len(chrg_end):
  474. chrg_start[-1]=i
  475. else:
  476. chrg_start.append(i)
  477. else:
  478. pass
  479. else:
  480. pass
  481. else: #充电中
  482. if (self.bmstime[i+1]-self.bmstime[i]).total_seconds()>180 or (self.packcrnt[i]>self.param.Capacity/3 and self.packcrnt[i+1]>self.param.Capacity/3): #如果充电过程中时间间隔>180s,则舍弃该次充电
  483. chrg_start.remove(chrg_start[-1])
  484. charging=0
  485. continue
  486. elif self.packcrnt[i]<=-1 and self.packcrnt[i+1]<=-1 and self.packcrnt[i+2]<-1:
  487. cellvolt_now=self._cellvolt_get(i)
  488. if min(cellvolt_now)>self.param.CellFullChrgVolt-0.13: #电压>满充电压-0.13V,即3.37V
  489. self._celltemp_weight(i)
  490. if i-chrg_start[-1]>10 and self.celltemp>10:
  491. chrg_end.append(i+1)
  492. dict_bal_list.append(dict_bal3)
  493. dict_bal3={}
  494. charging=0
  495. continue
  496. else:
  497. chrg_start.remove(chrg_start[-1])
  498. charging=0
  499. continue
  500. else:
  501. pass
  502. else:
  503. pass
  504. #基于充电数据计算单体电芯的漏电流..........................................................................................................
  505. if len(chrg_end)>1:
  506. for i in range(len(chrg_end)):
  507. if i<1:
  508. dict_baltime={}
  509. deltAs_last=self._cellDeltAs_get(chrg_start[i],chrg_end[i],dict_baltime)
  510. time_last=self.bmstime[chrg_end[i]]
  511. else:
  512. dict_baltime=self._bal_time(dict_bal_list[i]) #获取每个电芯的均衡时间
  513. deltAs_now=self._cellDeltAs_get(chrg_start[i],chrg_end[i],dict_baltime) #获取每个电芯的As差
  514. time_now=self.bmstime[chrg_end[i]]
  515. list_sub=deltAs_now-deltAs_last
  516. list_pud=-1000/(time_now-time_last).total_seconds()
  517. leak_current=list_sub*list_pud
  518. # leak_current=np.array(leak_current)
  519. leak_current=np.round(leak_current,3)
  520. leak_current=list(leak_current)
  521. df_res.loc[len(df_res)]=[time_last,time_now,self.sn,3,str(leak_current),str(dict_baltime)] #计算结果存入Dataframe
  522. deltAs_last=deltAs_now
  523. time_last=time_now
  524. else:
  525. pass
  526. if df_res.empty:
  527. return pd.DataFrame()
  528. else:
  529. return df_res