from types import CellType import pandas as pd import numpy as np import datetime,time import pika import json import BatParam class BatCrtl(): def __init__(self,host,port,df_statectrl_ram,df_rlyctrl_ram,df_diag,df_bms,sn_list): #参数初始化 self.host=host self.port=port self.sn_list=sn_list df_bms['time']=pd.to_datetime(df_bms['time'], format='%Y-%m-%d %H:%M:%S') self.df_bms=df_bms self.df_statectrl_ram=df_statectrl_ram.copy() self.df_rlyctrl_ram=df_rlyctrl_ram.copy() self.df_diag1=df_diag[(df_diag['fault_code']==110) | (df_diag['fault_code']==119) | (df_diag['fault_code']==12) | (df_diag['fault_code']==18)] self.df_diag2=df_diag[df_diag['fault_code']==100] # self.bmstime=df_bms['time'] # self.packcrnt=df_bms['PackCrnt']*self.param.PackCrntDec # self.bms_soc=df_bms['PackSOC'] # self.bms_soh=df_bms['PackSOH'] # self.bmsstat=df_bms['BMSStat'] #主调用函数........................................................................ def bat_crtl(self): df_res1=self._bat_rlycrtl() df_res2=self._bat_statecrtl() df_res3=self._bat_balcrtl() return df_res1,df_res2,df_res3 #Ribbit队列发送数据.............................................................. def _rabbit_send(self, dict_send): # 建立一个实例 credentials = pika.PlainCredentials('admin', 'admin') connection = pika.BlockingConnection(pika.ConnectionParameters(self.host,self.port,credentials=credentials)) # 声明一个管道,在管道里发消息 channel = connection.channel() # 在管道里声明queue channel.queue_declare(queue='cmdQueue',durable=True) channel.basic_publish(exchange='cmdExchange',routing_key='CmdDirectRouting',body=json.dumps(dict_send)) # 消息内容 connection.close() def _parameter(self,sn): if 'KPD' in sn: celltype=1 else: celltype=99 self.param=BatParam.BatParam(celltype) self.cellvolt_name=['CellVolt'+str(x) for x in range(1,self.param.CellVoltNums+1)] self.celltemp_name=['CellTemp'+str(x) for x in range(1,self.param.CellTempNums+1)] #电池继电器下行控制......................................................................................................................... def _bat_rlycrtl(self): time_now=datetime.datetime.now() for sn in self.sn_list: factory=self.df_bms.loc[self.df_bms[self.df_bms['sn']==sn].index[0], 'factory'] if sn in list(self.df_diag1['sn']): #该sn发生4级或5级故障 if sn in list(self.df_rlyctrl_ram['sn']): #ram是否包含该sn if self.df_rlyctrl_ram.loc[self.df_rlyctrl_ram[self.df_rlyctrl_ram['sn']==sn].index[0], 'batrlyctrl']==0: self.df_rlyctrl_ram.loc[self.df_rlyctrl_ram[self.df_rlyctrl_ram['sn']==sn].index[0], 'time']=time_now self.df_rlyctrl_ram.loc[self.df_rlyctrl_ram[self.df_rlyctrl_ram['sn']==sn].index[0], 'batrlyctrl']=1 dict_send={"cmd_type":1,"factory":factory,"sn":sn,"batrlyctrl":1} self._rabbit_send(dict_send) return self.df_rlyctrl_ram else: pass else: self.df_rlyctrl_ram.loc[len(self.df_rlyctrl_ram)]=[time_now,sn,1] dict_send={"cmd_type":1,"factory":factory,"sn":sn,"batrlyctrl":1} self._rabbit_send(dict_send) return self.df_rlyctrl_ram else: #该sn没有4级和5级故障 if sn in list(self.df_rlyctrl_ram['sn']): #ram是否包含该sn if self.df_rlyctrl_ram.loc[self.df_rlyctrl_ram[self.df_rlyctrl_ram['sn']==sn].index[0], 'batrlyctrl']==1: self.df_rlyctrl_ram.loc[self.df_rlyctrl_ram[self.df_rlyctrl_ram['sn']==sn].index[0], 'time']=time_now self.df_rlyctrl_ram.loc[self.df_rlyctrl_ram[self.df_rlyctrl_ram['sn']==sn].index[0], 'batrlyctrl']=0 dict_send={"cmd_type":1,"factory":factory,"sn":sn,"batrlyctrl":0} self._rabbit_send(dict_send) return self.df_rlyctrl_ram else: pass else: self.df_rlyctrl_ram.loc[len(self.df_rlyctrl_ram)]=[time_now,sn,0] dict_send={"cmd_type":1,"factory":factory,"sn":sn,"batrlyctrl":0} self._rabbit_send(dict_send) return self.df_rlyctrl_ram return self.df_rlyctrl_ram #电池充放电下行控制......................................................................................................................... def _bat_statecrtl(self): time_now=datetime.datetime.now() #对完成充放电循环,且超过10天的,done_flg置0 if not self.df_statectrl_ram.empty: for i in range(len(self.df_statectrl_ram)): if self.df_statectrl_ram.iloc[i]['done_flg']==1 and (time_now-self.df_statectrl_ram.iloc[i]['time']).total_seconds()>10*24*3600: self.df_statectrl_ram.iloc[i]['done_flg']=0 else: pass else: pass #存在电池正在放电------------------------------- if 3 in list(self.df_statectrl_ram['batstatectrl']): sn=self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['batstatectrl']==3].index[0], 'sn'] factory=self.df_bms.loc[self.df_bms[self.df_bms['sn']==sn].index[0], 'factory'] self._parameter(sn) bms_index=self.df_bms[self.df_bms['sn']==sn].index[0] packsoc=self.df_bms.loc[bms_index,'PackSOC'] cellvolt = self.df_bms.loc[bms_index,self.cellvolt_name] time_now=self.df_bms.loc[bms_index,'time'] if packsocself.param.DscPackSoc+5 or self.param.CellDscVolt+0.53700: #静置时间满足要求 self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'time']=time_now self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'batstatectrl']=1 dict_send={"cmd_type":2,"factory":factory,"sn":sn,"batstatectrl":1,"dischrg_volt":272} self._rabbit_send(dict_send) return self.df_statectrl_ram else: pass else: self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'time']=time_now self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'batstatectrl']=2 dict_send={"cmd_type":2,"factory":factory,"sn":sn,"batstatectrl":2,"dischrg_volt":272} self._rabbit_send(dict_send) return self.df_statectrl_ram #存在电池正在充电------------------------------------ elif 1 in list(self.df_statectrl_ram['batstatectrl']): sn=self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['batstatectrl']==1].index[0], 'sn'] factory=self.df_bms.loc[self.df_bms[self.df_bms['sn']==sn].index[0], 'factory'] self._parameter(sn) bms_index=self.df_bms[self.df_bms['sn']==sn].index[0] packsoc=self.df_bms.loc[bms_index,'PackSOC'] cellvolt = self.df_bms.loc[bms_index,self.cellvolt_name] time_now=self.df_bms.loc[bms_index,'time'] if packsoc>99 or max(cellvolt)>self.param.CellFullChrgVolt: #充电已完成 self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'time']=time_now self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'batstatectrl']=0 self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'done_flg']=1 dict_send={"cmd_type":2,"factory":factory,"sn":sn,"batstatectrl":0,"dischrg_volt":272} self._rabbit_send(dict_send) return self.df_statectrl_ram else: pass #当前电池均不在充放电循环过程中,则接下来判断是否存在100故障--------------------------------- else: for sn in self.sn_list: factory=self.df_bms.loc[self.df_bms[self.df_bms['sn']==sn].index[0], 'factory'] self._parameter(sn) if sn in list(self.df_diag2['sn']): #该sn发生100长时间未标定故障 if sn in list(self.df_bms['sn']): bms_index=self.df_bms[self.df_bms['sn']==sn].index[0] packsoc=self.df_bms.loc[bms_index,'PackSOC'] cellvolt = self.df_bms.loc[bms_index,self.cellvolt_name] time_now=self.df_bms.loc[bms_index,'time'] if packsoc>self.param.DscPackSoc+5 or self.param.CellDscVolt+0.52 and max(cellvolt)<4.5 and packsoc>20 and max(cellvolt)-min(cellvolt)>voltdiff: #寻找并判断最大电压是否在均衡 cellmax_index=list(cellvolt).index(max(cellvolt))+1 bal_group = cellmax_index // self.param.BalGroups #取整 bal_index = cellmax_index % self.param.BalGroups #取余 if bal_index==0: bal_index=self.param.BalNums else: pass #获取BMS当前最大电芯电压的均衡状态 bmscellmax_balgroup=bms_balstate[bal_group] bmscellmax_balgroup >> bal_index-1 bmscellmax_balstate=bmscellmax_balgroup & 1 if bmscellmax_balstate==1: #最大电压在均衡 pass else: #最大电芯不在均衡 cellvoltdiff=cellvolt-min(cellvolt) cellvoltdiff=cellvoltdiff[cellvoltdiff>voltdiff]=1 #压差>阈值的赋1 cellvoltdiff=cellvoltdiff[cellvoltdiff<=voltdiff]=0 #压差<=阈值的赋0 cellvoltdiff=list(map(int,cellvoltdiff)) #均衡状态按照分组赋值———————————————————————————————————————————————— limsbalctrl=[] for i in range(self.param.BalGroups): balstate=0 cellvoltdiff_group=cellvoltdiff[self.param.BalNums*i : self.param.BalNums*(i+1)] for j in range(self.param.BalNums): #计算每一个分组的均衡状态 balstate=balstate+cellvoltdiff_group[j]*2**j limsbalctrl.append(balstate) dict_send={"cmd_type":3,"factory":factory,"sn":sn,"batbalctrl":limsbalctrl} self._rabbit_send(dict_send) time.sleep(0.1) #不满足均衡开启条件———————————————————————————————————————————————————————————————————————————————————— else: limsbalctrl=[0]*self.param.BalGroups #所有电芯均衡关闭 dict_send={"cmd_type":3,"factory":factory,"sn":sn,"batbalctrl":limsbalctrl} self._rabbit_send(dict_send) time.sleep(0.1)