Browse Source

Merge branch 'dev' of http://git.fast-fun.cn:92/lmstack/data_analyze_platform into dev

lmstack 2 năm trước cách đây
mục cha
commit
223f26b291

+ 2 - 0
LIB/BACKEND/DEPLOY/build.cmd

@@ -0,0 +1,2 @@
+::  本脚本用于构建测试和生产环境中的python基础镜像
+

+ 2 - 2
LIB/BACKEND/Log.py

@@ -20,8 +20,8 @@ class Mylog:
     def get_logger(self):
         return self.logger
     
-    def set_file_hl(self, file_name='all.log', log_level='info', size=1):
-        fh = handlers.RotatingFileHandler(file_name, maxBytes=size, backupCount=10)
+    def set_file_hl(self, file_name='all.log', log_level='info', size=1, backupCount=10):
+        fh = handlers.RotatingFileHandler(file_name, maxBytes=size, backupCount=backupCount)
         fh_formatter = logging.Formatter('%(asctime)s:%(created)f:%(name)s:%(module)s:%(funcName)s:%(levelname)s:%(message)s')
         fh.setFormatter(fh_formatter)
         if len(log_level) > 0:

+ 35 - 0
LIB/FRONTEND/AlgoTest/Algo1/V_1_0_0/Dockerfile

@@ -0,0 +1,35 @@
+# 基础镜像
+FROM python:3.8
+
+# 作者,版本
+LABEL author="lm"  
+LABEL version="1.0.0"
+
+# 环境变量参数
+ENV TZ="Asia/Shanghai"
+
+# 安装用到的python 第三方库
+RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple \
+    sqlalchemy \
+    pandas==1.3.4 \
+    pymysql apscheduler \
+    scipy \
+    cryptography \
+    numpy==1.20.3 \
+    requests
+
+#RUN rm -r /usr/bin
+#RUN rm -r /bin
+
+# 配置算法路径
+ARG ALGO_PATH=LIB/MIDDLE/AlgoTest/Algo1
+# 配置版本路径
+ARG ALGO_VERSION=V_1_0_0
+
+# 复制文件文件到 容器
+ADD LIB/BACKEND/ /LIB/BACKEND
+ADD ${ALGO_PATH}/${ALGO_VERSION}/ /${ALGO_VERSION}/
+ADD ${ALGO_PATH}/main.py /main.py
+WORKDIR /
+
+CMD ["python", "main.py"]

+ 13 - 0
LIB/MIDDLE/AlgoDemo/Demo/V_1_0_0/CoreAlgo/core.py

@@ -0,0 +1,13 @@
+
+from LIB.BACKEND import DBManager # 以相对路径的方式从LIB开始引入
+import pandas as pd
+
+
+class CalSor:
+    
+    def __init__(self):
+        pass
+    
+    def calSor(self, sn,df_bms, celltype):
+        i = len(df_bms)
+        return pd.DataFrame({'data':[i],'sn':[sn]})

+ 34 - 0
LIB/MIDDLE/AlgoDemo/Demo/V_1_0_0/Main/Dockerfile

@@ -0,0 +1,34 @@
+# 基础镜像
+FROM python:3.8
+
+# 作者 (需要修改)
+LABEL author="lm"  
+
+
+# 环境变量参数
+ENV TZ="Asia/Shanghai"
+ENV PYTHONPATH="/"
+
+# 安装用到的python 第三方库 (需要修改)
+RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple \
+    sqlalchemy \
+    pandas==1.3.4 \
+    pymysql apscheduler \
+    scipy \
+    cryptography \
+    numpy==1.20.3 \
+    requests
+
+#RUN rm -r /usr/bin
+#RUN rm -r /bin
+
+# 配置算法路径 (需要修改)
+ARG ALGO_PATH=LIB/MIDDLE/AlgoDemo/Demo/V_1_0_0/
+
+
+# 复制文件文件到 容器
+ADD LIB/BACKEND/ /LIB/BACKEND
+ADD ${ALGO_PATH}/ /${ALGO_PATH}/
+WORKDIR ${ALGO_PATH}/Main/
+
+CMD ["python", "main.py"]

+ 13 - 0
LIB/MIDDLE/AlgoDemo/Demo/V_1_0_0/Main/config-dev.ini

@@ -0,0 +1,13 @@
+[Mysql-1]
+host = localhost
+port = 3306
+db = test
+user = root
+password = Qx123456
+
+[Mysql-2]
+host = localhost
+port = 3306
+db = test
+user = root
+password = Qx123456

+ 13 - 0
LIB/MIDDLE/AlgoDemo/Demo/V_1_0_0/Main/config-pro.ini

@@ -0,0 +1,13 @@
+[Mysql-1]
+host = 120.25.223.1
+port = 4901
+db = test
+user = root
+password = 123456
+
+[Mysql-2]
+host = 120.25.223.1
+port = 4901
+db = test
+user = root
+password = 123456

+ 13 - 0
LIB/MIDDLE/AlgoDemo/Demo/V_1_0_0/Main/config-test.ini

@@ -0,0 +1,13 @@
+[Mysql-1]
+host = 192.168.0.43
+port = 3306
+db = test
+user = root
+password = Qx123456
+
+[Mysql-2]
+host = 192.168.0.43
+port = 3306
+db = test
+user = root
+password = Qx123456

+ 141 - 0
LIB/MIDDLE/AlgoDemo/Demo/V_1_0_0/Main/main.py

@@ -0,0 +1,141 @@
+# -*- coding: UTF-8 -*-
+
+import pandas as pd
+import time
+from sqlalchemy import create_engine
+import os
+import configparser
+import pymysql
+import traceback
+import datetime
+from LIB.BACKEND import DBManager,Log # 以相对路径的方式从LIB开始引入!!!!!
+from LIB.MIDDLE.AlgoDemo.Demo.V_1_0_0.CoreAlgo import core # 以相对路径的方式从LIB开始引入!!!!!
+from LIB.BACKEND.OPENAPI import OpenApi
+
+if __name__ == '__main__':
+    
+    
+    # 环境变量配置(通过环境变量确定当前程序运行在开发、测试、生产环境)
+    env_dist = os.environ
+    cur_env = env_dist.get("CURENV", 'dev') # 默认为开发环境
+    
+    # 读取配置文件 (该部分请不要修改)
+    cf = configparser.ConfigParser()
+    if cur_env == 'dev':
+        cf.read("config-dev.ini")
+    elif cur_env == 'test':
+        cf.read("config-test.ini")
+    elif cur_env == 'pro':
+        cf.read("config-pro.ini")
+    
+    # 解析配置文件 (该部分请按照实际需求修改)
+    host1 = cf.get("Mysql-1", 'host')
+    port1 = int(cf.get("Mysql-1", 'port'))
+    db1 = cf.get("Mysql-1", 'db')
+    user1 = cf.get("Mysql-1", 'user')
+    password1 = cf.get("Mysql-1", 'password')
+    
+    host2 = cf.get("Mysql-2", 'host')
+    port2 = int(cf.get("Mysql-2", 'port'))
+    db2 = cf.get("Mysql-2", 'db')
+    user2 = cf.get("Mysql-2", 'user')
+    password2 = cf.get("Mysql-2", 'password')
+    
+    # 日志配置(按照该配置,每次运行时可自动生成运行日期的文件夹, 会在与main.py同级的, 该部分可按照实际需求修改)
+    now_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()).replace(":","_")
+    log_path = 'log/' + now_str
+    if not os.path.exists(log_path):
+        os.makedirs(log_path)
+    log = Log.Mylog(log_name='cal_sor', log_level = 'info')
+    log.set_file_hl(file_name='{}/info.log'.format(log_path), log_level='info', size=1024* 1024 * 100)
+    log.set_file_hl(file_name='{}/error.log'.format(log_path), log_level='error', size=1024* 1024 * 100)
+    log.set_stream_hl("error") # 打印错误日志
+    logger = log.get_logger()
+    logger.info("{}, 算法开始".format(str(os.getpid())))
+    
+    try:    
+        # 连接数据库的两种方式
+        # 方式一:新dataframe写入数据库时,采用该方式可以不需要写sql语句;
+        #    该方式无法对数据库进行修改;
+        
+        db_engine_1 = create_engine(
+            "mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8".format(
+                user1, password1, host1, port1, db1
+            ))
+        
+        # 方式二:该方式可以通过写update SQL语句,对数据库中的数据进行修改
+        conn = pymysql.connect(host=host2, port=port2, user=user2, password=password2, database=db2)
+        cursor = conn.cursor()
+
+        # 准备算法数据
+        
+        # 原始数据时间设置
+        end_time=datetime.datetime.now()
+        start_time=end_time-datetime.timedelta(seconds=300)
+        start_time=start_time.strftime('%Y-%m-%d %H:%M:%S')
+        end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
+        
+        # 从开放平台获取资产列表及相关信息
+        openApi = OpenApi.OpenApi()
+        df_all_sn = openApi.get_asset()
+        calSor = core.CalSor(); # 算法初始化
+        
+        # 遍历资产列表,获取数据和参数,输入算法中
+        for index in range(0, df_all_sn.index[-1]):
+            
+            try:# 解析得到厂家、sn、协议类型、电芯参数等输入数据
+                factory = df_all_sn.loc[index,'factory']
+                sn = df_all_sn.loc[index,'sn']
+                imei = df_all_sn.loc[index,'imei']
+                protocolType = df_all_sn.loc[index,'protocolType'] # 协议类型(3:32960,10:科易,13:优旦)
+                if imei[5:9] == 'N640':
+                    celltype=1 #6040三元电芯
+                elif imei[5:9] == 'N440':
+                    celltype=2 #4840三元电芯
+                elif imei[5:9] == 'L660':
+                    celltype=99 # 6060锂电芯
+                elif imei[3:5] == 'LX' and imei[5:9] == 'N750':    
+                    celltype=3 #力信 50ah三元电芯
+                elif imei[3:5] == 'CL' and imei[5:9] == 'N750': 
+                    celltype=4 #CATL 50ah三元电芯
+                elif imei[1:3] == 'JM': # 金茂
+                    celltype=100 #CATL 50ah三元电芯
+
+                # 获取电池历史数据
+                logger.info("{} start".format(sn))
+                dbManager = DBManager.DBManager()
+                df_data = dbManager.get_data(sn=sn, start_time=start_time, end_time=end_time, data_groups=['bms', 'gps', 'accum', 'system'])
+                df_bms = df_data['bms']
+                
+                # 获取数据库原始数据
+                df_ram = pd.read_sql("select * from test_tb where sn ='{}'".format(sn), db_engine_1)
+                
+                # 调用核心算法 
+                df_res = calSor.calSor(sn, df_bms,celltype);
+                
+                # 算法结果入库
+                # 新增
+                if (len(df_ram) == 0):
+                    df_res.to_sql("test_tb",con=db_engine_1, if_exists="append",index=False)
+                    
+                else:   
+                # 修改
+                    sql = '''update test_tb set data={} where sn='{}' '''.format(df_res['data'].values[0], (df_res['sn'].values[0]))
+                    cursor.execute(sql)
+                    conn.commit()
+                logger.info("{} done".format(sn))
+            except Exception as e :
+                logger.error(traceback.format_exc)
+                logger.error(str(e))
+                logger.error(u"{} :{},{} 任务运行错误\n".format(sn,start_time,end_time), exc_info=True)
+            
+    except Exception as e :
+        logger.error(traceback.format_exc)
+        logger.error(str(e))
+        logger.error(u"任务运行错误2\n", exc_info=True)
+        
+    # 释放数据库资源
+    cursor.close()
+    conn.close()
+    db_engine_1.dispose()
+

