CBMSBatCtrl.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. from types import CellType
  2. import pandas as pd
  3. import numpy as np
  4. import datetime,time
  5. import pika
  6. import json
  7. import BatParam
  8. class BatCrtl():
  9. def __init__(self,host,port,df_statectrl_ram,df_rlyctrl_ram,df_diag,df_bms,sn_list): #参数初始化
  10. self.host=host
  11. self.port=port
  12. self.sn_list=sn_list
  13. df_bms['time']=pd.to_datetime(df_bms['time'], format='%Y-%m-%d %H:%M:%S')
  14. self.df_bms=df_bms
  15. self.df_statectrl_ram=df_statectrl_ram.copy()
  16. self.df_rlyctrl_ram=df_rlyctrl_ram.copy()
  17. 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)]
  18. self.df_diag2=df_diag[df_diag['fault_code']==100]
  19. # self.bmstime=df_bms['time']
  20. # self.packcrnt=df_bms['PackCrnt']*self.param.PackCrntDec
  21. # self.bms_soc=df_bms['PackSOC']
  22. # self.bms_soh=df_bms['PackSOH']
  23. # self.bmsstat=df_bms['BMSStat']
  24. #主调用函数........................................................................
  25. def bat_crtl(self):
  26. df_res1=self._bat_rlycrtl()
  27. df_res2=self._bat_statecrtl()
  28. df_res3=self._bat_balcrtl()
  29. return df_res1,df_res2,df_res3
  30. #Ribbit队列发送数据..............................................................
  31. def _rabbit_send(self, dict_send):
  32. # 建立一个实例
  33. credentials = pika.PlainCredentials('admin', 'admin')
  34. connection = pika.BlockingConnection(pika.ConnectionParameters(self.host,self.port,credentials=credentials))
  35. # 声明一个管道,在管道里发消息
  36. channel = connection.channel()
  37. # 在管道里声明queue
  38. channel.queue_declare(queue='cmdQueue',durable=True)
  39. channel.basic_publish(exchange='cmdExchange',routing_key='CmdDirectRouting',body=json.dumps(dict_send)) # 消息内容
  40. connection.close()
  41. def _parameter(self,sn):
  42. if 'KPD' in sn:
  43. celltype=1
  44. else:
  45. celltype=99
  46. self.param=BatParam.BatParam(celltype)
  47. self.cellvolt_name=['CellVolt'+str(x) for x in range(1,self.param.CellVoltNums+1)]
  48. self.celltemp_name=['CellTemp'+str(x) for x in range(1,self.param.CellTempNums+1)]
  49. #电池继电器下行控制.........................................................................................................................
  50. def _bat_rlycrtl(self):
  51. time_now=datetime.datetime.now()
  52. for sn in self.sn_list:
  53. factory=self.df_bms.loc[self.df_bms[self.df_bms['sn']==sn].index[0], 'factory']
  54. if sn in list(self.df_diag1['sn']): #该sn发生4级或5级故障
  55. if sn in list(self.df_rlyctrl_ram['sn']): #ram是否包含该sn
  56. if self.df_rlyctrl_ram.loc[self.df_rlyctrl_ram[self.df_rlyctrl_ram['sn']==sn].index[0], 'batrlyctrl']==0:
  57. self.df_rlyctrl_ram.loc[self.df_rlyctrl_ram[self.df_rlyctrl_ram['sn']==sn].index[0], 'time']=time_now
  58. self.df_rlyctrl_ram.loc[self.df_rlyctrl_ram[self.df_rlyctrl_ram['sn']==sn].index[0], 'batrlyctrl']=1
  59. dict_send={"cmd_type":1,"factory":factory,"sn":sn,"batrlyctrl":1}
  60. self._rabbit_send(dict_send)
  61. return self.df_rlyctrl_ram
  62. else:
  63. pass
  64. else:
  65. self.df_rlyctrl_ram.loc[len(self.df_rlyctrl_ram)]=[time_now,sn,1]
  66. dict_send={"cmd_type":1,"factory":factory,"sn":sn,"batrlyctrl":1}
  67. self._rabbit_send(dict_send)
  68. return self.df_rlyctrl_ram
  69. else: #该sn没有4级和5级故障
  70. if sn in list(self.df_rlyctrl_ram['sn']): #ram是否包含该sn
  71. if self.df_rlyctrl_ram.loc[self.df_rlyctrl_ram[self.df_rlyctrl_ram['sn']==sn].index[0], 'batrlyctrl']==1:
  72. self.df_rlyctrl_ram.loc[self.df_rlyctrl_ram[self.df_rlyctrl_ram['sn']==sn].index[0], 'time']=time_now
  73. self.df_rlyctrl_ram.loc[self.df_rlyctrl_ram[self.df_rlyctrl_ram['sn']==sn].index[0], 'batrlyctrl']=0
  74. dict_send={"cmd_type":1,"factory":factory,"sn":sn,"batrlyctrl":0}
  75. self._rabbit_send(dict_send)
  76. return self.df_rlyctrl_ram
  77. else:
  78. pass
  79. else:
  80. self.df_rlyctrl_ram.loc[len(self.df_rlyctrl_ram)]=[time_now,sn,0]
  81. dict_send={"cmd_type":1,"factory":factory,"sn":sn,"batrlyctrl":0}
  82. self._rabbit_send(dict_send)
  83. return self.df_rlyctrl_ram
  84. return self.df_rlyctrl_ram
  85. #电池充放电下行控制.........................................................................................................................
  86. def _bat_statecrtl(self):
  87. time_now=datetime.datetime.now()
  88. #对完成充放电循环,且超过10天的,done_flg置0
  89. if not self.df_statectrl_ram.empty:
  90. for i in range(len(self.df_statectrl_ram)):
  91. 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:
  92. self.df_statectrl_ram.iloc[i]['done_flg']=0
  93. else:
  94. pass
  95. else:
  96. pass
  97. #存在电池正在放电-------------------------------
  98. if 3 in list(self.df_statectrl_ram['batstatectrl']):
  99. sn=self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['batstatectrl']==3].index[0], 'sn']
  100. factory=self.df_bms.loc[self.df_bms[self.df_bms['sn']==sn].index[0], 'factory']
  101. self._parameter(sn)
  102. bms_index=self.df_bms[self.df_bms['sn']==sn].index[0]
  103. packsoc=self.df_bms.loc[bms_index,'PackSOC']
  104. cellvolt = self.df_bms.loc[bms_index,self.cellvolt_name]
  105. time_now=self.df_bms.loc[bms_index,'time']
  106. if packsoc<self.param.DscPackSoc or 1<min(cellvolt)<self.param.CellDscVolt: #结束放电
  107. self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'time']=time_now
  108. self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'batstatectrl']=2
  109. dict_send={"cmd_type":2,"factory":factory,"sn":sn,"batstatectrl":2,"dischrg_volt":272}
  110. self._rabbit_send(dict_send)
  111. return self.df_statectrl_ram
  112. else:
  113. pass
  114. #存在电池正在静置---------------------------------
  115. elif 2 in list(self.df_statectrl_ram['batstatectrl']):
  116. sn=self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['batstatectrl']==2].index[0], 'sn']
  117. factory=self.df_bms.loc[self.df_bms[self.df_bms['sn']==sn].index[0], 'factory']
  118. self._parameter(sn)
  119. bms_index=self.df_bms[self.df_bms['sn']==sn].index[0]
  120. packcrnt=self.df_bms.loc[bms_index,'PackCrnt']
  121. packsoc=self.df_bms.loc[bms_index,'PackSOC']
  122. cellvolt = self.df_bms.loc[bms_index,self.cellvolt_name]
  123. time_now=self.df_bms.loc[bms_index,'time']
  124. if packsoc>self.param.DscPackSoc+5 or self.param.CellDscVolt+0.5<min(cellvolt)<4.5:
  125. self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'time']=time_now
  126. self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'batstatectrl']=3
  127. dict_send={"cmd_type":2,"factory":factory,"sn":sn,"batstatectrl":3,"dischrg_volt":272}
  128. self._rabbit_send(dict_send)
  129. return self.df_statectrl_ram
  130. elif abs(packcrnt)<0.1: #当前工况确实在静置
  131. time_st=self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'time']
  132. if (time_now-time_st).total_seconds()>3700: #静置时间满足要求
  133. self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'time']=time_now
  134. self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'batstatectrl']=1
  135. dict_send={"cmd_type":2,"factory":factory,"sn":sn,"batstatectrl":1,"dischrg_volt":272}
  136. self._rabbit_send(dict_send)
  137. return self.df_statectrl_ram
  138. else:
  139. pass
  140. else:
  141. self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'time']=time_now
  142. self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'batstatectrl']=2
  143. dict_send={"cmd_type":2,"factory":factory,"sn":sn,"batstatectrl":2,"dischrg_volt":272}
  144. self._rabbit_send(dict_send)
  145. return self.df_statectrl_ram
  146. #存在电池正在充电------------------------------------
  147. elif 1 in list(self.df_statectrl_ram['batstatectrl']):
  148. sn=self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['batstatectrl']==1].index[0], 'sn']
  149. factory=self.df_bms.loc[self.df_bms[self.df_bms['sn']==sn].index[0], 'factory']
  150. self._parameter(sn)
  151. bms_index=self.df_bms[self.df_bms['sn']==sn].index[0]
  152. packsoc=self.df_bms.loc[bms_index,'PackSOC']
  153. cellvolt = self.df_bms.loc[bms_index,self.cellvolt_name]
  154. time_now=self.df_bms.loc[bms_index,'time']
  155. if packsoc>99 or max(cellvolt)>self.param.CellFullChrgVolt: #充电已完成
  156. self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'time']=time_now
  157. self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'batstatectrl']=0
  158. self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'done_flg']=1
  159. dict_send={"cmd_type":2,"factory":factory,"sn":sn,"batstatectrl":0,"dischrg_volt":272}
  160. self._rabbit_send(dict_send)
  161. return self.df_statectrl_ram
  162. else:
  163. pass
  164. #当前电池均不在充放电循环过程中,则接下来判断是否存在100故障---------------------------------
  165. else:
  166. for sn in self.sn_list:
  167. factory=self.df_bms.loc[self.df_bms[self.df_bms['sn']==sn].index[0], 'factory']
  168. self._parameter(sn)
  169. if sn in list(self.df_diag2['sn']): #该sn发生100长时间未标定故障
  170. if sn in list(self.df_bms['sn']):
  171. bms_index=self.df_bms[self.df_bms['sn']==sn].index[0]
  172. packsoc=self.df_bms.loc[bms_index,'PackSOC']
  173. cellvolt = self.df_bms.loc[bms_index,self.cellvolt_name]
  174. time_now=self.df_bms.loc[bms_index,'time']
  175. if packsoc>self.param.DscPackSoc+5 or self.param.CellDscVolt+0.5<min(cellvolt)<4.5:
  176. if sn in list(self.df_statectrl_ram['sn']): #该sn的ram不为空
  177. if self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'done_flg']==0:
  178. self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'time']=time_now
  179. self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'batstatectrl']=3
  180. dict_send={"cmd_type":2,"factory":factory,"sn":sn,"batstatectrl":3,"dischrg_volt":272}
  181. self._rabbit_send(dict_send)
  182. return self.df_statectrl_ram
  183. else:
  184. pass
  185. else:
  186. self.df_statectrl_ram.loc[len(self.df_statectrl_ram)]=[time_now,sn,3,0]
  187. dict_send={"cmd_type":2,"factory":factory,"sn":sn,"batstatectrl":3,"dischrg_volt":272}
  188. self._rabbit_send(dict_send)
  189. return self.df_statectrl_ram
  190. else:
  191. if sn in list(self.df_statectrl_ram['sn']): #该sn的ram不为空
  192. if self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'done_flg']==0:
  193. self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'time']=time_now
  194. self.df_statectrl_ram.loc[self.df_statectrl_ram[self.df_statectrl_ram['sn']==sn].index[0], 'batstatectrl']=2
  195. dict_send={"cmd_type":2,"factory":factory,"sn":sn,"batstatectrl":2,"dischrg_volt":272}
  196. self._rabbit_send(dict_send)
  197. return self.df_statectrl_ram
  198. else:
  199. pass
  200. else:
  201. self.df_statectrl_ram.loc[len(self.df_statectrl_ram)]=[time_now,sn,2,0]
  202. dict_send={"cmd_type":2,"factory":factory,"sn":sn,"batstatectrl":2,"dischrg_volt":272}
  203. self._rabbit_send(dict_send)
  204. return self.df_statectrl_ram
  205. else: #原始数据库为空,给寄存器赋0
  206. if sn in list(self.df_statectrl_ram['sn']):
  207. pass
  208. else:
  209. self.df_statectrl_ram.loc[len(self.df_statectrl_ram)]=[time_now,sn,0,0]
  210. dict_send={"cmd_type":2,"factory":factory,"sn":sn,"batstatectrl":0,"dischrg_volt":272}
  211. self._rabbit_send(dict_send)
  212. return self.df_statectrl_ram
  213. else: #没有相关故障,给寄存器赋0
  214. if sn in list(self.df_statectrl_ram['sn']):
  215. pass
  216. else:
  217. self.df_statectrl_ram.loc[len(self.df_statectrl_ram)]=[time_now,sn,0,0]
  218. dict_send={"cmd_type":2,"factory":factory,"sn":sn,"batstatectrl":0,"dischrg_volt":272}
  219. self._rabbit_send(dict_send)
  220. return self.df_statectrl_ram
  221. return self.df_statectrl_ram
  222. #电池均衡下行控制————————————————————————————————————————————————————————————————————————————————————————————————————————
  223. def _bat_balcrtl(self):
  224. for sn in self.sn_list:
  225. sn_index=self.df_bms[self.df_bms['sn']==sn].index[0]
  226. factory=self.df_bms.loc[sn_index, 'factory'] #获取厂家名称
  227. bms_balstate=self.df_bms.loc[sn_index, 'balstate'] #获取BMS均衡状态
  228. bms_balstate=list(map(int,bms_balstate.split(',')))
  229. self._parameter(sn)
  230. bms_index=self.df_bms[self.df_bms['sn']==sn].index[0]
  231. packsoc=self.df_bms.loc[bms_index,'PackSOC']
  232. cellvolt = self.df_bms.loc[bms_index,self.cellvolt_name]
  233. for balname in self.df_bms.index.tolist():
  234. if 'bal' in balname:
  235. balname = self.df_bms.loc[bms_index, balname] #获取每一列均衡的状态
  236. voltdiff=np.interp(packsoc,self.param.LookTab_SOC,self.param.LookTab_DiffVolt)
  237. #满足均衡开启条件————————————————————————————————————————————————————————————————————————————————————
  238. if min(cellvolt)>2 and max(cellvolt)<4.5 and packsoc>20 and max(cellvolt)-min(cellvolt)>voltdiff:
  239. #寻找并判断最大电压是否在均衡
  240. cellmax_index=list(cellvolt).index(max(cellvolt))+1
  241. bal_group = cellmax_index // self.param.BalGroups #取整
  242. bal_index = cellmax_index % self.param.BalGroups #取余
  243. if bal_index==0:
  244. bal_index=self.param.BalNums
  245. else:
  246. pass
  247. #获取BMS当前最大电芯电压的均衡状态
  248. bmscellmax_balgroup=bms_balstate[bal_group]
  249. bmscellmax_balgroup >> bal_index-1
  250. bmscellmax_balstate=bmscellmax_balgroup & 1
  251. if bmscellmax_balstate==1: #最大电压在均衡
  252. pass
  253. else: #最大电芯不在均衡
  254. cellvoltdiff=cellvolt-min(cellvolt)
  255. cellvoltdiff=cellvoltdiff[cellvoltdiff>voltdiff]=1 #压差>阈值的赋1
  256. cellvoltdiff=cellvoltdiff[cellvoltdiff<=voltdiff]=0 #压差<=阈值的赋0
  257. cellvoltdiff=list(map(int,cellvoltdiff))
  258. #均衡状态按照分组赋值————————————————————————————————————————————————
  259. limsbalctrl=[]
  260. for i in range(self.param.BalGroups):
  261. balstate=0
  262. cellvoltdiff_group=cellvoltdiff[self.param.BalNums*i : self.param.BalNums*(i+1)]
  263. for j in range(self.param.BalNums): #计算每一个分组的均衡状态
  264. balstate=balstate+cellvoltdiff_group[j]*2**j
  265. limsbalctrl.append(balstate)
  266. dict_send={"cmd_type":3,"factory":factory,"sn":sn,"batbalctrl":limsbalctrl}
  267. self._rabbit_send(dict_send)
  268. time.sleep(0.1)
  269. #不满足均衡开启条件————————————————————————————————————————————————————————————————————————————————————
  270. else:
  271. limsbalctrl=[0]*self.param.BalGroups #所有电芯均衡关闭
  272. dict_send={"cmd_type":3,"factory":factory,"sn":sn,"batbalctrl":limsbalctrl}
  273. self._rabbit_send(dict_send)
  274. time.sleep(0.1)