lmstack преди 3 години
родител
ревизия
a52f3473fc

+ 27 - 0
LIB/FRONTEND/DrivingRange/main.py

@@ -0,0 +1,27 @@
+#coding=utf-8
+import os
+import datetime
+import pandas as pd
+from LIB.BACKEND import DBManager, Log
+from LIB.MIDDLE import SignalMonitor
+from sqlalchemy import create_engine
+from sqlalchemy.orm import sessionmaker
+import time, datetime
+import traceback
+from LIB.MIDDLE.DrivingRange import *
+
+from urllib import parse
+
+dbManager = DBManager.DBManager()
+if __name__ == "__main__":
+    SNdata_6060 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='6060')
+    SNnums_6060=SNdata_6060['SN号']
+    now_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
+    now_time=datetime.datetime.strptime(now_time,'%Y-%m-%d %H:%M:%S')
+    start_time=now_time-datetime.timedelta(days=31)
+    end_time=str(now_time)
+    start_time=str(start_time)
+
+    for sn in SNnums_6060.tolist():
+        res = LFPLeakCurrent.cal_LFPLeakCurrent(sn, end_time, start_time)
+        res.to_csv('BMS_LeakCurrent_'+sn+'.csv',encoding='GB18030')

+ 417 - 0
LIB/MIDDLE/DrivingRange/UpdtFct.py

