CBMSBatSoc.py 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. import pandas as pd
  2. import numpy as np
  3. from scipy.interpolate import interp2d
  4. import BatParam
  5. import datetime
  6. class BatSoc():
  7. def __init__(self,sn,celltype,df_bms,df_soh,df_ram_sn,df_socdiff): #参数初始化
  8. self.sn=sn
  9. self.celltype=celltype
  10. self.param=BatParam.BatParam(celltype)
  11. self.df_soh=df_soh
  12. self.df_socdiff=df_socdiff
  13. self.df_ram_sn=df_ram_sn
  14. df_bms['time']=pd.to_datetime(df_bms['time'], format='%Y-%m-%d %H:%M:%S')
  15. self.df_bms=df_bms
  16. if not self.df_ram_sn.empty:
  17. self.df_bms=self.df_bms[self.df_bms['time'] > self.df_ram_sn.iloc[-1]['time']] #滤除原始数据中的重复数据
  18. self.df_bms.reset_index(inplace=True,drop=True) #重置索引
  19. self.packcrnt=df_bms['PackCrnt']*self.param.PackCrntDec
  20. self.bms_soc=df_bms['PackSOC']
  21. self.bms_soh=df_bms['PackSOH']
  22. self.bmstime= pd.to_datetime(df_bms['time'], format='%Y-%m-%d %H:%M:%S')
  23. self.cellvolt_name=['CellVolt'+str(x) for x in range(1,self.param.CellVoltNums+1)]
  24. self.celltemp_name=['CellTemp'+str(x) for x in range(1,self.param.CellTempNums+1)]
  25. def batsoc(self):
  26. if self.celltype<50:
  27. if not self.df_bms.empty:
  28. df_res, df_ram=self._ncm_soc()
  29. return df_res, df_ram
  30. else:
  31. return pd.DataFrame(), pd.DataFrame()
  32. elif self.celltype>50:
  33. if not self.df_bms.empty:
  34. df_res, df_ram=self._lfp_soc()
  35. return df_res, df_ram
  36. else:
  37. return pd.DataFrame(), pd.DataFrame()
  38. else:
  39. return pd.DataFrame()
  40. #........................................................寻找当前行数据的最小温度值...........................................................................................
  41. def _celltemp_weight(self,num):
  42. celltemp = list(self.df_bms.loc[num,self.celltemp_name])
  43. celltemp=np.mean(celltemp)
  44. self.celltemp=celltemp
  45. if self.celltype==99:
  46. if celltemp>=25:
  47. self.tempweight=1
  48. self.StandardStandingTime=3600
  49. elif celltemp>=15:
  50. self.tempweight=0.6
  51. self.StandardStandingTime=7200
  52. elif celltemp>=5:
  53. self.tempweight=0.
  54. self.StandardStandingTime=10800
  55. else:
  56. self.tempweight=0.1
  57. self.StandardStandingTime=18000
  58. else:
  59. if celltemp>=20:
  60. self.tempweight=1
  61. self.StandardStandingTime=1800
  62. elif celltemp>=10:
  63. self.tempweight=0.8
  64. self.StandardStandingTime=3600
  65. elif celltemp>=5:
  66. self.tempweight=0.6
  67. self.StandardStandingTime=7200
  68. else:
  69. self.tempweight=0.2
  70. self.StandardStandingTime=10800
  71. #.......................................................获取当前行所有电压数据...............................................................................................
  72. def _cellvolt_get(self,num):
  73. cellvolt = np.array(self.df_bms.loc[num,self.cellvolt_name])
  74. return cellvolt
  75. #......................................................判断单体电压离散度,并返回OCV值....................................................................................
  76. def _ocv_dispersion(self):
  77. cellvolt=self.df_bms[self.cellvolt_name]
  78. cellocv=cellvolt.mean(axis=0)
  79. cellocv_std=cellvolt.std(axis=0)
  80. cellocv_std=cellocv_std.fillna(0)
  81. if max(cellocv_std)<0.003:
  82. return np.array(cellocv)
  83. else:
  84. return [0]
  85. #...........................................................三元电池的soc计算...............................................................................................
  86. def _ncm_soc(self):
  87. column_name=['time', 'sn', 'bms_soc', 'packsoc', 'socdsp', 'cellsocmin', 'cellsocmax','socmin_num','socmax_num','cellsoc_diff','cellsoc','ocvweight','socstep']
  88. df_res=pd.DataFrame(columns=column_name)
  89. df_bms_len=len(self.df_bms)
  90. rampackcrnt=self.packcrnt[df_bms_len-1]
  91. ocvweight=0
  92. #获取电池包SOH................................................................................................
  93. if self.df_soh.empty:
  94. batsoh=self.bms_soh[0]
  95. if batsoh>30:
  96. capacity=self.param.Capacity*batsoh/100
  97. else:
  98. capacity=self.param.Capacity
  99. else:
  100. batsoh=eval(self.df_soh.loc[0,'cellsoh'])
  101. batsoh=np.array(batsoh)
  102. capacity=self.param.Capacity*batsoh/100
  103. #计算静置时间和累计As量..................................................................................................
  104. if not self.df_ram_sn.empty:
  105. standingtime=self.df_ram_sn.iloc[-1]['standingtime']
  106. as_accum=0
  107. for i in range(df_bms_len):
  108. if i==0:
  109. step=(self.bmstime[i]-self.df_ram_sn.iloc[-1]['time']).total_seconds()
  110. if abs(self.packcrnt[i])<0.1 and abs(self.df_ram_sn.iloc[-1]['rampackcrnt'])<0.1:
  111. standingtime=standingtime+step
  112. else:
  113. standingtime=0
  114. if step<120:
  115. as_accum=as_accum-self.packcrnt[i]*step
  116. elif 1<self.bms_soc[i]<=100 and 1<self.df_ram_sn.iloc[-1]['bms_soc']<=100:
  117. as_accum=as_accum+((self.bms_soc[i]-self.df_ram_sn.iloc[-1]['bms_soc'])*capacity*3600/100)
  118. else:
  119. pass
  120. else:
  121. step=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
  122. if abs(self.packcrnt[i])<0.1 and abs(self.packcrnt[i-1])<0.1:
  123. standingtime=standingtime+step
  124. as_accum=as_accum-self.packcrnt[i]*step
  125. else:
  126. standingtime=0
  127. as_accum=as_accum-self.packcrnt[i]*step
  128. else:
  129. standingtime=0
  130. as_accum=0
  131. for i in range(df_bms_len):
  132. if i==0:
  133. pass
  134. else:
  135. step=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
  136. if abs(self.packcrnt[i])<0.1 and abs(self.packcrnt[i-1])<0.1:
  137. standingtime=standingtime+step
  138. as_accum=as_accum-self.packcrnt[i]*step
  139. else:
  140. standingtime=0
  141. as_accum=as_accum-self.packcrnt[i]*step
  142. if standingtime>3600*24*30:
  143. standingtime=3600*24*30
  144. else:
  145. pass
  146. #计算单体SOC.............................................................................................................................
  147. if not self.df_ram_sn.empty:
  148. self._celltemp_weight(0)
  149. ramcellvolt=self.df_ram_sn.iloc[-1]['ramcellvolt']
  150. ramcellsoc=self.df_ram_sn.iloc[-1]['cellsoc']
  151. ocvweight_2dlook=interp2d(self.param.OcvWeight_StandingTime, self.param.OcvWeight_Temp, self.param.OcvWeight, kind = 'linear')
  152. ocvweight=ocvweight_2dlook(standingtime, self.celltemp)
  153. ocvweight=ocvweight[0]
  154. if self.bmstime[0]>datetime.datetime.strptime('2021-10-22 19:49:20','%Y-%m-%d %H:%M:%S'):
  155. pass
  156. if ocvweight>0.01:
  157. cellocv=self._ocv_dispersion()
  158. if df_bms_len>1: #数据字段长度≥2
  159. if 2<max(cellocv)<4.5 and 2<min(cellocv)<4.5:
  160. ocvsoc=np.array(list(map(lambda x:np.interp(x,self.param.LookTab_OCV,self.param.LookTab_SOC),cellocv)))
  161. cellsoc=ocvsoc*ocvweight+ramcellsoc*(1-ocvweight)
  162. socstep=0
  163. else:
  164. cellsoc=ramcellsoc
  165. socstep=1
  166. else: #数据字段长度==1
  167. if 2<max(cellocv)<4.5 and 2<min(cellocv)<4.5 and max(abs(ramcellvolt-np.array(cellocv)))<0.004:
  168. ocvsoc=np.array(list(map(lambda x:np.interp(x,self.param.LookTab_OCV,self.param.LookTab_SOC),cellocv)))
  169. cellsoc=ocvsoc*ocvweight+ramcellsoc*(1-ocvweight)
  170. socstep=2
  171. else:
  172. cellsoc=ramcellsoc
  173. socstep=3
  174. else:
  175. cellsoc=ramcellsoc+(as_accum*100)/(3600*capacity)
  176. socstep=4
  177. else:
  178. cellsoc= np.array([self.bms_soc[df_bms_len-1]])+np.random.rand(self.param.CellVoltNums)
  179. socstep=5
  180. #更新ram电芯电压
  181. ramcellvolt=self._cellvolt_get(df_bms_len-1)
  182. #单体Soc满充修正........................................................................................................................................................................
  183. cellvoltall=self.df_bms[self.cellvolt_name] #筛选所有单体电压
  184. cellvoltall_min=cellvoltall.min(axis=0) #每一个单体电芯的最小值
  185. if self.param.CellFullChrgVolt<max(cellvoltall_min)<5 and self.param.CellFullChrgVolt<max(cellvoltall_min)<5 and min(self.packcrnt)>self.param.CellFullChrgCrnt and max(self.packcrnt)<-0.5:
  186. deltsoc=self.param.FullChrgSoc-max(cellsoc)
  187. cellsoc=cellsoc+deltsoc
  188. else:
  189. pass
  190. #计算电池包packsoc和最大最小SOC..................................................................................................................................................................................
  191. cellsoc[cellsoc>100]=100 #限值最大值100
  192. cellsoc[cellsoc<0]=0 #限值最小值0
  193. cellsoc1=list(map(lambda x:float(format(x,'.1f')), cellsoc))
  194. cellsocmin=min(cellsoc1)
  195. cellsocmax=max(cellsoc1)
  196. cellsoc_diff=cellsocmax-cellsocmin
  197. socmin_num=cellsoc1.index(cellsocmin)+1
  198. socmax_num=cellsoc1.index(cellsocmax)+1
  199. alpha=(cellsocmin+cellsocmax)*0.02-2 #blending系数计算
  200. if cellsocmax>90 or alpha>1:
  201. alpha=1
  202. elif cellsocmin<10 or alpha<-1:
  203. alpha=-1
  204. else:
  205. pass
  206. packsoc=(cellsocmin+cellsocmax)*0.5+(cellsocmax-cellsocmin)*0.5*alpha
  207. packsoc=eval(format(packsoc,'.1f'))
  208. socdsp=packsoc
  209. #输出ram结果....................................................................................................................................................................
  210. list_ram=[self.bmstime[df_bms_len-1], self.sn, self.bms_soc[df_bms_len-1], packsoc, cellsoc, standingtime, rampackcrnt, ramcellvolt,0,0,ocvweight,as_accum,socstep]
  211. df_ram=pd.DataFrame(columns=self.df_ram_sn.columns)
  212. df_ram.loc[0]=list_ram
  213. #输出计算结果........................................................................................................................................................................
  214. df_res.loc[0]=[self.bmstime[df_bms_len-1], self.sn, self.bms_soc[df_bms_len-1], packsoc, socdsp, cellsocmin, cellsocmax,socmin_num,socmax_num,cellsoc_diff,str(cellsoc1),ocvweight,socstep]
  215. return df_res, df_ram
  216. #...........................................................磷酸铁锂电池的soc计算...............................................................................................
  217. def _lfp_soc(self):
  218. column_name=['time', 'sn', 'bms_soc', 'packsoc', 'socdsp', 'cellsocmin', 'cellsocmax','socmin_num','socmax_num','cellsoc_diff','cellsoc','ocvweight','socstep']
  219. df_res=pd.DataFrame(columns=column_name)
  220. df_bms_len=len(self.df_bms)
  221. rampackcrnt=self.packcrnt[df_bms_len-1]
  222. if not self.df_socdiff.empty:
  223. cellsoc_diff=self.df_socdiff.iloc[-1]['cellsoc_diff']
  224. else:
  225. cellsoc_diff=2
  226. #获取电池包SOH................................................................................................
  227. if self.df_soh.empty:
  228. batsoh=self.bms_soh[0]
  229. if batsoh>30:
  230. capacity=self.param.Capacity*batsoh/100
  231. else:
  232. capacity=self.param.Capacity
  233. else:
  234. batsoh=self.df_soh.loc[0,'soh']
  235. capacity=self.param.Capacity*batsoh/100
  236. #计算静置时间和累计As量以及OCV权重值..................................................................................................
  237. if not self.df_ram_sn.empty:
  238. standingtime=self.df_ram_sn.iloc[-1]['standingtime']
  239. ocvweight=self.df_ram_sn.iloc[-1]['ocvweight']
  240. as_accum=0
  241. for i in range(df_bms_len):
  242. if i==0:
  243. step=(self.bmstime[i]-self.df_ram_sn.iloc[-1]['time']).total_seconds()
  244. if abs(self.packcrnt[i])<0.1 and abs(self.df_ram_sn.iloc[-1]['rampackcrnt'])<0.1:
  245. standingtime=standingtime+step
  246. else:
  247. standingtime=0
  248. if step<120:
  249. as_accum=as_accum-self.packcrnt[i]*step
  250. elif 1<self.bms_soc[i]<=100 and 1<self.df_ram_sn.iloc[-1]['bms_soc']<=100:
  251. as_accum=as_accum+((self.bms_soc[i]-self.df_ram_sn.iloc[-1]['bms_soc'])*capacity*3600/100)
  252. else:
  253. pass
  254. else:
  255. step=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
  256. if abs(self.packcrnt[i])<0.1 and abs(self.packcrnt[i-1])<0.1:
  257. standingtime=standingtime+step
  258. as_accum=as_accum-self.packcrnt[i]*step
  259. else:
  260. standingtime=0
  261. as_accum=as_accum-self.packcrnt[i]*step
  262. else:
  263. standingtime=0
  264. ocvweight=0.5
  265. as_accum=0
  266. for i in range(df_bms_len):
  267. if i==0:
  268. pass
  269. else:
  270. step=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
  271. if abs(self.packcrnt[i])<0.1 and abs(self.packcrnt[i-1])<0.1:
  272. standingtime=standingtime+step
  273. as_accum=as_accum-self.packcrnt[i]*step
  274. else:
  275. standingtime=0
  276. as_accum=as_accum-self.packcrnt[i]*step
  277. #静置时间限值..............................................
  278. if standingtime>3600*24*30:
  279. standingtime=3600*24*30
  280. else:
  281. pass
  282. #权重值计算.................................................
  283. ocvweight=ocvweight-(as_accum*10)/(capacity*3600)
  284. if ocvweight>1:
  285. ocvweight=1
  286. elif ocvweight<0:
  287. ocvweight=0
  288. else:
  289. pass
  290. ocvweight=eval(format(ocvweight,'.2f'))
  291. #计算单体最大最小SOC.............................................................................................................................
  292. cellocv=self._ocv_dispersion() #获取每一列电压的平均值
  293. if not self.df_ram_sn.empty:
  294. self._celltemp_weight(0)
  295. kocellvoltmin=self.df_ram_sn.iloc[-1]['kocellvoltmin']
  296. kocellvoltmax=self.df_ram_sn.iloc[-1]['kocellvoltmax']
  297. ramcellsoc=self.df_ram_sn.iloc[-1]['cellsoc']
  298. #满足静置时间
  299. if standingtime>self.StandardStandingTime:
  300. #数据字段长度≥2...............................................................................................................
  301. if df_bms_len>1:
  302. ocvsocmin=np.interp(min(cellocv),self.param.LookTab_OCV,self.param.LookTab_SOC)
  303. ocvsocmax=np.interp(max(cellocv),self.param.LookTab_OCV,self.param.LookTab_SOC)
  304. if 2<min(cellocv)<self.param.OcvInflexionBelow and 2<max(cellocv)<self.param.OcvInflexionBelow and ocvsocmax<self.param.SocInflexion1:
  305. cellsocmin=ocvsocmin
  306. cellsocmax=ocvsocmax
  307. socstep=0
  308. elif 2<min(cellocv)<self.param.OcvInflexionBelow and max(cellocv)>=self.param.OcvInflexionBelow and ocvsocmin<self.param.SocInflexion1:
  309. cellsocmin=ocvsocmin
  310. cellsocmax=ocvsocmin+cellsoc_diff
  311. socstep=1
  312. elif min(cellocv)>2 and max(cellocv)<4:
  313. #第一平台向第二平台修正
  314. if ocvsocmax>self.param.SocInflexion3+5 and max(ramcellsoc)<self.param.SocInflexion2-5:
  315. if ocvsocmin>self.param.SocInflexion3+5 and min(ramcellsoc)<self.param.SocInflexion2-5:
  316. cellsocmin=self.param.SocInflexion3
  317. cellsocmax=cellsocmin+cellsoc_diff
  318. socstep=2
  319. else:
  320. cellsocmax=self.param.SocInflexion3
  321. cellsocmin=cellsocmax-cellsoc_diff
  322. socstep=3
  323. #第一非平台区向第一平台区修正
  324. elif ocvsocmax>self.param.SocInflexion1+5 and max(ramcellsoc)<self.param.SocInflexion1-2:
  325. if ocvsocmin>self.param.SocInflexion1+5 and min(ramcellsoc)<self.param.SocInflexion1-2:
  326. cellsocmin=self.param.SocInflexion1
  327. cellsocmax=cellsocmin+cellsoc_diff
  328. socstep=4
  329. else:
  330. cellsocmax=self.param.SocInflexion1
  331. cellsocmin=cellsocmax-cellsoc_diff
  332. socstep=5
  333. #第二平台区向第一平台区修正
  334. elif ocvsocmin<self.param.SocInflexion2-5 and min(ramcellsoc)>self.param.SocInflexion3+5:
  335. if ocvsocmax<self.param.SocInflexion2-5 and max(ramcellsoc)>self.param.SocInflexion3+5:
  336. cellsocmax=self.param.SocInflexion2
  337. cellsocmin=cellsocmax-cellsoc_diff
  338. socstep=6
  339. else:
  340. cellsocmin=self.param.SocInflexion2
  341. cellsocmax=cellsocmin+cellsoc_diff
  342. socstep=7
  343. else:
  344. cellsoc=ramcellsoc
  345. socstep=8
  346. else:
  347. cellsoc=ramcellsoc
  348. socstep=8
  349. #数据字段长度==1..............................................................................................
  350. else:
  351. cellvolt0=self._cellvolt_get(0)
  352. ramcellvolt=self.df_ram_sn.iloc[-1]['ramcellvolt']
  353. if max(abs(cellvolt0-ramcellvolt))<0.004:
  354. ocvmax=max(cellvolt0)
  355. ocvmin=min(cellvolt0)
  356. ocvsocmin=np.interp(ocvmin,self.param.LookTab_OCV,self.param.LookTab_SOC)
  357. ocvsocmax=np.interp(ocvmax,self.param.LookTab_OCV,self.param.LookTab_SOC)
  358. if 2<ocvmin<self.param.OcvInflexionBelow and 2<ocvmax<self.param.OcvInflexionBelow and ocvsocmax<self.param.SocInflexion1:
  359. cellsocmin=ocvsocmin
  360. cellsocmax=ocvsocmax
  361. socstep=9
  362. elif 2<ocvmin<self.param.OcvInflexionBelow and ocvmax>=self.param.OcvInflexionBelow and ocvsocmin<self.param.SocInflexion1:
  363. cellsocmin=ocvsocmin
  364. cellsocmax=ocvsocmin+cellsoc_diff
  365. socstep=10
  366. elif ocvmin>2 and ocvmax<4:
  367. #第一平台向第二平台修正
  368. if ocvsocmax>self.param.SocInflexion3+5 and max(ramcellsoc)<self.param.SocInflexion2-5:
  369. if ocvsocmin>self.param.SocInflexion3+5 and min(ramcellsoc)<self.param.SocInflexion2-5:
  370. cellsocmin=self.param.SocInflexion3
  371. cellsocmax=cellsocmin+cellsoc_diff
  372. socstep=11
  373. else:
  374. cellsocmax=self.param.SocInflexion3
  375. cellsocmin=cellsocmax-cellsoc_diff
  376. socstep=12
  377. #第一非平台区向第一平台区修正
  378. elif ocvsocmax>self.param.SocInflexion1+5 and max(ramcellsoc)<self.param.SocInflexion1-2:
  379. if ocvsocmin>self.param.SocInflexion1+5 and min(ramcellsoc)<self.param.SocInflexion1-2:
  380. cellsocmin=self.param.SocInflexion1
  381. cellsocmax=cellsocmin+cellsoc_diff
  382. socstep=13
  383. else:
  384. cellsocmax=self.param.SocInflexion1
  385. cellsocmin=cellsocmax-cellsoc_diff
  386. socstep=14
  387. #第二平台区向第一平台区修正
  388. elif ocvsocmin<self.param.SocInflexion2-5 and min(ramcellsoc)>self.param.SocInflexion3+5:
  389. if ocvsocmax<self.param.SocInflexion2-5 and max(ramcellsoc)>self.param.SocInflexion3+5:
  390. cellsocmax=self.param.SocInflexion2
  391. cellsocmin=cellsocmax-cellsoc_diff
  392. socstep=15
  393. else:
  394. cellsocmin=self.param.SocInflexion2
  395. cellsocmax=cellsocmin+cellsoc_diff
  396. socstep=16
  397. else:
  398. cellsoc=ramcellsoc
  399. socstep=17
  400. else:
  401. cellsoc=ramcellsoc
  402. socstep=17
  403. else:
  404. cellsoc=ramcellsoc
  405. socstep=17
  406. #不满足静置时间,判断电压回弹方向
  407. elif standingtime>130 and 2<kocellvoltmax<4.5 and 2<kocellvoltmin<4.5:
  408. cellvoltmin=min(cellocv)
  409. cellvoltmax=max(cellocv)
  410. ocvsocmin1=np.interp(cellvoltmin,self.param.LookTab_OCV,self.param.LookTab_SOC)
  411. ocvsocmax1=np.interp(cellvoltmax,self.param.LookTab_OCV,self.param.LookTab_SOC)
  412. #最大最小电压向上回弹
  413. if 2<cellvoltmin<4.5 and cellvoltmin>kocellvoltmin+0.005 and ocvsocmin1>min(ramcellsoc):
  414. if 2<cellvoltmax<4.5 and cellvoltmax>kocellvoltmax+0.005 and ocvsocmax1>max(ramcellsoc):
  415. #最大最小电压均在非平台区
  416. if ocvsocmax1<self.param.SocInflexion1:
  417. cellsocmin=ocvsocmin1
  418. cellsocmax=ocvsocmax1
  419. socstep=18
  420. #最小电压均在非平台区,最大电压在平台区
  421. elif ocvsocmin1<self.param.SocInflexion1:
  422. cellsocmin=ocvsocmin1
  423. cellsocmax=cellsocmin+cellsoc_diff
  424. socstep=19
  425. #最大最小电压均在平台区,ramsoc在非平台区
  426. elif ocvsocmin1>self.param.SocInflexion1+5 and max(ramcellsoc)<self.param.SocInflexion1 and min(ramcellsoc)<self.param.SocInflexion1:
  427. cellsocmin=self.param.SocInflexion1
  428. cellsocmax=cellsocmin+cellsoc_diff
  429. socstep=20
  430. else:
  431. cellsoc=ramcellsoc
  432. socstep=21
  433. else:
  434. cellsoc=ramcellsoc
  435. socstep=22
  436. #最大最小电压向下回弹
  437. elif 2<cellvoltmin<4.5 and cellvoltmin<kocellvoltmin-0.005 and ocvsocmin1<min(ramcellsoc):
  438. if 2<cellvoltmax<4.5 and cellvoltmax<kocellvoltmax-0.005 and ocvsocmax1>max(ramcellsoc):
  439. #最大最小电压均在非平台区
  440. if ocvsocmax1<self.param.SocInflexion1:
  441. cellsocmin=ocvsocmin1
  442. cellsocmax=ocvsocmax1
  443. socstep=23
  444. #最小电压在非平台区,最大电压在平台区
  445. elif ocvsocmin1<self.param.SocInflexion1:
  446. cellsocmin=ocvsocmin1
  447. cellsocmax=cellsocmin+cellsoc_diff
  448. socstep=24
  449. else:
  450. cellsoc=ramcellsoc
  451. socstep=25
  452. else:
  453. cellsoc=ramcellsoc
  454. socstep=26
  455. #电压回弹方向一致
  456. else:
  457. cellsoc=ramcellsoc
  458. socstep=27
  459. #更新ko电压
  460. elif 70<standingtime<=130:
  461. cellsoc=ramcellsoc
  462. socstep=28
  463. cellvolt=self._cellvolt_get(df_bms_len-1)
  464. kocellvoltmin=min(cellvolt)
  465. kocellvoltmax=max(cellvolt)
  466. else:
  467. cellsoc=ramcellsoc+(as_accum*100)/(3600*capacity)
  468. socstep=29
  469. #更新ko电芯电压
  470. kocellvoltmin=0
  471. kocellvoltmax=0
  472. else:
  473. cellsocmin= self.bms_soc[df_bms_len-1]-cellsoc_diff/2
  474. cellsocmax= self.bms_soc[df_bms_len-1]+cellsoc_diff/2
  475. socstep=30
  476. #更新ko电芯电压
  477. kocellvoltmin=0
  478. kocellvoltmax=0
  479. #更新Ram电压.................
  480. ramcellvolt=self._cellvolt_get(df_bms_len-1)
  481. #单体Soc满充修正........................................................................................................................................................................
  482. cellvoltall=self.df_bms[self.cellvolt_name] #筛选所有单体电压
  483. cellvoltall_min=cellvoltall.min(axis=0) #每一个单体电芯的最小值
  484. if self.param.CellFullChrgVolt<max(cellvoltall_min)<5 and self.param.CellFullChrgVolt<max(cellvoltall_min)<5 and min(self.packcrnt)>self.param.CellFullChrgCrnt and max(self.packcrnt)<-0.5:
  485. deltsoc=self.param.FullChrgSoc-max(cellsoc)
  486. cellsoc=cellsoc+deltsoc
  487. else:
  488. pass
  489. #计算所有电芯SOC...........................................................................................
  490. if not socstep in [8,17,21,22,25,26,27,28,29]:
  491. looktab_ocv=[min(cellocv),max(cellocv)]
  492. looktab_soc=[cellsocmin,cellsocmax]
  493. cellsoc=np.array(list(map(lambda x:np.interp(x,looktab_ocv,looktab_soc),cellocv)))
  494. else:
  495. pass
  496. #计算电池包packsoc和最大最小SOC..................................................................................................................................................................................
  497. cellsoc[cellsoc>100]=100 #限值最大值100
  498. cellsoc[cellsoc<0]=0 #限值最小值0
  499. cellsoc1=list(map(lambda x:eval(format(x,'.1f')), cellsoc))
  500. cellsocmin=min(cellsoc1)
  501. cellsocmax=max(cellsoc1)
  502. cellsoc_diff=cellsocmax-cellsocmin
  503. socmin_num=cellsoc1.index(cellsocmin)+1
  504. socmax_num=cellsoc1.index(cellsocmax)+1
  505. alpha=(cellsocmin+cellsocmax)*0.02-2 #blending系数计算
  506. if cellsocmax>90 or alpha>1:
  507. alpha=1
  508. elif cellsocmin<10 or alpha<-1:
  509. alpha=-1
  510. else:
  511. pass
  512. packsoc=(cellsocmin+cellsocmax)*0.5+(cellsocmax-cellsocmin)*0.5*alpha
  513. packsoc=eval(format(packsoc,'.1f'))
  514. socdsp=packsoc
  515. #输出ram结果....................................................................................................................................................................
  516. list_ram=[self.bmstime[df_bms_len-1], self.sn, self.bms_soc[df_bms_len-1], packsoc, cellsoc, standingtime, rampackcrnt, ramcellvolt,kocellvoltmin,kocellvoltmax,ocvweight,as_accum,socstep]
  517. df_ram=pd.DataFrame(columns=self.df_ram_sn.columns)
  518. df_ram.loc[0]=list_ram
  519. #输出计算结果........................................................................................................................................................................
  520. df_res.loc[0]=[self.bmstime[df_bms_len-1], self.sn, self.bms_soc[df_bms_len-1], packsoc, socdsp, cellsocmin, cellsocmax,socmin_num,socmax_num,cellsoc_diff,str(cellsoc1),ocvweight,socstep]
  521. return df_res, df_ram