CBMSBatSoc.py 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  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.002:
  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. else:
  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. #数据字段长度==1..............................................................................................
  347. else:
  348. cellvolt0=self._cellvolt_get(0)
  349. ramcellvolt=self.df_ram_sn.iloc[-1]['ramcellvolt']
  350. if max(abs(cellvolt0-ramcellvolt))<0.004:
  351. ocvmax=max(cellvolt0)
  352. ocvmin=min(cellvolt0)
  353. ocvsocmin=np.interp(ocvmin,self.param.LookTab_OCV,self.param.LookTab_SOC)
  354. ocvsocmax=np.interp(ocvmax,self.param.LookTab_OCV,self.param.LookTab_SOC)
  355. if 2<ocvmin<self.param.OcvInflexionBelow and 2<ocvmax<self.param.OcvInflexionBelow and ocvsocmax<self.param.SocInflexion1:
  356. cellsocmin=ocvsocmin
  357. cellsocmax=ocvsocmax
  358. socstep=9
  359. elif 2<ocvmin<self.param.OcvInflexionBelow and ocvmax>=self.param.OcvInflexionBelow and ocvsocmin<self.param.SocInflexion1:
  360. cellsocmin=ocvsocmin
  361. cellsocmax=ocvsocmin+cellsoc_diff
  362. socstep=10
  363. else:
  364. #第一平台向第二平台修正
  365. if ocvsocmax>self.param.SocInflexion3+5 and max(ramcellsoc)<self.param.SocInflexion2-5:
  366. if ocvsocmin>self.param.SocInflexion3+5 and min(ramcellsoc)<self.param.SocInflexion2-5:
  367. cellsocmin=self.param.SocInflexion3
  368. cellsocmax=cellsocmin+cellsoc_diff
  369. socstep=11
  370. else:
  371. cellsocmax=self.param.SocInflexion3
  372. cellsocmin=cellsocmax-cellsoc_diff
  373. socstep=12
  374. #第一非平台区向第一平台区修正
  375. elif ocvsocmax>self.param.SocInflexion1+5 and max(ramcellsoc)<self.param.SocInflexion1-2:
  376. if ocvsocmin>self.param.SocInflexion1+5 and min(ramcellsoc)<self.param.SocInflexion1-2:
  377. cellsocmin=self.param.SocInflexion1
  378. cellsocmax=cellsocmin+cellsoc_diff
  379. socstep=13
  380. else:
  381. cellsocmax=self.param.SocInflexion1
  382. cellsocmin=cellsocmax-cellsoc_diff
  383. socstep=14
  384. #第二平台区向第一平台区修正
  385. elif ocvsocmin<self.param.SocInflexion2-5 and min(ramcellsoc)>self.param.SocInflexion3+5:
  386. if ocvsocmax<self.param.SocInflexion2-5 and max(ramcellsoc)>self.param.SocInflexion3+5:
  387. cellsocmax=self.param.SocInflexion2
  388. cellsocmin=cellsocmax-cellsoc_diff
  389. socstep=15
  390. else:
  391. cellsocmin=self.param.SocInflexion2
  392. cellsocmax=cellsocmin+cellsoc_diff
  393. socstep=16
  394. else:
  395. cellsoc=ramcellsoc
  396. socstep=17
  397. else:
  398. cellsoc=ramcellsoc
  399. socstep=17
  400. #不满足静置时间,判断电压回弹方向
  401. elif standingtime>130 and 2<kocellvoltmax<4.5 and 2<kocellvoltmin<4.5:
  402. cellvoltmin=min(cellocv)
  403. cellvoltmax=max(cellocv)
  404. ocvsocmin1=np.interp(cellvoltmin,self.param.LookTab_OCV,self.param.LookTab_SOC)
  405. ocvsocmax1=np.interp(cellvoltmax,self.param.LookTab_OCV,self.param.LookTab_SOC)
  406. #最大最小电压向上回弹
  407. if 2<cellvoltmin<4.5 and cellvoltmin>kocellvoltmin+0.005 and ocvsocmin1>min(ramcellsoc):
  408. if 2<cellvoltmax<4.5 and cellvoltmax>kocellvoltmax+0.005 and ocvsocmax1>max(ramcellsoc):
  409. #最大最小电压均在非平台区
  410. if ocvsocmax1<self.param.SocInflexion1:
  411. cellsocmin=ocvsocmin1
  412. cellsocmax=ocvsocmax1
  413. socstep=18
  414. #最小电压均在非平台区,最大电压在平台区
  415. elif ocvsocmin1<self.param.SocInflexion1:
  416. cellsocmin=ocvsocmin1
  417. cellsocmax=cellsocmin+cellsoc_diff
  418. socstep=19
  419. #最大最小电压均在平台区,ramsoc在非平台区
  420. elif ocvsocmin1>self.param.SocInflexion1+5 and max(ramcellsoc)<self.param.SocInflexion1 and min(ramcellsoc)<self.param.SocInflexion1:
  421. cellsocmin=self.param.SocInflexion1
  422. cellsocmax=cellsocmin+cellsoc_diff
  423. socstep=20
  424. else:
  425. cellsoc=ramcellsoc
  426. socstep=21
  427. else:
  428. cellsoc=ramcellsoc
  429. socstep=22
  430. #最大最小电压向下回弹
  431. elif 2<cellvoltmin<4.5 and cellvoltmin<kocellvoltmin-0.005 and ocvsocmin1<min(ramcellsoc):
  432. if 2<cellvoltmax<4.5 and cellvoltmax<kocellvoltmax-0.005 and ocvsocmax1>max(ramcellsoc):
  433. #最大最小电压均在非平台区
  434. if ocvsocmax1<self.param.SocInflexion1:
  435. cellsocmin=ocvsocmin1
  436. cellsocmax=ocvsocmax1
  437. socstep=23
  438. #最小电压在非平台区,最大电压在平台区
  439. elif ocvsocmin1<self.param.SocInflexion1:
  440. cellsocmin=ocvsocmin1
  441. cellsocmax=cellsocmin+cellsoc_diff
  442. socstep=24
  443. else:
  444. cellsoc=ramcellsoc
  445. socstep=25
  446. else:
  447. cellsoc=ramcellsoc
  448. socstep=26
  449. #电压回弹方向一致
  450. else:
  451. cellsoc=ramcellsoc
  452. socstep=27
  453. #更新ko电压
  454. elif 70<standingtime<=130:
  455. cellsoc=ramcellsoc
  456. socstep=28
  457. cellvolt=self._cellvolt_get(df_bms_len-1)
  458. kocellvoltmin=min(cellvolt)
  459. kocellvoltmax=max(cellvolt)
  460. else:
  461. cellsoc=ramcellsoc+(as_accum*100)/(3600*capacity)
  462. socstep=29
  463. #更新ko电芯电压
  464. kocellvoltmin=0
  465. kocellvoltmax=0
  466. else:
  467. cellsocmin= self.bms_soc[df_bms_len-1]-cellsoc_diff/2
  468. cellsocmax= self.bms_soc[df_bms_len-1]+cellsoc_diff/2
  469. socstep=30
  470. #更新ko电芯电压
  471. kocellvoltmin=0
  472. kocellvoltmax=0
  473. #更新Ram电压.................
  474. ramcellvolt=self._cellvolt_get(df_bms_len-1)
  475. #单体Soc满充修正........................................................................................................................................................................
  476. cellvoltall=self.df_bms[self.cellvolt_name] #筛选所有单体电压
  477. cellvoltall_min=cellvoltall.min(axis=0) #每一个单体电芯的最小值
  478. 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:
  479. deltsoc=self.param.FullChrgSoc-max(cellsoc)
  480. cellsoc=cellsoc+deltsoc
  481. else:
  482. pass
  483. #计算所有电芯SOC...........................................................................................
  484. if not socstep in [8,17,21,22,25,26,27,28,29]:
  485. looktab_ocv=[min(cellocv),max(cellocv)]
  486. looktab_soc=[cellsocmin,cellsocmax]
  487. cellsoc=np.array(list(map(lambda x:np.interp(x,looktab_ocv,looktab_soc),cellocv)))
  488. else:
  489. pass
  490. #计算电池包packsoc和最大最小SOC..................................................................................................................................................................................
  491. cellsoc[cellsoc>100]=100 #限值最大值100
  492. cellsoc[cellsoc<0]=0 #限值最小值0
  493. cellsoc1=list(map(lambda x:eval(format(x,'.1f')), cellsoc))
  494. cellsocmin=min(cellsoc1)
  495. cellsocmax=max(cellsoc1)
  496. cellsoc_diff=cellsocmax-cellsocmin
  497. socmin_num=cellsoc1.index(cellsocmin)+1
  498. socmax_num=cellsoc1.index(cellsocmax)+1
  499. alpha=(cellsocmin+cellsocmax)*0.02-2 #blending系数计算
  500. if cellsocmax>90 or alpha>1:
  501. alpha=1
  502. elif cellsocmin<10 or alpha<-1:
  503. alpha=-1
  504. else:
  505. pass
  506. packsoc=(cellsocmin+cellsocmax)*0.5+(cellsocmax-cellsocmin)*0.5*alpha
  507. packsoc=eval(format(packsoc,'.1f'))
  508. socdsp=packsoc
  509. #输出ram结果....................................................................................................................................................................
  510. 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]
  511. df_ram=pd.DataFrame(columns=self.df_ram_sn.columns)
  512. df_ram.loc[0]=list_ram
  513. #输出计算结果........................................................................................................................................................................
  514. 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]
  515. return df_res, df_ram