+ 699 - 0
LIB/MIDDLE/CellStateEstimation/BatDiag/V1_0_0/CBMSBatDiag.py

@@ -0,0 +1,699 @@
+import pandas as pd
+import numpy as np
+import datetime
+from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import BatParam
+
+class BatDiag:
+    def __init__(self,sn,celltype,df_bms,df_diag_ram_sn,df_bms_ram_sn,df_soh,df_uniform):  #参数初始化
+
+        self.sn=sn
+        self.celltype=celltype
+        self.param=BatParam.BatParam(celltype)
+        self.df_bms=df_bms
+        self.df_uniform=df_uniform
+        self.df_soh=df_soh
+        self.df_bms_ram=df_bms_ram_sn.copy()
+        self.df_diag_ram=df_diag_ram_sn.copy()
+        df_bms['时间戳']=pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
+
+        if not df_bms_ram_sn.empty:
+            self.df_bms=self.df_bms[self.df_bms['时间戳'] > df_bms_ram_sn.iloc[-1]['time']]    #滤除原始数据中的重复数据
+            self.df_bms.reset_index(inplace=True,drop=True)     #重置索引
+        
+        self.packcrnt=df_bms['总电流[A]']*self.param.PackCrntDec
+        self.packvolt=df_bms['总电压[V]']
+        self.bmstime= df_bms['时间戳']
+        self.bms_soc=df_bms['SOC[%]']
+
+        self.cellvolt_name=['单体电压'+str(x) for x in range(1,self.param.CellVoltNums+1)]
+        # othertemp=['其他温度'+str(x) for x in range(1,self.param.OtherTempNums+1)]
+        self.celltemp_name=['单体温度'+str(x) for x in range(1,self.param.CellTempNums+1)]
+        # self.celltemp_name=celltemp+othertemp
+
+    
+    def diag(self):
+        if self.celltype<=50:
+            df_res1,df_res2=self._bat_diag()
+            return df_res1,df_res2    
+        else:
+            df_res1,df_res2=self._bat_diag()
+            return df_res1,df_res2
+
+    
+    #寻找当前行数据的所有温度值...................................................................................
+    def _celltemp_get(self,num):   
+        celltemp = list(self.df_bms.loc[num,self.celltemp_name])
+        return celltemp
+
+    #获取当前行所有电压数据............................................................................................
+    def _cellvolt_get(self,num): 
+        cellvolt = list(self.df_bms.loc[num,self.cellvolt_name]/1000)
+        return cellvolt
+
+    #..........................................电池诊断功能..................................................................
+    def _bat_diag(self):
+
+        column_name=['start_time', 'end_time', 'product_id', 'code', 'level', 'info','advice']
+        df_res=pd.DataFrame(columns=column_name)
+
+        end_time='0000-00-00 00:00:00'
+        ah_accum=0  #SOC卡滞初始参数
+        as_chg=0    #过流诊断初始参数
+        as_dis=0    #过流诊断初始参数
+        cellvoltvalid=1
+        voltdsc_time=0
+        voltdsc_count=0
+        voltfail_time=0
+        voltfail_count=0
+        voltloose_time=0
+        voltloose_count=0
+        voltover_time=0
+        voltunder_time=0
+        cov_time=0
+        cuv_time=0
+        cdv_time=0
+        pov_time=0
+        puv_time=0 
+        ot_time=0
+        ut_time=0
+        dt_time=0
+            
+        for i in range(len(self.df_bms)):
+        
+            #电压诊断功能.........................................................................................................................................
+            if i<1:
+                cellvolt2=self._cellvolt_get(i)
+                cellvoltmin2=min(cellvolt2)
+                cellvoltmax2=max(cellvolt2)
+                cellvoltmin_index2=cellvolt2.index(cellvoltmin2)
+                cellvoltmax_index2=cellvolt2.index(cellvoltmax2)
+                if not self.df_bms_ram.empty:
+                    time1=self.df_bms_ram.iloc[-1]['time']
+                    time2=self.bmstime[i]
+                    cellvolt1=self.df_bms_ram.iloc[-1]['cellvolt']
+                    cellvoltmin1=min(cellvolt1)
+                    cellvoltmax1=max(cellvolt1)
+                    cellvoltmin_index1=cellvolt1.index(cellvoltmin1)
+                    cellvoltmax_index1=cellvolt1.index(cellvoltmax1)
+                else:
+                    cellvolt1=cellvolt2
+                    time1=self.bmstime[i]
+                    time2=self.bmstime[i]
+                    cellvoltmin1=cellvoltmin2
+                    cellvoltmax1=cellvoltmax2
+                    cellvoltmin_index1=cellvoltmin_index2
+                    cellvoltmax_index1=cellvoltmax_index2
+            else:
+                time1=self.bmstime[i-1]
+                time2=self.bmstime[i]
+                cellvolt2=self._cellvolt_get(i)
+                cellvoltmin2=min(cellvolt2)
+                cellvoltmax2=max(cellvolt2)
+                cellvoltmin_index2=cellvolt2.index(cellvoltmin2)
+                cellvoltmax_index2=cellvolt2.index(cellvoltmax2)
+                cellvolt1=self._cellvolt_get(i-1)
+                cellvoltmin1=min(cellvolt1)
+                cellvoltmax1=max(cellvolt1)
+                cellvoltmin_index1=cellvolt1.index(cellvoltmin1)
+                cellvoltmax_index1=cellvolt1.index(cellvoltmax1)
+
+            #电压采样断线..........................................................................................................................................
+            if not 'C308' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                if (cellvoltmin2<2 and cellvoltmax2>4.5 and abs(cellvoltmax_index2-cellvoltmin_index2)==1) and (cellvoltmin1<2 and cellvoltmax1>4.5 and abs(cellvoltmax_index1-cellvoltmin_index1)==1):   #电压断线故障进入
+                    cellvoltvalid=0
+                    voltdsc_time=voltdsc_time+(time2-time1).total_seconds()
+                    if voltdsc_time>self.param.volt_time:    #持续时间
+                        time=self.bmstime[i]
+                        code='C308'
+                        faultlv=3
+                        faultinfo='电芯{}和{}电压采样断线'.format(cellvoltmin_index2+1, cellvoltmax_index2+1)
+                        faultadvice='通知用户更换电池,电池返厂维修'
+                        self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                    else:
+                        pass
+                elif (cellvoltmin2<2 and cellvoltmax2>4.5 and abs(cellvoltmax_index2-cellvoltmin_index2)==1) and (cellvoltmin1>2.5 and cellvoltmax1<4.3):   #连续跳变
+                    cellvoltvalid=0
+                    voltdsc_count=voltdsc_count+1
+                    if voltdsc_count>=3:
+                        time=self.bmstime[i]
+                        code='C308'
+                        faultlv=3
+                        faultinfo='电芯{}和{}电压采样断线'.format(cellvoltmin_index2+1, cellvoltmax_index2+1)
+                        faultadvice='通知用户更换电池,电池返厂维修'
+                        self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                    else:
+                        pass
+                else:
+                    voltdsc_time=0
+            else:
+                cellvoltvalid=0
+                if cellvoltmin2>2 and cellvoltmax2<4.5 and cellvoltmin1>2 and cellvoltmax1<4.5:
+                    cellvoltvalid=1
+                    time=self.bmstime[i]
+                    self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C308'].index, 'end_time'] = time
+                else:
+                    pass
+            
+            #电压采样系统失效.............................................................................................................
+            if not 'C309' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                if (cellvoltmin2<1 and cellvoltmin1<1) or (cellvoltmax2>5 and cellvoltmax1>5):
+                    cellvoltvalid=0
+                    voltfail_time=voltfail_time+(time2-time1).total_seconds()
+                    if voltfail_time>self.param.volt_time:    #持续时间
+                        time=self.bmstime[i]
+                        code='C309'
+                        faultlv=3
+                        faultinfo='电芯电压采样系统失效'
+                        faultadvice='通知用户更换电池,电池返厂维修'
+                        self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                    else:
+                        pass
+                elif (cellvoltmin2<1 and cellvoltmin1>2.5) or  (cellvoltmax2>5 and cellvoltmax1<4.5):   #连续跳变
+                    cellvoltvalid=0
+                    voltfail_count=voltfail_count+1
+                    if voltfail_count>=3:
+                        time=self.bmstime[i]
+                        code='C309'
+                        faultlv=3
+                        faultinfo='电芯电压采样系统失效'
+                        faultadvice='通知用户更换电池,电池返厂维修'
+                        self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                    else:
+                        pass
+                else:
+                    voltfail_time=0
+            else:
+                cellvoltvalid=0
+                if cellvoltmin2>2.5 and cellvoltmax2<4.5 and cellvoltmin1>2.5 and cellvoltmax1<4.5:
+                    cellvoltvalid=1
+                    time=self.bmstime[i]
+                    self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C309'].index, 'end_time'] = time
+                else:
+                    pass
+            
+            #电压采样线松动.................................................................................................................
+            if not 'C208' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                if cellvoltmin2>2 and cellvoltmax2<4.5 and cellvoltmin1>2 and cellvoltmax1<4.5:
+                    cellvolt1_std=np.std(cellvolt1)
+                    cellvolt1_mean=np.mean(cellvolt1)
+                    cellvolt1_3sigma=(np.array(cellvolt1)-cellvolt1_mean)/cellvolt1_std
+                    cellvolt2_std=np.std(cellvolt2)
+                    cellvolt2_mean=np.mean(cellvolt2)
+                    cellvolt2_3sigma=(np.array(cellvolt2)-cellvolt2_mean)/cellvolt2_std
+                    if (min(cellvolt1_3sigma)<-3 and max(cellvolt1_3sigma)>3) and (min(cellvolt2_3sigma)<-3 and max(cellvolt2_3sigma)>3):   #连续发生
+                        cellvoltvalid=0
+                        voltloose_time=voltloose_time+(time2-time1).total_seconds()
+                        if voltloose_time>self.param.volt_time:
+                            time=self.bmstime[i]
+                            code='C208'
+                            faultlv=3
+                            faultinfo='电芯电压{}和{}采样松动'.format(cellvoltmin_index2+1, cellvoltmax_index2+1)
+                            faultadvice='通知技术人员介入诊断'
+                            self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                        else:
+                            pass
+                    elif (min(cellvolt1_3sigma)>-3 and max(cellvolt1_3sigma)<3) and (min(cellvolt2_3sigma)<-3 and max(cellvolt2_3sigma)>3): #连续跳变
+                        cellvoltvalid=0
+                        voltloose_count=voltloose_count+1
+                        if voltloose_count>=3:
+                            time=self.bmstime[i]
+                            code='C208'
+                            faultlv=3
+                            faultinfo='电芯电压{}和{}采样松动'.format(cellvoltmin_index2+1, cellvoltmax_index2+1)
+                            faultadvice='通知技术人员介入诊断'
+                            self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                        else:
+                            pass
+                    else:
+                        voltloose_time=0
+                else:
+                    voltloose_time=0
+            else:
+                cellvoltvalid=0
+                cellvolt1_std=np.std(cellvolt1)
+                cellvolt1_mean=np.mean(cellvolt1)
+                cellvolt1_3sigma=(np.array(cellvolt1)-cellvolt1_mean)/cellvolt1_std
+                cellvolt2_std=np.std(cellvolt2)
+                cellvolt2_mean=np.mean(cellvolt2)
+                cellvolt2_3sigma=(np.array(cellvolt2)-cellvolt2_mean)/cellvolt2_std
+                if(min(cellvolt1_3sigma)>-3 or max(cellvolt1_3sigma)<3) and (min(cellvolt2_3sigma)>-3 or max(cellvolt2_3sigma)<3):
+                    cellvoltvalid=1
+                    time=self.bmstime[i]
+                    self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C208'].index, 'end_time'] = time
+                else:
+                    pass
+        
+            if cellvoltvalid==1:
+                #继电器粘连.............................................................................................................................................
+                if not 'C310' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                    if cellvoltmax2>self.param.CellOvLv2 and cellvoltmax1>self.param.CellOvLv2 and self.packcrnt[i]<0:
+                        voltover_time=voltover_time+(time2-time1).total_seconds()
+                        if voltover_time>self.param.volt_time:
+                            time=self.bmstime[i]
+                            code='C310'
+                            faultlv=3
+                            faultinfo='充电继电器粘连'
+                            faultadvice='通知技术人员介入诊断'
+                            self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                        else:
+                            pass
+                    else:
+                        voltover_time=0
+                else:
+                    if cellvoltmax2<self.param.CellOvLv2-0.05 and cellvoltmax1<self.param.CellOvLv2-0.05:
+                        time=self.bmstime[i]
+                        self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C310'].index, 'end_time'] = time
+                    else:
+                        pass
+            
+                if not 'C311' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                    if cellvoltmin2<self.param.CellUvLv2 and cellvoltmin1<self.param.CellUvLv2 and self.packcrnt[i]>0:
+                        voltunder_time=voltunder_time+(time2-time1).total_seconds()
+                        if voltunder_time>self.param.volt_time:
+                            time=self.bmstime[i]
+                            code='C311'
+                            faultlv=3
+                            faultinfo='放电继电器粘连'
+                            faultadvice='通知技术人员介入诊断'
+                            self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                        else:
+                            pass
+                    else:
+                        voltunder_time=0
+                else:
+                    if cellvoltmin2>self.param.CellUvLv2+0.05 and cellvoltmin1>self.param.CellOvLv2+0.05:
+                        time=self.bmstime[i]
+                        self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C311'].index, 'end_time'] = time
+                    else:
+                        pass
+                
+                #电芯过压.............................................................................................................................................
+                if not 'C501' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                    if cellvoltmax2>self.param.CellOvLv2 and cellvoltmax1>self.param.CellOvLv2 and self.packcrnt[i]<0:  #二级过压进入
+                        cov_time=cov_time+(time2-time1).total_seconds()
+                        if cov_time>self.param.volt_time:
+                            time=self.bmstime[i]
+                            code='C501'
+                            faultlv=5
+                            faultinfo='电芯{}过压'.format(cellvolt1.index(cellvoltmax1)+1)
+                            faultadvice='联系用户立即停止充电,并通知技术运维人员'
+                            self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                        else:
+                            pass
+                    else:
+                        cov_time=0
+                else:   #ram当前故障中有该故障,则判断是否退出该故障
+                    if cellvoltmax2<self.param.CellOvLv1-0.05 and cellvoltmax1<self.param.CellOvLv1-0.05:   #二级过压故障恢复
+                        time=self.bmstime[i]
+                        self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C501'].index, 'end_time'] = time
+                    else:
+                        pass
+                
+                #欠压诊断.................................................................................................................
+                if not 'C202' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                    if cellvoltmin2<self.param.CellUvLv2 and cellvoltmin1<self.param.CellUvLv2:  #二级欠压
+                        cuv_time=cuv_time+(time2-time1).total_seconds()
+                        if cuv_time>self.param.volt_time:
+                            time=self.bmstime[i]
+                            code='C202'
+                            faultlv=2
+                            faultinfo='电芯{}欠压'.format(cellvolt1.index(cellvoltmin1)+1)
+                            faultadvice='联系用户询问用车场景,技术介入诊断'
+                            self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                        else:
+                            pass
+                    else:
+                        cuv_time=0
+                else:
+                    if cellvoltmin2>self.param.CellUvLv1+0.1 and cellvoltmin1>self.param.CellUvLv1+0.1:
+                        time=self.bmstime[i]
+                        self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C202'].index, 'end_time'] = time
+                    else:
+                        pass
+             
+                #电芯压差大.....................................................................................................................................................
+                if not 'C104' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                    if (cellvoltmax2-cellvoltmin2)>self.param.CellVoltDiffLv2 and (cellvoltmax1-cellvoltmin1)>self.param.CellVoltDiffLv2:  #二级电芯压差
+                        cdv_time=cdv_time+(time2-time1).total_seconds()
+                        if cdv_time>self.param.volt_time:
+                            time=self.bmstime[i]
+                            code='C104'
+                            faultlv=0
+                            faultinfo='电芯{}和{}压差大'.format(cellvolt1.index(cellvoltmax1)+1,cellvolt1.index(cellvoltmin1)+1)
+                            faultadvice='技术介入诊断'
+                            self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                        else:
+                            pass
+                    else:
+                        cdv_time=0
+                else:
+                    if (cellvoltmax2-cellvoltmin2)<self.param.CellVoltDiffLv1-0.05 and (cellvoltmax1-cellvoltmin1)<self.param.CellVoltDiffLv1-0.05: #二级欠压恢复
+                        time=self.bmstime[i]
+                        self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C104'].index, 'end_time'] = time
+                    else:
+                        pass
+            else:
+                cov_time=0
+                cuv_time=0
+                cdv_time=0
+            
+            #电池包诊断.....................................................................................................................................
+            if i<1:
+                if not self.df_bms_ram.empty:
+                    packvolt1=self.df_bms_ram.iloc[-1]['packvolt']
+                    packvolt2=self.packvolt[i]
+                    time1=self.df_bms_ram.iloc[-1]['time']
+                    time2=self.bmstime[i]
+                else:
+                    packvolt1=self.packvolt[i]
+                    packvolt2=self.packvolt[i]
+                    time1=self.bmstime[i]
+                    time2=self.bmstime[i]
+            else:
+                packvolt1=self.packvolt[i-1]
+                packvolt2=self.packvolt[i]
+                time1=self.bmstime[i-1]
+                time2=self.bmstime[i]
+            if packvolt1<2*self.param.CellVoltNums or packvolt2>4.5*self.param.CellVoltNums:   #电池包电压有效性
+                packvoltvalid=0
+            else:
+                packvoltvalid=1
+
+            if packvoltvalid==1:
+                if not 'C502' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                    if packvolt1>self.param.PackVoltOvLv2 and packvolt2>self.param.PackVoltOvLv2 and self.packcrnt[i]<0:   #电池包过压二级进入
+                        pov_time=pov_time+(time2-time1).total_seconds()
+                        if pov_time>self.param.volt_time:
+                            time=self.bmstime[i]
+                            code='C502'
+                            faultlv=5
+                            faultinfo='电池包过压'
+                            faultadvice='联系用户立即停止充电,并通知技术运维人员'
+                            self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                        else:
+                            pass
+                    else:
+                        pov_time=0
+                else:
+                    if packvolt1<self.param.PackVoltOvLv1-0.05*self.param.CellVoltNums and packvolt2<self.param.PackVoltOvLv1-0.05*self.param.CellVoltNums: #电池包过压二级恢复
+                        time=self.bmstime[i]
+                        self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C502'].index, 'end_time'] = time
+                    else:
+                        pass
+          
+                if not 'C203' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                    if packvolt1<self.param.PackVoltUvLv2 and packvolt2<self.param.PackVoltUvLv2:   #电池包二级欠压进入
+                        puv_time=puv_time+(time2-time1).total_seconds()
+                        if puv_time>self.param.volt_time:
+                            time=self.bmstime[i]
+                            code='C203'
+                            faultlv=2
+                            faultinfo='电池包欠压'
+                            faultadvice='联系用户询问用车场景,技术介入诊断'
+                            self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                        else:
+                            pass
+                    else:
+                        puv_time=0
+                else:
+                    if packvolt1>self.param.PackVoltUvLv1+0.1*self.param.CellVoltNums and packvolt2>self.param.PackVoltUvLv1+0.1*self.param.CellVoltNums:   #电池包二级欠压恢复
+                        time=self.bmstime[i]
+                        self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C203'].index, 'end_time'] = time
+                    else:
+                        pass
+            else:
+                pov_time=0
+                puv_time=0 
+            
+            #温度诊断功能.............................................................................................................
+            if i<1:
+                if not self.df_bms_ram.empty:
+                    celltemp1=self.df_bms_ram.iloc[-1]['celltemp']
+                    celltemp2=self._celltemp_get(i)
+                    time1=self.df_bms_ram.iloc[-1]['time']
+                    time2=self.bmstime[i]
+                else:
+                    celltemp1=self._celltemp_get(i)
+                    celltemp2=self._celltemp_get(i)
+                    time1=self.bmstime[i]
+                    time2=self.bmstime[i]
+            else:
+                celltemp1=self._celltemp_get(i-1)
+                celltemp2=self._celltemp_get(i)
+                time1=self.bmstime[i-1]
+                time2=self.bmstime[i]
+            celltempmin1=min(celltemp1)
+            celltempmin2=min(celltemp2)
+            celltempmax1=max(celltemp1)
+            celltempmax2=max(celltemp2)
+            #温度有效性判断..........................................................................
+            if celltempmax1>self.param.CellTempUpLmt or celltempmin1<self.param.CellTempLwLmt:
+                celltempvalid=0
+            else:  
+                celltempvalid=1
+           
+            if celltempvalid==1:
+                #过温判断.............................................................................................................
+                if not 'C302' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                    if celltempmax1>self.param.CellTempHighLv2 and celltempmax2>self.param.CellTempHighLv2:    #二级高温进入
+                        ot_time=ot_time+(time2-time1).total_seconds()
+                        if ot_time>self.param.temp_time:
+                            time=self.bmstime[i]
+                            code='C302'
+                            faultlv=3
+                            faultinfo='温度{}高温'.format(celltemp1.index(celltempmax1)+1)
+                            faultadvice='技术介入诊断'
+                            self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                        else:
+                            pass
+                    else:
+                        ot_time=0
+                else:   #ram当前故障中有该故障,则判断是否退出该故障
+                    if celltempmax1<self.param.CellTempHighLv1-5 and celltempmax2<self.param.CellTempHighLv1-5:    #二级高温恢复
+                        time=self.bmstime[i]
+                        self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C302'].index, 'end_time'] = time
+                    else:
+                        pass
+            
+                #欠温判断.................................................................................................................
+                if not 'C102' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                    if celltempmin1<self.param.CellTempLowLv2 and celltempmin2<self.param.CellTempLowLv2:  #二级低温进入
+                        ut_time=ut_time+(time2-time1).total_seconds()
+                        if ut_time>self.param.temp_time:
+                            time=self.bmstime[i]
+                            code='C102'
+                            faultlv=1
+                            faultinfo='温度{}低温'.format(celltemp1.index(celltempmin1)+1)
+                            faultadvice='技术介入诊断'
+                            self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                        else:
+                            pass
+                    else:
+                        ut_time=0
+                else:   #ram当前故障中有该故障,则判断是否退出该故障
+                    if celltempmax1>self.param.CellTempLowLv1+2 and celltempmax2>self.param.CellTempLowLv1+2:    #二级高温恢复
+                        time=self.bmstime[i]
+                        self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C102'].index, 'end_time'] = time
+                    else:
+                        pass
+              
+                #温差判断.............................................................................................................................
+                if not 'C103' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                    if (celltempmax1-celltempmin1)>self.param.CellTempDiffLv2 and (celltempmax2-celltempmin2)>self.param.CellTempDiffLv2:  #二级温差进入
+                        dt_time=dt_time+(time2-time1).total_seconds()
+                        if dt_time>self.param.temp_time:
+                            time=self.bmstime[i]
+                            code='C103'
+                            faultlv=1
+                            faultinfo='温度{}和{}温差大'.format(celltemp1.index(celltempmax1)+1,celltemp1.index(celltempmin1)+1)
+                            faultadvice='技术介入诊断'
+                            self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                        else:
+                            pass
+                    else:
+                        dt_time=0
+                else:   #ram当前故障中有该故障,则判断是否退出该故障
+                    if (celltempmax1-celltempmin1)<self.param.CellTempDiffLv1-2 and (celltempmax2-celltempmin2)>self.param.CellTempDiffLv1-2:  #二级温差恢复
+                        time=self.bmstime[i]
+                        self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C103'].index, 'end_time'] = time
+                    else:
+                        pass
+            
+            else:
+                ot_time=0
+                ut_time=0
+                dt_time=0
+            
+            #电流过流诊断.......................................................................................................................
+            if i>0.5:
+                step=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
+                if step<120 and self.packcrnt[i]>self.param.PackDisOc and self.packcrnt[i-1]>self.param.PackDisOc:
+                    as_dis=as_dis+(self.packcrnt[i]-self.param.PackDisOc)*step    #ah累计
+                elif step<120 and self.packcrnt[i]<self.param.PackChgOc and self.packcrnt[i-1]<self.param.PackChgOc:
+                    as_chg=as_chg+(self.param.PackDisOc-self.packcrnt[i])*step    #ah累计
+                else:
+                    as_dis=0
+                    as_chg=0
+                
+                if not 'C306' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                    if as_dis>100:
+                        time=self.bmstime[i]
+                        code='C306'
+                        faultlv=3
+                        faultinfo='电池包放电过流'
+                        faultadvice='联系用户询问用车场景,技术介入诊断'
+                        self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                    else:
+                        pass
+                else:
+                    if self.packcrnt[i]<self.param.PackDisOc-10:
+                        time=self.bmstime[i]
+                        self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C306'].index, 'end_time'] = time
+                    else:
+                        pass
+                
+                if not 'C305' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                    if as_chg>100:
+                        time=self.bmstime[i]
+                        code='C305'
+                        faultlv=3
+                        faultinfo='电池包充电过流'
+                        faultadvice='联系用户询问用车场景,技术介入诊断'
+                        self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                    else:
+                        pass
+                else:
+                    if self.packcrnt[i]>self.param.PackChgOc+10:
+                        time=self.bmstime[i]
+                        self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C305'].index, 'end_time'] = time
+                    else:
+                        pass
+            
+            #SOC卡滞、跳变诊断................................................................................................
+            if i<1:
+                bmssoc_st=float(self.bms_soc[i])
+                bmssoc_last=float(self.bms_soc[i])
+                bmssoc_now=float(self.bms_soc[i])
+            else:
+                step=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
+                if step<120:
+                    ah_accum=ah_accum-self.packcrnt[i]*step/3600    #ah累计
+                else:
+                    pass
+                #SOC卡滞............................................................................................................
+                if abs(ah_accum)>self.param.Capacity*0.1:   
+                    bmssoc_now=float(self.bms_soc[i])
+                    if not 'C106' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                        if abs(bmssoc_now-bmssoc_st)<self.param.SocClamp:   #SOC卡滞故障进入
+                            time=self.bmstime[i]
+                            code='C106'
+                            faultlv=0
+                            faultinfo='电池SOC卡滞'
+                            faultadvice='技术介入诊断,检修电池BMS软件'
+                            self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                        else:
+                            pass
+                    else:
+                        if abs(bmssoc_now-bmssoc_st)>self.param.SocClamp:   #SOC卡滞故障退出
+                            time=self.bmstime[i]
+                            self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C106'].index, 'end_time'] = time
+                        else:
+                            pass
+                    bmssoc_st=bmssoc_now
+                    ah_accum=0
+                else:
+                    pass
+
+                #SOC跳变....................................................................................................................
+                bmssoc_last=float(self.bms_soc[i-1])
+                bmssoc_now=float(self.bms_soc[i])
+                if not 'C107' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                    if step<70 and abs(bmssoc_now-bmssoc_last)>self.param.SocJump:  #SOC跳变进入
+                        time=self.bmstime[i]
+                        code='C107'
+                        faultlv=0
+                        faultinfo='电池SOC跳变{}%'.format(bmssoc_now-bmssoc_last)
+                        faultadvice='技术介入诊断,检修电池BMS软件'
+                        self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                    else:
+                        pass
+                else:
+                    if abs(bmssoc_now-bmssoc_st)<self.param.SocJump:    #SOC跳变故障退出
+                        time=self.bmstime[i]
+                        self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C107'].index, 'end_time'] = time
+                    else:
+                        pass
+        
+        #SOC一致性故障报警..........................................................................................................
+        if not self.df_uniform.empty:
+            cellsoc_diff=self.df_uniform.loc[0,'cellsoc_diff']
+            if not 'C201' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                if cellsoc_diff>self.param.SocDiff: #SOC一致性差故障进入
+                    time=self.bmstime[0]
+                    code='C201'
+                    faultlv=0
+                    faultinfo='电芯{}和{}SOC差过大:{}'.format(int(self.df_uniform.loc[0,'cellmin_num']),int(self.df_uniform.loc[0,'cellmax_num']),cellsoc_diff)
+                    faultadvice='技术介入诊断'
+                    self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                else:
+                    pass
+            else:
+                if cellsoc_diff<self.param.SocDiff: #SOC一致性差故障恢复
+                    time=self.bmstime[0]
+                    self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C201'].index, 'end_time'] = time
+        else:
+            cellsoc_diff=3
+
+        #容量过低和一致性故障报警................................................................................................
+        if not self.df_soh.empty:
+            soh=self.df_soh.loc[0,'soh']
+            cellsoh=eval(self.df_soh.loc[0,'cellsoh'])
+            cellsoh=np.array(cellsoh)
+            cellsoh_lowindex=np.argwhere(cellsoh<self.param.SohLow)
+            cellsoh_lowindex=cellsoh_lowindex+1
+            if self.celltype==1 or self.celltype==2 or self.celltype==3 or self.celltype==4: 
+                cellsoh_diff=np.max(cellsoh)-np.min(cellsoh)
+                if not 'C204' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                    if soh<self.param.SohLow:   #soh过低故障进入
+                        time=self.bmstime[0]
+                        code='C204'
+                        faultlv=2
+                        faultinfo='电池包容量过低:电芯{}'.format(cellsoh_lowindex)
+                        faultadvice='检修电池,更换容量过低的电芯或模组'
+                        self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                    else:
+                        pass
+                else:
+                    if soh>self.param.SohLow+2:   #soh过低故障恢复
+                        time=self.bmstime[0]
+                        self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C204'].index, 'end_time'] = time
+                    else:
+                        pass
+
+                if not 'C205' in list(self.df_diag_ram['code']):  #当前故障中没有该故障,则判断是否发生该故障
+                    if cellsoh_diff>self.param.SohDiff:
+                        time=self.bmstime[0]
+                        code='C205'
+                        faultlv=2
+                        faultinfo='电池包容量一致性差:电芯{}'.format(cellsoh_lowindex)
+                        faultadvice='检修电池,更换容量过低的电芯或模组'
+                        self.df_diag_ram.loc[len(self.df_diag_ram)]=[time, end_time, self.sn, code, faultlv, faultinfo, faultadvice]
+                    else:
+                        pass
+                else:
+                    if cellsoh_diff<self.param.SohDiff-2:
+                        time=self.bmstime[0]
+                        self.df_diag_ram.loc[self.df_diag_ram[self.df_diag_ram['code']=='C205'].index, 'end_time'] = time
+                    else:
+                        pass
+            else:
+                pass
+        else:
+            cellsoh_diff=5
+        
+        #ram更新.......................................................................
+        df_bms_ram=pd.DataFrame(columns=['time', 'sn', 'packvolt', 'cellvolt', 'celltemp'])
+        df_bms_ram.loc[0]=[self.bmstime[0], self.sn, packvolt2, cellvolt2, celltemp2]
+
+        return self.df_diag_ram, df_bms_ram
+

