浏览代码

Merge remote-tracking branch 'origin/dev' into pro

lmstack 3 年之前
父节点
当前提交
f0222b27f0

+ 75 - 0
LIB/MIDDLE/CellStateEstimation/Uniform/V1_0_0/BatParam.py

@@ -0,0 +1,75 @@
+
+#定义电池参数
+from types import CellType
+import sys
+
+class BatParam:
+
+    def __init__(self,celltype):
+
+        # if 'PK500' in sn:
+        #     self.celltype=1 #6040三元电芯
+        # elif 'PK502' in sn:
+        #     self.celltype=2 #4840三元电芯
+        # elif 'PK504' in sn:
+        #     self.celltype=99    #60ah林磷酸铁锂电芯
+        # elif 'MGMLXN750' in sn:
+        #     self.celltype=3 #力信50ah三元电芯
+        # elif 'MGMCLN750' in sn: 
+        #     self.celltype=4 #CATL 50ah三元电芯
+        # else:
+        #     print('未找到对应电池编号!!!')
+        #     sys.exit()
+
+        if celltype==1: #6040
+            self.Capacity = 41
+            self.PackFullChrgVolt=69.99
+            self.CellFullChrgVolt=4.2
+            self.CellVoltNums=17
+            self.CellTempNums=4
+            self.FullChrgSoc=98
+            self.PeakSoc=57
+            self.LookTab_SOC = [0,	    3.5348,	8.3581,	13.181,	18.004,	22.827,	27.651,	32.474,	37.297,	42.120,	46.944,	51.767,	56.590,	61.413,	66.237,	71.060,	75.883,	80.707,	85.530,	90.353,	95.176,	100]
+            self.LookTab_OCV = [3.3159,	3.4384,	3.4774,	3.5156,	3.5478,	3.5748,	3.6058,	3.6238,	3.638,	3.6535,	3.6715,	3.6951,	3.7279,	3.7757,	3.8126,	3.8529,	3.8969,	3.9446,	3.9946,	4.0491,	4.109,	4.183]
+        
+        elif celltype==2: #4840
+            self.Capacity = 41
+            self.PackFullChrgVolt=69.99
+            self.CellFullChrgVolt=4.2
+            self.CellVoltNums=14
+            self.CellTempNums=4
+            self.FullChrgSoc=98
+            self.PeakSoc=57
+            self.LookTab_SOC = [0,	    3.5348,	8.3581,	13.181,	18.004,	22.827,	27.651,	32.474,	37.297,	42.120,	46.944,	51.767,	56.590,	61.413,	66.237,	71.060,	75.883,	80.707,	85.530,	90.353,	95.176,	100]
+            self.LookTab_OCV = [3.3159,	3.4384,	3.4774,	3.5156,	3.5478,	3.5748,	3.6058,	3.6238,	3.638,	3.6535,	3.6715,	3.6951,	3.7279,	3.7757,	3.8126,	3.8529,	3.8969,	3.9446,	3.9946,	4.0491,	4.109,	4.183]
+       
+        elif celltype==99:   #60ah磷酸铁锂电芯
+            self.Capacity = 54
+            self.PackFullChrgVolt=69.99
+            self.CellFullChrgVolt=3.5
+            self.OcvInflexionBelow=3.285
+            self.OcvInflexion2=3.296
+            self.OcvInflexion3=3.328
+            self.OcvInflexionAbove=3.4
+            self.CellVoltNums=20
+            self.CellTempNums=4
+            self.FullChrgSoc=98
+            self.PeakSoc=57
+            self.LookTab_SOC = [0.00, 	2.40, 	6.38, 	10.37, 	14.35, 	18.33, 	22.32, 	26.30, 	30.28, 	35.26, 	40.24, 	45.22, 	50.20, 	54.19, 	58.17, 	60.16, 	65.14, 	70.12, 	75.10, 	80.08, 	84.06, 	88.05, 	92.03, 	96.02, 	100.00]
+            self.LookTab_OCV = [2.7151,	3.0298,	3.1935,	3.2009,	3.2167,	3.2393,	3.2561,	3.2703,	3.2843,	3.2871,	3.2874,	3.2868,	3.2896,	3.2917,	3.2967,	3.3128,	3.3283,	3.3286,	3.3287,	3.3288,	3.3289,	3.3296,	3.3302,	3.3314,	3.3429]
+        
+        elif celltype==3:
+            self.Capacity = 51
+            self.PackFullChrgVolt=80
+            self.CellFullChrgVolt=4.2
+            self.CellVoltNums=20
+            self.CellTempNums=4
+            self.FullChrgSoc=98
+            self.PeakSoc=57
+            self.LookTab_SOC = [0,	    5,	    10,	    15,	    20,	    25,	    30,	    35,	    40,	    45,	    50,	    55,	    60,	    65,	    70,	    75,	    80,	    85,	    90,	    95,	    100]
+            self.LookTab_OCV = [3.357, 	3.455, 	3.493, 	3.540, 	3.577, 	3.605, 	3.622, 	3.638, 	3.655, 	3.677, 	3.707, 	3.757, 	3.815, 	3.866, 	3.920, 	3.976, 	4.036, 	4.099, 	4.166, 	4.237, 	4.325]
+        
+        else:
+            print('未找到对应电池编号!!!')
+            sys.exit()
+

+ 358 - 0
LIB/MIDDLE/CellStateEstimation/Uniform/V1_0_0/CBMSBatUniform.py

