2026-02-09 11:36:37 +08:00
|
|
|
|
import threading
|
|
|
|
|
|
from enum import IntEnum
|
|
|
|
|
|
import queue
|
|
|
|
|
|
import json
|
2026-03-13 21:04:19 +08:00
|
|
|
|
import time
|
2026-02-09 11:36:37 +08:00
|
|
|
|
from dataclasses import asdict
|
2026-03-13 21:04:19 +08:00
|
|
|
|
from typing_extensions import Optional
|
2026-02-09 11:36:37 +08:00
|
|
|
|
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
|
|
|
|
|
|
|
2026-03-13 21:04:19 +08:00
|
|
|
|
# 上料斗是否振动(True:是,False:否)
|
|
|
|
|
|
self._upper_is_arch=False
|
|
|
|
|
|
#上料斗门关闭状态(0:关闭,1:半开,2全开)
|
|
|
|
|
|
self._upper_door_closed=0
|
|
|
|
|
|
#上料斗重量
|
2026-02-09 11:36:37 +08:00
|
|
|
|
self._upper_weight=0
|
2026-03-13 21:04:19 +08:00
|
|
|
|
#上料斗剩余方量
|
2026-02-09 11:36:37 +08:00
|
|
|
|
self._upper_volume=0.0
|
2026-02-10 10:18:17 +08:00
|
|
|
|
|
2026-03-13 21:04:19 +08:00
|
|
|
|
# 上料斗控制相关
|
|
|
|
|
|
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
|
|
|
|
|
|
|
2026-04-07 09:51:38 +08:00
|
|
|
|
#控制派单状态,1为可以派单 0未派单 2完成派单
|
|
|
|
|
|
self.pd_status=PD_StatusEnum.PD_Not
|
|
|
|
|
|
#记录当前派单编号
|
|
|
|
|
|
self.pd_mould_code=''
|
|
|
|
|
|
|
2026-02-09 11:36:37 +08:00
|
|
|
|
#下料比例变频
|
|
|
|
|
|
self.vf_frequencys=[{'radio':0,'fre':230},{'radio':0.3,'fre':230},{'radio':0.6,'fre':230}]
|
2026-03-13 21:04:19 +08:00
|
|
|
|
|
|
|
|
|
|
|
2026-02-09 11:36:37 +08:00
|
|
|
|
#记录模具开始振动的时间
|
|
|
|
|
|
self.mould_vibrate_time=0
|
2026-03-13 21:04:19 +08:00
|
|
|
|
#当前浇筑模具,ArtifactInfo对象需要属性:ArtifactID,ArtifactActionID,MouldCode (RFID情况下绑定)
|
|
|
|
|
|
self.current_mould=None
|
2026-04-07 09:51:38 +08:00
|
|
|
|
self.current_block_number=''
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
2026-03-13 21:04:19 +08:00
|
|
|
|
|
2026-02-09 11:36:37 +08:00
|
|
|
|
# 视觉系统状态
|
|
|
|
|
|
self.overflow_detected = "0" # 堆料检测
|
|
|
|
|
|
|
|
|
|
|
|
self.bll_artifact=ArtifactBll()
|
2026-03-13 21:04:19 +08:00
|
|
|
|
#记录生产的模具编号,更新到数据库的管片生成任务状态,status:2正生产3完成生成,weight:完成重量
|
|
|
|
|
|
self._db_mould_status={'mould_code':'','status':1,'weight':0}
|
2026-02-09 11:36:37 +08:00
|
|
|
|
#派单数据发送到OPC
|
2026-03-13 21:04:19 +08:00
|
|
|
|
# self._pd_data=''
|
|
|
|
|
|
#设置派单模式(1自动派单 2手动派单0未知)
|
|
|
|
|
|
self.pd_set_mode=0
|
|
|
|
|
|
#管片刷新通知UI
|
|
|
|
|
|
self._sys_segment_refresh=0
|
|
|
|
|
|
#派单刷新通知UI
|
|
|
|
|
|
self._sys_pd_refresh=0
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
#变频器相关
|
|
|
|
|
|
#是否启动变频器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:
|
2026-03-13 21:04:19 +08:00
|
|
|
|
if public_name=='mould_finish_weight':
|
2026-04-07 09:51:38 +08:00
|
|
|
|
return
|
2026-03-13 21:04:19 +08:00
|
|
|
|
elif public_name=='mould_finish_ratio':
|
2026-04-07 09:51:38 +08:00
|
|
|
|
if time.time()-self.opc_timestamp>=1 or value>=1:
|
|
|
|
|
|
if value>1:
|
|
|
|
|
|
value=1
|
2026-03-13 21:04:19 +08:00
|
|
|
|
self.opc_queue.put_nowait((public_name, value))
|
2026-04-07 09:51:38 +08:00
|
|
|
|
self.opc_queue.put_nowait(('mould_finish_weight', self._mould_finish_weight))
|
2026-03-13 21:04:19 +08:00
|
|
|
|
self.opc_timestamp=time.time()
|
2026-02-09 11:36:37 +08:00
|
|
|
|
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
|
2026-04-07 09:51:38 +08:00
|
|
|
|
try:
|
|
|
|
|
|
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'])
|
|
|
|
|
|
self.opc_queue.put_nowait(('sys_segment_refresh',1))
|
|
|
|
|
|
elif _status==2:
|
|
|
|
|
|
#开始生产
|
|
|
|
|
|
self.bll_artifact.start_produce(_code)
|
|
|
|
|
|
self.opc_queue.put_nowait(('sys_segment_refresh',1))
|
|
|
|
|
|
except queue.Full:
|
|
|
|
|
|
pass
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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):
|
2026-03-13 21:04:19 +08:00
|
|
|
|
# JBL(在搅拌楼), ZDS(在振捣室), Returning(返回中)
|
|
|
|
|
|
JBL = 1
|
|
|
|
|
|
ZDS = 2
|
|
|
|
|
|
Returning = 3
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
2026-04-07 09:51:38 +08:00
|
|
|
|
class PD_StatusEnum(IntEnum):
|
|
|
|
|
|
# 预定派单
|
|
|
|
|
|
PD_Ready = 1
|
|
|
|
|
|
# 不派单
|
|
|
|
|
|
PD_Not = 0
|
|
|
|
|
|
# 完成派单下发
|
|
|
|
|
|
PD_Send_Finish = 2
|
|
|
|
|
|
#派单超时
|
|
|
|
|
|
PD_TimeOut=3
|
|
|
|
|
|
#未扫码
|
|
|
|
|
|
PD_UnScan=4
|
|
|
|
|
|
#已完成
|
|
|
|
|
|
PD_Finish=5
|
|
|
|
|
|
|
|
|
|
|
|
#派单错误
|
|
|
|
|
|
PD_Error=1001
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-02-09 11:36:37 +08:00
|
|
|
|
|
2026-03-13 21:04:19 +08:00
|
|
|
|
# class Upper_PLC_Status(IntEnum):
|
|
|
|
|
|
# PLC_ZDS_Ready = 4
|
2026-04-07 09:51:38 +08:00
|
|
|
|
# #到达
|
2026-03-13 21:04:19 +08:00
|
|
|
|
# PLC_ZDS_Finish = 5
|
|
|
|
|
|
# #即将搅拌楼
|
|
|
|
|
|
# PLC_JBL_Ready = 64
|
|
|
|
|
|
# #到达搅拌楼
|
|
|
|
|
|
# PLC_JBL_Finish = 66
|