shangguanlie23 2 éve
szülő
commit
fc9913ec6c

+ 16 - 0
USER/LZX/01算法开发/.vscode/launch.json

@@ -0,0 +1,16 @@
+{
+    // 使用 IntelliSense 了解相关属性。 
+    // 悬停以查看现有属性的描述。
+    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Python: 当前文件",
+            "type": "python",
+            "request": "launch",
+            "program": "${file}",
+            "console": "integratedTerminal",
+            "justMyCode": true
+        }
+    ]
+}

+ 90 - 0
USER/LZX/01算法开发/08合众算法开发/01车辆行为统计/dschrgr_statics_packcrnt.py

@@ -0,0 +1,90 @@
+from ctypes import Structure
+from re import M
+import pandas as pd
+import numpy as np
+import datetime
+import time, datetime
+import matplotlib.pyplot as plt
+from pylab import*
+from scipy.signal import savgol_filter
+from scipy import interpolate
+import os
+from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import BatParam
+class cell_statistic:
+    def __init__(self,sn,celltype,df_bms):  #参数初始化
+        self.sn=sn
+        self.celltype=celltype
+        self.param=BatParam.BatParam(celltype)#鹏飞param中为BatParam,学琦为BatteryInfo
+        self.df_bms=pd.DataFrame(df_bms)
+        self.packcrnt=df_bms['总电流[A]']*self.param.PackCrntDec
+        self.packvolt=df_bms['总电压[V]']
+        self.bms_soc=df_bms['SOC[%]']
+        self.bmstime= pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
+        self.LookTab_OCV = self.param.LookTab_OCV
+        self.LookTab_SOC = self.param.LookTab_SOC
+        self.packcrnt_flg = self.param.PackCrntDec#判断充放电电流方向,一般放电为正,充电为负
+        self.cellvolt_list=['单体电压'+str(x) for x in range(1,self.param.CellVoltNums+1)]
+        self.celltemp_name=['单体温度'+str(x) for x in range(1,self.param.CellTempNums+1)]
+        self.bmssta = df_bms['充电状态']
+    #定义加权滤波函数..................................................................................................
+    def moving_average(interval, windowsize):
+        window = np.ones(int(windowsize)) / float(windowsize)
+        re = np.convolve(interval, window, 'same')
+        return re
+#.............................................充电行为统计............................................................................
+    def chrgr_sta(self):
+        start_time = time.time()
+        df_chrgr_soc = pd.DataFrame(columns = ['sn', 'time_st', 'time_end', 'soc_st', 'soc_sp', 'delta_soc', 'temp_st', 'temp_sp','meancrnt'])
+        data_temp = self.df_bms
+        data_temp = data_temp.dropna(axis = 0, how = 'any', subset = ['总电流[A]', 'SOC[%]'])#删除电流与SOC中的nan值
+        data_temp.reset_index(inplace = True, drop = True)
+        data = data_temp.copy()
+        data['总电流[A]'] = self.param.PackCrntDec*data_temp['总电流[A]']
+        #----------------------------------------区分充放电数据----------------------------------------------------------------------
+        df_soc = data['SOC[%]']
+        df_soc[df_soc > 98] = 100#满SOC
+        #-------------------------------------------------------利用电流连续为负及SOC升高判断充电---------------------------------------------------------
+        chrgr_crnt = data.loc[data['总电流[A]'] > 0]#电流为放电电流的数据
+        if not chrgr_crnt.empty:
+            chrgr_crnt_data = chrgr_crnt.reset_index(drop=True)
+            temp_chrgr_time = chrgr_crnt_data['时间戳']
+            chrgr_time = pd.to_datetime(temp_chrgr_time)
+            delta_time = (np.diff(chrgr_time)/pd.Timedelta(1, 'min'))#计算时间差的分钟数
+            pos = np.where(delta_time > 10)#充电数据分段,大于10min时,认为是两个静置过程
+            splice_num = []
+            if len(pos[0]) >= 1:
+                pos_ful_tem = np.insert(pos, 0, 0)
+                pos_len = len(pos_ful_tem)
+                data_len = len(chrgr_time)
+                pos_ful = np.insert(pos_ful_tem, pos_len, data_len-1)
+                for item in range(0,len(pos_ful)-1):
+                    splice_num.extend(item*np.ones(pos_ful[item +1]-pos_ful[item]))
+                splice_num = np.insert(splice_num, 0, 0)
+            else:
+                splice_num = np.zeros(len(temp_chrgr_time))
+                pos_ful = np.array([0])
+            chrgr_crnt_data['chrgr_rest'] = splice_num
+            if len(splice_num) > 0:
+                chrgr_splice_num = np.unique(chrgr_crnt_data['chrgr_rest'])#判断有几段放电数据
+                if len(chrgr_splice_num) > 0:
+                    for item_chrgr in chrgr_splice_num:
+                        celltemp_name = self.celltemp_name#电芯温度数量
+                        df_chrgr_splice_data = chrgr_crnt_data.loc[chrgr_crnt_data['chrgr_rest'] == item_chrgr]
+                        df_time_temp = pd.to_datetime(df_chrgr_splice_data['时间戳'])
+                        df_soc_temp = df_chrgr_splice_data['SOC[%]']
+                        delta_soc = round((df_soc_temp.iloc[-1] - df_soc_temp.iloc[0]), 3)
+                        delta_time = (df_time_temp.iloc[-1] - df_time_temp.iloc[0])/pd.Timedelta(1, 'hours')
+                        if delta_soc < -5:
+                            chrg_rate = round(delta_soc/(100*delta_time), 2)
+                            df_chrgr_soc_temp = pd.DataFrame({"sn":[self.sn], "time_st":[df_time_temp.iloc[0]], "time_end":[df_time_temp.iloc[-1]], 
+                                                    "soc_st":[df_soc_temp.iloc[0]], "soc_sp":[df_soc_temp.iloc[-1]], "delta_soc":[delta_soc],
+                                                    "temp_st":[str(list(df_chrgr_splice_data[celltemp_name].iloc[0]))], 
+                                                    "temp_sp":[str(list(df_chrgr_splice_data[celltemp_name].iloc[-1]))],
+                                                    "meancrnt":[chrg_rate]})
+                            df_chrgr_soc = df_chrgr_soc.append(df_chrgr_soc_temp)
+                            df_chrgr_soc.reset_index(drop = True, inplace = True)
+                        # df_chrgr_soc.sort_values(by = ['splicestrt_time'], axis = 0, ascending=True,inplace=True)#对故障信息按照时间进行排序
+        if not df_chrgr_soc.empty:
+            return df_chrgr_soc
+        else:
+            return pd.DataFrame()

+ 109 - 0
USER/LZX/01算法开发/08合众算法开发/01车辆行为统计/main.py

@@ -0,0 +1,109 @@
+import datetime
+import pandas as pd
+from LIB.BACKEND import DBManager, Log
+import time, datetime
+from apscheduler.schedulers.blocking import BlockingScheduler
+import log
+from pandas.core.frame import DataFrame
+import rest_stscs_v1
+
+#...................................电池包电芯安全诊断函数......................................................................................................................
+def rest_statics():
+    global SNnums
+    global df_rest_static
+    start=time.time()
+    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=3)
+    end_time=str(now_time)
+    start_time=str(start_time)
+    k = 0
+    for sn in SNnums[k:]:
+        if 'PK500' in sn:
+            celltype=1 #6040三元电芯
+        elif 'PK502' in sn:
+            celltype=2 #4840三元电芯
+        elif 'K504B' in sn:
+            celltype=99    #60ah林磷酸铁锂电芯
+        elif 'MGMLXN750' in sn:
+            celltype=3 #力信50ah三元电芯
+        elif 'MGMCLN750' in sn: 
+            celltype=4 #CATL 50ah三元电芯
+        elif 'UD' in sn:
+            celltype=4 #CATL 50ah三元电芯
+        elif 'TJMCL' in sn: 
+            celltype=100 #金茂电芯
+        else:
+            print('SN:{},未找到对应电池类型!!!'.format(sn))
+            continue
+            # sys.exit()
+        print('计算的第' + str(k) + '个:' + sn)
+        k = k + 1
+        #读取原始数据库数据........................................................................................................................................................
+        start_time = '2022-03-01 00:00:00'
+        end_time = '2022-04-01 00:00:00'
+        dbManager = DBManager.DBManager()
+        df_data = dbManager.get_data(sn=sn, start_time=start_time, end_time=end_time, data_groups=['bms'])
+        df_bms = df_data['bms']
+        df_Diag_rest_add = pd.DataFrame(columns = ['sn', 'time_st', 'time_end', 'delta_time', 'soc_st', 'soc_sp', 'delta_soc', 'temp_st', 'temp_sp', 'meancrnt', 'sts_flg'])
+        #充电统计................................................................................................................................................................
+        if not df_bms.empty:
+            rest_statics_temp = rest_stscs_v1.cell_statistic(sn,celltype,df_bms)#析锂检测
+            df_Diag_rest_add = rest_statics_temp.rest_sta()        
+        if not df_Diag_rest_add.empty:
+            df_rest_static = df_rest_static.append(df_Diag_rest_add)
+            df_rest_static = df_rest_static.drop_duplicates(subset = ['sn','time_st'], keep = 'first', inplace = False)
+            # df_rest_static.sort_values(by = ['sn'], axis = 0, ascending=True,inplace=True)#对故障信息按照时间进行排序
+            df_rest_static.to_csv(r'D:\Develop\User\Liuzhongxiao\data_analyze_platform\USER\LZX\01算法开发\08合众算法开发\01车辆行为统计\静置统计.csv',index=False,encoding='GB18030')
+        end=time.time()
+        print(end-start)
+
+#...............................................主函数.......................................................................................................................
+if __name__ == "__main__":
+    global SNnums
+    global df_rest_static
+    
+    excelpath=r'D:\Develop\User\Liuzhongxiao\data_analyze_platform\USER\LZX\01算法开发\00项目sn号\sn-20210903.xlsx'
+    SNdata_6060 = pd.read_excel(excelpath, sheet_name='科易6060')
+    SNdata_6040 = pd.read_excel(excelpath, sheet_name='科易6040')
+    SNdata_4840 = pd.read_excel(excelpath, sheet_name='科易4840')
+    SNdata_L7255 = pd.read_excel(excelpath, sheet_name='格林美-力信7255')
+    SNdata_C7255 = pd.read_excel(excelpath, sheet_name='格林美-CATL7255')
+    SNdata_U7255 = pd.read_excel(excelpath, sheet_name='优旦7255')
+    SNnums_6060=SNdata_6060['SN号'].tolist()
+    SNnums_6040=SNdata_6040['SN号'].tolist()
+    SNnums_4840=SNdata_4840['SN号'].tolist()
+    SNnums_L7255=SNdata_L7255['SN号'].tolist()
+    SNnums_C7255=SNdata_C7255['SN号'].tolist()
+    SNnums_U7255=SNdata_U7255['SN号'].tolist()
+    # SNums_file = pd.read_csv(r'D:\Work\Code_write\data_analyze_platform\USER\lzx\01算法开发\02析锂检测\02析锂分析\各项目析锂情况_211130\增加波峰高度与峰谷比计算结果\SNnums_C7255析锂情况析锂排序.csv',encoding='GB18030')
+    # SNums_sn = SNums_file['sn']
+    # liplated_high = SNums_sn.iloc[7:10]
+    # liplated_low = SNums_sn.iloc[-11:-1]
+    # cal_sn = liplated_high.append(liplated_low)
+    m = 100
+    SNnums = SNnums_U7255 + SNnums_C7255[0:m] + SNnums_L7255 + SNnums_4840[0:m] + SNnums_6040[0:m] + SNnums_6060[0:m]
+    # SNnums = SNnums_U7255
+    # SNnums=['TJMCL120502305010','TJMCL120502305012','TJMCL120502305048','TJMCL120502305044','TJMCL120502305026','TJMCL120502305022','TJMCL120502305032','TJMCL120502305038']
+    # SNnums = list(cal_sn)#['MGMCLN750N215N049']#['MGMCLN750N215N049'] #SNnums_6040 #SNnums_C7255 #SNnums_6040['MGMCLN750N215N049'] 
+    # SNnums = pd.read_csv(r'D:\Work\Code_write\data_analyze_platform\USER\lzx\01算法开发\02析锂检测\liplated\疑似析锂电池sn.csv',encoding='GB18030')
+    # SNnums=['TJMCL120502305010','TJMCL120502305012','TJMCL120502305048','TJMCL120502305044','TJMCL120502305026','TJMCL120502305022','TJMCL120502305032','TJMCL120502305038']
+    mylog=log.Mylog('log_diag.txt','error')#'TJMCL120502305010','TJMCL120502305012',
+    mylog.logcfg()
+    #............................模块运行前,先读取数据库中所有结束时间为0的数据,需要从数据库中读取................
+    df_rest_static = pd.read_csv(r'D:\Develop\User\Liuzhongxiao\data_analyze_platform\USER\LZX\01算法开发\08合众算法开发\01车辆行为统计\静置统计.csv',encoding='GB18030')
+
+    print('----------------输入--------')
+    print('-------计算中-----------')
+    rest_statics()
+    #定时任务.......................................................................................................................................................................
+    # scheduler = BlockingScheduler()
+    # scheduler.add_job(rest_statics, 'interval', seconds=10, id='diag_job')
+
+    # try:  
+    #     scheduler.start()
+    # except Exception as e:
+    #     scheduler.shutdown()
+    #     print(repr(e))
+    #     mylog.logopt(e)
+

