|
@@ -0,0 +1,122 @@
|
|
|
|
+import pandas as pd
|
|
|
|
+import numpy as np
|
|
|
|
+import datetime
|
|
|
|
+import time, datetime
|
|
|
|
+import scipy
|
|
|
|
+import math
|
|
|
|
+import itertools
|
|
|
|
+import log
|
|
|
|
+from scipy import interpolate
|
|
|
|
+from sklearn.linear_model import LinearRegression
|
|
|
|
+from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import BatParam
|
|
|
|
+
|
|
|
|
+class sor_est:
|
|
|
|
+ def __init__(self,sn,celltype,df_bms):
|
|
|
|
+
|
|
|
|
+ self.sn=sn
|
|
|
|
+ self.celltype=celltype
|
|
|
|
+ self.param=BatParam.BatParam(celltype)
|
|
|
|
+ self.df_bms=pd.DataFrame(df_bms)
|
|
|
|
+ self.packcrnt=df_bms['总电流[A]']*self.param.PackCrntDec
|
|
|
|
+ self.packvolt=df_bms['总电压[V]']
|
|
|
|
+ self.bms_soc=df_bms['SOC[%]']
|
|
|
|
+ self.bmstime= pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
|
|
|
|
+ self.LookTab_OCV = self.param.LookTab_OCV
|
|
|
|
+ self.LookTab_SOC = self.param.LookTab_SOC
|
|
|
|
+
|
|
|
|
+ self.cellvolt_list=['单体电压'+str(x) for x in range(1,self.param.CellVoltNums+1)]
|
|
|
|
+ self.celltemp_name=['单体温度'+str(x) for x in range(1,self.param.CellTempNums+1)]
|
|
|
|
+ self.bmssta = df_bms['充电状态']
|
|
|
|
+
|
|
|
|
+ def moving_average(interval, windowsize):
|
|
|
|
+ window = np.ones(int(windowsize)) / float(windowsize)
|
|
|
|
+ re = np.convolve(interval, window, 'same')
|
|
|
|
+ return re
|
|
|
|
+
|
|
|
|
+ def sor_cal(self):
|
|
|
|
+ start_time = time.time()
|
|
|
|
+ data = self.df_bms
|
|
|
|
+ data.fillna(0, inplace=True)
|
|
|
|
+ LookTab_OCV = self.LookTab_OCV
|
|
|
|
+ LookTab_SOC = self.LookTab_SOC
|
|
|
|
+ max_volt = max(LookTab_OCV)
|
|
|
|
+ min_volt = min(LookTab_OCV)
|
|
|
|
+ crnt = data['总电流[A]']
|
|
|
|
+ zero_group = itertools.groupby(crnt, lambda x : x == 0)
|
|
|
|
+ zero_flg = []
|
|
|
|
+ zero_value = []
|
|
|
|
+ for k, v in zero_group:
|
|
|
|
+ zero_flg.append(k)
|
|
|
|
+ zero_value.append(len(list(v)))
|
|
|
|
+ zero_flg_new = zero_flg.copy()
|
|
|
|
+ for item in range(0, len(zero_value)):
|
|
|
|
+ if (zero_flg[item] == True) & (zero_value[item] < 6):
|
|
|
|
+ zero_flg_new[item] = False
|
|
|
|
+ def get_index1(lst=None, item=''):
|
|
|
|
+ return [index for (index,value) in enumerate(lst) if value == item]
|
|
|
|
+ true_num = (get_index1(zero_flg_new, True))
|
|
|
|
+ zero_value_fit = []
|
|
|
|
+ true_num_flg = []
|
|
|
|
+ for item in range(len(true_num) - 1):
|
|
|
|
+ if ((true_num[item + 1] - true_num[item]) == 2):
|
|
|
|
+ true_num_flg.append(True)
|
|
|
|
+ true_num_flg.append(False)
|
|
|
|
+ zero_value_fit.append(zero_value[true_num[item]])
|
|
|
|
+ zero_value_fit.append(zero_value[true_num[item] + 1])
|
|
|
|
+ else:
|
|
|
|
+ true_num_flg.append(True)
|
|
|
|
+ true_num_flg.append(False)
|
|
|
|
+ zero_value_fit.append(zero_value[true_num[item]])
|
|
|
|
+ zero_value_fit.append(sum(zero_value[(true_num[item] + 1):(true_num[item + 1])]))
|
|
|
|
+ true_num_flg_fit = []
|
|
|
|
+ for item in range(1,len(zero_value_fit) + 1):
|
|
|
|
+ true_num_flg_fit.append(sum(zero_value_fit[0:item]) - 1)
|
|
|
|
+ true_num_flg_fit.insert(0,0)
|
|
|
|
+ soc_interplt = interpolate.interp1d(LookTab_OCV, LookTab_SOC, kind = 'linear')
|
|
|
|
+ cellvolt_name = self.cellvolt_list
|
|
|
|
+ celltemp_name = self.celltemp_name
|
|
|
|
+ df_sor_result = pd.DataFrame(columns = ["sn", "time", "sor", "sor_sigma", "soc", "temp", "delta_time"])
|
|
|
|
+ for range_num in range(0, len(true_num_flg) - 1):
|
|
|
|
+ sor_temp = []
|
|
|
|
+ df_time = pd.to_datetime(data['时间戳'])
|
|
|
|
+ delta_time = (df_time.iloc[true_num_flg_fit[range_num + 1]] - df_time.iloc[true_num_flg_fit[range_num] + 1])/pd.Timedelta(1, 'min')
|
|
|
|
+ if (true_num_flg[range_num] == True) & (delta_time > 10):
|
|
|
|
+ df_sor_soc_data = data.iloc[(true_num_flg_fit[range_num] + 1):(true_num_flg_fit[range_num + 1] + 1)]
|
|
|
|
+ df_sor_cal_temp = data.iloc[(true_num_flg_fit[range_num + 1] + 1):(true_num_flg_fit[range_num + 2] + 1)]
|
|
|
|
+ df_sor_cal_temp.reset_index(drop = True, inplace = True)
|
|
|
|
+ df_sor_cal_len = len(df_sor_cal_temp)
|
|
|
|
+ cal_range_num = true_num_flg_fit[range_num + 1] + 1
|
|
|
|
+ if df_sor_cal_len > 20:
|
|
|
|
+ df_sor_cal = df_sor_cal_temp.iloc[:30]
|
|
|
|
+ df_sor_time = pd.to_datetime(df_sor_cal['时间戳'])
|
|
|
|
+ delta_time_sor = (df_sor_time.iloc[-1] - df_sor_time.iloc[0])/pd.Timedelta(1, 'min')
|
|
|
|
+ df_soc_volt = df_sor_soc_data[cellvolt_name].iloc[-1]/1000
|
|
|
|
+ df_soc_volt[df_soc_volt > max_volt] = max_volt - 0.005
|
|
|
|
+ df_soc_volt[df_soc_volt < min_volt] = min_volt + 0.005
|
|
|
|
+ df_soc = soc_interplt(list(df_soc_volt))
|
|
|
|
+ df_sor_volt = df_sor_cal[cellvolt_name]/1000
|
|
|
|
+ df_sor_crnt = df_sor_cal['总电流[A]']
|
|
|
|
+ df_sorvolt_dif = np.diff(df_sor_volt, axis = 0)
|
|
|
|
+ df_sorcrnt_dif = np.diff(df_sor_crnt, axis = 0)
|
|
|
|
+ df_sorvolt_dif_csv = pd.DataFrame(df_sorvolt_dif)
|
|
|
|
+ df_sorvolt_dif_csv.columns = cellvolt_name
|
|
|
|
+ if np.sum(df_sorcrnt_dif != 0) > 0.5*len(df_sorcrnt_dif):
|
|
|
|
+ for item in cellvolt_name:
|
|
|
|
+ lineModel = LinearRegression()
|
|
|
|
+ lineModel.fit(np.array(df_sorcrnt_dif).reshape(-1, 1), df_sorvolt_dif_csv[item])
|
|
|
|
+ sor_temp.append(lineModel.coef_[0])
|
|
|
|
+ sor_sort_temp = np.sort(sor_temp)
|
|
|
|
+ sor_sort_del = sor_sort_temp[1:-2]
|
|
|
|
+ sor_sort_del_mean = np.mean(sor_sort_del)
|
|
|
|
+ sor_sort_del_std = np.std(sor_sort_del)
|
|
|
|
+ sor_sigma = list((sor_temp - sor_sort_del_mean)/sor_sort_del_std)
|
|
|
|
+ df_sor_result_temp = pd.DataFrame({"sn":[self.sn], "time":[df_sor_cal_temp['时间戳'][0]], "sor":[str(sor_temp)], "sor_sigma":[str(sor_sigma)],
|
|
|
|
+ "soc":[str(list(df_soc))], "temp":[str(list(df_sor_cal_temp[celltemp_name].iloc[0]))], "delta_time":[delta_time_sor]})
|
|
|
|
+ df_sor_result = df_sor_result.append(df_sor_result_temp)
|
|
|
|
+ df_sor_result.reset_index(drop = True, inplace = True)
|
|
|
|
+ end_time = time.time()
|
|
|
|
+ print(end_time - start_time)
|
|
|
|
+ if not df_sor_result.empty:
|
|
|
|
+ return df_sor_result
|
|
|
|
+ else:
|
|
|
|
+ return pd.DataFrame()
|