import threading from enum import IntEnum import queue import json import time from dataclasses import asdict from typing_extensions import Optional from busisness.blls import ArtifactBll,PDRecordBll class SystemState: """系统状态类,存在变化的参数及标志""" """系统状态中以_开头的属性会发送到OPC通知,不需要的不要加_开头""" # state_updated=Signal(str,object) def __init__(self): super().__init__() # self.watched_props = [] self.lock = threading.RLock() self.opc_queue = queue.Queue() # 系统运行状态 self.running = True # 上料斗是否振动(True:是,False:否) self._upper_is_arch=False #上料斗门关闭状态(0:关闭,1:半开,2全开) self._upper_door_closed=0 #上料斗重量 self._upper_weight=0 #上料斗剩余方量 self._upper_volume=0.0 # 上料斗控制相关 self._upper_door_position = Upper_Door_Position.JBL #低料斗是否振动(True:是,False:否) self._lower_is_arch=False self._lower_weight=0 #完成下料的总重量 self._mould_finish_weight=0 #时间戳,记录上一次发送到OPC的时间,不用每次都传 self.opc_timestamp=time.time() #需要下料的总重量 # self._mould_need_weight=0 self._mould_finish_ratio=0 #当前振捣频率 self._mould_frequency=230 #模具是否捣动中(True:是,False:否) self._mould_vibrate_status=False #True振捣中False未振捣 #当前模具状态 self._feed_status=FeedStatus.FNone #下料比例变频 self.vf_frequencys=[{'radio':0,'fre':230},{'radio':0.3,'fre':230},{'radio':0.6,'fre':230}] #记录模具开始振动的时间 self.mould_vibrate_time=0 #当前浇筑模具,ArtifactInfo对象需要属性:ArtifactID,ArtifactActionID,MouldCode (RFID情况下绑定) self.current_mould=None # 视觉系统状态 self.overflow_detected = "0" # 堆料检测 self.bll_artifact=ArtifactBll() #记录生产的模具编号,更新到数据库的管片生成任务状态,status:2正生产3完成生成,weight:完成重量 self._db_mould_status={'mould_code':'','status':1,'weight':0} #派单数据发送到OPC # self._pd_data='' #设置派单模式(1自动派单 2手动派单0未知) self.pd_set_mode=0 #管片刷新通知UI self._sys_segment_refresh=0 #派单刷新通知UI self._sys_pd_refresh=0 #变频器相关 #是否启动变频器0未1普通块启动2F块启动 3结束 self.vf_status=0 self.watched_props = [k for k in self.__dict__ if k.startswith('_')] def __setattr__(self, name, value): super().__setattr__(name, value) if name in self.watched_props: with self.lock: public_name = name.lstrip('_') try: if public_name.startswith('db'): self.save_db(public_name,value) #有影响的话改成异步 else: if public_name=='mould_finish_weight': if time.time()-self.opc_timestamp>=1: self.opc_queue.put_nowait((public_name, value)) self.opc_timestamp=time.time() elif public_name=='mould_finish_ratio': if time.time()-self.opc_timestamp>=1: self.opc_queue.put_nowait((public_name, value)) self.opc_timestamp=time.time() elif value>=1: #保证比例能到100% self.opc_queue.put_nowait((public_name, value)) self.opc_queue.put_nowait(('mould_finish_weight', self._mould_finish_weight)) self.opc_timestamp=time.time() else: self.opc_queue.put_nowait((public_name, value)) except queue.Full: # 队列已满,记录异常但不中断程序 print(f"OPC queue is full, skipping update for {public_name}") except Exception as e: # 捕获其他异常 print(f"Unexpected error putting to OPC queue: {e}") # self.state_updated.emit(public_name, value) def save_db(self,public_name,val): if not val: return if public_name=="db_mould_status": _code=val['mould_code'] if _code: _status=val['status'] if _status==3: #完成生产 self.bll_artifact.finish_produce(_code,val['weight']) elif _status==2: #开始生产 self.bll_artifact.start_produce(_code) class FeedStatus(IntEnum): #初始值 FNone = 0 # 检查模车(模车到位) FCheckGB = 1 #RFID检测或匹配 FRFID=2, # 下料1(下料斗到模具车) FFeed1=5 #下料2(上--》下) FFeed2 = 6 # 下料3(下--》模) FFeed3 = 7 # 下料4(上--》下) FFeed4 = 8 #下料5(下-》模) FFeed5 = 9 #完成(管片生产完成) FFinished = 11 class Upper_Door_Position(IntEnum): # JBL(在搅拌楼), ZDS(在振捣室), Returning(返回中) JBL = 1 ZDS = 2 Returning = 3 # class Upper_PLC_Status(IntEnum): # # 即将振捣室 # PLC_ZDS_Ready = 4 # #到达振捣室 # PLC_ZDS_Finish = 5 # #即将搅拌楼 # PLC_JBL_Ready = 64 # #到达搅拌楼 # PLC_JBL_Finish = 66