@@ -0,0 +1,358 @@
+import pandas as pd
+import numpy as np
+import datetime
+import bisect
+import matplotlib.pyplot as plt
+import BatParam
+
+class BatUniform:
+    def __init__(self,sn,celltype,df_bms):  #参数初始化
+
+        self.sn=sn
+        self.celltype=celltype
+        self.param=BatParam.BatParam(celltype)
+        self.df_bms=df_bms
+        self.packcrnt=df_bms['总电流[A]']
+        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')
+
+    def batuniform(self):
+        if self.celltype==1 or self.celltype==2:
+            df_res=self._ncm_uniform()
+            return df_res
+            
+        elif self.celltype==99:
+            df_res=self._lfp_uniform()
+            return df_res
+    
+    def _np_move_avg(self,a, n, mode="same"): #定义滑动滤波函数
+        return (np.convolve(a, np.ones((n,)) / n, mode=mode))
+    
+    def _celltemp_weight(self,num):   #寻找当前行数据的最小温度值
+        celltemp = []
+        for j in range(1, self.param.CellTempNums+1):
+            s = str(j)
+            celltemp.append(self.df_bms.loc[num,'单体温度' + s])
+        celltemp.remove(min(celltemp))
+        if self.celltype==99:
+            if min(celltemp)>=20:
+                self.tempweight=1
+                self.StandardStandingTime=600
+            elif min(celltemp)>=10:
+                self.tempweight=0.6
+                self.StandardStandingTime=900
+            elif min(celltemp)>=5:
+                self.tempweight=0.
+                self.StandardStandingTime=1800
+            else:
+                self.tempweight=0.1
+                self.StandardStandingTime=3600
+        else:
+            if min(celltemp)>=20:
+                self.tempweight=1
+                self.StandardStandingTime=300
+            elif min(celltemp)>=10:
+                self.tempweight=0.8
+                self.StandardStandingTime=600
+            elif min(celltemp)>=5:
+                self.tempweight=0.6
+                self.StandardStandingTime=1800
+            else:
+                self.tempweight=0.2
+                self.StandardStandingTime=3600
+
+    def _cellvolt_get(self,num): #获取当前行所有电压数据
+        cellvolt=[]
+        for j in range(1, self.param.CellVoltNums+1): 
+            s = str(j)
+            cellvolt.append(self.df_bms.loc[num,'单体电压' + s]/1000)
+        return(cellvolt)
+
+    def _dvdq_peak(self, time, soc, cellvolt, packcrnt):    #寻找DVDQ的峰值点,并返回
+        cellvolt1 = self._np_move_avg(cellvolt, 5, mode="same")
+        Soc = 0
+        Ah = 0
+        Volt = cellvolt1[0]
+        DV_Volt = []
+        DQ_Ah = []
+        DVDQ = []
+        time1 = []
+        soc1 = []
+        soc2 = []
+        xvolt=[]
+
+        for m in range(1, len(time)):
+            Step = (time[m] - time[m - 1]).total_seconds()
+            Soc = Soc - packcrnt[m] * Step * 100 / (3600 * self.param.Capacity)
+            Ah = Ah - packcrnt[m] * Step / 3600
+            if (cellvolt[m]-Volt)>0.99 and Ah>0:
+                DQ_Ah.append(Ah)
+                DV_Volt.append(cellvolt[m]-Volt)
+                DVDQ.append((DV_Volt[-1])/DQ_Ah[-1])
+                xvolt.append(cellvolt[m]/1000)
+                Volt=cellvolt[m]
+                Ah = 0
+                soc1.append(Soc)
+                time1.append(time[m])
+                soc2.append(soc[m])
+
+        #切片,去除前后10min的数据
+        df_Data1 = pd.DataFrame({'time': time1,
+                                'SOC': soc2,
+                                'DVDQ': DVDQ,
+                                'AhSoc': soc1,
+                                'DQ_Ah':DQ_Ah,
+                                'DV_Volt':DV_Volt,
+                                'XVOLT':xvolt})
+        start_time=df_Data1.loc[0,'time']
+        start_time=start_time+datetime.timedelta(seconds=600)
+        end_time=df_Data1.loc[len(time1)-1,'time']
+        end_time=end_time-datetime.timedelta(seconds=1200)
+        if soc2[0]<40 and soc2[-1]>93:
+            df_Data1=df_Data1[(df_Data1['SOC']>44) & (df_Data1['SOC']<90)]
+        elif soc2[0]<40 and soc2[-1]<=93:
+            df_Data1=df_Data1[(df_Data1['SOC']>44) & (df_Data1['time']<end_time)]
+        elif soc2[0]>=40 and soc2[-1]>93:
+            df_Data1=df_Data1[(df_Data1['time']>start_time) & (df_Data1['SOC']<90)]
+        else:
+            df_Data1=df_Data1[(df_Data1['time']>start_time) & (df_Data1['time']<end_time)]
+
+        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()
+
+        if len(df_Data1)>2:     #寻找峰值点,且峰值点个数>2
+            PeakIndex = df_Data1['DVDQ'].idxmax()
+            df_Data2 = df_Data1[(df_Data1['SOC'] > (df_Data1['SOC'][PeakIndex] - 0.5)) & (df_Data1['SOC'] < (df_Data1['SOC'][PeakIndex] + 0.5))]
+            if len(df_Data2) > 2:
+                return df_Data1['AhSoc'][PeakIndex]
+            else:
+                df_Data1 = df_Data1.drop([PeakIndex])
+                PeakIndex = df_Data1['DVDQ'].idxmax()
+                df_Data2 = df_Data1[(df_Data1['SOC'] > (df_Data1['SOC'][PeakIndex] - 0.5)) & (df_Data1['SOC'] < (df_Data1['SOC'][PeakIndex] + 0.5))]
+                if len(df_Data2) > 2:
+                    return df_Data1['AhSoc'][PeakIndex]
+                else:
+                    return 0
+        else:
+            return 0
+ 
+    def _ncm_uniform(self):
+        column_name=['time','sn','cellsoc_diff','cellvolt_diff','cellmin_num','cellmax_num']
+        df_res=pd.DataFrame(columns=column_name)
+        standingtime=0
+
+        for i in range(1,len(self.df_bms)-2):
+
+            if abs(self.packcrnt[i]) < 0.3:     #电流为0
+                delttime=(self.bmstime[i+1]-self.bmstime[i]).total_seconds()
+                standingtime=standingtime+delttime
+                self._celltemp_weight(i)     #获取不同温度对应的静置时间
+
+                if standingtime>self.StandardStandingTime:      #静置时间满足要求
+                    if abs(self.packcrnt[i+2]) >= 0.3:
+                        standingtime=0                    
+                        cellvolt_now=self._cellvolt_get(i)     #获取当前行电压数据
+                        cellvolt_min=min(cellvolt_now)
+                        cellvolt_max=max(cellvolt_now)
+                        cellmin_num=cellvolt_now.index(cellvolt_min)+1
+                        cellmax_num=cellvolt_now.index(cellvolt_max)+1
+                        cellsoc_min=np.interp(cellvolt_min,self.param.LookTab_OCV,self.param.LookTab_SOC)
+                        cellsoc_max=np.interp(cellvolt_max,self.param.LookTab_OCV,self.param.LookTab_SOC)
+                        cellvolt_diff=(cellvolt_max-cellvolt_min)*1000
+                        cellsoc_diff=cellsoc_max-cellsoc_min
+                        cellsoc_diff=format(cellsoc_diff,'.1f')
+                        cellvolt_diff=format(cellvolt_diff,'.0f')
+                        df_res.loc[len(df_res)]=[self.bmstime[i], self.sn, cellsoc_diff, cellvolt_diff, cellmin_num, cellmax_num]
+                    elif standingtime>3600*12:
+                        standingtime=0                    
+                        cellvolt_now=self._cellvolt_get(i)     #获取当前行电压数据
+                        cellvolt_min=min(cellvolt_now)
+                        cellvolt_max=max(cellvolt_now)
+                        cellmin_num=cellvolt_now.index(cellvolt_min)+1
+                        cellmax_num=cellvolt_now.index(cellvolt_max)+1
+                        cellsoc_min=np.interp(cellvolt_min,self.param.LookTab_OCV,self.param.LookTab_SOC)
+                        cellsoc_max=np.interp(cellvolt_max,self.param.LookTab_OCV,self.param.LookTab_SOC)
+                        cellvolt_diff=(cellvolt_max-cellvolt_min)*1000
+                        cellsoc_diff=cellsoc_max-cellsoc_min
+                        cellsoc_diff=format(cellsoc_diff,'.1f')
+                        cellvolt_diff=format(cellvolt_diff,'.0f')
+                        df_res.loc[len(df_res)]=[self.bmstime[i], self.sn, cellsoc_diff, cellvolt_diff, cellmin_num, cellmax_num]
+                    elif i>=len(self.df_bms)-4:
+                        standingtime=0
+                        cellvolt_now=self._cellvolt_get(i)     #获取当前行电压数据
+                        cellvolt_min=min(cellvolt_now)
+                        cellvolt_max=max(cellvolt_now)
+                        cellmin_num=cellvolt_now.index(cellvolt_min)+1
+                        cellmax_num=cellvolt_now.index(cellvolt_max)+1
+                        cellsoc_min=np.interp(cellvolt_min,self.param.LookTab_OCV,self.param.LookTab_SOC)
+                        cellsoc_max=np.interp(cellvolt_max,self.param.LookTab_OCV,self.param.LookTab_SOC)
+                        cellvolt_diff=(cellvolt_max-cellvolt_min)*1000
+                        cellsoc_diff=cellsoc_max-cellsoc_min
+                        cellsoc_diff=format(cellsoc_diff,'.1f')
+                        cellvolt_diff=format(cellvolt_diff,'.0f')
+                        df_res.loc[len(df_res)]=[self.bmstime[i], self.sn, cellsoc_diff, cellvolt_diff, cellmin_num, cellmax_num]
+                        break
+                    else:
+                        continue
+                else:
+                    continue
+            else:
+                standingtime=0
+                continue
+
+        if df_res.empty:    #返回计算结果
+            return pd.DataFrame()
+        else:
+            return df_res
+
+    def _lfp_uniform(self):
+        column_name=['time','sn','cellsoc_diff','cellvolt_diff','cellmin_num','cellmax_num']
+        df_res=pd.DataFrame(columns=column_name)
+        standingtime=0
+        chrg_start=[]
+        chrg_end=[]
+        charging=0
+
+        for i in range(3,len(self.df_bms)-3):
+
+            #静置电压法计算电芯一致性
+            if abs(self.packcrnt[i]) < 0.2:     #电流为0
+                delttime=(self.bmstime[i+1]-self.bmstime[i]).total_seconds()
+                standingtime=standingtime+delttime
+                self._celltemp_weight(i)     #获取不同温度对应的静置时间
+
+                if standingtime>self.StandardStandingTime:      #静置时间满足要求
+                    cellvolt_now=self._cellvolt_get(i)     #获取当前行电压数据
+                    cellvolt_min=min(cellvolt_now)
+                    cellvolt_max=max(cellvolt_now)
+                    if abs(self.packcrnt[i+2]) >= 0.2 and cellvolt_max < self.param.OcvInflexionBelow:     
+                        standingtime=0                   
+                        cellmin_num=cellvolt_now.index(cellvolt_min)+1
+                        cellmax_num=cellvolt_now.index(cellvolt_max)+1
+                        cellsoc_min=np.interp(cellvolt_min,self.param.LookTab_OCV,self.param.LookTab_SOC)
+                        cellsoc_max=np.interp(cellvolt_max,self.param.LookTab_OCV,self.param.LookTab_SOC)
+                        cellvolt_diff=(cellvolt_max-cellvolt_min)*1000
+                        cellsoc_diff=cellsoc_max-cellsoc_min
+                        cellsoc_diff=format(cellsoc_diff,'.1f')
+                        cellvolt_diff=format(cellvolt_diff,'.0f')
+                        df_res.loc[len(df_res)]=[self.bmstime[i], self.sn, cellsoc_diff, cellvolt_diff, cellmin_num, cellmax_num]
+                    elif i>=len(self.df_bms)-4 and cellvolt_max < self.param.OcvInflexionBelow:
+                        standingtime=0
+                        cellmin_num=cellvolt_now.index(cellvolt_min)+1
+                        cellmax_num=cellvolt_now.index(cellvolt_max)+1
+                        cellsoc_min=np.interp(cellvolt_min,self.param.LookTab_OCV,self.param.LookTab_SOC)
+                        cellsoc_max=np.interp(cellvolt_max,self.param.LookTab_OCV,self.param.LookTab_SOC)
+                        cellvolt_diff=(cellvolt_max-cellvolt_min)*1000
+                        cellsoc_diff=cellsoc_max-cellsoc_min
+                        cellsoc_diff=format(cellsoc_diff,'.1f')
+                        cellvolt_diff=format(cellvolt_diff,'.0f')
+                        df_res.loc[len(df_res)]=[self.bmstime[i], self.sn, cellsoc_diff, cellvolt_diff, cellmin_num, cellmax_num]
+                    else:
+                        pass
+                else:
+                    pass
+            else:
+                standingtime=0
+                pass   
+
+            #获取DVDQ算法所需数据——开始
+            if i==3 and self.packcrnt[1]<=-1 and self.packcrnt[2]<=-1 and self.packcrnt[3]<=-1:
+                chrg_start.append(i)
+                charging=1
+            elif self.packcrnt[i-1]>-1 and self.packcrnt[i]<=-1 and self.packcrnt[i+1]<=-1 and self.packcrnt[i+2]<=-1:     #判断充电开始
+                if self.bms_soc[i]<45:
+                    charging=1
+                    if len(chrg_start)>len(chrg_end):
+                        chrg_start[-1]=i
+                    else:
+                        chrg_start.append(i)
+                else:
+                    pass
+            else:
+                pass
+
+            if charging==1: #充电中
+                if (self.bmstime[i+1]-self.bmstime[i]).total_seconds()>180:  #如果充电过程中时间间隔>180s,则舍弃该次充电
+                    chrg_start.remove(chrg_start[-1])
+                    charging=0
+                    continue
+                elif self.packcrnt[i]<=-1 and self.packcrnt[i+1]<=-1 and  self.packcrnt[i+2]>-1:  #判断电流波动时刻
+                    cellvolt_now=self._cellvolt_get(i+1)
+                    if max(cellvolt_now)>self.param.CellFullChrgVolt:   #电压>满充电压
+                        chrg_end.append(i+1)
+                        charging=0
+                        continue
+                    else:
+                        pass
+                elif self.packcrnt[i+1]>-0.1 and self.packcrnt[i+2]>-0.1 and self.packcrnt[i+3]>-0.1:   #判断充电结束
+                    charging=0
+                    if len(chrg_start)>len(chrg_end):
+                        if self.bms_soc[i]>90:
+                            chrg_end.append(i)
+                        else:
+                            chrg_start.remove(chrg_start[-1])
+                            continue
+                    else:
+                        continue
+                elif i==len(self.packcrnt)-4 and self.packcrnt[i+1]<-1 and self.packcrnt[i+2]<-1:
+                    charging=0
+                    if len(chrg_start)>len(chrg_end):
+                        if self.bms_soc[i]>90:   #soc>90
+                            chrg_end.append(i)
+                            continue
+                        else:
+                            chrg_start.remove(chrg_start[-1])
+                            continue
+                    else:
+                        continue   
+            else:
+                pass
+            #获取DVDQ算法所需数据——结束
+
+        if chrg_end:    #DVDQ方法计算soc差
+            peaksoc_list=[]
+            for i in range(len(chrg_end)):
+                peaksoc_list = []
+                for j in range(1, self.param.CellVoltNums + 1):
+                    s = str(j)
+                    cellvolt = self.df_bms['单体电压' + s]
+                    cellvolt = list(cellvolt[chrg_start[i]:chrg_end[i]])
+                    time = list(self.bmstime[chrg_start[i]:chrg_end[i]])
+                    packcrnt = list(self.packcrnt[chrg_start[i]:chrg_end[i]])
+                    soc = list(self.bms_soc[chrg_start[i]:chrg_end[i]])
+                    peaksoc = self._dvdq_peak(time, soc, cellvolt, packcrnt)
+                    if peaksoc>1:
+                        peaksoc_list.append(peaksoc)    #计算到达峰值点的累计Soc
+                    else:
+                        pass
+                if len(peaksoc_list)>11:
+                    peaksoc_max=max(peaksoc_list)
+                    peaksoc_min=min(peaksoc_list)
+                    peaksoc_maxnum=peaksoc_list.index(peaksoc_min)+1
+                    peaksoc_minnum=peaksoc_list.index(peaksoc_max)+1
+                    cellsoc_diff=peaksoc_max-peaksoc_min
+                    cellsoc_diff=format(cellsoc_diff,'.1f')
+                    df_res.loc[len(df_res)]=[self.bmstime[chrg_start[i]], self.sn, cellsoc_diff, 0, peaksoc_minnum, peaksoc_maxnum]
+                else:
+                    pass
+
+        if df_res.empty:
+            return pd.DataFrame()
+        else:
+            df_res.sort_values(by='time', ascending=True, inplace=True)
+            return df_res

