123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- import datetime
- import pandas as pd
- from xlrd import open_workbook
- from xlutils.copy import copy
- from LIB.BACKEND import DBManager
- dbManager = DBManager.DBManager()
- class SignalMonitor():
- def __init__(self):
- pass
- @staticmethod
- def _set_working_states(df_state):
- for i in range(0, len(df_state)):
- if abs(df_state.loc[i, 'current']) >= 0.45:
- df_state.loc[i, 'PackState'] = 0
- else:
- df_state.loc[i, 'PackState'] = 1
-
-
- return df_state
-
- @staticmethod
- def _set_standby_states(df_state):
- index = 0
- set = 0
- while index < len(df_state)-1:
- index = index + 1
- if set == 0:
- if df_state.loc[index, 'PackState'] == 1 and df_state.loc[index-1, 'PackState'] == 0:
- set = 1
- start_time = df_state.loc[index-1, 'Timestamp']
- timeDelta = datetime.timedelta(minutes=10)
- end_time = start_time + timeDelta
- df_state.loc[index, 'PackState'] = 0
- else:
- if df_state.loc[index, 'Timestamp'] <= end_time:
- df_state.loc[index, 'PackState'] = 0
- if abs(df_state.loc[index, 'current']) >= 0.45:
- start_time = df_state.loc[index-1, 'Timestamp']
- timeDelta = datetime.timedelta(minutes=10)
- end_time = start_time + timeDelta
- else:
- set = 0
-
-
- return df_state
-
- @staticmethod
- def _set_lowpwr_states(df_state):
- index = 0
- set = 0
- while index < len(df_state)-1:
- index = index + 1
- if df_state.loc[index,'PackState'] == 1:
- if set ==0:
- start_time = df_state.loc[index,'Timestamp']
- timeDelta = datetime.timedelta(minutes=300)
- end_time = start_time + timeDelta
- set = 1
- else:
- if df_state.loc[index,'Timestamp'] > end_time:
- df_state.loc[index,'PackState'] = 2
- else:
- set = 0
-
-
- return df_state
-
- @staticmethod
- def _judge_offline_state_between_messages(sn, PackState_new, PackState_old, Timestamp_new, Timestamp_old, lat, long, df_res, mode):
- delta_time = (Timestamp_new - Timestamp_old).total_seconds()
- max_state = max(PackState_new, PackState_old)
- if max_state == 0:
- if mode == 'BMS':
- thres1 = 60
- thres2 = 300
- elif mode == 'GPS':
- thres1 = 120
- thres2 = 600
- elif max_state == 1:
- if mode == 'BMS':
- thres1 = 1200
- thres2 = 2400
- elif mode == 'GPS':
- thres1 = 2400
- thres2 = 4800
- else:
- if mode == 'BMS':
- thres1 = 3600
- thres2 = 7200
- elif mode == 'GPS':
- thres1 = 7200
- thres2 = 14400
-
- if delta_time <= thres1:
- LineState = 0
- elif delta_time <= thres2:
- LineState = 1
- else:
- LineState = 2
-
- if LineState > 0:
- if mode == 'BMS':
- df_res = df_res.append({'sn':sn[0], 'PackState':PackState_new*16+PackState_old, 'LineState':LineState, 'StartTime':Timestamp_old,
- 'EndTime':Timestamp_new, 'OfflineTime':delta_time}, ignore_index=True)
- elif mode == 'GPS':
- df_res = df_res.append({'sn':sn[0], 'PackState':PackState_new*16+PackState_old, 'LineState':LineState, 'StartTime':Timestamp_old,
- 'EndTime':Timestamp_new, 'OfflineTime':delta_time, 'latitude':lat, 'longitude':long}, ignore_index=True)
- return LineState, df_res
- @staticmethod
- def _get_offline_info(sn, df_state, df_last_state, df_res, mode):
- index = 0
- if len(df_last_state) == 0:
- df_state.loc[0,'LineState'] = 0
- while index < len(df_state)-1:
- index = index + 1
- if mode == 'BMS':
- LineState, df_res = SignalMonitor._judge_offline_state_between_messages(sn, df_state.loc[index, 'PackState'], df_state.loc[index-1, 'PackState'],
- df_state.loc[index, 'Timestamp'], df_state.loc[index-1, 'Timestamp'], None, None,
- df_res, mode=mode)
- elif mode == 'GPS':
- LineState, df_res = SignalMonitor._judge_offline_state_between_messages(sn, df_state.loc[index, 'PackState'], df_state.loc[index-1, 'PackState'],
- df_state.loc[index, 'Timestamp'], df_state.loc[index-1, 'Timestamp'], df_state.loc[index-1, 'latitude'], df_state.loc[index-1, 'longitude'],
- df_res, mode=mode)
- df_state.loc[index, 'LineState'] = LineState
- else:
- df_last_info = df_last_state.loc[len(df_last_state) - 1]
- if mode == 'BMS':
- df_state.loc[0,'LineState'], df_res = SignalMonitor._judge_offline_state_between_messages(sn, df_state.loc[0, 'PackState'], df_last_info['PackState'],
- df_state.loc[0, 'Timestamp'], df_last_info['Timestamp'], None, None,
- df_res, mode=mode)
- elif mode == 'GPS':
- df_state.loc[0,'LineState'], df_res = SignalMonitor._judge_offline_state_between_messages(sn, df_state.loc[0, 'PackState'], df_last_info['PackState'],
- df_state.loc[0, 'Timestamp'], df_last_info['Timestamp'], df_state.loc[0, 'latitude'], df_state.loc[0, 'longitude'],
- df_res, mode=mode)
- while index < len(df_state)-1:
- index = index + 1
- if mode == 'BMS':
- LineState, df_res = SignalMonitor._judge_offline_state_between_messages(sn, df_state.loc[index, 'PackState'], df_state.loc[index-1, 'PackState'],
- df_state.loc[index, 'Timestamp'], df_state.loc[index-1, 'Timestamp'], None, None,
- df_res, mode=mode)
- elif mode == 'GPS':
- LineState, df_res = SignalMonitor._judge_offline_state_between_messages(sn, df_state.loc[index, 'PackState'], df_state.loc[index-1, 'PackState'],
- df_state.loc[index, 'Timestamp'], df_state.loc[index-1, 'Timestamp'], df_state.loc[index-1, 'latitude'], df_state.loc[index-1, 'longitude'],
- df_res, mode=mode)
- df_state.loc[index, 'LineState'] = LineState
-
- return df_res
-
- @staticmethod
- def _set_gps_working_states(df_state, df_state_gps):
- for i in range(0, len(df_state_gps)):
- if df_state_gps.loc[i, 'Timestamp'] <= df_state.loc[0, 'Timestamp']:
- df_state_gps.loc[i, 'PackState'] = df_state.loc[0, 'PackState']
- elif df_state_gps.loc[i, 'Timestamp'] >= df_state.loc[len(df_state)-1, 'Timestamp']:
- df_state_gps.loc[i:len(df_state_gps)-1, 'PackState'] = df_state.loc[len(df_state)-1, 'PackState']
- break
- else:
- index0 = max(df_state[df_state['Timestamp'] <= df_state_gps.loc[i, 'Timestamp']].index)
- index1 = min(df_state[df_state['Timestamp'] >= df_state_gps.loc[i, 'Timestamp']].index)
- front = (df_state_gps.loc[i, 'Timestamp'] - df_state.loc[index0, 'Timestamp']).total_seconds()
- back = (df_state.loc[index1, 'Timestamp'] - df_state_gps.loc[i, 'Timestamp']).total_seconds()
- if front > back:
- df_state_gps.loc[i, 'PackState'] = df_state.loc[index1, 'PackState']
- elif front == back:
- df_state_gps.loc[i, 'PackState'] = max(df_state.loc[index1, 'PackState'], df_state.loc[index0, 'PackState'])
- else:
- df_state_gps.loc[i, 'PackState'] = df_state.loc[index0, 'PackState']
- return df_state_gps
-
- @staticmethod
- def _file_write(path, df_res):
- r_xls = open_workbook(path)
- sheet = len(r_xls.sheets())
- row = r_xls.sheets()[sheet-1].nrows
- excel = copy(r_xls)
- table = excel.get_sheet(sheet-1)
-
-
- current_row = row
- num = len(df_res.columns)
- for i in range(0, len(df_res)):
- for j in range(0, num):
- table.write(current_row, j, df_res.iloc[i][j])
- current_row = current_row + 1
- if current_row == 65500:
- table = r_xls.add_sheet('sheet'+ str(sheet))
- sheet = sheet + 1
- current_row = 0
- excel.save(path)
-
- def get_bms_offline_stat(self, sn, st, et, df_res, df_last_state, cal_Period=24):
- df_state = pd.DataFrame(columns=['sn', 'current', 'Timestamp', 'PackState', 'LineState'])
-
- relative_delta_time = datetime.timedelta(hours=6)
- end_time = st + datetime.timedelta(hours=cal_Period)
- relative_time = st - relative_delta_time
- relative_time = relative_time.strftime('%Y-%m-%d %H:%M:%S')
- end_time_str = end_time.strftime('%Y-%m-%d %H:%M:%S')
- df_data = dbManager.get_data(sn=sn[0], start_time=relative_time, end_time=end_time_str, data_groups=['bms'])
- df_bms = df_data['bms']
- df_bms = df_bms.drop_duplicates(['时间戳'])
- df_bms = df_bms.reset_index(drop=True)
- df_bms['时间戳'] = pd.to_datetime(df_bms['时间戳'])
- print('{} BMS data read Well Done!'.format(sn[0]))
- df_state['current'] = df_bms['总电流[A]']
- df_state['Timestamp'] = df_bms['时间戳']
- df_state['sn'] = sn[0]
- if len(df_state[df_state['Timestamp'] >= st]) > 0:
- df_state = SignalMonitor._set_working_states(df_state)
- if len(df_state) > 1:
- df_state = SignalMonitor._set_standby_states(df_state)
- df_state = SignalMonitor._set_lowpwr_states(df_state)
- df_state_spec = df_state[df_state['Timestamp'] >= st]
- df_state_spec = df_state_spec.reset_index(drop=True)
- df_res = SignalMonitor._get_offline_info(sn, df_state_spec, df_last_state, df_res, 'BMS')
- df_last_info = df_state_spec.loc[len(df_state_spec) - 1]
- df_last_state = df_last_state.append(df_last_info)
- df_last_state = df_last_state.reset_index(drop=True)
- return df_res,df_state, df_last_state
-
- def get_gps_offline_stat(self,sn, st, et, df_state, df_res_gps, df_last_state_gps, cal_Period=24):
- df_state_gps = pd.DataFrame(columns=['sn', 'Timestamp', 'PackState', 'LineState', 'latitude', 'longitude'])
-
- end_time = st + datetime.timedelta(hours=cal_Period)
- start_time_str = st.strftime('%Y-%m-%d %H:%M:%S')
- end_time_str = end_time.strftime('%Y-%m-%d %H:%M:%S')
- df_data = dbManager.get_data(sn=sn[0], start_time=start_time_str, end_time=end_time_str, data_groups=['gps'])
- df_gps = df_data['gps']
- df_gps = df_gps.drop_duplicates(['时间戳'])
- df_gps = df_gps.reset_index(drop=True)
- df_gps['时间戳'] = pd.to_datetime(df_gps['时间戳'])
- print('{} GPS data read Well Done!'.format(sn[0]))
- df_state_gps['Timestamp'] = df_gps['时间戳']
- df_state_gps['sn'] = sn[0]
- df_state_gps['latitude'] = df_gps['纬度']
- df_state_gps['longitude'] = df_gps['经度']
- if len(df_state_gps) > 0:
- df_state_gps = SignalMonitor._set_gps_working_states(df_state, df_state_gps)
- df_res_gps = SignalMonitor._get_offline_info(sn, df_state_gps, df_last_state_gps, df_res_gps, 'GPS')
- df_last_info = df_state_gps.loc[len(df_state_gps) - 1]
- df_last_state_gps = df_last_state_gps.append(df_last_info)
- df_last_state_gps = df_last_state_gps.reset_index(drop=True)
- return df_res_gps, df_last_state_gps
|