123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665 |
- # -*- 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['时间戳']<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['时间戳'])
- # 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['时间戳']<df_sel_bms.loc[len(df_sel_bms)-1,'时间戳'])]
- df_sel_gps = df_sel_gps.append(df_sel_gps_single)
- df_sel_gps = df_sel_gps.reset_index(drop=True)
- center_long = np.mean(df_sel_gps['经度'])
- center_lat = np.mean(df_sel_gps['纬度'])
- for i in range(1, len(df_sel_gps)):
- dis_single.append(math.sqrt(math.pow((df_sel_gps.loc[i, '经度'] - center_long),2) \
- + math.pow((df_sel_gps.loc[i, '纬度'] -center_lat),2)) * 111)
- dis = sorted(dis_single)
- if len(dis) > 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['时间戳']<df_sel_bms.loc[len(df_sel_bms)-1,'时间戳'])]
- df_sel_gps = df_sel_gps.reset_index(drop=True)
-
- if data_number != data_number_list[start]:
- # startTime= datetime.datetime.strptime(df_sel_bms.loc[0, '时间戳'],"%Y-%m-%d %H:%M:%S")
- startTime= df_sel_bms.loc[0, '时间戳']
- startSoc= df_sel_bms.loc[0, 'SOC[%]']
- if (startTime - endTime).seconds < 5*60 or abs(endSoc - startSoc) < 5:
- reconn = 1
- else:
- reconn = 0
- else:
- reconn = 0
-
- # endTime= datetime.datetime.strptime(df_sel_bms.loc[len(df_sel_bms)-1, '时间戳'],"%Y-%m-%d %H:%M:%S")
- endTime= df_sel_bms.loc[len(df_sel_bms)-1, '时间戳']
- endSoc= df_sel_bms.loc[len(df_sel_bms)-1, 'SOC[%]']
- # index = sorted(np.where(df_sel['data_split_by_union'] == data_number))[0]
- # print(index)
- # min_index = index[0]
- # print(data_number_list)
- # print(df_sel)
- # print('start={},index={},data_num={},value={}'.format(start,min_index,data_number,df_sel.loc[min_index+1, '时间戳']))
- # if ((df_sel_bms.loc[len(df_sel_bms)-1, 'SOC[%]'] - df_sel_bms.loc[0, 'SOC[%]']) > 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))
|