import time, threading from utils.s7data import S7data from utils.logger import Logger from models.billet_trace_pusher import Trace_pusher from models.parking import Parking from models.data_sender import Sender from models.billet_stacks import Stack_manager from utils.statepoint import Statepoint class Changed_recorder: def __init__(self, point: Statepoint): self.point = point self.point.set_convertor(self.do_update) self.old_data = self.point.data self.changed_count = 0 self.changed_time = time.time() def do_update(self, data): if data != self.old_data: self.changed_count = data - self.old_data self.changed_time = time.time() self.old_data = data def get_changed(self): if time.time() - self.changed_time <= 20: return self.changed_count return 0 class Crane: def __init__(self, data_s7: S7data, tracer_5: Trace_pusher, tracer_6: Trace_pusher, parking: Parking, stack_manager: Stack_manager, sender: Sender, logger: Logger): self.data = data_s7 self.tracer_5 = tracer_5 self.tracer_6 = tracer_6 self.parking = parking self.stack_manager = stack_manager self.sender = sender self.logger = logger self.cranes = { "A1": self.data.make_point("天车A1位置"), "A2": self.data.make_point("天车A2位置"), "A3": self.data.make_point("天车A3位置") } self.billetsNo = { "A1": "", "A2": "", "A3": "" } self.billet_layer_addr = { "A1": [0, 0, 0], "A2": [0, 0, 0], "A3": [0, 0, 0] } self.billets_from = { "A1": "", "A2": "", "A3": "" } self.billets_from_stack = { "A1": "", "A2": "", "A3": "" } self.areas = { "6#小冷床(北)": [34000, 39700],#确认 "6#小冷床(南)": [20000, 24300], "车位3": [1300, 4500],#确认 "高线辊道": [60300, 62300],#确认 "601堆垛": [6000, 17000],#确认 "5#小冷床(北)": [86000, 95000], "5#小冷床(南)": [72140, 76140], "501堆垛": [105520, 117725],#确认 "车位1": [119370, 122395],#确认 "车位2": [43000, 48000]#确认 } self.car1_checker = Changed_recorder(self.data.make_point("车1车厢夹数")) self.threads_poor = [ threading.Thread(target=self.area_producer, args=("6#小冷床(北)",)), threading.Thread(target=self.area_producer, args=("6#小冷床(南)",)), threading.Thread(target=self.area_producer, args=("5#小冷床(北)",)), threading.Thread(target=self.area_producer, args=("5#小冷床(南)",)), threading.Thread(target=self.area_consumer, args=("车位1", self.car1_checker)), threading.Thread(target=self.area_consumer, args=("车位2",)), threading.Thread(target=self.area_consumer, args=("车位3",)), threading.Thread(target=self.area_consumer, args=("高线辊道",)), threading.Thread(target=self.area_stack, args=("601堆垛",)), threading.Thread(target=self.area_stack, args=("501堆垛",)) ] for i in self.threads_poor: i.start() def scan_crane(self, areaNo): start = self.areas[areaNo][0] end = self.areas[areaNo][1] while True: for key, value in self.cranes.items(): if start <= value.data <= end: return key time.sleep(0.5) def crane_leave(self, craneNo, areaNo): start = self.areas[areaNo][0] end = self.areas[areaNo][1] wait_time = 0 while True: if self.cranes[craneNo].data < start or self.cranes[craneNo].data > end: return True if wait_time >= 16: return False time.sleep(0.5) wait_time += 0.5 def area_producer(self, areaNo): while True: craneNo = self.scan_crane(areaNo) self.logger.debug(f"天车{craneNo}进入区域{areaNo}") if self.crane_leave(craneNo, areaNo): self.logger.debug(f"天车{craneNo}离开区域{areaNo}") continue if self.billetsNo[craneNo] == "": self.logger.debug(f"天车{craneNo}区域{areaNo}:正在等待或尝试夹起钢坯") if self.get_billet(craneNo, areaNo): self.logger.info(f"天车{craneNo}区域{areaNo}:获取到钢坯{self.billetsNo[craneNo]}") #test if '5#' in areaNo: if '北' in areaNo: self.logger.debug(f"5#北侧冷床目前情况:{len(self.tracer_5.bed_left[0])}根|{len(self.tracer_5.bed_left[1])}根|{len(self.tracer_5.bed_left[2])}根") else: self.logger.debug(f"5#南侧冷床目前情况:{len(self.tracer_5.bed_right[2])}根|{len(self.tracer_5.bed_right[1])}根|{len(self.tracer_5.bed_right[0])}根") elif '6#' in areaNo: if '北' in areaNo: self.logger.debug(f"6#北侧冷床目前情况:{len(self.tracer_6.bed_left[0])}根|{len(self.tracer_6.bed_left[1])}根|{len(self.tracer_6.bed_left[2])}根") else: self.logger.debug(f"6#南侧冷床目前情况:{len(self.tracer_6.bed_right[2])}根|{len(self.tracer_6.bed_right[1])}根|{len(self.tracer_6.bed_right[0])}根") else: self.logger.debug(f"天车{craneNo}区域{areaNo}:未获取到钢坯直接离开") else: self.logger.debug(f"天车{craneNo}区域{areaNo}:有未卸下的钢坯") while not self.crane_leave(craneNo, areaNo): pass self.logger.debug(f"天车{craneNo}离开区域{areaNo}") time.sleep(1) def area_consumer(self, areaNo, checker: Changed_recorder = None): while True: craneNo = self.scan_crane(areaNo) self.logger.debug(f"天车{craneNo}进入区域{areaNo}") if self.crane_leave(craneNo, areaNo): self.logger.debug(f"天车{craneNo}离开区域{areaNo}") continue if self.billetsNo[craneNo] == "" and self.billet_layer_addr[craneNo][0] == 0: self.logger.debug(f"天车{craneNo}区域{areaNo}:未携带钢坯") else: self.logger.debug(f"天车{craneNo}区域{areaNo}:正在等待或尝试卸下钢坯") if checker == None: self.unload_billet(craneNo, areaNo) while not self.crane_leave(craneNo, areaNo): pass if checker != None: count = 4 while count: time.sleep(5) count -= 1 changed = checker.get_changed() if changed > 0: self.unload_billet(craneNo, areaNo) elif changed < 0: self.logger.warning(f"区域{areaNo}产生意料之外的钢坯数量减少{-changed}根") else: continue self.logger.debug(f"天车{craneNo}离开区域{areaNo}") time.sleep(1) def area_stack(self, areaNo): while True: craneNo = self.scan_crane(areaNo) self.logger.debug(f"天车{craneNo}进入区域{areaNo}") if self.crane_leave(craneNo, areaNo): self.logger.debug(f"天车{craneNo}离开区域{areaNo}") continue while not self.crane_leave(craneNo, areaNo): pass self.logger.debug(f"天车{craneNo}离开区域{areaNo}") if areaNo[-2:] == '堆垛': self.logger.debug(f"天车{craneNo}区域{areaNo}:等待识别信号") stack_change = self.stack_manager.wait_signal(areaNo[:-2]) if stack_change[0] > 0: if self.billetsNo[craneNo] == "": self.logger.debug(f"天车{craneNo}区域{areaNo}:未携带钢坯") else: self.unload_billet(craneNo, areaNo, stack_change[1], stack_change[2]) elif stack_change[0] < 0: self.logger.info(f"天车{craneNo}区域{areaNo}:获取到钢坯({stack_change[1]}, {stack_change[2]})") self.billet_layer_addr[craneNo] = stack_change self.billets_from_stack[craneNo] = areaNo def get_billet(self, craneNo, areaNo): # 阻塞获取 start = self.areas[areaNo][0] end = self.areas[areaNo][1] tmp = [] while not bool(tmp): if self.cranes[craneNo].data < start or self.cranes[craneNo].data > end: return False if areaNo == "6#小冷床(北)": tmp = self.tracer_6.get_billet("left") elif areaNo == "6#小冷床(南)": tmp = self.tracer_6.get_billet("right") elif areaNo == "5#小冷床(北)": tmp = self.tracer_5.get_billet("left") elif areaNo == "5#小冷床(南)": tmp = self.tracer_5.get_billet("right") time.sleep(0.5) self.billetsNo[craneNo] = ','.join(tmp) self.billets_from[craneNo] = areaNo return tmp def unload_billet(self, craneNo, areaNo, layer=0, addr=0): # 直接放下 tmp = self.billetsNo[craneNo] self.billetsNo[craneNo] = "" tmp_stack_addr = self.billet_layer_addr[craneNo] self.billet_layer_addr[craneNo] = [0, 0, 0] tmp_from = self.billets_from[craneNo] self.billets_from[craneNo] = "" tmp_from_stack = self.billets_from_stack[craneNo] self.billets_from_stack[craneNo] = "" if areaNo == "车位1": if tmp_stack_addr[0]: self.logger.info(f"天车{craneNo}区域{areaNo}:放入钢坯({tmp_stack_addr[1]}, {tmp_stack_addr[2]})") self.sender.stack_car_save(self.parking.ccmNo_list[0], craneNo, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), tmp_from_stack, areaNo, tmp_stack_addr[1], tmp_stack_addr[2]) elif tmp and not tmp.startswith("00"): self.logger.info(f"天车{craneNo}区域{areaNo}:放入钢坯{tmp}") self.sender.car_save(self.parking.ccmNo_list[0], tmp, self.parking.current_car[0], craneNo, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), tmp_from, areaNo) if areaNo == "车位2": if tmp_stack_addr[0]: self.logger.info(f"天车{craneNo}区域{areaNo}:放入钢坯({tmp_stack_addr[1]}, {tmp_stack_addr[2]})") self.sender.stack_car_save(self.parking.ccmNo_list[1], craneNo, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), tmp_from_stack, areaNo, tmp_stack_addr[1], tmp_stack_addr[2]) elif tmp and not tmp.startswith("00"): self.logger.info(f"天车{craneNo}区域{areaNo}:放入钢坯{tmp}") self.sender.car_save(self.parking.ccmNo_list[1], tmp, self.parking.current_car[1], craneNo, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), tmp_from, areaNo) if areaNo == "车位3": if tmp_stack_addr[0]: self.logger.info(f"天车{craneNo}区域{areaNo}:放入钢坯({tmp_stack_addr[1]}, {tmp_stack_addr[2]})") self.sender.stack_car_save(self.parking.ccmNo_list[2], craneNo, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), tmp_from_stack, areaNo, tmp_stack_addr[1], tmp_stack_addr[2]) elif tmp and not tmp.startswith("00"): self.logger.info(f"天车{craneNo}区域{areaNo}:放入钢坯{tmp}") self.sender.car_save(self.parking.ccmNo_list[2], tmp, self.parking.current_car[2], craneNo, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), tmp_from, areaNo) elif areaNo == "高线辊道": self.logger.info(f"天车{craneNo}区域{areaNo}:放入钢坯{tmp}") if not tmp.startswith("00"): self.sender.host_send("6", tmp, "高线", craneNo, tmp_from) elif areaNo == "601堆垛": self.logger.info(f"天车{craneNo}区域{areaNo}:放入钢坯{tmp}") self.sender.stack_add('6', tmp, craneNo, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), tmp_from, '601堆垛', layer, addr) elif areaNo == "501堆垛": self.logger.info(f"天车{craneNo}区域{areaNo}:放入钢坯{tmp}") self.sender.stack_add('5', tmp, craneNo, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), tmp_from, '501堆垛', layer, addr)