+ 164 - 0
LIB/MIDDLE/CellStateEstimation/BatDiag/main.py

@@ -0,0 +1,164 @@
+import CBMSBatDiag
+import pymysql
+import datetime
+import pandas as pd
+from LIB.BACKEND import DBManager
+from sqlalchemy import create_engine
+from urllib import parse
+import datetime, time
+from apscheduler.schedulers.blocking import BlockingScheduler
+from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import DBDownload
+from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import log
+
+#...................................电池包电芯安全诊断函数......................................................................................................................
+def diag_cal():
+    global SNnums, df_bms_ram
+
+    start=time.time()
+    now_time=datetime.datetime.now()
+    start_time=now_time-datetime.timedelta(seconds=310)
+    start_time=start_time.strftime('%Y-%m-%d %H:%M:%S')
+    end_time=now_time.strftime('%Y-%m-%d %H:%M:%S')
+
+    #数据库配置
+    host='rm-bp10j10qy42bzy0q77o.mysql.rds.aliyuncs.com'
+    port=3306
+    db='safety_platform'
+    user='qx_read'
+    password='Qx@123456'
+
+    #读取故障结果库中当前故障......................................................
+    param='start_time,end_time,product_id,code,level,info,advice'
+    tablename='all_fault_info_copy'
+    mysql = pymysql.connect (host=host, user=user, password=password, port=port, database=db)
+    cursor = mysql.cursor()
+    sql =  "select %s from %s where end_time='0000-00-00 00:00:00'" %(param,tablename)
+    cursor.execute(sql)
+    res = cursor.fetchall()
+    df_diag_ram= pd.DataFrame(res,columns=param.split(','))
+    
+
+    db_res_engine = create_engine(
+        "mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8".format(
+            user, parse.quote_plus(password), host, port, db
+        ))
+
+    mylog=log.Mylog('log_diag.txt','error')
+    mylog.logcfg()
+
+    for sn in SNnums:
+        try:
+            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) or ('UD' in sn): 
+                celltype=4 #CATL 50ah三元电芯
+            else:
+                print('SN:{},未找到对应电池类型!!!'.format(sn))
+                continue
+                # sys.exit()
+
+            #读取原始数据库数据........................................................................................................................................................
+            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']
+
+            #读取结果数据库数据........................................................................................................................................................
+            db='qx_cas'
+            mode=1
+            tablename1='cellstateestimation_soh'
+            tablename2='cellstateestimation_uniform_socvoltdiff'
+            # tablename3='cellstateestimation_soc'
+            DBRead=DBDownload.DBDownload(host, port, db, user, password,mode)
+            with DBRead as DBRead:
+                df_soh=DBRead.getdata('time_st,sn,soh,cellsoh', tablename=tablename1, sn=sn, timename='time_sp', st=start_time, sp=end_time)
+                df_uniform=DBRead.getdata('time,sn,cellsoc_diff,cellmin_num,cellmax_num', tablename=tablename2, sn=sn, timename='time', st=start_time, sp=end_time)
+                # df_soc=DBRead.getdata('time','sn','packsoc', tablename=tablename3, sn=sn)
+
+            #电池诊断................................................................................................................................................................
+            if not df_bms.empty:
+                df_diag_ram_sn=df_diag_ram[df_diag_ram['product_id']==sn]
+                df_diag_ram_sn.reset_index(inplace=True,drop=True)
+                df_bms_ram_sn=df_bms_ram[df_bms_ram['sn']==sn]
+                df_bms_ram_sn.reset_index(inplace=True,drop=True)
+                
+                df_bms=df_bms.dropna(axis=0,subset=['总电流[A]','SOH[%]','SOC[%]','总电压[V]']) #去除有空值的行
+                df_bms.reset_index(inplace=True,drop=True)     #重置索引
+
+                batquality=CBMSBatDiag.BatDiag(sn,celltype,df_bms,df_diag_ram_sn,df_bms_ram_sn,df_soh,df_uniform)
+                df_diag_res, df_bms_res=batquality.diag()   #获取电池故障结果和电池评分结果
+
+                #更新bms的ram数据
+                sn_index=df_bms_ram.loc[df_bms_ram['sn']==sn].index
+                df_bms_ram=df_bms_ram.drop(index=sn_index)
+                df_bms_ram=df_bms_ram.append(df_bms_res)
+
+                #历史故障筛选并更改数据库故障结束时间.........................................................
+                if not df_diag_res.empty:
+                    df_diag_new = pd.concat([df_diag_res,df_diag_ram_sn,df_diag_ram_sn]).drop_duplicates(subset=['start_time','code'],keep=False)#此次判断中新增故障
+                    df_diag_new.reset_index(inplace=True,drop=True)  #重置索引
+                    df_diag_end=pd.concat([df_diag_res,df_diag_new,df_diag_new]).drop_duplicates(subset=['start_time','code'],keep=False)#此次判断中新增故障
+                    df_diag_end=df_diag_end[df_diag_end['end_time'] != '0000-00-00 00:00:00']
+                    df_diag_end.reset_index(inplace=True,drop=True)  #重置索引
+
+                    if not df_diag_end.empty:   #变为历史故障更改数据库
+                        for j in range(len(df_diag_end)):
+                            cursor.execute('''
+                                        update all_fault_info_copy set update_time='{}',end_time='{}', Batpos={} where product_id='{}' and end_time='0000-00-00 00:00:00' and code='{}'
+                                        '''.format(datetime.datetime.now(), df_diag_end.loc[j,'end_time'], 1 ,sn, df_diag_end.loc[j,'code']))
+                            mysql.commit()
+
+                    #新增故障筛选并存入数据库.....................................................................
+                    if not df_diag_new.empty:  #新增写入数据库
+                        df_diag_new.to_sql("all_fault_info_copy",con=db_res_engine, if_exists="append",index=False)
+
+            end=time.time()
+            print(end-start)  
+            
+        except Exception as e:
+            print(repr(e))
+            mylog.logopt(e)
+
+    cursor.close()
+    mysql.close()
+
+#...............................................主函数起定时作用.......................................................................................................................
+if __name__ == "__main__":
+    
+    excelpath=r'D:\Platform\platform_python\data_analyze_platform\USER\spf\01qixiang\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()
+    SNnums=SNnums_L7255 + SNnums_C7255 + SNnums_U7255 + SNnums_6040 + SNnums_4840 + SNnums_6060
+    
+    mylog=log.Mylog('log_diag.txt','error')
+    mylog.logcfg()
+
+    #参数初始化
+    df_bms_ram=pd.DataFrame(columns=['time', 'sn', 'packvolt', 'cellvolt', 'celltemp'])
+
+    diag_cal()
+    #定时任务.......................................................................................................................................................................
+    scheduler = BlockingScheduler()
+    scheduler.add_job(diag_cal, 'interval', seconds=300)
+
+    try:  
+        scheduler.start()
+    except Exception as e:
+        scheduler.shutdown()
+        print(repr(e))
+        mylog.logopt(e)

