You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于C#.NETFramework从Kepware OPC UA服务器获取树结构及读取标签求助

简洁实现OPC UA节点树导入TreeView与标签定时读取(.NET Framework + Kepware)

依赖准备

  • 安装NuGet包:OPCFoundation.NetStandard.Opc.Ua(兼容.NET Framework 4.6.1及以上版本)

1. 连接OPC UA服务器并填充TreeView

核心通过递归遍历OPC UA节点树,将节点同步到WinForms的TreeView控件中,同时处理UI线程同步避免跨线程异常。

代码实现

using Opc.Ua;
using Opc.Ua.Client;
using System.Windows.Forms;

public class OpcUaTreeHelper
{
    private Session _session;
    private TreeView _treeView;

    public OpcUaTreeHelper(TreeView treeView)
    {
        _treeView = treeView;
    }

    // 连接Kepware OPC UA服务器
    public async Task ConnectAsync(string endpointUrl)
    {
        var endpoint = new ConfiguredEndpoint(null, new EndpointDescription(endpointUrl));
        // Kepware默认安全模式为None,可根据实际配置调整
        endpoint.SecurityMode = MessageSecurityMode.None;
        endpoint.SecurityPolicyUri = SecurityPolicies.None;

        _session = await Session.Create(
            new ApplicationConfiguration(),
            endpoint,
            false,
            "",
            60000,
            new UserIdentity(new AnonymousIdentityToken()),
            null);

        // 从根节点开始遍历填充TreeView
        await PopulateTreeViewAsync(_session.NodeCache.RootNode, _treeView.Nodes);
    }

    // 递归遍历节点并添加到TreeView
    private async Task PopulateTreeViewAsync(Node node, TreeNodeCollection parentNodes)
    {
        var treeNode = new TreeNode(node.DisplayName.Text) { Tag = node.NodeId };
        // 跨线程更新UI控件
        _treeView.Invoke((Action)(() => parentNodes.Add(treeNode)));

        // 遍历子节点(筛选变量和对象类型节点,跳过系统冗余节点)
        var browseResult = await _session.BrowseAsync(
            null,
            null,
            node.NodeId,
            0u,
            BrowseDirection.Forward,
            ReferenceTypeIds.HierarchicalReferences,
            true,
            (uint)NodeClass.Variable | (uint)NodeClass.Object);

        foreach (var reference in browseResult.References)
        {
            var childNode = await _session.ReadNodeAsync(reference.NodeId);
            if (childNode != null)
            {
                await PopulateTreeViewAsync(childNode, treeNode.Nodes);
            }
        }
    }
}

窗体中调用示例

private async void Form_Load(object sender, EventArgs e)
{
    var helper = new OpcUaTreeHelper(treeView1);
    // 替换为你的Kepware OPC UA服务器地址,默认端口49320
    await helper.ConnectAsync("opc.tcp://localhost:49320");
}

2. 定时读取指定标签并记录日志

使用WinForms Timer实现每分钟读取逻辑,通过OPC UA的ReadAsync方法获取标签值,追加到日志文件中。

代码实现

private Session _opcSession;
private Timer _readTimer;

// 初始化定时任务
private void InitReadTimer()
{
    _readTimer = new Timer { Interval = 60000 }; // 60秒间隔
    _readTimer.Tick += ReadTagsAndLog;
    _readTimer.Start();
}

// 读取标签并写入日志
private async void ReadTagsAndLog(object sender, EventArgs e)
{
    if (_opcSession == null || !_opcSession.Connected) return;

    // 替换为需要读取的标签NodeId,可从TreeView节点的Tag属性获取
    var targetTagIds = new NodeId[]
    {
        new NodeId("ns=2;s=Channel1.Device1.Pressure"),
        new NodeId("ns=2;s=Channel1.Device1.Temperature")
    };

    try
    {
        var readResults = await _opcSession.ReadAsync(
            null,
            0,
            TimestampsToReturn.Both,
            targetTagIds.Select(id => new ReadValueId { NodeId = id }).ToArray());

        // 构造日志内容
        var logLine = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] ";
        foreach (var result in readResults)
        {
            logLine += result.StatusCode.IsGood 
                ? $"{result.NodeId}: {result.Value} " 
                : $"{result.NodeId}: 读取失败({result.StatusCode}) ";
        }

        // 追加到日志文件
        File.AppendAllText("opc_tag_log.txt", logLine + Environment.NewLine);
    }
    catch (Exception ex)
    {
        File.AppendAllText("opc_tag_log.txt", $"[{DateTime.Now}] 读取异常: {ex.Message}" + Environment.NewLine);
    }
}

关键注意事项

  • Kepware的OPC UA节点Id格式:通常为ns=2;s=ChannelName.DeviceName.TagName,ns=2为用户命名空间,可在Kepware配置中确认。
  • 权限配置:确保Kepware OPC UA服务器允许匿名访问,或配置对应用户身份信息。
  • 资源释放:程序退出时需断开OPC会话,避免资源泄漏:await _session.CloseAsync();

内容的提问来源于stack exchange,提问作者Mert Atmaca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 15:55:20