二进制
LIB/MIDDLE/CellStateEstimation/Uniform/V1_0_0/Uniform表单.xlsx


+ 24 - 0
LIB/MIDDLE/CellStateEstimation/Uniform/V1_0_0/log.py

@@ -0,0 +1,24 @@
+import logging
+import traceback
+
+class Mylog:
+
+    def __init__(self,log_name,log_level):
+        self.name=log_name
+        self.level=log_level
+    
+    def logcfg(self):
+        if len(self.level) > 0:
+            if self.level == 'debug':
+                Level=logging.DEBUG
+            elif self.level == 'info':
+                Level=logging.INFO
+            elif self.level == 'warning':
+                Level=logging.WARNING
+            else:
+                Level=logging.ERROR
+        logging.basicConfig(filename=self.name, level=Level,format='%(asctime)s - %(levelname)s - %(message)s')
+
+    def logopt(self,*info):
+        logging.error(info)
+        logging.error(traceback.format_exc())

+ 73 - 0
LIB/MIDDLE/CellStateEstimation/Uniform/V1_0_0/main.py

@@ -0,0 +1,73 @@
+import CBMSBatUniform
+import log
+
+#coding=utf-8
+import os
+import sys
+import datetime
+import pandas as pd
+from LIB.BACKEND import DBManager, Log
+# from LIB.MIDDLE import SignalMonitor
+from sqlalchemy import create_engine
+from sqlalchemy.orm import sessionmaker
+import time, datetime
+from LIB.MIDDLE.soh import NCMSoh_20210716 as NCMSoh
+from LIB.MIDDLE.soh import LFPSoh_20210711 as LFPSoh
+from urllib import parse
+
+dbManager = DBManager.DBManager()
+if __name__ == "__main__":
+    SNdata_6040 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='6040骑享')
+    SNdata_6060 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='6060')
+    SNdata_4840 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='4840骑享')
+    SNdata_7250 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='7250')
+    SNnums_6060=SNdata_6060['SN号']
+    SNnums_6040=SNdata_6040['SN号']
+    SNnums_4840=SNdata_4840['SN号']
+    SNnums_7250=SNdata_7250['SN号']
+
+    SNnums=SNnums_6040.tolist()+SNnums_6060.tolist()+SNnums_4840.tolist()+SNnums_7250.tolist()
+    now_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
+    now_time=datetime.datetime.strptime(now_time,'%Y-%m-%d %H:%M:%S')
+    start_time=now_time-datetime.timedelta(days=5)
+    end_time=str(now_time)
+    start_time=str(start_time)
+
+    #log信息配置
+    mylog=log.Mylog('log.txt','error')
+    mylog.logcfg()
+
+    for sn in SNnums:
+        try:
+            if 'PK500' in sn:
+                celltype=1 #6040三元电芯
+            elif 'PK502' in sn:
+                celltype=2 #4840三元电芯
+            elif 'PK504' in sn:
+                celltype=99    #60ah林磷酸铁锂电芯
+            elif 'MGMLXN750' in sn:
+                celltype=3 #力信50ah三元电芯
+            elif 'MGMCLN750' in sn: 
+                celltype=4 #CATL 50ah三元电芯
+            else:
+                print('未找到对应电池编号!!!')
+                sys.exit()
+            
+            # sn='PK50001A100000035'
+            # start_time='2021-08-10 9:49:37'
+            # end_time='2021-08-29 19:49:37'
+
+            dbManager = DBManager.DBManager()
+            df_data = dbManager.get_data(sn=sn, start_time=start_time, end_time=end_time, data_groups=['bms'])
+            df_bms = df_data['bms']
+            # df_bms.to_csv('BMS_'+sn+'.csv',encoding='GB18030')
+
+            BatUniform=CBMSBatUniform.BatUniform(sn,celltype,df_bms)
+            df_res=BatUniform.batuniform()
+            df_res.to_csv('CBMS_Uniform_'+sn+'.csv',encoding='GB18030')
+        
+        
+        except IndexError as e:
+            print(repr(e))
+            mylog.logopt(sn,e)
+            pass

