import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import datetime
# from pymysql import paramstyle
from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import BatParam

class BatInterShort():
    def __init__(self,sn,celltype,df_bms,df_soh,df_last,df_last1,df_last2,df_last3,df_lfp):  #参数初始化

        if (not df_lfp.empty) and celltype>50:
            df_lfp.drop(['sn'],axis=1)
            df_bms=pd.concat([df_lfp, df_bms], ignore_index=True)
        else:
            pass

        self.sn=sn
        self.celltype=celltype
        self.param=BatParam.BatParam(celltype)
        self.packcrnt=df_bms['总电流[A]']*self.param.PackCrntDec
        self.packvolt=df_bms['总电压[V]']
        self.bms_soc=df_bms['SOC[%]']
        df_bms['time']=pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
        self.bmstime= df_bms['time']

        self.df_bms=df_bms
        self.df_soh=df_soh
        self.df_last=df_last
        self.df_last1=df_last1
        self.df_last2=df_last2
        self.df_last3=df_last3
        self.df_lfp=df_lfp

        self.cellvolt_name=['单体电压'+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)]
    
    def intershort(self):
        if self.celltype<=50:
            df_res, df_ram_last, df_ram_last1, df_ram_last3=self._ncm_intershort()
            return df_res, df_ram_last, df_ram_last1,self.df_last2, df_ram_last3,self.df_lfp
            
        else:
            df_res, df_ram_last, df_ram_last1, df_ram_last2, df_ram_last3, df_ram_lfp=self._lfp_intershort()
            return df_res, df_ram_last, df_ram_last1, df_ram_last2, df_ram_last3, df_ram_lfp


    #定义滑动滤波函数....................................................................................
    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 = list(self.df_bms.loc[num,self.celltemp_name])
        celltemp=min(celltemp)
        self.celltemp=celltemp
        if self.celltype==99:
            if celltemp>=25:
                self.tempweight=1
                self.StandardStandingTime=4800
            elif celltemp>=15:
                self.tempweight=0.6
                self.StandardStandingTime=7200
            elif celltemp>=5:
                self.tempweight=0.
                self.StandardStandingTime=10800
            else:
                self.tempweight=0.1
                self.StandardStandingTime=10800
        else:
            if celltemp>=25:
                self.tempweight=1
                self.StandardStandingTime=4800
            elif celltemp>=15:
                self.tempweight=0.8
                self.StandardStandingTime=7200
            elif celltemp>=5:
                self.tempweight=0.6
                self.StandardStandingTime=7200
            else:
                self.tempweight=0.2
                self.StandardStandingTime=10800

    #获取前半个小时每个电压的平均值........................................................................................
    def _avgvolt_get(self,num): 
        time_now=self.df_bms.loc[num, 'time']
        time_last=time_now-datetime.timedelta(seconds=1800)
        df_volt=self.df_bms[(self.df_bms['time']>=time_last) & (self.df_bms['time']<=time_now)]
        df_volt=df_volt[self.cellvolt_name]
        cellvolt_std=df_volt.std(axis=0)
        if len(df_volt)>2 and max(cellvolt_std)<1.5:
            cellvolt_sum=df_volt.sum(0)-df_volt.max(0)-df_volt.min(0)
            cellvolt_mean=cellvolt_sum/(len(df_volt)-2)
            cellvolt=cellvolt_mean/1000
        elif len(df_volt)==2:
            # df_volt=pd.DataFrame(df_volt,dtype=np.float)
            if max(abs(df_volt.iloc[1]-df_volt.iloc[0]))<3:
                cellvolt=df_volt.mean(0)/1000
            else:
                cellvolt=pd.DataFrame()
        else:
            cellvolt=pd.DataFrame()
        return cellvolt
    
    #获取单个电压值.................................................................................................
    def _singlevolt_get(self,num,series,mode):  #mode==1取当前行单体电压值，mode==2取某个单体所有电压值
        s=str(series)
        if mode==1:
            singlevolt=self.df_bms.loc[num,'单体电压' + s]/1000
            return singlevolt
        else:
            singlevolt=self.df_bms['单体电压' + s]/1000
            return singlevolt

    #获取当前行所有电压数据........................................................................................
    def _cellvolt_get(self,num):
        cellvolt = np.array(self.df_bms.loc[num,self.cellvolt_name])/1000
        return cellvolt

    #获取当前行所有soc差...........................................................................................
    def _celldeltsoc_get(self,cellvolt_list,dict_baltime,capacity): 
        cellsoc=[]
        celldeltsoc=[]
        for j in range(self.param.CellVoltNums):   #获取每个电芯电压对应的SOC值
            cellvolt=cellvolt_list[j]
            ocv_soc=np.interp(cellvolt,self.param.LookTab_OCV,self.param.LookTab_SOC)
            if j+1 in dict_baltime.keys():
                ocv_soc=ocv_soc+dict_baltime[j+1]*self.param.BalCurrent/(capacity*3600)   #补偿均衡电流
            else:
                pass
            cellsoc.append(ocv_soc)
        
        if self.celltype==1 or self.celltype==2:
            consum_num=7
            cellsoc1=cellsoc[:self.param.CellVoltNums-consum_num]    #切片，将bms耗电的电芯和非耗电的电芯分离开
            cellsocmean1=(sum(cellsoc1)-max(cellsoc1)-min(cellsoc1))/(len(cellsoc1)-2)
            cellsoc2=cellsoc[self.param.CellVoltNums-consum_num:]
            cellsocmean2=(sum(cellsoc2)-max(cellsoc2)-min(cellsoc2))/(len(cellsoc2)-2)
            
            for j in range(len(cellsoc)):   #计算每个电芯的soc差
                if j<self.param.CellVoltNums-consum_num:
                    celldeltsoc.append(cellsoc[j]-cellsocmean1)
                else:
                    celldeltsoc.append(cellsoc[j]-cellsocmean2)
            return np.array(celldeltsoc), np.array(cellsoc)
        
        elif self.celltype==99:
            consum_num=10
            cellsoc1=cellsoc[:self.param.CellVoltNums-consum_num]    #切片，将bms耗电的电芯和非耗电的电芯分离开
            cellsocmean1=(sum(cellsoc1)-max(cellsoc1)-min(cellsoc1))/(len(cellsoc1)-2)
            cellsoc2=cellsoc[self.param.CellVoltNums-consum_num:]
            cellsocmean2=(sum(cellsoc2)-max(cellsoc2)-min(cellsoc2))/(len(cellsoc2)-2)
            
            for j in range(len(cellsoc)):   #计算每个电芯的soc差
                if j<self.param.CellVoltNums-consum_num:
                    celldeltsoc.append(cellsoc[j]-cellsocmean1)
                else:
                    celldeltsoc.append(cellsoc[j]-cellsocmean2)
            return np.array(celldeltsoc), np.array(cellsoc)

        else:
            cellsocmean=(sum(cellsoc)-max(cellsoc)-min(cellsoc))/(len(cellsoc)-2)
            for j in range(len(cellsoc)):   #计算每个电芯的soc差
                celldeltsoc.append(cellsoc[j]-cellsocmean)
            return np.array(celldeltsoc), np.array(cellsoc)
 
    #获取所有电芯的As差
    def _cellDeltAs_get(self,chrg_st,chrg_end,dict_baltime):
        cellAs=[]
        celldeltAs=[]
        for j in range(1, self.param.CellVoltNums+1):   #获取每个电芯电压>峰值电压的充入As数
            if j in dict_baltime.keys():    #补偿均衡电流
                As=-self.param.BalCurrent*dict_baltime[j]
            else:    
                As=0
            As_tatol=0
            symbol=0
            for m in range(chrg_st+1,chrg_end):
                As=As-self.packcrnt[m]*(self.bmstime[m]-self.bmstime[m-1]).total_seconds()
                if symbol<5:
                    if self.df_bms.loc[m,'单体电压'+str(j)]/1000>self.param.PeakCellVolt[symbol]:
                        As_tatol=As_tatol+As
                        symbol=symbol+1
                    else:
                        continue
                else:
                    cellAs.append(As_tatol/5)
                    break
        
        if self.celltype==99:
            consum_num=10
            cellAs1=cellAs[:self.param.CellVoltNums-consum_num]    #切片，将bms耗电的电芯和非耗电的电芯分离开
            cellAsmean1=(sum(cellAs1)-max(cellAs1)-min(cellAs1))/(len(cellAs1)-2)
            cellAs2=cellAs[self.param.CellVoltNums-consum_num:]
            cellAsmean2=(sum(cellAs2)-max(cellAs2)-min(cellAs2))/(len(cellAs2)-2)
            
            for j in range(len(cellAs)):   #计算每个电芯的soc差
                if j<self.param.CellVoltNums-consum_num:
                    celldeltAs.append(cellAs[j]-cellAsmean1)
                else:
                    celldeltAs.append(cellAs[j]-cellAsmean2)
        else:
            cellAsmean=(sum(cellAs)-max(cellAs)-min(cellAs))/(len(cellAs)-2)
            for j in range(len(cellAs)):   #计算每个电芯的soc差
                celldeltAs.append(cellAs[j]-cellAsmean)
            
        return np.array(celldeltAs)
    
    #寻找DVDQ的峰值点，并返回..........................................................................................................................
    def _dvdq_peak(self, time, soc, cellvolt, packcrnt):
        cellvolt = self._np_move_avg(cellvolt, 3, mode="same")
        Soc = 0
        Ah = 0
        Volt = cellvolt[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.0015 and Ah>0:
                DQ_Ah.append(Ah)
                DV_Volt.append(cellvolt[m]-Volt)
                DVDQ.append((DV_Volt[-1])/Ah)
                xvolt.append(cellvolt[m])
                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=900)
        end_time=df_Data1.loc[len(time1)-1,'time']
        end_time=end_time-datetime.timedelta(seconds=1200)
        if soc2[0]<36:
            df_Data1=df_Data1[(df_Data1['SOC']>40) & (df_Data1['SOC']<80)]
        else:
            df_Data1=df_Data1[(df_Data1['time']>start_time) & (df_Data1['SOC']<80)]
        df_Data1=df_Data1[(df_Data1['XVOLT']>self.param.PeakVoltLowLmt) & (df_Data1['XVOLT']<self.param.PeakVoltUpLmt)]

        # print(packcrnt[int(len(time)/2)], min(self.celltemp))
        # ax1 = plt.subplot(3, 1, 1)
        # plt.plot(df_Data1['SOC'],df_Data1['DQ_Ah'],'g*-')
        # plt.xlabel('SOC/%')
        # plt.ylabel('DQ_Ah')
        # 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) > 1 and df_Data1.loc[PeakIndex,'XVOLT']<self.param.PeakVoltUpLmt-0.015:
                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) > 1 and df_Data1.loc[PeakIndex,'XVOLT']<self.param.PeakVoltUpLmt-0.015:
                    return df_Data1['AhSoc'][PeakIndex]
                else:
                    return 0
        else:
            return 0

    #计算每个电芯的均衡时长..........................................................................................................................
    def _bal_time(self,dict_bal):
        dict_baltime={}
        dict_baltime1={}
        for key in dict_bal:
            count=1
            x=eval(key)
            while x>0:
                if x & 1==1:    #判断最后一位是否为1
                    if count in dict_baltime.keys():
                        dict_baltime[count] = dict_baltime[count] + dict_bal[key]
                    else:
                        dict_baltime[count] = dict_bal[key]
                else:
                    pass
                count += 1
                x >>= 1    #右移一位
        
        dict_baltime=dict(sorted(dict_baltime.items(),key=lambda dict_baltime:dict_baltime[0]))
        for key in dict_baltime:    #解析均衡的电芯编号
            if self.celltype==1:    #科易6040
                if key<14:
                    dict_baltime1[key]=dict_baltime[key]
                elif key<18:
                    dict_baltime1[key-1]=dict_baltime[key]
                else:
                    dict_baltime1[key-3]=dict_baltime[key]
            elif self.celltype==1:    #科易4840
                if key<4:
                    dict_baltime1[key-1]=dict_baltime[key]
                elif key<8:
                    dict_baltime1[key-1]=dict_baltime[key]
                elif key<14:
                    dict_baltime1[key-3]=dict_baltime[key]
                elif key<18:
                    dict_baltime1[key-4]=dict_baltime[key]
                else:
                    dict_baltime1[key-6]=dict_baltime[key]
            else:
                dict_baltime1=dict_baltime
        return dict_baltime1

    #三元电池的内短路电流计算...........................................................................................................................................................
    def _ncm_intershort(self):
        df_res=pd.DataFrame(columns=['time_st', 'time_sp', 'sn', 'method','short_current','baltime'])
        df_ram_last=self.df_last
        df_ram_last1=self.df_last1
        df_ram_last3=self.df_last3

        #容量初始化
        if self.df_soh.empty:
            batsoh=(self.df_bms.loc[0,'SOH[%]'])
            capacity=self.param.Capacity*batsoh/100
        else:
            batsoh=self.df_soh.loc[len(self.df_soh)-1,'soh']
            capacity=self.param.Capacity*batsoh/100

        #参数初始化
        if df_ram_last.empty:  
            firsttime=1
            dict_bal={}
        else:
            deltsoc_last=df_ram_last.loc[0,'deltsoc']
            cellsoc_last=df_ram_last.loc[0,'cellsoc']
            time_last=df_ram_last.loc[0,'time']
            firsttime=0
            dict_bal={}
        if df_ram_last1.empty:
            firsttime1=1
            dict_bal1={}
        else:
            deltsoc_last1=df_ram_last1.loc[0,'deltsoc1']
            time_last1=df_ram_last1.loc[0,'time1']
            firsttime1=0
            dict_bal1={}
        if df_ram_last3.empty:
            standingtime=0
            standingtime1=0
            standingtime2=0
        else:
            standingtime=df_ram_last3.loc[0,'standingtime']
            standingtime1=df_ram_last3.loc[0,'standingtime1']
            standingtime2=df_ram_last3.loc[0,'standingtime2']
            dict_bal1={}
            if abs(self.packcrnt[0])<0.01 and standingtime>1 and standingtime1>1:
                standingtime=standingtime+(self.bmstime[0]-df_ram_last3.loc[0,'time3']).total_seconds()
                standingtime1=standingtime1+(self.bmstime[0]-df_ram_last3.loc[0,'time3']).total_seconds()
            else:
                pass

        for i in range(1,len(self.df_bms)-1):

            if firsttime1==0:   #满电静置算法--计算均衡状态对应的均衡时间
                try:
                    balstat=int(self.df_bms.loc[i,'单体均衡状态'])
                    if balstat>0.5:
                        bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds()  #均衡步长
                        bal_step=int(bal_step)
                        if str(balstat) in dict_bal1.keys():
                            dict_bal1[str(balstat)]=dict_bal1[str(balstat)]+bal_step
                        else:
                            dict_bal1[str(balstat)]=bal_step
                    else:
                        pass
                except:
                    dict_bal1={}
            else:
                pass

            if abs(self.packcrnt[i]) < 0.1 and abs(self.packcrnt[i-1]) < 0.1 and abs(self.packcrnt[i+1]) < 0.1:     
                delttime=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
                standingtime=standingtime+delttime
                standingtime1=standingtime1+delttime
                self._celltemp_weight(i)

                #长时间静置法计算内短路-开始.....................................................................................................................................
                if firsttime==1:    
                    if standingtime>self.StandardStandingTime*2:      #静置时间满足要求
                        standingtime=0
                        cellvolt_now=self._avgvolt_get(i)
                        if not cellvolt_now.empty:
                            cellvolt_min=min(cellvolt_now)
                            cellvolt_max=max(cellvolt_now)
                            # cellvolt_last=self._avgvolt_get(i-1)
                            # deltvolt=max(abs(cellvolt_now-cellvolt_last))
                            cellsoc_max=np.interp(cellvolt_max,self.param.LookTab_OCV,self.param.LookTab_SOC)
                            cellsoc_min=np.interp(cellvolt_min,self.param.LookTab_OCV,self.param.LookTab_SOC)

                            if 2<cellvolt_min<4.5 and 2<cellvolt_max<4.5 and (45<cellsoc_max or cellsoc_max<30) and (45<cellsoc_min or cellsoc_min<30): 
                                dict_baltime={}   #获取每个电芯的均衡时间
                                deltsoc_last, cellsoc_last=self._celldeltsoc_get(cellvolt_now,dict_baltime,capacity)
                                time_last=self.bmstime[i]
                                firsttime=0
                                df_ram_last.loc[0]=[self.sn,time_last,deltsoc_last,cellsoc_last]   #更新RAM信息
                    else:
                        pass                
                elif standingtime>3600*12:
                    standingtime=0
                    cellvolt_now=self._avgvolt_get(i)
                    if not cellvolt_now.empty:
                        cellvolt_min=min(cellvolt_now)
                        cellvolt_max=max(cellvolt_now)
                        # cellvolt_last=self._avgvolt_get(i-1)
                        # deltvolt=max(abs(cellvolt_now-cellvolt_last))
                        cellsoc_max=np.interp(cellvolt_max,self.param.LookTab_OCV,self.param.LookTab_SOC)
                        cellsoc_min=np.interp(cellvolt_min,self.param.LookTab_OCV,self.param.LookTab_SOC)
                        
                        if 2<cellvolt_min<4.5 and 2<cellvolt_max<4.5 and (45<cellsoc_max or cellsoc_max<30) and (45<cellsoc_min or cellsoc_min<30):
                            dict_baltime=self._bal_time(dict_bal)   #获取每个电芯的均衡时间
                            deltsoc_now, cellsoc_now=self._celldeltsoc_get(cellvolt_now,dict_baltime,capacity)
                            time_now=self.bmstime[i]
                            if -5<max(cellsoc_now-cellsoc_last)<5:
                                df_ram_last.loc[0]=[self.sn,time_now,deltsoc_now,cellsoc_now] #更新RAM信息
                                
                                list_sub=deltsoc_now-deltsoc_last
                                list_pud=(0.01*capacity*3600*1000)/(time_now-time_last).total_seconds()
                                leak_current=list_sub*list_pud
                                # leak_current=np.array(leak_current)
                                leak_current=np.round(leak_current,3)
                                leak_current=list(leak_current)
                                
                                df_res.loc[len(df_res)]=[time_last,time_now,self.sn,1,str(leak_current),str(dict_baltime)]  #计算结果存入Dataframe
                                time_last=time_now  #更新时间
                                deltsoc_last=deltsoc_now    #更新soc差
                                dict_bal={}
                            else:
                                firsttime=1
                else: 
                    try:  
                        balstat=int(self.df_bms.loc[i,'单体均衡状态'])
                        if balstat>0.5:
                            bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds()  #均衡步长
                            bal_step=int(bal_step)
                            if str(balstat) in dict_bal.keys():
                                dict_bal[str(balstat)]=dict_bal[str(balstat)]+bal_step
                            else:
                                dict_bal[str(balstat)]=bal_step
                        else:
                            pass
                    except:
                        dict_bal={}

                #满电静置法计算内短路-开始.....................................................................................................................................................
                if self.StandardStandingTime<standingtime1:  
                    standingtime1=0
                    cellvolt_now1=self._avgvolt_get(i)
                    if not cellvolt_now1.empty:
                        cellvolt_max1=max(cellvolt_now1)
                        cellvolt_min1=min(cellvolt_now1)
                        # cellvolt_last1=self._avgvolt_get(i-1)
                        # deltvolt1=max(abs(cellvolt_now1-cellvolt_last1))
                        cellsoc_now1=np.interp(cellvolt_max1,self.param.LookTab_OCV,self.param.LookTab_SOC)

                        if cellsoc_now1>self.param.FullChrgSoc-10 and 2<cellvolt_min1<4.5 and 2<cellvolt_max1<4.5:
                            if firsttime1==1:
                                dict_baltime1={}   #获取每个电芯的均衡时间
                                deltsoc_last1, cellsoc_last1=self._celldeltsoc_get(cellvolt_now1,dict_baltime1,capacity)
                                time_last1=self.bmstime[i]
                                firsttime1=0
                                df_ram_last1.loc[0]=[self.sn,time_last1,deltsoc_last1]    #更新RAM信息
                            else:
                                dict_baltime1=self._bal_time(dict_bal1)   #获取每个电芯的均衡时间
                                time_now1=self.bmstime[i]
                                if (time_now1-time_last1).total_seconds()>3600*20:
                                    deltsoc_now1, cellsoc_now1=self._celldeltsoc_get(cellvolt_now1,dict_baltime1,capacity)
                                    df_ram_last1.loc[0]=[self.sn,time_now1,deltsoc_now1] #更新RAM信息

                                    list_sub1=deltsoc_now1-deltsoc_last1
                                    list_pud1=(0.01*capacity*3600*1000)/(time_now1-time_last1).total_seconds()
                                    leak_current1=list_sub1*list_pud1
                                    # leak_current1=np.array(leak_current1)
                                    leak_current1=np.round(leak_current1,3)
                                    leak_current1=list(leak_current1)
                                    
                                    df_res.loc[len(df_res)]=[time_last1,time_now1,self.sn,2,str(leak_current1),str(dict_baltime1)]  #计算结果存入Dataframe
                                    time_last1=time_now1  #更新时间
                                    deltsoc_last1=deltsoc_now1    #更新soc差
                                    dict_bal1={}
                                else:
                                    pass
                    else:
                        pass
                else:   
                    pass

            else:
                df_ram_last=pd.DataFrame(columns=['sn','time','deltsoc','cellsoc'])   #电流>0,清空上次静置的SOC差
                dict_bal={} 
                firsttime=1
                standingtime=0
                standingtime1=0
                pass
        
        #更新RAM的standingtime
        df_ram_last3.loc[0]=[self.sn,self.bmstime[len(self.bmstime)-1],standingtime,standingtime1,standingtime2]

        #返回计算结果
        if df_res.empty:    
            return pd.DataFrame(), df_ram_last, df_ram_last1, df_ram_last3
        else:
            return df_res, df_ram_last, df_ram_last1, df_ram_last3

    #磷酸铁锂电池内短路计算程序.............................................................................................................................
    def _lfp_intershort(self):
        column_name=['time_st', 'time_sp', 'sn', 'method','short_current','baltime']
        df_res=pd.DataFrame(columns=column_name)
        df_ram_last=self.df_last
        df_ram_last1=self.df_last1
        df_ram_last2=self.df_last2
        df_ram_last3=self.df_last3
        df_ram_lfp=pd.DataFrame(columns=self.df_bms.columns.tolist())

        #容量初始化
        if self.df_soh.empty:
            batsoh=(self.df_bms.loc[0,'SOH[%]'])
            capacity=self.param.Capacity*batsoh/100
        else:
            batsoh=self.df_soh.loc[len(self.df_soh)-1,'soh']
            capacity=self.param.Capacity*batsoh/100
        #参数初始化
        if df_ram_last.empty:  
            firsttime=1
            dict_bal={}
        else:
            deltsoc_last=df_ram_last.loc[0,'deltsoc']
            cellsoc_last=df_ram_last.loc[0,'cellsoc']
            time_last=df_ram_last.loc[0,'time']
            firsttime=0
            dict_bal={}
        if df_ram_last1.empty:
            firsttime1=1
            dict_bal1={}
        else:
            deltsoc_last1=df_ram_last1.loc[0,'deltsoc1']
            time_last1=df_ram_last1.loc[0,'time1']
            firsttime1=0
            dict_bal1={}
        if df_ram_last2.empty:
            firsttime2=1
            charging=0
            dict_bal2={}
        else:
            deltAs_last2=df_ram_last2.loc[0,'deltAs2']
            time_last2=df_ram_last2.loc[0,'time2']
            firsttime2=0
            charging=0
            dict_bal2={}
        if df_ram_last3.empty:
            standingtime=0
            standingtime1=0
            standingtime2=0
        else:
            standingtime=df_ram_last3.loc[0,'standingtime']
            standingtime1=df_ram_last3.loc[0,'standingtime1']
            standingtime2=df_ram_last3.loc[0,'standingtime2']
            dict_bal1={}
            if abs(self.packcrnt[0])<0.01 and standingtime>1 and standingtime1>1:
                standingtime=standingtime+(self.bmstime[0]-df_ram_last3.loc[0,'time3']).total_seconds()
                standingtime1=standingtime1+(self.bmstime[0]-df_ram_last3.loc[0,'time3']).total_seconds()
            else:
                pass

        for i in range(1,len(self.df_bms)-1):

            #静置法计算内短路..........................................................................................................................
            if firsttime1==0:   #满电静置算法--计算均衡状态对应的均衡时间
                try:
                    balstat=int(self.df_bms.loc[i,'单体均衡状态'])
                    if balstat>0.5:
                        bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds()  #均衡步长
                        bal_step=int(bal_step)
                        if str(balstat) in dict_bal1.keys():
                            dict_bal1[str(balstat)]=dict_bal1[str(balstat)]+bal_step
                        else:
                            dict_bal1[str(balstat)]=bal_step
                    else:
                        pass
                except:
                    dict_bal1={}
            else:
                pass

            if abs(self.packcrnt[i]) < 0.1 and abs(self.packcrnt[i-1]) < 0.1 and abs(self.packcrnt[i+1]) < 0.1:     
                delttime=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
                standingtime=standingtime+delttime
                standingtime1=standingtime1+delttime
                self._celltemp_weight(i)

                #长时间静置法计算内短路-开始.....................................................................................................................................
                if firsttime==1:    
                    if standingtime>self.StandardStandingTime:      #静置时间满足要求
                        standingtime=0
                        cellvolt_now=self._avgvolt_get(i)
                        if not cellvolt_now.empty:
                            cellvolt_min=min(cellvolt_now)
                            cellvolt_max=max(cellvolt_now)
                            # cellvolt_last=self._avgvolt_get(i-1)
                            # deltvolt=max(abs(cellvolt_now-cellvolt_last))
                            cellsoc_max=np.interp(cellvolt_max,self.param.LookTab_OCV,self.param.LookTab_SOC)
                            cellsoc_min=np.interp(cellvolt_min,self.param.LookTab_OCV,self.param.LookTab_SOC)

                            if cellsoc_max<self.param.SocInflexion1-2 and 12<cellsoc_min:
                                dict_baltime={}  #获取每个电芯的均衡时间
                                deltsoc_last, cellsoc_last=self._celldeltsoc_get(cellvolt_now,dict_baltime,capacity)
                                time_last=self.bmstime[i]
                                firsttime=0
                                df_ram_last.loc[0]=[self.sn,time_last,deltsoc_last,cellsoc_last]   #更新RAM信息
                            else:
                                pass
                    else:
                        pass                
                elif standingtime>3600*12:
                    standingtime=0
                    cellvolt_now=self._avgvolt_get(i)
                    if not cellvolt_now.empty:
                        cellvolt_min=min(cellvolt_now)
                        cellvolt_max=max(cellvolt_now)
                        # cellvolt_last=np.array(self._avgvolt_get(i-1))
                        # deltvolt=max(abs(cellvolt_now-cellvolt_last))
                        cellsoc_max=np.interp(cellvolt_max,self.param.LookTab_OCV,self.param.LookTab_SOC)
                        cellsoc_min=np.interp(cellvolt_min,self.param.LookTab_OCV,self.param.LookTab_SOC)

                        if cellsoc_max<self.param.SocInflexion1-2 and 12<cellsoc_min:
                            dict_baltime=self._bal_time(dict_bal)   #获取每个电芯的均衡时间
                            deltsoc_now, cellsoc_now=self._celldeltsoc_get(cellvolt_now, dict_baltime,capacity)    #获取每个电芯的SOC差
                            time_now=self.bmstime[i]
                            if -5<max(cellsoc_now-cellsoc_last)<5:
                                df_ram_last.loc[0]=[self.sn,time_now,deltsoc_now,cellsoc_now]   #更新RAM信息

                                list_sub=deltsoc_now-deltsoc_last
                                list_pud=(0.01*capacity*3600*1000)/(time_now-time_last).total_seconds()
                                leak_current=list_sub*list_pud
                                # leak_current=np.array(leak_current)
                                leak_current=np.round(leak_current,3)
                                leak_current=list(leak_current)
                                
                                df_res.loc[len(df_res)]=[time_last,time_now,self.sn,1,str(leak_current),str(dict_baltime)]  #计算结果存入Dataframe
                                time_last=time_now  #更新时间
                                deltsoc_last=deltsoc_now    #更新soc差
                                dict_bal={}
                            else:
                                firsttime=1
                        else:
                            pass
                else: 
                    try:  
                        balstat=int(self.df_bms.loc[i,'单体均衡状态'])
                        if balstat>0.5:
                            bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds()  #均衡步长
                            bal_step=int(bal_step)
                            if str(balstat) in dict_bal.keys():
                                dict_bal[str(balstat)]=dict_bal[str(balstat)]+bal_step
                            else:
                                dict_bal[str(balstat)]=bal_step
                        else:
                            pass
                    except:
                        dict_bal={}

                #非平台区间静置法计算内短路-开始.....................................................................................................................................................
                if standingtime1>self.StandardStandingTime: 
                    standingtime1=0
                    cellvolt_now1=self._avgvolt_get(i)
                    if not cellvolt_now1.empty:
                        cellvolt_max1=max(cellvolt_now1)
                        cellvolt_min1=min(cellvolt_now1)
                        # cellvolt_last1=self._avgvolt_get(i-1)
                        # deltvolt1=max(abs(cellvolt_now1-cellvolt_last1))
                        cellsoc_max1=np.interp(cellvolt_max1,self.param.LookTab_OCV,self.param.LookTab_SOC)
                        cellsoc_min1=np.interp(cellvolt_min1,self.param.LookTab_OCV,self.param.LookTab_SOC)
                    
                        if cellsoc_max1<self.param.SocInflexion1-2 and 12<cellsoc_min1:
                            if firsttime1==1:
                                dict_baltime1=self._bal_time(dict_bal1)   #获取每个电芯的均衡时间
                                deltsoc_last1, cellsoc_last1=self._celldeltsoc_get(cellvolt_now1,dict_baltime1,capacity)
                                time_last1=self.bmstime[i]
                                firsttime1=0
                                df_ram_last1.loc[0]=[self.sn,time_last1,deltsoc_last1]    #更新RAM信息
                            else:
                                dict_baltime1=self._bal_time(dict_bal1)   #获取每个电芯的均衡时间
                                deltsoc_now1, cellsoc_now1=self._celldeltsoc_get(cellvolt_now1,dict_baltime1,capacity)
                                time_now1=self.bmstime[i]
                                df_ram_last1.loc[0]=[self.sn,time_now1,deltsoc_now1]    #更新RAM信息

                                if (time_now1-time_last1).total_seconds()>3600*24:
                                    list_sub1=deltsoc_now1-deltsoc_last1
                                    list_pud1=(0.01*capacity*3600*1000)/(time_now1-time_last1).total_seconds()
                                    leak_current1=list_sub1*list_pud1
                                    # leak_current1=np.array(leak_current1)
                                    leak_current1=np.round(leak_current1,3)
                                    leak_current1=list(leak_current1)
                                    
                                    df_res.loc[len(df_res)]=[time_last1,time_now1,self.sn,2,str(leak_current1),str(dict_baltime1)]  #计算结果存入Dataframe
                                    time_last1=time_now1  #更新时间
                                    deltsoc_last1=deltsoc_now1    #更新soc差
                                    dict_bal1={}
                                else:
                                    pass
                        else:
                            pass
                else:   
                    pass

            else:
                df_ram_last=pd.DataFrame(columns=['sn','time','deltsoc','cellsoc'])   #电流>0,清空上次静置的SOC差
                dict_bal={} 
                firsttime=1
                standingtime=0
                standingtime1=0
                pass

            #获取充电数据——开始..............................................................................................................
            try:
                balstat=int(self.df_bms.loc[i,'单体均衡状态'])  #统计均衡状态
                if balstat>0.5:
                    bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds()  #均衡步长
                    bal_step=int(bal_step)
                    if str(balstat) in dict_bal2.keys():
                        dict_bal2[str(balstat)]=dict_bal2[str(balstat)]+bal_step
                    else:
                        dict_bal2[str(balstat)]=bal_step
                else:
                    pass
            except:
                dict_bal2={}

            #判断充电状态
            if self.packcrnt[i]<=-1 and self.packcrnt[i+1]<=-1 and self.packcrnt[i-1]<=-1:
                if charging==0:
                    if self.bms_soc[i]<41:
                        cellvolt_now=self._cellvolt_get(i)
                        if min(cellvolt_now)<self.param.CellFullChrgVolt-0.15:
                            charging=1
                            chrg_start=i
                        else:
                            pass
                    else:
                        pass

                else: #充电中
                    cellvolt_now=self._cellvolt_get(i)
                    if (self.bmstime[i+1]-self.bmstime[i]).total_seconds()>180 or (self.packcrnt[i]>self.param.Capacity/2 and self.packcrnt[i+1]>self.param.Capacity/2):  #如果充电过程中时间间隔>180s，则舍弃该次充电
                        charging=0
                        continue
                    elif min(cellvolt_now)>self.param.CellFullChrgVolt-0.13:   #电压>满充电压-0.13V，即3.37V
                        self._celltemp_weight(i)
                        if i-chrg_start>10 and self.celltemp>20:
                            chrg_end=i+1
                            charging=0

                            #计算漏电流值...................................................................
                            if firsttime2==1:
                                dict_baltime={}
                                deltAs_last2=self._cellDeltAs_get(chrg_start,chrg_end,dict_baltime)
                                time_last2=self.bmstime[chrg_end]
                                df_ram_last2.loc[0]=[self.sn,time_last2,deltAs_last2]    #更新RAM信息
                            else:
                                dict_baltime=self._bal_time(dict_bal2)   #获取每个电芯的均衡时间
                                deltAs_now2=self._cellDeltAs_get(chrg_start,chrg_end,dict_baltime)  #获取每个电芯的As差
                                time_now2=self.bmstime[chrg_end]
                                df_ram_last2.loc[0]=[self.sn,time_now2,deltAs_now2]    #更新RAM信息

                                list_sub2=deltAs_now2-deltAs_last2
                                list_pud2=-1000/(time_now2-time_last2).total_seconds()
                                leak_current2=list_sub2*list_pud2
                                # leak_current=np.array(leak_current)
                                leak_current2=np.round(leak_current2,3)
                                leak_current2=list(leak_current2)

                                df_res.loc[len(df_res)]=[time_last2,time_now2,self.sn,3,str(leak_current2),str(dict_baltime)]  #计算结果存入Dataframe
                                deltAs_last2=deltAs_now2
                                time_last2=time_now2
                                dict_bal2={}

                        else:
                            charging=0
                            continue
                    # elif min(cellvolt_now)>self.param.CellFullChrgVolt-0.1:   #电压>满充电压
                    #     self._celltemp_weight(i)
                    #     if i-chrg_start>10 and self.celltemp>10:
                    #         chrg_end=i+1
                    #         charging=0

                    #         #计算漏电流值...................................................................
                    #         if firsttime2==1:
                    #             dict_baltime={}
                    #             peaksoc_list=[]
                    #             for j in range(1, self.param.CellVoltNums + 1):
                    #                 cellvolt = self._singlevolt_get(i,j,2)  #取单体电压j的所有电压值
                    #                 cellvolt = list(cellvolt[chrg_start:chrg_end])
                    #                 time = list(self.bmstime[chrg_start:chrg_end])
                    #                 packcrnt = list(self.packcrnt[chrg_start:chrg_end])
                    #                 soc = list(self.bms_soc[chrg_start:chrg_end])
                    #                 peaksoc = self._dvdq_peak(time, soc, cellvolt, packcrnt)
                    #                 if peaksoc>1:
                    #                     peaksoc_list.append(peaksoc)
                    #                 else:
                    #                     break
                    #             if len(peaksoc_list)==self.param.CellVoltNums:
                    #                 celldeltsoc=[]
                    #                 consum_num=10
                    #                 cellsoc1=peaksoc_list[:self.param.CellVoltNums-consum_num]    #切片，将bms耗电的电芯和非耗电的电芯分离开
                    #                 cellsocmean1=(sum(cellsoc1)-max(cellsoc1)-min(cellsoc1))/(len(cellsoc1)-2)
                    #                 cellsoc2=peaksoc_list[self.param.CellVoltNums-consum_num:]
                    #                 cellsocmean2=(sum(cellsoc2)-max(cellsoc2)-min(cellsoc2))/(len(cellsoc2)-2)
                                    
                    #                 for j in range(len(peaksoc_list)):   #计算每个电芯的soc差
                    #                     if j<self.param.CellVoltNums-consum_num:
                    #                         celldeltsoc.append(peaksoc_list[j]-cellsocmean1)
                    #                     else:
                    #                         celldeltsoc.append(peaksoc_list[j]-cellsocmean2)
                    #                 deltsoc_last2=celldeltsoc
                    #                 time_last2=self.bmstime[chrg_end]
                    #                 df_ram_last2.loc[0]=[self.sn,time_last2,deltsoc_last2]    #更新RAM信息
                    #         else:
                    #             dict_baltime=self._bal_time(dict_bal2)   #获取每个电芯的均衡时间
                    #             peaksoc_list=[]
                    #             for j in range(1, self.param.CellVoltNums + 1):
                    #                 cellvolt = self._singlevolt_get(i,j,2)  #取单体电压j的所有电压值
                    #                 cellvolt = list(cellvolt[chrg_start:chrg_end])
                    #                 time = list(self.bmstime[chrg_start:chrg_end])
                    #                 packcrnt = list(self.packcrnt[chrg_start:chrg_end])
                    #                 soc = list(self.bms_soc[chrg_start:chrg_end])
                    #                 peaksoc = self._dvdq_peak(time, soc, cellvolt, packcrnt)
                    #                 if peaksoc>1:
                    #                     peaksoc_list.append(peaksoc)
                    #                 else:
                    #                     break
                    #             if len(peaksoc_list)==self.param.CellVoltNums:
                    #                 celldeltsoc=[]
                    #                 consum_num=10
                    #                 cellsoc1=peaksoc_list[:self.param.CellVoltNums-consum_num]    #切片，将bms耗电的电芯和非耗电的电芯分离开
                    #                 cellsocmean1=(sum(cellsoc1)-max(cellsoc1)-min(cellsoc1))/(len(cellsoc1)-2)
                    #                 cellsoc2=peaksoc_list[self.param.CellVoltNums-consum_num:]
                    #                 cellsocmean2=(sum(cellsoc2)-max(cellsoc2)-min(cellsoc2))/(len(cellsoc2)-2)
                                    
                    #                 for j in range(len(peaksoc_list)):   #计算每个电芯的soc差
                    #                     if j<self.param.CellVoltNums-consum_num:
                    #                         celldeltsoc.append(peaksoc_list[j]-cellsocmean1)
                    #                     else:
                    #                         celldeltsoc.append(peaksoc_list[j]-cellsocmean2)
                    #                 deltsoc_now2=celldeltsoc
                    #                 time_now2=self.bmstime[chrg_end]
                    #                 df_ram_last2.loc[0]=[self.sn,time_now2,deltsoc_now2]    #更新RAM信息

                    #                 list_sub2=deltsoc_now2-deltsoc_last2
                    #                 list_pud2=(0.01*capacity*3600*1000)/(time_now2-time_last2).total_seconds()
                    #                 leak_current2=list_sub2*list_pud2
                    #                 leak_current2=np.round(leak_current2,3)
                    #                 leak_current2=list(leak_current2)

                    #                 df_res.loc[len(df_res)]=[time_last2,time_now2,self.sn,3,str(leak_current2),str(dict_baltime)]  #计算结果存入Dataframe
                    #                 deltsoc_last2=deltsoc_now2
                    #                 time_last2=time_now2
                    #                 dict_bal2={}
                        
                    #     else:
                    #         charging=0
                    #         continue

                    elif i==len(self.df_bms)-2:  #数据中断后仍在充电，将前段充电数据写入RAM
                        df_ram_lfp=self.df_bms.iloc[chrg_start:]
                        df_ram_lfp['sn']=self.sn
                    else:
                        pass
            else:
                pass

    
        #更新RAM
        df_ram_last3.loc[0]=[self.sn,self.bmstime[len(self.bmstime)-1],standingtime,standingtime1,standingtime2]

        #返回结果
        if df_res.empty:    
            return pd.DataFrame(), df_ram_last, df_ram_last1, df_ram_last2, df_ram_last3,df_ram_lfp
        else:
            return df_res, df_ram_last, df_ram_last1, df_ram_last2, df_ram_last3, df_ram_lfp