+ 7 - 4
LIB/MIDDLE/CellStateEstimation/BatSafetyAlarm/V1_0_1/CBMSSafetyAlarm.py

@@ -110,7 +110,10 @@ class SafetyAlarm:
                     
                     #温升判断.............................................................................................................................
                     delttime=(time2-time1).total_seconds()
-                    celltemp_rate=(max(temp2-temp1)*60)/delttime    #计算最大温升速率
+                    if delttime>1:
+                        celltemp_rate=(max(temp2-temp1)*60)/delttime    #计算最大温升速率
+                    else:
+                        celltemp_rate=0
                     if celltemp_rate>self.param.TrwTempRate and self.param.CellTempLwLmt<min(temp1) and max(temp1)<self.param.CellTempUpLmt:
                         celltemprise=celltemprise+1
                     else:
@@ -215,11 +218,11 @@ class SafetyAlarm:
             trw_array=np.array([trwtemp, trwcellvolt, trwpackvolt])
 
             if np.sum(trw_array)>3.5 and np.sum(trw_array>0.5)>1.5:
-                fltcode=119
+                fltcode='C599'
                 df_res.loc[0]=[self.bmstime[len(self.bmstime)-1], end_time, self.sn, fltcode, 5, '电池发生热失控', '联系用户立即远离电池,并通知技术人员介入']
                 df_ram_alarm=pd.DataFrame(columns=['sn','time','safetywarning1','safetywarning2'])
             elif safetywarning1>2.5 and np.sum(trw_array)>1.5 and np.sum(trw_array>0.5)>1.5:
