parameters.py 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Wed Dec 30 14:38:35 2020
  4. @author: striv
  5. """
  6. # import getdata
  7. import time
  8. import datetime
  9. import numpy as np
  10. import pandas as pd
  11. import os
  12. import matplotlib.pyplot as plt
  13. import tools.tools
  14. import importlib
  15. importlib.reload(tools.tools)
  16. import math
  17. from collections import Counter
  18. from sklearn.cluster import DBSCAN
  19. def getcellsoc(Chrg_data_static_cellu,soc_ocv_table):
  20. pass
  21. x = soc_ocv_table.iloc[:,0]
  22. y = soc_ocv_table.iloc[:,1]*1000
  23. xnew=np.linspace(0,105,1000)
  24. # print(x,y)
  25. z1 = np.polyfit(x,y,11)
  26. ynew = np.polyval(z1,xnew)
  27. data = [xnew,ynew]
  28. soc_ocv_ply = pd.DataFrame(data,index=('SOC','OCV')).T
  29. cellsoc = pd.DataFrame()
  30. cellsoc_list=[]
  31. temp = []
  32. for i_num,i in enumerate(Chrg_data_static_cellu):
  33. i = i /1000.0
  34. temp = soc_ocv_table.iloc[:,1]
  35. ocv_temp = soc_ocv_table.iloc[:,1].tolist()
  36. ocv_temp.append(i)
  37. ocv_temp.sort()
  38. ocv_index = ocv_temp.index(i)
  39. if ocv_index == 0:
  40. value = 0
  41. elif ocv_index == len(ocv_temp)-1:
  42. value = 100
  43. else:
  44. temp1=ocv_temp[ocv_index-1]
  45. temp2=ocv_temp[ocv_index+1]
  46. j_temp1 = temp.index[temp==temp1][0]
  47. j_temp2 = temp.index[temp==temp2][0]
  48. value = (soc_ocv_table.iloc[j_temp1,0]*(temp2-i) + soc_ocv_table.iloc[j_temp2,0]*(i-temp1))/min(1,(temp2 - temp1))
  49. cellsoc.loc[0,'cell'+str(i_num+1)] = min([100,value])
  50. cellsoc_list.append(cellsoc.loc[0,'cell'+str(i_num+1)])
  51. temp = []
  52. return cellsoc,cellsoc_list
  53. def get_date(df):
  54. time = df.loc[0, '时间戳']
  55. date = time.strftime('%Y-%m-%d %H:%M:%S')
  56. date = date[0:10]
  57. return date
  58. def get_daily_odo_and_speed(df,df_gps):
  59. data_number_list = sorted(list(set(df[df['data_status'].isin(['drive' or 'stand'])]['data_split_by_status'])))
  60. odo_sum = 0
  61. res_single = pd.DataFrame(columns=['speed'])
  62. max_speed_single = []
  63. max_speed = -1
  64. for data_number in data_number_list[0:]:
  65. df_sel_bms = df[df['data_split_by_status'] == data_number]
  66. df_sel_bms = df_sel_bms.reset_index(drop=True)
  67. # print('bmsstart={},bmsend={}'.format(df_sel_bms.loc[0, '时间戳'], df_sel_bms.loc[len(df_sel_bms)-1, '时间戳']))
  68. df_sel_gps = df_gps[(df_gps['时间戳']>df_sel_bms.loc[0,'时间戳']) & (df_gps['时间戳']<df_sel_bms.loc[len(df_sel_bms)-1,'时间戳'])]
  69. df_sel_gps = df_sel_gps.reset_index(drop=True)
  70. if len(df_sel_gps) >= 2:
  71. odo, avg_speed, odo_list, speed_list, invalid_flag = tools.tools.cal_odo_speed(df_sel_gps['纬度'], df_sel_gps['经度'],
  72. df_sel_gps['时间戳'])
  73. # print('gpsstart={},gpsend={},odo={}'.format(df_sel_gps.loc[0, '时间戳'], df_sel_gps.loc[len(df_sel_gps) - 1, '时间戳'],odo))
  74. # print(df_sel_gps['时间戳'])
  75. odo_sum = odo_sum + odo
  76. res_single = res_single.append({'speed':avg_speed},ignore_index = True)
  77. max_speed_single.append(np.max(speed_list))
  78. avr_speed = np.mean(res_single['speed'])
  79. if len(max_speed_single) > 0:
  80. max_speed = np.max(max_speed_single)
  81. return odo_sum, avr_speed, max_speed
  82. def get_daily_odo(df,df_gps):
  83. odo_sum = 0
  84. odo_plus = 0
  85. soc_sum = 0
  86. data_number_list = sorted(list(set(df[df['data_status'].isin(['drive' or 'stand' or 'charge' or 'None'])]['data_split_by_status'])))
  87. data_number_list = sorted(list(set(df['data_split_by_status'])))
  88. for i in range(0, len(data_number_list)):
  89. # for data_number in data_number_list[0:]:
  90. data_number = data_number_list[i]
  91. df_sel_bms = df[df['data_split_by_status'] == data_number]
  92. # print(df_sel_bms)
  93. df_sel_bms = df_sel_bms.reset_index(drop=True)
  94. df_sel_gps = df_gps[
  95. (df_gps['时间戳'] >= df_sel_bms.loc[0, '时间戳']) & (df_gps['时间戳'] <= df_sel_bms.loc[len(df_sel_bms) - 1, '时间戳'])]
  96. df_sel_gps = df_sel_gps.reset_index(drop=True)
  97. if len(df_sel_gps) >= 2:
  98. odo, avg_speed, odo_list, speed_list, invalid_flag = tools.tools.cal_odo_speed(df_sel_gps['纬度'],
  99. df_sel_gps['经度'],
  100. df_sel_gps['时间戳'])
  101. soc = abs(df_sel_bms.loc[len(df_sel_bms) - 1, 'SOC[%]'] - df_sel_bms.loc[0, 'SOC[%]'])
  102. if len(df_sel_gps) >= 2 and len(df_sel_bms) >= 2:
  103. last_df = df_sel_bms[
  104. (df_sel_bms['时间戳'] >= df_sel_gps.loc[0, '时间戳']) & (
  105. df_sel_bms['时间戳'] <= df_sel_gps.loc[len(df_sel_gps) - 1, '时间戳'])]
  106. last_df = last_df.reset_index(drop=True)
  107. last_soc = last_df.loc[len(last_df) - 1, 'SOC[%]']
  108. last_time = last_df.loc[len(last_df) - 1, '时间戳']
  109. else:
  110. last_soc = -1
  111. odo_sum = odo_sum + odo
  112. soc_sum = soc_sum + soc
  113. if i < len(data_number_list) - 1:
  114. data_number = data_number_list[i + 1]
  115. df_sel_bms = df[df['data_split_by_status'] == data_number]
  116. df_sel_bms = df_sel_bms.reset_index(drop=True)
  117. df_sel_gps = df_gps[
  118. (df_gps['时间戳'] >= df_sel_bms.loc[0, '时间戳']) & (df_gps['时间戳'] <= df_sel_bms.loc[len(df_sel_bms) - 1, '时间戳'])]
  119. df_sel_gps = df_sel_gps.reset_index(drop=True)
  120. if len(df_sel_gps) >= 2 and len(df_sel_bms) >= 2:
  121. cur_df = df_sel_bms[
  122. (df_sel_bms['时间戳'] >= df_sel_gps.loc[0, '时间戳']) & (
  123. df_sel_bms['时间戳'] <= df_sel_gps.loc[len(df_sel_gps) - 1, '时间戳'])]
  124. cur_df = cur_df.reset_index(drop=True)
  125. if len(cur_df)>0:
  126. # print('cur={}'.format(cur_df))
  127. cur_soc = cur_df.loc[0, 'SOC[%]']
  128. cur_time = cur_df.loc[0, '时间戳']
  129. else:
  130. cur_soc = -1
  131. else:
  132. cur_soc = -1
  133. print(last_time, cur_time, last_soc, cur_soc)
  134. if abs(cur_soc - last_soc) > 1 and soc_sum > 1 and cur_soc >= 0 and last_soc >= 0:
  135. odo_plus = odo_plus + odo_sum/soc_sum*abs(cur_soc - last_soc)
  136. return odo_sum+odo_plus, odo_sum, odo_plus
  137. def sta_one_drive_cycle(df_bms, df_gps, prepro_record, time_window=3600, step=3600, start_time="00:00:00"):
  138. st = datetime.datetime.strptime(str(df_bms.loc[0, '时间戳'])[0:10] + ' ' + start_time, '%Y-%m-%d %H:%M:%S')
  139. et = st + datetime.timedelta(seconds=time_window)
  140. time_list = []
  141. driveT_list = []
  142. driveSoc_list = []
  143. driveOdo_list = []
  144. driveOdoRevise_list = []
  145. while (et < df_bms.loc[len(df_bms) - 1, '时间戳']):
  146. df_t = df_bms[(df_bms['时间戳'] > st) & (df_bms['时间戳'] < et)]
  147. df_t = df_t.reset_index(drop=True)
  148. driveT = 0
  149. driveSoc = 0
  150. driveOdo = 0
  151. driveOdoRevise = 0
  152. if not df_t.empty:
  153. deltaT = (df_t.loc[len(df_t) - 1, '时间戳'] - df_t.loc[0, '时间戳']).total_seconds()
  154. df_drive = df_t[df_t['data_status'] == 'drive']
  155. df_drive = df_drive.reset_index(drop=True)
  156. data_number_list = sorted(list(set(df_drive['data_split_by_status'])))
  157. for data_number in data_number_list[:]:
  158. df_d = df_drive[df_drive['data_split_by_status'] == data_number]
  159. df_d = df_d.reset_index(drop=True)
  160. driveT = driveT + (df_d.loc[len(df_d) - 1, '时间戳'] - df_d.loc[0, '时间戳']).total_seconds()
  161. driveSoc = driveSoc + (df_d.loc[0, 'SOC[%]'] - df_d.loc[len(df_d) - 1, 'SOC[%]'])
  162. if df_d.loc[0, 'gps_rely'] == 1 and driveOdo != None:
  163. df_sel_gps = df_gps[
  164. (df_gps['时间戳'] >= df_d.loc[0, '时间戳']) & (df_gps['时间戳'] <= df_d.loc[len(df_d) - 1, '时间戳'])]
  165. df_sel_gps = df_sel_gps.reset_index(drop=True)
  166. if len(df_sel_gps) > 0:
  167. driveOdo = driveOdo + (df_sel_gps.loc[len(df_sel_gps) - 1, 'odo'] - df_sel_gps.loc[0, 'odo'])
  168. else:
  169. driveOdo = None
  170. else:
  171. driveOdo = None
  172. time_list.append(st)
  173. driveT_list.append(driveT)
  174. driveSoc_list.append(driveSoc)
  175. driveOdo_list.append(driveOdo)
  176. st = st + datetime.timedelta(seconds=step)
  177. et = st + datetime.timedelta(seconds=time_window)
  178. print(driveOdo_list)
  179. if prepro_record['drive'] < 0.8 and sum(driveSoc_list) > 0:
  180. # 计算能耗
  181. sum_odo = 0
  182. sum_soc = 0
  183. for i, odo in enumerate(driveOdo_list):
  184. if odo != 0 and not pd.isnull(odo):
  185. sum_odo += odo
  186. sum_soc += driveSoc_list[i]
  187. if sum_soc > 0:
  188. ene_consump = sum_odo / sum_soc
  189. else:
  190. ene_consump = -1
  191. st = datetime.datetime.strptime(str(df_bms.loc[0, '时间戳'])[0:10] + ' ' + start_time, '%Y-%m-%d %H:%M:%S')
  192. et = st + datetime.timedelta(seconds=time_window)
  193. driveOdoRevise_list = []
  194. while (et < df_bms.loc[len(df_bms) - 1, '时间戳']):
  195. df_t = df_bms[(df_bms['时间戳'] > st) & (df_bms['时间戳'] < et)]
  196. df_t = df_t.reset_index(drop=True)
  197. driveOdoRevise = 0
  198. if not df_t.empty:
  199. deltaT = (df_t.loc[len(df_t) - 1, '时间戳'] - df_t.loc[0, '时间戳']).total_seconds()
  200. df_drive = df_t[df_t['data_status'] == 'drive']
  201. df_drive = df_drive.reset_index(drop=True)
  202. data_number_list = sorted(list(set(df_drive['data_split_by_status'])))
  203. for data_number in data_number_list[:]:
  204. df_d = df_drive[df_drive['data_split_by_status'] == data_number]
  205. df_d = df_d.reset_index(drop=True)
  206. if df_d.loc[0, 'gps_rely'] == 1 and driveOdo != None:
  207. df_sel_gps = df_gps[
  208. (df_gps['时间戳'] >= df_d.loc[0, '时间戳']) & (df_gps['时间戳'] <= df_d.loc[len(df_d) - 1, '时间戳'])]
  209. df_sel_gps = df_sel_gps.reset_index(drop=True)
  210. if len(df_sel_gps) > 0:
  211. driveOdoRevise = driveOdoRevise + (
  212. df_sel_gps.loc[len(df_sel_gps) - 1, 'odo'] - df_sel_gps.loc[0, 'odo'])
  213. else:
  214. driveOdoRevise = driveOdoRevise + (
  215. df_d.loc[0, 'SOC[%]'] - df_d.loc[len(df_d) - 1, 'SOC[%]']) * ene_consump
  216. else:
  217. driveOdoRevise = driveOdoRevise + (
  218. df_d.loc[0, 'SOC[%]'] - df_d.loc[len(df_d) - 1, 'SOC[%]']) * ene_consump
  219. driveOdoRevise_list.append(driveOdoRevise)
  220. st = st + datetime.timedelta(seconds=step)
  221. et = st + datetime.timedelta(seconds=time_window)
  222. else:
  223. driveOdoRevise_list = [None] * len(driveSoc_list)
  224. df_res = pd.DataFrame(
  225. {'time': time_list, 'driveT': driveT_list, 'driveSoc': driveSoc_list, 'driveOdo': driveOdo_list,
  226. 'driveOdoRevise': driveOdoRevise_list})
  227. return df_res
  228. def get_daily_capacity_and_energy(df, cap):
  229. data_number_list = sorted(list(set(df[df['data_status'].isin(['drive'])]['data_split_by_status'])))
  230. energy_sum = 0
  231. capacity_sum = 0
  232. for data_number in data_number_list[0:]:
  233. df_sel_bms = df[df['data_split_by_status'] == data_number]
  234. df_sel_bms = df_sel_bms.reset_index(drop=True)
  235. capacity = (df_sel_bms.loc[0, 'SOC[%]'] - df_sel_bms.loc[len(df_sel_bms)-1,'SOC[%]']) * np.mean(df_sel_bms['SOH[%]']) * \
  236. cap / 100 / 100
  237. energy = capacity * np.mean(df_sel_bms['总电压[V]']) / 1000
  238. capacity_sum = capacity_sum + capacity
  239. energy_sum = energy_sum + energy
  240. return capacity_sum, energy_sum
  241. def get_daily_accum_time(df, status):
  242. data_number_list = sorted(list(set(df[df['data_status'].isin([status])]['data_split_by_status'])))
  243. accum_time_sum = 0
  244. for data_number in data_number_list[0:]:
  245. df_sel_bms = df[df['data_split_by_status'] == data_number]
  246. df_sel_bms = df_sel_bms.reset_index(drop=True)
  247. accum_time = (df_sel_bms.loc[len(df_sel_bms)-1, '时间戳'] - df_sel_bms.loc[0,'时间戳']).seconds
  248. accum_time_sum = accum_time_sum + accum_time / 3600
  249. return accum_time_sum
  250. def get_daily_stand_temp(df, status):
  251. data_number_list = sorted(list(set(df[df['data_status'].isin([status])]['data_split_by_status'])))
  252. res_single = pd.DataFrame(columns = ['avr_tem', 'avr_tem_rate'])
  253. cycle = 0
  254. avr_tem_sum = 0
  255. avr_tem_rate_sum =0
  256. avr_tem = 0
  257. avr_tem_rate = 0
  258. for data_number in data_number_list[0:]:
  259. cycle = cycle + 1
  260. df_sel_bms = df[df['data_split_by_status'] == data_number]
  261. df_sel_bms = df_sel_bms.reset_index(drop=True)
  262. avr_tem = np.mean(df_sel_bms['单体温度1'])
  263. avr_tem_rate = abs(df_sel_bms.loc[len(df_sel_bms)-1, '单体温度1'] - df_sel_bms.loc[0, '单体温度1'])/\
  264. (df_sel_bms.loc[len(df_sel_bms)-1, '时间戳'] - df_sel_bms.loc[0, '时间戳']).seconds * 3600
  265. avr_tem_sum = avr_tem_sum + avr_tem
  266. avr_tem_rate_sum = avr_tem_rate_sum + avr_tem_rate
  267. if cycle > 0:
  268. avr_tem = avr_tem_sum / cycle
  269. avr_tem_rate = avr_tem_rate_sum / cycle
  270. return avr_tem, avr_tem_rate
  271. def get_daily_max_pwr(df, status):
  272. data_number_list = sorted(list(set(df[df['data_status'].isin([status])]['data_split_by_status'])))
  273. max_pwr = 0
  274. res_pwr = pd.DataFrame(columns=['pwr'])
  275. for data_number in data_number_list[0:]:
  276. df_sel_bms = df[df['data_split_by_status'] == data_number]
  277. df_sel_bms = df_sel_bms.reset_index(drop=True)
  278. for index in df_sel_bms.index:
  279. res_pwr = res_pwr.append({'pwr':df_sel_bms.loc[index, '总电流[A]'] * df_sel_bms.loc[index, '总电压[V]'] / 1000},
  280. ignore_index=True )
  281. max_pwr_single = np.max(res_pwr['pwr'])
  282. max_pwr = max(max_pwr, max_pwr_single)
  283. return max_pwr
  284. def get_daily_regen(df, status):
  285. data_number_list = sorted(list(set(df[df['data_status'].isin([status])]['data_split_by_status'])))
  286. regen_flag = 0
  287. regen_rate = 0
  288. regen_count = 0
  289. total_count = 0
  290. res_pwr = pd.DataFrame(columns=['pwr'])
  291. for data_number in data_number_list[0:]:
  292. df_sel_bms = df[df['data_split_by_status'] == data_number]
  293. df_sel_bms = df_sel_bms.reset_index(drop=True)
  294. regen_count = regen_count + len(df_sel_bms[df_sel_bms['总电流[A]'] < -1])
  295. total_count = total_count + len(df_sel_bms)
  296. if regen_count > 10:
  297. regen_flag = 1
  298. regen_rate = regen_count / total_count * 100
  299. return regen_flag, regen_rate
  300. def get_working_scope(df,df_gps,status):
  301. data_number_list = sorted(list(set(df[df['data_status'].isin([status])]['data_split_by_status'])))
  302. dis_single = []
  303. rad = 3
  304. df_sel_gps = pd.DataFrame(columns=['时间戳','经度','纬度','海拔m','速度[km/h]','odo','speed'])
  305. for data_number in data_number_list[0:]:
  306. df_sel_bms = df[df['data_split_by_status'] == data_number]
  307. df_sel_bms = df_sel_bms.reset_index(drop=True)
  308. df_sel_gps_single = df_gps[(df_gps['时间戳']>df_sel_bms.loc[0,'时间戳']) & (df_gps['时间戳']<df_sel_bms.loc[len(df_sel_bms)-1,'时间戳'])]
  309. df_sel_gps = df_sel_gps.append(df_sel_gps_single)
  310. df_sel_gps = df_sel_gps.reset_index(drop=True)
  311. center_long = np.mean(df_sel_gps['经度'])
  312. center_lat = np.mean(df_sel_gps['纬度'])
  313. for i in range(1, len(df_sel_gps)):
  314. dis_single.append(math.sqrt(math.pow((df_sel_gps.loc[i, '经度'] - center_long),2) \
  315. + math.pow((df_sel_gps.loc[i, '纬度'] -center_lat),2)) * 111)
  316. dis = sorted(dis_single)
  317. if len(dis) > 100:
  318. rad = dis[math.floor(len(dis) * 0.99)]
  319. else:
  320. rad = -1
  321. return center_long, center_lat, rad
  322. def get_isc(df, status):
  323. total_len = 10
  324. data_number_list = sorted(list(set(df[df['data_status'].isin([status])]['data_split_by_status'])))
  325. # df_res = pd.DataFrame(columns=['time','limit','t1', 't2','t3', 't4','t5', 't6','t7', 't8','t9', 't10','t11', 't12','t13', 't14','tmean',
  326. # 'isc1','isc2','isc3','isc4','isc5','isc6','isc7','isc8','isc9','isc10','isc11','isc12','isc13','isc14',
  327. # 'res1','res2','res3','res4','res5','res6','res7','res8','res9','res10','res11','res12','res13','res14'])
  328. df_res = pd.DataFrame(columns=['time','limit','t1', 't2','t3', 't4','t5', 't6','t7', 't8','t9', 't10','tmean',
  329. 'isc1','isc2','isc3','isc4','isc5','isc6','isc7','isc8','isc9','isc10',
  330. 'res1','res2','res3','res4','res5','res6','res7','res8','res9','res10'])
  331. limits = [3360,3361,3362,3363,3364,3365,3366, 3367, 3368, 3369, 3370]
  332. num = len(limits)
  333. index = 0
  334. dd = -1
  335. timestamp = 1545730073
  336. base_time = datetime.fromtimestamp(timestamp)
  337. for data_number in data_number_list[0:]:
  338. dd = dd + 1
  339. df_sel_bms = df[df['data_split_by_status'] == data_number]
  340. df_sel_bms = df_sel_bms.reset_index(drop=True)
  341. # current = np.mean(df_sel_bms[df_sel_bms['总电压[V]']>=limits[0]*14 and df_sel_bms['总电压[V]']<=limits[-1]*14]['总电流[A]'])
  342. current = 9
  343. if df_sel_bms.loc[0, 'SOC[%]'] > 40:
  344. # print('delete_data={},time={},soc={}'.format(dd,df_sel_bms.loc[0, '时间戳'],df_sel_bms.loc[0, 'SOC[%]']))
  345. continue
  346. else:
  347. k = -1
  348. for limit in limits:
  349. k = k + 1
  350. df_res.loc[index,'time'] = df_sel_bms.loc[0, '时间戳']
  351. for i in range(1,total_len+1):
  352. # print('data={},index={},limit{}={},cell={},time={}'.format(dd,index,k,limit,i,df_sel_bms.loc[0, '时间戳']))
  353. time_list = sorted(list(set(df_sel_bms[df_sel_bms['单体电压'+ str(i)]==limit]['时间戳'])))
  354. time_list1 = list(df_sel_bms[df_sel_bms['单体电压'+ str(i)]==limit]['时间戳'])
  355. # print(df_sel_bms['单体电压'+ str(i)])
  356. # print('index={},limit{}={},cell={},time={}'.format(index,k,limit,i,time_list[0]))
  357. df_res.loc[index,'limit'] = limit
  358. if len(time_list) > 0:
  359. time_counter = Counter(time_list1)
  360. most_counterNum = time_counter.most_common(2)
  361. time_raw = most_counterNum[0]
  362. # print('value={},type={}'.format(most_counterNum,type(time_raw)))
  363. time = (time_list[-1] - base_time).seconds
  364. # print('limit={},i={},time={}'.format(limit, i ,time))
  365. df_res.loc[index,'t'+str(i)] = time_list[-1]
  366. df_res.loc[index,'isc'+str(i)] = time
  367. # print('data={},index={},limit{}={},cell={},time={}'.format(dd,index,k,limit,i,time_list[-1]))
  368. if i == total_len:
  369. print(df_res.loc[index,'t1':'t'+str(total_len)])
  370. df_res.loc[index,'tmean'] = np.mean(df_res.loc[index,'isc1':'isc'+str(total_len)])
  371. df_res.loc[index,'isc1':'isc'+str(total_len)] = df_res.loc[index,'isc1':'isc'+str(total_len)] - df_res.loc[index,'tmean']
  372. # print('data={},k={},index={}'.format(dd,k,index))
  373. total_index = index
  374. index = index + 1
  375. # df_res.loc[index*num+k,'isc1':'isc14'] = df_res.loc[index*num+k,'t1':'t14'] - df_res.loc[index*num+k,'tmean']
  376. else:
  377. # print('NoValue_data={},time={},soc={},limit{}={},cell={}'.
  378. # format(dd,df_sel_bms.loc[0, '时间戳'],df_sel_bms.loc[0, 'SOC[%]'],k,limit,i))
  379. break
  380. for limit in limits:
  381. # print(df_res)
  382. data_number_list = sorted(list(set(df_res[df_res['limit']==limit].index)))
  383. # print(data_number_list)
  384. df_res.loc[data_number_list[0],'res1':'res'+str(total_len)]=0
  385. index = 1
  386. for data_number in data_number_list[1:]:
  387. for i in range(1,total_len+1):
  388. 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()
  389. index = index + 1
  390. result=[]
  391. for i in range(1,total_len+1):
  392. # result.append(np.mean(df_res[11:total_index,'res'+str(i)]))
  393. mean_value = df_res['res'+str(i)][11:total_index+1].mean()
  394. result.append(mean_value)
  395. # print('i{}={},total_index={}'.format(i,df_res['res'+str(i)][11:total_index+1],total_index))
  396. return df_res,result
  397. def get_charge_statics(df, status):
  398. # 计算充电行为
  399. df_res = pd.DataFrame(columns=['time', 'num','duration','Capacity'])
  400. df_res_single = pd.DataFrame(columns=['time','cycle','start_time','stop_time','start_soc','stop_soc','gps_long','gps_lat',])
  401. start_time = df_bms.loc[3771, '时间戳']
  402. timeDelta = datetime.timedelta(days=1)
  403. end_time = start_time + timeDelta
  404. while end_time < df_bms.loc[len(df_bms)-1, '时间戳']:
  405. # import pdb;pdb.set_trace()
  406. cycle = 0
  407. df_res_temp = pd.DataFrame(columns=['time', 'num'])
  408. df_sel = df_bms[(df_bms['时间戳']>=start_time) & (df_bms['时间戳']<=end_time)]
  409. origin_index = list(df_sel.index)
  410. # print(origin_index[0])
  411. data_number_list = sorted(list(set(df_sel[df_sel['data_status'].isin(['charge'])]['data_split_by_status'])))
  412. if (df_bms.loc[origin_index[0], 'data_status'] == df_bms.loc[origin_index[0]-1, 'data_status'] == ['charge']):
  413. charge_num = len(data_number_list)-1
  414. start = 1
  415. else:
  416. charge_num = len(data_number_list)
  417. start = 0
  418. for data_number in data_number_list[start:]:
  419. df_sel_bms = df_sel[df_sel['data_split_by_status'] == data_number]
  420. df_sel_bms = df_sel_bms.reset_index(drop=True)
  421. df_sel_gps = df_gps[(df_gps['时间戳']>df_sel_bms.loc[0,'时间戳']) & (df_gps['时间戳']<df_sel_bms.loc[len(df_sel_bms)-1,'时间戳'])]
  422. df_sel_gps = df_sel_gps.reset_index(drop=True)
  423. if data_number != data_number_list[start]:
  424. # startTime= datetime.datetime.strptime(df_sel_bms.loc[0, '时间戳'],"%Y-%m-%d %H:%M:%S")
  425. startTime= df_sel_bms.loc[0, '时间戳']
  426. startSoc= df_sel_bms.loc[0, 'SOC[%]']
  427. if (startTime - endTime).seconds < 5*60 or abs(endSoc - startSoc) < 5:
  428. reconn = 1
  429. else:
  430. reconn = 0
  431. else:
  432. reconn = 0
  433. # endTime= datetime.datetime.strptime(df_sel_bms.loc[len(df_sel_bms)-1, '时间戳'],"%Y-%m-%d %H:%M:%S")
  434. endTime= df_sel_bms.loc[len(df_sel_bms)-1, '时间戳']
  435. endSoc= df_sel_bms.loc[len(df_sel_bms)-1, 'SOC[%]']
  436. # index = sorted(np.where(df_sel['data_split_by_union'] == data_number))[0]
  437. # print(index)
  438. # min_index = index[0]
  439. # print(data_number_list)
  440. # print(df_sel)
  441. # print('start={},index={},data_num={},value={}'.format(start,min_index,data_number,df_sel.loc[min_index+1, '时间戳']))
  442. # if ((df_sel_bms.loc[len(df_sel_bms)-1, 'SOC[%]'] - df_sel_bms.loc[0, 'SOC[%]']) > 10.0) and reconn==0:
  443. if 1:
  444. cycle = cycle + 1
  445. # print('cycle = {}, delta = {}'.format(cycle, df_sel_bms.loc[len(df_sel_bms)-1, 'SOC[%]'] - df_sel_bms.loc[0, 'SOC[%]']))
  446. df_res_single = df_res_single.append({'time': df_sel.loc[origin_index[0], '时间戳'],
  447. 'cycle': cycle,
  448. 'start_time': df_sel_bms.loc[0, '时间戳'],
  449. 'stop_time': df_sel_bms.loc[len(df_sel_bms)-1, '时间戳'],
  450. 'start_soc': df_sel_bms.loc[0, 'SOC[%]'],
  451. 'stop_soc': df_sel_bms.loc[len(df_sel_bms)-1, 'SOC[%]'],
  452. 'gps_long': np.mean(df_sel_gps['经度']),
  453. 'gps_lat': np.mean(df_sel_gps['纬度'])}, ignore_index=True)
  454. # print(df_sel_bms)
  455. df_res = df_res.append({'time': df_sel.loc[origin_index[0], '时间戳'],
  456. 'num': charge_num}, ignore_index=True)
  457. start_time = end_time
  458. end_time = start_time + timeDelta
  459. print(df_res_single)
  460. def get_soh(df_bms, sn):
  461. # 计算SOH和一致性
  462. df_res = pd.DataFrame(columns=['sn','time', 'accum_ah','soh_cell01','soh_cell02','soh_cell03',
  463. 'soh_cell04','soh_cell05','soh_cell06','soh_cell07',
  464. 'soh_cell08','soh_cell09','soh_cell10','soh_cell11',
  465. 'soh_cell12','soh_cell13','soh_cell14','soh_cell15',
  466. 'soh_cell16','soh_cell17','soh_cell18','soh_cell19',
  467. 'soh_cell20'])
  468. df_cell_res = pd.DataFrame(columns=['sn','time','status','volt_cell01','volt_cell02','volt_cell03',
  469. 'volt_cell04','volt_cell05','volt_cell06','volt_cell07',
  470. 'volt_cell08','volt_cell09','volt_cell10','volt_cell11',
  471. 'volt_cell12','volt_cell13','volt_cell14','volt_cell15',
  472. 'volt_cell16','volt_cell17','volt_cell18','volt_cell19',
  473. 'volt_cell20','volt_max','volt_min', 'volt_avr','soc_diff','soc_diff_div','over_discharge'])
  474. df_sel = df_bms
  475. # print(sn[0][0:2])
  476. if sn[0][0:5] == 'PK504':
  477. soc_ocv_table = pd.read_excel(r'D:\Work\Interior\Cloud_BMS\Overall\产品信息\电池OCV表格.xlsx', '60AH')
  478. cellcap = 55 # Capacity
  479. elif sn[0][0:5] == 'PK501':
  480. soc_ocv_table = pd.read_excel(r'D:\Work\Interior\Cloud_BMS\Overall\产品信息\电池OCV表格.xlsx', '40AH')
  481. cellcap = 40 # Capacity
  482. elif sn[0][0:2] == 'UD':
  483. soc_ocv_table = pd.read_excel(r'D:\Work\Interior\Cloud_BMS\Overall\产品信息\电池OCV表格.xlsx', '50AH')
  484. cellcap = 50 # Capacity
  485. cellsoh_list = []
  486. data_number_list = sorted(list(set(df_sel[df_sel['data_status'].isin(['charge'])]['data_split_by_status'])))
  487. start = 1
  488. for data_number in data_number_list[start:-2]:
  489. ## 充电以及前后数据全部获取
  490. df_sel_bms_relax_start = df_sel[df_sel['data_split_by_status'] == data_number-1]
  491. df_sel_bms = df_sel[df_sel['data_split_by_status'] == data_number]
  492. df_sel_bms_relax_end = df_sel[df_sel['data_split_by_status'] == data_number+1]
  493. origin_index = list(df_sel_bms.index)
  494. origin_index_relax_start = list(df_sel_bms_relax_start.index)
  495. origin_index_relax_end = list(df_sel_bms_relax_end.index)
  496. df_sel_bms_relax_start = df_sel_bms_relax_start.reset_index(drop=True)
  497. df_sel_bms = df_sel_bms.reset_index(drop=True)
  498. df_sel_bms_relax_end = df_sel_bms_relax_end.reset_index(drop=True)
  499. ## 充电前后静置时间
  500. # delta_time_start = (df_sel_bms_relax_start.loc[len(df_sel_bms_relax_start)-1,'时间戳'] - df_sel_bms_relax_start.loc[0,'时间戳']).seconds
  501. delta_time_end = (df_sel_bms_relax_end.loc[len(df_sel_bms_relax_end)-1,'时间戳'] - df_sel_bms_relax_end.loc[0,'时间戳']).seconds
  502. # print(df_sel_bms_relax_start.loc[len(df_sel_bms_relax_start)-1,'时间戳'],
  503. # df_sel_bms_relax_start.loc[0,'时间戳'],
  504. # df_sel_bms_relax_start.loc[len(df_sel_bms_relax_start)-1,'data_status'],
  505. # df_sel_bms_relax_end.loc[len(df_sel_bms_relax_end)-1,'data_status'],
  506. # df_sel_bms.loc[0,'时间戳'],
  507. # delta_time_start,
  508. # delta_time_end)
  509. ## 充电前后静置并且充电前静置超过10min,充电后静置超过3h
  510. if (df_sel_bms_relax_start.loc[len(df_sel_bms_relax_start)-1,'data_status'] == 'stand' or \
  511. df_sel_bms_relax_start.loc[len(df_sel_bms_relax_start)-1,'data_status'] == 'drive') and \
  512. df_sel_bms_relax_end.loc[len(df_sel_bms_relax_end)-1,'data_status'] == 'stand' and\
  513. delta_time_end > 18000:
  514. ## 记录充电相关信息
  515. start_time = df_sel_bms.loc[0,'时间戳']
  516. end_time = df_sel_bms.loc[len(df_sel_bms)-1,'时间戳']
  517. relax_time = df_sel_bms_relax_end.loc[len(df_sel_bms_relax_end)-1,'时间戳']
  518. start_current = df_sel_bms_relax_start.loc[len(df_sel_bms_relax_start)-1,'总电流[A]']
  519. end_current = df_sel_bms_relax_end.loc[len(df_sel_bms_relax_end)-1,'总电流[A]']
  520. # print(start_time,end_time,relax_time,start_current,end_current)
  521. ## 记录充电开始前信息
  522. start_volt_class = df_sel.loc[origin_index[0]-3,'单体电压1':'单体电压20']
  523. start_index = start_volt_class
  524. start_index = start_index.apply(lambda x: 1 if x<3.279 or (x > 3.292 and x < 3.307) else 0)
  525. start_index = np.array(start_index)
  526. start_soc,start_cellsoc_list = getcellsoc(start_volt_class,soc_ocv_table)
  527. if np.min(start_volt_class) < 3182:
  528. over_discharge = 1
  529. else:
  530. over_discharge = 0
  531. if np.max(start_volt_class) > 3640:
  532. over_charge = 1
  533. else:
  534. over_charge = 0
  535. df_cell_res = df_cell_res.append({'sn':sn,
  536. 'time':df_sel.loc[origin_index[0]-3,'时间戳'],
  537. 'status':'start',
  538. 'volt_cell01':start_volt_class[0],'volt_cell02':start_volt_class[1],
  539. 'volt_cell03':start_volt_class[2],'volt_cell04':start_volt_class[3],
  540. 'volt_cell05':start_volt_class[4],'volt_cell06':start_volt_class[5],
  541. 'volt_cell07':start_volt_class[6],'volt_cell08':start_volt_class[7],
  542. 'volt_cell09':start_volt_class[8],'volt_cell10':start_volt_class[9],
  543. 'volt_cell11':start_volt_class[10],'volt_cell12':start_volt_class[11],
  544. 'volt_cell13':start_volt_class[12],'volt_cell14':start_volt_class[13],
  545. 'volt_cell15':start_volt_class[14],'volt_cell16':start_volt_class[15],
  546. 'volt_cell17':start_volt_class[16],'volt_cell18':start_volt_class[17],
  547. 'volt_cell19':start_volt_class[18],'volt_cell20':start_volt_class[19],
  548. 'volt_max':np.max(start_volt_class),
  549. 'volt_min':np.min(start_volt_class),
  550. 'volt_avr':np.mean(start_volt_class),
  551. 'soc_diff':np.max(start_cellsoc_list)-np.min(start_cellsoc_list),
  552. 'soc_diff_div':np.mean(start_volt_class[0:9])-np.mean(start_volt_class[10:19]),
  553. 'over_discharge':over_discharge,'over_charge':over_charge}, ignore_index=True)
  554. ## 记录充电结束信息
  555. end_volt_class = df_sel_bms_relax_end.loc[len(df_sel_bms_relax_end)-3,'单体电压1':'单体电压20']
  556. end_index = end_volt_class
  557. end_index = end_index.apply(lambda x: 1 if x>3.346 or (x > 3.292 and x < 3.307) else 0)
  558. end_index = np.array(end_index)
  559. end_soc,end_cellsoc_list = getcellsoc(end_volt_class,soc_ocv_table)
  560. if np.min(end_volt_class) < 3182:
  561. over_discharge = 1
  562. else:
  563. over_discharge = 0
  564. if np.max(end_volt_class) > 3640:
  565. over_charge = 1
  566. else:
  567. over_charge = 0
  568. df_cell_res = df_cell_res.append({'sn':sn,
  569. 'time':df_sel_bms_relax_end.loc[len(df_sel_bms_relax_end)-3,'时间戳'],
  570. 'status':'end',
  571. 'volt_cell01':end_volt_class[0],'volt_cell02':end_volt_class[1],
  572. 'volt_cell03':end_volt_class[2],'volt_cell04':end_volt_class[3],
  573. 'volt_cell05':end_volt_class[4],'volt_cell06':end_volt_class[5],
  574. 'volt_cell07':end_volt_class[6],'volt_cell08':end_volt_class[7],
  575. 'volt_cell09':end_volt_class[8],'volt_cell10':end_volt_class[9],
  576. 'volt_cell11':end_volt_class[10],'volt_cell12':end_volt_class[11],
  577. 'volt_cell13':end_volt_class[12],'volt_cell14':end_volt_class[13],
  578. 'volt_cell15':end_volt_class[14],'volt_cell16':end_volt_class[15],
  579. 'volt_cell17':end_volt_class[16],'volt_cell18':end_volt_class[17],
  580. 'volt_cell19':end_volt_class[18],'volt_cell20':end_volt_class[19],
  581. 'volt_max':np.max(end_volt_class),
  582. 'volt_min':np.min(end_volt_class),
  583. 'volt_avr':np.mean(end_volt_class),
  584. 'soc_diff':np.max(end_cellsoc_list)-np.min(end_cellsoc_list),
  585. 'soc_diff_div':np.mean(end_volt_class[0:9])-np.mean(end_volt_class[10:19]),
  586. 'over_discharge':over_discharge,'over_charge':over_charge}, ignore_index=True)
  587. ## 计算过程量,deltaSOC和deltaAh
  588. delta_cellsoc_list = np.array(end_cellsoc_list) - np.array(start_cellsoc_list)
  589. accum = 0
  590. for time_num in range(1,len(df_sel_bms)):
  591. delta_time = (df_sel_bms.loc[time_num,'时间戳'] - df_sel_bms.loc[time_num-1,'时间戳']).seconds
  592. accum = accum - df_sel_bms.loc[time_num,'总电流[A]']* delta_time/3600
  593. ## 单次SOC间隔超过10%,计算SOH
  594. if np.mean(delta_cellsoc_list) > 10:
  595. cellsoh=accum/delta_cellsoc_list*100/cellcap*100
  596. # cellsoh=cellsoh*start_index*end_index
  597. # print(cellsoh)
  598. df_res = df_res.append({'sn':sn,
  599. 'time':df_sel_bms.loc[0,'时间戳'],
  600. 'accum_ah':accum,
  601. 'soh_cell01':cellsoh[0],'soh_cell02':cellsoh[1],'soh_cell03':cellsoh[2],
  602. 'soh_cell04':cellsoh[3],'soh_cell05':cellsoh[4],'soh_cell06':cellsoh[5],
  603. 'soh_cell07':cellsoh[6],'soh_cell08':cellsoh[7],'soh_cell09':cellsoh[8],
  604. 'soh_cell10':cellsoh[9],'soh_cell11':cellsoh[10],'soh_cell12':cellsoh[11],
  605. 'soh_cell13':cellsoh[12],'soh_cell14':cellsoh[13],'soh_cell15':cellsoh[14],
  606. 'soh_cell16':cellsoh[15],'soh_cell17':cellsoh[16],'soh_cell18':cellsoh[17],
  607. 'soh_cell19':cellsoh[18],'soh_cell20':cellsoh[19]},ignore_index=True)
  608. cellsoh_list_single=cellsoh.tolist()
  609. cellsoh_list.append(cellsoh_list_single)
  610. return df_res, df_cell_res
  611. def get_charge_start_time(df,status):
  612. data_number_list = sorted(list(set(df[df['data_status'].isin([status])]['data_split_by_status'])))
  613. for data_number in data_number_list[0:]:
  614. df_sel_bms = df[df['data_split_by_status'] == data_number]
  615. df_sel_bms = df_sel_bms.reset_index(drop=True)
  616. start_time = df_sel_bms.loc[0,'时间戳']
  617. start_time = datetime.strftime(start_time, "%H:%M:%S")
  618. limit_time = datetime.strptime("20:00:00", "%H:%M:%S")
  619. print('start_time{}>20:00:{}'.format(start_time,limit_time))