+ 162 - 0
USER/LZX/01算法开发/08合众算法开发/01车辆行为统计/rest_stscs_v1.py

@@ -0,0 +1,162 @@
+from ctypes import Structure
+from re import M
+import pandas as pd
+import numpy as np
+import datetime
+import time, datetime
+import matplotlib.pyplot as plt
+from pylab import*
+from scipy.signal import savgol_filter
+from scipy import interpolate
+import os
+from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import BatParam
+class cell_statistic:
+    def __init__(self,sn,celltype,df_bms):  #参数初始化
+        self.sn=sn
+        self.celltype=celltype
+        self.param=BatParam.BatParam(celltype)#鹏飞param中为BatParam,学琦为BatteryInfo
+        self.df_bms=pd.DataFrame(df_bms)
+        self.packcrnt=df_bms['总电流[A]']*self.param.PackCrntDec
+        self.packvolt=df_bms['总电压[V]']
+        self.bms_soc=df_bms['SOC[%]']
+        self.bmstime= pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
+        self.LookTab_OCV = self.param.LookTab_OCV
+        self.LookTab_SOC = self.param.LookTab_SOC
+        self.packcrnt_flg = self.param.PackCrntDec#判断充放电电流方向,一般放电为正,充电为负
+        self.cellvolt_list=['单体电压'+str(x) for x in range(1,self.param.CellVoltNums+1)]
+        self.celltemp_name=['单体温度'+str(x) for x in range(1,self.param.CellTempNums+1)]
+        self.bmssta = df_bms['充电状态']
+    #定义加权滤波函数..................................................................................................
+    def moving_average(interval, windowsize):
+        window = np.ones(int(windowsize)) / float(windowsize)
+        re = np.convolve(interval, window, 'same')
+        return re
+    
+#.............................................静置行为统计............................................................................
+    def rest_sta(self):
+        def clean_dead_value(series, num_dead_thresh):
+            slide_list = [series.index[0]]
+            slide_list_all = []
+            for i in range(series.index[0],series.index[-1]):
+                j = i + 1
+                diff = series[j] - series[i]
+                if diff == 0:
+                    slide_list.append(j)
+                else:
+                    slide_list.clear()
+                    slide_list.append(j)
+                # print("slide_list:",slide_list)
+                if len(slide_list) >= num_dead_thresh:
+                    target_list = slide_list.copy()
+                    slide_list_all.append(target_list)
+            # print("slide_list_all:",slide_list_all)
+            index= []  # 将找到的满足条件的index合并
+            # 因为可能有前后包含的情况,只保留最长序列
+            for i in range(len(slide_list_all) - 1):
+                if set(slide_list_all[i]) < set(slide_list_all[i + 1]):
+                    index.append(i)
+            m = {i: element for i, element in enumerate(slide_list_all)}
+            [m.pop(i) for i in index]
+            # 将所有需要删除的行数合并
+            # indexs_to_delete = []
+            # for i in range(len(slide_list_all)):
+            #     indexs_to_delete = list(set(indexs_to_delete).union(slide_list_all[i]))
+            return list(m.values())
+        start_time = time.time()
+        df_sts_chrg_rt = pd.DataFrame(columns = ['sn', 'time_st', 'time_end', 'delta_time','soc_st', 'soc_sp', 'delta_soc', 'temp_st', 'temp_sp', 'meancrnt', 'sts_flg'])
+        df_sts_dschrg = pd.DataFrame(columns = ['sn', 'time_st', 'time_end','delta_time', 'soc_st', 'soc_sp', 'delta_soc', 'temp_st', 'temp_sp', 'meancrnt', 'sts_flg'])
+        df_sts_soc = pd.DataFrame(columns = ['sn', 'time_st', 'time_end','delta_time', 'soc_st', 'soc_sp', 'delta_soc', 'temp_st', 'temp_sp', 'meancrnt', 'sts_flg'])
+        data_temp = self.df_bms
+        data_temp = data_temp.dropna(axis = 0, how = 'any', subset = ['总电流[A]', 'SOC[%]'])#删除电流与SOC中的nan值
+        data_temp.reset_index(inplace = True, drop = True)
+        data = data_temp.copy()
+        data['总电流[A]'] = self.param.PackCrntDec*data_temp['总电流[A]']#电流小于0为充电,大于0为放电
+        data['crnt_flg'] = 0
+        data.loc[data['总电流[A]'] > 0, 'crnt_flg'] = 1
+        data.loc[data['总电流[A]'] < 0, 'crnt_flg'] = -1
+        celltemp_name = self.celltemp_name#电芯温度数量
+        # data.to_csv(r'D:\Work\Code_write\data_analyze_platform\USER\lzx\01算法开发\08合众算法开发\04放电统计\分析数据.csv',index=False,encoding='GB18030')
+        #-------------------------------------------------------利用电流连续为0判断电池静置---------------------------------------------------------
+        # rest_crnt = data.loc[data['总电流[A]'] == 0]#电流为0,判断电池静置
+        if not data.empty:
+            df_crnt_flg = data['crnt_flg']
+            num_dead_thresh = 15#判断连续多少个数据为阈值
+            # series = df.iloc[:,0]  #仅作为示例,如果是多列,可以进行循环
+            indexs_to_delelte = clean_dead_value(df_crnt_flg, num_dead_thresh)#获得连续数据所在的行
+            # print(indexs_to_delelte)
+            rest_num = len(indexs_to_delelte)
+            if rest_num > 0:#仅有一个连续数据时
+                for splice_item in range(0, rest_num):#rest_num
+                    df_data_temp = data.iloc[indexs_to_delelte[splice_item][0]:indexs_to_delelte[splice_item][-1]]#获得电流连续数据
+                    df_soc_temp = df_data_temp['SOC[%]']
+                    delta_soc = round((df_soc_temp.iloc[-1] - df_soc_temp.iloc[0]), 3)
+                    df_time_temp = pd.to_datetime(df_data_temp['时间戳'])
+                    delta_time = (df_time_temp.iloc[-1] - df_time_temp.iloc[0])/pd.Timedelta(1, 'hours')
+                    if all(df_data_temp['crnt_flg'] == 0):#静置判断
+                        if delta_time > 0.17:
+                            rate = round(delta_soc/(100*delta_time), 2)
+                            df_sts_chrg_rt_temp = pd.DataFrame({"sn":[self.sn],
+                                                    "time_st":[df_time_temp.iloc[0]], "time_end":[df_time_temp.iloc[-1]], "delta_time":[delta_time],
+                                                    "soc_st":[df_soc_temp.iloc[0]], "soc_sp":[df_soc_temp.iloc[-1]], "delta_soc":[delta_soc],
+                                                    "temp_st":[str(list(df_data_temp[celltemp_name].iloc[0]))],
+                                                    "temp_sp":[str(list(df_data_temp[celltemp_name].iloc[-1]))],
+                                                    "meancrnt":[rate], "sts_flg":['0']})
+                            df_sts_chrg_rt = df_sts_chrg_rt.append(df_sts_chrg_rt_temp)
+                            df_sts_chrg_rt.reset_index(drop = True, inplace = True)
+                    elif all(df_data_temp['crnt_flg'] == -1):#充电判断
+                        if delta_time > 0.2:
+                            rate_chrg = round(delta_soc/(100*delta_time), 2)
+                            df_sts_chrg_rt_temp = pd.DataFrame({"sn":[self.sn],
+                                                    "time_st":[df_time_temp.iloc[0]], "time_end":[df_time_temp.iloc[-1]], "delta_time":[delta_time],
+                                                    "soc_st":[df_soc_temp.iloc[0]], "soc_sp":[df_soc_temp.iloc[-1]], "delta_soc":[delta_soc],
+                                                    "temp_st":[str(list(df_data_temp[celltemp_name].iloc[0]))],
+                                                    "temp_sp":[str(list(df_data_temp[celltemp_name].iloc[-1]))],
+                                                    "meancrnt":[rate_chrg], "sts_flg":['-1']})
+                            df_sts_chrg_rt = df_sts_chrg_rt.append(df_sts_chrg_rt_temp)
+                            df_sts_chrg_rt.reset_index(drop = True, inplace = True)
+            chrg_rest_len = len(df_sts_chrg_rt)
+            df_data_time = pd.to_datetime(data['时间戳'])
+            if chrg_rest_len > 0:
+                for item in range(0, 1):
+                    time_early = (df_sts_chrg_rt.loc[0, 'time_st'] - df_data_time.iloc[0])/pd.Timedelta(1, 'hours')
+                    if time_early > 0.2:
+                        index_early = data[df_data_time == df_sts_chrg_rt.loc[0, 'time_st']].index.tolist()[0]
+                        df_data_early = data.iloc[0:index_early]
+                        df_soc_dschrg = df_data_early['SOC[%]']
+                        df_time_dschrg = pd.to_datetime(df_data_early['时间戳'])
+                        delta_soc_dschrg = round((df_soc_dschrg.iloc[-1] - df_soc_dschrg.iloc[0]), 3)
+                        rate_dschrg = round(delta_soc_dschrg/(100*time_early), 2)
+                        df_sts_dschrg_temp = pd.DataFrame({"sn":[self.sn], 
+                                                "time_st":[df_time_dschrg.iloc[0]], "time_end":[df_time_dschrg.iloc[-1]], "delta_time":[time_early],
+                                                "soc_st":[df_soc_dschrg.iloc[0]], "soc_sp":[df_soc_dschrg.iloc[-1]], "delta_soc":[delta_soc_dschrg],
+                                                "temp_st":[str(list(df_data_early[celltemp_name].iloc[0]))],
+                                                "temp_sp":[str(list(df_data_early[celltemp_name].iloc[-1]))],
+                                                "meancrnt":[rate_dschrg], "sts_flg":['1']})
+                        df_sts_dschrg = df_sts_dschrg.append(df_sts_dschrg_temp)
+                        df_sts_dschrg.reset_index(drop = True, inplace = True)
+                for item in range(1, chrg_rest_len):
+                    time_early = (df_sts_chrg_rt.loc[item, 'time_st'] - df_sts_chrg_rt.loc[item-1, 'time_end'])/pd.Timedelta(1, 'hours')
+                    if time_early > 0.2:
+                        index_early = df_data_time[df_data_time == df_sts_chrg_rt.loc[item - 1, 'time_end']].index.tolist()[0]
+                        index_later = df_data_time[df_data_time == df_sts_chrg_rt.loc[item, 'time_st']].index.tolist()[0]
+                        df_data_early = data.iloc[index_early:index_later]
+                        df_soc_dschrg = df_data_early['SOC[%]']
+                        df_time_dschrg = pd.to_datetime(df_data_early['时间戳'])
+                        delta_soc_dschrg = round((df_soc_dschrg.iloc[-1] - df_soc_dschrg.iloc[0]), 3)
+                        rate_dschrg = round(delta_soc_dschrg/(100*time_early), 2)
+                        df_sts_dschrg_temp = pd.DataFrame({"sn":[self.sn], 
+                                                "time_st":[df_time_dschrg.iloc[0]], "time_end":[df_time_dschrg.iloc[-1]], "delta_time":[time_early],
+                                                "soc_st":[df_soc_dschrg.iloc[0]], "soc_sp":[df_soc_dschrg.iloc[-1]], "delta_soc":[delta_soc_dschrg],
+                                                "temp_st":[str(list(df_data_early[celltemp_name].iloc[0]))],
+                                                "temp_sp":[str(list(df_data_early[celltemp_name].iloc[-1]))],
+                                                "meancrnt":[rate_dschrg], "sts_flg":['1']})
+                        df_sts_dschrg = df_sts_dschrg.append(df_sts_dschrg_temp)
+                        df_sts_dschrg.reset_index(drop = True, inplace = True)
+            df_sts_soc = df_sts_chrg_rt.append(df_sts_dschrg)
+            df_sts_soc = df_sts_soc.sort_values(by = 'time_st')
+        end_time = time.time()
+        print(end_time - start_time)
+        if not df_sts_soc.empty:
+            return df_sts_soc
+        else:
+            return pd.DataFrame()