+ 73 - 0
LIB/MIDDLE/CellStateEstimation/Uniform/main.py

@@ -0,0 +1,73 @@
+import CBMSBatUniform
+import log
+
+#coding=utf-8
+import os
+import sys
+import datetime
+import pandas as pd
+from LIB.BACKEND import DBManager, Log
+# from LIB.MIDDLE import SignalMonitor
+from sqlalchemy import create_engine
+from sqlalchemy.orm import sessionmaker
+import time, datetime
+from LIB.MIDDLE.soh import NCMSoh_20210716 as NCMSoh
+from LIB.MIDDLE.soh import LFPSoh_20210711 as LFPSoh
+from urllib import parse
+
+dbManager = DBManager.DBManager()
+if __name__ == "__main__":
+    SNdata_6040 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='6040骑享')
+    SNdata_6060 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='6060')
+    SNdata_4840 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='4840骑享')
+    SNdata_7250 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='7250')
+    SNnums_6060=SNdata_6060['SN号']
+    SNnums_6040=SNdata_6040['SN号']
+    SNnums_4840=SNdata_4840['SN号']
+    SNnums_7250=SNdata_7250['SN号']
+
+    SNnums=SNnums_6040.tolist()+SNnums_6060.tolist()+SNnums_4840.tolist()+SNnums_7250.tolist()
+    now_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
+    now_time=datetime.datetime.strptime(now_time,'%Y-%m-%d %H:%M:%S')
+    start_time=now_time-datetime.timedelta(days=5)
+    end_time=str(now_time)
+    start_time=str(start_time)
+
+    #log信息配置
+    mylog=log.Mylog('log.txt','error')
+    mylog.logcfg()
+
+    for sn in SNnums:
+        try:
+            if 'PK500' in sn:
+                celltype=1 #6040三元电芯
+            elif 'PK502' in sn:
+                celltype=2 #4840三元电芯
+            elif 'PK504' in sn:
+                celltype=99    #60ah林磷酸铁锂电芯
+            elif 'MGMLXN750' in sn:
+                celltype=3 #力信50ah三元电芯
+            elif 'MGMCLN750' in sn: 
+                celltype=4 #CATL 50ah三元电芯
+            else:
+                print('未找到对应电池编号!!!')
+                sys.exit()
+            
+            # sn='PK50001A100000035'
+            # start_time='2021-08-10 9:49:37'
+            # end_time='2021-08-29 19:49:37'
+
+            dbManager = DBManager.DBManager()
+            df_data = dbManager.get_data(sn=sn, start_time=start_time, end_time=end_time, data_groups=['bms'])
+            df_bms = df_data['bms']
+            # df_bms.to_csv('BMS_'+sn+'.csv',encoding='GB18030')
+
+            BatUniform=CBMSBatUniform.BatUniform(sn,celltype,df_bms)
+            df_res=BatUniform.batuniform()
+            df_res.to_csv('CBMS_Uniform_'+sn+'.csv',encoding='GB18030')
+        
+        
+        except IndexError as e:
+            print(repr(e))
+            mylog.logopt(sn,e)
+            pass

+ 0 - 155
LIB/MIDDLE/DeltSoc/LFPDeltSoc20210804.py

