import logging from utils.statepoint import * from utils.s7data import * from models.data_sender import * class Trace_pusher: def __init__(self, data_s7: S7data, logger: logging.Logger, sender: Sender, strand_position: list, hostsend_flag=False, hostmove_flag=False): self.data_s7 = data_s7 self.logger = logger self.sender = sender self.strands_cutting = [[], [], [], [], [], [], [], []] self.strands_buffer = [[], [], [], [], [], [], [], []] self.locks = [threading.Lock() for i in range(8)] self.strand_position = strand_position self.hostsend_flag = hostsend_flag self.hostmove_flag = hostmove_flag self.old_heatNo = "00000000" self.current_heatNo = "00000000" self.old_heatData = {} self.current_heatData = {} self.total = 0 self.strand = [0, 0, 0, 0, 0, 0, 0, 0] self.count_lock = threading.Lock() self.sizing_count_heatNo = "00000000" self.sizing_count = {} self.pusher_left_list = [] self.pusher_right_list = [] self.bed_left = [[], [], []] self.bed_right = [[], [], []] self.pusher_left = data_s7.make_point('推钢机激光') self.pusher_right = data_s7.make_point('推钢机激光') self.pusher_left.hmd_add(0) self.pusher_right.hmd_add(0) self.pusher_left.set_convertor(lambda data: data < min(self.strand_position)) self.pusher_right.set_convertor(lambda data: data > max(self.strand_position)) self.pusher_left.set_excite_action(lambda: self.arrive_cooling_bed('left')) self.pusher_right.set_excite_action(lambda: self.arrive_cooling_bed('right')) self.billet_out = [[], [], [], [], [], [], [], []] self.length_cutting = [] for i in range(8): self.length_cutting.append(self.data_s7.make_point(f'L{i+1}定尺')) self.drawing_speed = [] for i in range(8): self.drawing_speed.append(self.data_s7.make_point(f'L{i+1}拉速')) if self.hostsend_flag: self.billet_position = [ Through_state_continues3(data_s7.make_point('集群限位L1_1[3]'), data_s7.make_point('集群限位L1_1[4]'), data_s7.make_point('集群限位L1_1[5]')), Through_state_continues3(data_s7.make_point('集群限位L2_1[3]'), data_s7.make_point('集群限位L2_1[4]'), data_s7.make_point('集群限位L2_1[5]')), Through_state_continues3(data_s7.make_point('集群限位L3_1[3]'), data_s7.make_point('集群限位L3_1[4]'), data_s7.make_point('集群限位L3_1[5]')), Through_state_continues3(data_s7.make_point('集群限位L4_1[3]'), data_s7.make_point('集群限位L4_1[4]'), data_s7.make_point('集群限位L4_1[5]')), Through_state_continues3(data_s7.make_point('集群限位L5_1[3]'), data_s7.make_point('集群限位L5_1[4]'), data_s7.make_point('集群限位L5_1[5]')), Through_state_continues3(data_s7.make_point('集群限位L6_1[3]'), data_s7.make_point('集群限位L6_1[4]'), data_s7.make_point('集群限位L6_1[5]')), Through_state_separation2(data_s7.make_point('集群限位L7_1[4]'), data_s7.make_point('集群限位L7_1[5]')), Through_state_continues3(data_s7.make_point('集群限位L8_1[3]'), data_s7.make_point('集群限位L8_1[4]'), data_s7.make_point('集群限位L8_1[5]')) ] self.billet_out_sig = [ data_s7.make_point('集群限位L1_2[1]'), data_s7.make_point('集群限位L2_2[1]'), data_s7.make_point('集群限位L3_2[1]'), data_s7.make_point('集群限位L4_2[1]'), data_s7.make_point('集群限位L5_2[1]'), data_s7.make_point('集群限位L6_2[1]'), data_s7.make_point('集群限位L7_2[1]'), data_s7.make_point('集群限位L8_2[1]') ] else: self.billet_position = [ self.data_s7.make_point('L1坯头位置'), self.data_s7.make_point('L2坯头位置'), self.data_s7.make_point('L3坯头位置'), self.data_s7.make_point('L4坯头位置'), self.data_s7.make_point('L5坯头位置'), self.data_s7.make_point('L6坯头位置'), self.data_s7.make_point('L7坯头位置'), self.data_s7.make_point('L8坯头位置') ] self.barrier = [ self.data_s7.make_point('L1挡板'), self.data_s7.make_point('L2挡板'), self.data_s7.make_point('L3挡板'), self.data_s7.make_point('L4挡板'), self.data_s7.make_point('L5挡板'), self.data_s7.make_point('L6挡板'), self.data_s7.make_point('L7挡板'), self.data_s7.make_point('L8挡板') ] self.barrier_checker = [False, False, False, False, False, False, False, False] if self.hostsend_flag: self.hostsend_barrier = [ self.data_s7.make_point('热送挡板[0]'), self.data_s7.make_point('热送挡板[1]'), self.data_s7.make_point('热送挡板[2]'), self.data_s7.make_point('热送挡板[3]'), self.data_s7.make_point('热送挡板[4]'), self.data_s7.make_point('热送挡板[5]'), self.data_s7.make_point('热送挡板[6]'), self.data_s7.make_point('热送挡板[7]'), ] if self.hostmove_flag: self.hostmove_sig = data_s7.make_point('推钢机激光') self.hostmove_sig.hmd_add(0) self.hostmove_sig.set_convertor(lambda data: data > 19000) self.hostmove_sig.set_excite_action(lambda: self.billet_to_stack("步进冷床", self.get_billet('right'))) for i in range(8): # 坯子出现 self.billet_position[i].allow_update(False) self.billet_position[i].set_state(False) if not self.hostsend_flag: self.billet_position[i].set_convertor(lambda data: 12000 < data < 20000) self.billet_position[i].set_excite_action(lambda i=i: self.billet_out_action(i)) self.billet_position[i].set_reset_action(lambda i=i: self.billet_in_buffer_action(i)) else: self.billet_position[i].set_excite_action(lambda i=i: self.billet_in_buffer_action(i)) self.billet_out_sig[i].set_excite_action(lambda i=i: self.billet_out_action(i)) self.billet_position[i].allow_update() # 挡板抬起 self.barrier[i].allow_update(False) self.barrier[i].set_state(False) self.barrier[i].set_convertor(lambda data: not bool(data)) self.barrier[i].set_excite_action(lambda i=i: self.barrier_up_action(i)) self.barrier[i].set_reset_action(lambda i=i: self.barrier_down_action(i)) self.barrier[i].allow_update() # 直轧挡板抬起 if self.hostsend_flag: self.hostsend_barrier[i].allow_update(False) self.hostsend_barrier[i].set_state(False) self.hostsend_barrier[i].set_convertor(lambda data: not bool(data)) self.hostsend_barrier[i].set_excite_action(lambda i=i: self.hostsend_barrier_up_action(i)) self.hostsend_barrier[i].set_reset_action(lambda i=i: self.logger.debug(f"{i+1}流热送挡板关闭")) self.hostsend_barrier[i].allow_update() def billet_out_action(self, i): # [坯号, 炉次信息, 定尺, 拉速, 开切时间, 停切时间] billetNo = self.current_heatNo + '0' + str(i+1) + '99' sizing = self.length_cutting[i].data speed = self.drawing_speed[i].data self.billet_out[i] = [billetNo, self.current_heatData, sizing, speed, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), ''] def billet_in_buffer_action(self, i): with self.locks[i]: if self.strands_cutting[i]: self.logger.info(f"[TRACE]{i+1}流新增钢坯存储") self.strands_buffer[i] = self.strands_cutting[i] self.strands_cutting[i] = [] elif self.billet_out[i]: self.logger.info(f"[TRACE]{i+1}流开切漏钢,算法补入") self.strands_buffer[i] = self.billet_out[i] else: self.logger.info(f"[TRACE]{i+1}流开切漏钢,但未检测到可补入钢坯的信息") self.billet_out[i] = [] if self.barrier[i].state and self.barrier_checker[i] == False: self.barrier_up_action(i) def barrier_up_action(self, i): with self.locks[i]: if self.strands_buffer[i]: self.barrier_checker[i] = True time.sleep(12) billetData = self.strands_buffer[i] self.strands_buffer[i] = [] if self.strand_position[i] <= self.pusher_left.data: self.logger.info(f"[TRACE]{i+1}流钢坯通过挡板进入推钢区域,在推钢机左侧") self.pusher_left_list.append(billetData) else: self.logger.info(f"[TRACE]{i+1}流钢坯通过挡板进入推钢区域,在推钢机右侧") self.pusher_right_list.append(billetData) if self.hostsend_flag and self.hostsend_barrier[i].state: self.hostsend_barrier_up_action(i) def barrier_down_action(self, i): if self.barrier_checker[i]: self.logger.debug(f"[TRACE]{i+1}流挡板关闭") else: self.logger.error(f"[TRACE]{i+1}流挡板关闭,期间无钢坯流出") self.barrier_checker[i] = False def hostsend_barrier_up_action(self, i): with self.count_lock: gp_tmp = [] if self.strand_position[i] <= self.pusher_left.data: index = -1 for j in range(len(self.pusher_left_list)-1, -1, -1): if self.pusher_left_list[j][0][-3] == str(i+1): index = j break if index == -1: pass #self.logger.warning(f"[TRACE]推钢机左侧未找到{i+1}流的热送钢坯") else: gp_tmp = self.pusher_left_list[index] self.pusher_left_list = self.pusher_left_list[:index] + self.pusher_left_list[index+1:] else: index = -1 for j in range(len(self.pusher_right_list)-1, -1, -1): if self.pusher_right_list[j][0][-3] == str(i+1): index = j break if index == -1: pass #self.logger.warning(f"[TRACE]推钢机右侧未找到{i+1}流的热送钢坯") else: gp_tmp = self.pusher_right_list[index] self.pusher_right_list = self.pusher_right_list[:index] + self.pusher_right_list[index+1:] if gp_tmp: self.logger.info(f"[TRACE]{i+1}流钢坯热送") if not (gp_tmp[0].startswith(self.current_heatNo) or gp_tmp[0].startswith(self.old_heatNo)): self.change_heat(gp_tmp) if not gp_tmp[0].startswith('0'): self.hostsend(gp_tmp) def change_heat(self, data): # 换炉代码 self.old_heatNo = self.current_heatNo self.old_heatData = self.current_heatData self.current_heatNo = data[0][:8] self.current_heatData = data[1] # 上一炉终止信号在这里发 self.total = 0 self.strand = [0, 0, 0, 0, 0, 0, 0, 0] def arrive_cooling_bed(self, direc): with self.count_lock: if direc == 'left': self.logger.debug(f"左侧冷床上推入{len(self.pusher_left_list)}根钢坯") tmp = self.pusher_left_list self.pusher_left_list = [] elif direc == 'right': self.logger.debug(f"右侧冷床上推入{len(self.pusher_right_list)}根钢坯") tmp = self.pusher_right_list self.pusher_right_list = [] for i in tmp: if not (i[0].startswith(self.current_heatNo) or i[0].startswith(self.old_heatNo)): self.change_heat(i) break self.billet_to_bed(tmp, direc) def billet_to_bed(self, billets, direc): if direc == 'left': if len(billets): self.billet_to_bed_impl(billets, self.bed_left) self.logger.debug(f"左侧冷床目前情况:{len(self.bed_left[0])}根|{len(self.bed_left[1])}根|{len(self.bed_left[2])}根") elif direc == 'right': if len(billets): self.billet_to_bed_impl(billets, self.bed_right) self.logger.debug(f"右侧冷床目前情况:{len(self.bed_right[2])}根|{len(self.bed_right[1])}根|{len(self.bed_right[0])}根") def billet_to_bed_impl(self, billets: list, dst: list): i = 0 count = 0 while i < len(dst) and dst[i]: count += 1 i += 1 if count == 0: dst[0].extend(billets) # elif count == 3 and (len(billets) >= 4 or len(dst[count-1]) >= 4): # self.logger.error(f"组坯异常!") # flag = False # for j in dst: # if len(j) < 4: # flag = True # dst.remove(j) # break # if flag: # dst.append(billets) # else: # dst.remove(dst[0]) # dst.append(billets) # count -= 1 # elif count == 3 and len(dst[count-1]) + len(billets) > 4: # self.logger.error(f"组坯异常!") # dst[count-1].extend(billets) # count -= 1 elif count == 3 and (len(billets) >= 4 or len(dst[count-1]) >= 4 or len(dst[count-1]) + len(billets) > 4): self.logger.error(f"组坯异常!") dst.remove(dst[0]) dst.append(billets) count -= 1 elif len(billets) >= 4 or len(dst[count-1]) >= 4 or len(dst[count-1]) + len(billets) > 4: dst[count].extend(billets) else: dst[count-1].extend(billets) count -= 1 if len(dst[count]) >= 4: self.billet_union(dst[count]) def billet_union(self, billets): if self.sizing_count_heatNo != self.current_heatNo: self.sizing_count_heatNo = self.current_heatNo self.sizing_count = {} if billets[0][2] not in self.sizing_count: self.sizing_count[billets[0][2]] = 0 self.sizing_count[billets[0][2]] += 1 billet_unionNo = self.current_heatNo + '{:0>5}'.format(int(billets[0][2])) + '{:0>2}'.format(self.sizing_count[billets[0][2]]) billetsNo = [] ccmNo = self.current_heatData['ccmNo'] if self.current_heatData else '0' for i in billets: strandNo = i[0][9] self.total += 1 self.strand[int(strandNo)-1] += 1 billetNo = self.current_heatNo + ccmNo + strandNo + '{:0>2}'.format(self.strand[int(strandNo)-1]) billetsNo.append(billetNo) i[0] = billetNo i[1] = self.current_heatData if self.current_heatData: self.sender.billet_upload(self.current_heatData, billetNo, self.total, i[2], i[3], i[4], i[5], billet_unionNo) if self.current_heatData: self.sender.billet_union(self.current_heatData, billet_unionNo, billetsNo, int(billets[0][2])) self.logger.info(f"{self.current_heatNo}炉组号{billet_unionNo}钢坯{len(billets)}根:\n {'、'.join(billetsNo)}") def data_from_casting(self, i, data, extend=False): with self.locks[i]: if extend: if self.strands_cutting[i] and self.strands_cutting[i][0] == data[0]: self.logger.info(f"{i+1}流补充了钢坯停切时间") self.strands_cutting[i] = data elif self.strands_buffer[i] and self.strands_buffer[i][0] == data[0]: self.logger.info(f"{i+1}流补充了钢坯停切时间") self.strands_buffer[i] = data else: self.logger.warning(f"{i+1}流对已经离开的钢坯补充停切时间,无效") else: if self.strands_cutting[i]: self.logger.warning(f"{i+1}流有钢坯开切冲突") self.strands_cutting[i] = data self.strands_cutting[i].append('') else: self.logger.info(f"{i+1}流钢坯开切") self.strands_cutting[i] = data self.strands_cutting[i].append('') def hostsend(self, i): ccmNo = self.current_heatData['ccmNo'] strandNo = i[0][9] self.total += 1 self.strand[int(strandNo)-1] += 1 billetNo = self.current_heatNo + ccmNo + strandNo + '{:0>2}'.format(self.strand[int(strandNo)-1]) i[0] = billetNo i[1] = self.current_heatData self.sender.billet_upload(self.current_heatData, billetNo, self.total, i[2], i[3], i[4], i[5], '') self.logger.info(f"{self.current_heatNo}炉钢坯热送:{billetNo}") self.sender.host_send(ccmNo, billetNo, "棒一") def clean_status(self): self.logger.debug(f"[TRACE]小冷床状态清空") with self.count_lock: self.pusher_left_list = [] self.pusher_right_list = [] self.bed_left = [[], [], []] self.bed_right = [[], [], []] def get_billet(self, direc): with self.count_lock: if direc == "left": return self.get_billet_action(self.bed_left) if direc == "right": return self.get_billet_action(self.bed_right) def get_billet_action(self, src): for i in range(len(src)-1, -1, -1): if len(src[i]) >= 4: tmp = [j[0] for j in src[i]] src[i] = [] return tmp return [] def billet_to_stack(self, stackNo, billets): self.logger.info(f"有钢坯放入{stackNo}堆垛") # [坯号, 炉次信息, 定尺, 拉速, 开切时间, 停切时间]