123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- 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.heat_filter_index = 1
- self.heat_filter = ["00000000"] + ['' for i in range(9)]
- 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}拉速'))
- # 5号机
- if self.hostsend_flag:
- # 拉速积分得到长度
- self.integration_total = [0] * 8
- self.integration_lock = threading.Lock()
- self.billet_out_sig = [self.data_s7.make_point(f"L{i+1}拉速", Integration_speed_mpmin) for i in range(8)]
- self.billet_position = [
- self.data_s7.make_point('L1切割信号[1]'),
- self.data_s7.make_point('L2切割信号[1]'),
- self.data_s7.make_point('L3切割信号[1]'),
- self.data_s7.make_point('L4切割信号[1]'),
- self.data_s7.make_point('L5切割信号[1]'),
- self.data_s7.make_point('L6切割信号[1]'),
- self.data_s7.make_point('L7切割信号[1]'),
- self.data_s7.make_point('L8切割信号[1]')
- ]
- # 6号机
- 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)
- # 6号机
- 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))
- # 5号机
- else:
- # 拉速补充钢坯
- self.billet_out_sig[i].set_convertor(lambda data, i=i: round(data*1000) >= self.integration_total[i] + self.length_cutting[i].data)
- self.billet_out_sig[i].set_excite_action(lambda i=i: self.billet_out_action(i))
- # 正常情况进入跟踪
- self.billet_position[i].set_excite_action(lambda i=i: self.billet_in_buffer_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()
- # 5号机直轧挡板抬起
- 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
- # 积分的钢坯长度的累计
- with self.integration_lock:
- if self.strands_cutting[i]:
- return None
- self.integration_total[i] += sizing
-
- # [坯号, 炉次信息, 定尺, 拉速, 开切时间, 停切时间]
- self.billet_out[i] = [billetNo, self.current_heatData, sizing, speed, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), '']
- # 等待20s,若无开切信号,即为漏坯
- start_time = time.time()
- while time.time() - start_time < 20:
- if self.strands_cutting[i]:
- return None
- time.sleep(0.5)
- self.billet_in_buffer_action(i)
- def billet_in_buffer_action(self, i):
- with self.locks[i]:
- if self.strands_cutting[i]:
- time.sleep(15)
- 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):
- time.sleep(1)
- 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 gp_tmp[0][:8] not in self.heat_filter:
- 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.heat_filter[self.heat_filter_index] = self.current_heatNo
- self.heat_filter_index = (self.heat_filter_index + 1) % 10
- # 上一炉终止信号在这里发
- 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 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:
- with self.integration_lock:
- self.billet_out_sig[i].data = 0
- self.integration_total[i] = 0
- 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: list):
- for i in range(len(src)-1, -1, -1):
- if len(src[i]) >= 4:
- tmp = [j[0] for j in src.pop(i)]
- src.append([])
- if tmp[0].startswith('0'):
- return []
- return tmp
-
- return []
-
- def billet_to_stack(self, stackNo, billets):
- self.logger.info(f"有钢坯放入{stackNo}堆垛")
- # [坯号, 炉次信息, 定尺, 拉速, 开切时间, 停切时间]
|