-                fltcode=119
+                fltcode='C599'
                 df_res.loc[0]=[self.bmstime[len(self.bmstime)-1], end_time, self.sn, fltcode, 5, '电池发生热失控', '联系用户立即远离电池,并通知技术人员介入']
                 df_ram_alarm=pd.DataFrame(columns=['sn','time','safetywarning1','safetywarning2'])
             else:
@@ -248,7 +251,7 @@ class SafetyAlarm:
             df_ram_alarm=self.df_ram_alarm
             df_ram_bms=self.df_ram_bms
             if (safetywarning1>2.5 or safetywarning2>2.5) and (time_now-df_ram_alarm.iloc[-1]['time']).total_seconds()>120:
-                fltcode=119
+                fltcode='C599'
                 time_now=time_now.strftime('%Y-%m-%d %H:%M:%S')
                 time_now=datetime.datetime.strptime(time_now,'%Y-%m-%d %H:%M:%S')
                 df_res.loc[0]=[time_now, end_time, self.sn, fltcode, 5, '电池发生热失控', '联系用户立即远离电池,并通知技术人员介入']

+ 1 - 1
LIB/MIDDLE/CellStateEstimation/Common/V1_0_1/log.py

@@ -17,7 +17,7 @@ class Mylog:
                 Level=logging.WARNING
             else:
                 Level=logging.ERROR
-        logging.basicConfig(filename=r'D:\Platform\platform_python\data_analyze_platform\USER\spf\101log\\'+self.name, level=Level,format='%(asctime)s - %(levelname)s - %(message)s')
+        logging.basicConfig(filename=r'D:\Develop\User\Songpengfei\data_analyze_platform\WORK\101log\\'+self.name, level=Level,format='%(asctime)s - %(levelname)s - %(message)s')
 
 
     def logopt(self,*info):

+ 1 - 1
LIB/MIDDLE/SaftyCenter/DataDiag_Static/SC_BMSUploadError.py

@@ -53,7 +53,7 @@ class BMSReportError:
                                 newCode.append(nCode)
                                 code=code-nCode
                         elif code>0:
-                            newCode=newCode.append(code)
+                            newCode.append(code)
                         else:
                             newCode=[]
                     else:

+ 4 - 4
LIB/MIDDLE/SaftyCenter/DataDiag_Static/SC_CtrlSafty.py

@@ -53,19 +53,19 @@ class CtrlSafty:
         OtherTempMax=OtherTempMax[OtherTempMax[OtherTempNum]<(param.OtherOTlmt+5)].dropna(axis=0,how='all')
         if len(CellTempMax) and len(OtherTempMax):
             QuitErrCount[57]=0
-            if not 57 in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
-                df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_info.loc[len(bms_info)-1,'时间戳'],'0000-00-00 00:00:00',sn,57,4,'电芯温度高','立即联系用户确认电池状态']
+            if not 'C357' in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
+                df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_info.loc[len(bms_info)-1,'时间戳'],'0000-00-00 00:00:00',sn,'C357',3,'电芯温度高','立即联系用户确认电池状态']
                 ErrorFlg=1            
             else:#如果故障发生当前故障中有该故障,则不进行操作
                 pass
         else:
-            if 57 in df_Diag_Ram['code'].values.tolist():
+            if 'C357' in df_Diag_Ram['code'].values.tolist():
                 QuitErrCount[57]=QuitErrCount[57]+1
                 if QuitErrCount[57]>3:
                     QuitErrCount[57]=4
                     end_time=datetime.datetime.now()
                     end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
-                    df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==57].index,['end_time']]=end_time
+                    df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']=='C357'].index,['end_time']]=end_time
                 else:
                     pass
             else:

+ 50 - 50
LIB/MIDDLE/SaftyCenter/DataDiag_Static/SC_SamplingSafty.py

@@ -67,38 +67,38 @@ class SamplingSafty:
         if len(InVMaxBatNo):
             if len(InVMinBatNo):
                 QuitErrCount[10]=0
