from PySide6.QtCore import QTimer, Signal, QObject, Slot import threading from hardware.transmitter import TransmitterController from hardware.relay import RelayController from view.widgets.hopper_widget import HopperWidget from view.widgets.conveyor_system_widget import ConveyorSystemWidget from enum import Enum class UpperHopperPosition(Enum): """上料斗位置 - MIXING_TOWER: 搅拌楼处,对应数值 66 - VIBRATION_CHAMBER: 振捣室处,对应数值 5 """ MIXING_TOWER = 66 # 搅拌楼处 VIBRATION_CHAMBER = 5 # 振捣室处 # 信号类:后台线程向主线程传递数据 class HopperSignals(QObject): upper_weight_updated = Signal(int) # 上料斗重量更新信号 class HopperController: def __init__(self, hopper_view:HopperWidget, conveyor_view:ConveyorSystemWidget): self.hopper_view = hopper_view self.conveyor_view = conveyor_view # 控制传送带中的上料斗 self.signals = HopperSignals() # 信号 # 下料斗夹爪测试用例数据 # 注意:目前只控制 下料斗的夹爪角度变化 self.angle = 10.33 # 夹爪当前角度 self.max_angle = 60.00 # 夹爪最大张开角度 self.min_angle = 10.00 # 夹爪最小张开角度 self.is_add = True # 角度增加/减小 控制 self.timer_angle = QTimer() # 角度更新定时器 self.timer_angle.setInterval(1000) # 1秒更新一次角度 # 重量读取定时器 # self.timer_weight = QTimer() # 重量读取定时器 # self.timer_weight.setInterval(2000) # 每2秒读取一次重量 # 绑定信号 self._connect_signals() # 开启定时器 self.timer_angle.start() # self.timer_weight.start() def _connect_signals(self): # 更新上料斗重量 self.signals.upper_weight_updated.connect(self.onUpdateUpperHopperWeight) # 上料斗重量定时读取 # self.timer_weight.timeout.connect(self.handleReadUpperHopperWeight) # 下料斗夹爪定时更新 self.timer_angle.timeout.connect(self.handleLowerClampAngleUpdate) # 上料斗 "开"按钮点击 self.hopper_view.upper_open_btn.clicked.connect(self.onUpperClampOpenBottonClicked) # 上料斗 "破拱"按钮 self.hopper_view.upper_arch_breaking_signal.connect(self.onUpperArchBreaking) # 下料斗 "开"按钮点击 self.hopper_view.lower_open_btn.clicked.connect(self.onLowerClampOpenBottonClicked) # 下料斗 "破拱"按钮 self.hopper_view.lower_arch_breaking_signal.connect(self.onLowerArchBreaking) def handleLowerClampAngleUpdate(self): """处理下料斗夹爪开合""" # 角度增减逻辑 if self.is_add: self.angle += 1.22 else: self.angle -= 1.33 # 边界控制 if self.angle > self.max_angle: self.is_add = False self.angle = self.max_angle if self.angle <= self.min_angle: self.is_add = True self.angle = self.min_angle # 更新下料斗夹爪角度 self.onUpdateLowerClampAngle(self.angle) @Slot(int) def onUpdateUpperHopperWeight(self, weight:int): "更新上料斗重量" self.hopper_view.setUpperHopperWeight(weight) # 注意:此时需要同步更新传送带中的上料斗的重量 self.conveyor_view.setConveyorHopperWeight(weight) @Slot(int) def onUpdateLowerHopperWeight(self, weight:int): "更新下料斗重量" self.hopper_view.setLowerHopperWeight(weight) @Slot() def handleReadUpperHopperWeight(self): # 后台读取上料斗重量 def upper_weight_task(): loc_tra = TransmitterController(RelayController()) # 上料斗重量 (目前只有上料斗安装变送器, 可以读取到重量) upper_weight = loc_tra.read_data(1) # 发送信号到主线程更新UI if upper_weight is not None: self.signals.upper_weight_updated.emit(upper_weight) threading.Thread(target=upper_weight_task, daemon=True).start() @Slot(float) def onUpdateLowerClampAngle(self, angle:float): """更新下料斗夹爪角度""" self.hopper_view.setLowerHopperOpeningAngle(angle) @Slot(float) def onUpdateUpperClampAngle(self, angle:float): """更新上料斗夹爪角度""" self.hopper_view.setUpperHopperClampAngle(angle) @Slot() def onUpperClampOpenBottonClicked(self): # 上料斗 夹爪 "开"按钮点击 print("hopper_controller: onUpperClampOpenBottonClicked") # 测试上料斗夹爪,6秒打开60度 self.hopper_view.upper_clamp_widget.testAnimation(target_angle=60, duration=10) @Slot(int) def onUpdateUpperClampStatus(self, status:int): # 上料斗夹爪状态 1表示打开,0表示关闭 if status: # 执行上料斗夹爪打开动画 self.hopper_view.upper_clamp_widget.testAnimation(target_angle=60, duration=10) else: # 执行上料斗夹爪关闭动画 self.hopper_view.upper_clamp_widget.testAnimation(target_angle=0, duration=10) def onUpdateUpperHopperPosition(self, position:int): # 上料斗位置 if position == UpperHopperPosition.MIXING_TOWER.value: # 上料斗到达搅拌楼,值为66 # 上料斗在搅拌楼下 self.hopper_view.hideUpperHopper() # 隐藏非传送带处的上料斗 self.conveyor_view.moveHopperBelowMixer() # 传送带处的上料斗移动到搅料楼下 self.conveyor_view.showHopper() # 显示传送带处的上料斗 elif position == UpperHopperPosition.VIBRATION_CHAMBER.value: # 上料斗就绪,到达振捣室,值为5 # 上料斗在振捣室处 self.conveyor_view.hideHopper() # 隐藏传送带处的上料斗 self.hopper_view.upper_clamp_widget.set_angle(0) # 上料斗夹爪角度设置为0,此时上料斗一定是关闭的 self.hopper_view.showUpperHopper() # 显示非传送带处的上料斗 else: # 上料斗在途中 self.hopper_view.hideUpperHopper() # 隐藏非传送带处的上料斗 (下料斗处对应的上料斗叫非传送带处上料斗) self.conveyor_view.moveHopperToTransition() # 传送带处上料斗移动到中间过渡位置 self.conveyor_view.showHopper() # 显示传送带处的上料斗 @Slot(bool) def onUpperArchBreaking(self, status:bool): """上料斗破拱: status 为True表示 开启破拱, 为False表示 关闭破拱""" print("hopper_controller: onUpperArchBreaking ", status) @Slot(int) def onUpperHopperStatusChanged(self, status:int): """上料斗状态改变: status为 0=绿(正常), 1=黄(警告), 2=红(异常) """ # 料斗中的状态指示器 self.hopper_view.setUpperHopperStatus(status) @Slot(float) def onUpdateUpperHopperVolume(self, volume: float): """更新上料斗显示的方量,如: 2.0""" self.hopper_view.setUpperHopperVolume(volume) @Slot() def onLowerClampOpenBottonClicked(self): # 下料斗 夹爪 "开"按钮点击 print("hopper_controller: onLowerClampOpenBottonClicked") @Slot(bool) def onLowerArchBreaking(self, status:bool): """下料斗破拱: status 为True表示 开启破拱, 为False表示 关闭破拱""" print("hopper_controller: onLowerArchBreaking ", status) @Slot(int) def onLowerHopperStatusChanged(self, status:int): """下料斗状态改变: status为 0=绿(正常), 1=黄(警告), 2=红(异常) """ # 料斗中的状态指示器 self.hopper_view.setLowerHopperStatus(status)