feeding
This commit is contained in:
158
opc/opcua_client_test.py
Normal file
158
opc/opcua_client_test.py
Normal file
@ -0,0 +1,158 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
OPC UA 客户端测试脚本
|
||||
用于连接和测试 OPC UA 服务器
|
||||
"""
|
||||
|
||||
from opcua import Client
|
||||
import time
|
||||
import sys
|
||||
|
||||
class OPCUAClientTest:
|
||||
def __init__(self, server_url="opc.tcp://localhost:4840/zjsh_feed/server/"):
|
||||
"""
|
||||
初始化 OPC UA 客户端
|
||||
|
||||
Args:
|
||||
server_url: 服务器URL地址
|
||||
"""
|
||||
self.client = Client(server_url)
|
||||
self.connected = False
|
||||
|
||||
def connect(self):
|
||||
"""连接到服务器"""
|
||||
try:
|
||||
self.client.connect()
|
||||
self.connected = True
|
||||
print(f"成功连接到 OPC UA 服务器: {self.client.server_url}")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"连接服务器失败: {e}")
|
||||
return False
|
||||
|
||||
def disconnect(self):
|
||||
"""断开连接"""
|
||||
if self.connected:
|
||||
self.client.disconnect()
|
||||
self.connected = False
|
||||
print("已断开与 OPC UA 服务器的连接")
|
||||
|
||||
def browse_nodes(self):
|
||||
"""浏览服务器节点结构"""
|
||||
if not self.connected:
|
||||
print("请先连接到服务器")
|
||||
return
|
||||
|
||||
try:
|
||||
# 获取根节点
|
||||
root = self.client.get_root_node()
|
||||
print(f"根节点: {root}")
|
||||
|
||||
# 获取对象节点
|
||||
objects = self.client.get_objects_node()
|
||||
print(f"对象节点: {objects}")
|
||||
|
||||
# 浏览 IndustrialDevice 节点
|
||||
upper_device = objects.get_child("2:upper")
|
||||
print(f"\n工业设备节点: {upper_device}")
|
||||
|
||||
# 获取传感器节点
|
||||
lower_device = objects.get_child("2:lower")
|
||||
print(f"传感器节点: {lower_device}")
|
||||
|
||||
|
||||
print(f"温度传感器: {upper_device}")
|
||||
print(f"压力传感器: {lower_device}")
|
||||
|
||||
# 获取变量值
|
||||
print("\n=== 当前传感器数据 ===")
|
||||
self.read_sensor_values(upper_device, lower_device)
|
||||
|
||||
except Exception as e:
|
||||
print(f"浏览节点时出错: {e}")
|
||||
|
||||
def read_sensor_values(self, upper_device, lower_device):
|
||||
"""读取传感器数值"""
|
||||
try:
|
||||
# 读取温度
|
||||
temp_value = upper_device.get_child("2:upper_weight").get_value()
|
||||
temp_unit = upper_device.get_child("2:lower_weight").get_value()
|
||||
print(f"温度: {temp_value} {temp_unit}")
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print(f"读取传感器数据时出错: {e}")
|
||||
|
||||
def monitor_data(self, duration=30):
|
||||
"""监控数据变化"""
|
||||
if not self.connected:
|
||||
print("请先连接到服务器")
|
||||
return
|
||||
|
||||
print(f"\n开始监控数据变化,持续 {duration} 秒...")
|
||||
|
||||
try:
|
||||
# 获取传感器节点
|
||||
objects = self.client.get_objects_node()
|
||||
upper_device = objects.get_child("2:upper")
|
||||
lower_device = objects.get_child("2:lower")
|
||||
|
||||
|
||||
|
||||
|
||||
start_time = time.time()
|
||||
while time.time() - start_time < duration:
|
||||
print(f"\n--- {time.strftime('%H:%M:%S')} ---")
|
||||
self.read_sensor_values(upper_device, lower_device)
|
||||
time.sleep(5) # 每5秒读取一次
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n监控被用户中断")
|
||||
except Exception as e:
|
||||
print(f"监控数据时出错: {e}")
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
# 创建客户端
|
||||
client = OPCUAClientTest("opc.tcp://localhost:4840/zjsh_feed/server/")
|
||||
|
||||
try:
|
||||
# 连接到服务器
|
||||
if not client.connect():
|
||||
return
|
||||
|
||||
# 浏览节点结构
|
||||
client.browse_nodes()
|
||||
|
||||
# 监控数据变化
|
||||
client.monitor_data(duration=30)
|
||||
|
||||
# 测试写入数据
|
||||
# client.write_test_data()
|
||||
|
||||
# 继续监控
|
||||
print("\n继续监控数据...")
|
||||
client.monitor_data(duration=15)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n客户端被用户中断")
|
||||
finally:
|
||||
# 断开连接
|
||||
client.disconnect()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) > 1:
|
||||
# 支持自定义服务器地址
|
||||
server_url = sys.argv[1]
|
||||
client = OPCUAClientTest(server_url)
|
||||
else:
|
||||
client = OPCUAClientTest()
|
||||
|
||||
try:
|
||||
main()
|
||||
except Exception as e:
|
||||
print(f"客户端运行错误: {e}")
|
||||
sys.exit(1)
|
||||
172
opc/opcua_server.py
Normal file
172
opc/opcua_server.py
Normal file
@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
简单的OPC UA服务器示例
|
||||
用于工业自动化数据通信
|
||||
"""
|
||||
|
||||
from opcua import Server, ua
|
||||
import time
|
||||
import random
|
||||
import threading
|
||||
from datetime import datetime
|
||||
from core.system import SystemState
|
||||
|
||||
class SimpleOPCUAServer:
|
||||
def __init__(self, state, endpoint="opc.tcp://0.0.0.0:4840/zjsh_feed/server/", name="Feed_Server"):
|
||||
"""
|
||||
初始化OPC UA服务器
|
||||
|
||||
Args:
|
||||
endpoint: 服务器端点地址
|
||||
name: 服务器名称
|
||||
"""
|
||||
self.server = Server()
|
||||
self.server.set_endpoint(endpoint)
|
||||
self.server.set_server_name(name)
|
||||
self.state = state
|
||||
|
||||
# 设置服务器命名空间
|
||||
self.namespace = self.server.register_namespace("Feed_Control_System")
|
||||
|
||||
# 获取对象节点
|
||||
self.objects = self.server.get_objects_node()
|
||||
|
||||
# 创建自定义对象
|
||||
self.create_object_structure()
|
||||
|
||||
# 运行标志
|
||||
self.running = False
|
||||
|
||||
def create_object_structure(self):
|
||||
"""创建OPC UA对象结构"""
|
||||
# 创建上料斗对象
|
||||
self.upper = self.objects.add_object(self.namespace, "upper")
|
||||
self.lower=self.objects.add_object(self.namespace, "lower")
|
||||
self.sys=self.objects.add_object(self.namespace, "sys")
|
||||
|
||||
# 创建变量
|
||||
self.create_variables()
|
||||
|
||||
def create_variables(self):
|
||||
"""创建OPC UA变量"""
|
||||
# 上料斗重量变量
|
||||
self.upper_weight = self.upper.add_variable(self.namespace, "upper_weight", 0.0)
|
||||
self.lower_weight = self.lower.add_variable(self.namespace, "lower_weight", 0.0)
|
||||
|
||||
# 设置变量为可写
|
||||
self.upper_weight.set_writable()
|
||||
self.lower_weight.set_writable()
|
||||
|
||||
def setup_state_listeners(self):
|
||||
"""设置状态监听器 - 事件驱动更新"""
|
||||
if hasattr(self.state, 'state_updated'):
|
||||
self.state.state_updated.connect(self.on_state_changed)
|
||||
print("状态监听器已设置 - 事件驱动模式")
|
||||
|
||||
def on_state_changed(self, property_name, value):
|
||||
"""状态变化时的回调函数"""
|
||||
try:
|
||||
# 根据属性名更新对应的OPC UA变量
|
||||
if property_name == "upper_weight":
|
||||
self.upper_weight.set_value(value)
|
||||
elif property_name == "lower_weight":
|
||||
self.lower_weight.set_value(value)
|
||||
|
||||
# 可以在这里添加更多状态映射
|
||||
print(f"状态更新: {property_name} = {value}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"状态更新错误: {e}")
|
||||
|
||||
def start(self):
|
||||
"""启动服务器"""
|
||||
try:
|
||||
self.server.start()
|
||||
self.running = True
|
||||
print(f"OPC UA服务器启动成功!")
|
||||
print(f"服务器端点: opc.tcp://0.0.0.0:4840/freeopcua/server/")
|
||||
print(f"命名空间: {self.namespace}")
|
||||
|
||||
# 初始化当前值
|
||||
if self.state:
|
||||
self.upper_weight.set_value(self.state._upper_weight)
|
||||
self.lower_weight.set_value(self.state._lower_weight)
|
||||
print("已同步初始状态值")
|
||||
|
||||
# 设置状态监听器 - 关键步骤!
|
||||
self.setup_state_listeners()
|
||||
|
||||
# # 只有在没有状态系统时才使用模拟线程
|
||||
# if not self.state:
|
||||
# print("使用模拟数据模式")
|
||||
# self.simulation_thread = threading.Thread(target=self.simulate_data)
|
||||
# self.simulation_thread.daemon = True
|
||||
# self.simulation_thread.start()
|
||||
|
||||
except Exception as e:
|
||||
print(f"启动服务器失败: {e}")
|
||||
|
||||
def stop(self):
|
||||
"""停止服务器"""
|
||||
self.running = False
|
||||
if hasattr(self, 'simulation_thread'):
|
||||
self.simulation_thread.join(timeout=2)
|
||||
self.server.stop()
|
||||
print("OPC UA服务器已停止")
|
||||
|
||||
# 断开状态监听器
|
||||
if hasattr(self.state, 'state_updated'):
|
||||
try:
|
||||
self.state.state_updated.disconnect(self.on_state_changed)
|
||||
except:
|
||||
pass
|
||||
|
||||
def simulate_data(self):
|
||||
"""模拟数据更新"""
|
||||
while self.running:
|
||||
try:
|
||||
# 更新变量值
|
||||
self.upper_weight.set_value(self.state.upper_weight)
|
||||
self.lower_weight.set_value(self.state.lower_weight)
|
||||
|
||||
# 模拟延迟
|
||||
time.sleep(1)
|
||||
|
||||
except Exception as e:
|
||||
print(f"数据更新错误: {e}")
|
||||
continue
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
# 创建系统状态实例
|
||||
state = SystemState()
|
||||
|
||||
# 创建并启动服务器
|
||||
server = SimpleOPCUAServer(
|
||||
state=state,
|
||||
endpoint="opc.tcp://0.0.0.0:4840/freeopcua/server/",
|
||||
name="工业自动化 OPC UA 服务器"
|
||||
)
|
||||
|
||||
try:
|
||||
server.start()
|
||||
|
||||
|
||||
print("服务器正在运行,按 Ctrl+C 停止...")
|
||||
|
||||
# 保持服务器运行
|
||||
while True:
|
||||
time.sleep(1)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n正在停止服务器...")
|
||||
server.stop()
|
||||
|
||||
except Exception as e:
|
||||
print(f"服务器运行错误: {e}")
|
||||
server.stop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user