|
@@ -5,6 +5,8 @@ import bisect
|
|
|
import matplotlib.pyplot as plt
|
|
|
from LIB.MIDDLE.CellStateEstimation.SOH.V1_0_0 import BatParam
|
|
|
from LIB.MIDDLE.CellStateEstimation.SOH.V1_0_0 import DBDownload
|
|
|
+import BatParam
|
|
|
+import DBDownload
|
|
|
|
|
|
class BatSoh:
|
|
|
def __init__(self,sn,celltype,df_bms,df_accum, host, port, db, user, password, tablename): #参数初始化
|
|
@@ -31,7 +33,7 @@ class BatSoh:
|
|
|
self.tablename=tablename
|
|
|
|
|
|
def batsoh(self):
|
|
|
- if self.celltype==1 or self.celltype==2:
|
|
|
+ if self.celltype==1 or self.celltype==2 or self.celltype==3 or self.celltype==4:
|
|
|
df_res=self._ncmsoh_twopoint()
|
|
|
return df_res
|
|
|
|
|
@@ -39,8 +41,10 @@ class BatSoh:
|
|
|
df_res=self._lfpsoh()
|
|
|
return df_res
|
|
|
|
|
|
- def getdata(self): #获取已有soh结果
|
|
|
+ else:
|
|
|
+ return pd.DataFrame()
|
|
|
|
|
|
+ def getdata(self): #获取预算结果库的结果
|
|
|
DBManager=DBDownload.DBDownload(self.host, self.port, self.db, self.user, self.password)
|
|
|
with DBManager as DBManager:
|
|
|
self.df_soh=DBManager.getdata('time_st','time_sp','sn','method','soh','cellsoh', tablename='soh_result', sn=self.sn)
|
|
@@ -115,7 +119,7 @@ class BatSoh:
|
|
|
for j in range(1, self.param.CellVoltNums+1):
|
|
|
s = str(j)
|
|
|
cellvolt.append(self.df_bms.loc[num,'单体电压' + s]/1000)
|
|
|
- return(cellvolt)
|
|
|
+ return cellvolt
|
|
|
|
|
|
def _ncmsoh_chrg(self): #NCM充电数据soh计算
|
|
|
self._chrgdata()
|
|
@@ -188,7 +192,7 @@ class BatSoh:
|
|
|
for i in range(3,len(self.df_bms)-3):
|
|
|
|
|
|
if abs(self.packcrnt[i]) < 0.3: #电流为0
|
|
|
- delttime=(self.bmstime[i+1]-self.bmstime[1]).total_seconds()
|
|
|
+ delttime=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
|
|
|
standingtime=standingtime+delttime
|
|
|
self._celltemp_weight(i) #获取不同温度对应的静置时间
|
|
|
|
|
@@ -297,17 +301,12 @@ class BatSoh:
|
|
|
elif abs(ah_accum_tatol-ah_packcrnt) < self.param.Capacity/10:
|
|
|
soh_weight1=soh_weight1*0.8
|
|
|
else:
|
|
|
- soh_weight1=0.5
|
|
|
+ soh_weight1=soh_weight1*0.5
|
|
|
else:
|
|
|
if self.param.Capacity*0.7*0.4< abs(ah_packcrnt) <self.param.Capacity:
|
|
|
soh_weight1=soh_weight1*0.5
|
|
|
else:
|
|
|
soh_weight1=0
|
|
|
-
|
|
|
- if ah_packcrnt_chg + ah_packcrnt_dis > self.param.Capacity: #总Ah数对结果的影响
|
|
|
- soh_weight1=soh_weight1*0.6
|
|
|
- else:
|
|
|
- soh_weight1=soh_weight1
|
|
|
|
|
|
cellsoh=[]
|
|
|
for j in range(self.param.CellVoltNums): #计算每个电芯的SOH值
|
|
@@ -322,16 +321,21 @@ class BatSoh:
|
|
|
if len(df_res)<1:
|
|
|
if not self.df_soh.empty:
|
|
|
cellsoh_last=eval(self.df_soh.loc[len(self.df_soh)-1,'cellsoh'])
|
|
|
- cellsoh_cal=cellsoh_init*soh_weight + cellsoh_last[j]*(1-soh_weight)
|
|
|
+ if soh_weight>1/abs(cellsoh_init-cellsoh_last):
|
|
|
+ soh_weight=1/abs(cellsoh_init-cellsoh_last)
|
|
|
+ cellsoh_cal=cellsoh_init*soh_weight + cellsoh_last[j]*(1-soh_weight)
|
|
|
+ else:
|
|
|
+ cellsoh_cal=cellsoh_init*soh_weight + cellsoh_last[j]*(1-soh_weight)
|
|
|
else:
|
|
|
cellsoh_cal=cellsoh_init*soh_weight+100*(1-soh_weight)
|
|
|
else:
|
|
|
cellsoh_last=eval(df_res.loc[len(df_res)-1,'cellsoh'])
|
|
|
- if abs(cellsoh_init-cellsoh_last[j])<10:
|
|
|
- cellsoh_cal=cellsoh_init*soh_weight*0.5 + cellsoh_last[j]*(1-soh_weight*0.5)
|
|
|
+ if soh_weight>1/abs(cellsoh_init-cellsoh_last[j]):
|
|
|
+ soh_weight=1/abs(cellsoh_init-cellsoh_last[j])
|
|
|
+ cellsoh_cal=cellsoh_init*soh_weight + cellsoh_last[j]*(1-soh_weight)
|
|
|
else:
|
|
|
- soh_weight=soh_weight*0.2
|
|
|
- cellsoh_cal=cellsoh_init*soh_weight*0.5 + cellsoh_last[j]*(1-soh_weight*0.5)
|
|
|
+ cellsoh_cal=cellsoh_init*soh_weight + cellsoh_last[j]*(1-soh_weight)
|
|
|
+ cellsoh_cal=eval(format(cellsoh_cal,'.1f'))
|
|
|
cellsoh.append(cellsoh_cal)
|
|
|
else:
|
|
|
cellsoh=[]
|
|
@@ -364,7 +368,7 @@ class BatSoh:
|
|
|
|
|
|
#获取两点法法所需数据-开始
|
|
|
if abs(self.packcrnt[i]) < 0.2: #判断非平台区静置状态
|
|
|
- delttime=(self.bmstime[i+1]-self.bmstime[i]).total_seconds()
|
|
|
+ delttime=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
|
|
|
standingtime=standingtime+delttime
|
|
|
self._celltemp_weight(i) #获取不同温度对应的静置时间
|
|
|
|
|
@@ -529,7 +533,7 @@ class BatSoh:
|
|
|
if delt_days<=1: #两次时间间隔对计算结果的影响
|
|
|
soh_weight=1
|
|
|
elif delt_days<=2:
|
|
|
- soh_weight=0.9
|
|
|
+ soh_weight=0.7
|
|
|
elif delt_days<=3:
|
|
|
soh_weight=0.4
|
|
|
else:
|
|
@@ -547,10 +551,6 @@ class BatSoh:
|
|
|
soh_weight=soh_weight*0.5
|
|
|
else:
|
|
|
soh_weight=0
|
|
|
- if ah_accum_dis+ah_accum_chg>self.param.Capacity:
|
|
|
- soh_weight=soh_weight*0.6
|
|
|
- else:
|
|
|
- soh_weight=soh_weight
|
|
|
|
|
|
delt_ocv_soc=ocv_soc2-ocv_soc1
|
|
|
delt_ocv_soc_weight=self._deltsoc_weight(abs(delt_ocv_soc))
|
|
@@ -560,17 +560,23 @@ class BatSoh:
|
|
|
if cellsoh_init>65 and cellsoh_init<115: #判断soh值的有效区间
|
|
|
if len(df_res)<1:
|
|
|
if not self.df_soh.empty:
|
|
|
- cellsoh_cal=cellsoh_init*soh_weight + list(self.df_soh['soh'])[-1]*(1-soh_weight)
|
|
|
+ cellsoh_last=self.df_soh.loc[len(self.df_soh)-1,'soh']
|
|
|
+ if soh_weight>1/abs(cellsoh_init-cellsoh_last):
|
|
|
+ soh_weight=1/abs(cellsoh_init-cellsoh_last)
|
|
|
+ cellsoh_cal=cellsoh_init*soh_weight + cellsoh_last*(1-soh_weight)
|
|
|
+ else:
|
|
|
+ cellsoh_cal=cellsoh_init*soh_weight + cellsoh_last*(1-soh_weight)
|
|
|
else:
|
|
|
cellsoh_cal=cellsoh_init*soh_weight+100*(1-soh_weight)
|
|
|
else:
|
|
|
cellsoh_last=df_res.loc[len(df_res)-1,'soh']
|
|
|
- if abs(cellsoh_init-cellsoh_last)<10:
|
|
|
+ if soh_weight>1/abs(cellsoh_init-cellsoh_last):
|
|
|
+ soh_weight=1/abs(cellsoh_init-cellsoh_last)
|
|
|
cellsoh_cal=cellsoh_init*soh_weight + cellsoh_last*(1-soh_weight)
|
|
|
else:
|
|
|
- soh_weight=soh_weight*0.1
|
|
|
cellsoh_cal=cellsoh_init*soh_weight + cellsoh_last*(1-soh_weight)
|
|
|
-
|
|
|
+
|
|
|
+ cellsoh_cal=eval(format(cellsoh_cal,'.1f'))
|
|
|
soh_list=[timepoint_bms_st, timepoint_bms_sp, self.sn, 1, cellsoh_cal, str(cellsoh_cal)]
|
|
|
df_res.loc[len(df_res)]=soh_list
|
|
|
else:
|
|
@@ -618,7 +624,7 @@ class BatSoh:
|
|
|
start_time=df_Data1.loc[0,'time']
|
|
|
start_time=start_time+datetime.timedelta(seconds=900)
|
|
|
end_time=df_Data1.loc[len(time2)-1,'time']
|
|
|
- end_time=end_time-datetime.timedelta(seconds=1500)
|
|
|
+ end_time=end_time-datetime.timedelta(seconds=1200)
|
|
|
if soc2[0]<40:
|
|
|
df_Data1=df_Data1[(df_Data1['SOC']>43) & (df_Data1['time']<end_time)]
|
|
|
else:
|
|
@@ -626,10 +632,19 @@ class BatSoh:
|
|
|
|
|
|
# ax1 = plt.subplot(3, 1, 1)
|
|
|
# plt.plot(df_Data1['XVOLT'],df_Data1['DVDQ'],'r*-')
|
|
|
+ # plt.xlabel('Volt/V')
|
|
|
+ # plt.ylabel('DV/DQ')
|
|
|
+ # plt.legend()
|
|
|
# ax1 = plt.subplot(3, 1, 2)
|
|
|
# plt.plot(df_Data1['SOC'],df_Data1['XVOLT'],'y*-')
|
|
|
+ # plt.xlabel('SOC/%')
|
|
|
+ # plt.ylabel('Volt/V')
|
|
|
+ # plt.legend()
|
|
|
# ax1 = plt.subplot(3, 1, 3)
|
|
|
# plt.plot(df_Data1['SOC'], df_Data1['DVDQ'], 'r*-')
|
|
|
+ # plt.xlabel('SOC/%')
|
|
|
+ # plt.ylabel('DV/DQ')
|
|
|
+ # plt.legend()
|
|
|
# plt.show()
|
|
|
|
|
|
#寻找峰值并计算Soh和置信度
|
|
@@ -670,21 +685,27 @@ class BatSoh:
|
|
|
else:
|
|
|
continue
|
|
|
|
|
|
- soh_weight=tempweightlist2[i]*0.5
|
|
|
+ soh_weight=tempweightlist2[i]*0.25
|
|
|
if cellsoh_init>65 and cellsoh_init<115: #判断soh值的有效区间
|
|
|
if len(df_res)<1:
|
|
|
- if not self.df_soh.empty and self.df_soh.shape[1]>10:
|
|
|
- cellsoh_cal=cellsoh_init*soh_weight + list(self.df_soh['soh'])[-1]*(1-soh_weight)
|
|
|
+ if not self.df_soh.empty:
|
|
|
+ cellsoh_last=self.df_soh.loc[len(self.df_soh)-1,'soh']
|
|
|
+ if soh_weight>1/abs(cellsoh_init-cellsoh_last):
|
|
|
+ soh_weight=1/abs(cellsoh_init-cellsoh_last)
|
|
|
+ cellsoh_cal=cellsoh_init*soh_weight + cellsoh_last*(1-soh_weight)
|
|
|
+ else:
|
|
|
+ cellsoh_cal=cellsoh_init*soh_weight + cellsoh_last*(1-soh_weight)
|
|
|
else:
|
|
|
cellsoh_cal=cellsoh_init*soh_weight+100*(1-soh_weight)
|
|
|
else:
|
|
|
cellsoh_last=df_res.loc[len(df_res)-1,'soh']
|
|
|
- if abs(cellsoh_init-cellsoh_last)<10:
|
|
|
+ if soh_weight>1/abs(cellsoh_init-cellsoh_last):
|
|
|
+ soh_weight=1/abs(cellsoh_init-cellsoh_last)
|
|
|
cellsoh_cal=cellsoh_init*soh_weight + cellsoh_last*(1-soh_weight)
|
|
|
else:
|
|
|
- soh_weight=soh_weight*0.2
|
|
|
cellsoh_cal=cellsoh_init*soh_weight + cellsoh_last*(1-soh_weight)
|
|
|
|
|
|
+ cellsoh_cal=eval(format(cellsoh_cal,'.1f'))
|
|
|
soh_list=[self.bmstime[chrg_start[i]], self.bmstime[chrg_end[i]], self.sn, 2, cellsoh_cal, str(cellsoh_cal)]
|
|
|
df_res.loc[len(df_res)]=soh_list
|
|
|
else:
|