+ 413 - 0
USER/LZX/01算法开发/08合众算法开发/01静置统计/chrgr_state.ipynb

@@ -0,0 +1,413 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from ctypes import Structure\n",
+    "from re import M\n",
+    "import pandas as pd\n",
+    "import numpy as np\n",
+    "import datetime\n",
+    "import time, datetime\n",
+    "import matplotlib.pyplot as plt\n",
+    "from pylab import*\n",
+    "from scipy.signal import savgol_filter\n",
+    "import os\n",
+    "\n",
+    "path = r'D:\\Work\\Code_write\\data_analyze_platform\\USER\\lzx\\05问题查询\\PK504B00100004003内阻可疑-211206\\原始数据'\n",
+    "    \n",
+    "def get_file():                   #创建一个空列表\n",
+    "    files =os.listdir(path)\n",
+    "    files.sort() #排序\n",
+    "    file_list= []\n",
+    "    for file in files:\n",
+    "        if not  os.path.isdir(path +file):  #判断该文件是否是一个文件夹       \n",
+    "            f_name = str(file)        \n",
+    "#             print(f_name)\n",
+    "            tr = '\\\\'   #多增加一个斜杠\n",
+    "            filename = path + tr + f_name        \n",
+    "            file_list.append(filename)  \n",
+    "    return file_list \n",
+    "\n",
+    "file_list = get_file()\n",
+    "for file in file_list:\n",
+    "    data = pd.read_csv(file,encoding='GB18030')\n",
+    "    #----------------------------------------定义滤波函数-----------------------------------------------------------------------\n",
+    "    def moving_average(interval, windowsize):\n",
+    "        window = np.ones(int(windowsize)) / float(windowsize)\n",
+    "        re = np.convolve(interval, window, 'same')\n",
+    "        return re\n",
+    "    #----------------------------------------区分充放电数据----------------------------------------------------------------------\n",
+    "    df_soc = data['SOC[%]']\n",
+    "    # df_soc[df_soc >= 99] = 100\n",
+    "    # df_soc_flt = moving_average(df_soc, 3)#SOC滤波\n",
+    "    df_soc_len = len(df_soc)\n",
+    "    df_soc_add = df_soc.iloc[df_soc_len-3:df_soc_len-1]#由于对SOC二次微分,增加两行数据\n",
+    "    df_soc_new = df_soc.append(df_soc_add)\n",
+    "    # df_soc_cal = savgol_filter(df_soc_new, 13, 3)\n",
+    "    df_soc_new_dif = np.diff(df_soc_new,axis=0)#电压一次微分,判断升降\n",
+    "    df_soc_new_dif = pd.DataFrame(df_soc_new_dif)\n",
+    "    df_soc_new_dif[df_soc_new_dif > 0] = 1#SOC升高\n",
+    "    df_soc_new_dif[df_soc_new_dif == 0] = 0#SOC升高或静置\n",
+    "    df_soc_new_dif[df_soc_new_dif < 0] = -1#SOC下降\n",
+    "    df_soc_dif_arr = np.array(df_soc_new_dif)\n",
+    "    pos_change = nonzero(df_soc_dif_arr)#寻找非零元素位置\n",
+    "    value_change = df_soc_dif_arr[pos_change[0]]#非零元素数值\n",
+    "    value_change_dif = np.diff(value_change)#对非零元素值二次微分\n",
+    "    peak_pos = np.where(value_change_dif == -2)#充电结束点\n",
+    "    bot_pos = np.where(value_change_dif == 2)#放电结束点\n",
+    "    # df_soc_new_difdif = np.diff(df_soc_new_dif,axis=0)#三次微分,利用-2,2判断充电-静置与放电-静置的区别\n",
+    "    # df_soc_new_difdif = pd.DataFrame(df_soc_new_difdif)\n",
+    "    # peak_pos = np.where(df_soc_new_difdif == -2)\n",
+    "    # bot_pos = np.where(df_soc_new_difdif == 2)\n",
+    "    print(pos_change)\n",
+    "    # print(df_soc)\n",
+    "    # print(df_soc_new_dif)\n",
+    "    print(value_change)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(array([ 6855,  6860,  9481,  9510,  9519,  9538,  9554,  9564,  9618,\n",
+      "        9637,  9681,  9687,  9694,  9704,  9722,  9752,  9812,  9845,\n",
+      "        9892,  9916,  9945,  9974, 10004, 10021, 10033, 10053, 10068,\n",
+      "       10123, 10138, 10150, 10184, 10271, 10374, 10387, 10406, 10449,\n",
+      "       10459, 10510, 10554, 10567, 10599, 10605], dtype=int64), array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
+      "       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n",
+      "      dtype=int64))\n",
+      "[[ 1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]\n",
+      " [-1]]\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(pos_change)\n",
+    "print(value_change)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(array([ 6855,  6860,  9481,  9510,  9519,  9538,  9554,  9564,  9618,\n",
+      "        9637,  9681,  9687,  9694,  9704,  9722,  9752,  9812,  9845,\n",
+      "        9892,  9916,  9945,  9974, 10004, 10021, 10033, 10053, 10068,\n",
+      "       10123, 10138, 10150, 10184, 10271, 10374, 10387, 10406, 10449,\n",
+      "       10459, 10510, 10554, 10567, 10599, 10605], dtype=int64), array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
+      "       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n",
+      "      dtype=int64))\n",
+      "[ 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1\n",
+      " -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1]\n",
+      "<class 'list'>\n"
+     ]
+    }
+   ],
+   "source": [
+    "#-------------------------------------------------------利用soc的升降判断充放电---------------------------------------------------------\n",
+    "pos_change_dif = np.diff(pos_change[0])#SOC变化时的位置信息\n",
+    "pos_change_del_temp = np.where(pos_change_dif < 10)\n",
+    "pos_change_del = pos_change_del_temp[0] + 1\n",
+    "value_change_new = np.delete(value_change[:,0], pos_change_del)#SOC发生变化数值\n",
+    "pos_change_new = np.delete(pos_change[0], pos_change_del)#SOC发生变化位置\n",
+    "print(pos_change)\n",
+    "print(value_change_new)\n",
+    "value_change_new_dif = np.diff(value_change_new)#寻找充电或放电结束位置\n",
+    "value_change_new_dif = np.insert(value_change_new_dif, 0, value_change_new_dif[0])\n",
+    "chrgr_dischrgr_pos_temp = np.where(abs(value_change_new_dif) == 2)#寻找充电或放电结束位置\n",
+    "splice_num = []\n",
+    "if len(chrgr_dischrgr_pos_temp[0]) >= 1:\n",
+    "    chrgr_dischrgr_pos = pos_change_new[chrgr_dischrgr_pos_temp[0]]#原数据中充电或放电结束位置\n",
+    "    chrgr_dischrgr_pos = np.insert(chrgr_dischrgr_pos, 0, 0)\n",
+    "    data_len = len(df_soc)#数据长度\n",
+    "    pos_len = len(chrgr_dischrgr_pos)#切片长度\n",
+    "    chrgr_dischrgr_pos = np.insert(chrgr_dischrgr_pos, pos_len, data_len-1)#\n",
+    "    print(type(splice_num))\n",
+    "    for item in range(0,len(chrgr_dischrgr_pos)-1):\n",
+    "        splice_num.extend(item*np.ones(chrgr_dischrgr_pos[item +1]-chrgr_dischrgr_pos[item]))\n",
+    "    splice_num = np.insert(splice_num, data_len-2, item)\n",
+    "else:\n",
+    "    splice_num = np.zeros(len(df_soc))\n",
+    "    pos_ful = np.array([0])\n",
+    "data['stat'] = splice_num"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "array([    0,  6855,  9481, 12141], dtype=int64)"
+      ]
+     },
+     "execution_count": 27,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "chrgr_dischrgr_pos"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#--------------------------------------------------------筛选充电数据与放电数据-------------------------------------\n",
+    "chrgr_data = pd.DataFrame()\n",
+    "dischrgr_data = pd.DataFrame()\n",
+    "for num_chrgr in range(0,len(chrgr_dischrgr_pos)-1):\n",
+    "    df_data_temp = data.loc[(data['stat'] == num_chrgr)]#筛选每段数据\n",
+    "    data_splice_len = len(df_data_temp)\n",
+    "    if np.count_nonzero(df_data_temp['总电流[A]'] > 0) > 0.3*data_splice_len:\n",
+    "        chrgr_data_temp = df_data_temp.loc[df_data_temp['总电流[A]'] >= 0]#筛选具有充电电流的充电数据\n",
+    "        chrgr_data = chrgr_data.append(chrgr_data_temp)\n",
+    "        chrgr_data = chrgr_data.reset_index(drop = True)\n",
+    "    else:\n",
+    "        dischrgr_data_temp = df_data_temp.loc[df_data_temp['总电流[A]'] <= 0]#筛选具有放电电流的放电数据\n",
+    "        dischrgr_data = dischrgr_data.append(dischrgr_data_temp)\n",
+    "        dischrgr_data = dischrgr_data.reset_index(drop = True)\n",
+    "chrgr_num_difference = np.unique(chrgr_data['stat'])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "       Unnamed: 0                  时间戳  GSM信号  故障等级  故障代码  总电流[A]  总电压[V]  \\\n",
+      "9481         9481  2021-12-02 20:29:00     19     0     0     0.2    65.5   \n",
+      "9483         9483  2021-12-02 20:29:44     30     0     0     0.0    65.6   \n",
+      "9484         9484  2021-12-02 20:29:54     30     0     0     0.6    65.6   \n",
+      "9485         9485  2021-12-02 20:30:03     31     0     0     0.5    65.6   \n",
+      "9486         9486  2021-12-02 20:30:13     31     0     0     0.4    65.7   \n",
+      "...           ...                  ...    ...   ...   ...     ...     ...   \n",
+      "12137       12137  2021-12-03 23:55:59     23     0     0     0.0    65.6   \n",
+      "12138       12138  2021-12-03 23:56:59     23     0     0     0.0    65.6   \n",
+      "12139       12139  2021-12-03 23:57:59     23     0     0     0.0    65.6   \n",
+      "12140       12140  2021-12-03 23:58:59     23     0     0     0.0    65.6   \n",
+      "12141       12141  2021-12-03 23:59:59     23     0     0     0.0    65.5   \n",
+      "\n",
+      "       外电压  总输出状态  上锁状态  ...  单体温度1  单体温度2  单体温度3  单体温度4  其他温度1  其他温度2  其他温度3  \\\n",
+      "9481     0      3     0  ...     13     14     14     14     16     15     13   \n",
+      "9483     0      3     0  ...     14     14     14     13     18     16     13   \n",
+      "9484     0      3     0  ...     14     14     14     14     18     16     13   \n",
+      "9485     0      3     0  ...     14     14     14     14     18     16     13   \n",
+      "9486     0      3     0  ...     13     14     14     14     18     16     13   \n",
+      "...    ...    ...   ...  ...    ...    ...    ...    ...    ...    ...    ...   \n",
+      "12137    0      3     0  ...     14     14     14     14     15     15     13   \n",
+      "12138    0      3     0  ...     14     14     14     14     15     15     13   \n",
+      "12139    0      3     0  ...     14     14     14     14     15     15     13   \n",
+      "12140    0      3     0  ...     14     14     14     14     15     15     13   \n",
+      "12141    0      3     0  ...     14     14     14     14     15     15     13   \n",
+      "\n",
+      "       其他温度4  其他温度5  stat  \n",
+      "9481      15     14   2.0  \n",
+      "9483      15     13   2.0  \n",
+      "9484      15     14   2.0  \n",
+      "9485      15     14   2.0  \n",
+      "9486      15     14   2.0  \n",
+      "...      ...    ...   ...  \n",
+      "12137     15     14   2.0  \n",
+      "12138     15     14   2.0  \n",
+      "12139     15     14   2.0  \n",
+      "12140     15     14   2.0  \n",
+      "12141     15     14   2.0  \n",
+      "\n",
+      "[2590 rows x 47 columns]\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(chrgr_data_temp)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "LookTab_SOC = [0.00, \t2.40, \t6.38, \t10.37, \t14.35, \t18.33, \t22.32, \t26.30, \t30.28, \t35.26, \t40.24, \t45.22, \t50.20, \t54.19, \t58.17, \t60.16, \t65.14, \t70.12, \t75.10, \t80.08, \t84.06, \t88.05, \t92.03, \t96.02, \t100.00, 105]\n",
+    "LookTab_OCV = [2.7151,\t3.0298,\t3.1935,\t3.2009,\t3.2167,\t3.2393,\t3.2561,\t3.2703,\t3.2843,\t3.2871,\t3.2874,\t3.2868,\t3.2896,\t3.2917,\t3.2967,\t3.3128,\t3.3283,\t3.3286,\t3.3287,\t3.3288,\t3.3289,\t3.3296,\t3.3302,\t3.3314,\t3.3429, 3.6]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "     单体电压1  单体电压2  单体电压3  单体电压4  单体电压5  单体电压6  单体电压7  单体电压8  单体电压9  单体电压10  \\\n",
+      "787  3.281  3.286  3.283  3.284  3.283  3.283  3.286  3.286  3.287   3.285   \n",
+      "\n",
+      "     单体电压11  单体电压12  单体电压13  单体电压14  单体电压15  单体电压16  单体电压17  单体电压18  单体电压19  \\\n",
+      "787   3.282   3.288   3.287   3.284   3.284   3.286   3.289   3.289   3.288   \n",
+      "\n",
+      "     单体电压20  \n",
+      "787   3.287  \n"
+     ]
+    }
+   ],
+   "source": [
+    "#--------------------------------------------------------统计充电截止电压、充电SOC区间---------------------------------------------------------\n",
+    "from scipy import interpolate\n",
+    "cell_name = ['单体电压'+str(x) for x in range(1,21)]#电芯电压名称\n",
+    "chrgr_volt = pd.DataFrame()\n",
+    "chrgr_fin_volt = pd.DataFrame()\n",
+    "chrgr_soc = pd.DataFrame()\n",
+    "f = interpolate.interp1d(LookTab_OCV, LookTab_SOC, kind = 'linear')#差值函数\n",
+    "for chrgr_num in chrgr_num_difference:\n",
+    "    data_temp = chrgr_data.loc[chrgr_data['stat'] == chrgr_num]#该片段数据\n",
+    "    chrgr_crnt_data = data_temp.loc[data_temp['总电流[A]'] > 0]#充电数据中有电流部分,充电时电流为正\n",
+    "    chrgr_crnt_data = chrgr_crnt_data.reset_index(drop = True)\n",
+    "    chrgr_crnt_zero_before = data_temp.loc[data_temp['时间戳'] < chrgr_crnt_data['时间戳'][0]]#充电数据中出现电流前数据\n",
+    "    chrgr_crnt_zero_after = data_temp.loc[data_temp['时间戳'] > chrgr_crnt_data.iloc[-1]['时间戳']]#充电数据中出现电流前数据\n",
+    "    chrgr_crnt_zero_before = chrgr_crnt_zero_before.reset_index(drop = True)\n",
+    "    chrgr_crnt_zero_after = chrgr_crnt_zero_after.reset_index(drop = True)\n",
+    "    time_before = pd.to_datetime(chrgr_crnt_zero_before['时间戳'])\n",
+    "    time_after = pd.to_datetime(chrgr_crnt_zero_after['时间戳'])\n",
+    "    chrgr_rest_len = len(time_after)\n",
+    "    if chrgr_rest_len > 1:\n",
+    "        if (time_after[chrgr_rest_len - 1] - time_after[0])/pd.Timedelta(1, 'min') > 10:\n",
+    "            # chrgr_volt = chrgr_volt.append(chrgr_crnt_zero_before.iloc[-1])#充电开始前静置电压\n",
+    "            chrgr_volt = chrgr_volt.append(chrgr_crnt_zero_after.iloc[-1])#充电结束静置电压\n",
+    "            df_cell_volt = chrgr_volt[cell_name]/1000\n",
+    "            df_cell_volt[df_cell_volt >= 3.6] = 3.595\n",
+    "            df_cell_volt[df_cell_volt <= 2.715] = 2.72\n",
+    "            print(df_cell_volt)\n",
+    "            chrgr_soc = f(df_cell_volt)\n",
+    "# for cell_num in cell_name:#获取各个电芯充电结束后的SOC\n",
+    "#     chrgr_cellsoc = f(chrgr_volt[cell_num]/1000)\n",
+    "#     chrgr_cellsoc_temp = pd.DataFrame(chrgr_cellsoc)\n",
+    "#     chrgr_soc = pd.concat([chrgr_soc, chrgr_cellsoc_temp], axis = 1)#按列合并各个电芯\n",
+    "# chrgr_soc = chrgr_soc.reset_index(drop = True)\n",
+    "# chrgr_soc.columns = cell_name\n",
+    "# chrgr_soc['时间戳'] = list(chrgr_volt['时间戳'])\n",
+    "# chrgr_soc['stat'] = list(chrgr_volt['stat'])\n",
+    "# chrgr_soc['soc_delta'] =  np.max(chrgr_soc[cell_name], axis = 1) - np.min(chrgr_soc[cell_name], axis = 1)\n",
+    "# chrgr_soc['sn'] = 'sn'\n",
+    "# chrgr_soc.to_csv(r'D:\\Work\\Code_write\\data_analyze_platform\\USER\\lzx\\05问题查询\\PK504B00100004003内阻可疑-211206\\充电行为统计\\充电截止SOC.csv',index=False,encoding='GB18030')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0        0.0\n",
+      "1        0.0\n",
+      "2        0.0\n",
+      "3        0.0\n",
+      "4        0.0\n",
+      "        ... \n",
+      "12137    2.0\n",
+      "12138    2.0\n",
+      "12139    2.0\n",
+      "12140    2.0\n",
+      "12141    2.0\n",
+      "Name: stat, Length: 12142, dtype: float64\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(data['stat'])"
+   ]
+  }
+ ],
+ "metadata": {
+  "interpreter": {
+   "hash": "b3ba2566441a7c06988d0923437866b63cedc61552a5af99d1f4fb67d367b25f"
+  },
+  "kernelspec": {
+   "display_name": "Python 3.8.8 64-bit ('base': conda)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.8"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}

+ 129 - 0
USER/LZX/01算法开发/08合众算法开发/01静置统计/chrgr_statics_pack.py

@@ -0,0 +1,129 @@
+from ctypes import Structure
+from re import M
+import pandas as pd
+import numpy as np
+import datetime
+import time, datetime
+import matplotlib.pyplot as plt
+from pylab import*
+from scipy.signal import savgol_filter
+from scipy import interpolate
+import os
+from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import BatParam
+class cell_statistic:
+    def __init__(self,sn,celltype,df_bms):  #参数初始化
+        self.sn=sn
+        self.celltype=celltype
+        self.param=BatParam.BatParam(celltype)#鹏飞param中为BatParam,学琦为BatteryInfo
+        self.df_bms=pd.DataFrame(df_bms)
+        self.packcrnt=df_bms['总电流[A]']*self.param.PackCrntDec
+        self.packvolt=df_bms['总电压[V]']
+        self.bms_soc=df_bms['SOC[%]']
+        self.bmstime= pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
+        self.LookTab_OCV = self.param.LookTab_OCV
+        self.LookTab_SOC = self.param.LookTab_SOC
+        self.packcrnt_flg = self.param.PackCrntDec#判断充放电电流方向,一般放电为正,充电为负
+        self.cellvolt_list=['单体电压'+str(x) for x in range(1,self.param.CellVoltNums+1)]
+        self.celltemp_name=['单体温度'+str(x) for x in range(1,self.param.CellTempNums+1)]
+        self.bmssta = df_bms['充电状态']
+    #定义加权滤波函数..................................................................................................
+    def moving_average(interval, windowsize):
+        window = np.ones(int(windowsize)) / float(windowsize)
+        re = np.convolve(interval, window, 'same')
+        return re
+#.............................................充电行为统计............................................................................
+    def chrgr_sta(self):
+        start_time = time.time()
+        df_chrgr_soc = pd.DataFrame(columns = ['sn', 'crntstrt_time', 'splicestrt_time', 'crntend_time', 'spliceend_time', 'strt_soc', 'end_soc', 'delta_soc', 'state'])
+        data_temp = self.df_bms
+        data = data_temp.dropna(axis = 0, how = 'any', subset = ['总电流[A]', 'SOC[%]'])#删除电流与SOC中的nan值
+        #----------------------------------------区分充放电数据----------------------------------------------------------------------
+        print(data['总电流[A]'])
+        df_soc = data['SOC[%]']
+        df_soc[df_soc > 98] = 100#满SOC
+        df_crnt = data['总电流[A]']
+        df_soc_len = len(df_soc)
+        df_soc_add = df_soc.iloc[df_soc_len-3:df_soc_len-1]#由于对SOC二次微分,增加两行数据
+        df_crnt_add = df_crnt.iloc[df_soc_len-2:df_soc_len-1]#由于对电流不做微分为匹配SOC的一次微分,增加一行数据
+        df_soc_new = df_soc.append(df_soc_add)
+        df_crnt_new = df_crnt.append(df_crnt_add)
+        df_soc_new_dif = np.diff(df_soc_new,axis=0)#SOC一次微分,判断升降
+        df_soc_new_dif = pd.DataFrame(df_soc_new_dif)
+        df_crnt_new = pd.DataFrame(df_crnt_new)
+        df_soc_new_dif[(df_soc_new_dif > 0)] = 1#SOC升高
+        # df_soc_new_dif[(df_soc_new_dif > 0) & (df_crnt_new > 0)] = 0#放电时SOC升高,将SOC差值置0
+        df_soc_new_dif[df_soc_new_dif == 0] = 0#SOC升高或静置
+        df_soc_new_dif[(df_soc_new_dif < 0)] = -1#SOC下降
+        df_soc_dif_arr = np.array(df_soc_new_dif)
+        pos_change = nonzero(df_soc_dif_arr)#寻找非零元素位置
+        value_change = df_soc_dif_arr[pos_change[0]]#非零元素数值
+        #-------------------------------------------------------利用soc的升降判断充放电---------------------------------------------------------
+        pos_change_dif = np.diff(pos_change[0])#计算SOC变化时的位置信息
+        pos_change_del_temp = np.where(pos_change_dif < 30)
+        pos_change_del = pos_change_del_temp[0] + 1
+        value_change_new = np.delete(value_change[:,0], pos_change_del)#SOC发生变化数值
+        pos_change_new = np.delete(pos_change[0], pos_change_del)#SOC发生变化位置
+        value_change_new_dif = np.diff(value_change_new)#寻找充电或放电结束位置
+        value_change_new_dif = np.insert(value_change_new_dif, 0, value_change_new_dif[0])
+        chrgr_dischrgr_pos_temp = np.where(abs(value_change_new_dif) == 2)#寻找充电或放电结束位置
+        splice_num = []
+        if len(chrgr_dischrgr_pos_temp[0]) >= 1:
+            chrgr_dischrgr_pos = pos_change_new[chrgr_dischrgr_pos_temp[0]]#原数据中充电或放电结束位置
+            chrgr_dischrgr_pos = np.insert(chrgr_dischrgr_pos, 0, 0)
+            # data_len = len(df_soc)#数据长度
+            pos_len = len(chrgr_dischrgr_pos)#切片长度
+            chrgr_dischrgr_pos = np.insert(chrgr_dischrgr_pos, pos_len, df_soc_len-1)#
+            for item in range(0,len(chrgr_dischrgr_pos)-1):
+                splice_num.extend(item*np.ones(chrgr_dischrgr_pos[item +1]-chrgr_dischrgr_pos[item]))
+            splice_num = np.insert(splice_num, df_soc_len-2, item)
+        else:
+            splice_num = np.zeros(df_soc_len)
+            # pos_ful = np.array([0])
+        data['stat'] = splice_num
+        #--------------------------------------------------------筛选充电数据与放电数据-------------------------------------
+        chrgr_data = pd.DataFrame()
+        dischrgr_data = pd.DataFrame()
+        for num_chrgr in range(0,len(chrgr_dischrgr_pos)-1):
+            df_data_temp = data.loc[(data['stat'] == num_chrgr)]
+            df_data_temp = df_data_temp.reset_index(drop = True)
+            df_soc_temp = df_data_temp['SOC[%]']
+            if len(df_soc_temp) > 10:
+                if (df_soc_temp.iloc[-1] - df_soc_temp.iloc[0]) > 10:#筛选SOC增大的区间段,认为是一次充电
+                    # chrgr_data_temp = df_data_temp.loc[df_data_temp['总电流[A]'] >= 0]
+                    chrgr_data = chrgr_data.append(df_data_temp)
+                    chrgr_data = chrgr_data.reset_index(drop = True)
+                else:
+                    # dischrgr_data_temp = df_data_temp.loc[df_data_temp['总电流[A]'] <= 0]#筛选具有放电电流的放电数据
+                    dischrgr_data = dischrgr_data.append(df_data_temp)
+                    dischrgr_data = dischrgr_data.reset_index(drop = True)
+            else:
+                dischrgr_data = dischrgr_data.append(df_data_temp)
+                dischrgr_data = dischrgr_data.reset_index(drop = True)
+        if len(chrgr_data) > 1:
+            process_difference = set(data['stat'])#充电数据在原数据中的段数
+            #---------------------------------------------------统计充电截止电压、充电SOC区间---------------------------------------------------------
+            if len(process_difference) > 0:
+                for chrgr_num in process_difference:
+                    data_temp = data.loc[(data['stat'] == (chrgr_num - 1))]#该片段数据
+                    crnt_data = data_temp.loc[data_temp['总电流[A]'] != 0]#充电数据中电流非零部分,充电时电流为负
+                    # chrgr_crnt_data = chrgr_crnt_data.reset_index(drop = True)
+                    crnt_zero = data_temp.loc[data_temp['总电流[A]'] == 0]#充电数据中电流为0数据
+                    # chrgr_crnt_zero = chrgr_crnt_zero.reset_index(drop = True)
+                    crnt_time = pd.to_datetime(crnt_data['时间戳'])
+                    crnt_zero_time = pd.to_datetime(crnt_zero['时间戳'])
+                    if (len(crnt_time) > 0) & (len(crnt_zero_time) > 0):
+                        delta_soc = crnt_data['SOC[%]'].iloc[-1] - crnt_data['SOC[%]'].iloc[0]
+                        if delta_soc > 0:
+                            chrgr_sta = ['charged']
+                        else:
+                            chrgr_sta = ['discharged']
+                        df_chrgr_soc_temp = pd.DataFrame({"sn":[self.sn], "crntstrt_time":[crnt_time.iloc[0]], "splicestrt_time":[data_temp['时间戳'].iloc[0]], "crntend_time":[crnt_time.iloc[-1]], 
+                                                "spliceend_time":[data_temp['时间戳'].iloc[-1]], "strt_soc":[crnt_data['SOC[%]'].iloc[0]], "end_soc":[crnt_data['SOC[%]'].iloc[-1]], 
+                                                "delta_soc":[delta_soc], "state":[chrgr_sta]})
+                        df_chrgr_soc = df_chrgr_soc.append(df_chrgr_soc_temp)
+                        df_chrgr_soc.reset_index(drop = True, inplace = True)
+                        # df_chrgr_soc.sort_values(by = ['splicestrt_time'], axis = 0, ascending=True,inplace=True)#对故障信息按照时间进行排序
+        if not df_chrgr_soc.empty:
+            return df_chrgr_soc
+        else:
+            return pd.DataFrame()

+ 109 - 0
USER/LZX/01算法开发/08合众算法开发/01静置统计/main.py

@@ -0,0 +1,109 @@
+import datetime
+import pandas as pd
+from LIB.BACKEND import DBManager, Log
+import time, datetime
+from apscheduler.schedulers.blocking import BlockingScheduler
+import log
+from pandas.core.frame import DataFrame
+import rest_stscs_v1
+import soc_total
+
+#...................................电池包电芯安全诊断函数......................................................................................................................
+def rest_statics():
+    global SNnums
+    global df_rest_static
+    start=time.time()
+    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=3)
+    end_time=str(now_time)
+    start_time=str(start_time)
+    k = 602
+    for sn in SNnums[k:]:
+        if 'PK500' in sn:
+            celltype=1 #6040三元电芯
+        elif 'PK502' in sn:
+            celltype=2 #4840三元电芯
+        elif 'K504B' in sn:
+            celltype=99    #60ah林磷酸铁锂电芯
+        elif 'MGMLXN750' in sn:
+            celltype=3 #力信50ah三元电芯
+        elif 'MGMCLN750' in sn: 
+            celltype=4 #CATL 50ah三元电芯
+        elif 'UD' in sn:
+            celltype=4 #CATL 50ah三元电芯
+        elif 'TJMCL' in sn: 
+            celltype=100 #金茂电芯
+        else:
+            print('SN:{},未找到对应电池类型!!!'.format(sn))
+            continue
+            # sys.exit()
+        print('计算的第' + str(k) + '个:' + sn)
+        k = k + 1
+        #读取原始数据库数据........................................................................................................................................................
+        start_time = '2021-06-01 00:00:00'
+        end_time = '2021-07-01 00:00:00'
+        dbManager = DBManager.DBManager()
+        df_data = dbManager.get_data(sn=sn, start_time=start_time, end_time=end_time, data_groups=['bms'])
+        df_bms = df_data['bms']
+        df_Diag_rest_add = pd.DataFrame(columns = ['sn', 'time_st', 'time_end', 'soc_st', 'soc_sp', 'delta_soc', 'tempure', 'meancrnt'])
+        #充电统计................................................................................................................................................................
+        if not df_bms.empty:
+            rest_statics_temp = rest_stscs_v1.cell_statistic(sn,celltype,df_bms)#析锂检测
+            df_Diag_rest_add = rest_statics_temp.rest_sta()        
+        if not df_Diag_rest_add.empty:
+            df_rest_static = df_rest_static.append(df_Diag_rest_add)
+            df_rest_static = df_rest_static.drop_duplicates(subset = ['sn','time_st'], keep = 'first', inplace = False)
+            # df_rest_static.sort_values(by = ['sn'], axis = 0, ascending=True,inplace=True)#对故障信息按照时间进行排序
+            df_rest_static.to_csv(r'D:\Develop\User\Liuzhongxiao\data_analyze_platform\USER\LZX\01算法开发\08合众算法开发\01静置统计\静置统计.csv',index=False,encoding='GB18030')
+        end=time.time()
+        print(end-start)
+
+#...............................................主函数.......................................................................................................................
+if __name__ == "__main__":
+    global SNnums
+    global df_rest_static
+    
+    excelpath=r'D:\Develop\User\Liuzhongxiao\data_analyze_platform\USER\LZX\01算法开发\00项目sn号\sn-20210903.xlsx'
+    SNdata_6060 = pd.read_excel(excelpath, sheet_name='科易6060')
+    SNdata_6040 = pd.read_excel(excelpath, sheet_name='科易6040')
+    SNdata_4840 = pd.read_excel(excelpath, sheet_name='科易4840')
+    SNdata_L7255 = pd.read_excel(excelpath, sheet_name='格林美-力信7255')
+    SNdata_C7255 = pd.read_excel(excelpath, sheet_name='格林美-CATL7255')
+    SNdata_U7255 = pd.read_excel(excelpath, sheet_name='优旦7255')
+    SNnums_6060=SNdata_6060['SN号'].tolist()
+    SNnums_6040=SNdata_6040['SN号'].tolist()
+    SNnums_4840=SNdata_4840['SN号'].tolist()
+    SNnums_L7255=SNdata_L7255['SN号'].tolist()
+    SNnums_C7255=SNdata_C7255['SN号'].tolist()
+    SNnums_U7255=SNdata_U7255['SN号'].tolist()
+    # SNums_file = pd.read_csv(r'D:\Work\Code_write\data_analyze_platform\USER\lzx\01算法开发\02析锂检测\02析锂分析\各项目析锂情况_211130\增加波峰高度与峰谷比计算结果\SNnums_C7255析锂情况析锂排序.csv',encoding='GB18030')
+    # SNums_sn = SNums_file['sn']
+    # liplated_high = SNums_sn.iloc[7:10]
+    # liplated_low = SNums_sn.iloc[-11:-1]
+    # cal_sn = liplated_high.append(liplated_low)
+    SNnums = SNnums_L7255[50:] + SNnums_C7255[50:] + SNnums_6040[50:] + SNnums_4840[50:] + SNnums_U7255[50:]+ SNnums_6060[50:]
+    # SNnums = SNnums_U7255
+    # SNnums=['TJMCL120502305010','TJMCL120502305012','TJMCL120502305048','TJMCL120502305044','TJMCL120502305026','TJMCL120502305022','TJMCL120502305032','TJMCL120502305038']
+    # SNnums = list(cal_sn)#['MGMCLN750N215N049']#['MGMCLN750N215N049'] #SNnums_6040 #SNnums_C7255 #SNnums_6040['MGMCLN750N215N049'] 
+    # SNnums = pd.read_csv(r'D:\Work\Code_write\data_analyze_platform\USER\lzx\01算法开发\02析锂检测\liplated\疑似析锂电池sn.csv',encoding='GB18030')
+    # SNnums=['TJMCL120502305010','TJMCL120502305012','TJMCL120502305048','TJMCL120502305044','TJMCL120502305026','TJMCL120502305022','TJMCL120502305032','TJMCL120502305038']
+    mylog=log.Mylog('log_diag.txt','error')#'TJMCL120502305010','TJMCL120502305012',
+    mylog.logcfg()
+    #............................模块运行前,先读取数据库中所有结束时间为0的数据,需要从数据库中读取................
+    df_rest_static = pd.read_csv(r'D:\Develop\User\Liuzhongxiao\data_analyze_platform\USER\LZX\01算法开发\08合众算法开发\01静置统计\静置统计.csv',encoding='GB18030')
+
+    print('----------------输入--------')
+    print('-------计算中-----------')
+    rest_statics()
+    #定时任务.......................................................................................................................................................................
+    # scheduler = BlockingScheduler()
+    # scheduler.add_job(rest_statics, 'interval', seconds=10, id='diag_job')
+
+    # try:  
+    #     scheduler.start()
+    # except Exception as e:
+    #     scheduler.shutdown()
+    #     print(repr(e))
+    #     mylog.logopt(e)
+

