DBManager.py 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. <<<<<<< HEAD
  2. '''
  3. 暂时采用http方式获取历史数据。
  4. 预留:后期若改用通过访问数据库的形式进行数据的获取,则本文件负责数据库的连接,sql指令的执行,数据获取等功能。
  5. '''
  6. __author__ = 'lmstack'
  7. from re import S
  8. import time
  9. import datetime
  10. import os
  11. import urllib.request
  12. import time
  13. import pandas as pd
  14. import numpy as np
  15. import json
  16. import requests
  17. import pdb
  18. # import http.client
  19. # http.client.HTTPConnection._http_vsn = 10
  20. # http.client.HTTPConnection._http_vsn_str = 'HTTP/1.1'
  21. class DBManager():
  22. def __init__(self, host='', port='', auth='', db='', username='', password=''):
  23. pass
  24. def __enter__(self):
  25. self.connect()
  26. return self
  27. def __exit__(self):
  28. self.close()
  29. def connect(self):
  30. conn_success_flag = 0
  31. while not conn_success_flag:
  32. try:
  33. pass # 连接数据库
  34. except Exception as e:
  35. conn_success_flag = 0
  36. time.sleep(5)
  37. else:
  38. conn_success_flag = 1
  39. pass # 连接成功, 获取cursor
  40. def close(self):
  41. try:
  42. pass # 断开数据库
  43. except Exception as e:
  44. print(e)
  45. else:
  46. print('数据库已断开连接')
  47. # 以下各个函数实现 通过http方式获取数据
  48. @staticmethod
  49. def _get_var_name(cellnum,Tempnum,Othernum):
  50. temp = []
  51. for i in range(cellnum):
  52. temp.append('单体电压'+str(i+1))
  53. for i in range(Tempnum):
  54. temp.append('单体温度'+str(i+1))
  55. for i in range(Othernum):
  56. temp.append('其他温度'+str(i+1))
  57. return temp
  58. @staticmethod
  59. def _download_json_data(url):
  60. '''
  61. 返回json数据的生成器,一次一行
  62. '''
  63. i = 0
  64. while 1:
  65. try:
  66. r = requests.get(url, stream=True, timeout=100, headers={'Connection':'close'})
  67. break
  68. except requests.exceptions.RequestException as e:
  69. if (i == 0):
  70. print()
  71. print('\r' + 'Server Error, retry {}......'.format(str(i)), end=" ")
  72. time.sleep(5)
  73. i+=1
  74. # print(r.content)
  75. # pdb.set_trace()
  76. for line in r.iter_lines():
  77. if line:
  78. yield json.loads(line)
  79. @staticmethod
  80. def _convert_to_dataframe_bms(data, mode=0):
  81. CellU = []
  82. CellT = []
  83. OtherT = []
  84. CellU_Num = 0
  85. CellT_Num = 0
  86. OtherT_Num = 0
  87. CellU_Num = len(data['ffBatteryStatus']['cellVoltageList'])
  88. CellT_Num = len(data['ffBatteryStatus']['cellTempList'])
  89. try:
  90. OtherT_Num = len(data['ffBatteryStatus']['otherTempList'])
  91. except:
  92. OtherT_Num = 0
  93. for i in range(CellU_Num):
  94. CellU.append(data['ffBatteryStatus']['cellVoltageList'][i]*1000)
  95. for i in range(CellT_Num):
  96. CellU.append(data['ffBatteryStatus']['cellTempList'][i])
  97. for i in range(OtherT_Num):
  98. CellU.append(data['ffBatteryStatus']['otherTempList'][i])
  99. if mode == 0:
  100. data_len = 15
  101. data_block = np.array([data['info']['obdTime'],data['ffBatteryStatus']['rssi'],data['ffBatteryStatus']['errorLevel'],data['ffBatteryStatus']['errorCode']
  102. ,data['ffBatteryStatus']['current'],data['ffBatteryStatus']['voltageInner'],data['ffBatteryStatus']['voltageOutter'],
  103. data['ffBatteryStatus']['totalOutputState'],data['ffBatteryStatus']['lockedState'],
  104. data['ffBatteryStatus']['chargeState'],data['ffBatteryStatus']['heatState'],data['ffBatteryStatus']['cellVoltageDiff']
  105. ,data['ffBatteryStatus']['soc'],data['ffBatteryStatus']['soh'],data['ffBatteryStatus']['cellVolBalance']]).reshape(1,data_len)
  106. elif mode == 1:
  107. data_len = 11
  108. data_block = np.array([data['info']['obdTime'],data['ffBatteryStatus']['rssi']
  109. ,data['ffBatteryStatus'].get('errorLevel'),data['ffBatteryStatus'].get('errorCode'),data['ffBatteryStatus']['switchState']
  110. ,data['ffBatteryStatus']['current'],data['ffBatteryStatus']['voltageInner'],data['ffBatteryStatus']['chargeState'],
  111. data['ffBatteryStatus']['cellVoltageDiff'],data['ffBatteryStatus']['soc'],data['ffBatteryStatus']['soh']]).reshape(1,data_len)
  112. data_block = np.append(data_block,CellU)
  113. data_block = np.append(data_block,CellT)
  114. data_block = np.append(data_block,OtherT)
  115. data_block = data_block.reshape(1,len(data_block))
  116. return data_block,CellU_Num,CellT_Num,OtherT_Num
  117. @staticmethod
  118. def _convert_to_dataframe_gps(data, mode=0):
  119. if mode == 0:
  120. if data['info']['subType'] == 1:
  121. data_block = np.array([data['info']['obdTime'],data['ffGps']['locationType'], data['ffGps']['satellites'],
  122. data['ffGps']['latitude'],data['ffGps']['longitude'],data['ffGps']['speed'],
  123. data['ffGps']['altitude'], data['ffGps']['direction']]).reshape(1,8)
  124. df = pd.DataFrame(
  125. columns=['时间戳','定位类型', '卫星数','纬度','经度','速度[km/h]','海拔','航向'],data=data_block)
  126. elif data['info']['subType'] == 2:
  127. df = pd.DataFrame(
  128. columns=['时间戳','定位类型', '卫星数','纬度','经度','速度[km/h]','海拔','航向'])
  129. if mode == 1:
  130. data_block = np.array([data['info']['obdTime'],data['ffGps']['locationType'],data['ffGps']['latitude'],data['ffGps']['longitude']
  131. ,data['ffGps']['speed'], data['ffGps']['isValid']]).reshape(1,6)
  132. df = pd.DataFrame(
  133. columns=['时间戳','定位类型', '纬度','经度','速度[km/h]','有效位'],data=data_block)
  134. return df
  135. @staticmethod
  136. def _convert_to_dataframe_system(data, mode=0):
  137. if mode == 0:
  138. data_block = np.array([data['info']['obdTime'],data['ffSystemInfo']['heatTargetTemp'], data['ffSystemInfo']['heatTimeout'],
  139. time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(int(data['ffSystemInfo']['rentalStartTime'])/1000)),
  140. data['ffSystemInfo']['rentalPeriodDays'],data['ffSystemInfo']['bmsInterval'],
  141. data['ffSystemInfo']['gpsInterval']]).reshape(1,7)
  142. df = pd.DataFrame(
  143. columns=['时间戳','加热目标温度', '加热超时','租赁开始时间','租赁天数','bms上传周期','gps上传周期'],data=data_block)
  144. if mode == 1:
  145. df = pd.DataFrame()
  146. return df
  147. @staticmethod
  148. def _convert_to_dataframe_accum(data, mode=0):
  149. if mode == 0:
  150. data_block = np.array([data['info']['obdTime'],data['ffBatteryAccum']['SOH_AlgUnexTime'], data['ffBatteryAccum']['CHG_AHaccum'],
  151. data['ffBatteryAccum']['CHG_PHaccum'], data['ffBatteryAccum']['DSG_AHaccum'],
  152. data['ffBatteryAccum']['DSG_PHaccum'],data['ffBatteryAccum']['OverTemp_CHG_AHaccum'],
  153. data['ffBatteryAccum']['OverTemp_CHG_PHaccum']]).reshape(1,8)
  154. df = pd.DataFrame(
  155. columns=['时间戳','SOH未标定时间', '累计充电电量','累计充电能量','累计放电电量','累计放电能量',
  156. '累计高温充电电量', '累计高温充电能量'],data=data_block)
  157. if mode == 1:
  158. data_block = np.array([data['info']['obdTime'], data['ffBatteryAccum']['CHG_AHaccum'],
  159. data['ffBatteryAccum']['CHG_PHaccum'], data['ffBatteryAccum']['DSG_AHaccum'],
  160. data['ffBatteryAccum']['DSG_PHaccum'],data['ffBatteryAccum']['totalMileage']]).reshape(1,6)
  161. df = pd.DataFrame(
  162. columns=['时间戳','累计充电电量','累计充电能量','累计放电电量','累计放电能量', '累积里程'],data=data_block)
  163. return df
  164. @staticmethod
  165. def _get_data(urls,type_name,mode=0):
  166. if type_name == 'bms':
  167. if mode == 0:
  168. name_const = ['时间戳','GSM信号','故障等级','故障代码','总电流[A]','总电压[V]', '外电压', '总输出状态', '上锁状态', '充电状态','加热状态',
  169. '单体压差', 'SOC[%]','SOH[%]','单体均衡状态']
  170. elif mode == 1:
  171. name_const = ['时间戳','GSM信号','故障等级', '故障代码','开关状态', '总电流[A]','总电压[V]','充电状态', '单体压差', 'SOC[%]','SOH[%]']
  172. i=0
  173. CellUNum = 0
  174. CellTNum = 0
  175. OtherTNumm = 0
  176. st = time.time()
  177. for line in DBManager._download_json_data(urls):
  178. et = time.time()
  179. if i==0:
  180. data_blocks,CellUNum,CellTNum,OtherTNumm = DBManager._convert_to_dataframe_bms(line, mode)
  181. i+=1
  182. continue
  183. try:
  184. data_block,CellUNum,CellTNum,OtherTNumm = DBManager._convert_to_dataframe_bms(line, mode)
  185. except:
  186. continue
  187. data_blocks = np.concatenate((data_blocks,data_block),axis=0)
  188. # print('\r'+str(i),end=" ")
  189. # print(data_block)
  190. # print(urls)
  191. # print(time.time()-et)
  192. i+=1
  193. name_var = DBManager._get_var_name(CellUNum,CellTNum,OtherTNumm)
  194. name_const.extend(name_var)
  195. columns_name = name_const
  196. if i==0:
  197. data_blocks = []
  198. df_all = pd.DataFrame(columns=columns_name,data=data_blocks)
  199. if not df_all.empty:
  200. df_all.loc[:,'时间戳'] = df_all.loc[:,'时间戳'].apply(lambda x:time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(int(x)/1000)))
  201. return df_all
  202. elif type_name =='gps':
  203. if mode == 0:
  204. df_all = pd.DataFrame(columns=['时间戳','定位类型', '卫星数','纬度','经度','速度[km/h]','海拔','航向'])
  205. elif mode == 1:
  206. df_all = pd.DataFrame(columns=['时间戳','定位类型', '纬度','经度','速度[km/h]','有效位'])
  207. for line in DBManager._download_json_data(urls):
  208. df_add = DBManager._convert_to_dataframe_gps(line, mode)
  209. df_all = df_all.append(df_add,ignore_index=True)
  210. if not df_all.empty:
  211. df_all.loc[:,'时间戳'] = df_all.loc[:,'时间戳'].apply(lambda x:time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(int(x)/1000)))
  212. return df_all
  213. elif type_name =='system':
  214. if mode == 0:
  215. df_all = pd.DataFrame(columns=['时间戳','加热目标温度', '加热超时','租赁开始时间','租赁天数','bms上传周期','gps上传周期'])
  216. elif mode == 1:
  217. df_all = pd.DataFrame()
  218. for line in DBManager._download_json_data(urls):
  219. df_add = DBManager._convert_to_dataframe_system(line, mode)
  220. df_all = df_all.append(df_add,ignore_index=True)
  221. if not df_all.empty:
  222. df_all.loc[:,'时间戳'] = df_all.loc[:,'时间戳'].apply(lambda x:time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(int(x)/1000)))
  223. return df_all
  224. elif type_name =='accum':
  225. if mode == 0:
  226. df_all = pd.DataFrame(columns=['时间戳','SOH未标定时间', '累计充电电量','累计充电能量','累计放电电量','累计放电能量',
  227. '累计高温充电电量', '累计高温充电能量'])
  228. elif mode == 1:
  229. df_all = pd.DataFrame(columns=['时间戳','累计充电电量','累计充电能量','累计放电电量','累计放电能量', '累积里程'])
  230. for line in DBManager._download_json_data(urls):
  231. df_add = DBManager._convert_to_dataframe_accum(line, mode)
  232. df_all = df_all.append(df_add,ignore_index=True)
  233. if not df_all.empty:
  234. df_all.loc[:,'时间戳'] = df_all.loc[:,'时间戳'].apply(lambda x:time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(int(x)/1000)))
  235. return df_all
  236. def get_data(self, url='http://172.16.126.13/store/load?dataType={}&limit=0&sn={}', sn='', start_time='', end_time='',
  237. data_groups=['bms', 'gps']):
  238. '''
  239. 获取指定 sn 和起止日期的bms和gps数据.
  240. 添加了重试机制。
  241. --------------输入参数------------
  242. url:数据获取url, 可采用默认值
  243. sn: str, 电池sn号
  244. start_time: str, 开始时间
  245. end_time: str, 结束时间
  246. data_groups: 选择需要获取的数据组,可填入多个字符串(默认只获取bms和gps数据)
  247. bms: bms数据
  248. gps:gps数据
  249. system:system数据
  250. accum:accum数据
  251. --------------输出参数------------
  252. df_data: {'bms':dataframe, 'gps':dataframe, 'system':dataframe, ;accum':dataframe}
  253. '''
  254. if len(set(data_groups) - (set(data_groups) and set(['bms', 'gps', 'system', 'accum']))) > 0:
  255. raise Exception("data_groups 参数错误")
  256. # mode: 0:正常取数; 1:7255 取数
  257. if sn[0:2] == 'UD' or sn[0:2] == 'MG':
  258. mode = 1
  259. else:
  260. mode = 0
  261. bms_all_data = pd.DataFrame()
  262. gps_all_data = pd.DataFrame()
  263. system_all_data = pd.DataFrame()
  264. accum_all_data = pd.DataFrame()
  265. maxnum = (datetime.datetime.strptime(end_time, "%Y-%m-%d %H:%M:%S") - datetime.datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S")).days +1
  266. print("### start to get data {} from {} to {}".format(sn, start_time, end_time))
  267. # 为避免chunkEncodingError错误,数据每天获取一次,然后将每天的数据合并,得到最终的数据
  268. for j in range(int(maxnum)):
  269. timefrom = datetime.datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S")+ datetime.timedelta(days=j)
  270. timeto = datetime.datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S")+ datetime.timedelta(days=j+1)
  271. #滴滴的数据sub=0
  272. if timefrom.strftime('%Y-%m-%d %H:%M:%S') >= end_time:
  273. break
  274. elif timeto.strftime('%Y-%m-%d %H:%M:%S') > end_time:
  275. timeto = datetime.datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S')
  276. #print('{}_{}_----getting data----'.format(sn, timefrom))
  277. bms_data = pd.DataFrame()
  278. gps_data = pd.DataFrame()
  279. system_data = pd.DataFrame()
  280. accum_data = pd.DataFrame()
  281. while True:
  282. try:
  283. print('\r' + "# get data from {} to {}.........".format(str(timefrom), str(timeto)), end=" ")
  284. for data_group in data_groups:
  285. if data_group == 'bms':
  286. file_url = url.format(12, sn) + "&from="+timefrom.strftime('%Y-%m-%d %H:%M:%S')+"&to="+timeto.strftime('%Y-%m-%d %H:%M:%S')
  287. bms_data = DBManager._get_data(file_url,'bms',mode)
  288. if data_group == 'gps':
  289. file_url = url.format(16, sn) + "&from="+timefrom.strftime('%Y-%m-%d %H:%M:%S')+"&to="+timeto.strftime('%Y-%m-%d %H:%M:%S')
  290. gps_data = DBManager._get_data(file_url,'gps',mode)
  291. if data_group == 'system':
  292. file_url = url.format(13, sn) + "&from="+timefrom.strftime('%Y-%m-%d %H:%M:%S')+"&to="+timeto.strftime('%Y-%m-%d %H:%M:%S')
  293. system_data = DBManager._get_data(file_url,'system',mode)
  294. if data_group == 'accum':
  295. file_url = url.format(23, sn) + "&from="+timefrom.strftime('%Y-%m-%d %H:%M:%S')+"&to="+timeto.strftime('%Y-%m-%d %H:%M:%S')
  296. accum_data = DBManager._get_data(file_url,'accum',mode)
  297. except Exception as e:
  298. if 'Connection broken' in str(e):
  299. continue
  300. else:
  301. raise Exception
  302. else:
  303. bms_all_data = pd.concat([bms_all_data, bms_data], ignore_index=True)
  304. gps_all_data = pd.concat([gps_all_data, gps_data], ignore_index=True)
  305. system_all_data = pd.concat([system_all_data, system_data], ignore_index=True)
  306. accum_all_data = pd.concat([accum_all_data, accum_data], ignore_index=True)
  307. break
  308. bms_all_data = bms_all_data.reset_index(drop=True)
  309. gps_all_data = gps_all_data.reset_index(drop=True)
  310. system_all_data = system_all_data.reset_index(drop=True)
  311. accum_all_data = accum_all_data.reset_index(drop=True)
  312. print('\nall data-getting done, bms_count is {}, gps_count is {}, system_count is {}, accum_count is {} \n'.format(
  313. str(len(bms_all_data)), str(len(gps_all_data)), str(len(system_all_data)), str(len(accum_all_data))))
  314. return {'bms':bms_all_data, 'gps':gps_all_data, 'system':system_all_data, 'accum':accum_all_data}
  315. =======
  316. '''
  317. 暂时采用http方式获取历史数据。
  318. 预留:后期若改用通过访问数据库的形式进行数据的获取,则本文件负责数据库的连接,sql指令的执行,数据获取等功能。
  319. '''
  320. __author__ = 'lmstack'
  321. import time
  322. import datetime
  323. import time
  324. import pandas as pd
  325. import numpy as np
  326. import json
  327. import requests
  328. import pymysql
  329. import pdb
  330. class DBManager():
  331. def __init__(self, host='', port='', auth='', db='', username='', password=''):
  332. self.host = host
  333. self.port = port
  334. self.auth = auth
  335. self.db = db
  336. self.username = username
  337. self.password = password
  338. pass
  339. def __enter__(self):
  340. self.connect()
  341. return self
  342. def __exit__(self, exc_type, exc_val, exc_tb):
  343. self.close()
  344. def connect(self):
  345. conn_success_flag = 0
  346. while not conn_success_flag:
  347. try:
  348. self.conn = pymysql.connect(host=self.host, port=self.port, user=self.user, password=self.password, database=self.db)
  349. except Exception as e:
  350. conn_success_flag = 0
  351. print("数据库连接失败 :{}".format(e))
  352. time.sleep(5)
  353. else:
  354. conn_success_flag = 1
  355. self.cursor = self.conn.cursor()
  356. def close(self):
  357. try:
  358. self.conn.close()
  359. except Exception as e:
  360. print(e)
  361. else:
  362. print('数据库已断开连接')
  363. def add(table, keyvalue):
  364. fields_str = ''
  365. values_str = ''
  366. for k,v in keyvalue.items():
  367. fields_str += k+' '
  368. sql = 'insert into table {} ({}) values ({})'.format(table, fields_str, values_str)
  369. # 以下各个函数实现 通过http方式获取数据
  370. @staticmethod
  371. def _get_var_name(cellnum,Tempnum,Othernum):
  372. temp = []
  373. for i in range(cellnum):
  374. temp.append('单体电压'+str(i+1))
  375. for i in range(Tempnum):
  376. temp.append('单体温度'+str(i+1))
  377. for i in range(Othernum):
  378. temp.append('其他温度'+str(i+1))
  379. return temp
  380. @staticmethod
  381. def _download_json_data(url):
  382. '''
  383. 返回json数据的生成器,一次一行
  384. '''
  385. i = 0
  386. while 1:
  387. try:
  388. r = requests.get(url, stream=True, timeout=100, headers={'Connection':'close'})
  389. break
  390. except requests.exceptions.RequestException as e:
  391. if (i == 0):
  392. print()
  393. print('\r' + 'Server Error, retry {}......'.format(str(i)), end=" ")
  394. time.sleep(5)
  395. i+=1
  396. # print(r.content)
  397. # pdb.set_trace()
  398. for line in r.iter_lines():
  399. if line:
  400. yield json.loads(line)
  401. @staticmethod
  402. def _convert_to_dataframe_bms(data, mode=0):
  403. CellU = []
  404. CellT = []
  405. OtherT = []
  406. CellU_Num = 0
  407. CellT_Num = 0
  408. OtherT_Num = 0
  409. CellU_Num = len(data['ffBatteryStatus']['cellVoltageList'])
  410. CellT_Num = len(data['ffBatteryStatus']['cellTempList'])
  411. try:
  412. OtherT_Num = len(data['ffBatteryStatus']['otherTempList'])
  413. except:
  414. OtherT_Num = 0
  415. for i in range(CellU_Num):
  416. CellU.append(data['ffBatteryStatus']['cellVoltageList'][i]*1000)
  417. for i in range(CellT_Num):
  418. CellU.append(data['ffBatteryStatus']['cellTempList'][i])
  419. for i in range(OtherT_Num):
  420. CellU.append(data['ffBatteryStatus']['otherTempList'][i])
  421. if mode == 0:
  422. data_len = 15
  423. data_block = np.array([data['info']['obdTime'],data['ffBatteryStatus']['rssi'],data['ffBatteryStatus']['errorLevel'],data['ffBatteryStatus']['errorCode']
  424. ,data['ffBatteryStatus']['current'],data['ffBatteryStatus']['voltageInner'],data['ffBatteryStatus']['voltageOutter'],
  425. data['ffBatteryStatus']['totalOutputState'],data['ffBatteryStatus']['lockedState'],
  426. data['ffBatteryStatus']['chargeState'],data['ffBatteryStatus']['heatState'],data['ffBatteryStatus']['cellVoltageDiff']
  427. ,data['ffBatteryStatus']['soc'],data['ffBatteryStatus']['soh'],data['ffBatteryStatus']['cellVolBalance']]).reshape(1,data_len)
  428. elif mode == 1:
  429. data_len = 11
  430. data_block = np.array([data['info']['obdTime'],data['ffBatteryStatus']['rssi']
  431. ,data['ffBatteryStatus'].get('errorLevel'),data['ffBatteryStatus'].get('errorCode'),data['ffBatteryStatus']['switchState']
  432. ,data['ffBatteryStatus']['current'],data['ffBatteryStatus']['voltageInner'],data['ffBatteryStatus']['chargeState'],
  433. data['ffBatteryStatus']['cellVoltageDiff'],data['ffBatteryStatus']['soc'],data['ffBatteryStatus']['soh']]).reshape(1,data_len)
  434. data_block = np.append(data_block,CellU)
  435. data_block = np.append(data_block,CellT)
  436. data_block = np.append(data_block,OtherT)
  437. data_block = data_block.reshape(1,len(data_block))
  438. return data_block,CellU_Num,CellT_Num,OtherT_Num
  439. @staticmethod
  440. def _convert_to_dataframe_gps(data, mode=0):
  441. if mode == 0:
  442. if data['info']['subType'] == 1:
  443. data_block = np.array([data['info']['obdTime'],data['ffGps']['locationType'], data['ffGps']['satellites'],
  444. data['ffGps']['latitude'],data['ffGps']['longitude'],data['ffGps']['speed'],
  445. data['ffGps']['altitude'], data['ffGps']['direction']]).reshape(1,8)
  446. df = pd.DataFrame(
  447. columns=['时间戳','定位类型', '卫星数','纬度','经度','速度[km/h]','海拔','航向'],data=data_block)
  448. elif data['info']['subType'] == 2:
  449. df = pd.DataFrame(
  450. columns=['时间戳','定位类型', '卫星数','纬度','经度','速度[km/h]','海拔','航向'])
  451. if mode == 1:
  452. data_block = np.array([data['info']['obdTime'],data['ffGps']['locationType'],data['ffGps']['latitude'],data['ffGps']['longitude']
  453. ,data['ffGps']['speed'], data['ffGps']['isValid']]).reshape(1,6)
  454. df = pd.DataFrame(
  455. columns=['时间戳','定位类型', '纬度','经度','速度[km/h]','有效位'],data=data_block)
  456. return df
  457. @staticmethod
  458. def _convert_to_dataframe_system(data, mode=0):
  459. if mode == 0:
  460. data_block = np.array([data['info']['obdTime'],data['ffSystemInfo']['heatTargetTemp'], data['ffSystemInfo']['heatTimeout'],
  461. time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(int(data['ffSystemInfo']['rentalStartTime'])/1000)),
  462. data['ffSystemInfo']['rentalPeriodDays'],data['ffSystemInfo']['bmsInterval'],
  463. data['ffSystemInfo']['gpsInterval']]).reshape(1,7)
  464. df = pd.DataFrame(
  465. columns=['时间戳','加热目标温度', '加热超时','租赁开始时间','租赁天数','bms上传周期','gps上传周期'],data=data_block)
  466. if mode == 1:
  467. df = pd.DataFrame()
  468. return df
  469. @staticmethod
  470. def _convert_to_dataframe_accum(data, mode=0):
  471. if mode == 0:
  472. data_block = np.array([data['info']['obdTime'],data['ffBatteryAccum']['SOH_AlgUnexTime'], data['ffBatteryAccum']['CHG_AHaccum'],
  473. data['ffBatteryAccum']['CHG_PHaccum'], data['ffBatteryAccum']['DSG_AHaccum'],
  474. data['ffBatteryAccum']['DSG_PHaccum'],data['ffBatteryAccum']['OverTemp_CHG_AHaccum'],
  475. data['ffBatteryAccum']['OverTemp_CHG_PHaccum']]).reshape(1,8)
  476. df = pd.DataFrame(
  477. columns=['时间戳','SOH未标定时间', '累计充电电量','累计充电能量','累计放电电量','累计放电能量',
  478. '累计高温充电电量', '累计高温充电能量'],data=data_block)
  479. if mode == 1:
  480. data_block = np.array([data['info']['obdTime'], data['ffBatteryAccum']['CHG_AHaccum'],
  481. data['ffBatteryAccum']['CHG_PHaccum'], data['ffBatteryAccum']['DSG_AHaccum'],
  482. data['ffBatteryAccum']['DSG_PHaccum'],data['ffBatteryAccum']['totalMileage']]).reshape(1,6)
  483. df = pd.DataFrame(
  484. columns=['时间戳','累计充电电量','累计充电能量','累计放电电量','累计放电能量', '累积里程'],data=data_block)
  485. return df
  486. @staticmethod
  487. def _get_data(urls,type_name,mode=0):
  488. if type_name == 'bms':
  489. if mode == 0:
  490. name_const = ['时间戳','GSM信号','故障等级','故障代码','总电流[A]','总电压[V]', '外电压', '总输出状态', '上锁状态', '充电状态','加热状态',
  491. '单体压差', 'SOC[%]','SOH[%]','单体均衡状态']
  492. elif mode == 1:
  493. name_const = ['时间戳','GSM信号','故障等级', '故障代码','开关状态', '总电流[A]','总电压[V]','充电状态', '单体压差', 'SOC[%]','SOH[%]']
  494. i=0
  495. CellUNum = 0
  496. CellTNum = 0
  497. OtherTNumm = 0
  498. st = time.time()
  499. for line in DBManager._download_json_data(urls):
  500. et = time.time()
  501. try:
  502. if i==0:
  503. data_blocks,CellUNum,CellTNum,OtherTNumm = DBManager._convert_to_dataframe_bms(line, mode)
  504. i+=1
  505. continue
  506. except:
  507. i = 0
  508. try:
  509. data_block,CellUNum,CellTNum,OtherTNumm = DBManager._convert_to_dataframe_bms(line, mode)
  510. except:
  511. continue
  512. try:
  513. data_blocks = np.concatenate((data_blocks,data_block),axis=0)
  514. except Exception as e:
  515. if 'all the input array dimensions for the concatenation axis must match exactly' in str(e) or \
  516. 'all the input array dimensions except for the concatenation axis must match exactly' in str(e):
  517. pass
  518. else:
  519. raise e
  520. # print('\r'+str(i),end=" ")
  521. # print(data_block)
  522. # print(urls)
  523. # print(time.time()-et)
  524. i+=1
  525. name_var = DBManager._get_var_name(CellUNum,CellTNum,OtherTNumm)
  526. name_const.extend(name_var)
  527. columns_name = name_const
  528. if i==0:
  529. data_blocks = []
  530. df_all = pd.DataFrame(columns=columns_name,data=data_blocks)
  531. if not df_all.empty:
  532. df_all.loc[:,'时间戳'] = df_all.loc[:,'时间戳'].apply(lambda x:time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(int(x)/1000)))
  533. return df_all
  534. elif type_name =='gps':
  535. if mode == 0:
  536. df_all = pd.DataFrame(columns=['时间戳','定位类型', '卫星数','纬度','经度','速度[km/h]','海拔','航向'])
  537. elif mode == 1:
  538. df_all = pd.DataFrame(columns=['时间戳','定位类型', '纬度','经度','速度[km/h]','有效位'])
  539. for line in DBManager._download_json_data(urls):
  540. df_add = DBManager._convert_to_dataframe_gps(line, mode)
  541. df_all = df_all.append(df_add,ignore_index=True)
  542. if not df_all.empty:
  543. df_all.loc[:,'时间戳'] = df_all.loc[:,'时间戳'].apply(lambda x:time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(int(x)/1000)))
  544. return df_all
  545. elif type_name =='system':
  546. if mode == 0:
  547. df_all = pd.DataFrame(columns=['时间戳','加热目标温度', '加热超时','租赁开始时间','租赁天数','bms上传周期','gps上传周期'])
  548. elif mode == 1:
  549. df_all = pd.DataFrame()
  550. for line in DBManager._download_json_data(urls):
  551. df_add = DBManager._convert_to_dataframe_system(line, mode)
  552. df_all = df_all.append(df_add,ignore_index=True)
  553. if not df_all.empty:
  554. df_all.loc[:,'时间戳'] = df_all.loc[:,'时间戳'].apply(lambda x:time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(int(x)/1000)))
  555. return df_all
  556. elif type_name =='accum':
  557. if mode == 0:
  558. df_all = pd.DataFrame(columns=['时间戳','SOH未标定时间', '累计充电电量','累计充电能量','累计放电电量','累计放电能量',
  559. '累计高温充电电量', '累计高温充电能量'])
  560. elif mode == 1:
  561. df_all = pd.DataFrame(columns=['时间戳','累计充电电量','累计充电能量','累计放电电量','累计放电能量', '累积里程'])
  562. for line in DBManager._download_json_data(urls):
  563. df_add = DBManager._convert_to_dataframe_accum(line, mode)
  564. df_all = df_all.append(df_add,ignore_index=True)
  565. if not df_all.empty:
  566. df_all.loc[:,'时间戳'] = df_all.loc[:,'时间戳'].apply(lambda x:time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(int(x)/1000)))
  567. return df_all
  568. def get_data(self, url='http://172.16.126.13/store/load?dataType={}&limit=0&sn={}', sn='', start_time='', end_time='',
  569. data_groups=['bms', 'gps']):
  570. '''
  571. 获取指定 sn 和起止日期的bms和gps数据.
  572. 添加了重试机制。
  573. --------------输入参数------------
  574. url:数据获取url, 可采用默认值
  575. sn: str, 电池sn号
  576. start_time: str, 开始时间
  577. end_time: str, 结束时间
  578. data_groups: 选择需要获取的数据组,可填入多个字符串(默认只获取bms和gps数据)
  579. bms: bms数据
  580. gps:gps数据
  581. system:system数据
  582. accum:accum数据
  583. --------------输出参数------------
  584. df_data: {'bms':dataframe, 'gps':dataframe, 'system':dataframe, ;accum':dataframe}
  585. '''
  586. if len(set(data_groups) - (set(data_groups) and set(['bms', 'gps', 'system', 'accum']))) > 0:
  587. raise Exception("data_groups 参数错误")
  588. # mode: 0:正常取数; 1:7255 取数
  589. if sn[0:2] == 'UD' or sn[0:2] == 'MG':
  590. mode = 1
  591. else:
  592. mode = 0
  593. bms_all_data = pd.DataFrame()
  594. gps_all_data = pd.DataFrame()
  595. system_all_data = pd.DataFrame()
  596. accum_all_data = pd.DataFrame()
  597. maxnum = (datetime.datetime.strptime(end_time, "%Y-%m-%d %H:%M:%S") - datetime.datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S")).days +1
  598. print("### start to get data {} from {} to {}".format(sn, start_time, end_time))
  599. # 为避免chunkEncodingError错误,数据每天获取一次,然后将每天的数据合并,得到最终的数据
  600. for j in range(int(maxnum)):
  601. timefrom = datetime.datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S")+ datetime.timedelta(days=j)
  602. timeto = datetime.datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S")+ datetime.timedelta(days=j+1)
  603. #滴滴的数据sub=0
  604. if timefrom.strftime('%Y-%m-%d %H:%M:%S') >= end_time:
  605. break
  606. elif timeto.strftime('%Y-%m-%d %H:%M:%S') > end_time:
  607. timeto = datetime.datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S')
  608. #print('{}_{}_----getting data----'.format(sn, timefrom))
  609. bms_data = pd.DataFrame()
  610. gps_data = pd.DataFrame()
  611. system_data = pd.DataFrame()
  612. accum_data = pd.DataFrame()
  613. while True:
  614. try:
  615. print('\r' + "# get data from {} to {}.........".format(str(timefrom), str(timeto)), end=" ")
  616. for data_group in data_groups:
  617. if data_group == 'bms':
  618. file_url = url.format(12, sn) + "&from="+timefrom.strftime('%Y-%m-%d %H:%M:%S')+"&to="+timeto.strftime('%Y-%m-%d %H:%M:%S')
  619. bms_data = DBManager._get_data(file_url,'bms',mode)
  620. if data_group == 'gps':
  621. file_url = url.format(16, sn) + "&from="+timefrom.strftime('%Y-%m-%d %H:%M:%S')+"&to="+timeto.strftime('%Y-%m-%d %H:%M:%S')
  622. gps_data = DBManager._get_data(file_url,'gps',mode)
  623. if data_group == 'system':
  624. file_url = url.format(13, sn) + "&from="+timefrom.strftime('%Y-%m-%d %H:%M:%S')+"&to="+timeto.strftime('%Y-%m-%d %H:%M:%S')
  625. system_data = DBManager._get_data(file_url,'system',mode)
  626. if data_group == 'accum':
  627. file_url = url.format(23, sn) + "&from="+timefrom.strftime('%Y-%m-%d %H:%M:%S')+"&to="+timeto.strftime('%Y-%m-%d %H:%M:%S')
  628. accum_data = DBManager._get_data(file_url,'accum',mode)
  629. except Exception as e:
  630. if 'Connection broken' in str(e):
  631. continue
  632. else:
  633. raise Exception
  634. else:
  635. bms_all_data = pd.concat([bms_all_data, bms_data], ignore_index=True)
  636. gps_all_data = pd.concat([gps_all_data, gps_data], ignore_index=True)
  637. system_all_data = pd.concat([system_all_data, system_data], ignore_index=True)
  638. accum_all_data = pd.concat([accum_all_data, accum_data], ignore_index=True)
  639. break
  640. bms_all_data = bms_all_data.reset_index(drop=True)
  641. gps_all_data = gps_all_data.reset_index(drop=True)
  642. system_all_data = system_all_data.reset_index(drop=True)
  643. accum_all_data = accum_all_data.reset_index(drop=True)
  644. print('\nall data-getting done, bms_count is {}, gps_count is {}, system_count is {}, accum_count is {} \n'.format(
  645. str(len(bms_all_data)), str(len(gps_all_data)), str(len(system_all_data)), str(len(accum_all_data))))
  646. return {'bms':bms_all_data, 'gps':gps_all_data, 'system':system_all_data, 'accum':accum_all_data}
  647. >>>>>>> 65a87ae16013552e359df047df19f46fc4e6eb08