Files
Feeding_control_system/core/system.py

705 lines
33 KiB
Python
Raw Normal View History

import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import threading
import time
import queue
2026-03-13 21:04:19 +08:00
import json
2026-04-07 09:51:38 +08:00
import math
from core.system_state import SystemState,FeedStatus,Upper_Door_Position,PD_StatusEnum
from hardware.relay import RelayController
from hardware.inverter import InverterController
from hardware.transmitter import TransmitterController
from config.ini_manager import ini_manager
from hardware.upper_plc import OmronFinsPollingService
from vision.visual_callback_dq import VisualCallback
from opc.opcua_client_feed import OpcuaClientFeed
2026-03-13 21:04:19 +08:00
from busisness.blls import ArtifactBll,PDRecordBll,FreqRecordBll
from busisness.models import ArtifactInfoModel,PDRecordModel,FreqRecordModel
from core.pd_task_service import PD_TaskService
2026-04-07 09:51:38 +08:00
from vision.charge_3cls.charge_utils import run_stable_charge_loop
from core.pd_volume import PdVolume
from core.core_utils import CoreUtils
from datetime import datetime, timedelta
class FeedingControlSystem:
2025-11-21 14:55:52 +08:00
def __init__(self):
print('FeedingControlSystem初始化')
self.state = SystemState()
2026-04-07 09:51:38 +08:00
self.prev_pd_volume=0.0
2026-03-13 21:04:19 +08:00
self.pd_task_service = PD_TaskService()
self.pd_record_bll=PDRecordBll()
self.freq_record_bll=FreqRecordBll()
# 初始化硬件控制器
self.relay_controller = RelayController(
host=ini_manager.relay_host,
port=ini_manager.relay_port
)
self.inverter_controller = InverterController()
self.transmitter_controller = TransmitterController(self.relay_controller)
2026-02-10 10:18:17 +08:00
self.plc_service = OmronFinsPollingService(ini_manager.upper_plc_ip, ini_manager.upper_plc_port)
# 初始化下料控制器
2026-02-10 10:18:17 +08:00
self.feeding_controller = VisualCallback(
relay_controller=self.relay_controller,
transmitter_controller=self.transmitter_controller,
state=self.state
)
2025-11-17 00:05:40 +08:00
2026-02-10 10:18:17 +08:00
self.plc_service.register_data_callback(self.feeding_controller.on_plc_update)
#小屏修改过屏幕
self.vf_auto_mode=True
# 初始化 OPC UA 客户端
2026-03-13 21:04:19 +08:00
self.opcua_client_feed = OpcuaClientFeed(notify_callback=self.on_opcua_notify)
2025-11-01 17:33:26 +08:00
# 线程管理
2026-02-10 10:18:17 +08:00
self.feed_thread = None
self.vf_thread = None
self.arch_thread = None
self.api_thread = None
self.pd_jbl_thread = None
# 初始化 OPC 队列监听线程,用于处理队列中的数据
self.opc_queue_thread = None
2026-03-13 21:04:19 +08:00
#处理频率上传线程
self.freq_thread=None
2026-02-10 10:18:17 +08:00
def initialize(self)->bool:
"""初始化系统"""
print("初始化控制系统...")
# self.check_device_connectivity()
2026-02-10 10:18:17 +08:00
#启用上料斗PLC
self.plc_service.start_polling(interval=2.0)
#启用下料线程
self.start_feed_thread()
#启用变频器线程
self.start_vf_thread()
2026-02-10 10:18:17 +08:00
#启用破拱线程
self.start_arch_thread()
#启用推送模型数据线程
self.feeding_controller.start_visual_thread()
#启用API(对接PD API数据),线程
self.start_api_thread()
#启用派单线程
2026-02-10 10:18:17 +08:00
self.start_pd_thread()
# 启动OPC队列处理线程维护连接的断开重连等
self.opcua_client_feed.start()
2026-03-13 21:04:19 +08:00
#开启接收通知数据(queue线程)
self.opcua_client_feed.start_accept()
2026-02-10 10:18:17 +08:00
self.start_opc_queue_thread()
2026-03-13 21:04:19 +08:00
#启用频率上传线程
self.start_freq_thread()
2026-02-10 10:18:17 +08:00
print("控制系统初始化完成")
2026-02-10 10:18:17 +08:00
return True
def start_feed_thread(self):
"下料线程控制,主要控制下料斗(视觉控制)以及上料斗"
self.feed_thread = threading.Thread(
target=self.feeding_controller._run_feed,
daemon=True
)
self.feed_thread.start()
def start_opc_queue_thread(self):
2026-02-10 10:18:17 +08:00
"""启动OPC队列处理线程从控制系统中获取数据通过OPC外发"""
print('启动OPC队列处理线程')
self.opc_queue_thread = threading.Thread(
target=self._process_opc_queue,
daemon=True,
2026-03-13 21:04:19 +08:00
name='send_queue_processor'
)
self.opc_queue_thread.start()
def start_api_thread(self):
"""启动PD线程"""
# print('启动API处理线程从API获取未浇筑数据')
self.api_thread = threading.Thread(
target=self._process_api_db,
daemon=True,
name='api_thread'
)
self.api_thread.start()
def start_vf_thread(self):
2026-02-10 10:18:17 +08:00
"""启动变频器控制线程(控制变频器开始启动,以及频率变换)"""
# print('启动API处理线程从API获取未浇筑数据')
self.vf_thread = threading.Thread(
target=self._process_vf,
daemon=True,
name='vf_thread'
)
self.vf_thread.start()
def _process_vf(self):
_begin_time=None
_wait_times=300
_start_wait_seconds=None
2026-03-13 21:04:19 +08:00
_is_start=False
#处理振捣频率
while self.state.running:
try:
# if self.feeding_controller._is_finish_ratio>=0.6:
# self.inverter_controller.set_frequency(230)
# else:
# self.inverter_controller.set_frequency(220)
if self.state.vf_status in [1,2]:
if _begin_time is None :
print("----浇筑即将启动-----")
if _start_wait_seconds is None:
#记录盖板对齐时间
_start_wait_seconds=time.time()
2026-03-13 21:04:19 +08:00
if self.state._mould_finish_ratio>=0.05:
2026-04-07 09:51:38 +08:00
_is_charge= run_stable_charge_loop()
if _is_charge is not None:
print(f'------------已插好振捣棒: {_is_charge}-------------')
time.sleep(2)
# _elasped_time=time.time()-_start_wait_seconds
# if _elasped_time<10:
# time.sleep(10-_elasped_time)
self.inverter_controller.control('start',230)
2026-03-13 21:04:19 +08:00
_is_start=True
print("----浇筑已经启动-----")
_begin_time=time.time()
self.state._mould_frequency=230
self.state._mould_vibrate_status=True
if self.state.vf_status==2:
print("----振捣270s-----")
_wait_time=270
else:
print("----振捣300秒-----")
_wait_time=300
else:
2026-03-13 21:04:19 +08:00
print("----下料重量小于46KG,暂时不振捣-----")
else:
2026-04-07 09:51:38 +08:00
if self.state._mould_finish_ratio>=0.3 and self.state._mould_finish_ratio<0.4:
if self.state._mould_frequency!=230:
self.inverter_controller.set_frequency(230)
self.state._mould_frequency=230
2026-03-13 21:04:19 +08:00
elif self.state._mould_finish_ratio>=0.4:
if self.state._mould_frequency!=230:
self.inverter_controller.set_frequency(230)
self.state._mould_frequency=230
elif self.state.vf_status==3 and _begin_time is not None:
if time.time()-_begin_time>=_wait_time:
if self.vf_auto_mode:
self.inverter_controller.control('stop')
2026-03-13 21:04:19 +08:00
_is_start=False
self.state._mould_vibrate_status=False
_begin_time=None
_start_wait_seconds=None
except Exception as e:
print(f"处理变频器数据时发生错误: {e}")
time.sleep(2)
def _process_api_db(self):
from service.mould_service import app_web_service
"""处理API队列中的数据"""
# 初始化三个列表用于跟踪ArtifactActionID
processed_artifact_actions = [] # 已处理的ArtifactActionID列表
processed_artifact_ids = [] # 已处理的ArtifactActionID列表
processed_pd_records = [] # 已插入PDRecord表的ArtifactActionID列表
processed_pd_ids=[]
_model_task=None
artifact_bll=ArtifactBll()
pdrecord_bll=PDRecordBll()
print('启动API处理线程从API获取未浇筑数据')
while self.state.running:
try:
not_poured = app_web_service.get_not_pour_artifacts()
if not_poured:
2026-04-07 09:51:38 +08:00
_is_refresh=False
for item in reversed(not_poured):
if item.MouldCode is None or item.MouldCode == '':
continue
_is_artifactid=True
# 检查MouldCode是否已处理
if item.MouldCode in processed_artifact_actions:
#print(f"待浇筑:MouldCode {item.MouldCode} 已处理,跳过")
#处理过了。判断是否更新
if item.ArtifactID is None or item.ArtifactID == '':
_is_artifactid=False
if item.ArtifactID in processed_artifact_ids:
# print(f"待浇筑:ArtifactID {item.ArtifactID} 已处理,跳过")
_is_artifactid=False
if _is_artifactid:
_model_data = ArtifactInfoModel(**item.__dict__)
_ret=artifact_bll.save_artifact_task(_model_data)
if _ret > 0:
# 标记为已处理
2026-04-07 09:51:38 +08:00
_is_refresh=True
# self.state._sys_segment_refresh=1
processed_artifact_actions.append(item.MouldCode)
2026-04-07 09:51:38 +08:00
if len(processed_artifact_actions) > 10:
processed_artifact_actions.pop(0)
if item.ArtifactID:
processed_artifact_ids.append(item.ArtifactID)
2026-04-07 09:51:38 +08:00
if len(processed_artifact_ids) > 10:
processed_artifact_ids.pop(0)
# 限制最多保存3条记录删除最旧的
#print(f"待浇筑:已处理MouldCode {item.MouldCode} ArtifactID {item.ArtifactID}")
if item.MouldCode in processed_pd_records:
#print(f"派单:MouldCode {item.MouldCode} 已处理,跳过")
if item.ArtifactID is None or item.ArtifactID == '':
continue
if item.ArtifactID in processed_pd_ids:
#print(f"待浇筑:ArtifactID {item.ArtifactID} 已处理,跳过")
continue
_pd_record_data=None
if item.ArtifactID:
if item.BetonTaskID is not None and item.BetonTaskID != '':
#获取taskid
if _model_task is None or item.BetonTaskID != _model_task.TaskID:
_model_task = app_web_service.get_task_info(item.BetonTaskID)
if _model_task is None:
print(f"异常:BetonTaskID {item.BetonTaskID} 不存在,跳过")
continue
_pd_record_data = PDRecordModel(
ArtifactID=item.ArtifactID,
ArtifactActionID=item.ArtifactActionID,
TaskID=_model_task.TaskID,
ProjectName=_model_task.ProjectName,
ProduceMixID=_model_task.ProduceMixID,
BetonGrade=_model_task.BetonGrade,
BetonVolume=item.BetonVolume,
2026-04-07 09:51:38 +08:00
BetonVolume2=PdVolume.get_volume_expect(item.MouldCode),
MouldCode=item.MouldCode,
SkeletonID=item.SkeletonID,
RingTypeCode=item.RingTypeCode,
SizeSpecification=item.SizeSpecification,
BuriedDepth=item.BuriedDepth,
BlockNumber=item.BlockNumber,
PlannedVolume=_model_task.PlannedVolume
)
else:
_pd_record_data = PDRecordModel(
2026-04-07 09:51:38 +08:00
MouldCode=item.MouldCode,
BetonVolume2=PdVolume.get_volume_expect(item.MouldCode),
)
if _pd_record_data is None:
continue
_ret=pdrecord_bll.save_PD_record(_pd_record_data)
if _ret > 0:
2026-04-07 09:51:38 +08:00
# self.state._sys_segment_refresh=1
_is_refresh=True
# 标记为已处理
processed_pd_records.append(item.MouldCode)
# 限制最多保存3条记录删除最旧的
2026-04-07 09:51:38 +08:00
if len(processed_pd_records) > 10:
processed_pd_records.pop(0)
if item.ArtifactID:
processed_pd_ids.append(item.ArtifactID)
2026-04-07 09:51:38 +08:00
if len(processed_pd_ids) > 10:
processed_pd_ids.pop(0)
#print(f"派单:已处理MouldCode {item.MouldCode} ArtifactID {item.ArtifactID}")
2026-04-07 09:51:38 +08:00
if _is_refresh:
self.state._sys_segment_refresh=1
except Exception as e:
print(f"处理MouldCode {item.MouldCode} 时发生错误: {e}")
time.sleep(5)
def _process_opc_queue(self):
"""处理OPC队列中的数据"""
while self.state.running:
try:
# 从队列中获取数据,设置超时以允许线程退出
item = self.state.opc_queue.get(timeout=1)
if item:
public_name, value = item
# 这里可以添加实际的OPC处理逻辑
2026-03-13 21:04:19 +08:00
print(f"控制程序opc数据上传: {public_name} = {value}")
self.opcua_client_feed.write_value_by_name(public_name, value)
# 标记任务完成
self.state.opc_queue.task_done()
except queue.Empty:
# 队列为空,继续循环
continue
except Exception as e:
print(f"OPC队列处理错误: {e}")
def angle_visual_callback(self, current_angle, overflow_detected, mould_aligned):
"""角度视觉回调"""
self.feeding_controller.angle_visual_callback(current_angle, overflow_detected, mould_aligned)
def diff_visual_callback(self, current_diff,current_area):
"""差异视觉回调"""
self.feeding_controller.diff_visual_callback(current_diff,current_area)
def shutdown(self):
"""关闭系统"""
self.feeding_controller.shutdown()
self.stop()
2026-02-10 10:18:17 +08:00
def start_arch_thread(self):
"""启动系统监控和要料"""
2025-11-21 14:55:52 +08:00
print('振动和要料监控线程启动')
2026-02-10 10:18:17 +08:00
#启动振动线程
self.arch_thread = threading.Thread(
target=self.feeding_controller._arch_loop,
2025-11-21 14:55:52 +08:00
daemon=True,
2026-02-10 10:18:17 +08:00
name='arch'
)
self.arch_thread.start()
2025-11-21 14:55:52 +08:00
2025-11-01 17:33:26 +08:00
def check_device_connectivity(self) -> bool:
"""检查关键设备连接状态"""
try:
# 检查网络继电器连接
test_response = self.relay_controller.send_command(self.relay_controller.read_status_command)
if not test_response:
print("网络继电器连接失败")
return False
# 检查变频器连接
if not self.relay_controller.modbus_client.connect():
print("无法连接到网络继电器Modbus服务")
return False
# 检查下料斗变送器连接
test_weight = self.transmitter_controller.read_data(2)
if test_weight is None:
print("下料斗变送器连接失败")
return False
self.relay_controller.modbus_client.close()
return True
except Exception as e:
print(f"设备连接检查失败: {e}")
return False
2026-02-10 10:18:17 +08:00
def start_pd_thread(self):
"""启动PD线程"""
print('启动派单处理线程从API获取未浇筑数据')
self.pd_jbl_thread = threading.Thread(
target=self._process_pd_jbl,
daemon=True,
name='pd_jbl_thread'
)
self.pd_jbl_thread.start()
def _process_pd_jbl(self):
# pass
#根据当前浇筑块进行最近一块的派单
2026-04-07 09:51:38 +08:00
# _start_time=None
while self.state.running:
2026-03-13 21:04:19 +08:00
#设置的派单模式
if self.state.pd_set_mode==1:
2026-04-07 09:51:38 +08:00
#增加生产阶段检测,
try:
if self.state.pd_status==PD_StatusEnum.PD_Ready:
#L1对齐排L2和F的。L2对齐派F块,L2完成派B1块
# if _start_time is None:
# _start_time=time.time()
2026-03-13 21:04:19 +08:00
_isSuccess=self.send_pd_data()
if _isSuccess:
2026-04-07 09:51:38 +08:00
self.state.pd_status=PD_StatusEnum.PD_Send_Finish
# _start_time=None
# elif time.time()-_start_time>60:
# print('派单超时,人工介入')
# self.pd_record_bll.start_pd(PD_StatusEnum.PD_TimeOut.value,_pdrecord.MouldCode,0)
# self.state.pd_status=PD_StatusEnum.PD_TimeOut
# _start_time=None
elif self.state.pd_status==PD_StatusEnum.PD_TimeOut:
self.pd_record_bll.start_pd(PD_StatusEnum.PD_TimeOut.value,self.state.pd_mould_code,-1)
self.state.pd_status=PD_StatusEnum.PD_Not
except Exception as e:
print(f"派单处理错误: {e}")
self.state.pd_status=PD_StatusEnum.PD_Error
2026-03-13 21:04:19 +08:00
_start_time=None
2026-04-07 09:51:38 +08:00
else:
print('已开启手动派单,或未设置派单模式')
print('已开启手动派单,或未设置派单模式')
time.sleep(5)
2026-02-10 10:18:17 +08:00
2026-03-13 21:04:19 +08:00
def send_pd_data(self):
"""
发送PD数据到OPC队列
2026-04-07 09:51:38 +08:00
:param _pd_status: PD状态
2026-03-13 21:04:19 +08:00
"""
# 构建PD数据
2026-04-07 09:51:38 +08:00
# print("send_pd_data1")
2026-03-13 21:04:19 +08:00
_cur_mould=self.state.current_mould
if _cur_mould is not None:
2026-04-07 09:51:38 +08:00
# print("send_pd_data2")
2026-03-13 21:04:19 +08:00
if _cur_mould.MouldCode:
2026-04-07 09:51:38 +08:00
_pdrecords = self.pd_record_bll.get_last_pds(_cur_mould.MouldCode,2)
if _pdrecords and len(_pdrecords)>1:
_pdrecord=_pdrecords[1]
# print(f"send_pd_data3,{_pdrecord.MouldCode}")
_block_number=CoreUtils.get_number_by_mould_code(_pdrecord.MouldCode)
_size=CoreUtils.get_size_by_mould_code(_pdrecord.MouldCode)
self.state.pd_mould_code=_pdrecord.MouldCode
_pd_flag=1
if not _pdrecord.TaskID:
#查找最近的未浇筑块
print(f"未扫描,使用最近的未浇筑块,{_size}")
_nearrecord=self.pd_record_bll.get_near_pd_scan(_size)
if _nearrecord is not None:
_pd_flag=2
_pdrecord.ArtifactActionID=0
_pdrecord.TaskID=_nearrecord.TaskID
_pdrecord.ProduceMixID=_nearrecord.ProduceMixID
_pdrecord.PlannedVolume=_nearrecord.PlannedVolume
print(f"未扫描,使用最近的未浇筑块,{_size},派单:{_pdrecord.TaskID},配比号:{_pdrecord.ProduceMixID}")
# print(f"send_pd_data5,{_pdrecord.TaskID}")
2026-03-13 21:04:19 +08:00
if _pdrecord.TaskID:
if _pdrecord.Status==1:
2026-04-07 09:51:38 +08:00
# print(f"send_pd_data6,{_pdrecord.TaskID}")
# tasks, artifact_list, send_list, half_volume = self.pd_task_service.process_not_pour_info(_pdrecords)
2026-03-13 21:04:19 +08:00
# if tasks and len(tasks)>0:
# task=tasks[0]
# # task['MouldCode']=_pdrecord.MouldCode
# #更新派单表
# _ret_flag=self.pd_record_bll.start_pd(_pdrecord.MouldCode,task['beton_volume'])
# if _ret_flag:
# _opc_pd={
# "ID":task['id'],
# "ArtifactActionID":task['artifact_id'],
# "TaskID":task['beton_task_id'],
# "ProduceMixID":task['produce_mix_id'],
# "BetonVolume":task['beton_volume'],
# "PlannedVolume":task['planned_volume']
# }
# print(f"{self.state.current_mould.MouldCode}派单:{_pdrecord.MouldCode},数据:{_opc_pd}")
# self.state.opc_queue.put_nowait(('pd_data', json.dumps(_opc_pd)))
2026-04-07 09:51:38 +08:00
_fact_volumn=0
if _pdrecord.BetonVolumeUpd>0.8:
#当前已经修改过方量
_fact_volumn=_pdrecord.BetonVolumeUpd
print(f"当前已经修改过方量,方量:{_fact_volumn}")
if _block_number=='F' and _fact_volumn<0.8:
2026-03-13 21:04:19 +08:00
print(f'{_pdrecord.MouldCode} F块不发送派单数据')
2026-04-07 09:51:38 +08:00
self.pd_record_bll.start_pd(PD_StatusEnum.PD_Send_Finish.value,_pdrecord.MouldCode,0)
2026-03-13 21:04:19 +08:00
else:
2026-04-07 09:51:38 +08:00
if _fact_volumn<0.8:
# _fact_volumn=0
if _size=='6600*1500':
_fact_volumn=PdVolume.get_fact_volume(self.transmitter_controller,_pdrecord.MouldCode)
elif _size=='6600*1200':
_fact_volumn=PdVolume.get_fact_volume_12(self.transmitter_controller,_pdrecord.MouldCode)
if _fact_volumn is not None and _fact_volumn>0:
2026-03-13 21:04:19 +08:00
#更新派单表
2026-04-07 09:51:38 +08:00
# print(f"send_pd_data7,{_pdrecord.MouldCode},{_fact_volumn}")
_ret_flag=self.pd_record_bll.start_pd(PD_StatusEnum.PD_Send_Finish.value,_pdrecord.MouldCode,_fact_volumn)
_cur_code=_pdrecords[0].MouldCode
2026-03-13 21:04:19 +08:00
if _ret_flag:
_opc_pd={
"ID":_pdrecord.ID,
"ArtifactActionID":_pdrecord.ArtifactActionID,
2026-04-07 09:51:38 +08:00
"MouldCodePD":_pdrecord.MouldCode,
"MouldCode":_cur_code,
2026-03-13 21:04:19 +08:00
"TaskID":_pdrecord.TaskID,
"ProduceMixID":_pdrecord.ProduceMixID,
2026-04-07 09:51:38 +08:00
"BetonVolume":round(_fact_volumn,1),
"PlannedVolume":round(_pdrecord.PlannedVolume,1),
"Flag":_pd_flag,
"Msg":"已扫码" if _pd_flag==1 else "未扫码",
"Time":time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
2026-03-13 21:04:19 +08:00
}
print(f"{self.state.current_mould.MouldCode}派单:{_pdrecord.MouldCode}-{_pdrecord.BlockNumber},数据:{_opc_pd}")
self.state.opc_queue.put_nowait(('pd_data', json.dumps(_opc_pd)))
return True
else:
print(f'{_pdrecord.MouldCode} 未派单,当前状态为:{_pdrecord.Status}')
2026-04-07 09:51:38 +08:00
return True
2026-03-13 21:04:19 +08:00
else:
print(f'{_pdrecord.MouldCode} 未获取到数据-(等待扫码)')
return False
else:
print(f'接口数据为空')
return False
else:
2026-04-07 09:51:38 +08:00
print(f'当前浇筑模具为空')
return False
else:
return False
2026-03-13 21:04:19 +08:00
2026-02-10 10:18:17 +08:00
def start_led(self):
"""启动LED流程"""
self.led_thread = threading.Thread(
target=self._start_led,
name="LED",
daemon=True
)
self.led_thread.start()
def _start_led(self):
"""启动LED流程"""
from service.mould_service import app_web_service
while self.state.running:
led_info = app_web_service.get_pouring_led()
if led_info:
2026-03-13 21:04:19 +08:00
if self.state.mould_code==led_info.MouldCode:
led_info.RingTypeCode=led_info.RingTypeCode
2026-02-10 10:18:17 +08:00
led_info.UpperWeight=self.state._upper_weight
led_info.LowerWeight=self.state._lower_weight
led_info.VibrationFrequency=self.state._mould_frequency
#发送到LED屏
2026-04-07 09:51:38 +08:00
time.sleep(2)
2026-02-10 10:18:17 +08:00
2026-03-13 21:04:19 +08:00
def on_opcua_notify(self,var_name,val):
"""OPC UA通知回调"""
2026-04-07 09:51:38 +08:00
try:
if var_name=='pd_set_mode':
self.state.pd_set_mode=val
elif var_name=='pd_set_volume' and val:
if self.state.pd_status!=PD_StatusEnum.PD_Ready:
_notify=json.loads(val)
_ret=self.pd_record_bll.update_PD_record_byid(_notify['ID'],{'BetonVolumeUpd':_notify['Volume']})
if _ret:
#刷新派单表
try:
self.state.opc_queue.put_nowait(('sys_pd_refresh',1))
except queue.Full:
pass
2026-03-13 21:04:19 +08:00
else:
2026-04-07 09:51:38 +08:00
print('当前状态为派单中,不能修改方量')
print('当前状态为派单中,不能修改方量')
# self.state._db_pd_set_volume=val
elif (var_name=='pd_notify_finish' or var_name=='pd_notify') and val:
# self.state._db_pd_notify=val
_notify=json.loads(val)
if 'ID' in _notify and 'Time' in _notify and _notify['ID'] and _notify['Time']:
if _notify['Flag']==5:
#搅拌楼下料完毕
_ret=self.pd_record_bll.update_pd_notify(_notify['ID'],{'GStatus':5,'Status':5,'FBetonVolume':_notify['BetonVolume'],'ErpID':_notify['ErpID'],'EndTime':time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())})
if _ret:
_time=datetime.strptime(_notify['Time'], '%Y-%m-%d %H:%M:%S')
if _time+timedelta(seconds=10)>=datetime.now():
# 发送命令
# from service.jbl_service import app_jbl_service
# _is_jb_finished=app_jbl_service.is_finish_jb()
if self.state._upper_door_position==Upper_Door_Position.JBL:
print("发送命令:搅拌楼--->振捣室")
print("发送命令:搅拌楼--->振捣室")
time.sleep(3)
self.relay_controller.control_upper_to_zd()
else:
print("搅拌楼下料未完成,或者料斗未在搅拌楼")
print("搅拌楼下料未完成,或者料斗未在搅拌楼")
else:
print("pd_notify:时间已过期")
print("pd_notify:时间已过期")
else:
print("pd_notify:更新失败")
print("pd_notify:更新失败")
else:
self.pd_record_bll.update_pd_notify(_notify['ID'],{'GStatus':_notify['Flag'],'ErpID':_notify['ErpID']})
else:
print(f'pd_notify:ID数据为空或Time数据为空')
print(f'pd_notify:ID数据为空或Time数据为空')
print(f'on_opcua_notify收到,var_name:{var_name},val:{val}')
except Exception as e:
print(f'on_opcua_notify处理异常,var_name:{var_name},val:{val},e:{e}')
2026-03-13 21:04:19 +08:00
def start_freq_thread(self):
"""启动频率上传线程"""
self.freq_thread = threading.Thread(
target=self._start_freq,
name="Freq",
daemon=True
)
self.freq_thread.start()
def _start_freq(self):
"""启动频率上传线程"""
while self.state.running:
# 上传频率
#未上传到IOT平台保存到数据库
_cur_mould=self.state.current_mould
if _cur_mould:
_code=_cur_mould.ArtifactID
_id=_cur_mould.ArtifactActionID
_mcode=_cur_mould.MouldCode
# freq=self.inverter_controller.read_frequency()
2026-04-07 09:51:38 +08:00
# freq=self.state._mould_frequency
freq=0
2026-03-13 21:04:19 +08:00
if freq>0:
self.freq_record_bll.insert_freq_record(FreqRecordModel(ArtifactID=_code,ArtifactActionID=_id,MouldCode=_mcode,Freq=freq))
else:
print('振捣频率未保存(因为当前浇筑的模具号为空)')
time.sleep(1)
2026-02-10 10:18:17 +08:00
@property
def _is_finish(self):
2026-03-13 21:04:19 +08:00
"""检查系统是否完成"""
return self.state._feed_status==FeedStatus.FFinished
@property
def _is_finish_ratio(self):
2026-03-13 21:04:19 +08:00
"""完成比例"""
return self.state._mould_finish_ratio
@property
def vibrate_status(self):
"""检查系统是否运行"""
return self.state._mould_vibrate_status
def set_vf_mode(self,is_auto=False):
"""设置变频器为自动模式"""
self.vf_auto_mode=is_auto
def stop(self):
"""停止系统"""
print("停止控制系统...")
self.state.running = False
# 等待线程结束
if self.opc_queue_thread:
self.opc_queue_thread.join()
if self.vf_thread:
self.vf_thread.join()
if self.api_thread:
self.api_thread.join()
2026-02-10 10:18:17 +08:00
if self.pd_jbl_thread:
self.pd_jbl_thread.join()
if self.feed_thread:
self.feed_thread.join()
if self.arch_thread:
self.arch_thread.join()
if self.plc_service:
self.plc_service.stop_polling()
2026-03-13 21:04:19 +08:00
self.opcua_client_feed.stop_run()
2026-02-10 10:18:17 +08:00
self.feeding_controller.shutdown()
# 释放摄像头资源
# self.camera_controller.release()
print("控制系统已停止")
if __name__ == "__main__":
system = FeedingControlSystem()
system.initialize()
2026-03-13 21:04:19 +08:00
system.opcua_client_feed.subscribe_node(system.state.feed_status)
time.sleep(2)
system.state._upper_weight=1000
while True:
time.sleep(1)