Browse Source

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

Eric412V 2 years ago
parent
commit
a24e0df497

+ 17 - 7
LIB/MIDDLE/Anomaly Detection/V1_0_0/anomalyPCA.py → LIB/MIDDLE/Anomaly_Detection/V1_0_0/anomalyPCA.py

@@ -16,7 +16,8 @@ def makedataset1(df_data):
         df_data=df_data[(df_data['单体电压'+str(i)]>2200) & (df_data['单体电压'+str(i)]<4800)]
     df_data=df_data[df_data['SOC[%]']>20]
     df_data['时间']=[df_data.loc[i,'时间戳'][0:15] for i in df_data.index]
-    data_set=df_data.groupby('时间').mean()
+    df_data=df_data.drop('时间戳',axis=1)
+    data_set=df_data.groupby('时间').mean(False)
     for k in data_set.columns:
         data_set[k]=savgol_filter(data_set[k],3,2)
     return data_set
@@ -108,12 +109,21 @@ def prediction(data_test,pca1,pca2):
     pred2=transform(x_test_pro2,pca2,x_test2)
     return pred1,pred2
 
+def boxplot_fill(res2):
+    col=res2['低压差']
+    # 计算iqr:数据四分之三分位值与四分之一分位值的差
+    iqr=col.quantile(0.75)-col.quantile(0.25)
+    # 根据iqr计算异常值判断阈值
+    u_th=col.quantile(0.75) + 2*iqr # 上界
+    return u_th
+
 #判定异常
-def check_anomaly(outliers1,outliers2):
-    if (len(outliers1)>0) & (len(outliers2)>0):
-        outliers=pd.merge(outliers1,outliers2,on='时间')
-        outliers=outliers[outliers['SOC[%]_x']>45]
-        outliers=outliers.drop(['总电压[V]_y','单体压差_y','SOC[%]_y'],axis=1)
-        return outliers
+def check_anomaly(outliers1,outliers2,res2):
+    outliers=pd.merge(outliers1,outliers2,on='时间')
+    outliers=outliers[outliers['SOC[%]_x']>50]
+    outliers=outliers.drop(['总电压[V]_y','单体压差_y','SOC[%]_y'],axis=1)
+    u_th=boxplot_fill(res2)
+    outliers=outliers[outliers['低压差']>u_th]
+    return outliers
     
 

+ 0 - 0
LIB/MIDDLE/Anomaly Detection/V1_0_0/main_anomalyPCA.py → LIB/MIDDLE/Anomaly_Detection/V1_0_0/main_anomalyPCA.py


+ 98 - 0
LIB/MIDDLE/Anomaly_Detection/V1_0_0/main_detection.py