@@ -0,0 +1,417 @@
+import pandas as pd
+import pymysql
+from sqlalchemy import create_engine
+import datetime
+import pdb
+
+#建立引擎
+engine = create_engine(str(r"mysql+mysqldb://%s:" + '%s' + "@%s/%s") % ('root', 'pengmin', 'localhost', 'qixiangdb'))
+#连接到qx数据库
+conn_qx = pymysql.connect(
+        host='rm-bp10j10qy42bzy0q77o.mysql.rds.aliyuncs.com',
+        user='qx_cas',
+        password='Qx@123456',#Qx@123456
+        database='qx_cas',
+        charset='utf8'
+    )
+#连接到本地数据库,输出物
+conn_local = pymysql.connect(
+        host='localhost',
+        user='root',
+        password='pengmin',
+        database='qixiangdb',
+        charset='utf8'
+    )
+
+#计算下一个soc
+def getNextSoc(start_soc):
+    '''输入当前的soc,寻找目标soc函数'''
+    if start_soc>80:
+        next_soc=80
+    elif start_soc>60:
+        next_soc=60
+    elif start_soc>40:
+        next_soc=40
+    elif start_soc>20:
+        next_soc=20
+    else:
+        next_soc=5#下一次目标soc
+    return next_soc
+#更新全部5个区间段的factor
+def updtSnFct(sn_factor_df,end_soc,delta_range,range_soc):
+    '''输入当前的soc区间段,里程变量量,soc变化量,输出新的df
+    sn_factor_df为dataframe,delta_range单位为km,range_soc单位为km/persoc'''
+    if end_soc==80:
+        updtFctByCol(sn_factor_df,'a0',delta_range,range_soc)
+    elif end_soc==60:
+        updtFctByCol(sn_factor_df,'a1',delta_range,range_soc)
+    elif end_soc==40:
+        updtFctByCol(sn_factor_df,'a2',delta_range,range_soc)
+    elif end_soc==20:
+        updtFctByCol(sn_factor_df,'a3',delta_range,range_soc)
+    elif end_soc<20:
+        updtFctByCol(sn_factor_df,'a4',delta_range,range_soc)
+    return sn_factor_df
+#更新一列的factor
+def updtFctByCol(sn_factor_df,colmun_name,delta_range,range_soc):
+    '''更新制定列的factor,sn_factor_df为dataframe,新的系数更新到第一行。delta_range单位为km,
+    range_soc单位为km/persoc,默认按照100km更新续驶里程权重'''
+    range_soc_old=sn_factor_df.loc[0,colmun_name]#读取第0行的老factor
+    debounce_range=100#更新权重
+    new_factor=range_soc*((delta_range)/debounce_range)+range_soc_old*(1-delta_range/debounce_range)
+    #在第1行,存储新的factor
+    sn_factor_df.loc[1,colmun_name]=new_factor
+    return sn_factor_df
+#更新今日的factor
+def updtTodayFct(factor_input,sn_day_df):
+    '''更新今日的Factor***'''
+    sn_factor_df_last=factor_input
+    start_soc=sn_day_df.loc[0,'soc']#首行soc
+    next_soc=getNextSoc(start_soc)#下一个目标soc
+    start_range=sn_day_df.loc[0,'vehodo']#首行vehodo
+    sn=sn_day_df.loc[0,'name']#sn号
+
+    for index in range(len(sn_day_df)-1):
+    #寻找分割点,
+        index_soc=sn_day_df.loc[index,'soc']#当前行soc
+        next_index_soc=sn_day_df.loc[index+1,'soc']#下一行soc
+
+        if (index_soc>=next_soc)&(next_index_soc<next_soc):
+            #当前行soc>目标soc,下一行低soc<目标soc,说明到达了分割点80-60-40-20
+            delta_soc_tonext=start_soc-next_soc#两个距离点的soc差,单位为%
+            delta_range_tonext=sn_day_df.loc[index,'vehodo']-start_range#两个时间点的距离差,单位为m
+            delta_range_tonext_km=delta_range_tonext/1000#两个时间点的距离差,单位为km
+            range_soc_tonext=(delta_range_tonext_km)/delta_soc_tonext#单位soc可行驶的公里数
+
+            # print(sn+'start_soc: '+str(start_soc),'next_soc: '+str(next_soc),'delta_vehodo; '+str(round(delta_range_tonext_km,3))
+            # +'km'+' range_soc:'+str(round(range_soc_tonext,3)))#调试用语句,看单次factor变化量
+
+            if (delta_range_tonext_km>1)&(delta_range_tonext_km<5*delta_soc_tonext):
+                #里程变化量>1km。且<5倍的soc变化量,大于此值认为不合理。
+                sn_factor_df_last=updtSnFct(sn_factor_df_last,next_soc,delta_range_tonext_km,range_soc_tonext)
+            
+            start_soc=next_index_soc#变更开始soc
+            next_soc=getNextSoc(start_soc)#变更结束soc
+            start_range=sn_day_df.loc[index+1,'vehodo']#变更开始里程    
+
+    return sn_factor_df_last
+#对driveinfo进行预处理
+def snDayDfPreProcess(sn_day_df):
+    '''预处理,判断是否在dirvemode,获取drivemode条件下的累计行驶距离。
+    增加delta_soc列,drive_flg列,vehodo列'''
+    sn_day_df=sn_day_df.reset_index(drop=True)#重置index
+    #增加列,计算delta_soc
+    for index in range(len(sn_day_df)):
+        if index==0:
+            sn_day_df.loc[index,'delta_soc']=0
+        else:
+            sn_day_df.loc[index,'delta_soc']=sn_day_df.loc[index,'soc']-sn_day_df.loc[index-1,'soc']
+    #增加列,判断是否在drive状态
+    drive_flg=False
+    accum_distance=0
+    for index in range(len(sn_day_df)):
+        if index==0:
+            sn_day_df.loc[index,'drive_status']=drive_flg
+            sn_day_df.loc[index,'vehodo']=0
+        else:
+            if (sn_day_df.loc[index,'delta_soc']<-0.1)|\
+                ((sn_day_df.loc[index,'delta_soc']<=0)&(sn_day_df.loc[index,'distance']>500)):#soc处于下降状态,说明在drive
+                drive_flg=True#置true
+            elif sn_day_df.loc[index,'delta_soc']>0.1:#soc处于上升状态,说明不在drive
+                drive_flg=False#置false
+                accum_distance=0#清零
+            sn_day_df.loc[index,'drive_flg']=drive_flg
+            accum_distance+=sn_day_df.loc[index,'distance']#对行驶里程进行累加
+            sn_day_df.loc[index,'vehodo']=accum_distance
+    #筛选所有的drive信息行
+    sn_day_drive_df=sn_day_df.loc[sn_day_df['drive_flg']==True,:]
+    #按时间进行一次筛选,此处丢弃了晚上0点以后的行车数据
+
+    sn_day_drive_df=sn_day_drive_df.reset_index(drop=True)#重置index
+    
+    return sn_day_drive_df 
+
+
+#更新所有sn,连读多天的的factor
+def updtAllSnFct(start_date,end_date):
+    '''计算开始时间到结束时间的,所有sn的factor'''
+    start_date_datetime=datetime.datetime.strptime(start_date,'%Y-%m-%d')#开始时间
+    end_date_datetime=datetime.datetime.strptime(end_date,'%Y-%m-%d')#开始时间
+    delta_day=(end_date_datetime-start_date_datetime).days#间隔天数
+    i=1
+    while i<=delta_day:
+        end_date=(start_date_datetime+datetime.timedelta(days=i)).strftime("%Y-%m-%d")
+        updtAllSnTodayFct(start_date,end_date)#调用函数
+        # print('update all sn factor from '+start_date+" to "+end_date)
+        start_date=end_date
+        i+=1#自加
+#更新所有sn,一天的factor
+def updtAllSnTodayFct(start_date,end_date):
+    ''''更新今天所有sn的factorx信息,start_date和end_date相隔一天。此处还可优化'''
+    conn_local = pymysql.connect(
+        host='localhost',
+        user='root',
+        password='pengmin',
+        database='qixiangdb',
+        charset='utf8'
+        )
+    
+    start_date_str="'"+start_date+"'"
+    end_date_str="'"+end_date+"'"
+    sql_cmd="select * from drive_info where time between "+start_date_str+" and "+end_date_str+" and distance!=0;"
+    range_soc_df = pd.read_sql(sql_cmd, conn_qx)#使用read_sql方法查询qx数据库
+
+    #筛选出所有当日数据之后,筛选当日有更新的sn
+    today_sn_list=range_soc_df['name'].unique().tolist()#[:100]#先一次更新5个
+    #建立空的dataframe,用于承接所有更新的factor信息
+    today_sn_fct_df=pd.DataFrame([],columns=['sn','date','a0','a1','a2','a3','a4'])
+
+    for sn in today_sn_list:
+        #寻找factor_df,里面是否有sn号,如果没有sn对应信息,则新增信息。
+        sn_str="'"+sn+"'"
+        update_today_factor_flg=True
+        sql_cmd3="select sn,date,a0,a1,a2,a3,a4 from tb_sn_factor where date="+start_date_str+" and sn="+sn_str
+        factor_today_df=pd.read_sql(sql_cmd3, conn_local)#使用read_sql方法查询local数据库
+        if len(factor_today_df)>=1:
+            print(sn+' '+start_date_str+' factor exist in table! Factor not update.')
+            update_today_factor_flg=False
+
+        sql_cmd2="select sn,date,a0,a1,a2,a3,a4 from tb_sn_factor where date<"+start_date_str+" and sn="+sn_str
+        #此处可以限定每次查询的数量,例如不高于5行
+        factor_df=pd.read_sql(sql_cmd2, conn_local)#使用read_sql方法查询local数据库
+
+        #按照sn号和日期进行去重,避免运行时重复产生factor数据,保留第一次出现的行。
+        factor_df=factor_df.drop_duplicates(subset=['sn','date'],keep='first')
+
+        if len(factor_df)==0:
+            #如果没有搜索到factor历史数据,则声明一个新的进行初始化
+            start_date_datetime=datetime.datetime.strptime(start_date,'%Y-%m-%d')
+            yesterday=(start_date_datetime+datetime.timedelta(days=-1)).strftime("%Y-%m-%d")
+            #为sn申请一个新的factor,初始值为1
+            factor_df=pd.DataFrame({'sn':sn,'date':yesterday,'a0':[1],'a1':[1],'a2':[1],'a3':[1],'a4':[1]})
+        sn_factor_df=factor_df.loc[factor_df['sn']==sn,:]#筛选sn对应的factor
+        sn_factor_df=sn_factor_df.sort_values(by='date',ascending='True')#按照日期排序
+
+        sn_factor_df_last=sn_factor_df.tail(1).copy()#寻找最后一行,代表最近日期
+        sn_factor_df_last=sn_factor_df_last.append(sn_factor_df_last)#新增加一行,用于存储新的factor
+        sn_factor_df_last=sn_factor_df_last.reset_index(drop=True)#重置index
+        sn_factor_df_last.loc[1,'date']=start_date#更改后一行的date为当前日期
+        #筛选对应车辆的信息
+        condition_sn=(range_soc_df['name']==sn)
+        sn_day_df=range_soc_df.loc[condition_sn,:].copy()
+        sn_day_df=sn_day_df.reset_index(drop=True)
+        #使用updtTodayFct函数更新今天的factor
+        if len(sn_day_df)>=2:
+            #使用process函数,进行预处理
+            sn_day_df=snDayDfPreProcess(sn_day_df)#预处理函数
+            # 临时措施,删除每天晚上0点以后的数据,5点以前的数据,防止对驾驶cycle判断产生影响。
+            day_start_time=datetime.datetime.strptime(start_date,'%Y-%m-%d')
+            day_morning_time=day_start_time+datetime.timedelta(hours=5)
+            morning_time_str=day_morning_time.strftime('%Y-%m-%d %H:%M:%S')
+            sn_day_df=sn_day_df.loc[sn_day_df['time']>morning_time_str,:]#去除掉了每天晚上0点以后的数据,短期措施
+            sn_day_df=sn_day_df.reset_index(drop=True)#重置index
+
+            if len(sn_day_df)>=2:
+                sn_factor_df_new=updtTodayFct(sn_factor_df_last,sn_day_df)#
+                if (len(sn_factor_df_new)>=2)&(update_today_factor_flg):#如果factor
+                    today_sn_fct_df=today_sn_fct_df.append(sn_factor_df_new.loc[1,:])#筛选第一行,进行拼接,最后写入到数据库中
+    
+    #将today_sn_fct_df写入到数据库中,今天所有factor更新的系数,一次写入。
+    if len(today_sn_fct_df)>=1:
+        today_sn_fct_df.to_sql('tb_sn_factor',con=engine,chunksize=10000,if_exists='append',index=False)
+
+#更新一个sn,连续多天的factor
+def updtOneSnFct(sn,start_date,end_date):
+    '''计算开始时间到结束时间的,一个sn的所有factor。
+    重复多次调用,updtOneSnTodayFct。
+    '''
+    start_date_datetime=datetime.datetime.strptime(start_date,'%Y-%m-%d')#开始时间
+    end_date_datetime=datetime.datetime.strptime(end_date,'%Y-%m-%d')#开始时间
+    delta_day=(end_date_datetime-start_date_datetime).days#间隔天数
+    i=1
+    while i<=delta_day:
+        end_date=(start_date_datetime+datetime.timedelta(days=i)).strftime("%Y-%m-%d")
+        # print('update one '+sn+'factor from '+start_date+" to "+end_date)
+        updtOneSnTodayFct(sn,start_date,end_date)#调用函数,更新当日的factor。
+        start_date=end_date
+        i+=1#自加
+#更新一个sn,一天的factor
+def updtOneSnTodayFct(sn,start_date,end_date):
+    '''更新一个sn,一天的factor。'''
+    #重新建立连接,更新数据库
+    conn_local = pymysql.connect(
+        host='localhost',
+        user='root',
+        password='pengmin',
+        database='qixiangdb',
+        charset='utf8'
+        )
+
+    start_date_str="'"+start_date+"'"
+    end_date_str="'"+end_date+"'"
+    sn_str="'"+sn+"'"
+    sql_cmd="select * from drive_info where time between "+start_date_str+" and "+end_date_str+\
+    " and distance!=0 and name="+sn_str
+    range_soc_df = pd.read_sql(sql_cmd, conn_qx)#使用read_sql方法查询qx数据库
+
+    if len(range_soc_df)>0:
+        #筛选出所有当日数据之后,筛选当日有更新的sn
+        today_sn_list=range_soc_df['name'].unique().tolist()
+        #建立空的dataframe,用于承接所有更新的factor信息
+        today_sn_fct_df=pd.DataFrame([],columns=['sn','date','a0','a1','a2','a3','a4'])
+
+        for sn in today_sn_list:
+            #寻找factor_df,里面是否有sn号,如果没有sn对应信息,则新增信息。
+            sn_str="'"+sn+"'"
+
+            update_today_factor_flg=True
+            sql_cmd3="select sn,date,a0,a1,a2,a3,a4 from tb_sn_factor where date="+start_date_str+" and sn="+sn_str
+            factor_today_df=pd.read_sql(sql_cmd3, conn_local)#使用read_sql方法查询local数据库
+            if len(factor_today_df)>=1:
+                print(sn+' '+start_date_str+' factor exist in table! Factor not update.')
+                update_today_factor_flg=False
+
+            sql_cmd2="select sn,date,a0,a1,a2,a3,a4 from tb_sn_factor where date<="+start_date_str+" and sn="+sn_str
+            factor_df=pd.read_sql(sql_cmd2, conn_local)#使用read_sql方法查询local数据库
+            #按照sn号和日期进行去重,避免运行时重复产生factor数据,保留第一次出现的行。
+            factor_df=factor_df.drop_duplicates(subset=['sn','date'],keep='first')
+            # pdb.set_trace()
+            if len(factor_df)==0:
+                #如果没有搜索到factor历史数据,则声明一个新的进行初始化
+                start_date_datetime=datetime.datetime.strptime(start_date,'%Y-%m-%d')
+                yesterday=(start_date_datetime+datetime.timedelta(days=-1)).strftime("%Y-%m-%d")
+                factor_df=pd.DataFrame({'sn':sn,'date':yesterday,'a0':[1],'a1':[1],'a2':[1],'a3':[1],'a4':[1]})
+                today_sn_fct_df=today_sn_fct_df.append(factor_df.loc[0,:])#将初始化的行记录到数据库
+
+            sn_factor_df=factor_df.loc[factor_df['sn']==sn,:]#筛选sn对应的factor
+            sn_factor_df=sn_factor_df.sort_values(by='date',ascending='True')#按照日期排序
+
+            sn_factor_df_last=sn_factor_df.tail(1).copy()#寻找最后一行,代表最近日期
+            sn_factor_df_last=sn_factor_df_last.append(sn_factor_df_last)#新增加一行,用于存储新的factor
+            sn_factor_df_last=sn_factor_df_last.reset_index(drop=True)#重置index
+            sn_factor_df_last.loc[1,'date']=start_date#更改后一行的date为当前日期
+            #筛选对应车辆的信息
+            condition_sn=(range_soc_df['name']==sn)
+            sn_day_df=range_soc_df.loc[condition_sn,:].copy()
+            sn_day_df=sn_day_df.reset_index(drop=True)
+            #使用updtTodayFct函数更新今天的factor
+            if len(sn_day_df)>=2:
+                #使用process函数,进行预处理
+                sn_day_df=snDayDfPreProcess(sn_day_df)#!!!!!!!!!!!增加
+                # 临时措施,删除每天晚上0点以后的数据,5点以前的数据,防止对驾驶cycle判断产生影响。
+                day_start_time=datetime.datetime.strptime(start_date,'%Y-%m-%d')
+                day_morning_time=day_start_time+datetime.timedelta(hours=5)
+                morning_time_str=day_morning_time.strftime('%Y-%m-%d %H:%M:%S')
+                sn_day_df=sn_day_df.loc[sn_day_df['time']>morning_time_str,:]#去除掉了每天晚上0点以后的数据,短期措施
+                sn_day_df=sn_day_df.reset_index(drop=True)#重置index
+
+                if len(sn_day_df)>=2:
+                    sn_factor_df_new=updtTodayFct(sn_factor_df_last,sn_day_df)#更新fator的主函数
+
+                    if (len(sn_factor_df_new)>=2)&(update_today_factor_flg):#如果今日factor没有更新
+                        today_sn_fct_df=today_sn_fct_df.append(sn_factor_df_new.loc[1,:])#筛选第一行,进行拼接,最后写入到数据库中
+        
+        # #将today_sn_fct_df写入到数据库中
+        if len(today_sn_fct_df)>=1:
+            today_sn_fct_df.to_sql('tb_sn_factor',con=engine,chunksize=10000,if_exists='append',index=False)
+            # print(sn+' factor will be update in table tb_sn_factor!')
+        return sn_factor_df_new
+
+
+#更新最新的factor,一天调用一次。
+def updtNewestFctTb():
+
+    '''更新tb_sn_factor_newest,只保留最新日期的factor。
+    从tb_sn_factor中,筛选最新的日期。
+    函数每天运行一次,从tb_sn_factor中筛选最新日期的factor。'''
+
+    current_time=datetime.datetime.now()#当前时间
+    current_time_str=current_time.strftime('%Y-%m-%d %H:%M:%S')#时间格式化为字符串,年-月-日 时-分-秒
+    current_time_str="'"+current_time_str+"'"
+
+    sql_cmd_4="select sn,date,a0,a1,a2,a3,a4 from tb_sn_factor where date<"+current_time_str
+    factor_all_df = pd.read_sql(sql_cmd_4, conn_local)#使用read_sql方法查询qx数据库
+    #筛选今天之前的所有factor,只保留最近的一天。
+    sn_list=factor_all_df['sn'].unique().tolist()#筛选sn序列
+    newest_sn_fct_df=pd.DataFrame([],columns=['sn','date','a0','a1','a2','a3','a4'])#声明空df
+
+    for sn in sn_list:
+        condition_sn=(factor_all_df['sn']==sn)
+        factor_pick_df=factor_all_df.loc[condition_sn,:]#按照sn进行筛选
+        factor_pick_df=factor_pick_df.sort_values(by='date')#按照日期排序
+        factor_last_df=factor_pick_df.tail(1)#选择最后日期
+        newest_sn_fct_df=newest_sn_fct_df.append(factor_last_df)#拼接到空df中
+
+    #按照日期排序,只保留最近的一天,输出factor_unique_df,方法为replace。
+    #本函数,每天需要运行一次,用于更新factor。
+    newest_sn_fct_df.to_sql('tb_sn_factor_newest',con=engine,chunksize=10000,\
+        if_exists='replace',index=False)
+#使用factor和soc推荐剩余续驶里程
+def calDistFromFct(input_df):
+    '''根据sn-time-soc-a0-a1-a2-a3-a4,使用factor正向计算计算VehElecRng。'''
+    row_df=input_df.copy()
+    soc=row_df['soc']#获取soc
+    factor=[]
+    factor.append(row_df['a4'])#0~20之间的factor
+    factor.append(row_df['a3'])#20~40之间的factor
+    factor.append(row_df['a2'])#40~60之间的factor
+    factor.append(row_df['a1'])#60~80之间的factor
+    factor.append(row_df['a0'])#80~100之间的factor
+
+    gap=20
+    yushu=soc%gap#余数部分
+    zhengshu=soc//gap#整数部分
+    i=0
+    range=0
+    while i<zhengshu:
+        dur_factor=factor[i]#当前权重
+        range+=dur_factor*gap#分段累加里程
+        i=i+1
+    if yushu>0.01:#避免soc=100时报错
+        range=range+yushu*factor[zhengshu]#最后把余项对应的里程加上
+    row_df['vehelecrng']=range#给VehElecRng列赋值
+    return row_df
+#更新当前时间对应的里程,每5min调用一次
+def updtVehElecRng(input_time='2021-07-29 12:01:00'):
+    '''更新续驶里程,到tb_sn_factor_soc_range。
+    部署时设置每5min更新一次。
+    '''
+    #设置一个时间作为结束时间
+    # current_time=datetime.datetime.now()
+    current_time_raw=input_time#当前时间
+    current_time=datetime.datetime.strptime(current_time_raw,'%Y-%m-%d %H:%M:%S')#字符串转时间
+
+    #结束时间往前4min,59s,作为起始时间
+    before6min_time_str=(current_time+datetime.timedelta(minutes=-4,seconds=-59)).strftime('%Y-%m-%d %H:%M:%S')#6min前
+    before6min_time_str="'"+before6min_time_str+"'"
+    current_time_str=current_time.strftime('%Y-%m-%d %H:%M:%S')#时间格式化为字符串
+    current_time_str="'"+current_time_str+"'"
+
+    #从drive_info里面读取,该时间段内的name,time,soc三列
+    sql_cmd="select name,time,soc from drive_info where time between "+before6min_time_str+" and "+current_time_str
+    print(sql_cmd)
+    range_soc_df = pd.read_sql(sql_cmd, conn_qx)#使用read_sql方法查询qx数据库
+    range_soc_df.rename(columns={'name':'sn'},inplace=True)#将name列重命名为sn列
+
+    #任务2,从tb_sn_factor_newest里面读取最新的factor,获取距离今天最近的一个factor list
+    sql_cmd_1="select sn,a0,a1,a2,a3,a4 from tb_sn_factor_newest"
+    print(sql_cmd_1)
+    sn_factor_newest_df_raw = pd.read_sql(sql_cmd_1, conn_local)#使用read_sql方法查询qx数据库
+
+    #任务3,将range_soc_df和sn_factor_newest_df_raw,双表合并成为一个新表格。
+    sn_soc_factor_df=pd.merge(range_soc_df,sn_factor_newest_df_raw,how='left',on='sn')
+    sn_soc_factor_df.fillna(1,inplace=True)#如果range_soc_df中有sn号,但sn_factor_newest_df_raw中没有。用1填充。
+    # sn_soc_factor_df.head()
+    #填充完成后,sn-time-soc-a0-a1-a2-a3-a4都已经齐全。
+
+    #任务4,调用函数,将VehElecRng计算出来
+    sn_soc_factor_range_df=pd.DataFrame([],columns=['sn','time','soc','a0','a1','a2','a3','a4','vehelecrng'])
+    for index in sn_soc_factor_df.index.tolist():
+        input_df=sn_soc_factor_df.loc[index,:]#挑选
+        sn_soc_factor_range_row=calDistFromFct(input_df)#计算VehElecRng
+        sn_soc_factor_range_df=sn_soc_factor_range_df.append(sn_soc_factor_range_row)#拼接
+
+    ##任务5,将sn_soc_factor_range_df写入到tb_sn_factor_soc_range中,使用替换关系。
+    sn_soc_factor_range_df.to_sql('tb_sn_factor_soc_range',con=engine,chunksize=10000,\
+        if_exists='replace',index=False)    
+

