|
|
@@ -2,427 +2,203 @@ import logging
|
|
|
from utils.statepoint import *
|
|
|
from utils.s7data import *
|
|
|
from models.data_sender import *
|
|
|
+from models.batcher import *
|
|
|
+import queue
|
|
|
|
|
|
class Trace_pusher:
|
|
|
- def __init__(self, data_s7: S7data, logger: logging.Logger, sender: Sender, strand_position: list, manual_change_heat_sig: Statepoint, hostsend_flag=False, hostmove_flag=False):
|
|
|
+ def __init__(self, billet_input: list[queue.Queue[Billet]], data_s7: S7data, logger: logging.Logger, sender: Sender, strand_position: list, hostsend_flag=False, hostmove_flag=False):
|
|
|
+ self.billet_input = billet_input
|
|
|
self.data_s7 = data_s7
|
|
|
self.logger = logger
|
|
|
self.sender = sender
|
|
|
- self.manual_change_heat_sig = manual_change_heat_sig
|
|
|
- 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.cool_bed_lock = threading.Lock()
|
|
|
+
|
|
|
+ # 挡板事件 出坯到推钢区域
|
|
|
+ self.barrier_up_sig = [self.data_s7.make_point(f'L{i+1}挡板') for i in range(8)]
|
|
|
+ self.barrier_checker = [False, False, False, False, False, False, False, False]
|
|
|
+
|
|
|
+ for i in range(8):
|
|
|
+ self.barrier_up_sig[i].set_convertor(lambda data: not bool(data))
|
|
|
+ self.barrier_up_sig[i].set_excite_action(lambda i=i: self.barrier_up_action(i))
|
|
|
+ self.barrier_up_sig[i].set_reset_action(lambda i=i: self.barrier_down_action(i))
|
|
|
|
|
|
+ # 推钢事件 推钢到南北小冷床
|
|
|
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.manual_change_heat_sig.set_excite_action(self.manual_change_heat)
|
|
|
+ self.pusher_left_list: list[Billet] = []
|
|
|
+ self.pusher_right_list: list[Billet] = []
|
|
|
|
|
|
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号机 + 6号机
|
|
|
- # 拉速积分得到长度
|
|
|
- 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.speed_to_zero_sig = [self.data_s7.make_point(f"L{i+1}拉速") 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]')
|
|
|
- ]
|
|
|
-
|
|
|
- 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]')
|
|
|
- ]
|
|
|
+ self.hostsend_barrier = [self.data_s7.make_point(f'热送挡板[{i}]') for i in range(8)]
|
|
|
|
|
|
+ for i in range(8):
|
|
|
+ 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"[TRACE]{i+1}流热送挡板关闭"))
|
|
|
+
|
|
|
+ # 热送副跨事件(仅六号机)
|
|
|
if self.hostmove_flag:
|
|
|
self.hostmove_sig = data_s7.make_point('热送辊道状态[1]')
|
|
|
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)
|
|
|
- self.billet_out_sig[i].allow_update(False)
|
|
|
- self.billet_out_sig[i].set_state(False)
|
|
|
- # 6号机 + 5号机
|
|
|
- # 拉速补充钢坯
|
|
|
- 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))
|
|
|
- # 拉速为0时表示此时拉速补偿已经不可用
|
|
|
- self.speed_to_zero_sig[i].set_convertor(lambda data: data == 0)
|
|
|
- self.speed_to_zero_sig[i].set_excite_action(lambda i=i: self.billet_out_sig[i].allow_update(False))
|
|
|
- # 正常情况进入跟踪
|
|
|
- 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 integration_start(self, i):
|
|
|
- if self.speed_to_zero_sig[i].data == 0:
|
|
|
- return None
|
|
|
- self.billet_out_sig[i].data = 0
|
|
|
- self.billet_out_sig[i].state = False
|
|
|
- self.integration_total[i] = 0
|
|
|
- self.billet_out_sig[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
|
|
|
-
|
|
|
- if self.strands_cutting[i]:
|
|
|
- return None
|
|
|
-
|
|
|
- # [坯号, 炉次信息, 定尺, 拉速, 开切时间, 停切时间]
|
|
|
- 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)
|
|
|
-
|
|
|
- # 漏钢时,积分数据不会被清零,需要累加
|
|
|
- with self.integration_lock:
|
|
|
- self.integration_total[i] += sizing
|
|
|
- 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]
|
|
|
+ def barrier_up_action(self, i: int):
|
|
|
+ self.logger.debug(f"[TRACE]{i+1}流挡板开启")
|
|
|
+ while self.barrier_up_sig[i].converter(self.barrier_up_sig[i].data):
|
|
|
+ if self.billet_input[i].empty() or datetime.datetime.now() - self.billet_input[i].queue[0].start_cutting_time < datetime.timedelta(seconds=25):
|
|
|
+ time.sleep(0.5)
|
|
|
+ continue
|
|
|
+ billet = self.billet_input[i].get(False)
|
|
|
+ self.barrier_checker[i] = True
|
|
|
+ self.logger.debug(f"[TRACE]{i+1}流钢坯经过挡板")
|
|
|
+ time.sleep(10)
|
|
|
+ if self.strand_position[i] <= self.pusher_left.data:
|
|
|
+ self.logger.info(f"[TRACE]{i+1}流钢坯通过挡板进入推钢区域,在推钢机北侧")
|
|
|
+ self.pusher_left_list.append(billet)
|
|
|
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(10)
|
|
|
- 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)
|
|
|
-
|
|
|
+ self.logger.info(f"[TRACE]{i+1}流钢坯通过挡板进入推钢区域,在推钢机南侧")
|
|
|
+ self.pusher_right_list.append(billet)
|
|
|
+ if self.hostsend_flag and self.hostsend_barrier[i].state:
|
|
|
+ self.hostsend_barrier_up_action(i)
|
|
|
+ time.sleep(5)
|
|
|
|
|
|
- def barrier_down_action(self, i):
|
|
|
+ def barrier_down_action(self, i: int):
|
|
|
if self.barrier_checker[i]:
|
|
|
self.logger.debug(f"[TRACE]{i+1}流挡板关闭")
|
|
|
else:
|
|
|
- self.logger.error(f"[TRACE]{i+1}流挡板关闭,期间无钢坯流出")
|
|
|
+ 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('0') and gp_tmp[0][:8] not in self.heat_filter:
|
|
|
- self.change_heat(gp_tmp)
|
|
|
- if not self.current_heatNo.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 manual_change_heat(self):
|
|
|
- with self.count_lock:
|
|
|
- tmp = self.manual_change_heat_sig.data
|
|
|
- if tmp['heatNo'] == self.current_heatNo:
|
|
|
- return None
|
|
|
-
|
|
|
- self.logger.info(f"手动换炉触发:{self.current_heatNo}->{tmp['heatNo']}")
|
|
|
-
|
|
|
- tmp['sendTime'] = tmp['startPourTime']
|
|
|
- self.sender.begin_pour(tmp, max(self.data_s7.get_value('大包重量1'), self.data_s7.get_value('大包重量2')))
|
|
|
-
|
|
|
- self.change_heat([tmp['heatNo'], tmp])
|
|
|
|
|
|
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('0') and i[0][:8] not in self.heat_filter:
|
|
|
- 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])}根")
|
|
|
+ tmp = self.pusher_left_list
|
|
|
+ self.pusher_left_list = []
|
|
|
+ tmp.sort(key=lambda obj: obj.strand_no)
|
|
|
+ dst = self.bed_left
|
|
|
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"组坯异常!")
|
|
|
-
|
|
|
- # test 把无法组坯的不正常钢坯 直接上传服务器
|
|
|
- tmp = dst[0]
|
|
|
- if len(tmp) < 4:
|
|
|
- self.billet_union(tmp)
|
|
|
-
|
|
|
- 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)
|
|
|
+ tmp = self.pusher_right_list
|
|
|
+ self.pusher_right_list = []
|
|
|
+ tmp.sort(key=lambda obj: obj.strand_no, reverse=True)
|
|
|
+ dst = self.bed_right
|
|
|
else:
|
|
|
- dst[count-1].extend(billets)
|
|
|
- count -= 1
|
|
|
+ return
|
|
|
+
|
|
|
+ if tmp:
|
|
|
+ self.billet_to_bed(tmp, dst, True if direc == "right" else False)
|
|
|
+
|
|
|
+ def billet_to_bed(self, billets: list[Billet], dst: list[list[Billet]], union_reverse = False):
|
|
|
+ with self.cool_bed_lock:
|
|
|
+ len_count = len(billets)
|
|
|
+ # 找到第一个空位
|
|
|
+ count = 0
|
|
|
+ while count < len(dst) and dst[count]:
|
|
|
+ count += 1
|
|
|
+
|
|
|
+ if count == 0:
|
|
|
+ dst[0].extend(billets)
|
|
|
+ elif count == len(dst) and (len_count >= 4 or len(dst[count-1]) >= 4 or len(dst[count-1]) + len_count > 4):
|
|
|
+ self.logger.error(f"[TRACE]组坯异常!")
|
|
|
+
|
|
|
+ tmp = dst.pop(0)
|
|
|
+ dst.append(billets)
|
|
|
+
|
|
|
+ # test 把无法组坯的不正常钢坯 直接上传服务器
|
|
|
+ if len(tmp) < 4:
|
|
|
+ self.billet_union(tmp)
|
|
|
+
|
|
|
+ count -= 1
|
|
|
+ elif len_count >= 4 or len(dst[count-1]) >= 4 or len(dst[count-1]) + len_count > 4:
|
|
|
+ dst[count].extend(billets)
|
|
|
+ else:
|
|
|
+ count -= 1
|
|
|
+ dst[count].extend(billets)
|
|
|
|
|
|
- if len(dst[count]) >= 4:
|
|
|
- self.billet_union(dst[count])
|
|
|
+ if len(dst[count]) >= 4:
|
|
|
+ self.billet_union(dst[count], union_reverse)
|
|
|
|
|
|
+ if not union_reverse:
|
|
|
+ self.logger.info(f"[TRACE]北侧冷床上推入{len_count}根钢坯,目前情况:{len(self.bed_left[0])}根|{len(self.bed_left[1])}根|{len(self.bed_left[2])}根")
|
|
|
+ else:
|
|
|
+ self.logger.info(f"[TRACE]南侧冷床上推入{len_count}根钢坯,目前情况:{len(self.bed_right[2])}根|{len(self.bed_right[1])}根|{len(self.bed_right[0])}根")
|
|
|
|
|
|
- def billet_union(self, billets):
|
|
|
- ccmNo = self.current_heatData['ccmNo'] if self.current_heatData else '0'
|
|
|
+ def billet_union(self, billets: list[Billet], reverse = False):
|
|
|
+ if reverse:
|
|
|
+ billets.reverse()
|
|
|
|
|
|
if len(billets) < 4:
|
|
|
for i in billets:
|
|
|
- strandNo = i[0][9]
|
|
|
- billetNo = self.current_heatNo + ccmNo + strandNo + '{:0>2}'.format(99)
|
|
|
- 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], '', error=True)
|
|
|
- self.logger.warning(f"{self.current_heatNo}炉发送异常钢坯{len(billets)}根")
|
|
|
- return None
|
|
|
-
|
|
|
- if self.sizing_count_heatNo != self.current_heatNo:
|
|
|
- self.sizing_count_heatNo = self.current_heatNo
|
|
|
- self.sizing_count = {}
|
|
|
-
|
|
|
- # 组坯时,定尺为此组内定尺最小值
|
|
|
- sizing = billets[0][2]
|
|
|
- for i in billets:
|
|
|
- if i[2] < sizing:
|
|
|
- sizing = i[2]
|
|
|
+ if i.batch_strand():
|
|
|
+ self.sender.billet_upload(i.heat.to_dict(), i.heat_no + i.ccm_no + str(i.strand_no) + "99", 0, i.sizing, i.drawing_speed,
|
|
|
+ i.start_cutting_time.strftime("%Y-%m-%d %H:%M:%S"), "", '', error=True)
|
|
|
+ self.logger.warning(f"[TRACE]发送异常钢坯{len(billets)}根")
|
|
|
+ return
|
|
|
|
|
|
- if sizing not in self.sizing_count:
|
|
|
- self.sizing_count[sizing] = 0
|
|
|
+ # 组坯时,定尺为此组内定尺最小值,炉次为最后一根加入此组的炉次
|
|
|
+ sizing = min(billets, key=lambda obj: obj.sizing).sizing
|
|
|
+ heat = max(billets, key=lambda obj: obj.start_cutting_time).heat
|
|
|
|
|
|
- self.sizing_count[sizing] += 1
|
|
|
- billet_unionNo = self.current_heatNo + '{:0>5}'.format(int(sizing)) + '{:0>2}'.format(self.sizing_count[sizing])
|
|
|
+ billet_unionNo = heat.heat_no + '{:0>5}'.format(int(sizing)) + '{:0>2}'.format(heat.claim_union_seq(sizing))
|
|
|
|
|
|
billetsNo = []
|
|
|
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
|
|
|
- i[2] = sizing
|
|
|
- if self.current_heatData:
|
|
|
- self.sender.billet_upload(self.current_heatData, billetNo, self.total, i[2], i[3], i[4], i[5], billet_unionNo)
|
|
|
+ i.heat = heat
|
|
|
+ i.batch_strand()
|
|
|
+ billetsNo.append(i.billet_no)
|
|
|
+ self.sender.billet_upload(heat.to_dict(), i.billet_no, i.heat_seq, i.sizing, i.drawing_speed,
|
|
|
+ i.start_cutting_time.strftime("%Y-%m-%d %H:%M:%S"), "", billet_unionNo)
|
|
|
|
|
|
- if self.current_heatData:
|
|
|
- self.sender.billet_union(self.current_heatData, billet_unionNo, billetsNo, sizing)
|
|
|
+ self.sender.billet_union(heat.to_dict(), billet_unionNo, billetsNo, sizing)
|
|
|
|
|
|
- self.logger.info(f"{self.current_heatNo}炉组号{billet_unionNo}钢坯{len(billets)}根:\n {'、'.join(billetsNo)}")
|
|
|
+ self.logger.info(f"[TRACE]{heat.heat_no}炉组号{billet_unionNo}钢坯{len(billets)}根:\n {'、'.join(billetsNo)}")
|
|
|
|
|
|
+ def hostsend_barrier_up_action(self, i: int):
|
|
|
+ gp_tmp = None
|
|
|
+ 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].strand_no == i+1:
|
|
|
+ index = j
|
|
|
+ break
|
|
|
+ if index == -1:
|
|
|
+ self.logger.debug(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].strand_no == i+1:
|
|
|
+ index = j
|
|
|
+ break
|
|
|
+ if index == -1:
|
|
|
+ self.logger.debug(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:]
|
|
|
|
|
|
- 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}流对已经离开的钢坯补充停切时间,无效")
|
|
|
+ if gp_tmp:
|
|
|
+ self.hostsend(gp_tmp)
|
|
|
|
|
|
- else:
|
|
|
- with self.integration_lock:
|
|
|
- # 验证现在拉速积分是否有效
|
|
|
- if self.billet_out_sig[i].permitted_update:
|
|
|
- # 有效:检测并把所有短尺的钢坯定尺都改为定尺软件给的
|
|
|
- if round(self.billet_out_sig[i].data * 1000) - self.integration_total[i] < 10000:
|
|
|
- data[2] = self.data_s7.get_value(f"L{i+1}短尺")
|
|
|
-
|
|
|
- # 对拉速积分进行切割信号校准
|
|
|
- self.billet_out_sig[i].data = 0
|
|
|
- self.integration_total[i] = 0
|
|
|
- else:
|
|
|
- # 无效:开启拉速积分
|
|
|
- self.integration_start(i)
|
|
|
-
|
|
|
- if self.strands_cutting[i]:
|
|
|
- self.logger.warning(f"{i+1}流有钢坯开切冲突")
|
|
|
- self.strands_cutting[i] = data
|
|
|
- else:
|
|
|
- self.logger.info(f"{i+1}流钢坯开切")
|
|
|
- self.strands_cutting[i] = data
|
|
|
-
|
|
|
- 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}炉{strandNo}流钢坯热送:{billetNo}")
|
|
|
- self.sender.host_send(ccmNo, billetNo, "棒一")
|
|
|
+ def hostsend(self, billet: Billet):
|
|
|
+ billet.batch_strand()
|
|
|
+ self.sender.billet_upload(billet.heat.to_dict(), billet.billet_no, billet.heat_seq, billet.sizing, billet.drawing_speed,
|
|
|
+ billet.start_cutting_time.strftime("%Y-%m-%d %H:%M:%S"), "", '')
|
|
|
+
|
|
|
+ self.logger.info(f"[TRACE]{billet.heat.heat_no}炉{billet.strand_no}流钢坯热送:{billet.billet_no}")
|
|
|
+ self.sender.host_send(billet.ccm_no, billet.billet_no, "棒一")
|
|
|
|
|
|
def show_coolbed(self):
|
|
|
print(f"北侧冷床目前情况:{len(self.bed_left[0])}根|{len(self.bed_left[1])}根|{len(self.bed_left[2])}根")
|
|
|
@@ -430,48 +206,28 @@ class Trace_pusher:
|
|
|
|
|
|
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 init_coolbed(self):
|
|
|
- left_count = input(f"输入北侧冷床钢坯根数序列(由外到内):")
|
|
|
- right_count = input(f"输入南侧冷床钢坯根数序列(由外到内):")
|
|
|
- if not (left_count.isdigit() and len(left_count) == 3 and right_count.isdigit() and len(right_count) == 3):
|
|
|
- warnings.warn("冷床格式化错误,请输入正确格式")
|
|
|
- return None
|
|
|
-
|
|
|
- left_count = [int(i) for i in left_count]
|
|
|
- right_count = [int(i) for i in right_count]
|
|
|
- temp = ['000000000000', {}, 0, 0, '', '']
|
|
|
- with self.count_lock:
|
|
|
- self.bed_left = [[temp.copy() for i in range(left_count[j])] for j in range(3)]
|
|
|
- self.bed_right = [[temp.copy() for i in range(right_count[j])] for j in range(3)]
|
|
|
-
|
|
|
-
|
|
|
- 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
|
|
|
+ self.pusher_left_list = []
|
|
|
+ self.pusher_right_list = []
|
|
|
+ self.bed_left = [[], [], []]
|
|
|
+ self.bed_right = [[], [], []]
|
|
|
+
|
|
|
+ def get_billet(self, direc) -> list[str]:
|
|
|
+ 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[list[Billet]]) -> list[str]:
|
|
|
+ with self.cool_bed_lock:
|
|
|
+ for i in range(len(src)-1, -1, -1):
|
|
|
+ if len(src[i]) >= 4:
|
|
|
+ tmp = [j.billet_no for j in src.pop(i)]
|
|
|
+ src.append([])
|
|
|
+ return tmp
|
|
|
|
|
|
return []
|
|
|
|
|
|
- def billet_to_stack(self, stackNo, billets):
|
|
|
+ def billet_to_stack(self, stackNo, billets: list[str]):
|
|
|
if billets:
|
|
|
- self.logger.info(f"有钢坯放入{stackNo}堆垛")
|
|
|
+ self.logger.info(f"[TRACE]有钢坯放入{stackNo}堆垛")
|
|
|
self.sender.stack_add('6', billets, "", time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), "6#小冷床(南)", '步进冷床堆垛')
|
|
|
-
|
|
|
-# [坯号, 炉次信息, 定尺, 拉速, 开切时间, 停切时间]
|