@@ -0,0 +1,98 @@
+#热失控预警:PCA异常指数
+#预测及异常预警
+
+from LIB.BACKEND import DBManager
+
+dbManager = DBManager.DBManager()
+import datetime
+
+import joblib
+import pandas as pd
+import pymysql
+from LIB.MIDDLE.CellStateEstimation.Common import log
+
+from anomalyPCA import *
+
+dataSOH = pd.read_excel('sn-20210903.xlsx',sheet_name='sn-20210903')
+fileNames = dataSOH['sn']
+fileNames = list(fileNames)
+l = len(fileNames)
+
+now_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')   #type: str
+now_time=datetime.datetime.strptime(now_time,'%Y-%m-%d %H:%M:%S')     #type: datetime
+start_time=now_time-datetime.timedelta(hours=3)
+end_time=str(now_time)
+start_time=str(start_time)
+
+mylog=log.Mylog('log.txt','error')
+mylog.logcfg()
+
+#数据库配置
+host='rm-bp10j10qy42bzy0q77o.mysql.rds.aliyuncs.com'
+port=3306
+user='qx_algo_readonly'
+password = 'qx@123456'
+
+#读取故障结果库中code==119且end_time='0000-00-00 00:00:00'...............................
+db='safety_platform'
+mysql = pymysql.connect (host=host, port=port, user=user, password=password, database=db)
+cursor = mysql.cursor()
+param='start_time,end_time,product_id,code,level,info,advice'
+tablename='all_fault_info'
+sql =  "select %s from %s where code='C493' and 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(','))
+cursor.close()
+mysql.close()
+
+anomalies=pd.DataFrame()
+df_res=pd.DataFrame(columns=['start_time','end_time','product_id','code','level','info','advice'])
+for k in range(l): 
+    try: 
+        sn = fileNames[k]
+        df_diag_ram_sn=df_diag_ram[df_diag_ram['product_id']==sn]
+        df_data = dbManager.get_data(sn=sn, start_time=start_time, end_time=end_time, data_groups=['bms'])
+        data_test = df_data['bms']
+        data_test=data_test[data_test['SOC[%]']>20]
+        if len(data_test)>5:
+            pca1 = joblib.load('pca1_'+sn+'.m')  
+            pca2 = joblib.load('pca2_'+sn+'.m') 
+            res1 = pd.read_csv('res1_'+sn+'.csv',encoding='gbk')
+            res2 = pd.read_csv('res2_'+sn+'.csv',encoding='gbk')
+            pred1,pred2=prediction(data_test,pca1,pca2)
+            outliers1=detect_outliers(res1,pred1,threshold=30)
+            outliers2=detect_outliers(res2,pred2,threshold=16)
+            if (len(outliers1)>0) & (len(outliers2)>0):
+                outliers=check_anomaly(outliers1,outliers2,res2)
+                if len(outliers)>5:
+                    outliers['sn']=sn
+                    anomalies=anomalies.append(outliers)
+                    if df_diag_ram_sn.empty: 
+                        product_id=sn
+                        start_time=outliers.loc[0,'时间']
+                        if outliers.loc[-1,'时间'] == pred1.loc[-1,'时间']:
+                            end_time='0000-00-00 00:00:00'
+                        else:
+                            end_time=outliers.loc[-1,'时间']
+                        code='C493'
+                        level=4
+                        info='热失控预警'
+                        advice='建议返厂维修'
+                        df_res=df_res.append([start_time, end_time,product_id, code, level, info,advice])    
+                        with open(r'D:\Platform\platform_python\data_analyze_platform\USER\spf\01qixiang\06BatSafetyAlarm\热失控报警.txt','a') as file:
+                            file.write(str(tuple(df_res.iloc[-1]))+'\n')    
+                    else:
+                        if outliers.loc[-1,'时间'] == pred1.loc[-1,'时间']:
+                            end_time='0000-00-00 00:00:00'
+                        else:
+                            end_time=outliers.loc[-1,'时间']
+                            df_diag_ram_sn['end_time']=end_time
+                            with open(r'D:\Platform\platform_python\data_analyze_platform\USER\spf\01qixiang\06BatSafetyAlarm\热失控报警.txt','a') as file:
+                                file.write(str(tuple(df_diag_ram_sn.iloc[-1]))+'\n')
+                        
+           
+    except Exception as e:
+        print(repr(e))
+        mylog.logopt(sn,e)
+        pass 

+ 0 - 0
LIB/MIDDLE/Anomaly Detection/V1_0_0/sn-20210903.xlsx → LIB/MIDDLE/Anomaly_Detection/V1_0_0/sn-20210903.xlsx


+ 155 - 159
LIB/MIDDLE/CellStateEstimation/BatSafetyAlarm/V1_0_1/CBMSSafetyAlarm.py

@@ -4,18 +4,19 @@ import datetime
 from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import BatParam
 
 class SafetyAlarm:
-    def __init__(self,sn,celltype,df_bms,df_bms_ram):  #参数初始化
+    def __init__(self,sn,celltype,df_bms,df_bms_ram_sn,df_alarm_ram_sn):  #参数初始化
 
         self.sn=sn
         self.celltype=celltype
         self.param=BatParam.BatParam(celltype)
         self.df_bms=df_bms
-        self.df_bms_ram=df_bms_ram
+        self.df_ram_bms=df_bms_ram_sn.copy()
         df_bms['时间戳']=pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
+        self.df_ram_alarm=df_alarm_ram_sn.copy()
 