-                if not 10 in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
-                    df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,10,2,'电池电压采样断线,最高电压为{:.2f}V,电池编号为{},最低电压为{:.2f}V,电池编号为{}'.format(MaxVolt,InVMaxBatNo.values,MinVolt,InVMinBatNo.values),'返厂维修']
+                if not 'C310' in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
+                    df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C310',3,'电池电压采样断线,最高电压为{:.2f}V,电池编号为{},最低电压为{:.2f}V,电池编号为{}'.format(MaxVolt,InVMaxBatNo.values,MinVolt,InVMinBatNo.values),'返厂维修']
                     ErrorFlg=1  
                 else:#如果故障发生当前故障中有该故障,则不进行操作
                     pass                 
             else:#如果没有故障,并且当前故障表中有该故障,则判断故障是否结束
                 QuitErrCount[50]=0
-                if 10 in df_Diag_Ram['code'].values.tolist():
+                if 'C310' in df_Diag_Ram['code'].values.tolist():
                     QuitErrCount[10]=QuitErrCount[10]+1
                     if QuitErrCount[10]>3:
                         QuitErrCount[10]=4
                         end_time=datetime.datetime.now()
                         end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
-                        df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==10].index,['end_time']]=end_time
+                        df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']=='C310'].index,['end_time']]=end_time
                     else:
                         pass
                 else:
                     pass
-                if not 50 in df_Diag_Ram['code'].values.tolist():
-                    df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,50,2,str(InVMaxBatNo.values)+'号电压大于{:.2f}V,采样无效'.format(param.CellOVlmt),'返厂维修']
+                if not 'C350' in df_Diag_Ram['code'].values.tolist():
+                    df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C350',3,str(InVMaxBatNo.values)+'号电压大于{:.2f}V,采样无效'.format(param.CellOVlmt),'返厂维修']
                     ErrorFlg=1
                 else:
                     pass
         elif len(InVMinBatNo):
             QuitErrCount[50]=0
-            if not 50 in df_Diag_Ram['code'].values.tolist():
-                df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,50,2,str(InVMinBatNo.values)+'号电压小于{:.2f}V,采样无效'.format(param.CellUVlmt),'返厂维修']
+            if not 'C350' in df_Diag_Ram['code'].values.tolist():
+                df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C350',3,str(InVMinBatNo.values)+'号电压小于{:.2f}V,采样无效'.format(param.CellUVlmt),'返厂维修']
                 ErrorFlg=1
             else:
                 pass
         else:
-            if 50 in df_Diag_Ram['code'].values.tolist():
+            if 'C350' in df_Diag_Ram['code'].values.tolist():
                 QuitErrCount[50]=QuitErrCount[50]+1
                 if QuitErrCount[50]>3:
                     QuitErrCount[50]=4
@@ -113,25 +113,25 @@ class SamplingSafty:
         if ErrorFlg==0:
             AvgVolGap=CellVoltage-AvgVol
             OutlierVolNo=AvgVolGap[AvgVolGap>=param.AvgVolGap].index
-            if len(OutlierVolNo) and abs(bms_infoN['总电流[A]'])<2 and not 51 in df_Diag_Ram['code']:
+            if len(OutlierVolNo) and abs(bms_infoN['总电流[A]'])<2 and not 'C251' in df_Diag_Ram['code']:
                 VolCount=VolCount+1
                 QuitErrCount[51]=0
                 if VolCount>10:
                     VolCount=11
-                    if not 51 in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
-                        df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,51,2,str(OutlierVolNo.values)+'号电池电压离群','技术介入诊断']
+                    if not 'C251' in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
+                        df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C251',2,str(OutlierVolNo.values)+'号电池电压离群','技术介入诊断']
                         ErrorFlg=1            
                     else:#如果故障发生当前故障中有该故障,则不进行操作
                         pass                
             else:
                 VolCount=0
-                if 51 in df_Diag_Ram['code'].values.tolist():
+                if 'C251' in df_Diag_Ram['code'].values.tolist():
                     QuitErrCount[51]=QuitErrCount[51]+1
                     if QuitErrCount[51]>3:
                         QuitErrCount[51]=4
                         end_time=datetime.datetime.now()
                         end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
-                        df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==51].index,['end_time']]=end_time                
+                        df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']=='C251'].index,['end_time']]=end_time                
                     else:
                         pass
                 else:
@@ -176,44 +176,44 @@ class SamplingSafty:
         if len(InVMaxTempBatNo):
             if len(InVMinTempBatNo):
                 QuitErrCount[53]=0
-                if not 53 in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
-                    df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,53,2,'电池温度采样断线,最高温度为{}℃,电池编号为{},最低温度为{}℃,电池编号为{}'.format(maxCellTemp,InVMaxTempBatNo.values,minCellTemp,InVMinTempBatNo.values),'返厂维修']
+                if not 'C353' in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
+                    df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C353',3,'电池温度采样断线,最高温度为{}℃,电池编号为{},最低温度为{}℃,电池编号为{}'.format(maxCellTemp,InVMaxTempBatNo.values,minCellTemp,InVMinTempBatNo.values),'返厂维修']
                     ErrorFlg=1 
                 else:#如果故障发生当前故障中有该故障,则不进行操作
                     pass                 
             else:#如果没有故障,并且当前故障表中有该故障,则判断故障是否结束
                 QuitErrCount[2]=0
-                if 53 in df_Diag_Ram['code'].values.tolist():
+                if 'C353' in df_Diag_Ram['code'].values.tolist():
                     QuitErrCount[53]=QuitErrCount[53]+1
                     if QuitErrCount[53]>3:
                         QuitErrCount[53]=4
                         end_time=datetime.datetime.now()
                         end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
-                        df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==53].index,['end_time']]=end_time
+                        df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']=='C353'].index,['end_time']]=end_time
                     else:
                         pass
                 else:
                     pass
-                if not 2 in df_Diag_Ram['code'].values.tolist():
-                    df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,2,2,str(InVMaxTempBatNo.values)+'号温度大于{}℃,采样无效'.format(param.PackOTlmt),'联系用户核实电池温度情况,并返厂维修']
+                if not 'C302' in df_Diag_Ram['code'].values.tolist():
+                    df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C302',3,str(InVMaxTempBatNo.values)+'号温度大于{}℃,采样无效'.format(param.PackOTlmt),'联系用户核实电池温度情况,并返厂维修']
                     ErrorFlg=1
                 else:
                     pass
         elif len(InVMinTempBatNo):
             QuitErrCount[2]=0
-            if not 2 in df_Diag_Ram['code'].values.tolist():
-                df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,2,2,str(InVMinTempBatNo.values)+'号温度小于{}℃,采样无效'.format(param.PackUTlmt),'返厂维修']
+            if not 'C302' in df_Diag_Ram['code'].values.tolist():
+                df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C302',3,str(InVMinTempBatNo.values)+'号温度小于{}℃,采样无效'.format(param.PackUTlmt),'返厂维修']
                 ErrorFlg=1
             else:
                 pass
         else:
-            if 2 in df_Diag_Ram['code'].values.tolist():
+            if 'C302' in df_Diag_Ram['code'].values.tolist():
                 QuitErrCount[2]=QuitErrCount[2]+1
                 if QuitErrCount[2]>3:
                     QuitErrCount[2]=4
                     end_time=datetime.datetime.now()
                     end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
-                    df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==2].index,['end_time']]=end_time                   
+                    df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']=='C302'].index,['end_time']]=end_time                   
                 else:
                     pass
             else:
@@ -223,19 +223,19 @@ class SamplingSafty:
             OutlierTempNo=AvgCellTempGap[AvgCellTempGap>=param.AvgCellTempGap].index
             if len(OutlierTempNo):
                 QuitErrCount[8]=0
-                if not 8 in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
-                    df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,8,2,str(OutlierTempNo.values)+'号电池异常温度离群','技术介入诊断']
+                if not 'C108' in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
+                    df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C108',1,str(OutlierTempNo.values)+'号电池异常温度离群','技术介入诊断']
                     ErrorFlg=1            
                 else:#如果故障发生当前故障中有该故障,则不进行操作
                     pass
             else:
-                if 8 in df_Diag_Ram['code'].values.tolist():
+                if 'C108' in df_Diag_Ram['code'].values.tolist():
                     QuitErrCount[8]=QuitErrCount[8]+1
                     if QuitErrCount[8]>3:
                         QuitErrCount[8]=4
                         end_time=datetime.datetime.now()
                         end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
-                        df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==8].index,['end_time']]=end_time
+                        df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']=='C108'].index,['end_time']]=end_time
                     else:
                         pass
                 else:
@@ -263,44 +263,44 @@ class SamplingSafty:
             if len(InVMaxOtherTempBatNo):
                 if len(InVMinOtherTempBatNo):
                     QuitErrCount[54]=0
-                    if not 54 in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
-                        df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,54,2,'其他温度采样断线,最高温度为{}℃,传感器编号为{},最低温度为{}℃,传感器编号为{}'.format(maxOtherTemp,InVMaxOtherTempBatNo.values,minOtherTemp,InVMinOtherTempBatNo.values),'返厂维修']
+                    if not 'C354' in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
+                        df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C354',3,'其他温度采样断线,最高温度为{}℃,传感器编号为{},最低温度为{}℃,传感器编号为{}'.format(maxOtherTemp,InVMaxOtherTempBatNo.values,minOtherTemp,InVMinOtherTempBatNo.values),'返厂维修']
                         ErrorFlg=1 
                     else:#如果故障发生当前故障中有该故障,则不进行操作
                         pass                 
                 else:#如果没有故障,并且当前故障表中有该故障,则判断故障是否结束
                     QuitErrCount[55]=0
-                    if 54 in df_Diag_Ram['code'].values.tolist():
+                    if 'C354' in df_Diag_Ram['code'].values.tolist():
                         QuitErrCount[54]=QuitErrCount[54]+1
                         if QuitErrCount[54]>3:
                             QuitErrCount[54]=4
                             end_time=datetime.datetime.now()
                             end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
-                            df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==54].index,['end_time']]=end_time
+                            df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']=='C354'].index,['end_time']]=end_time
                         else:
                             pass
                     else:
                         pass
-                    if not 55 in df_Diag_Ram['code'].values.tolist():
-                        df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,55,2,'传感器温度大于{}℃,采样无效'.format(param.OtherOTlmt),'联系用户核实电池温度情况,并返厂维修']
+                    if not 'C355' in df_Diag_Ram['code'].values.tolist():
+                        df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C355',3,'传感器温度大于{}℃,采样无效'.format(param.OtherOTlmt),'联系用户核实电池温度情况,并返厂维修']
                         ErrorFlg=1
                     else:
                         pass
             elif len(InVMinTempBatNo):
                 QuitErrCount[55]=0
-                if not 55 in df_Diag_Ram['code'].values.tolist():
-                    df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,55,2,'传感器温度小于{}℃,采样无效'.format(param.OtherUTlmt),'返厂维修']
+                if not 'C355' in df_Diag_Ram['code'].values.tolist():
+                    df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C355',3,'传感器温度小于{}℃,采样无效'.format(param.OtherUTlmt),'返厂维修']
                     ErrorFlg=1
                 else:
                     pass
             else:
-                if 55 in df_Diag_Ram['code'].values.tolist():
+                if 'C355' in df_Diag_Ram['code'].values.tolist():
                     QuitErrCount[55]=QuitErrCount[55]+1
                     if QuitErrCount[55]>3:
                         QuitErrCount[55]=4
                         end_time=datetime.datetime.now()
                         end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
-                        df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==55].index,['end_time']]=end_time                   
+                        df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']=='C355'].index,['end_time']]=end_time                   
                     else:
                         pass
                 else:
@@ -310,19 +310,19 @@ class SamplingSafty:
                 OutlierOtherTempNo=AvgOtherTempGap[AvgOtherTempGap>=param.AvgOtherTempGap].index
                 if len(OutlierOtherTempNo):
                     QuitErrCount[56]=0
-                    if not 56 in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
-                        df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,56,2,'传感器温度异常离群','技术介入诊断']
+                    if not 'C156' in df_Diag_Ram['code'].values.tolist():#如果故障发生当前故障中没有该故障,则压入该故障
+                        df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C156',1,'传感器温度异常离群','技术介入诊断']
                         ErrorFlg=1            
                     else:#如果故障发生当前故障中有该故障,则不进行操作
                         pass
                 else:
-                    if 56 in df_Diag_Ram['code'].values.tolist():
+                    if 'C156' in df_Diag_Ram['code'].values.tolist():
                         QuitErrCount[56]=QuitErrCount[56]+1
                         if QuitErrCount[56]>3:
                             QuitErrCount[56]=4
                             end_time=datetime.datetime.now()
                             end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
-                            df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==56].index,['end_time']]=end_time
+                            df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']=='C156'].index,['end_time']]=end_time
                         else:
                             pass
                     else:
@@ -330,31 +330,31 @@ class SamplingSafty:
 
                 if (maxOtherTemp-maxCellTemp)>param.AvgOtherTempGap and  maxOtherTemp<param.OtherOTlmt and maxCellTemp<param.PackOTlmt:
                     QuitErrCount[56]=0
-                    if not 56 in df_Diag_Ram['code'].values.tolist():
-                        df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,56,2,'传感器温度异常离群','技术立即介入诊断']
+                    if not 'C156' in df_Diag_Ram['code'].values.tolist():
+                        df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C156',1,'传感器温度异常离群','技术立即介入诊断']
                         ErrorFlg=1
                 else:
-                    if 56 in df_Diag_Ram['code'].values.tolist():
+                    if 'C156' in df_Diag_Ram['code'].values.tolist():
                             QuitErrCount[56]=QuitErrCount[56]+1
                             if QuitErrCount[56]>3:
                                 QuitErrCount[56]=4
                                 end_time=datetime.datetime.now()
                                 end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
-                                df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==56].index,['end_time']]=end_time
+                                df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']=='C156'].index,['end_time']]=end_time
                                 
                 if (maxCellTemp-maxOtherTemp)>param.AvgOtherTempGap and  maxOtherTemp<param.OtherOTlmt and maxCellTemp<param.PackOTlmt and not 8 in df_Diag_Ram['code']:
                     QuitErrCount[8]=0
-                    if not 8 in df_Diag_Ram['code'].values.tolist():
-                        df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,8,2,str(OutlierTempNo.values)+'号电芯温度异常离群','技术立即介入诊断']
+                    if not 'C108' in df_Diag_Ram['code'].values.tolist():
+                        df_Diag_Ram.loc[len(df_Diag_Ram)]=[bms_infoN['时间戳'],'0000-00-00 00:00:00',sn,'C108',1,str(OutlierTempNo.values)+'号电芯温度异常离群','技术立即介入诊断']
                         
                         ErrorFlg=1
                 else:
-                    if 8 in df_Diag_Ram['code'].values.tolist():
+                    if 'C108' in df_Diag_Ram['code'].values.tolist():
                             QuitErrCount[8]=QuitErrCount[8]+1
                             if QuitErrCount[8]>3:
                                 QuitErrCount[8]=4
                                 end_time=datetime.datetime.now()
                                 end_time=end_time.strftime('%Y-%m-%d %H:%M:%S')
-                                df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']==8].index,['end_time']]=end_time              
+                                df_Diag_Ram.loc[df_Diag_Ram[df_Diag_Ram['code']=='C108'].index,['end_time']]=end_time              
 
         return df_Diag_Ram

+ 5 - 4
LIB/MIDDLE/SaftyCenter/DataDiag_Static/main.py

@@ -121,14 +121,15 @@ def diag_cal():
         if not df_bms.empty:
             df_Diag_Batdiag_update_xq=SamplingSafty.main(sn,param,df_bms,CellFltInfo)#采样安全   
             df_Diag_Batdiag_update_xq2=CtrlSafty.main(sn,param,df_bms,df_Diag_Batdiag_update_xq)#控制安全
-            batDiag=CBMSBatDiag.BatDiag(sn,celltype,df_bms, df_soh, df_uniform, df_Diag_Batdiag_update_xq2)#鹏飞计算
-            df_Diag_Batdiag_update2=batDiag.diag()
-            df_Diag_Batdiag_update=BMSReportError.main(sn,df_bms,df_Diag_Batdiag_update2,FactoryType,errorcode_map)
+            #batDiag=CBMSBatDiag.BatDiag(sn,celltype,df_bms, df_soh, df_uniform, df_Diag_Batdiag_update_xq2)#鹏飞计算
+            #df_Diag_Batdiag_update2=batDiag.diag()
+            #df_Diag_Batdiag_update=BMSReportError.main(sn,df_bms,df_Diag_Batdiag_update2,FactoryType,errorcode_map)
+            df_Diag_Batdiag_update=BMSReportError.main(sn,df_bms,df_Diag_Batdiag_update_xq2,FactoryType,errorcode_map)
             # df_Diag_Batdiag_update=BatDiag.diag() 
         else:
             df_Diag_Batdiag_update_xq=DataFrame(columns=['start_time','end_time','product_id','code','level','info','advice','Batpos'])
             df_Diag_Batdiag_update_xq2=DataFrame(columns=['start_time','end_time','product_id','code','level','info','advice','Batpos'])
-            df_Diag_Batdiag_update2=DataFrame(columns=['start_time','end_time','product_id','code','level','info','advice','Batpos'])
+            #df_Diag_Batdiag_update2=DataFrame(columns=['start_time','end_time','product_id','code','level','info','advice','Batpos'])
             df_Diag_Batdiag_update=DataFrame(columns=['start_time','end_time','product_id','code','level','info','advice','Batpos'])
         df_Diag_Ram_add,df_Diag_Ram_Update=DiagDataMerge.DetaMerge(df_Diag_Ram_sn,df_Diag_Batdiag_update,df_OprtnSta,df_Diag_Ram_sn_else)
     task_on=0        

BIN
all_statistic_info.xlsx


+ 131 - 112
demo.ipynb

@@ -2,164 +2,183 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 2,
-   "source": [
-    "# 获取数据\r\n",
-    "import sys\r\n",
-    "from LIB.BACKEND import DBManager\r\n",
-    "\r\n",
-    "sn = \"PK10001A326000123\"\r\n",
-    "st = '2021-07-06 00:00:00'\r\n",
-    "et = '2021-07-07 20:00:00'\r\n",
-    "\r\n",
-    "dbManager = DBManager.DBManager()\r\n",
-    "df_data = dbManager.get_data(sn=sn, start_time=st, end_time=et, data_groups=['bms', 'gps', 'accum', 'system'])\r\n",
-    "# \r\n",
-    "df_bms = df_data['bms']\r\n",
-    "df_gps = df_data['gps']\r\n",
-    "df_accum = df_data['accum']\r\n",
-    "df_system = df_data['system']"
-   ],
+   "execution_count": 6,
+   "metadata": {},
    "outputs": [
     {
-     "output_type": "stream",
      "name": "stdout",
+     "output_type": "stream",
      "text": [
-      "### start to get data PK10001A326000123 from 2021-07-06 00:00:00 to 2021-07-07 20:00:00\n",
-      "# get data from 2021-07-06 00:00:00 to 2021-07-07 00:00:00......... \n",
-      "Server Error, retry 1...... \n",
-      "# get data from 2021-07-07 00:00:00 to 2021-07-07 20:00:00......... \n",
-      "all data-getting done, bms_count is 0, gps_count is 0, system_count is 0, accum_count is 0 \n",
+      "### start to get data PK50001A100000100 from 2021-02-10 22:54:36 to 2021-02-20 22:54:36\n",
+      "# get data from 2021-02-19 22:54:36 to 2021-02-20 22:54:36......... \n",
+      "all data-getting done, bms_count is 19444, gps_count is 5960, system_count is 566, accum_count is 2391 \n",
       "\n"
      ]
     }
    ],
-   "metadata": {}
+   "source": [
+    "# 获取数据\n",
+    "import sys\n",
+    "from LIB.BACKEND import DBManager\n",
+    "\n",
+    "sn = \"PK50001A100000100\"\n",
+    "st = '2021-02-10 22:54:36'\n",
+    "et = '2021-02-20 22:54:36'\n",
+    "\n",
+    "dbManager = DBManager.DBManager()\n",
+    "df_data = dbManager.get_data(sn=sn, start_time=st, end_time=et, data_groups=['bms', 'gps', 'accum', 'system'])\n",
+    "# \n",
+    "df_bms = df_data['bms']\n",
+    "df_gps = df_data['gps']\n",
+    "df_accum = df_data['accum']\n",
+    "df_system = df_data['system']"
+   ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "source": [
-    "# 下载数据 \r\n",
-    "import sys\r\n",
-    "from LIB.BACKEND import Tools\r\n",
-    "\r\n",
-    "tools = Tools.Tools()\r\n",
-    "write_path = r''\r\n",
-    "sn = \"PK50001A100000680\"\r\n",
-    "\r\n",
-    "st = '2021-07-06 00:00:00'\r\n",
-    "et = '2021-07-07 20:00:00'\r\n",
-    "tools.data_download(write_path=write_path, sn=sn, start_time=st, end_time=et, data_groups=['bms'])"
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[1;31mPython 3.8.12 64-bit ('algo_dev_env': conda) 需要安装 ipykernel。\n",
+      "Run the following command to install 'ipykernel' into the Python environment. \n",
+      "Command: 'conda install -n algo_dev_env ipykernel --update-deps --force-reinstall'"
+     ]
+    }
    ],
