Files
Feeding_control_system/core/system.py
2026-04-07 09:51:38 +08:00

705 lines
33 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import threading
import time
import queue
import json
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
from busisness.blls import ArtifactBll,PDRecordBll,FreqRecordBll
from busisness.models import ArtifactInfoModel,PDRecordModel,FreqRecordModel
from core.pd_task_service import PD_TaskService
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:
def __init__(self):
print('FeedingControlSystem初始化')
self.state = SystemState()
self.prev_pd_volume=0.0
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)
self.plc_service = OmronFinsPollingService(ini_manager.upper_plc_ip, ini_manager.upper_plc_port)
# 初始化下料控制器
self.feeding_controller = VisualCallback(
relay_controller=self.relay_controller,
transmitter_controller=self.transmitter_controller,
state=self.state
)
self.plc_service.register_data_callback(self.feeding_controller.on_plc_update)
#小屏修改过屏幕
self.vf_auto_mode=True
# 初始化 OPC UA 客户端
self.opcua_client_feed = OpcuaClientFeed(notify_callback=self.on_opcua_notify)
# 线程管理
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
#处理频率上传线程
self.freq_thread=None
def initialize(self)->bool:
"""初始化系统"""
print("初始化控制系统...")
# self.check_device_connectivity()
#启用上料斗PLC
self.plc_service.start_polling(interval=2.0)
#启用下料线程
self.start_feed_thread()
#启用变频器线程
self.start_vf_thread()
#启用破拱线程
self.start_arch_thread()
#启用推送模型数据线程
self.feeding_controller.start_visual_thread()
#启用API(对接PD API数据),线程
self.start_api_thread()
#启用派单线程
self.start_pd_thread()
# 启动OPC队列处理线程维护连接的断开重连等
self.opcua_client_feed.start()
#开启接收通知数据(queue线程)
self.opcua_client_feed.start_accept()
self.start_opc_queue_thread()
#启用频率上传线程
self.start_freq_thread()
print("控制系统初始化完成")
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):
"""启动OPC队列处理线程从控制系统中获取数据通过OPC外发"""
print('启动OPC队列处理线程')
self.opc_queue_thread = threading.Thread(
target=self._process_opc_queue,
daemon=True,
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):
"""启动变频器控制线程(控制变频器开始启动,以及频率变换)"""
# 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
_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()
if self.state._mould_finish_ratio>=0.05:
_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)
_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:
print("----下料重量小于46KG,暂时不振捣-----")
else:
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
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')
_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:
_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:
# 标记为已处理
_is_refresh=True
# self.state._sys_segment_refresh=1
processed_artifact_actions.append(item.MouldCode)
if len(processed_artifact_actions) > 10:
processed_artifact_actions.pop(0)
if item.ArtifactID:
processed_artifact_ids.append(item.ArtifactID)
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,
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(
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:
# self.state._sys_segment_refresh=1
_is_refresh=True
# 标记为已处理
processed_pd_records.append(item.MouldCode)
# 限制最多保存3条记录删除最旧的
if len(processed_pd_records) > 10:
processed_pd_records.pop(0)
if item.ArtifactID:
processed_pd_ids.append(item.ArtifactID)
if len(processed_pd_ids) > 10:
processed_pd_ids.pop(0)
#print(f"派单:已处理MouldCode {item.MouldCode} ArtifactID {item.ArtifactID}")
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处理逻辑
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()
def start_arch_thread(self):
"""启动系统监控和要料"""
print('振动和要料监控线程启动')
#启动振动线程
self.arch_thread = threading.Thread(
target=self.feeding_controller._arch_loop,
daemon=True,
name='arch'
)
self.arch_thread.start()
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
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
#根据当前浇筑块进行最近一块的派单
# _start_time=None
while self.state.running:
#设置的派单模式
if self.state.pd_set_mode==1:
#增加生产阶段检测,
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()
_isSuccess=self.send_pd_data()
if _isSuccess:
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
_start_time=None
else:
print('已开启手动派单,或未设置派单模式')
print('已开启手动派单,或未设置派单模式')
time.sleep(5)
def send_pd_data(self):
"""
发送PD数据到OPC队列
:param _pd_status: PD状态
"""
# 构建PD数据
# print("send_pd_data1")
_cur_mould=self.state.current_mould
if _cur_mould is not None:
# print("send_pd_data2")
if _cur_mould.MouldCode:
_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}")
if _pdrecord.TaskID:
if _pdrecord.Status==1:
# print(f"send_pd_data6,{_pdrecord.TaskID}")
# tasks, artifact_list, send_list, half_volume = self.pd_task_service.process_not_pour_info(_pdrecords)
# 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)))
_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:
print(f'{_pdrecord.MouldCode} F块不发送派单数据')
self.pd_record_bll.start_pd(PD_StatusEnum.PD_Send_Finish.value,_pdrecord.MouldCode,0)
else:
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:
#更新派单表
# 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
if _ret_flag:
_opc_pd={
"ID":_pdrecord.ID,
"ArtifactActionID":_pdrecord.ArtifactActionID,
"MouldCodePD":_pdrecord.MouldCode,
"MouldCode":_cur_code,
"TaskID":_pdrecord.TaskID,
"ProduceMixID":_pdrecord.ProduceMixID,
"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()),
}
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}')
return True
else:
print(f'{_pdrecord.MouldCode} 未获取到数据-(等待扫码)')
return False
else:
print(f'接口数据为空')
return False
else:
print(f'当前浇筑模具为空')
return False
else:
return False
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:
if self.state.mould_code==led_info.MouldCode:
led_info.RingTypeCode=led_info.RingTypeCode
led_info.UpperWeight=self.state._upper_weight
led_info.LowerWeight=self.state._lower_weight
led_info.VibrationFrequency=self.state._mould_frequency
#发送到LED屏
time.sleep(2)
def on_opcua_notify(self,var_name,val):
"""OPC UA通知回调"""
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
else:
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}')
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()
# freq=self.state._mould_frequency
freq=0
if freq>0:
self.freq_record_bll.insert_freq_record(FreqRecordModel(ArtifactID=_code,ArtifactActionID=_id,MouldCode=_mcode,Freq=freq))
else:
print('振捣频率未保存(因为当前浇筑的模具号为空)')
time.sleep(1)
@property
def _is_finish(self):
"""检查系统是否完成"""
return self.state._feed_status==FeedStatus.FFinished
@property
def _is_finish_ratio(self):
"""完成比例"""
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()
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()
self.opcua_client_feed.stop_run()
self.feeding_controller.shutdown()
# 释放摄像头资源
# self.camera_controller.release()
print("控制系统已停止")
if __name__ == "__main__":
system = FeedingControlSystem()
system.initialize()
system.opcua_client_feed.subscribe_node(system.state.feed_status)
time.sleep(2)
system.state._upper_weight=1000
while True:
time.sleep(1)