import sys import numpy as np import pandas as pd import string import os from pandas import Series from matplotlib import pyplot as plt from pandas.core.frame import DataFrame from pandas.core.indexes.base import Index from LIB.BACKEND import DBManager import datetime import time import string import re class SamplingSafty: def __init__(self): pass def main(sn,param,bms_info,df_Diag_Ram_in): df_Diag_Ram_Update_inside=DataFrame(columns=['start_time', 'end_time', 'product_id', 'code', 'level', 'info','advice']) df_Diag_Ram_Update_inside=df_Diag_Ram_Update_inside.append(df_Diag_Ram_in) global QuitErrCount VolStarkCount=[0 for i in range(param.CellVoltNums)] VolCount=0 QuitErrCount=[0 for i in range(param.FaultCount)] #--------------该电池的所有当前故障------------- for i in range(0,len(bms_info)): if i==0: bms_infoP=bms_info.loc[i] elif len(bms_info)>=1: bms_infoP=bms_info.loc[i-1] df_Diag_Ram_Update_inside,VolStarkCount,VolCount=SamplingSafty.VoltSamplingDiag(sn,bms_info.loc[i],bms_infoP,param,VolStarkCount,VolCount,df_Diag_Ram_Update_inside) df_Diag_Ram_Update_inside=SamplingSafty.TempSamplingDiag(sn,bms_info.loc[i],bms_infoP,param,df_Diag_Ram_Update_inside) # FltInfo=SamplingSafty.CrntSamplingDiag(sn,bms_info.loc[i],FltInfo,param) return df_Diag_Ram_Update_inside def VoltSamplingDiag(sn,bms_infoN,bms_infoP,param,VolStarkCount,VolCount,df_Diag_Ram): InVMaxBatNo=[] InVMinBatNo=[] StackVolNo=[] OutlierVolNo=[] ErrorFlg=0 #——————————————————————取最高最低电压———————————————————————————————— VoltageNum=['单体电压'+str(i) for i in range(1,param.CellVoltNums+1)] CellVoltage=bms_infoN[VoltageNum]/1000 CellVoltageP=bms_infoP[VoltageNum]/1000 MaxVolt=CellVoltage.max() MinVolt=CellVoltage.min() MaxVoltNum=CellVoltage[MaxVolt==CellVoltage].index MinVoltNum=CellVoltage[MinVolt==CellVoltage].index InVMaxBatNo=CellVoltage[CellVoltage>=param.CellOVlmt].index InVMinBatNo=CellVoltage[CellVoltage<=param.CellUVlmt].index if param.CellVoltNums>2: AvgVol=(CellVoltage.sum()-MaxVolt-MinVolt)/(param.CellVoltNums-2) else: AvgVol=CellVoltage.mean() #—————————————————————————————电压无效和断线判断——————————————————————— 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),'返厂维修'] ErrorFlg=1 else:#如果故障发生当前故障中有该故障,则不进行操作 pass else:#如果没有故障,并且当前故障表中有该故障,则判断故障是否结束 QuitErrCount[50]=0 if 10 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 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),'返厂维修'] 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),'返厂维修'] ErrorFlg=1 else: pass else: if 50 in df_Diag_Ram['code'].values.tolist(): QuitErrCount[50]=QuitErrCount[50]+1 if QuitErrCount[50]>3: QuitErrCount[50]=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']==50].index,['end_time']]=end_time else: pass else: pass #——————————————————————————————————电压卡滞和离群判断————————————————————————— 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']: 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)+'号电池电压离群','技术介入诊断'] ErrorFlg=1 else:#如果故障发生当前故障中有该故障,则不进行操作 pass else: VolCount=0 if 51 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 else: pass else: pass # -------------------卡滞逻辑未加------------------------------------- # if (abs(float(bms_infoN['总电流[A]']))>=10 and not 'PK504' in sn) or (abs(float(bms_infoN['总电流[A]']))>=15 and 'PK504' in sn): # StackVolNo=CellVoltage[abs(CellVoltage-CellVoltageP)<=0.0001].index # NotStackVolNo=CellVoltage[abs(CellVoltage-CellVoltageP)>0.0001].index # if len(StackVolNo) and not 52 in df_Diag_Ram['code']: # StackVolNo=[int(s) for s in StackVolNo.str.replace(r'[^0-9]','').tolist()] # NotStackVolNo=[int(s) for s in NotStackVolNo.str.replace(r'[^0-9]','').tolist()] # for i in StackVolNo: # VolStarkCount[i-1]=VolStarkCount[i-1]+1 # for i in NotStackVolNo: # VolStarkCount[i-1]=0 # if [s for s in VolStarkCount]>10: # StacVolNo= return df_Diag_Ram,VolStarkCount,VolCount def TempSamplingDiag(sn,bms_infoN,bms_infoP,param,df_Diag_Ram): InVMaxBatNo=[] InVMinBatNo=[] StackVolNo=[] OutlierVolNo=[] ErrorFlg=0 #——————————————————————Cell取最高最低温度———————————————————————————————— TempNum=['单体温度'+str(i) for i in range(1,param.CellTempNums+1)] CellTemp=bms_infoN[TempNum] CellTempP=bms_infoP[TempNum] maxCellTemp=CellTemp.max() minCellTemp=CellTemp.min() MaxVoltNum=CellTemp[maxCellTemp==CellTemp].index MinVoltNum=CellTemp[minCellTemp==CellTemp].index InVMaxTempBatNo=CellTemp[CellTemp>=param.PackOTlmt].index InVMinTempBatNo=CellTemp[CellTemp<=param.PackUTlmt].index if param.CellTempNums>2: AvgCellTemp=(CellTemp.sum()-maxCellTemp-minCellTemp)/(param.CellTempNums-2) else: AvgCellTemp=CellTemp.mean() #——————————————————————温度无效,离群和断线判断——————————————————————— 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),'返厂维修'] ErrorFlg=1 else:#如果故障发生当前故障中有该故障,则不进行操作 pass else:#如果没有故障,并且当前故障表中有该故障,则判断故障是否结束 QuitErrCount[2]=0 if 53 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 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),'联系用户核实电池温度情况,并返厂维修'] 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),'返厂维修'] ErrorFlg=1 else: pass else: if 2 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 else: pass else: pass if ErrorFlg==0: AvgCellTempGap=abs(CellTemp-AvgCellTemp) 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)+'号电池异常温度离群','技术介入诊断'] ErrorFlg=1 else:#如果故障发生当前故障中有该故障,则不进行操作 pass else: if 8 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 else: pass else: pass #——————————————————————————————————OtherTemp———————————————————————————————————— if param.OtherTempNums>0: OtherTempNum=['其他温度'+str(i) for i in range(1,param.OtherTempNums+1)] OtherTemp=bms_infoN[OtherTempNum] if 'MGMLX' in sn: OtherTemp['其他温度2']=OtherTemp['其他温度1'] else: pass OtherTemppP=bms_infoP[OtherTempNum] maxOtherTemp=OtherTemp.max() minOtherTemp=OtherTemp.min() MaxVoltNum=OtherTemp[maxOtherTemp==OtherTemp].index MinVoltNum=OtherTemp[minOtherTemp==OtherTemp].index InVMaxOtherTempBatNo=OtherTemp[OtherTemp>=param.OtherOTlmt].index InVMinOtherTempBatNo=OtherTemp[OtherTemp<=param.OtherUTlmt].index if param.OtherTempNums>2: AvgOtherTemp=(OtherTemp.sum()-maxOtherTemp-minOtherTemp)/(param.OtherTempNums-2) else: AvgOtherTemp=OtherTemp.mean() #——————————————————————温度无效,离群和断线判断——————————————————————— 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),'返厂维修'] ErrorFlg=1 else:#如果故障发生当前故障中有该故障,则不进行操作 pass else:#如果没有故障,并且当前故障表中有该故障,则判断故障是否结束 QuitErrCount[55]=0 if 54 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 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),'联系用户核实电池温度情况,并返厂维修'] 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),'返厂维修'] ErrorFlg=1 else: pass else: if 55 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 else: pass else: pass if ErrorFlg==0: AvgOtherTempGap=abs(OtherTemp-AvgOtherTemp) 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,'传感器温度异常离群','技术介入诊断'] ErrorFlg=1 else:#如果故障发生当前故障中有该故障,则不进行操作 pass else: if 56 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 else: pass else: pass if (maxOtherTemp-maxCellTemp)>param.AvgOtherTempGap and maxOtherTemp3: 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 if (maxCellTemp-maxOtherTemp)>param.AvgOtherTempGap and maxOtherTemp3: 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 return df_Diag_Ram