+   "source": [
+    "import plotly.io as pio\n",
+    "pio.renderers.default = 'iframe_connected'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
    "outputs": [],
-   "metadata": {}
+   "source": [
+    "# 下载数据 \n",
+    "import sys\n",
+    "from LIB.BACKEND import Tools\n",
+    "\n",
+    "tools = Tools.Tools()\n",
+    "write_path = r''\n",
+    "sn = \"PK50001A100000680\"\n",
+    "\n",
+    "st = '2021-07-06 00:00:00'\n",
+    "et = '2021-07-07 20:00:00'\n",
+    "tools.data_download(write_path=write_path, sn=sn, start_time=st, end_time=et, data_groups=['bms'])"
+   ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
+   "metadata": {},
+   "outputs": [],
    "source": [
-    "# 数据预处理\r\n",
-    "import sys\r\n",
-    "from LIB.BACKEND import DataPreProcess\r\n",
-    "\r\n",
-    "dataPrePro = DataPreProcess.DataPreProcess()\r\n",
-    "# 时间完全相同的数据仅保留一行\r\n",
-    "df_bms_pro, df_gps_pro = dataPrePro.time_filter(df_bms, df_gps)\r\n",
-    "\r\n",
-    "# bms数据按照电流和状态分段, 然后在状态分段内部,根据时间跳变继续分段(解决段内数据丢失)\r\n",
-    "df_bms_pro = dataPrePro.data_split_by_status(df_bms_pro)\r\n",
-    "df_bms_pro = dataPrePro.data_split_by_time(df_bms_pro)\r\n",
-    "\r\n",
-    "# bms数据将两次充电间的状态合并\r\n",
-    "df_bms_pro = dataPrePro.combine_drive_stand(df_bms_pro)\r\n",
-    "# bms 数据计算行车和充电开始前后的静置时间\r\n",
-    "df_bms_pro = dataPrePro.cal_stand_time(df_bms_pro)\r\n",
-    "# gps 数据可靠性判断, 并增加里程和速度至gps数据(根据未合并的数据段判断)\r\n",
-    "df_bms_pro, df_gps_pro, res_record= dataPrePro.gps_data_judge(df_bms_pro, df_gps_pro)\r\n",
-    "# gps 数据可靠性判断, 并增加里程和速度至gps数据(根据已合并的数据段判断)\r\n",
+    "# 数据预处理\n",
+    "import sys\n",
+    "from LIB.BACKEND import DataPreProcess\n",
+    "\n",
+    "dataPrePro = DataPreProcess.DataPreProcess()\n",
+    "# 时间完全相同的数据仅保留一行\n",
+    "df_bms_pro, df_gps_pro = dataPrePro.time_filter(df_bms, df_gps)\n",
+    "\n",
+    "# bms数据按照电流和状态分段, 然后在状态分段内部,根据时间跳变继续分段(解决段内数据丢失)\n",
+    "df_bms_pro = dataPrePro.data_split_by_status(df_bms_pro)\n",
+    "df_bms_pro = dataPrePro.data_split_by_time(df_bms_pro)\n",
+    "\n",
+    "# bms数据将两次充电间的状态合并\n",
+    "df_bms_pro = dataPrePro.combine_drive_stand(df_bms_pro)\n",
+    "# bms 数据计算行车和充电开始前后的静置时间\n",
+    "df_bms_pro = dataPrePro.cal_stand_time(df_bms_pro)\n",
+    "# gps 数据可靠性判断, 并增加里程和速度至gps数据(根据未合并的数据段判断)\n",
+    "df_bms_pro, df_gps_pro, res_record= dataPrePro.gps_data_judge(df_bms_pro, df_gps_pro)\n",
+    "# gps 数据可靠性判断, 并增加里程和速度至gps数据(根据已合并的数据段判断)\n",
     "df_bms_pro, df_gps_pro, res_record= dataPrePro.data_gps_judge_after_combine(df_bms_pro, df_gps_pro)"
-   ],
-   "outputs": [],
-   "metadata": {}
+   ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
+   "metadata": {},
+   "outputs": [],
    "source": [
-    "# 单cycle指标统计\r\n",
-    "import sys\r\n",
-    "from LIB.BACKEND import IndexStaByOneCycle\r\n",
-    "\r\n",
-    "indexSta = IndexStaByOneCycle.IndexStaByOneCycle()\r\n",
-    "\r\n",
-    "data_number_list = sorted(list(set(df_bms[(df_bms['data_status'].isin(['drive']))]['data_split_by_status'])))\r\n",
-    "for data_number in data_number_list[:]:\r\n",
-    "    df_sel_bms = df_bms[df_bms['data_split_by_status'] == data_number]\r\n",
-    "    df_sel_bms = df_sel_bms.reset_index(drop=True)\r\n",
-    "    df_sel_gps = df_gps[(df_gps['时间戳']>df_sel_bms.loc[0,'时间戳']) & (df_gps['时间戳']<df_sel_bms.loc[len(df_sel_bms)-1,'时间戳'])]\r\n",
-    "    df_sel_gps = df_sel_gps.reset_index(drop=True)\r\n",
-    "\r\n",
-    "    print(indexSta.odo_sta(np.array(df_sel_gps['odo'])))\r\n",
-    "    print(indexSta.capacity_sta(40, np.array(df_sel_bms['SOC[%]']), np.array(df_sel_bms['SOH[%]'])))\r\n",
-    "    print(indexSta.energy_sta(40, np.array(df_sel_bms['SOC[%]']), np.array(df_sel_bms['SOH[%]']),np.array(df_sel_bms['总电压[V]'])))\r\n",
-    "    print(indexSta.acc_time_sta(np.array(df_sel_bms['时间戳'])))\r\n",
-    "    print(indexSta.mean_temp_sta(np.array(df_sel_bms['单体温度1'])))\r\n",
-    "    print(indexSta.temp_change_rate_sta(np.array(df_sel_bms['时间戳']), np.array(df_sel_bms['单体温度1'])))\r\n",
-    "    print(indexSta.dischrg_max_pwr_sta(np.array(df_sel_bms['总电压[V]']), np.array(df_sel_bms['总电流[A]'])))\r\n",
-    "    print(indexSta.chrg_max_pwr_sta(np.array(df_sel_bms['总电压[V]']), np.array(df_sel_bms['总电流[A]'])))\r\n",
-    "    print(indexSta.speed_sta(indexSta.odo_sta(np.array(df_sel_gps['odo'])), indexSta.acc_time_sta(np.array(df_sel_gps['时间戳'])), np.array(df_sel_gps['speed'])))\r\n",
+    "# 单cycle指标统计\n",
+    "import sys\n",
+    "from LIB.BACKEND import IndexStaByOneCycle\n",
+    "\n",
+    "indexSta = IndexStaByOneCycle.IndexStaByOneCycle()\n",
+    "\n",
+    "data_number_list = sorted(list(set(df_bms[(df_bms['data_status'].isin(['drive']))]['data_split_by_status'])))\n",
+    "for data_number in data_number_list[:]:\n",
+    "    df_sel_bms = df_bms[df_bms['data_split_by_status'] == data_number]\n",
+    "    df_sel_bms = df_sel_bms.reset_index(drop=True)\n",
+    "    df_sel_gps = df_gps[(df_gps['时间戳']>df_sel_bms.loc[0,'时间戳']) & (df_gps['时间戳']<df_sel_bms.loc[len(df_sel_bms)-1,'时间戳'])]\n",
+    "    df_sel_gps = df_sel_gps.reset_index(drop=True)\n",
+    "\n",
+    "    print(indexSta.odo_sta(np.array(df_sel_gps['odo'])))\n",
+    "    print(indexSta.capacity_sta(40, np.array(df_sel_bms['SOC[%]']), np.array(df_sel_bms['SOH[%]'])))\n",
+    "    print(indexSta.energy_sta(40, np.array(df_sel_bms['SOC[%]']), np.array(df_sel_bms['SOH[%]']),np.array(df_sel_bms['总电压[V]'])))\n",
+    "    print(indexSta.acc_time_sta(np.array(df_sel_bms['时间戳'])))\n",
+    "    print(indexSta.mean_temp_sta(np.array(df_sel_bms['单体温度1'])))\n",
+    "    print(indexSta.temp_change_rate_sta(np.array(df_sel_bms['时间戳']), np.array(df_sel_bms['单体温度1'])))\n",
+    "    print(indexSta.dischrg_max_pwr_sta(np.array(df_sel_bms['总电压[V]']), np.array(df_sel_bms['总电流[A]'])))\n",
+    "    print(indexSta.chrg_max_pwr_sta(np.array(df_sel_bms['总电压[V]']), np.array(df_sel_bms['总电流[A]'])))\n",
+    "    print(indexSta.speed_sta(indexSta.odo_sta(np.array(df_sel_gps['odo'])), indexSta.acc_time_sta(np.array(df_sel_gps['时间戳'])), np.array(df_sel_gps['speed'])))\n",
     "    break"
-   ],
-   "outputs": [],
-   "metadata": {}
+   ]
   },
   {
    "cell_type": "code",
    "execution_count": 2,
-   "source": [
-    "# 生成pydoc 说明文档\r\n",
-    "!python -m pydoc -w LIB\\BACKEND\\DataPreProcess.py"
-   ],
+   "metadata": {},
    "outputs": [
     {
-     "output_type": "stream",
      "name": "stdout",
+     "output_type": "stream",
      "text": [
       "problem in LIB\\BACKEND\\DataPreProcess.py - ModuleNotFoundError: No module named 'DBManager'\n"
      ]
     }
    ],
-   "metadata": {}
+   "source": [
+    "# 生成pydoc 说明文档\n",
+    "!python -m pydoc -w LIB\\BACKEND\\DataPreProcess.py"
+   ]
   },
   {
    "cell_type": "code",
    "execution_count": 1,
-   "source": [
-    "from LIB.BACKEND import DBManager, Log\r\n",
-    "log = Log.Mylog(log_name='signal_monitor', log_level = 'info')\r\n",
-    "log.set_file_hl(file_name='info.log', log_level='info')\r\n",
-    "log.set_file_hl(file_name='error.log', log_level='error')\r\n",
-    "logger = log.get_logger()\r\n"
-   ],
+   "metadata": {},
    "outputs": [],
-   "metadata": {}
+   "source": [
+    "from LIB.BACKEND import DBManager, Log\n",
+    "log = Log.Mylog(log_name='signal_monitor', log_level = 'info')\n",
+    "log.set_file_hl(file_name='info.log', log_level='info')\n",
+    "log.set_file_hl(file_name='error.log', log_level='error')\n",
+    "logger = log.get_logger()\n"
+   ]
   },
   {
    "cell_type": "code",
    "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
    "source": [
     "logger.error(\"ttt5\")"
-   ],
-   "outputs": [],
-   "metadata": {}
+   ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "source": [],
+   "metadata": {},
    "outputs": [],
-   "metadata": {}
+   "source": []
   }
  ],
  "metadata": {
@@ -167,23 +186,23 @@
    "hash": "b3ba2566441a7c06988d0923437866b63cedc61552a5af99d1f4fb67d367b25f"
   },
   "kernelspec": {
-   "name": "python3",
-   "display_name": "Python 3.8.8 64-bit ('base': conda)"
+   "display_name": "Python 3.8.8 64-bit ('base': conda)",
+   "name": "python3"
   },
   "language_info": {
-   "name": "python",
-   "version": "3.8.8",
-   "mimetype": "text/x-python",
    "codemirror_mode": {
     "name": "ipython",
     "version": 3
    },
-   "pygments_lexer": "ipython3",
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
    "nbconvert_exporter": "python",
-   "file_extension": ".py"
+   "pygments_lexer": "ipython3",
+   "version": "3.8.12"
   },
   "orig_nbformat": 4
  },
  "nbformat": 4,
  "nbformat_minor": 2
-}
+}