123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- import pandas as pd
- import numpy as np
- import bisect
- import datetime
- import matplotlib.pyplot as plt
- import matplotlib.dates as mdates
- import BatParam
- class BatChrg:
- def __init__(self,sn,celltype,df_bms,df_volt,df_temp,df_accum): #参数初始化
- self.sn=sn
- self.celltype=celltype
- self.param=BatParam.BatParam(celltype)
- self.df_volt=df_volt
- self.df_temp=df_temp
- self.df_bms=df_bms
- self.packcrnt=(df_volt['可充电储能装置电流(A)'].astype('float'))*self.param.PackCrntDec
- self.packvolt=df_volt['可充电储能装置电压(V)'].astype('float')
- self.bms_soc=df_bms['SOC']
- self.bmsstat=df_bms['充电状态']
- self.bmstime= pd.to_datetime(df_volt['上报时间'], format='%Y-%m-%d %H:%M:%S')
- self.param.CellVoltNums=int(df_volt.loc[5,'单体电池总数'])
- self.param.CellTempNums=int(df_temp.loc[5,'可充电储能温度探针个数'])
- self.param.PackVoltOvLv1=self.param.CellOvLv1*self.param.CellVoltNums
- self.param.PackVoltOvLv2=self.param.CellOvLv2*self.param.CellVoltNums
- self.param.PackVoltUvLv1=self.param.CellUvLv1*self.param.CellVoltNums
- self.param.PackVoltUvLv2=self.param.CellUvLv2*self.param.CellVoltNums
-
- def chrg(self):
- if self.celltype==1 or self.celltype==2 or self.celltype==3 or self.celltype==4 or self.celltype==100:
- df_res=self._ncm_chrg()
- return df_res
-
- elif self.celltype==99:
- df_res=self._lfp_diag()
- return df_res
-
- else:
- return pd.DataFrame()
- #定义滑动滤波函数.............................................................................................
- def _np_move_avg(self,a, n, mode="same"):
- return (np.convolve(a, np.ones((n,)) / n, mode=mode))
-
- #寻找当前行数据的所有温度值...................................................................................
- def _celltemp_get(self,num):
- celltemp = []
- for j in range(1, self.param.CellTempNums+1):
- celltemp.append(self.df_temp.loc[num,str(j)+'.0'])
- return celltemp
- #获取当前行所有电压数据........................................................................................
- def _cellvolt_get(self,num):
- cellvolt=[]
- for j in range(1, self.param.CellVoltNums+1):
- cellvolt.append(self.df_volt.loc[num, str(j)+'.0'])
- return cellvolt
-
- #筛选充电数据..............................................................................................................................
- def _chrgdata(self):
- self.ChgStart=[]
- self.ChgEnd=[]
- if len(self.packvolt)>100:
- charging=0
- for i in range(3, len(self.bmstime) - 3):
- if charging==0:
- if i==3 and self.bmsstat[i]=='停车充电' and self.bmsstat[i+1]=='停车充电':
- self.ChgStart.append(i)
- charging=1
- elif self.bmsstat[i-1]!='停车充电' and self.bmsstat[i]=='停车充电':
- self.ChgStart.append(i)
- charging=1
- else:
- pass
- else:
- if (self.bmsstat[i-1]=='停车充电' or '充电完成') and self.packcrnt[i]>0:
- self.ChgEnd.append(i)
- charging=0
- elif i == (len(self.bmstime) - 4) and (self.bmsstat[i] == '停车充电' or '充电完成') and self.packcrnt[i]<-1:
- self.ChgEnd.append(len(self.bmstime)-2)
- charging=0
-
- #dvdq方法计算soh...........................................................................................................................
- def _dvdq_soh(self, chrg_st, chrg_end,cellvolt):
- Ah = 0 #参数赋初始值
- Volt = cellvolt[chrg_st]
- DV_Volt=[]
- DQ_Ah = []
- DVDQ = []
- time2 = []
- soc2 = []
- Ah_tatal=[0]
- xvolt=[]
- #计算DV和DQ值
- for j in range(chrg_st,chrg_end):
- Step=(self.bmstime[j+1]-self.bmstime[j]).total_seconds()
- Ah=Ah-self.packcrnt[j]*Step/3600
- if (cellvolt[j]-Volt)>0.002 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(self.bmstime[j])
- soc2.append(float(self.bms_soc[j].strip('%')))
- #切片,去除前后10min的数据
- df_Data1 = pd.DataFrame({'time': time2,
- 'SOC': soc2,
- 'DVDQ': DVDQ,
- 'Ah_tatal': Ah_tatal[:-1],
- '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(time2)-1,'time']
- end_time=end_time-datetime.timedelta(seconds=600)
- # 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['time']<end_time)]
- # df_Data1=df_Data1[(df_Data1['XVOLT']>self.param.PeakVoltLowLmt) & (df_Data1['XVOLT']<self.param.PeakVoltUpLmt)]
- # plt.figure()
- # print(self.packcrnt[int((chrg_st+chrg_end)/2)], min(self.celltemp))
- # 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(2, 1, 1)
- plt.plot(df_Data1['SOC'],df_Data1['XVOLT'],'y*-')
- plt.xlabel('SOC/%')
- plt.ylabel('Volt/V')
- plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
- plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
- plt.legend()
- ax1 = plt.subplot(2, 1, 2)
- plt.plot(df_Data1['SOC'], df_Data1['DVDQ'], 'r*-')
- plt.xlabel('SOC/%')
- plt.ylabel('析锂指标')
- plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
- plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
- plt.legend()
- # plt.show()
- #..........................................三元电池充电画像.....................。。。......................................
- def _ncm_chrg(self):
-
-
- if not self.df_volt.empty:
- self._chrgdata()
- print(self.ChgStart,self.ChgEnd)
- # name=str(self.sn)
- # with pd.ExcelWriter(r'D:\00WorkSpace\01Python\data_analyze_platform\USER\03hezhong\99Result\\'+name+'.xlsx') as writer:
-
- for i in range(len(self.ChgStart)):
- # df_chgvolt=pd.DataFrame()
- # chrg_time=self.df_volt['上报时间'][self.ChgStart[i]:self.ChgEnd[i]]
- # chrg_soc=self.df_bms['SOC'][self.ChgStart[i]:self.ChgEnd[i]]
- # chrg_crnt=self.df_bms['总电流(A)'][self.ChgStart[i]:self.ChgEnd[i]]
- for k in range(1, self.param.CellVoltNums+1):
- s = str(k)
- cellvolt = self.df_volt[s+'.0']
- self._dvdq_soh(self.ChgStart[i],self.ChgEnd[i],cellvolt) #dvdq计算soh
- plt.show()
-
- # plt.figure(figsize=(20,10))
- # ax1 = plt.subplot(3, 1, 1)
- # plt.plot(chrg_soc,'y*-')
- # plt.ylabel('SOC/A')
- # plt.legend()
- # plt.title(str(self.sn)+str(self.df_volt.loc[self.ChgStart[i],'上报时间']))
- # ax2 = plt.subplot(3, 1, 2)
- # plt.plot(chrg_crnt,'y*-')
- # plt.ylabel('Crnt/A')
- # plt.legend()
- # for j in range(1, self.param.CellTempNums+1):
- # celltemp=self.df_temp[str(j)+'.0'][self.ChgStart[i]:self.ChgEnd[i]]
- # ax3 = plt.subplot(3, 1, 3)
- # plt.plot(celltemp,'y*-')
- # plt.xlabel('time')
- # plt.ylabel('Temp/℃')
- # plt.legend()
- # plt.savefig('./'+str(self.sn)+str(i)+'电流温度.png')
-
- # plt.figure()
- # for j in range(1, self.param.CellVoltNums+1):
- # cellvolt=self.df_volt[str(j)+'.0'][self.ChgStart[i]:self.ChgEnd[i]]
- # df_chgvolt[j]=cellvolt
- # df_chgvolt.plot(linestyle=':',marker='*', figsize=(30,10))
- # plt.title(str(self.sn)+str(self.df_volt.loc[self.ChgStart[i],'上报时间']))
- # plt.savefig('./'+str(self.sn)+str(i)+'电压.png')
- # if j <13:
- # color1='r'
- # elif j<25:
- # color1='orange'
- # elif j<37:
- # color1='y'
- # elif j<49:
- # color1='g'
- # elif j<61:
- # color1='c'
- # elif j<73:
- # color1='b'
- # elif j<85:
- # color1='m'
- # else:
- # color1='pink'
- # cellvolt=self.df_volt[str(j)+'.0'][self.ChgStart[i]:self.ChgEnd[i]]
- # # ax1 = plt.subplot(3, 1, 1)
- # plt.plot(chrg_time,cellvolt,color=color1,linestyle='-',marker='*')
- # plt.xlabel('SOC/%')
- # plt.ylabel('Volt/V')
- # plt.legend(loc='upper left')
- # plt.title(str(self.sn)+str(self.df_volt.loc[self.ChgStart[i],'上报时间']))
- # 标准差计算及电芯电压排序...................................................................................
- # std_error=[]
- # df_rank=pd.DataFrame(columns=list(range(1,self.param.CellVoltNums+1)))
- # for j in range(self.ChgStart[i],self.ChgEnd[i]):
- # cellvolt=self._cellvolt_get(j)
- # std_error.append(np.std(cellvolt,ddof=1)) #标准差计算
- # cellvolt=pd.Series(cellvolt)
- # cellvolt_rank=(cellvolt.rank(method='min')).tolist()
- # df_rank.loc[len(df_rank)]=cellvolt_rank
- # for j in range(1,self.param.CellVoltNums+1):
- # df_rank[j].plot(linestyle='-',marker='*')
- # # plt.legend()
- # # plt.title(str(self.sn)+str(self.df_volt.loc[self.ChgStart[i],'上报时间']))
- # # plt.savefig('./'+str(self.sn)+str(i)+'电压排名.png')
- # # plt.show()
-
- # sheetname=str(self.df_volt.loc[self.ChgStart[i],'上报时间']).replace(':','-')
- # df_rank.to_excel(writer,sheet_name=sheetname)
-
- # writer.save()
- # writer.close()
-
- # plt.figure(figsize=(20,10))
- # plt.plot(std_error,'r*-')
- # plt.xlabel('time')
- # plt.ylabel('std_error')
- # plt.legend()
- # plt.title(str(self.sn)+str(self.df_volt.loc[self.ChgStart[i],'上报时间']))
- # plt.savefig('./'+str(self.sn)+str(i)+'标准差.png')
-
-
-
-
-
- return pd.DataFrame()
-
-
-
|