+ 84 - 0
USER/LZX/01算法开发/08合众算法开发/01静置统计/rest_stscs.py

@@ -0,0 +1,84 @@
+from ctypes import Structure
+from re import M
+import pandas as pd
+import numpy as np
+import datetime
+import time, datetime
+import matplotlib.pyplot as plt
+from pylab import*
+from scipy.signal import savgol_filter
+from scipy import interpolate
+import os
+from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import BatParam
+class cell_statistic:
+    def __init__(self,sn,celltype,df_bms):  #参数初始化
+        self.sn=sn
+        self.celltype=celltype
+        self.param=BatParam.BatParam(celltype)#鹏飞param中为BatParam,学琦为BatteryInfo
+        self.df_bms=pd.DataFrame(df_bms)
+        self.packcrnt=df_bms['总电流[A]']*self.param.PackCrntDec
+        self.packvolt=df_bms['总电压[V]']
+        self.bms_soc=df_bms['SOC[%]']
+        self.bmstime= pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
+        self.LookTab_OCV = self.param.LookTab_OCV
+        self.LookTab_SOC = self.param.LookTab_SOC
+        self.packcrnt_flg = self.param.PackCrntDec#判断充放电电流方向,一般放电为正,充电为负
+        self.cellvolt_list=['单体电压'+str(x) for x in range(1,self.param.CellVoltNums+1)]
+        self.celltemp_name=['单体温度'+str(x) for x in range(1,self.param.CellTempNums+1)]
+        self.bmssta = df_bms['充电状态']
+    #定义加权滤波函数..................................................................................................
+    def moving_average(interval, windowsize):
+        window = np.ones(int(windowsize)) / float(windowsize)
+        re = np.convolve(interval, window, 'same')
+        return re
+#.............................................充电行为统计............................................................................
+    def rest_sta(self):
+        start_time = time.time()
+        df_rest_soc = pd.DataFrame(columns = ['sn', 'time_st', 'time_end', 'soc_st', 'soc_sp', 'delta_soc', 'tempure', 'meancrnt'])
+        data_temp = self.df_bms
+        data = data_temp.dropna(axis = 0, how = 'any', subset = ['总电流[A]', 'SOC[%]'])#删除电流与SOC中的nan值
+        #----------------------------------------区分充放电数据----------------------------------------------------------------------
+        df_soc = data['SOC[%]']
+        # df_soc[df_soc > 98] = 100#满SOC
+        #-------------------------------------------------------利用电流连续为0判断电池静置---------------------------------------------------------
+        rest_crnt = data.loc[data['总电流[A]'] == 0]#电流为0,判断电池静置
+        if not rest_crnt.empty:
+            rest_crnt_data = rest_crnt.reset_index(drop=True)
+            temp_rest_time = rest_crnt_data['时间戳']
+            rest_time = pd.to_datetime(temp_rest_time)
+            delta_time = (np.diff(rest_time)/pd.Timedelta(1, 'min'))#计算时间差的分钟数
+            pos = np.where(delta_time > 60)#静置数据分段,大于60min时,认为是两个静置过程
+            splice_num = []
+            if len(pos[0]) >= 1:
+                pos_ful_tem = np.insert(pos, 0, 0)
+                pos_len = len(pos_ful_tem)
+                data_len = len(rest_time)
+                pos_ful = np.insert(pos_ful_tem, pos_len, data_len-1)
+                for item in range(0,len(pos_ful)-1):
+                    splice_num.extend(item*np.ones(pos_ful[item +1]-pos_ful[item]))
+                splice_num = np.insert(splice_num, 0, 0)
+            else:
+                splice_num = np.zeros(len(temp_rest_time))
+                pos_ful = np.array([0])
+            rest_crnt_data['rest_rest'] = splice_num
+        rest_splice_num = np.unique(rest_crnt_data['rest_rest'])#判断有几段充电数据
+        if len(rest_splice_num) > 0:
+            for item_rest in rest_splice_num:
+                celltemp_name = self.celltemp_name#电芯温度数量
+                df_rest_splice_data = rest_crnt_data.loc[rest_crnt_data['rest_rest'] == item_rest]
+                df_time_temp = pd.to_datetime(df_rest_splice_data['时间戳'])
+                df_soc_temp = df_rest_splice_data['SOC[%]']
+                delta_soc = abs(round((df_soc_temp.iloc[-1] - df_soc_temp.iloc[0]), 3))
+                delta_time = (df_time_temp.iloc[-1] - df_time_temp.iloc[0])/pd.Timedelta(1, 'hours')
+                if (delta_soc < 2) & (delta_time > 1):
+                    chrg_rate = round(delta_soc/(100*delta_time), 2)
+                    df_rest_soc_temp = pd.DataFrame({"sn":[self.sn], "time_st":[df_time_temp.iloc[0]], "time_end":[df_time_temp.iloc[-1]], 
+                                            "soc_st":[df_soc_temp.iloc[0]], "soc_sp":[df_soc_temp.iloc[-1]], "delta_soc":[delta_soc],
+                                            "tempure":[str(list(df_rest_splice_data[celltemp_name].iloc[0]))], "meancrnt":[chrg_rate]})
+                    df_rest_soc = df_rest_soc.append(df_rest_soc_temp)
+                    df_rest_soc.reset_index(drop = True, inplace = True)
+                        # df_rest_soc.sort_values(by = ['splicestrt_time'], axis = 0, ascending=True,inplace=True)#对故障信息按照时间进行排序
+        if not df_rest_soc.empty:
+            return df_rest_soc
+        else:
+            return pd.DataFrame()

