CBMSBatInterShort.py 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. import pandas as pd
  2. import numpy as np
  3. import datetime
  4. import BatParam
  5. class BatInterShort():
  6. def __init__(self,sn,celltype,df_bms,df_soh,df_last,df_last1,df_last2,df_last3,df_lfp): #参数初始化
  7. if (not df_lfp.empty) and celltype>50:
  8. df_bms=pd.concat([df_lfp, df_bms], ignore_index=True)
  9. df_bms.reset_index(inplace=True,drop=True)
  10. else:
  11. pass
  12. self.sn=sn
  13. self.celltype=celltype
  14. self.param=BatParam.BatParam(celltype)
  15. self.packcrnt=df_bms['PackCrnt']*self.param.PackCrntDec
  16. self.packvolt=df_bms['PackVolt']
  17. self.bms_soc=df_bms['PackSOC']
  18. df_bms['time']=pd.to_datetime(df_bms['time'], format='%Y-%m-%d %H:%M:%S')
  19. self.bmstime= df_bms['time']
  20. self.df_bms=df_bms
  21. self.df_soh=df_soh
  22. self.df_last=df_last
  23. self.df_last1=df_last1
  24. self.df_last2=df_last2
  25. self.df_last3=df_last3
  26. self.df_lfp=df_lfp
  27. self.cellvolt_name=['CellVolt'+str(x) for x in range(1,self.param.CellVoltNums+1)]
  28. self.celltemp_name=['CellTemp'+str(x) for x in range(1,self.param.CellTempNums+1)]
  29. def intershort(self):
  30. if self.celltype<=50:
  31. df_res, df_ram_last, df_ram_last1, df_ram_last3=self._ncm_intershort()
  32. return df_res, df_ram_last, df_ram_last1,self.df_last2, df_ram_last3,self.df_lfp
  33. else:
  34. df_res, df_ram_last, df_ram_last1, df_ram_last2, df_ram_last3, df_ram_lfp=self._lfp_intershort()
  35. return df_res, df_ram_last, df_ram_last1, df_ram_last2, df_ram_last3, df_ram_lfp
  36. #定义滑动滤波函数....................................................................................
  37. def _np_move_avg(self,a, n, mode="same"):
  38. return (np.convolve(a, np.ones((n,)) / n, mode=mode))
  39. #寻找当前行数据的最小温度值.............................................................................
  40. def _celltemp_weight(self,num):
  41. celltemp = list(self.df_bms.loc[num,self.celltemp_name])
  42. celltemp=min(celltemp)
  43. self.celltemp=celltemp
  44. if self.celltype>50:
  45. if celltemp>=25:
  46. self.tempweight=1
  47. self.StandardStandingTime=4500
  48. elif celltemp>=15:
  49. self.tempweight=0.6
  50. self.StandardStandingTime=7200
  51. elif celltemp>=5:
  52. self.tempweight=0.2
  53. self.StandardStandingTime=10800
  54. else:
  55. self.tempweight=0.1
  56. self.StandardStandingTime=10800
  57. else:
  58. if celltemp>=25:
  59. self.tempweight=1
  60. self.StandardStandingTime=3600
  61. elif celltemp>=15:
  62. self.tempweight=0.8
  63. self.StandardStandingTime=5400
  64. elif celltemp>=5:
  65. self.tempweight=0.6
  66. self.StandardStandingTime=7200
  67. else:
  68. self.tempweight=0.2
  69. self.StandardStandingTime=10800
  70. #获取前5min每个电压的平均值........................................................................................
  71. def _avgvolt_get(self,num):
  72. time_now=self.df_bms.loc[num, 'time']
  73. time_last=time_now-datetime.timedelta(seconds=300)
  74. df_volt=self.df_bms[(self.df_bms['time']>=time_last) & (self.df_bms['time']<=time_now)]
  75. df_volt=df_volt[self.cellvolt_name]
  76. df_volt=df_volt[(df_volt>2) & (df_volt<4.5)]
  77. df_volt=df_volt.dropna()
  78. cellvolt_std=df_volt.std(axis=0)
  79. if len(df_volt)>2 and max(cellvolt_std)<0.005:
  80. cellvolt_sum=df_volt.sum(0)-df_volt.max(0)-df_volt.min(0)
  81. cellvolt_mean=cellvolt_sum/(len(df_volt)-2)
  82. cellvolt=cellvolt_mean
  83. elif len(df_volt)==2:
  84. # df_volt=pd.DataFrame(df_volt,dtype=np.float)
  85. if max(abs(df_volt.iloc[1]-df_volt.iloc[0]))<0.003:
  86. cellvolt=df_volt.mean(0)
  87. else:
  88. cellvolt=pd.DataFrame()
  89. elif len(df_volt)==1:
  90. cellvolt=df_volt.iloc[0]
  91. else:
  92. cellvolt=pd.DataFrame()
  93. return cellvolt
  94. #获取当前行所有电压数据........................................................................................
  95. def _cellvolt_get(self,num):
  96. cellvolt = np.array(self.df_bms.loc[num,self.cellvolt_name])
  97. return cellvolt
  98. #获取当前行所有soc差...........................................................................................
  99. def _celldeltsoc_get(self,cellvolt_list,dict_baltime,capacity):
  100. cellsoc=[]
  101. celldeltsoc=[]
  102. for j in range(1, self.param.CellVoltNums+1): #获取每个电芯电压对应的SOC值
  103. cellvolt=cellvolt_list[j-1]
  104. ocv_soc=np.interp(cellvolt,self.param.LookTab_OCV,self.param.LookTab_SOC)
  105. if j in dict_baltime.keys():
  106. ocv_soc=ocv_soc+dict_baltime[j]*self.param.BalCurrent/(capacity*3600) #补偿均衡电流
  107. else:
  108. pass
  109. cellsoc.append(ocv_soc)
  110. cellsocmean=(sum(cellsoc)-max(cellsoc)-min(cellsoc))/(len(cellsoc)-2)
  111. for j in range(len(cellsoc)): #计算每个电芯的soc差
  112. celldeltsoc.append(cellsoc[j]-cellsocmean)
  113. return np.array(celldeltsoc), np.array(cellsoc)
  114. #获取所有电芯的As差
  115. def _cellDeltAs_get(self,chrg_st,chrg_end,dict_baltime):
  116. cellAs=[]
  117. celldeltAs=[]
  118. for j in range(1, self.param.CellVoltNums+1): #获取每个电芯电压>峰值电压的充入As数
  119. if j in dict_baltime.keys(): #补偿均衡电流
  120. As=-self.param.BalCurrent*dict_baltime[j]
  121. else:
  122. As=0
  123. As_tatol=0
  124. symbol=0
  125. for m in range(chrg_st+1,chrg_end):
  126. As=As-self.packcrnt[m]*(self.bmstime[m]-self.bmstime[m-1]).total_seconds()
  127. if symbol<5:
  128. if self.df_bms.loc[m,'CellVolt'+str(j)]>self.param.PeakCellVolt[symbol]:
  129. As_tatol=As_tatol+As
  130. symbol=symbol+1
  131. else:
  132. continue
  133. else:
  134. cellAs.append(As_tatol/5)
  135. break
  136. cellAsmean=(sum(cellAs)-max(cellAs)-min(cellAs))/(len(cellAs)-2)
  137. for j in range(len(cellAs)): #计算每个电芯的soc差
  138. celldeltAs.append(cellAs[j]-cellAsmean)
  139. return np.array(celldeltAs)
  140. #计算每个电芯的均衡时长..........................................................................................................................
  141. def _bal_time(self,dict_bal):
  142. dict_baltime={}
  143. dict_baltime1={}
  144. for key in dict_bal:
  145. count=1
  146. x=eval(key)
  147. while x>0:
  148. if x & 1==1: #判断最后一位是否为1
  149. if count in dict_baltime.keys():
  150. dict_baltime[count] = dict_baltime[count] + dict_bal[key]
  151. else:
  152. dict_baltime[count] = dict_bal[key]
  153. else:
  154. pass
  155. count += 1
  156. x >>= 1 #右移一位
  157. dict_baltime=dict(sorted(dict_baltime.items(),key=lambda dict_baltime:dict_baltime[0]))
  158. for key in dict_baltime: #解析均衡的电芯编号
  159. if self.celltype==1: #科易6040
  160. if key<14:
  161. dict_baltime1[key]=dict_baltime[key]
  162. elif key<18:
  163. dict_baltime1[key-1]=dict_baltime[key]
  164. else:
  165. dict_baltime1[key-3]=dict_baltime[key]
  166. elif self.celltype==1: #科易4840
  167. if key<4:
  168. dict_baltime1[key-1]=dict_baltime[key]
  169. elif key<8:
  170. dict_baltime1[key-1]=dict_baltime[key]
  171. elif key<14:
  172. dict_baltime1[key-3]=dict_baltime[key]
  173. elif key<18:
  174. dict_baltime1[key-4]=dict_baltime[key]
  175. else:
  176. dict_baltime1[key-6]=dict_baltime[key]
  177. else:
  178. dict_baltime1=dict_baltime
  179. return dict_baltime1
  180. #三元电池的内短路电流计算...........................................................................................................................................................
  181. def _ncm_intershort(self):
  182. df_res=pd.DataFrame(columns=['time_st', 'time_sp', 'sn', 'method','short_current','baltime'])
  183. df_ram_last=self.df_last
  184. df_ram_last1=self.df_last1
  185. df_ram_last3=self.df_last3
  186. #容量初始化
  187. if self.df_soh.empty:
  188. batsoh=self.df_bms.loc[0,'PackSOH']
  189. capacity=self.param.Capacity*batsoh/100
  190. else:
  191. batsoh=self.df_soh.loc[len(self.df_soh)-1,'soh']
  192. capacity=self.param.Capacity*batsoh/100
  193. #参数初始化
  194. if df_ram_last.empty:
  195. firsttime=1
  196. dict_bal={}
  197. else:
  198. deltsoc_last=df_ram_last.loc[0,'deltsoc']
  199. cellsoc_last=df_ram_last.loc[0,'cellsoc']
  200. time_last=df_ram_last.loc[0,'time']
  201. firsttime=0
  202. dict_bal={}
  203. if df_ram_last1.empty:
  204. firsttime1=1
  205. dict_bal1={}
  206. else:
  207. deltsoc_last1=df_ram_last1.loc[0,'deltsoc1']
  208. time_last1=df_ram_last1.loc[0,'time1']
  209. firsttime1=0
  210. dict_bal1={}
  211. if df_ram_last3.empty:
  212. standingtime=0
  213. standingtime1=0
  214. standingtime2=0
  215. else:
  216. standingtime=df_ram_last3.loc[0,'standingtime']
  217. standingtime1=df_ram_last3.loc[0,'standingtime1']
  218. standingtime2=df_ram_last3.loc[0,'standingtime2']
  219. dict_bal1={}
  220. if abs(self.packcrnt[0])<0.01 and standingtime>1 and standingtime1>1:
  221. standingtime=standingtime+(self.bmstime[0]-df_ram_last3.loc[0,'time3']).total_seconds()
  222. standingtime1=standingtime1+(self.bmstime[0]-df_ram_last3.loc[0,'time3']).total_seconds()
  223. else:
  224. pass
  225. for i in range(1,len(self.df_bms)-1):
  226. if firsttime1==0: #满电静置算法--计算均衡状态对应的均衡时间
  227. try:
  228. balstat=int(self.df_bms.loc[i,'单体均衡状态'])
  229. if balstat>0.5:
  230. bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds() #均衡步长
  231. bal_step=int(bal_step)
  232. if str(balstat) in dict_bal1.keys():
  233. dict_bal1[str(balstat)]=dict_bal1[str(balstat)]+bal_step
  234. else:
  235. dict_bal1[str(balstat)]=bal_step
  236. else:
  237. pass
  238. except:
  239. dict_bal1={}
  240. else:
  241. pass
  242. if abs(self.packcrnt[i]) < 0.1 and abs(self.packcrnt[i-1]) < 0.1 and abs(self.packcrnt[i+1]) < 0.1:
  243. delttime=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
  244. standingtime=standingtime+delttime
  245. standingtime1=standingtime1+delttime
  246. self._celltemp_weight(i)
  247. #长时间静置法计算内短路-开始.....................................................................................................................................
  248. if firsttime==1:
  249. if standingtime>self.StandardStandingTime*2: #静置时间满足要求
  250. standingtime=0
  251. cellvolt_now=self._avgvolt_get(i)
  252. if not cellvolt_now.empty:
  253. cellvolt_min=min(cellvolt_now)
  254. cellvolt_max=max(cellvolt_now)
  255. # cellvolt_last=self._avgvolt_get(i-1)
  256. # deltvolt=max(abs(cellvolt_now-cellvolt_last))
  257. cellsoc_max=np.interp(cellvolt_max,self.param.LookTab_OCV,self.param.LookTab_SOC)
  258. cellsoc_min=np.interp(cellvolt_min,self.param.LookTab_OCV,self.param.LookTab_SOC)
  259. if 2<cellvolt_min<4.5 and 2<cellvolt_max<4.5 and (45<cellsoc_max or cellsoc_max<30) and (45<cellsoc_min or cellsoc_min<30):
  260. dict_baltime={} #获取每个电芯的均衡时间
  261. deltsoc_last, cellsoc_last=self._celldeltsoc_get(cellvolt_now,dict_baltime,capacity)
  262. time_last=self.bmstime[i]
  263. firsttime=0
  264. df_ram_last.loc[0]=[self.sn,time_last,deltsoc_last,cellsoc_last] #更新RAM信息
  265. else:
  266. pass
  267. elif standingtime>3600*12:
  268. standingtime=0
  269. cellvolt_now=self._avgvolt_get(i)
  270. if not cellvolt_now.empty:
  271. cellvolt_min=min(cellvolt_now)
  272. cellvolt_max=max(cellvolt_now)
  273. # cellvolt_last=self._avgvolt_get(i-1)
  274. # deltvolt=max(abs(cellvolt_now-cellvolt_last))
  275. cellsoc_max=np.interp(cellvolt_max,self.param.LookTab_OCV,self.param.LookTab_SOC)
  276. cellsoc_min=np.interp(cellvolt_min,self.param.LookTab_OCV,self.param.LookTab_SOC)
  277. if 2<cellvolt_min<4.5 and 2<cellvolt_max<4.5 and (45<cellsoc_max or cellsoc_max<30) and (45<cellsoc_min or cellsoc_min<30):
  278. dict_baltime=self._bal_time(dict_bal) #获取每个电芯的均衡时间
  279. deltsoc_now, cellsoc_now=self._celldeltsoc_get(cellvolt_now,dict_baltime,capacity)
  280. time_now=self.bmstime[i]
  281. if -5<max(cellsoc_now-cellsoc_last)<5:
  282. df_ram_last.loc[0]=[self.sn,time_now,deltsoc_now,cellsoc_now] #更新RAM信息
  283. list_sub=deltsoc_now-deltsoc_last
  284. list_pud=(0.01*capacity*3600*1000)/(time_now-time_last).total_seconds()
  285. leak_current=list_sub*list_pud
  286. # leak_current=np.array(leak_current)
  287. leak_current=np.round(leak_current,3)
  288. leak_current=list(leak_current)
  289. df_res.loc[len(df_res)]=[time_last,time_now,self.sn,1,str(leak_current),str(dict_baltime)] #计算结果存入Dataframe
  290. time_last=time_now #更新时间
  291. deltsoc_last=deltsoc_now #更新soc差
  292. dict_bal={}
  293. else:
  294. firsttime=1
  295. else:
  296. try:
  297. balstat=int(self.df_bms.loc[i,'单体均衡状态'])
  298. if balstat>0.5:
  299. bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds() #均衡步长
  300. bal_step=int(bal_step)
  301. if str(balstat) in dict_bal.keys():
  302. dict_bal[str(balstat)]=dict_bal[str(balstat)]+bal_step
  303. else:
  304. dict_bal[str(balstat)]=bal_step
  305. else:
  306. pass
  307. except:
  308. dict_bal={}
  309. #满电静置法计算内短路-开始.....................................................................................................................................................
  310. if self.StandardStandingTime<standingtime1:
  311. standingtime1=0
  312. cellvolt_now1=self._avgvolt_get(i)
  313. if not cellvolt_now1.empty:
  314. cellvolt_max1=max(cellvolt_now1)
  315. cellvolt_min1=min(cellvolt_now1)
  316. # cellvolt_last1=self._avgvolt_get(i-1)
  317. # deltvolt1=max(abs(cellvolt_now1-cellvolt_last1))
  318. cellsoc_now1=np.interp(cellvolt_max1,self.param.LookTab_OCV,self.param.LookTab_SOC)
  319. if cellsoc_now1>self.param.FullChrgSoc-10 and 2<cellvolt_min1<4.5 and 2<cellvolt_max1<4.5:
  320. if firsttime1==1:
  321. dict_baltime1={} #获取每个电芯的均衡时间
  322. deltsoc_last1, cellsoc_last1=self._celldeltsoc_get(cellvolt_now1,dict_baltime1,capacity)
  323. time_last1=self.bmstime[i]
  324. firsttime1=0
  325. df_ram_last1.loc[0]=[self.sn,time_last1,deltsoc_last1] #更新RAM信息
  326. else:
  327. dict_baltime1=self._bal_time(dict_bal1) #获取每个电芯的均衡时间
  328. time_now1=self.bmstime[i]
  329. if (time_now1-time_last1).total_seconds()>3600*20:
  330. deltsoc_now1, cellsoc_now1=self._celldeltsoc_get(cellvolt_now1,dict_baltime1,capacity)
  331. df_ram_last1.loc[0]=[self.sn,time_now1,deltsoc_now1] #更新RAM信息
  332. list_sub1=deltsoc_now1-deltsoc_last1
  333. list_pud1=(0.01*capacity*3600*1000)/(time_now1-time_last1).total_seconds()
  334. leak_current1=list_sub1*list_pud1
  335. # leak_current1=np.array(leak_current1)
  336. leak_current1=np.round(leak_current1,3)
  337. leak_current1=list(leak_current1)
  338. df_res.loc[len(df_res)]=[time_last1,time_now1,self.sn,2,str(leak_current1),str(dict_baltime1)] #计算结果存入Dataframe
  339. time_last1=time_now1 #更新时间
  340. deltsoc_last1=deltsoc_now1 #更新soc差
  341. dict_bal1={}
  342. else:
  343. pass
  344. else:
  345. pass
  346. else:
  347. pass
  348. else:
  349. df_ram_last=pd.DataFrame(columns=['sn','time','deltsoc','cellsoc']) #电流>0,清空上次静置的SOC差
  350. dict_bal={}
  351. firsttime=1
  352. standingtime=0
  353. standingtime1=0
  354. pass
  355. #更新RAM的standingtime
  356. df_ram_last3.loc[0]=[self.sn,self.bmstime[len(self.bmstime)-1],standingtime,standingtime1,standingtime2]
  357. #返回计算结果
  358. if df_res.empty:
  359. return pd.DataFrame(), df_ram_last, df_ram_last1, df_ram_last3
  360. else:
  361. return df_res, df_ram_last, df_ram_last1, df_ram_last3
  362. #磷酸铁锂电池内短路计算程序.............................................................................................................................
  363. def _lfp_intershort(self):
  364. column_name=['time_st', 'time_sp', 'sn', 'method','short_current','baltime']
  365. df_res=pd.DataFrame(columns=column_name)
  366. df_ram_last=self.df_last
  367. df_ram_last1=self.df_last1
  368. df_ram_last2=self.df_last2
  369. df_ram_last3=self.df_last3
  370. df_ram_lfp=pd.DataFrame(columns=self.df_bms.columns.tolist())
  371. #容量初始化
  372. if self.df_soh.empty:
  373. batsoh=self.df_bms.loc[0,'PackSOH']
  374. capacity=self.param.Capacity*batsoh/100
  375. else:
  376. batsoh=self.df_soh.loc[len(self.df_soh)-1,'soh']
  377. capacity=self.param.Capacity*batsoh/100
  378. #参数初始化
  379. if df_ram_last.empty:
  380. firsttime=1
  381. dict_bal={}
  382. else:
  383. deltsoc_last=df_ram_last.loc[0,'deltsoc']
  384. cellsoc_last=df_ram_last.loc[0,'cellsoc']
  385. time_last=df_ram_last.loc[0,'time']
  386. firsttime=0
  387. dict_bal={}
  388. if df_ram_last1.empty:
  389. firsttime1=1
  390. dict_bal1={}
  391. else:
  392. deltsoc_last1=df_ram_last1.loc[0,'deltsoc1']
  393. time_last1=df_ram_last1.loc[0,'time1']
  394. firsttime1=0
  395. dict_bal1={}
  396. if df_ram_last2.empty:
  397. firsttime2=1
  398. charging=0
  399. dict_bal2={}
  400. else:
  401. deltAs_last2=df_ram_last2.loc[0,'deltAs2']
  402. time_last2=df_ram_last2.loc[0,'time2']
  403. firsttime2=0
  404. charging=0
  405. dict_bal2={}
  406. if df_ram_last3.empty:
  407. standingtime=0
  408. standingtime1=0
  409. standingtime2=0
  410. else:
  411. standingtime=df_ram_last3.loc[0,'standingtime']
  412. standingtime1=df_ram_last3.loc[0,'standingtime1']
  413. standingtime2=df_ram_last3.loc[0,'standingtime2']
  414. dict_bal1={}
  415. if abs(self.packcrnt[0])<0.01 and standingtime>1 and standingtime1>1:
  416. standingtime=standingtime+(self.bmstime[0]-df_ram_last3.loc[0,'time3']).total_seconds()
  417. standingtime1=standingtime1+(self.bmstime[0]-df_ram_last3.loc[0,'time3']).total_seconds()
  418. else:
  419. pass
  420. for i in range(1,len(self.df_bms)-1):
  421. #静置法计算内短路..........................................................................................................................
  422. if firsttime1==0: #满电静置算法--计算均衡状态对应的均衡时间
  423. try:
  424. balstat=int(self.df_bms.loc[i,'单体均衡状态'])
  425. if balstat>0.5:
  426. bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds() #均衡步长
  427. bal_step=int(bal_step)
  428. if str(balstat) in dict_bal1.keys():
  429. dict_bal1[str(balstat)]=dict_bal1[str(balstat)]+bal_step
  430. else:
  431. dict_bal1[str(balstat)]=bal_step
  432. else:
  433. pass
  434. except:
  435. dict_bal1={}
  436. else:
  437. pass
  438. if abs(self.packcrnt[i]) < 0.1 and abs(self.packcrnt[i-1]) < 0.1:
  439. delttime=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
  440. standingtime=standingtime+delttime
  441. standingtime1=standingtime1+delttime
  442. self._celltemp_weight(i)
  443. #长时间静置法计算内短路-开始.....................................................................................................................................
  444. if firsttime==1:
  445. if standingtime>self.StandardStandingTime: #静置时间满足要求
  446. cellvolt_now=self._avgvolt_get(i)
  447. if not cellvolt_now.empty:
  448. standingtime=0
  449. cellvolt_min=min(cellvolt_now)
  450. cellvolt_max=max(cellvolt_now)
  451. # cellvolt_last=self._avgvolt_get(i-1)
  452. # deltvolt=max(abs(cellvolt_now-cellvolt_last))
  453. cellsoc_max=np.interp(cellvolt_max,self.param.LookTab_OCV,self.param.LookTab_SOC)
  454. cellsoc_min=np.interp(cellvolt_min,self.param.LookTab_OCV,self.param.LookTab_SOC)
  455. if cellsoc_max<self.param.SocInflexion1-2 and 12<cellsoc_min:
  456. dict_baltime={} #获取每个电芯的均衡时间
  457. deltsoc_last, cellsoc_last=self._celldeltsoc_get(cellvolt_now,dict_baltime,capacity)
  458. time_last=self.bmstime[i]
  459. firsttime=0
  460. df_ram_last.loc[0]=[self.sn,time_last,deltsoc_last,cellsoc_last] #更新RAM信息
  461. else:
  462. pass
  463. else:
  464. pass
  465. elif standingtime>3600*12:
  466. cellvolt_now=np.array(self._avgvolt_get(i))
  467. if not cellvolt_now.empty:
  468. standingtime=0
  469. cellvolt_min=min(cellvolt_now)
  470. cellvolt_max=max(cellvolt_now)
  471. # cellvolt_last=np.array(self._avgvolt_get(i-1))
  472. # deltvolt=max(abs(cellvolt_now-cellvolt_last))
  473. cellsoc_max=np.interp(cellvolt_max,self.param.LookTab_OCV,self.param.LookTab_SOC)
  474. cellsoc_min=np.interp(cellvolt_min,self.param.LookTab_OCV,self.param.LookTab_SOC)
  475. if cellsoc_max<self.param.SocInflexion1-2 and 12<cellsoc_min:
  476. dict_baltime=self._bal_time(dict_bal) #获取每个电芯的均衡时间
  477. deltsoc_now, cellsoc_now=self._celldeltsoc_get(cellvolt_now, dict_baltime,capacity) #获取每个电芯的SOC差
  478. time_now=self.bmstime[i]
  479. if -5<max(cellsoc_now-cellsoc_last)<5:
  480. df_ram_last.loc[0]=[self.sn,time_now,deltsoc_now,cellsoc_now] #更新RAM信息
  481. list_sub=deltsoc_now-deltsoc_last
  482. list_pud=(0.01*capacity*3600*1000)/(time_now-time_last).total_seconds()
  483. leak_current=list_sub*list_pud
  484. # leak_current=np.array(leak_current)
  485. leak_current=np.round(leak_current,3)
  486. leak_current=list(leak_current)
  487. df_res.loc[len(df_res)]=[time_last,time_now,self.sn,1,str(leak_current),str(dict_baltime)] #计算结果存入Dataframe
  488. time_last=time_now #更新时间
  489. deltsoc_last=deltsoc_now #更新soc差
  490. dict_bal={}
  491. else:
  492. firsttime=1
  493. else:
  494. pass
  495. else:
  496. try:
  497. balstat=int(self.df_bms.loc[i,'单体均衡状态'])
  498. if balstat>0.5:
  499. bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds() #均衡步长
  500. bal_step=int(bal_step)
  501. if str(balstat) in dict_bal.keys():
  502. dict_bal[str(balstat)]=dict_bal[str(balstat)]+bal_step
  503. else:
  504. dict_bal[str(balstat)]=bal_step
  505. else:
  506. pass
  507. except:
  508. dict_bal={}
  509. #非平台区间静置法计算内短路-开始.....................................................................................................................................................
  510. if standingtime1>self.StandardStandingTime:
  511. cellvolt_now1=self._avgvolt_get(i)
  512. if not cellvolt_now1.empty:
  513. standingtime1=0
  514. cellvolt_max1=max(cellvolt_now1)
  515. cellvolt_min1=min(cellvolt_now1)
  516. # cellvolt_last1=self._avgvolt_get(i-1)
  517. # deltvolt1=max(abs(cellvolt_now1-cellvolt_last1))
  518. cellsoc_max1=np.interp(cellvolt_max1,self.param.LookTab_OCV,self.param.LookTab_SOC)
  519. cellsoc_min1=np.interp(cellvolt_min1,self.param.LookTab_OCV,self.param.LookTab_SOC)
  520. if cellsoc_max1<self.param.SocInflexion1-2 and 1<cellsoc_min1:
  521. if firsttime1==1:
  522. dict_baltime1=self._bal_time(dict_bal1) #获取每个电芯的均衡时间
  523. deltsoc_last1, cellsoc_last1=self._celldeltsoc_get(cellvolt_now1,dict_baltime1,capacity)
  524. time_last1=self.bmstime[i]
  525. firsttime1=0
  526. df_ram_last1.loc[0]=[self.sn,time_last1,deltsoc_last1] #更新RAM信息
  527. else:
  528. dict_baltime1=self._bal_time(dict_bal1) #获取每个电芯的均衡时间
  529. deltsoc_now1, cellsoc_now1=self._celldeltsoc_get(cellvolt_now1,dict_baltime1,capacity)
  530. time_now1=self.bmstime[i]
  531. df_ram_last1.loc[0]=[self.sn,time_now1,deltsoc_now1] #更新RAM信息
  532. if (time_now1-time_last1).total_seconds()>3600*24:
  533. list_sub1=deltsoc_now1-deltsoc_last1
  534. list_pud1=(0.01*capacity*3600*1000)/(time_now1-time_last1).total_seconds()
  535. leak_current1=list_sub1*list_pud1
  536. # leak_current1=np.array(leak_current1)
  537. leak_current1=np.round(leak_current1,3)
  538. leak_current1=list(leak_current1)
  539. df_res.loc[len(df_res)]=[time_last1,time_now1,self.sn,2,str(leak_current1),str(dict_baltime1)] #计算结果存入Dataframe
  540. time_last1=time_now1 #更新时间
  541. deltsoc_last1=deltsoc_now1 #更新soc差
  542. dict_bal1={}
  543. else:
  544. pass
  545. else:
  546. pass
  547. else:
  548. pass
  549. else:
  550. df_ram_last=pd.DataFrame(columns=['sn','time','deltsoc','cellsoc']) #电流>0,清空上次静置的SOC差
  551. dict_bal={}
  552. firsttime=1
  553. standingtime=0
  554. standingtime1=0
  555. pass
  556. if i==len(self.df_bms)-2 and abs(self.packcrnt[i+1]) < 0.1: #数据中断后仍在静置,将最后一条数据写入RAM
  557. df_ram_lfp.loc[0]=self.df_bms.iloc[-1]
  558. else:
  559. pass
  560. #获取充电数据——开始..............................................................................................................
  561. try:
  562. balstat=int(self.df_bms.loc[i,'单体均衡状态']) #统计均衡状态
  563. if balstat>0.5:
  564. bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds() #均衡步长
  565. bal_step=int(bal_step)
  566. if str(balstat) in dict_bal2.keys():
  567. dict_bal2[str(balstat)]=dict_bal2[str(balstat)]+bal_step
  568. else:
  569. dict_bal2[str(balstat)]=bal_step
  570. else:
  571. pass
  572. except:
  573. dict_bal2={}
  574. #判断充电状态
  575. if charging==0:
  576. if self.packcrnt[i]<=-1 and self.packcrnt[i+1]<=-1 and self.packcrnt[i-1]<=-1:
  577. if self.bms_soc[i]<40:
  578. cellvolt_now=self._cellvolt_get(i)
  579. if min(cellvolt_now)<self.param.CellFullChrgVolt-0.17:
  580. charging=1
  581. chrg_start=i
  582. else:
  583. pass
  584. else:
  585. pass
  586. else: #充电中
  587. cellvolt_now=self._cellvolt_get(i)
  588. if (self.bmstime[i+1]-self.bmstime[i]).total_seconds()>180 or (self.packcrnt[i]>-0.1 and self.packcrnt[i-1]>-0.1) or (self.packcrnt[i]<-self.param.Capacity and self.packcrnt[i+1]<-self.param.Capacity): #如果充电过程中时间间隔>180s,则舍弃该次充电
  589. charging=0
  590. continue
  591. elif min(cellvolt_now)>self.param.CellFullChrgVolt-0.1:
  592. self._celltemp_weight(i)
  593. if i-chrg_start>10 and self.celltemp>20:
  594. chrg_end=i+1
  595. charging=0
  596. #计算漏电流值...................................................................
  597. if firsttime2==1:
  598. dict_baltime={}
  599. deltAs_last2=self._cellDeltAs_get(chrg_start,chrg_end,dict_baltime)
  600. time_last2=self.bmstime[chrg_end]
  601. df_ram_last2.loc[0]=[self.sn,time_last2,deltAs_last2] #更新RAM信息
  602. else:
  603. dict_baltime=self._bal_time(dict_bal2) #获取每个电芯的均衡时间
  604. deltAs_now2=self._cellDeltAs_get(chrg_start,chrg_end,dict_baltime) #获取每个电芯的As差
  605. time_now2=self.bmstime[chrg_end]
  606. df_ram_last2.loc[0]=[self.sn,time_now2,deltAs_now2] #更新RAM信息
  607. list_sub2=deltAs_now2-deltAs_last2
  608. list_pud2=-1000/(time_now2-time_last2).total_seconds()
  609. leak_current2=list_sub2*list_pud2
  610. # leak_current=np.array(leak_current)
  611. leak_current2=np.round(leak_current2,3)
  612. leak_current2=list(leak_current2)
  613. df_res.loc[len(df_res)]=[time_last2,time_now2,self.sn,3,str(leak_current2),str(dict_baltime)] #计算结果存入Dataframe
  614. deltAs_last2=deltAs_now2
  615. time_last2=time_now2
  616. dict_bal2={}
  617. else:
  618. charging=0
  619. continue
  620. elif i==len(self.df_bms)-2: #数据中断后仍在充电,将前段充电数据写入RAM
  621. df_ram_lfp=self.df_bms.iloc[chrg_start:]
  622. df_ram_lfp['sn']=self.sn
  623. else:
  624. pass
  625. #更新RAM
  626. df_ram_last3.loc[0]=[self.sn,self.bmstime[len(self.bmstime)-1],standingtime,standingtime1,standingtime2]
  627. #返回结果
  628. if df_res.empty:
  629. return pd.DataFrame(), df_ram_last, df_ram_last1, df_ram_last2, df_ram_last3,df_ram_lfp
  630. else:
  631. return df_res, df_ram_last, df_ram_last1, df_ram_last2, df_ram_last3, df_ram_lfp