CBMSBatSoc.py 32 KB

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