-        if not df_bms_ram.empty:
-            self.df_bms=self.df_bms[self.df_bms['时间戳'] > df_bms_ram.iloc[-1]['time']]    #滤除原始数据中的重复数据
-            self.df_bms.reset_index(inplace=True,drop=True)     #重置索引
+        if (not df_bms_ram_sn.empty) and (not self.df_bms.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]']
@@ -27,12 +28,12 @@ class SafetyAlarm:
         # self.celltemp_name=celltemp+othertemp
 
     
-    def diag(self):
+    def safety_alarm_diag(self):
         if self.celltype<=50:
-            df_res=self._ncm_diag()
+            df_res=self._alarm_diag()
             return df_res    
         else:
-            df_res=self._ncm_diag()
+            df_res=self._alarm_diag()
             return df_res
         
 
@@ -47,200 +48,195 @@ class SafetyAlarm:
 
     #获取当前行所有电压数据............................................................................................
     def _cellvolt_get(self,num): 
-        cellvolt = list(self.df_bms.loc[num,self.cellvolt_name]/1000)
+        cellvolt = np.array(self.df_bms.loc[num,self.cellvolt_name]/1000)
         return cellvolt
 
     #..........................................三元电池诊断功能..................................................................
-    def _ncm_diag(self):
+    def _alarm_diag(self):
 
-        column_name=['start_time', 'end_time', 'product_id', 'code', 'level', 'info','advice']
-        df_res=pd.DataFrame(columns=column_name)
+        df_res=pd.DataFrame(columns=['start_time', 'end_time', 'product_id', 'code', 'level', 'info','advice'])
 
         end_time='0000-00-00 00:00:00'
+        time_now=datetime.datetime.now()
         celltemprise=0
         celltemphigh=0
         cellvoltfall=0
-        cellvoltdiff=0
         packvoltfall=0
-            
-        for i in range(len(self.df_bms)):
-            
-            #温度诊断功能.............................................................................................................
-            temp2=np.array(self._celltemp_get(i))
-            celltempmin=min(temp2)
-            celltempmax=max(temp2)
-            #温度有效性判断...........................................................................
-            if celltempmax>self.param.CellTempUpLmt or celltempmin<self.param.CellTempLwLmt:
-                celltempvalid=0
-            else:   #不作处理
-                celltempvalid=1
 
-            if celltempvalid==1:
-                
-                #过温判断............................................................................................................................
-                if celltempmax>self.param.TrwTempHigh:
-                    celltemphigh=1
-                else:
-                    pass
-            
-                
-                #温升判断.............................................................................................................................
+        if not self.df_ram_alarm.empty:
+            if (time_now-self.df_ram_alarm.loc[0,'time']).total_seconds()<300:
+                safetywarning=self.df_ram_alarm['safetywarning']
+            else:
+                self.df_ram_alarm=pd.DataFrame(columns=['time','sn','safetywarning'])
+                safetywarning=0
+        else:
+            self.df_ram_alarm=pd.DataFrame(columns=['time','sn','safetywarning'])
+            safetywarning=0
+
+        if not self.df_bms.empty:
+            for i in range(len(self.df_bms)):
+                #温度诊断功能.............................................................................................................
                 if i<1:
-                    if not self.df_bms_ram.empty:
-                        time1=self.df_bms_ram.iloc[-1]['time']
+                    if not self.df_ram_bms.empty:
+                        temp1=self.df_ram_bms.iloc[-1]['celltemp']
+                        temp2=self._celltemp_get(i)
+                        time1=self.df_ram_bms.iloc[-1]['time']
                         time2=self.bmstime[i]
-                        temp1=np.array(self.df_bms_ram.iloc[-1]['celltemp'])
-
-                        delttime=(time2-time1).total_seconds()
-                        celltemp_rate=(max(temp2-temp1)*60)/delttime    #计算最大温升速率
-                        if celltemp_rate>self.param.TrwTempRate and self.param.CellTempLwLmt<min(temp1) and max(temp1)<self.param.CellTempUpLmt and max(temp2-temp1)>3:
-                            celltemprise=1
-                        else:
-                            pass
                     else:
-                        pass
+                        temp1=self._celltemp_get(i)
+                        temp2=self._celltemp_get(i)
+                        time1=self.bmstime[i]-datetime.timedelta(seconds=10)
+                        time2=self.bmstime[i]
                 else:
+                    temp1=self._celltemp_get(i-1)
+                    temp2=self._celltemp_get(i)
                     time1=self.bmstime[i-1]
                     time2=self.bmstime[i]
-                    temp1=np.array(self._celltemp_get(i-1))
-
+                
+                temp1=temp1[np.where((temp1<self.param.CellTempUpLmt) & (temp1>self.param.CellTempLwLmt))]
+                temp2=temp2[np.where((temp2<self.param.CellTempUpLmt) & (temp2>self.param.CellTempLwLmt))]
+                
+                #温度有效性判断...........................................................................
+                if len(temp1)>0.5 and len(temp2)>0.5 and len(temp1)==len(temp2):
+                    celltempvalid=1
+                else:   #不作处理
+                    celltempvalid=0
+
+                if celltempvalid==1:
+                    celltempmax=max(temp2)
+                    #过温判断............................................................................................................................
+                    if celltempmax>self.param.TrwTempHigh:
+                        celltemphigh=1
+                    else:
+                        pass
+                
+                    
+                    #温升判断.............................................................................................................................
                     delttime=(time2-time1).total_seconds()
                     celltemp_rate=(max(temp2-temp1)*60)/delttime    #计算最大温升速率
                     if celltemp_rate>self.param.TrwTempRate and self.param.CellTempLwLmt<min(temp1) and max(temp1)<self.param.CellTempUpLmt:
-                        celltemprise=1
+                        celltemprise=celltemprise+1
                     else:
                         pass
-            
-            else:
-                pass
-            
-            #电压诊断功能.........................................................................................................................................
-            if i<1:
-                cellvolt2=self._cellvolt_get(i)
-                cellvoltmin2=min(cellvolt2)
-                cellvoltmax2=max(cellvolt2)
-                cellvoltmin_index2=list(cellvolt2).index(cellvoltmin2)
-                cellvoltmax_index2=list(cellvolt2).index(cellvoltmax2)
-                if not self.df_bms_ram.empty:
-                    cellvolt1=np.array(self.df_bms_ram.iloc[-1]['cellvolt'])
-                    cellvoltmin1=min(cellvolt1)
-                    cellvoltmax1=max(cellvolt1)
-                    cellvoltmin_index1=list(cellvolt1).index(cellvoltmin1)
-                    cellvoltmax_index1=list(cellvolt1).index(cellvoltmax1)
+                
                 else:
-                    cellvoltmin1=cellvoltmin2
-                    cellvoltmax1=cellvoltmax2
-                    cellvoltmin_index1=cellvoltmin_index2
-                    cellvoltmax_index1=cellvoltmax_index2
-            else:
-                cellvolt2=self._cellvolt_get(i)
+                    pass
+                
+                #电压诊断功能.........................................................................................................................................
+                if i<1:
+                    cellvolt2=self._cellvolt_get(i)
+                    time2=self.bmstime[i]
+                    if not self.df_ram_bms.empty:
+                        cellvolt1=self.df_ram_bms.iloc[-1]['cellvolt']
+                        time1=self.df_ram_bms.iloc[-1]['time']
+                    else:
+                        cellvolt1=cellvolt2
+                        time1=time2
+                else:
+                    cellvolt2=self._cellvolt_get(i)
+                    cellvolt1=self._cellvolt_get(i-1)
+                    time2=self.bmstime[i]
+                    time1=self.bmstime[i-1]
+                    
+
+                #电压有效性..........................................................................................................................................
                 cellvoltmin2=min(cellvolt2)
                 cellvoltmax2=max(cellvolt2)
                 cellvoltmin_index2=list(cellvolt2).index(cellvoltmin2)
                 cellvoltmax_index2=list(cellvolt2).index(cellvoltmax2)
-                cellvolt1=self._cellvolt_get(i-1)
                 cellvoltmin1=min(cellvolt1)
                 cellvoltmax1=max(cellvolt1)
                 cellvoltmin_index1=list(cellvolt1).index(cellvoltmin1)
                 cellvoltmax_index1=list(cellvolt1).index(cellvoltmax1)