+ 12 - 0
LIB/MIDDLE/DrivingRange/UpdtFctTable.py

@@ -0,0 +1,12 @@
+import pandas as pd
+import pymysql
+from sqlalchemy import create_engine
+import datetime
+from UpdtFct import *
+
+#调度周期:每天运行一次。
+
+#更新所有sn,连读多日的factor,如果start_date和end_date相隔一天,代表更新start_date的factor。
+start_date="2021-07-23"
+end_date="2021-07-28"
+updtAllSnFct(start_date,end_date)

+ 11 - 0
LIB/MIDDLE/DrivingRange/UpdtFctTableNewest.py

@@ -0,0 +1,11 @@
+import pandas as pd
+import pymysql
+from sqlalchemy import create_engine
+import datetime
+from UpdtFct import *
+
+#调度周期:在UpdtFctTable运行结束之后,运行一次,不需要输入参数。
+
+#更新factor到最新状态,只保留最新的。
+
+updtNewestFctTb()

+ 16 - 0
LIB/MIDDLE/DrivingRange/UpdtVehElecRng.py

@@ -0,0 +1,16 @@
+import pandas as pd
+import pymysql
+from sqlalchemy import create_engine
+import datetime
+from UpdtFct import *
+
+#调度周期:程序每5分钟运行一次
+
+#更新剩余里程,每5min一次,几秒钟运行结束。
+test_time=datetime.datetime.now()#当前系统时间
+input_time=datetime.datetime.strftime(test_time,'%Y-%m-%d %H:%M:%S')
+
+# input_time='2021-07-29 11:59:00'#手动设定一个时间
+
+#函数每5min调度一次,input_time为当前时间,更新tb_sn_factor_soc_range表格
+updtVehElecRng(input_time)

BIN
LIB/MIDDLE/DrivingRange/计算续驶里程程序介绍.docx