@@ -1,155 +0,0 @@
-# 获取数据
-from LIB.BACKEND import DBManager
-
-import os
-import pandas as pd
-import numpy as np
-import datetime
-# import matplotlib.pyplot as plt
-#参数初始化
-Capacity = 53.6
-PackFullChrgVolt=69.99
-CellFullChrgVolt=3.6
-CellVoltNums=20
-CellTempNums=4
-FullChrgSoc=98
-PeakSoc=57
-
-#获取数据时间段
-def cal_deltsoc(sn, end_time, start_time):
-    end_time = end_time
-    strat_time = start_time
-    SNnum=str(sn)
-
-    sn = sn
-    st = strat_time
-    et = end_time
-
-
-    dbManager = DBManager.DBManager()
-    df_data = dbManager.get_data(sn=sn, start_time=st, end_time=et, data_groups=['bms'])
-    df_bms = df_data['bms']
-    # 计算电芯Soc差
-    packcrnt = df_bms['总电流[A]']
-    packvolt = df_bms['总电压[V]']
-    SOC = df_bms['SOC[%]']
-    SOH = df_bms['SOH[%]']
-    bmsstat = (df_bms['充电状态']).astype(int)
-    time = pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
-
-    # 筛选充电数据
-    ChgStart = []
-    ChgEnd = []
-    for i in range(3, len(time) - 3):
-        if i==3 and bmsstat[i]==2 and bmsstat[i+1]==2 and bmsstat[i+2]==2:
-            ChgStart.append(i)
-        elif bmsstat[i-2]!=2 and bmsstat[i-1]!=2 and bmsstat[i]==2:
-            ChgStart.append(i)
-        elif bmsstat[i-1]==2 and bmsstat[i]!=2 and bmsstat[i+1]!=2:
-            ChgEnd.append(i)
-        elif i == (len(time) - 4) and bmsstat[len(bmsstat)-1] == 2 and bmsstat[len(bmsstat)-2] == 2:
-            ChgEnd.append(len(time)-1)
-
-    # 筛选充电起始Soc<46%,电芯温度>15℃的数据
-    ChgStartValid = []
-    ChgEndValid = []
-    if ChgStart:
-        for i in range(min(len(ChgStart),len(ChgEnd))):
-            # 获取最小温度值
-            celltemp = []
-            for j in range(1, CellTempNums + 1):
-                s = str(j)
-                temp = df_bms['单体温度' + s]
-                celltemp.append(temp[ChgEnd[i]])
-
-            if SOC[ChgStart[i]] < 46 and SOC[ChgEnd[i]]>85 and min(celltemp) > 10 and (ChgEnd[i]-ChgStart[i])>10:
-                if ((time[ChgEnd[i]]-time[ChgStart[i]]).total_seconds())/(ChgEnd[i]-ChgStart[i])<30:
-                    ChgStartValid.append(ChgStart[i])
-                    ChgEndValid.append(ChgEnd[i])
-
-    # 计算充电每个单体到达DVDQ峰值的Ah差
-    # 定义滑动平均滤波函数
-    def np_move_avg(a, n, mode="same"):
-        return (np.convolve(a, np.ones((n,)) / n, mode=mode))
-
-
-    # 定义函数:切片Soc>50且Soc<80,并寻找峰值返回峰值点的时间
-    def data_search(t, soc, cellvolt1, packcrnt1):
-        cellvolt2 = np_move_avg(cellvolt1, 5, mode="same")
-        Soc = 0
-        Ah = 0
-        Volt = [cellvolt2[0]]
-        DV_Volt = []
-        DQ_Ah = []
-        DVDQ = []
-        time1 = []
-        soc1 = []
-        soc2 = []
-
-        for m in range(1, len(t)):
-            Step = (t[m] - t[m - 1]).total_seconds()
-            Soc = Soc - packcrnt1[m] * Step * 100 / (3600 * Capacity)
-            Ah = Ah - packcrnt1[m] * Step / 3600
-            if (cellvolt2[m] - Volt[-1]) > 0.9 and Ah>0:
-                DQ_Ah.append(Ah)
-                Volt.append(cellvolt2[m])
-                DV_Volt.append(Volt[-1] - Volt[-2])
-                DVDQ.append((DV_Volt[-1]) / DQ_Ah[-1])
-                Ah = 0
-                time1.append(t[m])
-                soc1.append(Soc)
-                soc2.append(soc[m])
-        df_Data1 = pd.DataFrame({'Time': time1,
-                                'SOC': soc2,
-                                'DVDQ': DVDQ,
-                                'AhSOC': soc1})
-
-        df_Data1 = df_Data1[(df_Data1['SOC'] > 50) & (df_Data1['SOC'] < 80)]
-        # 寻找峰值点,且峰值点个数>3
-        if len(df_Data1['DVDQ'])>2:
-            PeakIndex = df_Data1['DVDQ'].idxmax()
-            df_Data2 = df_Data1[
-                (df_Data1['SOC'] > (df_Data1['SOC'][PeakIndex] - 0.5)) & (df_Data1['SOC'] < (df_Data1['SOC'][PeakIndex] + 0.5))]
-            if len(df_Data2) > 3:
-                return df_Data1['AhSOC'][PeakIndex]
-            else:
-                df_Data1 = df_Data1.drop([PeakIndex])
-                PeakIndex = df_Data1['DVDQ'].idxmax()
-                return df_Data1['AhSOC'][PeakIndex]
-
-
-    # 计算最大最小Soc差
-    if ChgStartValid:
-        DetaSoc2 = []
-        DetaSoc=[]
-        DetaSoc_SN=[]
-        DetaSoc_time=[]
-        for i in range(len(ChgStartValid)):
-            DetaSoc1 = []
-            for j in range(1, CellVoltNums + 1):
-                s = str(j)
-                cellvolt = df_bms['单体电压' + s]
-                cellvolt = list(cellvolt[ChgStartValid[i]:ChgEndValid[i]])
-                Time = list(time[ChgStartValid[i]:ChgEndValid[i]])
-                Packcrnt = list(packcrnt[ChgStartValid[i]:ChgEndValid[i]])
-                SOC1 = list(SOC[ChgStartValid[i]:ChgEndValid[i]])
-                a = data_search(Time, SOC1, cellvolt, Packcrnt)
-                if a:
-                    DetaSoc1.append(a)  # 计算到达峰值点的累计Soc
-            if DetaSoc1:
-                DetaSoc2.append(max(DetaSoc1) - min(DetaSoc1))
-
-        DetaSocMean = np.mean(DetaSoc2)
-        DetaSoc.append(DetaSocMean)
-        DetaSoc_SN.append(SNnum)
-        DetaSoc_time.append(time[ChgStartValid[-1]])
-
-
-        result_DetaSoc={'time':DetaSoc_time,
-                        'SN号':DetaSoc_SN,
-                        'Soc差':DetaSoc}
-        Result_DetaSoc=pd.DataFrame(result_DetaSoc)
-        return Result_DetaSoc
-    return pd.DataFrame()
-
-

+ 0 - 4
LIB/MIDDLE/DeltSoc/detaSOC表头及数据类型.xlsx

@@ -1,4 +0,0 @@
-±íÍ·	Ãû³Æ	Êý¾ÝÀàÐÍ
-time	time	timestamps
-SNºÅ	sn	str
-Soc²î	deta_soc	float64

二进制
LIB/MIDDLE/DeltSoc/骑享资产梳理-20210621.xlsx


+ 0 - 304
LIB/MIDDLE/soh/LFPSoh_20210711.py

