soc_total.py 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. from ctypes import Structure
  2. from re import M
  3. import pandas as pd
  4. import numpy as np
  5. import datetime
  6. import time, datetime
  7. import matplotlib.pyplot as plt
  8. from pylab import*
  9. from scipy.signal import savgol_filter
  10. from scipy import interpolate
  11. import os
  12. from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import BatParam
  13. class chrgr_statistic:
  14. def __init__(self,sn,celltype,df_bms): #参数初始化
  15. self.sn=sn
  16. self.celltype=celltype
  17. self.param=BatParam.BatParam(celltype)#鹏飞param中为BatParam,学琦为BatteryInfo
  18. self.df_bms=pd.DataFrame(df_bms)
  19. self.packcrnt=df_bms['总电流[A]']*self.param.PackCrntDec
  20. self.packvolt=df_bms['总电压[V]']
  21. self.bms_soc=df_bms['SOC[%]']
  22. self.bmstime= pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
  23. self.LookTab_OCV = self.param.LookTab_OCV
  24. self.LookTab_SOC = self.param.LookTab_SOC
  25. self.packcrnt_flg = self.param.PackCrntDec#判断充放电电流方向,一般放电为正,充电为负
  26. self.cellvolt_list=['单体电压'+str(x) for x in range(1,self.param.CellVoltNums+1)]
  27. self.celltemp_name=['单体温度'+str(x) for x in range(1,self.param.CellTempNums+1)]
  28. self.bmssta = df_bms['充电状态']
  29. #定义加权滤波函数..................................................................................................
  30. def moving_average(interval, windowsize):
  31. window = np.ones(int(windowsize)) / float(windowsize)
  32. re = np.convolve(interval, window, 'same')
  33. return re
  34. #.............................................充电行为统计............................................................................
  35. def chrgr_soc_sta(self):
  36. start_time = time.time()
  37. df_chrgr_soc = pd.DataFrame(columns = ['sn', 'time', 'chrgr_soc', 'chrgr_volt', 'temp', 'full_chrgr_num'])
  38. data = self.df_bms
  39. data.fillna(0, inplace = True)
  40. crnt_flg = self.packcrnt_flg
  41. LookTab_OCV = self.LookTab_OCV
  42. LookTab_SOC = self.LookTab_SOC
  43. #----------------------------------------区分充放电数据----------------------------------------------------------------------
  44. df_soc = data['SOC[%]']
  45. df_soc_len = len(df_soc)
  46. df_soc_add = df_soc.iloc[df_soc_len-3:df_soc_len-1]#由于对SOC二次微分,增加两行数据
  47. df_soc_new = df_soc.append(df_soc_add)
  48. df_soc_new_dif = np.diff(df_soc_new,axis=0)#SOC一次微分,判断升降
  49. df_soc_new_dif = pd.DataFrame(df_soc_new_dif)
  50. df_soc_new_dif[df_soc_new_dif > 0] = 1#SOC升高
  51. df_soc_new_dif[df_soc_new_dif == 0] = 0#SOC升高或静置
  52. df_soc_new_dif[df_soc_new_dif < 0] = -1#SOC下降
  53. df_soc_dif_arr = np.array(df_soc_new_dif)
  54. pos_change = nonzero(df_soc_dif_arr)#寻找非零元素位置
  55. value_change = df_soc_dif_arr[pos_change[0]]#非零元素数值
  56. #-------------------------------------------------------利用soc的升降判断充放电---------------------------------------------------------
  57. pos_change_dif = np.diff(pos_change[0])#计算SOC变化时的位置信息
  58. pos_change_del_temp = np.where(pos_change_dif < 10)
  59. pos_change_del = pos_change_del_temp[0] + 1
  60. value_change_new = np.delete(value_change[:,0], pos_change_del)#SOC发生变化数值
  61. pos_change_new = np.delete(pos_change[0], pos_change_del)#SOC发生变化位置
  62. value_change_new_dif = np.diff(value_change_new)#寻找充电或放电结束位置
  63. if len(value_change_new_dif) > 0:
  64. value_change_new_dif = np.insert(value_change_new_dif, 0, value_change_new_dif[0])
  65. chrgr_dischrgr_pos_temp = np.where(abs(value_change_new_dif) == 2)#寻找充电或放电结束位置
  66. splice_num = []
  67. if len(chrgr_dischrgr_pos_temp[0]) >= 1:
  68. chrgr_dischrgr_pos = pos_change_new[chrgr_dischrgr_pos_temp[0]]#原数据中充电或放电结束位置
  69. chrgr_dischrgr_pos = np.insert(chrgr_dischrgr_pos, 0, 0)
  70. # data_len = len(df_soc)#数据长度
  71. pos_len = len(chrgr_dischrgr_pos)#切片长度
  72. chrgr_dischrgr_pos = np.insert(chrgr_dischrgr_pos, pos_len, df_soc_len-1)#
  73. for item in range(0,len(chrgr_dischrgr_pos)-1):
  74. splice_num.extend(item*np.ones(chrgr_dischrgr_pos[item +1]-chrgr_dischrgr_pos[item]))
  75. splice_num = np.insert(splice_num, df_soc_len-2, item)
  76. else:
  77. splice_num = np.zeros(df_soc_len)
  78. # pos_ful = np.array([0])
  79. data['stat'] = splice_num
  80. #--------------------------------------------------------筛选充电数据与放电数据-------------------------------------
  81. chrgr_data = pd.DataFrame()
  82. dischrgr_data = pd.DataFrame()
  83. for num_chrgr in range(0,len(set(splice_num))-1):
  84. df_data_temp = data.loc[(data['stat'] == num_chrgr)]
  85. df_data_temp = df_data_temp.reset_index(drop = True)
  86. df_soc_temp = df_data_temp['SOC[%]']
  87. if len(df_soc_temp) > 10:
  88. if (df_soc_temp.iloc[-1] - df_soc_temp.iloc[0]) > 10:#筛选SOC增大的区间段,认为是一次充电
  89. # chrgr_data_temp = df_data_temp.loc[df_data_temp['总电流[A]'] >= 0]
  90. chrgr_data = chrgr_data.append(df_data_temp)
  91. chrgr_data = chrgr_data.reset_index(drop = True)
  92. else:
  93. # dischrgr_data_temp = df_data_temp.loc[df_data_temp['总电流[A]'] <= 0]#筛选具有放电电流的放电数据
  94. dischrgr_data = dischrgr_data.append(df_data_temp)
  95. dischrgr_data = dischrgr_data.reset_index(drop = True)
  96. else:
  97. dischrgr_data = dischrgr_data.append(df_data_temp)
  98. dischrgr_data = dischrgr_data.reset_index(drop = True)
  99. if len(chrgr_data) > 1:
  100. chrgr_num_difference = np.unique(chrgr_data['stat'])#充电过程有几段数据
  101. #---------------------------------------------------统计充电截止电压、充电SOC区间---------------------------------------------------------
  102. cell_name = self.cellvolt_list#电芯电压名称
  103. temp_name = self.celltemp_name
  104. full_chrgr_num = 0
  105. if len(chrgr_num_difference) > 0:
  106. chrgr_soc = pd.DataFrame()
  107. soc_cal = interpolate.interp1d(LookTab_OCV, LookTab_SOC, kind = 'linear')#插值函数
  108. max_volt = max(LookTab_OCV)
  109. min_volt = min(LookTab_OCV)
  110. for chrgr_num in chrgr_num_difference:
  111. data_temp = chrgr_data.loc[chrgr_data['stat'] == chrgr_num]#该片段数据
  112. chrgr_crnt_data = data_temp.loc[crnt_flg*data_temp['总电流[A]'] < 0]#充电数据中电流非零部分,充电时电流为负
  113. chrgr_crnt_data = chrgr_crnt_data.reset_index(drop = True)
  114. chrgr_crnt_zero = data_temp.loc[data_temp['总电流[A]'] == 0]#充电数据中电流为0数据
  115. chrgr_crnt_zero = chrgr_crnt_zero.reset_index(drop = True)
  116. chrgr_crnt_time = pd.to_datetime(chrgr_crnt_data['时间戳'])
  117. if len(chrgr_crnt_data) > 1:
  118. df_cell_volt = chrgr_crnt_data[cell_name].iloc[-1]/1000
  119. df_cell_volt[df_cell_volt >= max_volt] = max_volt - 0.005
  120. df_cell_volt[df_cell_volt <= min_volt] = min_volt + 0.005
  121. chrgr_soc = soc_cal(list(df_cell_volt))
  122. full_chrgr_check = (chrgr_soc > 98)
  123. if any(full_chrgr_check):
  124. full_chrgr_num = full_chrgr_num + 1
  125. df_chrgr_soc_temp = pd.DataFrame({"sn":[self.sn], "time":[chrgr_crnt_time.iloc[-1]], "chrgr_soc":[str(list(chrgr_soc))], "chrgr_volt":[str(list(df_cell_volt))],
  126. "temp":[str(list(chrgr_crnt_data[temp_name].iloc[-1]))], "full_chrgr_num":[full_chrgr_num]})
  127. df_chrgr_soc = df_chrgr_soc.append(df_chrgr_soc_temp)
  128. df_chrgr_soc = df_chrgr_soc.reset_index(drop = True)
  129. df_chrgr_soc.sort_values(by = ['time'], axis = 0, ascending=True,inplace=True)#对故障信息按照时间进行排序
  130. if not df_chrgr_soc.empty:
  131. return df_chrgr_soc
  132. else:
  133. return pd.DataFrame()