CBMSBatCtrl.py 16 KB

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