billet_trace_pusher.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. import logging
  2. from utils.statepoint import *
  3. from utils.s7data import *
  4. from models.data_sender import *
  5. class Trace_pusher:
  6. def __init__(self, data_s7: S7data, logger: logging.Logger, sender: Sender, strand_position: list, hostsend_flag=False):
  7. self.data_s7 = data_s7
  8. self.logger = logger
  9. self.sender = sender
  10. self.strands_cutting = [[], [], [], [], [], [], [], []]
  11. self.strands_buffer = [[], [], [], [], [], [], [], []]
  12. self.locks = [threading.Lock() for i in range(8)]
  13. self.strand_position = strand_position
  14. self.hostsend_flag = hostsend_flag
  15. self.old_heatNo = "00000000"
  16. self.current_heatNo = "00000000"
  17. self.old_heatData = {}
  18. self.current_heatData = {}
  19. self.total = 0
  20. self.strand = [0, 0, 0, 0, 0, 0, 0, 0]
  21. self.count_lock = threading.Lock()
  22. self.pusher_left_list = []
  23. self.pusher_right_list = []
  24. self.bed_left = []
  25. self.bed_right = []
  26. self.pusher_left = data_s7.make_point('推钢机激光')
  27. self.pusher_right = data_s7.make_point('推钢机激光')
  28. self.pusher_left.set_convertor(lambda data: data < min(self.strand_position))
  29. self.pusher_right.set_convertor(lambda data: data > max(self.strand_position))
  30. self.pusher_left.set_excite_action(lambda: self.arrive_cooling_bed('left'))
  31. self.pusher_right.set_excite_action(lambda: self.arrive_cooling_bed('right'))
  32. self.billet_out = [[], [], [], [], [], [], [], []]
  33. self.length_cutting = []
  34. for i in range(8):
  35. self.length_cutting.append(self.data_s7.make_point(f'L{i+1}定尺'))
  36. self.drawing_speed = []
  37. for i in range(8):
  38. self.drawing_speed.append(self.data_s7.make_point(f'L{i+1}拉速'))
  39. self.billet_position = [
  40. self.data_s7.make_point('L1坯头位置'),
  41. self.data_s7.make_point('L2坯头位置'),
  42. self.data_s7.make_point('L3坯头位置'),
  43. self.data_s7.make_point('L4坯头位置'),
  44. self.data_s7.make_point('L5坯头位置'),
  45. self.data_s7.make_point('L6坯头位置'),
  46. self.data_s7.make_point('L7坯头位置'),
  47. self.data_s7.make_point('L8坯头位置')
  48. ]
  49. self.barrier = [
  50. self.data_s7.make_point('L1挡板'),
  51. self.data_s7.make_point('L2挡板'),
  52. self.data_s7.make_point('L3挡板'),
  53. self.data_s7.make_point('L4挡板'),
  54. self.data_s7.make_point('L5挡板'),
  55. self.data_s7.make_point('L6挡板'),
  56. self.data_s7.make_point('L7挡板'),
  57. self.data_s7.make_point('L8挡板')
  58. ]
  59. self.barrier_checker = [False, False, False, False, False, False, False, False]
  60. if self.hostsend_flag:
  61. self.hostsend_barrier = [
  62. self.data_s7.make_point('热送挡板[0]'),
  63. self.data_s7.make_point('热送挡板[1]'),
  64. self.data_s7.make_point('热送挡板[2]'),
  65. self.data_s7.make_point('热送挡板[3]'),
  66. self.data_s7.make_point('热送挡板[4]'),
  67. self.data_s7.make_point('热送挡板[5]'),
  68. self.data_s7.make_point('热送挡板[6]'),
  69. self.data_s7.make_point('热送挡板[7]'),
  70. ]
  71. for i in range(8):
  72. # 坯子出现
  73. self.billet_position[i].allow_update(False)
  74. self.billet_position[i].set_state(False)
  75. self.billet_position[i].set_convertor(lambda data: data > 12000)
  76. self.billet_position[i].set_excite_action(lambda i=i: self.billet_out_action(i))
  77. self.billet_position[i].set_reset_action(lambda i=i: self.billet_in_buffer_action(i))
  78. self.billet_position[i].allow_update()
  79. # 挡板抬起
  80. self.barrier[i].allow_update(False)
  81. self.barrier[i].set_state(False)
  82. self.barrier[i].set_convertor(lambda data: not bool(data))
  83. self.barrier[i].set_excite_action(lambda i=i: self.barrier_up_action(i))
  84. self.barrier[i].set_reset_action(lambda i=i: self.barrier_down_action(i))
  85. self.barrier[i].allow_update()
  86. # 直轧挡板抬起
  87. if self.hostsend_flag:
  88. self.hostsend_barrier[i].allow_update(False)
  89. self.hostsend_barrier[i].set_state(False)
  90. self.hostsend_barrier[i].set_convertor(lambda data: not bool(data))
  91. self.hostsend_barrier[i].set_excite_action(lambda i=i: self.hostsend_barrier_up_action(i))
  92. self.hostsend_barrier[i].set_reset_action(lambda i=i: self.logger.debug(f"{i+1}流热送挡板关闭"))
  93. self.hostsend_barrier[i].allow_update()
  94. def billet_out_action(self, i):
  95. # [坯号, 炉次信息, 定尺, 拉速, 开切时间, 停切时间]
  96. billetNo = self.current_heatNo + '0' + str(i+1) + '99'
  97. sizing = self.length_cutting[i].data
  98. speed = self.drawing_speed[i].data
  99. self.billet_out[i] = [billetNo, self.current_heatData, sizing, speed, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), '']
  100. def billet_in_buffer_action(self, i):
  101. with self.locks[i]:
  102. if self.strands_cutting[i]:
  103. self.logger.info(f"[TRACE]{i+1}流新增钢坯存储")
  104. self.strands_buffer[i] = self.strands_cutting[i]
  105. self.strands_cutting[i] = []
  106. else:
  107. self.logger.info(f"[TRACE]{i+1}流开切漏钢,算法补入")
  108. self.strands_buffer[i] = self.billet_out[i]
  109. self.billet_out[i] = []
  110. if self.barrier[i].state and self.barrier_checker[i] == False:
  111. self.barrier_up_action(i)
  112. def barrier_up_action(self, i):
  113. with self.locks[i]:
  114. if self.strands_buffer[i]:
  115. billetData = self.strands_buffer[i]
  116. self.strands_buffer[i] = []
  117. if self.strand_position[i] <= self.pusher_left.data:
  118. self.logger.info(f"[TRACE]{i+1}流钢坯通过挡板进入推钢区域,在推钢机左侧")
  119. self.barrier_checker[i] = True
  120. self.pusher_left_list.append(billetData)
  121. else:
  122. self.logger.info(f"[TRACE]{i+1}流钢坯通过挡板进入推钢区域,在推钢机右侧")
  123. self.barrier_checker[i] = True
  124. self.pusher_right_list.append(billetData)
  125. def barrier_down_action(self, i):
  126. if self.barrier_checker[i]:
  127. self.logger.debug(f"[TRACE]{i+1}流挡板关闭")
  128. else:
  129. self.logger.error(f"[TRACE]{i+1}流挡板关闭,期间无钢坯流出")
  130. self.barrier_checker[i] = False
  131. def hostsend_barrier_up_action(self, i):
  132. with self.count_lock:
  133. gp_tmp = []
  134. if self.strand_position[i] <= self.pusher_left.data:
  135. index = -1
  136. for j in range(len(self.pusher_left_list)-1, -1, -1):
  137. if self.pusher_left_list[j][0][-3] == str(i+1):
  138. index = j
  139. break
  140. if index == -1:
  141. self.logger.warning(f"[TRACE]推钢机左侧未找到{i+1}流的热送钢坯")
  142. else:
  143. gp_tmp = self.pusher_left_list[index]
  144. self.pusher_left_list = self.pusher_left_list[:index] + self.pusher_left_list[index+1:]
  145. else:
  146. index = -1
  147. for j in range(len(self.pusher_right_list)-1, -1, -1):
  148. if self.pusher_right_list[j][0][-3] == str(i+1):
  149. index = j
  150. break
  151. if index == -1:
  152. self.logger.warning(f"[TRACE]推钢机右侧未找到{i+1}流的热送钢坯")
  153. else:
  154. gp_tmp = self.pusher_right_list[index]
  155. self.pusher_right_list = self.pusher_right_list[:index] + self.pusher_right_list[index+1:]
  156. if gp_tmp:
  157. if not (gp_tmp[0].startswith(self.current_heatNo) or gp_tmp[0].startswith(self.old_heatNo)):
  158. self.change_heat(gp_tmp)
  159. self.hostsend(gp_tmp)
  160. def change_heat(self, data):
  161. # 换炉代码
  162. self.old_heatNo = self.current_heatNo
  163. self.old_heatData = self.current_heatData
  164. self.current_heatNo = data[0][:8]
  165. self.current_heatData = data[1]
  166. # 上一炉终止信号在这里发
  167. self.total = 0
  168. self.strand = [0, 0, 0, 0, 0, 0, 0, 0]
  169. def arrive_cooling_bed(self, direc):
  170. with self.count_lock:
  171. if direc == 'left':
  172. if len(self.pusher_left_list) >= 4:
  173. if len(self.bed_left):
  174. self.logger.warning(f"有左侧冷床上的钢坯无法录入:{'、'.join([i[0] for i in self.bed_left])}")
  175. self.bed_left = []
  176. self.logger.debug(f"左侧冷床上推入{len(self.pusher_left_list)}根钢坯")
  177. self.bed_left.extend(self.pusher_left_list)
  178. self.pusher_left_list = []
  179. if len(self.bed_left) >= 4:
  180. for i in self.bed_left:
  181. if not (i[0].startswith(self.current_heatNo) or i[0].startswith(self.old_heatNo)):
  182. self.change_heat(i)
  183. break
  184. tmp = self.bed_left
  185. self.bed_left = []
  186. self.billet_union(tmp)
  187. elif direc == 'right':
  188. if len(self.pusher_right_list) >= 4:
  189. if len(self.bed_right):
  190. self.logger.warning(f"有右侧冷床上的钢坯无法录入:{'、'.join([i[0] for i in self.bed_right])}")
  191. self.bed_right = []
  192. self.logger.debug(f"右侧冷床上推入{len(self.pusher_right_list)}根钢坯")
  193. self.bed_right.extend(self.pusher_right_list)
  194. self.pusher_right_list = []
  195. if len(self.bed_right) >= 4:
  196. for i in self.bed_right:
  197. if not (i[0].startswith(self.current_heatNo) or i[0].startswith(self.old_heatNo)):
  198. self.change_heat(i)
  199. break
  200. tmp = self.bed_right
  201. self.bed_right = []
  202. self.billet_union(tmp)
  203. def billet_union(self, billets):
  204. billetsNo = []
  205. ccmNo = self.current_heatData['ccmNo'] if self.current_heatData else '0'
  206. for i in billets:
  207. strandNo = i[0][9]
  208. self.total += 1
  209. self.strand[int(strandNo)-1] += 1
  210. billetNo = self.current_heatNo + ccmNo + strandNo + '{:0>2}'.format(self.strand[int(strandNo)-1])
  211. billetsNo.append(billetNo)
  212. if self.current_heatData:
  213. self.sender.billet_upload(self.current_heatData, billetNo, self.total, i[2], i[3], i[4], i[5])
  214. self.logger.info(f"{self.current_heatNo}炉{len(billets)}根钢坯组成了一夹子:{'、'.join(billetsNo)}")
  215. def data_from_casting(self, i, data, extend=False):
  216. with self.locks[i]:
  217. if extend:
  218. if self.strands_cutting[i] and self.strands_cutting[i][0] == data[0]:
  219. self.logger.info(f"{i+1}流补充了钢坯停切时间")
  220. self.strands_cutting[i] = data
  221. elif self.strands_buffer[i] and self.strands_buffer[i][0] == data[0]:
  222. self.logger.info(f"{i+1}流补充了钢坯停切时间")
  223. self.strands_buffer[i] = data
  224. else:
  225. self.logger.warning(f"{i+1}流对已经离开的钢坯补充停切时间,无效")
  226. else:
  227. if self.strands_cutting[i]:
  228. self.logger.warning(f"{i+1}流有钢坯开切冲突")
  229. self.strands_cutting[i] = data
  230. self.strands_cutting[i].append('')
  231. else:
  232. self.logger.info(f"{i+1}流钢坯开切")
  233. self.strands_cutting[i] = data
  234. self.strands_cutting[i].append('')
  235. def hostsend(self, i):
  236. ccmNo = self.current_heatData['ccmNo']
  237. strandNo = i[0][9]
  238. self.total += 1
  239. self.strand[int(strandNo)-1] += 1
  240. billetNo = self.current_heatNo + ccmNo + strandNo + '{:0>2}'.format(self.strand[int(strandNo)-1])
  241. self.sender.billet_upload(self.current_heatData, billetNo, self.total, i[2], i[3], i[4], i[5])
  242. self.logger.info(f"{self.current_heatNo}炉钢坯热送:{billetNo}")
  243. # [坯号, 炉次信息, 定尺, 拉速, 开浇时间, 停浇时间]