# -*- coding: utf-8 -*- """ Created on Wed Dec 30 14:38:35 2020 @author: striv """ # import getdata import time import datetime import numpy as np import pandas as pd import os import matplotlib.pyplot as plt import tools.tools import importlib importlib.reload(tools.tools) import math from collections import Counter from sklearn.cluster import DBSCAN def getcellsoc(Chrg_data_static_cellu,soc_ocv_table): pass x = soc_ocv_table.iloc[:,0] y = soc_ocv_table.iloc[:,1]*1000 xnew=np.linspace(0,105,1000) # print(x,y) z1 = np.polyfit(x,y,11) ynew = np.polyval(z1,xnew) data = [xnew,ynew] soc_ocv_ply = pd.DataFrame(data,index=('SOC','OCV')).T cellsoc = pd.DataFrame() cellsoc_list=[] temp = [] for i_num,i in enumerate(Chrg_data_static_cellu): i = i /1000.0 temp = soc_ocv_table.iloc[:,1] ocv_temp = soc_ocv_table.iloc[:,1].tolist() ocv_temp.append(i) ocv_temp.sort() ocv_index = ocv_temp.index(i) if ocv_index == 0: value = 0 elif ocv_index == len(ocv_temp)-1: value = 100 else: temp1=ocv_temp[ocv_index-1] temp2=ocv_temp[ocv_index+1] j_temp1 = temp.index[temp==temp1][0] j_temp2 = temp.index[temp==temp2][0] value = (soc_ocv_table.iloc[j_temp1,0]*(temp2-i) + soc_ocv_table.iloc[j_temp2,0]*(i-temp1))/min(1,(temp2 - temp1)) cellsoc.loc[0,'cell'+str(i_num+1)] = min([100,value]) cellsoc_list.append(cellsoc.loc[0,'cell'+str(i_num+1)]) temp = [] return cellsoc,cellsoc_list def get_date(df): time = df.loc[0, '时间戳'] date = time.strftime('%Y-%m-%d %H:%M:%S') date = date[0:10] return date def get_daily_odo_and_speed(df,df_gps): data_number_list = sorted(list(set(df[df['data_status'].isin(['drive' or 'stand'])]['data_split_by_status']))) odo_sum = 0 res_single = pd.DataFrame(columns=['speed']) max_speed_single = [] max_speed = -1 for data_number in data_number_list[0:]: df_sel_bms = df[df['data_split_by_status'] == data_number] df_sel_bms = df_sel_bms.reset_index(drop=True) # print('bmsstart={},bmsend={}'.format(df_sel_bms.loc[0, '时间戳'], df_sel_bms.loc[len(df_sel_bms)-1, '时间戳'])) df_sel_gps = df_gps[(df_gps['时间戳']>df_sel_bms.loc[0,'时间戳']) & (df_gps['时间戳']= 2: odo, avg_speed, odo_list, speed_list, invalid_flag = tools.tools.cal_odo_speed(df_sel_gps['纬度'], df_sel_gps['经度'], df_sel_gps['时间戳']) # print('gpsstart={},gpsend={},odo={}'.format(df_sel_gps.loc[0, '时间戳'], df_sel_gps.loc[len(df_sel_gps) - 1, '时间戳'],odo)) # print(df_sel_gps['时间戳']) odo_sum = odo_sum + odo res_single = res_single.append({'speed':avg_speed},ignore_index = True) max_speed_single.append(np.max(speed_list)) avr_speed = np.mean(res_single['speed']) if len(max_speed_single) > 0: max_speed = np.max(max_speed_single) return odo_sum, avr_speed, max_speed def get_daily_odo(df,df_gps): odo_sum = 0 odo_plus = 0 soc_sum = 0 data_number_list = sorted(list(set(df[df['data_status'].isin(['drive' or 'stand' or 'charge' or 'None'])]['data_split_by_status']))) data_number_list = sorted(list(set(df['data_split_by_status']))) for i in range(0, len(data_number_list)): # for data_number in data_number_list[0:]: data_number = data_number_list[i] df_sel_bms = df[df['data_split_by_status'] == data_number] # print(df_sel_bms) df_sel_bms = df_sel_bms.reset_index(drop=True) df_sel_gps = df_gps[ (df_gps['时间戳'] >= df_sel_bms.loc[0, '时间戳']) & (df_gps['时间戳'] <= df_sel_bms.loc[len(df_sel_bms) - 1, '时间戳'])] df_sel_gps = df_sel_gps.reset_index(drop=True) if len(df_sel_gps) >= 2: odo, avg_speed, odo_list, speed_list, invalid_flag = tools.tools.cal_odo_speed(df_sel_gps['纬度'], df_sel_gps['经度'], df_sel_gps['时间戳']) soc = abs(df_sel_bms.loc[len(df_sel_bms) - 1, 'SOC[%]'] - df_sel_bms.loc[0, 'SOC[%]']) if len(df_sel_gps) >= 2 and len(df_sel_bms) >= 2: last_df = df_sel_bms[ (df_sel_bms['时间戳'] >= df_sel_gps.loc[0, '时间戳']) & ( df_sel_bms['时间戳'] <= df_sel_gps.loc[len(df_sel_gps) - 1, '时间戳'])] last_df = last_df.reset_index(drop=True) last_soc = last_df.loc[len(last_df) - 1, 'SOC[%]'] last_time = last_df.loc[len(last_df) - 1, '时间戳'] else: last_soc = -1 odo_sum = odo_sum + odo soc_sum = soc_sum + soc if i < len(data_number_list) - 1: data_number = data_number_list[i + 1] df_sel_bms = df[df['data_split_by_status'] == data_number] df_sel_bms = df_sel_bms.reset_index(drop=True) df_sel_gps = df_gps[ (df_gps['时间戳'] >= df_sel_bms.loc[0, '时间戳']) & (df_gps['时间戳'] <= df_sel_bms.loc[len(df_sel_bms) - 1, '时间戳'])] df_sel_gps = df_sel_gps.reset_index(drop=True) if len(df_sel_gps) >= 2 and len(df_sel_bms) >= 2: cur_df = df_sel_bms[ (df_sel_bms['时间戳'] >= df_sel_gps.loc[0, '时间戳']) & ( df_sel_bms['时间戳'] <= df_sel_gps.loc[len(df_sel_gps) - 1, '时间戳'])] cur_df = cur_df.reset_index(drop=True) if len(cur_df)>0: # print('cur={}'.format(cur_df)) cur_soc = cur_df.loc[0, 'SOC[%]'] cur_time = cur_df.loc[0, '时间戳'] else: cur_soc = -1 else: cur_soc = -1 print(last_time, cur_time, last_soc, cur_soc) if abs(cur_soc - last_soc) > 1 and soc_sum > 1 and cur_soc >= 0 and last_soc >= 0: odo_plus = odo_plus + odo_sum/soc_sum*abs(cur_soc - last_soc) return odo_sum+odo_plus, odo_sum, odo_plus def sta_one_drive_cycle(df_bms, df_gps, prepro_record, time_window=3600, step=3600, start_time="00:00:00"): st = datetime.datetime.strptime(str(df_bms.loc[0, '时间戳'])[0:10] + ' ' + start_time, '%Y-%m-%d %H:%M:%S') et = st + datetime.timedelta(seconds=time_window) time_list = [] driveT_list = [] driveSoc_list = [] driveOdo_list = [] driveOdoRevise_list = [] while (et < df_bms.loc[len(df_bms) - 1, '时间戳']): df_t = df_bms[(df_bms['时间戳'] > st) & (df_bms['时间戳'] < et)] df_t = df_t.reset_index(drop=True) driveT = 0 driveSoc = 0 driveOdo = 0 driveOdoRevise = 0 if not df_t.empty: deltaT = (df_t.loc[len(df_t) - 1, '时间戳'] - df_t.loc[0, '时间戳']).total_seconds() df_drive = df_t[df_t['data_status'] == 'drive'] df_drive = df_drive.reset_index(drop=True) data_number_list = sorted(list(set(df_drive['data_split_by_status']))) for data_number in data_number_list[:]: df_d = df_drive[df_drive['data_split_by_status'] == data_number] df_d = df_d.reset_index(drop=True) driveT = driveT + (df_d.loc[len(df_d) - 1, '时间戳'] - df_d.loc[0, '时间戳']).total_seconds() driveSoc = driveSoc + (df_d.loc[0, 'SOC[%]'] - df_d.loc[len(df_d) - 1, 'SOC[%]']) if df_d.loc[0, 'gps_rely'] == 1 and driveOdo != None: df_sel_gps = df_gps[ (df_gps['时间戳'] >= df_d.loc[0, '时间戳']) & (df_gps['时间戳'] <= df_d.loc[len(df_d) - 1, '时间戳'])] df_sel_gps = df_sel_gps.reset_index(drop=True) if len(df_sel_gps) > 0: driveOdo = driveOdo + (df_sel_gps.loc[len(df_sel_gps) - 1, 'odo'] - df_sel_gps.loc[0, 'odo']) else: driveOdo = None else: driveOdo = None time_list.append(st) driveT_list.append(driveT) driveSoc_list.append(driveSoc) driveOdo_list.append(driveOdo) st = st + datetime.timedelta(seconds=step) et = st + datetime.timedelta(seconds=time_window) print(driveOdo_list) if prepro_record['drive'] < 0.8 and sum(driveSoc_list) > 0: # 计算能耗 sum_odo = 0 sum_soc = 0 for i, odo in enumerate(driveOdo_list): if odo != 0 and not pd.isnull(odo): sum_odo += odo sum_soc += driveSoc_list[i] if sum_soc > 0: ene_consump = sum_odo / sum_soc else: ene_consump = -1 st = datetime.datetime.strptime(str(df_bms.loc[0, '时间戳'])[0:10] + ' ' + start_time, '%Y-%m-%d %H:%M:%S') et = st + datetime.timedelta(seconds=time_window) driveOdoRevise_list = [] while (et < df_bms.loc[len(df_bms) - 1, '时间戳']): df_t = df_bms[(df_bms['时间戳'] > st) & (df_bms['时间戳'] < et)] df_t = df_t.reset_index(drop=True) driveOdoRevise = 0 if not df_t.empty: deltaT = (df_t.loc[len(df_t) - 1, '时间戳'] - df_t.loc[0, '时间戳']).total_seconds() df_drive = df_t[df_t['data_status'] == 'drive'] df_drive = df_drive.reset_index(drop=True) data_number_list = sorted(list(set(df_drive['data_split_by_status']))) for data_number in data_number_list[:]: df_d = df_drive[df_drive['data_split_by_status'] == data_number] df_d = df_d.reset_index(drop=True) if df_d.loc[0, 'gps_rely'] == 1 and driveOdo != None: df_sel_gps = df_gps[ (df_gps['时间戳'] >= df_d.loc[0, '时间戳']) & (df_gps['时间戳'] <= df_d.loc[len(df_d) - 1, '时间戳'])] df_sel_gps = df_sel_gps.reset_index(drop=True) if len(df_sel_gps) > 0: driveOdoRevise = driveOdoRevise + ( df_sel_gps.loc[len(df_sel_gps) - 1, 'odo'] - df_sel_gps.loc[0, 'odo']) else: driveOdoRevise = driveOdoRevise + ( df_d.loc[0, 'SOC[%]'] - df_d.loc[len(df_d) - 1, 'SOC[%]']) * ene_consump else: driveOdoRevise = driveOdoRevise + ( df_d.loc[0, 'SOC[%]'] - df_d.loc[len(df_d) - 1, 'SOC[%]']) * ene_consump driveOdoRevise_list.append(driveOdoRevise) st = st + datetime.timedelta(seconds=step) et = st + datetime.timedelta(seconds=time_window) else: driveOdoRevise_list = [None] * len(driveSoc_list) df_res = pd.DataFrame( {'time': time_list, 'driveT': driveT_list, 'driveSoc': driveSoc_list, 'driveOdo': driveOdo_list, 'driveOdoRevise': driveOdoRevise_list}) return df_res def get_daily_capacity_and_energy(df, cap): data_number_list = sorted(list(set(df[df['data_status'].isin(['drive'])]['data_split_by_status']))) energy_sum = 0 capacity_sum = 0 for data_number in data_number_list[0:]: df_sel_bms = df[df['data_split_by_status'] == data_number] df_sel_bms = df_sel_bms.reset_index(drop=True) capacity = (df_sel_bms.loc[0, 'SOC[%]'] - df_sel_bms.loc[len(df_sel_bms)-1,'SOC[%]']) * np.mean(df_sel_bms['SOH[%]']) * \ cap / 100 / 100 energy = capacity * np.mean(df_sel_bms['总电压[V]']) / 1000 capacity_sum = capacity_sum + capacity energy_sum = energy_sum + energy return capacity_sum, energy_sum def get_daily_accum_time(df, status): data_number_list = sorted(list(set(df[df['data_status'].isin([status])]['data_split_by_status']))) accum_time_sum = 0 for data_number in data_number_list[0:]: df_sel_bms = df[df['data_split_by_status'] == data_number] df_sel_bms = df_sel_bms.reset_index(drop=True) accum_time = (df_sel_bms.loc[len(df_sel_bms)-1, '时间戳'] - df_sel_bms.loc[0,'时间戳']).seconds accum_time_sum = accum_time_sum + accum_time / 3600 return accum_time_sum def get_daily_stand_temp(df, status): data_number_list = sorted(list(set(df[df['data_status'].isin([status])]['data_split_by_status']))) res_single = pd.DataFrame(columns = ['avr_tem', 'avr_tem_rate']) cycle = 0 avr_tem_sum = 0 avr_tem_rate_sum =0 avr_tem = 0 avr_tem_rate = 0 for data_number in data_number_list[0:]: cycle = cycle + 1 df_sel_bms = df[df['data_split_by_status'] == data_number] df_sel_bms = df_sel_bms.reset_index(drop=True) avr_tem = np.mean(df_sel_bms['单体温度1']) avr_tem_rate = abs(df_sel_bms.loc[len(df_sel_bms)-1, '单体温度1'] - df_sel_bms.loc[0, '单体温度1'])/\ (df_sel_bms.loc[len(df_sel_bms)-1, '时间戳'] - df_sel_bms.loc[0, '时间戳']).seconds * 3600 avr_tem_sum = avr_tem_sum + avr_tem avr_tem_rate_sum = avr_tem_rate_sum + avr_tem_rate if cycle > 0: avr_tem = avr_tem_sum / cycle avr_tem_rate = avr_tem_rate_sum / cycle return avr_tem, avr_tem_rate def get_daily_max_pwr(df, status): data_number_list = sorted(list(set(df[df['data_status'].isin([status])]['data_split_by_status']))) max_pwr = 0 res_pwr = pd.DataFrame(columns=['pwr']) for data_number in data_number_list[0:]: df_sel_bms = df[df['data_split_by_status'] == data_number] df_sel_bms = df_sel_bms.reset_index(drop=True) for index in df_sel_bms.index: res_pwr = res_pwr.append({'pwr':df_sel_bms.loc[index, '总电流[A]'] * df_sel_bms.loc[index, '总电压[V]'] / 1000}, ignore_index=True ) max_pwr_single = np.max(res_pwr['pwr']) max_pwr = max(max_pwr, max_pwr_single) return max_pwr def get_daily_regen(df, status): data_number_list = sorted(list(set(df[df['data_status'].isin([status])]['data_split_by_status']))) regen_flag = 0 regen_rate = 0 regen_count = 0 total_count = 0 res_pwr = pd.DataFrame(columns=['pwr']) for data_number in data_number_list[0:]: df_sel_bms = df[df['data_split_by_status'] == data_number] df_sel_bms = df_sel_bms.reset_index(drop=True) regen_count = regen_count + len(df_sel_bms[df_sel_bms['总电流[A]'] < -1]) total_count = total_count + len(df_sel_bms) if regen_count > 10: regen_flag = 1 regen_rate = regen_count / total_count * 100 return regen_flag, regen_rate def get_working_scope(df,df_gps,status): data_number_list = sorted(list(set(df[df['data_status'].isin([status])]['data_split_by_status']))) dis_single = [] rad = 3 df_sel_gps = pd.DataFrame(columns=['时间戳','经度','纬度','海拔m','速度[km/h]','odo','speed']) for data_number in data_number_list[0:]: df_sel_bms = df[df['data_split_by_status'] == data_number] df_sel_bms = df_sel_bms.reset_index(drop=True) df_sel_gps_single = df_gps[(df_gps['时间戳']>df_sel_bms.loc[0,'时间戳']) & (df_gps['时间戳'] 100: rad = dis[math.floor(len(dis) * 0.99)] else: rad = -1 return center_long, center_lat, rad def get_isc(df, status): total_len = 10 data_number_list = sorted(list(set(df[df['data_status'].isin([status])]['data_split_by_status']))) # df_res = pd.DataFrame(columns=['time','limit','t1', 't2','t3', 't4','t5', 't6','t7', 't8','t9', 't10','t11', 't12','t13', 't14','tmean', # 'isc1','isc2','isc3','isc4','isc5','isc6','isc7','isc8','isc9','isc10','isc11','isc12','isc13','isc14', # 'res1','res2','res3','res4','res5','res6','res7','res8','res9','res10','res11','res12','res13','res14']) df_res = pd.DataFrame(columns=['time','limit','t1', 't2','t3', 't4','t5', 't6','t7', 't8','t9', 't10','tmean', 'isc1','isc2','isc3','isc4','isc5','isc6','isc7','isc8','isc9','isc10', 'res1','res2','res3','res4','res5','res6','res7','res8','res9','res10']) limits = [3360,3361,3362,3363,3364,3365,3366, 3367, 3368, 3369, 3370] num = len(limits) index = 0 dd = -1 timestamp = 1545730073 base_time = datetime.fromtimestamp(timestamp) for data_number in data_number_list[0:]: dd = dd + 1 df_sel_bms = df[df['data_split_by_status'] == data_number] df_sel_bms = df_sel_bms.reset_index(drop=True) # current = np.mean(df_sel_bms[df_sel_bms['总电压[V]']>=limits[0]*14 and df_sel_bms['总电压[V]']<=limits[-1]*14]['总电流[A]']) current = 9 if df_sel_bms.loc[0, 'SOC[%]'] > 40: # print('delete_data={},time={},soc={}'.format(dd,df_sel_bms.loc[0, '时间戳'],df_sel_bms.loc[0, 'SOC[%]'])) continue else: k = -1 for limit in limits: k = k + 1 df_res.loc[index,'time'] = df_sel_bms.loc[0, '时间戳'] for i in range(1,total_len+1): # print('data={},index={},limit{}={},cell={},time={}'.format(dd,index,k,limit,i,df_sel_bms.loc[0, '时间戳'])) time_list = sorted(list(set(df_sel_bms[df_sel_bms['单体电压'+ str(i)]==limit]['时间戳']))) time_list1 = list(df_sel_bms[df_sel_bms['单体电压'+ str(i)]==limit]['时间戳']) # print(df_sel_bms['单体电压'+ str(i)]) # print('index={},limit{}={},cell={},time={}'.format(index,k,limit,i,time_list[0])) df_res.loc[index,'limit'] = limit if len(time_list) > 0: time_counter = Counter(time_list1) most_counterNum = time_counter.most_common(2) time_raw = most_counterNum[0] # print('value={},type={}'.format(most_counterNum,type(time_raw))) time = (time_list[-1] - base_time).seconds # print('limit={},i={},time={}'.format(limit, i ,time)) df_res.loc[index,'t'+str(i)] = time_list[-1] df_res.loc[index,'isc'+str(i)] = time # print('data={},index={},limit{}={},cell={},time={}'.format(dd,index,k,limit,i,time_list[-1])) if i == total_len: print(df_res.loc[index,'t1':'t'+str(total_len)]) df_res.loc[index,'tmean'] = np.mean(df_res.loc[index,'isc1':'isc'+str(total_len)]) df_res.loc[index,'isc1':'isc'+str(total_len)] = df_res.loc[index,'isc1':'isc'+str(total_len)] - df_res.loc[index,'tmean'] # print('data={},k={},index={}'.format(dd,k,index)) total_index = index index = index + 1 # df_res.loc[index*num+k,'isc1':'isc14'] = df_res.loc[index*num+k,'t1':'t14'] - df_res.loc[index*num+k,'tmean'] else: # print('NoValue_data={},time={},soc={},limit{}={},cell={}'. # format(dd,df_sel_bms.loc[0, '时间戳'],df_sel_bms.loc[0, 'SOC[%]'],k,limit,i)) break for limit in limits: # print(df_res) data_number_list = sorted(list(set(df_res[df_res['limit']==limit].index))) # print(data_number_list) df_res.loc[data_number_list[0],'res1':'res'+str(total_len)]=0 index = 1 for data_number in data_number_list[1:]: for i in range(1,total_len+1): df_res.loc[data_number_list[index],'res'+str(i)]=(df_res.loc[data_number_list[index],'isc'+str(i)] - df_res.loc[data_number_list[index-1],'isc'+str(i)])*1000*current / (df_res.loc[data_number_list[index],'time'] - df_res.loc[data_number_list[index- 1],'time']).total_seconds() index = index + 1 result=[] for i in range(1,total_len+1): # result.append(np.mean(df_res[11:total_index,'res'+str(i)])) mean_value = df_res['res'+str(i)][11:total_index+1].mean() result.append(mean_value) # print('i{}={},total_index={}'.format(i,df_res['res'+str(i)][11:total_index+1],total_index)) return df_res,result def get_charge_statics(df, status): # 计算充电行为 df_res = pd.DataFrame(columns=['time', 'num','duration','Capacity']) df_res_single = pd.DataFrame(columns=['time','cycle','start_time','stop_time','start_soc','stop_soc','gps_long','gps_lat',]) start_time = df_bms.loc[3771, '时间戳'] timeDelta = datetime.timedelta(days=1) end_time = start_time + timeDelta while end_time < df_bms.loc[len(df_bms)-1, '时间戳']: # import pdb;pdb.set_trace() cycle = 0 df_res_temp = pd.DataFrame(columns=['time', 'num']) df_sel = df_bms[(df_bms['时间戳']>=start_time) & (df_bms['时间戳']<=end_time)] origin_index = list(df_sel.index) # print(origin_index[0]) data_number_list = sorted(list(set(df_sel[df_sel['data_status'].isin(['charge'])]['data_split_by_status']))) if (df_bms.loc[origin_index[0], 'data_status'] == df_bms.loc[origin_index[0]-1, 'data_status'] == ['charge']): charge_num = len(data_number_list)-1 start = 1 else: charge_num = len(data_number_list) start = 0 for data_number in data_number_list[start:]: df_sel_bms = df_sel[df_sel['data_split_by_status'] == data_number] df_sel_bms = df_sel_bms.reset_index(drop=True) df_sel_gps = df_gps[(df_gps['时间戳']>df_sel_bms.loc[0,'时间戳']) & (df_gps['时间戳'] 10.0) and reconn==0: if 1: cycle = cycle + 1 # print('cycle = {}, delta = {}'.format(cycle, df_sel_bms.loc[len(df_sel_bms)-1, 'SOC[%]'] - df_sel_bms.loc[0, 'SOC[%]'])) df_res_single = df_res_single.append({'time': df_sel.loc[origin_index[0], '时间戳'], 'cycle': cycle, 'start_time': df_sel_bms.loc[0, '时间戳'], 'stop_time': df_sel_bms.loc[len(df_sel_bms)-1, '时间戳'], 'start_soc': df_sel_bms.loc[0, 'SOC[%]'], 'stop_soc': df_sel_bms.loc[len(df_sel_bms)-1, 'SOC[%]'], 'gps_long': np.mean(df_sel_gps['经度']), 'gps_lat': np.mean(df_sel_gps['纬度'])}, ignore_index=True) # print(df_sel_bms) df_res = df_res.append({'time': df_sel.loc[origin_index[0], '时间戳'], 'num': charge_num}, ignore_index=True) start_time = end_time end_time = start_time + timeDelta print(df_res_single) def get_soh(df_bms, sn): # 计算SOH和一致性 df_res = pd.DataFrame(columns=['sn','time', 'accum_ah','soh_cell01','soh_cell02','soh_cell03', 'soh_cell04','soh_cell05','soh_cell06','soh_cell07', 'soh_cell08','soh_cell09','soh_cell10','soh_cell11', 'soh_cell12','soh_cell13','soh_cell14','soh_cell15', 'soh_cell16','soh_cell17','soh_cell18','soh_cell19', 'soh_cell20']) df_cell_res = pd.DataFrame(columns=['sn','time','status','volt_cell01','volt_cell02','volt_cell03', 'volt_cell04','volt_cell05','volt_cell06','volt_cell07', 'volt_cell08','volt_cell09','volt_cell10','volt_cell11', 'volt_cell12','volt_cell13','volt_cell14','volt_cell15', 'volt_cell16','volt_cell17','volt_cell18','volt_cell19', 'volt_cell20','volt_max','volt_min', 'volt_avr','soc_diff','soc_diff_div','over_discharge']) df_sel = df_bms # print(sn[0][0:2]) if sn[0][0:5] == 'PK504': soc_ocv_table = pd.read_excel(r'D:\Work\Interior\Cloud_BMS\Overall\产品信息\电池OCV表格.xlsx', '60AH') cellcap = 55 # Capacity elif sn[0][0:5] == 'PK501': soc_ocv_table = pd.read_excel(r'D:\Work\Interior\Cloud_BMS\Overall\产品信息\电池OCV表格.xlsx', '40AH') cellcap = 40 # Capacity elif sn[0][0:2] == 'UD': soc_ocv_table = pd.read_excel(r'D:\Work\Interior\Cloud_BMS\Overall\产品信息\电池OCV表格.xlsx', '50AH') cellcap = 50 # Capacity cellsoh_list = [] data_number_list = sorted(list(set(df_sel[df_sel['data_status'].isin(['charge'])]['data_split_by_status']))) start = 1 for data_number in data_number_list[start:-2]: ## 充电以及前后数据全部获取 df_sel_bms_relax_start = df_sel[df_sel['data_split_by_status'] == data_number-1] df_sel_bms = df_sel[df_sel['data_split_by_status'] == data_number] df_sel_bms_relax_end = df_sel[df_sel['data_split_by_status'] == data_number+1] origin_index = list(df_sel_bms.index) origin_index_relax_start = list(df_sel_bms_relax_start.index) origin_index_relax_end = list(df_sel_bms_relax_end.index) df_sel_bms_relax_start = df_sel_bms_relax_start.reset_index(drop=True) df_sel_bms = df_sel_bms.reset_index(drop=True) df_sel_bms_relax_end = df_sel_bms_relax_end.reset_index(drop=True) ## 充电前后静置时间 # delta_time_start = (df_sel_bms_relax_start.loc[len(df_sel_bms_relax_start)-1,'时间戳'] - df_sel_bms_relax_start.loc[0,'时间戳']).seconds delta_time_end = (df_sel_bms_relax_end.loc[len(df_sel_bms_relax_end)-1,'时间戳'] - df_sel_bms_relax_end.loc[0,'时间戳']).seconds # print(df_sel_bms_relax_start.loc[len(df_sel_bms_relax_start)-1,'时间戳'], # df_sel_bms_relax_start.loc[0,'时间戳'], # df_sel_bms_relax_start.loc[len(df_sel_bms_relax_start)-1,'data_status'], # df_sel_bms_relax_end.loc[len(df_sel_bms_relax_end)-1,'data_status'], # df_sel_bms.loc[0,'时间戳'], # delta_time_start, # delta_time_end) ## 充电前后静置并且充电前静置超过10min,充电后静置超过3h if (df_sel_bms_relax_start.loc[len(df_sel_bms_relax_start)-1,'data_status'] == 'stand' or \ df_sel_bms_relax_start.loc[len(df_sel_bms_relax_start)-1,'data_status'] == 'drive') and \ df_sel_bms_relax_end.loc[len(df_sel_bms_relax_end)-1,'data_status'] == 'stand' and\ delta_time_end > 18000: ## 记录充电相关信息 start_time = df_sel_bms.loc[0,'时间戳'] end_time = df_sel_bms.loc[len(df_sel_bms)-1,'时间戳'] relax_time = df_sel_bms_relax_end.loc[len(df_sel_bms_relax_end)-1,'时间戳'] start_current = df_sel_bms_relax_start.loc[len(df_sel_bms_relax_start)-1,'总电流[A]'] end_current = df_sel_bms_relax_end.loc[len(df_sel_bms_relax_end)-1,'总电流[A]'] # print(start_time,end_time,relax_time,start_current,end_current) ## 记录充电开始前信息 start_volt_class = df_sel.loc[origin_index[0]-3,'单体电压1':'单体电压20'] start_index = start_volt_class start_index = start_index.apply(lambda x: 1 if x<3.279 or (x > 3.292 and x < 3.307) else 0) start_index = np.array(start_index) start_soc,start_cellsoc_list = getcellsoc(start_volt_class,soc_ocv_table) if np.min(start_volt_class) < 3182: over_discharge = 1 else: over_discharge = 0 if np.max(start_volt_class) > 3640: over_charge = 1 else: over_charge = 0 df_cell_res = df_cell_res.append({'sn':sn, 'time':df_sel.loc[origin_index[0]-3,'时间戳'], 'status':'start', 'volt_cell01':start_volt_class[0],'volt_cell02':start_volt_class[1], 'volt_cell03':start_volt_class[2],'volt_cell04':start_volt_class[3], 'volt_cell05':start_volt_class[4],'volt_cell06':start_volt_class[5], 'volt_cell07':start_volt_class[6],'volt_cell08':start_volt_class[7], 'volt_cell09':start_volt_class[8],'volt_cell10':start_volt_class[9], 'volt_cell11':start_volt_class[10],'volt_cell12':start_volt_class[11], 'volt_cell13':start_volt_class[12],'volt_cell14':start_volt_class[13], 'volt_cell15':start_volt_class[14],'volt_cell16':start_volt_class[15], 'volt_cell17':start_volt_class[16],'volt_cell18':start_volt_class[17], 'volt_cell19':start_volt_class[18],'volt_cell20':start_volt_class[19], 'volt_max':np.max(start_volt_class), 'volt_min':np.min(start_volt_class), 'volt_avr':np.mean(start_volt_class), 'soc_diff':np.max(start_cellsoc_list)-np.min(start_cellsoc_list), 'soc_diff_div':np.mean(start_volt_class[0:9])-np.mean(start_volt_class[10:19]), 'over_discharge':over_discharge,'over_charge':over_charge}, ignore_index=True) ## 记录充电结束信息 end_volt_class = df_sel_bms_relax_end.loc[len(df_sel_bms_relax_end)-3,'单体电压1':'单体电压20'] end_index = end_volt_class end_index = end_index.apply(lambda x: 1 if x>3.346 or (x > 3.292 and x < 3.307) else 0) end_index = np.array(end_index) end_soc,end_cellsoc_list = getcellsoc(end_volt_class,soc_ocv_table) if np.min(end_volt_class) < 3182: over_discharge = 1 else: over_discharge = 0 if np.max(end_volt_class) > 3640: over_charge = 1 else: over_charge = 0 df_cell_res = df_cell_res.append({'sn':sn, 'time':df_sel_bms_relax_end.loc[len(df_sel_bms_relax_end)-3,'时间戳'], 'status':'end', 'volt_cell01':end_volt_class[0],'volt_cell02':end_volt_class[1], 'volt_cell03':end_volt_class[2],'volt_cell04':end_volt_class[3], 'volt_cell05':end_volt_class[4],'volt_cell06':end_volt_class[5], 'volt_cell07':end_volt_class[6],'volt_cell08':end_volt_class[7], 'volt_cell09':end_volt_class[8],'volt_cell10':end_volt_class[9], 'volt_cell11':end_volt_class[10],'volt_cell12':end_volt_class[11], 'volt_cell13':end_volt_class[12],'volt_cell14':end_volt_class[13], 'volt_cell15':end_volt_class[14],'volt_cell16':end_volt_class[15], 'volt_cell17':end_volt_class[16],'volt_cell18':end_volt_class[17], 'volt_cell19':end_volt_class[18],'volt_cell20':end_volt_class[19], 'volt_max':np.max(end_volt_class), 'volt_min':np.min(end_volt_class), 'volt_avr':np.mean(end_volt_class), 'soc_diff':np.max(end_cellsoc_list)-np.min(end_cellsoc_list), 'soc_diff_div':np.mean(end_volt_class[0:9])-np.mean(end_volt_class[10:19]), 'over_discharge':over_discharge,'over_charge':over_charge}, ignore_index=True) ## 计算过程量,deltaSOC和deltaAh delta_cellsoc_list = np.array(end_cellsoc_list) - np.array(start_cellsoc_list) accum = 0 for time_num in range(1,len(df_sel_bms)): delta_time = (df_sel_bms.loc[time_num,'时间戳'] - df_sel_bms.loc[time_num-1,'时间戳']).seconds accum = accum - df_sel_bms.loc[time_num,'总电流[A]']* delta_time/3600 ## 单次SOC间隔超过10%,计算SOH if np.mean(delta_cellsoc_list) > 10: cellsoh=accum/delta_cellsoc_list*100/cellcap*100 # cellsoh=cellsoh*start_index*end_index # print(cellsoh) df_res = df_res.append({'sn':sn, 'time':df_sel_bms.loc[0,'时间戳'], 'accum_ah':accum, 'soh_cell01':cellsoh[0],'soh_cell02':cellsoh[1],'soh_cell03':cellsoh[2], 'soh_cell04':cellsoh[3],'soh_cell05':cellsoh[4],'soh_cell06':cellsoh[5], 'soh_cell07':cellsoh[6],'soh_cell08':cellsoh[7],'soh_cell09':cellsoh[8], 'soh_cell10':cellsoh[9],'soh_cell11':cellsoh[10],'soh_cell12':cellsoh[11], 'soh_cell13':cellsoh[12],'soh_cell14':cellsoh[13],'soh_cell15':cellsoh[14], 'soh_cell16':cellsoh[15],'soh_cell17':cellsoh[16],'soh_cell18':cellsoh[17], 'soh_cell19':cellsoh[18],'soh_cell20':cellsoh[19]},ignore_index=True) cellsoh_list_single=cellsoh.tolist() cellsoh_list.append(cellsoh_list_single) return df_res, df_cell_res def get_charge_start_time(df,status): data_number_list = sorted(list(set(df[df['data_status'].isin([status])]['data_split_by_status']))) for data_number in data_number_list[0:]: df_sel_bms = df[df['data_split_by_status'] == data_number] df_sel_bms = df_sel_bms.reset_index(drop=True) start_time = df_sel_bms.loc[0,'时间戳'] start_time = datetime.strftime(start_time, "%H:%M:%S") limit_time = datetime.strptime("20:00:00", "%H:%M:%S") print('start_time{}>20:00:{}'.format(start_time,limit_time))