+ 105 - 0
USER/LZX/01算法开发/08合众算法开发/01静置统计/rest_stscs_v1.py

@@ -0,0 +1,105 @@
+from ctypes import Structure
+from re import M
+import pandas as pd
+import numpy as np
+import datetime
+import time, datetime
+import matplotlib.pyplot as plt
+from pylab import*
+from scipy.signal import savgol_filter
+from scipy import interpolate
+import os
+from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import BatParam
+class cell_statistic:
+    def __init__(self,sn,celltype,df_bms):  #参数初始化
+        self.sn=sn
+        self.celltype=celltype
+        self.param=BatParam.BatParam(celltype)#鹏飞param中为BatParam,学琦为BatteryInfo
+        self.df_bms=pd.DataFrame(df_bms)
+        self.packcrnt=df_bms['总电流[A]']*self.param.PackCrntDec
+        self.packvolt=df_bms['总电压[V]']
+        self.bms_soc=df_bms['SOC[%]']
+        self.bmstime= pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
+        self.LookTab_OCV = self.param.LookTab_OCV
+        self.LookTab_SOC = self.param.LookTab_SOC
+        self.packcrnt_flg = self.param.PackCrntDec#判断充放电电流方向,一般放电为正,充电为负
+        self.cellvolt_list=['单体电压'+str(x) for x in range(1,self.param.CellVoltNums+1)]
+        self.celltemp_name=['单体温度'+str(x) for x in range(1,self.param.CellTempNums+1)]
+        self.bmssta = df_bms['充电状态']
+    #定义加权滤波函数..................................................................................................
+    def moving_average(interval, windowsize):
+        window = np.ones(int(windowsize)) / float(windowsize)
+        re = np.convolve(interval, window, 'same')
+        return re
+    
+#.............................................静置行为统计............................................................................
+    def rest_sta(self):
+        def clean_dead_value(series, num_dead_thresh):
+            slide_list = [series.index[0]]
+            slide_list_all = []
+            for i in range(series.index[0],series.index[-1]):
+                j = i + 1
+                diff = series[j] - series[i]
+                if diff == 0:
+                    slide_list.append(j)
+                else:
+                    slide_list.clear()
+                    slide_list.append(j)
+                # print("slide_list:",slide_list)
+                if len(slide_list) >= num_dead_thresh:
+                    target_list = slide_list.copy()
+                    slide_list_all.append(target_list)
+            # print("slide_list_all:",slide_list_all)
+            index= []  # 将找到的满足条件的index合并
+            # 因为可能有前后包含的情况,只保留最长序列
+            for i in range(len(slide_list_all) - 1):
+                if set(slide_list_all[i]) < set(slide_list_all[i + 1]):
+                    index.append(i)
+            m = {i: element for i, element in enumerate(slide_list_all)}
+            [m.pop(i) for i in index]
+            # 将所有需要删除的行数合并
+            # indexs_to_delete = []
+            # for i in range(len(slide_list_all)):
+            #     indexs_to_delete = list(set(indexs_to_delete).union(slide_list_all[i]))
+            return list(m.values())
+        df_rest_soc = pd.DataFrame(columns = ['sn', 'time_st', 'time_end', 'soc_st', 'soc_sp', 'delta_soc', 'tempure', 'meancrnt'])
+        data_temp = self.df_bms
+        data = data_temp.dropna(axis = 0, how = 'any', subset = ['总电流[A]', 'SOC[%]'])#删除电流与SOC中的nan值
+        #----------------------------------------区分充放电数据----------------------------------------------------------------------
+        # df_crnt = data['总电流[A]']
+        # df_soc[df_soc > 98] = 100#满SOC
+        #-------------------------------------------------------利用电流连续为0判断电池静置---------------------------------------------------------
+        rest_crnt = data.loc[data['总电流[A]'] == 0]#电流为0,判断电池静置
+        if not rest_crnt.empty:
+            df_crnt = data['总电流[A]']
+            num_dead_thresh = 12#判断连续多少个数据为阈值
+            # series = df.iloc[:,0]  #仅作为示例,如果是多列,可以进行循环
+            indexs_to_delelte = clean_dead_value(df_crnt, num_dead_thresh)#获得连续数据所在的行
+            rest_num = len(indexs_to_delelte)
+            for splice_item in range(0, rest_num):#
+                print('第' + str(splice_item) + '个片段')
+                start_time = time.time()
+                df_data_temp = pd.DataFrame()
+                df_rest_soc_temp = pd.DataFrame(columns = ['sn', 'time_st', 'time_end', 'soc_st', 'soc_sp', 'delta_soc', 'tempure', 'meancrnt'])
+                df_data_temp = data.iloc[indexs_to_delelte[splice_item][0]:indexs_to_delelte[splice_item][-1]]#获得电流连续数据
+                df_time_temp = pd.to_datetime(df_data_temp['时间戳'])
+                if all(df_data_temp['总电流[A]'] == 0):
+                    delta_time = (df_time_temp.iloc[-1] - df_time_temp.iloc[0])/pd.Timedelta(1, 'hours')
+                    if delta_time > 1:
+                        celltemp_name = self.celltemp_name#电芯温度数量
+                        df_soc_temp = df_data_temp['SOC[%]']
+                        delta_soc = round((df_soc_temp.iloc[-1] - df_soc_temp.iloc[0]), 3)
+                        # delta_time = (df_time_temp.iolc[-1] - df_time_temp.iloc[0])/pd.Timedelta(1, 'hours')
+                        chrg_rate = round(delta_soc/(100*delta_time), 2)
+                        df_rest_soc_temp = pd.DataFrame({"sn":[self.sn], "time_st":[df_time_temp.iloc[0]], "time_end":[df_time_temp.iloc[-1]], 
+                                                "soc_st":[df_soc_temp.iloc[0]], "soc_sp":[df_soc_temp.iloc[-1]], "delta_soc":[delta_soc],
+                                                "tempure":[str(list(df_data_temp[celltemp_name].iloc[0]))], "meancrnt":[chrg_rate]})
+                        df_rest_soc = df_rest_soc.append(df_rest_soc_temp)
+                        df_rest_soc.reset_index(drop = True, inplace = True)
+                        end_time = time.time()
+                        print(end_time - start_time)
+                        # df_rest_soc.sort_values(by = ['splicestrt_time'], axis = 0, ascending=True,inplace=True)#对故障信息按照时间进行排序
+        if not df_rest_soc.empty:
+            return df_rest_soc
+        else:
+            return pd.DataFrame()