-
-            #电压有效性..........................................................................................................................................
-            if (cellvoltmin2<2 and cellvoltmax2>4.5 and abs(cellvoltmax_index2-cellvoltmin_index2)==1) or cellvoltmin2<0.01 or (cellvoltmin1<2 and cellvoltmax1>4.5 and abs(cellvoltmax_index1-cellvoltmin_index1)==1) or cellvoltmin1<0.01:   #电压断线故障进入
-                cellvoltvalid=0
-            else:
-                cellvoltvalid=1
-
-            if cellvoltvalid==1:
-                #单体电压跌落诊断...........................................................................................................................
-                if i<1:
-                    if not self.df_bms_ram.empty:
-                        time1=self.df_bms_ram.iloc[-1]['time']
-                        time2=self.bmstime[i]
-                        delttime=(time2-time1).total_seconds()
-                        if delttime<310:
-                            if self.packcrnt[i]<0.5 and max(cellvolt1-cellvolt2)>self.param.TrwCellVoltFall:
-                                cellvoltfall=1
-                            elif self.packcrnt[i]>0.5 and max(cellvolt1-cellvolt2)-self.packcrnt[i]*0.01>self.param.TrwCellVoltFall:
-                                cellvoltfall=1
-                            else:
-                                pass
-                        else:
-                            if min(cellvolt2)<self.param.TrwCellVoltLow:  #电压跌落至<1.5V
-                                cellvoltfall=1
-                            else:
-                                pass
-                    else:
-                        pass
+                
+                if (cellvoltmin2<2 and cellvoltmax2>4.5 and abs(cellvoltmax_index2-cellvoltmin_index2)==1) or (cellvoltmin1<2 and cellvoltmax1>4.5 and abs(cellvoltmax_index1-cellvoltmin_index1)==1):   #电压断线故障进入
+                    cellvoltvalid=0
                 else:
-                    delttime=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
-                    cellvolt1=np.array(self._cellvolt_get(i-1))
-                    if self.packcrnt[i]<0.5 and max(cellvolt1-cellvolt2)>self.param.TrwCellVoltFall:
-                        cellvoltfall=1
-                    elif self.packcrnt[i]>0.5 and max(cellvolt1-cellvolt2)-self.packcrnt[i]*0.01>self.param.TrwCellVoltFall:
-                        cellvoltfall=1
+                    cellvolt1=cellvolt1[np.where((cellvolt1>0.01) & (cellvolt1<4.5))]
+                    cellvolt2=cellvolt2[np.where((cellvolt2>0.01) & (cellvolt2<4.5))]
+                    if len(cellvolt1)>1 and len(cellvolt2)>1 and len(cellvolt1)==len(cellvolt2):
+                        cellvoltvalid=1
                     else:
-                        pass
+                        cellvoltvalid=0
                 
-                #压差诊断........................................................................................................................................
-                if (max(cellvolt2)-min(cellvolt2))>self.param.TrwCellVoltDiff:
-                    cellvoltdiff=1
+                if cellvoltvalid==1:
+                    #单体电压跌落诊断...........................................................................................................................
+                    delttime=(time2-time1).total_seconds()
+                    if delttime<360:
+                        if self.packcrnt[i]<0.5 and max(cellvolt1-cellvolt2)>self.param.TrwCellVoltFall:
+                            cellvoltfall=cellvoltfall+1
+                        elif self.packcrnt[i]>0.5 and max(cellvolt1-cellvolt2)-self.packcrnt[i]*0.01>self.param.TrwCellVoltFall:
+                            cellvoltfall=cellvoltfall+1
+                        else:
+                            pass
+                    else:
+                        pass
                 else:
                     pass
-            
-            else:
-                pass
-                
-            #电池包诊断.....................................................................................................................................
-            packvolt2=self.packvolt[i]
-            #电池包电压有效性............................................................................................................................
-            if self.param.CellVoltNums<packvolt2<self.param.CellVoltNums*4.5:
-                packvoltvalid=1
-            else:
-                packvoltvalid=0
-            
-
-            if packvoltvalid==1:
-                if i<1:
-                    if not self.df_bms_ram.empty:
-                        time1=self.df_bms_ram.iloc[-1]['time']
-                        time2=self.bmstime[i]
-                        delttime=(time2-time1).total_seconds()
-                        packvolt1=self.df_bms_ram.iloc[-1]['packvolt']
                     