@@ -1,304 +0,0 @@
-# 获取数据
-from LIB.BACKEND import DBManager
-
-import os
-import pandas as pd
-import numpy as np
-import datetime
-# import matplotlib.pyplot as plt
-
-#参数输入
-Capacity = 54
-PackFullChrgVolt=69.99
-CellFullChrgVolt=3.5
-CellVoltNums=20
-CellTempNums=4
-FullChrgSoc=98
-PeakSoc=57
-# #40Ah-OCV
-# LookTab_SOC = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100]
-# LookTab_OCV = [3.3159, 3.4502, 3.4904, 3.5277, 3.5590, 3.5888, 3.6146, 3.6312, 3.6467, 3.6642, 3.6865, 3.7171, 3.7617,
-#                3.8031, 3.8440, 3.8888, 3.9376, 3.9891, 4.0451, 4.1068, 4.1830]
-#55Ah-OCV
-LookTab_SOC = [0.00, 	2.40, 	6.38, 	10.37, 	14.35, 	18.33, 	22.32, 	26.30, 	30.28, 	35.26, 	40.24, 	45.22, 	50.20, 	54.19, 	58.17, 	60.16, 	65.14, 	70.12, 	75.10, 	80.08, 	84.06, 	88.05, 	92.03, 	96.02, 	100.00]
-LookTab_OCV = [2.7151,	3.0298,	3.1935,	3.2009,	3.2167,	3.2393,	3.2561,	3.2703,	3.2843,	3.2871,	3.2874,	3.2868,	3.2896,	3.2917,	3.2967,	3.3128,	3.3283,	3.3286,	3.3287,	3.3288,	3.3289,	3.3296,	3.3302,	3.3314,	3.3429]
-
-#定义滑动滤波函数
-def np_move_avg(a, n, mode="same"):
-    return (np.convolve(a, np.ones((n,)) / n, mode=mode))
-
-#参数初始化
-dvdq_soh=[]
-dvdq_soh_err=[]
-bms_soh=[]
-dvdq_time=[]
-dvdq_sohcfd=[]
-sn_list=[]
-
-
-#输入一个含有‘SN号’的xlsx
-def cal_soh(sn, end_time, start_time):
-    #获取数据时间段
-    end_time = end_time
-    strat_time = start_time
-    SNnum=str(sn)
-    sn = SNnum
-    st = start_time
-    et = end_time
-
-    dbManager = DBManager.DBManager()
-    df_data = dbManager.get_data(sn=sn, start_time=st, end_time=et, data_groups=['bms'])
-    data = df_data['bms']
-
-    packcrnt=data['总电流[A]']
-    packvolt=data['总电压[V]']
-    SOC=data['SOC[%]']
-    SOH=data['SOH[%]']
-    bmsstat=data['充电状态']
-    time= pd.to_datetime(data['时间戳'], format='%Y-%m-%d %H:%M:%S')
-
-    #第一步:筛选充电数据
-    ChgStart=[]
-    ChgEnd=[]
-    for i in range(3, len(time) - 3):
-        if i==3 and bmsstat[i]==2 and bmsstat[i+1]==2 and bmsstat[i+2]==2:
-            ChgStart.append(i)
-        elif bmsstat[i-2]!=2 and bmsstat[i-1]!=2 and bmsstat[i]==2:
-            ChgStart.append(i)
-        elif bmsstat[i-1]==2 and bmsstat[i]!=2 and bmsstat[i+1]!=2:
-            ChgEnd.append(i)
-        elif i == (len(time) - 4) and bmsstat[len(bmsstat)-1] == 2 and bmsstat[len(bmsstat)-2] == 2:
-            ChgEnd.append(len(time)-1)
-
-    #第二步:筛选充电起始Soc<48%,电芯温度>15℃,且满充的数据
-    ChgStartValid1=[]
-    ChgEndValid1=[]
-    ChgStartValid2=[]
-    ChgEndValid2=[]
-
-    for i in range(min(len(ChgStart),len(ChgEnd))):
-
-        #获取最小温度值
-        celltemp = []
-        for j in range(1, CellTempNums+1):
-            s = str(j)
-            temp = data['单体温度' + s]
-            celltemp.append(temp[ChgEnd[i]])
-
-        #寻找最大电压值
-        cellvolt = []
-        for j in range(1, CellVoltNums+1):
-            s = str(j)
-            volt = max(data['单体电压' + s][ChgStart[i]:ChgEnd[i]]/1000)
-            cellvolt.append(volt)
-
-        #筛选满足2点法计算的数据
-        StandingTime=0
-        if max(cellvolt)>CellFullChrgVolt and SOC[ChgStart[i]]<30 and min(celltemp)>5:
-            for k in reversed(range(ChgStart[i])):
-                if abs(packcrnt[k - 2]) < 0.01:
-                    StandingTime = StandingTime + (time[k] - time[k-1]).total_seconds()
-                    if StandingTime > 600:  # 筛选静置时间>10min
-                        ChgStartValid1.append(ChgStart[i])
-                        ChgEndValid1.append(ChgEnd[i])
-                        break
-                else:
-                    break
-
-        #筛选满足DV/DQ方法的数据
-        if max(cellvolt)>CellFullChrgVolt and SOC[ChgStart[i]]<45 and min(celltemp)>5:
-            if ((time[ChgEnd[i]]-time[ChgStart[i]]).total_seconds())/(ChgEnd[i]-ChgStart[i])<60:
-                ChgStartValid2.append(ChgStart[i])
-                ChgEndValid2.append(ChgEnd[i])
-
-    #第三步:计算充电Soc和Soh
-
-    # 两点法计算soh
-    Soc=[]
-    Time=[]
-    Soc_Err=[]
-    Bms_Soc=[]
-
-    Soh1=[]
-    Time1=[]
-    Bms_Soh1=[]
-    Soh_Err1=[]
-
-    for i in range(len(ChgStartValid1)):
-
-        #寻找最大电压值
-        cellvolt = []
-        for j in range(1, CellVoltNums+1):
-            s = str(j)
-            volt = max(data['单体电压' + s])
-            cellvolt.append(volt)
-        voltmax_index = cellvolt.index(max(cellvolt)) + 1
-        cellvolt = data['单体电压' + str(voltmax_index)] / 1000
-
-        #soc
-        Soc.append(np.interp(cellvolt[ChgStartValid1[i]-3],LookTab_OCV,LookTab_SOC))
-        Time.append(time[ChgStartValid1[i]-3])
-        Bms_Soc.append(SOC[ChgStartValid1[i]-3])
-        Soc_Err.append(Bms_Soc[-1]-Soc[-1])
-
-        #soh
-        Ocv_Soc=np.interp(cellvolt[ChgStartValid1[i]-3],LookTab_OCV,LookTab_SOC)
-        Ah=0
-
-        for j in range(ChgStartValid1[i],ChgEndValid1[i]):
-            #计算soc
-            Step=(time[j]-time[j-1]).total_seconds()
-            Time.append(time[j])
-            Bms_Soc.append(SOC[j])
-            if Soc[-1]-(packcrnt[j]*Step*100)/(3600*Capacity)<100:
-                Soc.append(Soc[-1]-(packcrnt[j]*Step*100)/(3600*Capacity))
-            else:
-                Soc.append(100)
-            Soc_Err.append(Bms_Soc[-1] - Soc[-1])
-
-            #两点法计算soh
-            Ah=Ah-packcrnt[j]*Step/3600
-        Soh1.append(Ah*100/((FullChrgSoc-Ocv_Soc)*0.01*Capacity))
-        Bms_Soh1.append(SOH[i])
-        Soh_Err1.append(Bms_Soh1[-1]-Soh1[-1])
-        Time1.append(time[ChgStartValid1[i]])
-
-    # DV/DQ法计算soh
-    Soh2=[]
-    Time2=[]
-    Bms_Soh2=[]
-    Soh_Err2=[]
-    SohCfd = []
-    sn_list=[]
-
-    for i in range(len(ChgStartValid2)):
-
-        #寻找最大电压值
-        cellvolt1 = []
-        cellvolt=[]
-        for j in range(1, CellVoltNums+1):
-            s = str(j)
-            volt = data['单体电压' + s]
-            cellvolt1.append(volt[ChgEndValid2[i]])
-        voltmax1_index = cellvolt1.index(max(cellvolt1)) + 1
-        cellvolt1 = data['单体电压' + str(voltmax1_index)] / 1000
-
-        #电压采用滑动平均滤波
-        cellvolt=np_move_avg(cellvolt1, 3, mode="same")
-
-
-        #参数赋初始值
-        Ah = 0
-        Volt = cellvolt[ChgStartValid2[i]]
-        DV_Volt=[]
-        DQ_Ah = []
-        DVDQ = []
-        time2 = []
-        soc2 = []
-        Ah_tatal=[0]
-        xvolt=[]
-        #计算DV和DQ值
-        for j in range(ChgStartValid2[i],ChgEndValid2[i]):
-            Step=(time[j+1]-time[j]).total_seconds()
-            Ah=Ah-packcrnt[j]*Step/3600
-            if (cellvolt[j]-Volt)>0.0009 and Ah>0:
-                Ah_tatal.append(Ah_tatal[-1]+Ah)
-                DQ_Ah.append(Ah)
-                DV_Volt.append(cellvolt[j]-Volt)
-                DVDQ.append((DV_Volt[-1])/DQ_Ah[-1])
-                xvolt.append(cellvolt[j])
-                Volt=cellvolt[j]
-                Ah = 0
-                time2.append(time[j])
-                soc2.append(SOC[j])
-
-        #切片Soc>50且Soc<80
-        Data1 = pd.DataFrame({'SOC': soc2,
-                                'DVDQ': DVDQ,
-                                'Ah_tatal': Ah_tatal[:-1],
-                                'DQ_Ah':DQ_Ah,
-                                'DV_Volt':DV_Volt,
-                                'XVOLT':xvolt})
-
-        Data1=Data1[(Data1['SOC']>50) & (Data1['SOC']<80)]
-
-        #寻找峰值并计算Soh和置信度
-        # 获取最小温度值
-        celltemp = []
-        for j in range(1, CellTempNums+1):
-            s = str(j)
-            temp = data['单体温度' + s]
-            celltemp.append(temp[ChgStartValid2[i]])
-        if len(Data1['DVDQ'])>1:
-            PeakIndex=Data1['DVDQ'].idxmax()
-            #筛选峰值点附近±0.5%SOC内的数据
-            Data2=Data1[(Data1['SOC']>(Data1['SOC'][PeakIndex]-0.5)) & (Data1['SOC']<(Data1['SOC'][PeakIndex]+0.5))]
-            if len(Data2)>2:
-                Ah_tatal1 = Data1['Ah_tatal']
-                DVDQ = Data1['DVDQ']
-                soc2 = Data1['SOC']
-                xvolt = Data1['XVOLT']
-                if soc2[PeakIndex]>50 and soc2[PeakIndex]<80:
-                    DVDQ_SOH=(Ah_tatal[-1]-Ah_tatal1[PeakIndex]) * 100 / ((FullChrgSoc - PeakSoc) * 0.01 * Capacity)
-                    if DVDQ_SOH<95:
-                        DVDQ_SOH=DVDQ_SOH*0.3926+58.14
-                    if DVDQ_SOH>70 and DVDQ_SOH<120:
-                        Soh2.append(DVDQ_SOH)
-                        Bms_Soh2.append(SOH[ChgStartValid2[i]])
-                        Soh_Err2.append(Bms_Soh2[-1] - Soh2[-1])
-                        Time2.append(time[ChgStartValid2[i]])
-                        sn_list.append(SNnum)
-
-                        #计算置信度
-                        if min(celltemp)<10:
-                            SohCfd.append(50)
-                        elif min(celltemp)<20:
-                            SohCfd.append(80)
-                        else:
-                            SohCfd.append(100)
-            else:
-                Data1=Data1.drop([PeakIndex])
-                PeakIndex = Data1['DVDQ'].idxmax()
-                Data2 = Data1[(Data1['SOC'] > (Data1['SOC'][PeakIndex] - 0.5)) & (Data1['SOC'] < (Data1['SOC'][PeakIndex] + 0.5))]
-                if len(Data2) > 3:
-                    Ah_tatal1 = Data1['Ah_tatal']
-                    DVDQ = Data1['DVDQ']
-                    soc2 = Data1['SOC']
-                    xvolt = Data1['XVOLT']
-                    if soc2[PeakIndex]>50 and soc2[PeakIndex]<80:
-                        DVDQ_SOH=(Ah_tatal[-1]-Ah_tatal1[PeakIndex]) * 100 / ((FullChrgSoc - PeakSoc) * 0.01 * Capacity)
-                        if DVDQ_SOH<95:
-                            DVDQ_SOH=DVDQ_SOH*0.3926+58.14
-                        if DVDQ_SOH>70 and DVDQ_SOH<120:
-                            Soh2.append(DVDQ_SOH)
-                            Bms_Soh2.append(SOH[ChgStartValid2[i]])
-                            Soh_Err2.append(Bms_Soh2[-1] - Soh2[-1])
-                            Time2.append(time[ChgStartValid2[i]])
-                            sn_list.append(SNnum)
-
-                            #计算置信度
-                            if min(celltemp)<10:
-                                SohCfd.append(50)
-                            elif min(celltemp)<20:
-                                SohCfd.append(80)
-                            else:
-                                SohCfd.append(100)
-
-    #处理数据
-    if len(Soh2)>5:
-        Soh2=np_move_avg(Soh2,5,mode="valid")
-        result_soh2={'时间': Time2[4::],
-            'SN号':sn_list[4::],
-            'BMS_SOH': Bms_Soh2[4::],
-            'SOH': Soh2,
-            'SOH误差': Soh_Err2[4::]}
-    else:
-        result_soh2={'时间': Time2,
-            'SN号':sn_list,
-            'BMS_SOH': Bms_Soh2,
-            'SOH': Soh2,
-            'SOH误差': Soh_Err2}
-    #第四步:将数据存入Excel
-    Result_Soh2=pd.DataFrame(result_soh2)
-    # Result_Soh2.to_csv('BMS_SOH_'+SNnum+'.csv',encoding='GB18030')
-    return Result_Soh2