+ 132 - 0
USER/LZX/01算法开发/08合众算法开发/01静置统计/soc_total.py

@@ -0,0 +1,132 @@
+from ctypes import Structure
+from re import M
+import pandas as pd
+import numpy as np
+import datetime
+import time, datetime
+import matplotlib.pyplot as plt
+from pylab import*
+from scipy.signal import savgol_filter
+from scipy import interpolate
+import os
+from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import BatParam
+class chrgr_statistic:
+    def __init__(self,sn,celltype,df_bms):  #参数初始化
+        self.sn=sn
+        self.celltype=celltype
+        self.param=BatParam.BatParam(celltype)#鹏飞param中为BatParam,学琦为BatteryInfo
+        self.df_bms=pd.DataFrame(df_bms)
+        self.packcrnt=df_bms['总电流[A]']*self.param.PackCrntDec
+        self.packvolt=df_bms['总电压[V]']
+        self.bms_soc=df_bms['SOC[%]']
+        self.bmstime= pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
+        self.LookTab_OCV = self.param.LookTab_OCV
+        self.LookTab_SOC = self.param.LookTab_SOC
+        self.packcrnt_flg = self.param.PackCrntDec#判断充放电电流方向,一般放电为正,充电为负
+        self.cellvolt_list=['单体电压'+str(x) for x in range(1,self.param.CellVoltNums+1)]
+        self.celltemp_name=['单体温度'+str(x) for x in range(1,self.param.CellTempNums+1)]
+        self.bmssta = df_bms['充电状态']
+    #定义加权滤波函数..................................................................................................
+    def moving_average(interval, windowsize):
+        window = np.ones(int(windowsize)) / float(windowsize)
+        re = np.convolve(interval, window, 'same')
+        return re
+#.............................................充电行为统计............................................................................
+    def chrgr_soc_sta(self):
+        start_time = time.time()
+        df_chrgr_soc = pd.DataFrame(columns = ['sn', 'time', 'chrgr_soc', 'chrgr_volt', 'temp', 'full_chrgr_num'])
+        data = self.df_bms
+        data.fillna(0, inplace = True)
+        crnt_flg = self.packcrnt_flg
+        LookTab_OCV = self.LookTab_OCV
+        LookTab_SOC = self.LookTab_SOC
+        #----------------------------------------区分充放电数据----------------------------------------------------------------------
+        df_soc = data['SOC[%]']
+        df_soc_len = len(df_soc)
+        df_soc_add = df_soc.iloc[df_soc_len-3:df_soc_len-1]#由于对SOC二次微分,增加两行数据
+        df_soc_new = df_soc.append(df_soc_add)
+        df_soc_new_dif = np.diff(df_soc_new,axis=0)#SOC一次微分,判断升降
+        df_soc_new_dif = pd.DataFrame(df_soc_new_dif)
+        df_soc_new_dif[df_soc_new_dif > 0] = 1#SOC升高
+        df_soc_new_dif[df_soc_new_dif == 0] = 0#SOC升高或静置
+        df_soc_new_dif[df_soc_new_dif < 0] = -1#SOC下降
+        df_soc_dif_arr = np.array(df_soc_new_dif)
+        pos_change = nonzero(df_soc_dif_arr)#寻找非零元素位置
+        value_change = df_soc_dif_arr[pos_change[0]]#非零元素数值
+        #-------------------------------------------------------利用soc的升降判断充放电---------------------------------------------------------
+        pos_change_dif = np.diff(pos_change[0])#计算SOC变化时的位置信息
+        pos_change_del_temp = np.where(pos_change_dif < 10)
+        pos_change_del = pos_change_del_temp[0] + 1
+        value_change_new = np.delete(value_change[:,0], pos_change_del)#SOC发生变化数值
+        pos_change_new = np.delete(pos_change[0], pos_change_del)#SOC发生变化位置
+        value_change_new_dif = np.diff(value_change_new)#寻找充电或放电结束位置
+        value_change_new_dif = np.insert(value_change_new_dif, 0, value_change_new_dif[0])
+        chrgr_dischrgr_pos_temp = np.where(abs(value_change_new_dif) == 2)#寻找充电或放电结束位置
+        splice_num = []
+        if len(chrgr_dischrgr_pos_temp[0]) >= 1:
+            chrgr_dischrgr_pos = pos_change_new[chrgr_dischrgr_pos_temp[0]]#原数据中充电或放电结束位置
+            chrgr_dischrgr_pos = np.insert(chrgr_dischrgr_pos, 0, 0)
+            # data_len = len(df_soc)#数据长度
+            pos_len = len(chrgr_dischrgr_pos)#切片长度
+            chrgr_dischrgr_pos = np.insert(chrgr_dischrgr_pos, pos_len, df_soc_len-1)#
+            for item in range(0,len(chrgr_dischrgr_pos)-1):
+                splice_num.extend(item*np.ones(chrgr_dischrgr_pos[item +1]-chrgr_dischrgr_pos[item]))
+            splice_num = np.insert(splice_num, df_soc_len-2, item)
+        else:
+            splice_num = np.zeros(df_soc_len)
+            # pos_ful = np.array([0])
+        data['stat'] = splice_num
+        #--------------------------------------------------------筛选充电数据与放电数据-------------------------------------
+        chrgr_data = pd.DataFrame()
+        dischrgr_data = pd.DataFrame()
+        for num_chrgr in range(0,len(chrgr_dischrgr_pos)-1):
+            df_data_temp = data.loc[(data['stat'] == num_chrgr)]
+            df_data_temp = df_data_temp.reset_index(drop = True)
+            df_soc_temp = df_data_temp['SOC[%]']
+            if len(df_soc_temp) > 10:
+                if (df_soc_temp.iloc[-1] - df_soc_temp.iloc[0]) > 10:#筛选SOC增大的区间段,认为是一次充电
+                    # chrgr_data_temp = df_data_temp.loc[df_data_temp['总电流[A]'] >= 0]
+                    chrgr_data = chrgr_data.append(df_data_temp)
+                    chrgr_data = chrgr_data.reset_index(drop = True)
+                else:
+                    # dischrgr_data_temp = df_data_temp.loc[df_data_temp['总电流[A]'] <= 0]#筛选具有放电电流的放电数据
+                    dischrgr_data = dischrgr_data.append(df_data_temp)
+                    dischrgr_data = dischrgr_data.reset_index(drop = True)
+            else:
+                dischrgr_data = dischrgr_data.append(df_data_temp)
+                dischrgr_data = dischrgr_data.reset_index(drop = True)
+        if len(chrgr_data) > 1:
+            chrgr_num_difference = np.unique(chrgr_data['stat'])#充电过程有几段数据
+            #---------------------------------------------------统计充电截止电压、充电SOC区间---------------------------------------------------------
+            cell_name = self.cellvolt_list#电芯电压名称
+            temp_name = self.celltemp_name
+            full_chrgr_num = 0
+            if len(chrgr_num_difference) > 0:
+                chrgr_soc = pd.DataFrame()
+                soc_cal = interpolate.interp1d(LookTab_OCV, LookTab_SOC, kind = 'linear')#插值函数
+                max_volt = max(LookTab_OCV)
+                min_volt = min(LookTab_OCV)
+                for chrgr_num in chrgr_num_difference:
+                    data_temp = chrgr_data.loc[chrgr_data['stat'] == chrgr_num]#该片段数据
+                    chrgr_crnt_data = data_temp.loc[crnt_flg*data_temp['总电流[A]'] < 0]#充电数据中电流非零部分,充电时电流为负
+                    chrgr_crnt_data = chrgr_crnt_data.reset_index(drop = True)
+                    chrgr_crnt_zero = data_temp.loc[data_temp['总电流[A]'] == 0]#充电数据中电流为0数据
+                    chrgr_crnt_zero = chrgr_crnt_zero.reset_index(drop = True)
+                    chrgr_crnt_time = pd.to_datetime(chrgr_crnt_data['时间戳'])
+                    if len(chrgr_crnt_data) > 1:
+                        df_cell_volt = chrgr_crnt_data[cell_name].iloc[-1]/1000
+                        df_cell_volt[df_cell_volt >= max_volt] = max_volt - 0.005
+                        df_cell_volt[df_cell_volt <= min_volt] = min_volt + 0.005
+                        chrgr_soc = soc_cal(list(df_cell_volt))
+                        full_chrgr_check = (chrgr_soc > 98)
+                        if any(full_chrgr_check):
+                            full_chrgr_num = full_chrgr_num + 1
+                        df_chrgr_soc_temp = pd.DataFrame({"sn":[self.sn], "time":[chrgr_crnt_time.iloc[-1]], "chrgr_soc":[str(list(chrgr_soc))], "chrgr_volt":[str(list(df_cell_volt))], 
+                                                "temp":[str(list(chrgr_crnt_data[temp_name].iloc[-1]))], "full_chrgr_num":[full_chrgr_num]})
+                        df_chrgr_soc = df_chrgr_soc.append(df_chrgr_soc_temp)
+                        df_chrgr_soc = df_chrgr_soc.reset_index(drop = True)
+                        df_chrgr_soc.sort_values(by = ['time'], axis = 0, ascending=True,inplace=True)#对故障信息按照时间进行排序
+        if not df_chrgr_soc.empty:
+            return df_chrgr_soc
+        else:
+            return pd.DataFrame()