-                        if delttime<310:
-                            if self.packcrnt[i]<5 and (packvolt1-packvolt2)>self.param.TrwPackVoltFall and self.param.CellVoltNums<packvolt1<self.param.CellVoltNums*4.5:
-                                packvoltfall=1
+                #电池包诊断.....................................................................................................................................
+                packvolt2=self.packvolt[i]
+                #电池包电压有效性............................................................................................................................
+                if self.param.CellVoltNums<packvolt2<self.param.CellVoltNums*4.5:
+                    packvoltvalid=1
+                else:
+                    packvoltvalid=0
+                
+                if packvoltvalid==1:
+                    if i<1:
+                        if not self.df_ram_bms.empty:
+                            time1=self.df_ram_bms.iloc[-1]['time']
+                            time2=self.bmstime[i]
+                            delttime=(time2-time1).total_seconds()
+                            packvolt1=self.df_ram_bms.iloc[-1]['packvolt']
+                        
+                            if delttime<360:
+                                if self.packcrnt[i]<5 and (packvolt1-packvolt2)>self.param.TrwPackVoltFall and self.param.CellVoltNums<packvolt1<self.param.CellVoltNums*4.5:
+                                    packvoltfall=packvoltfall+1
+                                else:
+                                    pass
                             else:
                                 pass
                         else:
                             pass
                     else:
-                        pass
+                        packvolt1=self.packvolt[i-1]
+                        if self.packcrnt[i]<5 and (packvolt1-packvolt2)>self.param.TrwPackVoltFall and self.param.CellVoltNums<packvolt1<self.param.CellVoltNums*4.5:
+                            packvoltfall=packvoltfall+1
+                        else:
+                            pass
                 else:
-                    packvolt1=self.packvolt[i-1]
-                    if self.packcrnt[i]<5 and (packvolt1-packvolt2)>self.param.TrwPackVoltFall and self.param.CellVoltNums<packvolt1<self.param.CellVoltNums*4.5:
-                        packvoltfall=1
-                    else:
-                        pass
+                    pass
+            
+            #热失控故障判断........................................................................................................................
+            df_bms_ram=pd.DataFrame(columns=['time', 'sn', 'packvolt',  'cellvolt', 'celltemp'])
+            df_bms_ram.loc[0]=[self.bmstime[0], self.sn, packvolt2, cellvolt2, temp2]
+            df_ram_alarm=self.df_ram_alarm
+            trwtemp=max(celltemprise,celltemphigh)
+            trwcellvolt=cellvoltfall
+            trwpackvolt=packvoltfall
+            trw_array=np.array([trwtemp, trwcellvolt, trwpackvolt])
+
+            if np.sum(trw_array)>3.5 and np.sum(trw_array>0.5)>1.5:
+                fltcode='C599'
+                df_res.loc[0]=[self.bmstime[len(self.bmstime)-1], end_time, self.sn, fltcode, 5, '电池发生热失控', '联系用户立即远离电池,并通知技术人员介入']
+                return df_res, df_bms_ram, df_ram_alarm
+            elif safetywarning>2.5 and np.sum(trw_array)>1.5 and np.sum(trw_array>0.5)>1.5:
+                fltcode='C599'
+                df_res.loc[0]=[self.bmstime[len(self.bmstime)-1], end_time, self.sn, fltcode, 5, '电池发生热失控', '联系用户立即远离电池,并通知技术人员介入']
+                return df_res, df_bms_ram, df_ram_alarm
             else:
-                pass
-        
-        #热失控故障判断........................................................................................................................
-        df_bms_ram=pd.DataFrame(columns=['time', 'sn', 'packvolt',  'cellvolt', 'celltemp'])
-        df_bms_ram.loc[0]=[self.bmstime[0], self.sn, packvolt2, list(cellvolt2), list(temp2)]
-        if celltemprise==1 or celltemphigh==1:
-            trwtemp=1
-        else:
-            trwtemp=0
-
-        if cellvoltfall==1 or cellvoltdiff==1:
-            trwcellvolt=1
-        else:
-            trwcellvolt=0
+                if np.sum(trw_array)>1.5 and np.sum(trw_array>0.5)>1.5:
+                    safetywarning=3
+                    df_ram_alarm.loc[0]=[self.bmstime[len(self.bmstime)-1], self.sn, safetywarning]
+                else:
+                    pass
+                return pd.DataFrame(), df_bms_ram, df_ram_alarm
         
-        if trwtemp+trwcellvolt+packvoltfall>1.5:
-            fltcode=119
-            df_res.loc[0]=[self.bmstime[0], end_time, self.sn, fltcode, 5, '电池发生热失控', '立刻远离电池']
-            return df_res, df_bms_ram
         else:
-            return pd.DataFrame(), df_bms_ram
+            if safetywarning>2.5:
+                fltcode='C599'
+                df_res.loc[0]=[time_now, end_time, self.sn, fltcode, 5, '电池发生热失控', '联系用户立即远离电池,并通知技术人员介入']
+                return df_res, self.df_ram_bms, self.df_ram_alarm
+            else:
+                return pd.DataFrame(), self.df_ram_bms, self.df_ram_alarm

+ 46 - 27
LIB/MIDDLE/CellStateEstimation/BatSafetyAlarm/main.py

@@ -10,10 +10,10 @@ from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import log
 
 
 #...................................电池包电芯安全诊断函数......................................................................................................................
-def diag_cal(sn_list, df_bms_ram):
+def diag_cal(sn_list, df_bms_ram, df_alarm_ram):
 
     # start=time.time()
-    now_time=datetime.datetime.now()
+    now_time=datetime.datetime.now() #-datetime.timedelta(seconds=3600*24+3600*14.6)
     start_time=now_time-datetime.timedelta(seconds=70)
     start_time=start_time.strftime('%Y-%m-%d %H:%M:%S')
     end_time=now_time.strftime('%Y-%m-%d %H:%M:%S')
@@ -24,13 +24,13 @@ def diag_cal(sn_list, df_bms_ram):
     user='qx_algo_readonly'
     password = 'qx@123456'
 
-    #读取故障结果库中code==119且end_time='0000-00-00 00:00:00'...............................
+    #读取故障结果库中code=='C599'且end_time='0000-00-00 00:00:00'...............................
     db='safety_platform'
     mysql = pymysql.connect (host=host, port=port, user=user, password=password, database=db)
     cursor = mysql.cursor()
     param='start_time,end_time,product_id,code,level,info,advice'
     tablename='all_fault_info'
-    sql =  "select %s from %s where code=119 and end_time='0000-00-00 00:00:00'" %(param,tablename)
+    sql =  "select %s from %s where code='C599' and 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(','))
@@ -57,26 +57,30 @@ def diag_cal(sn_list, df_bms_ram):
         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']
-        print(df_bms)
+        # print(df_bms)
 
         #电池诊断................................................................................................................................................................
         df_diag_ram_sn=df_diag_ram[df_diag_ram['product_id']==sn]
         df_bms_ram_sn=df_bms_ram[df_bms_ram['sn']==sn]
+        df_alarm_ram_sn=df_alarm_ram[df_alarm_ram['sn']==sn]
         if df_diag_ram_sn.empty:   
