__author__ = 'Wang Liming'

# 每日指标统计函数
import CONFIGURE.PathSetting as PathSetting
import sys
sys.path.append(PathSetting.backend_path)
sys.path.append(PathSetting.middle_path)
import DBManager
import Tools
import DataPreProcess
import IndexStaByPeriod
import Log
import IndexStaByPeriod
import importlib
import datetime
import os
import pandas as pd
import time
importlib.reload(IndexStaByPeriod)

dbManager = DBManager.DBManager()
dataPrePro = DataPreProcess.DataPreProcess()
indexPerSta = IndexStaByPeriod.IndexStaByPeriod()

# log 文件配置
myLog = Log.Mylog('day_sta')
myLog.set_file_hl(file_name=r'D:\Platform\platform\FRONTEND\day_sta\day_sta.log', log_level='info')
myLog.set_stream_hl(log_level='info')
logger = myLog.get_logger()
logger.info(str(os.getpid()))

# sn文件读取
sn_list = list(pd.read_excel('D:\Platform\platform\苏州电池列表.xlsx')['sn'])
sn_list.extend(list(pd.read_excel('D:\Platform\platform\骑享北京6040电池包统计更新20210407.xlsx')['SN号']))

sn = sn_list[0]

# 字段设置及结果文件生成
columns = ['sn', 'time',  'sumDriveTime', 'sumDriveSoc', 'sumDriveAh', 'sumDriveEnergy']
st = datetime.datetime.strptime('00:00:00', '%H:%M:%S')
for i in range(96):
    et = st + datetime.timedelta(minutes=15)
    columns.append(st.strftime('%H:%M') + '-' + et.strftime('%H:%M'))
    st = et
result_path = r'D:\Platform\platform\FRONTEND\day_sta\result.csv'
df_res = pd.DataFrame(columns=columns)
if not os.path.exists(result_path):
    df_res.to_csv(result_path, index=False)
    
# 时间范围设置
start_time = '{} 00:00:00'.format('2020-01-01')
end_time = '{} 00:00:00'.format('2021-06-01')
sta_days = (datetime.datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S') - datetime.datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S')).days

count= 0
sn_result = {}
for sn in sn_list[:]:
    count += 1
    logger.info('{} start,  {}/{} '.format(sn, str(count), str(len(sn_list))))
    if sn[2:5] == '500':
        cap = 40
    elif sn[2:5] == '504':
        cap = 55
    else:
        logger.info('{} cap error'.format(sn))
        cap = None
        continue
        
    sn_result.update({'sn':sn})
    logger.info('{} :{} to {} start'.format(sn, str(start_time), str(end_time)))
    
    # 获取数据
    df_bms, df_gps = dbManager.get_data(sn=sn, start_time=start_time, end_time=end_time, gps_switch=True, mode=0)
    if df_bms.empty:
        continue
    # 数据预处理
    
    # 时间完全相同的数据仅保留一行
    df_bms_pro, df_gps_pro = dataPrePro.time_filter(df_bms, df_gps)
    
    # bms数据按照电流和状态分段, 然后在状态分段内部,根据时间跳变继续分段(解决段内数据丢失)
    df_bms_pro = dataPrePro.data_split_by_status(df_bms_pro)
    df_bms_pro = dataPrePro.data_split_by_time(df_bms_pro)

    # bms数据将两次充电间的状态合并
    df_bms_pro = dataPrePro.combine_drive_stand(df_bms_pro)
    # bms 数据计算行车和充电开始前后的静置时间
    df_bms_pro = dataPrePro.cal_stand_time(df_bms_pro)
    # gps 数据可靠性判断, 并增加里程和速度至gps数据(根据未合并的数据段判断)
    df_bms_pro, df_gps_pro, res_record= dataPrePro.gps_data_judge(df_bms_pro, df_gps_pro)
    # gps 数据可靠性判断, 并增加里程和速度至gps数据(根据已合并的数据段判断)
    df_bms_pro, df_gps_pro, res_record= dataPrePro.data_gps_judge_after_combine(df_bms_pro, df_gps_pro)
    
    for sta_day in range(sta_days):
        try:
            st_ = datetime.datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S') + datetime.timedelta(days=sta_day)
            et_ =datetime.datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S') + datetime.timedelta(days=sta_day+1)

        # 按天统计指标
            sn_result.update({'time':st_.strftime('%Y-%m-%d')})

            df_bms_period = df_bms_pro[(df_bms_pro['时间戳'] > st_.strftime('%Y-%m-%d %H:%M:%S')) & (df_bms_pro['时间戳'] <= et_.strftime('%Y-%m-%d %H:%M:%S'))]
            #df_gps_period = df_gps_pro[(df_gps_pro['时间戳'] > st_.strftime('%Y-%m-%d %H:%M:%S')) & (df_gps_pro['时间戳'] <= et_.strftime('%Y-%m-%d %H:%M:%S'))]
            sn_result.update({'sumDriveTime':[indexPerSta.drive_time_sta(df_bms_period)]})
            sn_result.update({'sumDriveSoc':[indexPerSta.drive_soc_sta(df_bms_period)]})
            sn_result.update({'sumDriveAh':[indexPerSta.drive_capacity_sta(cap, df_bms_period)]})
            sn_result.update({'sumDriveEnergy':[indexPerSta.drive_energy_sta(cap, df_bms_period)]})

            # 每天间隔15分钟 统计一次
            for i in range(96):
                cur_result = []
                st__ = st_ + datetime.timedelta(minutes=15 * i)
                et__ = st_ + datetime.timedelta(minutes=15 * (i+1))
                df_bms_period = df_bms_pro[(df_bms_pro['时间戳'] > st__.strftime('%Y-%m-%d %H:%M:%S')) & (df_bms_pro['时间戳'] <= et__.strftime('%Y-%m-%d %H:%M:%S'))]
                #df_gps_period = df_gps_pro[(df_gps_pro['时间戳'] > st__.strftime('%Y-%m-%d %H:%M:%S')) & (df_gps_pro['时间戳'] <= et__.strftime('%Y-%m-%d %H:%M:%S'))]
                cur_result.append(indexPerSta.drive_time_sta(df_bms_period))
                cur_result.append(indexPerSta.drive_soc_sta(df_bms_period))
                cur_result.append(indexPerSta.drive_capacity_sta(cap, df_bms_period))
                cur_result.append(indexPerSta.drive_energy_sta(cap, df_bms_period))
                key = st__.strftime('%H:%M') + '-' + et__.strftime('%H:%M')
                sn_result.update({key:[cur_result]})
            df_cur_res = pd.DataFrame(sn_result)
            df_cur_res = df_cur_res[columns]

            # 防止写入结果时,结果文件被打开
            write_flag = False
            while not write_flag:
                try:
                    df_cur_res.to_csv(result_path, mode='a+', index=False,  header=False)
                except PermissionError as e:
                    logger.info('{} error:{}'.format(sn, str(e)))
                    time.sleep(10)
                    continue
                else:
                    write_flag = True 
        except Exception as e:
                logger.info('{} {}_{} error: {}'.format(sn, st_.strftime('%Y-%m-%d %H:%M:%S'), et_.strftime('%Y-%m-%d %H:%M:%S'), str(e)))
                continue
        else:
            continue
    logger.info('{} done,  {}/{} '.format(sn, str(count), str(len(sn_list))))