CBMSBatSoc.py 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  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. else:
  117. as_accum=as_accum+((self.bms_soc[i]-self.df_ram_sn.iloc[-1]['bms_soc'])*capacity*3600/100)
  118. else:
  119. step=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
  120. if abs(self.packcrnt[i])<0.1 and abs(self.packcrnt[i-1])<0.1:
  121. standingtime=standingtime+step
  122. as_accum=as_accum-self.packcrnt[i]*step
  123. else:
  124. standingtime=0
  125. as_accum=as_accum-self.packcrnt[i]*step
  126. else:
  127. standingtime=0
  128. as_accum=0
  129. for i in range(df_bms_len):
  130. if i==0:
  131. pass
  132. else:
  133. step=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
  134. if abs(self.packcrnt[i])<0.1 and abs(self.packcrnt[i-1])<0.1:
  135. standingtime=standingtime+step
  136. as_accum=as_accum-self.packcrnt[i]*step
  137. else:
  138. standingtime=0
  139. as_accum=as_accum-self.packcrnt[i]*step
  140. if standingtime>3600*24*30:
  141. standingtime=3600*24*30
  142. else:
  143. pass
  144. #计算单体SOC.............................................................................................................................
  145. if not self.df_ram_sn.empty:
  146. self._celltemp_weight(0)
  147. ramcellvolt=self.df_ram_sn.iloc[-1]['ramcellvolt']
  148. ramcellsoc=self.df_ram_sn.iloc[-1]['cellsoc']
  149. ocvweight_2dlook=interp2d(self.param.OcvWeight_StandingTime, self.param.OcvWeight_Temp, self.param.OcvWeight, kind = 'linear')
  150. ocvweight=ocvweight_2dlook(standingtime, self.celltemp)
  151. ocvweight=ocvweight[0]
  152. if self.bmstime[0]>datetime.datetime.strptime('2021-10-22 19:49:20','%Y-%m-%d %H:%M:%S'):
  153. pass
  154. if ocvweight>0.01:
  155. cellocv=self._ocv_dispersion()
  156. if df_bms_len>1: #数据字段长度≥2
  157. if 2<max(cellocv)<4.5 and 2<min(cellocv)<4.5:
  158. ocvsoc=np.array(list(map(lambda x:np.interp(x,self.param.LookTab_OCV,self.param.LookTab_SOC),cellocv)))
  159. cellsoc=ocvsoc*ocvweight+ramcellsoc*(1-ocvweight)
  160. socstep=0
  161. else:
  162. cellsoc=ramcellsoc
  163. socstep=1
  164. else: #数据字段长度==1
  165. if 2<max(cellocv)<4.5 and 2<min(cellocv)<4.5 and max(abs(ramcellvolt-np.array(cellocv)))<0.004:
  166. ocvsoc=np.array(list(map(lambda x:np.interp(x,self.param.LookTab_OCV,self.param.LookTab_SOC),cellocv)))
  167. cellsoc=ocvsoc*ocvweight+ramcellsoc*(1-ocvweight)
  168. socstep=2
  169. else:
  170. cellsoc=ramcellsoc
  171. socstep=3
  172. else:
  173. cellsoc=ramcellsoc+(as_accum*100)/(3600*capacity)
  174. socstep=4
  175. else:
  176. cellsoc= np.array([self.bms_soc[df_bms_len-1]])+np.random.rand(self.param.CellVoltNums)
  177. socstep=5
  178. #更新ram电芯电压
  179. ramcellvolt=self._cellvolt_get(df_bms_len-1)
  180. #单体Soc满充修正........................................................................................................................................................................
  181. cellvoltall=self.df_bms[self.cellvolt_name] #筛选所有单体电压
  182. cellvoltall_min=cellvoltall.min(axis=0) #每一个单体电芯的最小值
  183. 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:
  184. deltsoc=self.param.FullChrgSoc-max(cellsoc)
  185. cellsoc=cellsoc+deltsoc
  186. else:
  187. pass
  188. #计算电池包packsoc和最大最小SOC..................................................................................................................................................................................
  189. cellsoc[cellsoc>100]=100 #限值最大值100
  190. cellsoc[cellsoc<0]=0 #限值最小值0
  191. cellsoc1=list(map(lambda x:float(format(x,'.1f')), cellsoc))
  192. cellsocmin=min(cellsoc1)
  193. cellsocmax=max(cellsoc1)
  194. cellsoc_diff=cellsocmax-cellsocmin
  195. socmin_num=cellsoc1.index(cellsocmin)+1
  196. socmax_num=cellsoc1.index(cellsocmax)+1
  197. alpha=(cellsocmin+cellsocmax)*0.02-2 #blending系数计算
  198. if cellsocmax>90 or alpha>1:
  199. alpha=1
  200. elif cellsocmin<10 or alpha<-1:
  201. alpha=-1
  202. else:
  203. pass
  204. packsoc=(cellsocmin+cellsocmax)*0.5+(cellsocmax-cellsocmin)*0.5*alpha
  205. packsoc=eval(format(packsoc,'.1f'))
  206. socdsp=packsoc
  207. #输出ram结果....................................................................................................................................................................
  208. 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]
  209. df_ram=pd.DataFrame(columns=self.df_ram_sn.columns)
  210. df_ram.loc[0]=list_ram
  211. #输出计算结果........................................................................................................................................................................
  212. 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]
  213. return df_res, df_ram
  214. #...........................................................磷酸铁锂电池的soc计算...............................................................................................
  215. def _lfp_soc(self):
  216. column_name=['time', 'sn', 'bms_soc', 'packsoc', 'socdsp', 'cellsocmin', 'cellsocmax','socmin_num','socmax_num','cellsoc_diff','cellsoc','ocvweight','socstep']
  217. df_res=pd.DataFrame(columns=column_name)
  218. df_bms_len=len(self.df_bms)
  219. rampackcrnt=self.packcrnt[df_bms_len-1]
  220. if not self.df_socdiff.empty:
  221. cellsoc_diff=self.df_socdiff.iloc[-1]['cellsoc_diff']
  222. else:
  223. cellsoc_diff=2
  224. #获取电池包SOH................................................................................................
  225. if self.df_soh.empty:
  226. batsoh=self.bms_soh[0]
  227. capacity=self.param.Capacity*batsoh/100
  228. else:
  229. batsoh=self.df_soh.loc[0,'soh']
  230. capacity=self.param.Capacity*batsoh/100
  231. #计算静置时间和累计As量以及OCV权重值..................................................................................................
  232. if not self.df_ram_sn.empty:
  233. standingtime=self.df_ram_sn.iloc[-1]['standingtime']
  234. ocvweight=self.df_ram_sn.iloc[-1]['ocvweight']
  235. as_accum=0
  236. for i in range(df_bms_len):
  237. if i==0:
  238. step=(self.bmstime[i]-self.df_ram_sn.iloc[-1]['time']).total_seconds()
  239. if abs(self.packcrnt[i])<0.1 and abs(self.df_ram_sn.iloc[-1]['rampackcrnt'])<0.1:
  240. standingtime=standingtime+step
  241. else:
  242. standingtime=0
  243. if step<120:
  244. as_accum=as_accum-self.packcrnt[i]*step
  245. else:
  246. as_accum=as_accum+((self.bms_soc[i]-self.df_ram_sn.iloc[-1]['bms_soc'])*capacity*3600/100)
  247. else:
  248. step=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
  249. if abs(self.packcrnt[i])<0.1 and abs(self.packcrnt[i-1])<0.1:
  250. standingtime=standingtime+step
  251. as_accum=as_accum-self.packcrnt[i]*step
  252. else:
  253. standingtime=0
  254. as_accum=as_accum-self.packcrnt[i]*step
  255. else:
  256. standingtime=0
  257. ocvweight=0.5
  258. as_accum=0
  259. for i in range(df_bms_len):
  260. if i==0:
  261. pass
  262. else:
  263. step=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
  264. if abs(self.packcrnt[i])<0.1 and abs(self.packcrnt[i-1])<0.1:
  265. standingtime=standingtime+step
  266. as_accum=as_accum-self.packcrnt[i]*step
  267. else:
  268. standingtime=0
  269. as_accum=as_accum-self.packcrnt[i]*step
  270. #静置时间限值..............................................
  271. if standingtime>3600*24*30:
  272. standingtime=3600*24*30
  273. else:
  274. pass
  275. #权重值计算.................................................
  276. ocvweight=ocvweight-as_accum*10/(capacity*3600)
  277. if ocvweight>1:
  278. ocvweight=1
  279. elif ocvweight<0:
  280. ocvweight=0
  281. else:
  282. pass
  283. ocvweight=eval(format(ocvweight,'.2f'))
  284. #计算单体最大最小SOC.............................................................................................................................
  285. cellocv=self._ocv_dispersion() #获取每一列电压的平均值
  286. if not self.df_ram_sn.empty:
  287. self._celltemp_weight(0)
  288. kocellvoltmin=self.df_ram_sn.iloc[-1]['kocellvoltmin']
  289. kocellvoltmax=self.df_ram_sn.iloc[-1]['kocellvoltmax']
  290. ramcellsoc=self.df_ram_sn.iloc[-1]['cellsoc']
  291. #满足静置时间
  292. if standingtime>self.StandardStandingTime:
  293. #数据字段长度≥2...............................................................................................................
  294. if df_bms_len>1:
  295. ocvsocmin=np.interp(min(cellocv),self.param.LookTab_OCV,self.param.LookTab_SOC)
  296. ocvsocmax=np.interp(max(cellocv),self.param.LookTab_OCV,self.param.LookTab_SOC)
  297. if 2<min(cellocv)<self.param.OcvInflexionBelow and 2<max(cellocv)<self.param.OcvInflexionBelow and ocvsocmax<self.param.SocInflexion1:
  298. cellsocmin=ocvsocmin
  299. cellsocmax=ocvsocmax
  300. socstep=0
  301. elif 2<min(cellocv)<self.param.OcvInflexionBelow and max(cellocv)>=self.param.OcvInflexionBelow and ocvsocmin<self.param.SocInflexion1:
  302. cellsocmin=ocvsocmin
  303. cellsocmax=ocvsocmin+cellsoc_diff
  304. socstep=1
  305. else:
  306. #第一平台向第二平台修正
  307. if ocvsocmax>self.param.SocInflexion3+5 and max(ramcellsoc)<self.param.SocInflexion2-5:
  308. if ocvsocmin>self.param.SocInflexion3+5 and min(ramcellsoc)<self.param.SocInflexion2-5:
  309. cellsocmin=self.param.SocInflexion3
  310. cellsocmax=cellsocmin+cellsoc_diff
  311. socstep=2
  312. else:
  313. cellsocmax=self.param.SocInflexion3
  314. cellsocmin=cellsocmax-cellsoc_diff
  315. socstep=3
  316. #第一非平台区向第一平台区修正
  317. elif ocvsocmax>self.param.SocInflexion1+5 and max(ramcellsoc)<self.param.SocInflexion1-2:
  318. if ocvsocmin>self.param.SocInflexion1+5 and min(ramcellsoc)<self.param.SocInflexion1-2:
  319. cellsocmin=self.param.SocInflexion1
  320. cellsocmax=cellsocmin+cellsoc_diff
  321. socstep=4
  322. else:
  323. cellsocmax=self.param.SocInflexion1
  324. cellsocmin=cellsocmax-cellsoc_diff
  325. socstep=5
  326. #第二平台区向第一平台区修正
  327. elif ocvsocmin<self.param.SocInflexion2-5 and min(ramcellsoc)>self.param.SocInflexion3+5:
  328. if ocvsocmax<self.param.SocInflexion2-5 and max(ramcellsoc)>self.param.SocInflexion3+5:
  329. cellsocmax=self.param.SocInflexion2
  330. cellsocmin=cellsocmax-cellsoc_diff
  331. socstep=6
  332. else:
  333. cellsocmin=self.param.SocInflexion2
  334. cellsocmax=cellsocmin+cellsoc_diff
  335. socstep=7
  336. else:
  337. cellsoc=ramcellsoc
  338. socstep=8
  339. #数据字段长度==1..............................................................................................
  340. else:
  341. cellvolt0=self._cellvolt_get(0)
  342. ramcellvolt=self.df_ram_sn.iloc[-1]['ramcellvolt']
  343. if max(abs(cellvolt0-ramcellvolt))<0.004:
  344. ocvmax=max(cellvolt0)
  345. ocvmin=min(cellvolt0)
  346. ocvsocmin=np.interp(ocvmin,self.param.LookTab_OCV,self.param.LookTab_SOC)
  347. ocvsocmax=np.interp(ocvmax,self.param.LookTab_OCV,self.param.LookTab_SOC)
  348. if 2<ocvmin<self.param.OcvInflexionBelow and 2<ocvmax<self.param.OcvInflexionBelow and ocvsocmax<self.param.SocInflexion1:
  349. cellsocmin=ocvsocmin
  350. cellsocmax=ocvsocmax
  351. socstep=9
  352. elif 2<ocvmin<self.param.OcvInflexionBelow and ocvmax>=self.param.OcvInflexionBelow and ocvsocmin<self.param.SocInflexion1:
  353. cellsocmin=ocvsocmin
  354. cellsocmax=ocvsocmin+cellsoc_diff
  355. socstep=10
  356. else:
  357. #第一平台向第二平台修正
  358. if ocvsocmax>self.param.SocInflexion3+5 and max(ramcellsoc)<self.param.SocInflexion2-5:
  359. if ocvsocmin>self.param.SocInflexion3+5 and min(ramcellsoc)<self.param.SocInflexion2-5:
  360. cellsocmin=self.param.SocInflexion3
  361. cellsocmax=cellsocmin+cellsoc_diff
  362. socstep=11
  363. else:
  364. cellsocmax=self.param.SocInflexion3
  365. cellsocmin=cellsocmax-cellsoc_diff
  366. socstep=12
  367. #第一非平台区向第一平台区修正
  368. elif ocvsocmax>self.param.SocInflexion1+5 and max(ramcellsoc)<self.param.SocInflexion1-2:
  369. if ocvsocmin>self.param.SocInflexion1+5 and min(ramcellsoc)<self.param.SocInflexion1-2:
  370. cellsocmin=self.param.SocInflexion1
  371. cellsocmax=cellsocmin+cellsoc_diff
  372. socstep=13
  373. else:
  374. cellsocmax=self.param.SocInflexion1
  375. cellsocmin=cellsocmax-cellsoc_diff
  376. socstep=14
  377. #第二平台区向第一平台区修正
  378. elif ocvsocmin<self.param.SocInflexion2-5 and min(ramcellsoc)>self.param.SocInflexion3+5:
  379. if ocvsocmax<self.param.SocInflexion2-5 and max(ramcellsoc)>self.param.SocInflexion3+5:
  380. cellsocmax=self.param.SocInflexion2
  381. cellsocmin=cellsocmax-cellsoc_diff
  382. socstep=15
  383. else:
  384. cellsocmin=self.param.SocInflexion2
  385. cellsocmax=cellsocmin+cellsoc_diff
  386. socstep=16
  387. else:
  388. cellsoc=ramcellsoc
  389. socstep=17
  390. else:
  391. cellsoc=ramcellsoc
  392. socstep=17
  393. #不满足静置时间,判断电压回弹方向
  394. elif standingtime>130 and 2<kocellvoltmax<4.5 and 2<kocellvoltmin<4.5:
  395. cellvoltmin=min(cellocv)
  396. cellvoltmax=max(cellocv)
  397. ocvsocmin1=np.interp(cellvoltmin,self.param.LookTab_OCV,self.param.LookTab_SOC)
  398. ocvsocmax1=np.interp(cellvoltmax,self.param.LookTab_OCV,self.param.LookTab_SOC)
  399. #最大最小电压向上回弹
  400. if 2<cellvoltmin<4.5 and cellvoltmin>kocellvoltmin+0.005 and ocvsocmin1>min(ramcellsoc):
  401. if 2<cellvoltmax<4.5 and cellvoltmax>kocellvoltmax+0.005 and ocvsocmax1>max(ramcellsoc):
  402. #最大最小电压均在非平台区
  403. if ocvsocmax1<self.param.SocInflexion1:
  404. cellsocmin=ocvsocmin1
  405. cellsocmax=ocvsocmax1
  406. socstep=18
  407. #最小电压均在非平台区,最大电压在平台区
  408. elif ocvsocmin1<self.param.SocInflexion1:
  409. cellsocmin=ocvsocmin1
  410. cellsocmax=cellsocmin+cellsoc_diff
  411. socstep=19
  412. #最大最小电压均在平台区,ramsoc在非平台区
  413. elif ocvsocmin1>self.param.SocInflexion1+5 and max(ramcellsoc)<self.param.SocInflexion1 and min(ramcellsoc)<self.param.SocInflexion1:
  414. cellsocmin=self.param.SocInflexion1
  415. cellsocmax=cellsocmin+cellsoc_diff
  416. socstep=20
  417. else:
  418. cellsoc=ramcellsoc
  419. socstep=21
  420. else:
  421. cellsoc=ramcellsoc
  422. socstep=22
  423. #最大最小电压向下回弹
  424. elif 2<cellvoltmin<4.5 and cellvoltmin<kocellvoltmin-0.005 and ocvsocmin1<min(ramcellsoc):
  425. if 2<cellvoltmax<4.5 and cellvoltmax<kocellvoltmax-0.005 and ocvsocmax1>max(ramcellsoc):
  426. #最大最小电压均在非平台区
  427. if ocvsocmax1<self.param.SocInflexion1:
  428. cellsocmin=ocvsocmin1
  429. cellsocmax=ocvsocmax1
  430. socstep=23
  431. #最小电压在非平台区,最大电压在平台区
  432. elif ocvsocmin1<self.param.SocInflexion1:
  433. cellsocmin=ocvsocmin1
  434. cellsocmax=cellsocmin+cellsoc_diff
  435. socstep=24
  436. else:
  437. cellsoc=ramcellsoc
  438. socstep=25
  439. else:
  440. cellsoc=ramcellsoc
  441. socstep=26
  442. #电压回弹方向一致
  443. else:
  444. cellsoc=ramcellsoc
  445. socstep=27
  446. #更新ko电压
  447. elif 70<standingtime<=130:
  448. cellsoc=ramcellsoc
  449. socstep=28
  450. cellvolt=self._cellvolt_get(df_bms_len-1)
  451. kocellvoltmin=min(cellvolt)
  452. kocellvoltmax=max(cellvolt)
  453. else:
  454. cellsoc=ramcellsoc+(as_accum*100)/(3600*capacity)
  455. socstep=29
  456. #更新ko电芯电压
  457. kocellvoltmin=0
  458. kocellvoltmax=0
  459. else:
  460. cellsocmin= self.bms_soc[df_bms_len-1]-cellsoc_diff/2
  461. cellsocmax= self.bms_soc[df_bms_len-1]+cellsoc_diff/2
  462. socstep=30
  463. #更新ko电芯电压
  464. kocellvoltmin=0
  465. kocellvoltmax=0
  466. #更新Ram电压.................
  467. ramcellvolt=self._cellvolt_get(df_bms_len-1)
  468. #单体Soc满充修正........................................................................................................................................................................
  469. cellvoltall=self.df_bms[self.cellvolt_name] #筛选所有单体电压
  470. cellvoltall_min=cellvoltall.min(axis=0) #每一个单体电芯的最小值
  471. 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:
  472. deltsoc=self.param.FullChrgSoc-max(cellsoc)
  473. cellsoc=cellsoc+deltsoc
  474. else:
  475. pass
  476. #计算所有电芯SOC...........................................................................................
  477. if not socstep in [8,17,21,22,25,26,27,28,29]:
  478. looktab_ocv=[min(cellocv),max(cellocv)]
  479. looktab_soc=[cellsocmin,cellsocmax]
  480. cellsoc=np.array(list(map(lambda x:np.interp(x,looktab_ocv,looktab_soc),cellocv)))
  481. else:
  482. pass
  483. #计算电池包packsoc和最大最小SOC..................................................................................................................................................................................
  484. cellsoc[cellsoc>100]=100 #限值最大值100
  485. cellsoc[cellsoc<0]=0 #限值最小值0
  486. cellsoc1=list(map(lambda x:eval(format(x,'.1f')), cellsoc))
  487. cellsocmin=min(cellsoc1)
  488. cellsocmax=max(cellsoc1)
  489. cellsoc_diff=cellsocmax-cellsocmin
  490. socmin_num=cellsoc1.index(cellsocmin)+1
  491. socmax_num=cellsoc1.index(cellsocmax)+1
  492. alpha=(cellsocmin+cellsocmax)*0.02-2 #blending系数计算
  493. if cellsocmax>90 or alpha>1:
  494. alpha=1
  495. elif cellsocmin<10 or alpha<-1:
  496. alpha=-1
  497. else:
  498. pass
  499. packsoc=(cellsocmin+cellsocmax)*0.5+(cellsocmax-cellsocmin)*0.5*alpha
  500. packsoc=eval(format(packsoc,'.1f'))
  501. socdsp=packsoc
  502. #输出ram结果....................................................................................................................................................................
  503. 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]
  504. df_ram=pd.DataFrame(columns=self.df_ram_sn.columns)
  505. df_ram.loc[0]=list_ram
  506. #输出计算结果........................................................................................................................................................................
  507. 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]
  508. return df_res, df_ram