-            if not df_bms.empty:
-                SafetyAlarm=CBMSSafetyAlarm.SafetyAlarm(sn,celltype,df_bms, df_bms_ram_sn)
-                df_diag_res, df_bms_res=SafetyAlarm.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:
-                    with open(r'D:\Platform\platform_python\data_analyze_platform\USER\spf\01qixiang\06BatSafetyAlarm\热失控报警.txt','a') as file:
-                        file.write(str(tuple(df_diag_res.iloc[-1]))+'\n')
-                
+            SafetyAlarm=CBMSSafetyAlarm.SafetyAlarm(sn,celltype,df_bms, df_bms_ram_sn, df_alarm_ram_sn)
+            df_diag_res, df_bms_res, df_ram_res=SafetyAlarm.safety_alarm_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)
+
+            sn_index=df_alarm_ram.loc[df_alarm_ram['sn']==sn].index
+            df_alarm_ram=df_alarm_ram.drop(index=sn_index)
+            df_alarm_ram=df_alarm_ram.append(df_ram_res)
+
+            #当前热失控故障写入数据库
+            if not df_diag_res.empty:
+                with open(r'D:\Platform\platform_python\data_analyze_platform\USER\spf\01qixiang\06BatSafetyAlarm\热失控报警.txt','a') as file:
+                    file.write(str(tuple(df_diag_res.iloc[-1]))+'\n')
+              
         #当前热失控已超过一天变为历史故障并更改数据库
         else:
             fault_time=datetime.datetime.strptime(df_diag_ram_sn.iloc[-1]['start_time'], '%Y-%m-%d %H:%M:%S')
@@ -88,19 +92,30 @@ def diag_cal(sn_list, df_bms_ram):
 
         # end=time.time()
         # print(end-start)
+    
+    return df_bms_ram,df_alarm_ram
 #...................................................主进程...........................................................................................................
 def mainprocess():
-    global SNnums
-    global df_bms_ram
+    global df_bms_ram1, df_bms_ram2, df_alarm_ram1, df_alarm_ram2, SNnums
     process = 2
     pool = multiprocessing.Pool(processes = process)
 
+    res_list=[]
+    ram_list1=[df_bms_ram1, df_bms_ram2]
+    ram_list2=[df_alarm_ram1, df_alarm_ram1]
     for i in range(process):
         sn_list = SNnums[i]
-        pool.apply_async(diag_cal, (sn_list,df_bms_ram))
-
+        df_bms_ram=ram_list1[i]
+        df_alarm_ram=ram_list2[i]
+        df_res=pool.apply_async(diag_cal, (sn_list,df_bms_ram,df_alarm_ram)).get()
+        res_list.append(df_res)
+    
     pool.close()
     pool.join()
+    df_bms_ram1=res_list[0][0]
+    df_bms_ram2=res_list[1][0]
+    df_alarm_ram1=res_list[0][1]
+    df_alarm_ram2=res_list[1][1]
 
 
 #...............................................主函数起定时作用.......................................................................................................................
@@ -119,18 +134,22 @@ if __name__ == "__main__":
     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]
-    SNnums=[[], ['PK504B10100004447']]
+    SNnums=[SNnums_L7255 + SNnums_C7255 + SNnums_U7255 + SNnums_4840, SNnums_6040 + SNnums_6060]
+    # SNnums=[['MGMLXN750N2189008','PK504B10100004328'], ['PK500A20100000752','PK504B10100004387']]
     
     mylog=log.Mylog('log_diag.txt','error')
     mylog.logcfg()
     
     #参数初始化
-    df_bms_ram=pd.DataFrame(columns=['time', 'sn', 'packvolt', 'cellvolt', 'celltemp'])
+    df_bms_ram1=pd.DataFrame(columns=['time', 'sn', 'packvolt', 'cellvolt', 'celltemp'])
+    df_bms_ram2=pd.DataFrame(columns=['time', 'sn', 'packvolt', 'cellvolt', 'celltemp'])
+    df_alarm_ram1=pd.DataFrame(columns=['time','sn','safetywarning'])
+    df_alarm_ram2=pd.DataFrame(columns=['time','sn','safetywarning'])
 
+    mainprocess()
     #定时任务.......................................................................................................................................................................
     scheduler = BlockingScheduler()
-    scheduler.add_job(mainprocess, 'interval', seconds=10, id='diag_job')
+    scheduler.add_job(mainprocess, 'interval', seconds=60, id='diag_job')
 
     try:  
         scheduler.start()

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

@@ -292,7 +292,7 @@ class BatParam:
             self.CellTempDiffLv2=15   
 
             # self.TrwVoltRate=-8
-            self.mk_slope=-0.3
+            self.mk_slope=-0.5
             
             
             self.DifVolGap = 3