+ 0 - 169
LIB/MIDDLE/soh/NCMSoh_20210716.py

@@ -1,169 +0,0 @@
-# 获取数据
-from LIB.BACKEND import DBManager
-
-import os
-import pandas as pd
-import numpy as np
-import datetime
-# import matplotlib.pyplot as plt
-
-#参数输入
-Capacity = 41
-PackFullChrgVolt=69.99
-CellFullChrgVolt=3.5
-CellVoltNums=17
-CellTempNums=4
-FullChrgSoc=98
-PeakSoc=57
-# #40Ah-OCV
-LookTab_SOC = [0,	3.534883489,	8.358178409,	13.18141871,	18.00471528,	22.82796155,	27.65123833,	32.47444668,	37.29772717,	42.12099502,	46.94423182,	51.76744813,	56.59070685,	61.4139927,	66.23719857,	71.0604667,	75.88373853,	80.70702266,	85.5302705,	90.35352009,	95.17676458,	100]
-LookTab_OCV = [3.3159,	3.4384,	3.4774,	3.5156,	3.5478,	3.5748,	3.6058,	3.6238,	3.638,	3.6535,	3.6715,	3.6951,	3.7279,	3.7757,	3.8126,	3.8529,	3.8969,	3.9446,	3.9946,	4.0491,	4.109,	4.183]
-# #55Ah-OCV
-# LookTab_SOC = [0.00, 	2.40, 	6.38, 	10.37, 	14.35, 	18.33, 	22.32, 	26.30, 	30.28, 	35.26, 	40.24, 	45.22, 	50.20, 	54.19, 	58.17, 	60.16, 	65.14, 	70.12, 	75.10, 	80.08, 	84.06, 	88.05, 	92.03, 	96.02, 	100.00]
-# LookTab_OCV = [2.7151,	3.0298,	3.1935,	3.2009,	3.2167,	3.2393,	3.2561,	3.2703,	3.2843,	3.2871,	3.2874,	3.2868,	3.2896,	3.2917,	3.2967,	3.3128,	3.3283,	3.3286,	3.3287,	3.3288,	3.3289,	3.3296,	3.3302,	3.3314,	3.3429]
-
-#参数初始化
-Soh3=[]
-Time3=[]
-Bms_Soh3=[]
-Soh_Err3=[]
-sn_list=[]
-
-#获取数据时间段
-
-def cal_soh(sn, end_time, start_time):
-    end_time = end_time
-    strat_time = start_time
-    SNnum=str(sn)
-
-    sn = sn
-    st = strat_time
-    et = end_time
-
-    dbManager = DBManager.DBManager()
-    df_data = dbManager.get_data(sn=sn, start_time=st, end_time=et, data_groups=['bms'])
-    data = df_data['bms']
-    # print(data)
-
-    packcrnt=data['总电流[A]']
-    packvolt=data['总电压[V]']
-    SOC=data['SOC[%]']
-    SOH=data['SOH[%]']
-    bmsstat=data['充电状态']
-    time= pd.to_datetime(data['时间戳'], format='%Y-%m-%d %H:%M:%S')
-
-    #第一步:筛选充电数据
-    if len(packcrnt)>100:
-        ChgStart=[]
-        ChgEnd=[]
-        for i in range(3, len(time) - 3):
-            if i==3 and bmsstat[i]==2 and bmsstat[i+1]==2 and bmsstat[i+2]==2:
-                ChgStart.append(i)
-            elif bmsstat[i-2]!=2 and bmsstat[i-1]!=2 and bmsstat[i]==2:
-                ChgStart.append(i)
-            elif bmsstat[i-1]==2 and bmsstat[i]!=2 and bmsstat[i+1]!=2:
-                ChgEnd.append(i-1)
-            elif i == (len(time) - 4) and bmsstat[len(bmsstat)-1] == 2 and bmsstat[len(bmsstat)-2] == 2:
-                ChgEnd.append(len(time)-2)
-
-        #第二步:筛选充电起始Soc<45% & SOC>85%,电芯温度>5℃
-        ChgStartValid1=[]
-        ChgEndValid1=[]
-        ChgStartValid2=[]
-        ChgEndValid2=[]
-        StandingNum=[]
-
-        for i in range(min(len(ChgStart),len(ChgEnd))):
-
-            #获取最小温度值
-            celltemp = []
-            for j in range(1, CellTempNums+1):
-                s = str(j)
-                temp = data['单体温度' + s]
-                celltemp.append(temp[ChgEnd[i]])
-            
-            #去除电流0点   
-            for k in range(ChgStart[i],ChgEnd[i]):
-                if packcrnt[k]<-0.5 and packcrnt[k+1]>-0.5 and packcrnt[k+2]>-0.5 and packcrnt[k+3]>-0.5:
-                    ChgEnd[i]=k
-            
-            #计算最大packvolt
-            if len(packvolt[ChgStart[i]:ChgEnd[i]])>0:
-                packvoltMAX=max(packvolt[ChgStart[i]:ChgEnd[i]])
-
-                #筛选满足2点法计算的数据
-                StandingTime=0
-                StandingTime1=0
-                StandingTime2=0
-                if SOC[ChgEnd[i]]>85 and SOC[ChgStart[i]]<45 and min(celltemp)>5:
-                    for m in range(min(len(packcrnt)-ChgEnd[i]-2,ChgStart[i]-2)):
-                        if abs(packcrnt[ChgStart[i] - m - 1]) < 0.1:
-                            StandingTime = StandingTime + (time[ChgStart[i] - m] - time[ChgStart[i] - m - 1]).total_seconds()
-                        if abs(packcrnt[ChgEnd[i] + m + 1]) < 0.1:
-                            StandingTime1 = StandingTime1 + (time[ChgEnd[i] + m + 1] - time[ChgEnd[i] + m]).total_seconds()
-                        if StandingTime > 900 and StandingTime1>900 and ((time[ChgEnd[i]]-time[ChgStart[i]]).total_seconds())/(ChgEnd[i]-ChgStart[i])<60:  #筛选静置时间>15min且慢充过程丢失数据少
-                            ChgStartValid1.append(ChgStart[i])
-                            ChgEndValid1.append(ChgEnd[i])
-                            StandingNum.append(m)
-                            break
-                        if abs(packcrnt[ChgStart[i] - m - 2])>0.5 and abs(packcrnt[ChgEnd[i] + m + 2])>0.5:
-                            break
-
-        # 计算soh
-        Soh1=[]
-        Soh2=[]
-        Time1=[]
-        Bms_Soh1=[]
-        Soh_Err1=[]
-        sn_list1=[]
-        #两点法计算Soh
-        if len(ChgStartValid1)>0:
-            for i in range(len(ChgStartValid1)):
-                #计算Ah
-                Ah=0
-                for j in range(ChgStartValid1[i],ChgEndValid1[i]):
-                    Step=(time[j+1]-time[j]).total_seconds()
-                    Ah=Ah-packcrnt[j+1]*Step/3600
-                #计算每个电芯的Soh
-                for j in range(1, CellVoltNums+1):
-                    s = str(j)
-                    cellvolt = data['单体电压' + s]/1000
-                    OCVStart=cellvolt[ChgStartValid1[i]-2]
-                    OCVEnd=cellvolt[ChgEndValid1[i]+StandingNum[i]]
-                    #soh
-                    Ocv_Soc1=np.interp(OCVStart,LookTab_OCV,LookTab_SOC)
-                    Ocv_Soc2=np.interp(OCVEnd,LookTab_OCV,LookTab_SOC)
-                    Soh2.append(Ah*100/((Ocv_Soc2-Ocv_Soc1)*0.01*Capacity))
-                Soh1.append(np.mean(Soh2))
-                Bms_Soh1.append(SOH[ChgStartValid1[i]])
-                Soh_Err1.append(Bms_Soh1[-1]-Soh1[-1])
-                Time1.append(time[ChgStartValid1[i]])
-                sn_list1.append(SNnum)
-       
-            # Soh3.append(np.mean(Soh1))
-            # Bms_Soh3.append(np.mean(Bms_Soh1))
-            # Soh_Err3.append(np.mean(Soh_Err1))
-            # Time3.append(time[ChgStartValid1[-1]])
-            # sn_list.append(SNnum)
-
-        #第四步:将数据存入Excel
-            result_soh2={'时间': Time1,
-                'SN号': sn_list1,
-                'BMS_SOH': Bms_Soh1,
-                'SOH': Soh1,
-                'SOH误差': Soh_Err1}
-
-            Result_Soh2=pd.DataFrame(result_soh2)
-            # Result_Soh2.to_csv('BMS_SOH_'+SNnum+'.csv',encoding='GB18030')
-            return Result_Soh2
-    return pd.DataFrame()
-
-#     result_soh1={'时间': Time3,
-#         'SN号':sn_list,
-#         'BMS_SOH': Bms_Soh3,
-#         'SOH': Soh3,
-#         'SOH误差': Soh_Err3}
-
-# Result_Soh1=pd.DataFrame(result_soh1)
-# print(Result_Soh1)
-# Result_Soh1.to_csv('BMS_SOH_'+'6040'+'.csv',encoding='GB18030')