在工业自动化和数据采集领域,OPC(OLE for Process Control)是一种标准通信协议,用于在不同工业设备和软件系统之间实现数据交换。OPC DA(Data Access)是最常用的OPC协议之一,用于读取和写入实时数据。
C#using OpcClientSdk.Da;
using OpcClientSdk;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AppDaBrowser
{
/// <summary>
/// OPC DA服务器浏览器
/// </summary>
public class OpcDaBrowser
{
/// <summary>
/// 日志记录委托
/// </summary>
private Action<string> Logger { get; set; }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="logger">日志记录方法</param>
public OpcDaBrowser(Action<string> logger = null)
{
Logger = logger ?? Console.WriteLine;
}
/// <summary>
/// 发现OPC服务器
/// </summary>
/// <returns>可用服务器列表</returns>
public List<OpcServer> DiscoverServers()
{
try
{
Logger("开始发现OPC服务器...");
// 发现OPC DA 2.0服务器
List<OpcServer> servers = OpcDiscovery.GetServers(OpcSpecification.OPC_DA_20);
Logger($"发现 {servers.Count} 个OPC服务器");
// 打印服务器详情
foreach (var server in servers)
{
Logger($"服务器名称: {server.ServerName}");
Logger($"服务器地址: {server.Url}");
}
return servers;
}
catch (Exception ex)
{
Logger($"服务器发现失败: {ex.Message}");
return new List<OpcServer>();
}
}
/// <summary>
/// 连接到OPC服务器
/// </summary>
/// <param name="serverUrl">服务器URL</param>
/// <returns>连接的服务器实例</returns>
public TsCDaServer ConnectToServer(string serverUrl)
{
try
{
TsCDaServer server = new TsCDaServer();
Logger($"正在连接服务器: {serverUrl}");
// 连接服务器
server.Connect(serverUrl);
Logger("成功连接到服务器");
return server;
}
catch (Exception ex)
{
Logger($"服务器连接失败: {ex.Message}");
return null;
}
}
/// <summary>
/// 浏览服务器地址空间
/// </summary>
/// <param name="server">OPC服务器实例</param>
public void BrowseAddressSpace(TsCDaServer server)
{
if (server == null) return;
try
{
Logger("开始浏览地址空间...");
// 配置浏览过滤器
TsCDaBrowseFilters filters = new TsCDaBrowseFilters
{
BrowseFilter = TsCDaBrowseFilter.All,
ReturnAllProperties = true,
ReturnPropertyValues = true
};
// 初始浏览位置
TsCDaBrowsePosition position;
// 浏览根节点
TsCDaBrowseElement[] elements = server.Browse(
new OpcItem(""), // 根路径
filters,
out position
);
// 递归打印浏览元素
PrintBrowseElements(elements, 0);
}
catch (Exception ex)
{
Logger($"地址空间浏览失败: {ex.Message}");
}
}
/// <summary>
/// 递归打印浏览元素
/// </summary>
/// <param name="elements">浏览元素数组</param>
/// <param name="depth">树深度</param>
private void PrintBrowseElements(TsCDaBrowseElement[] elements, int depth)
{
if (elements == null) return;
foreach (var element in elements)
{
string indent = new string(' ', depth * 2);
Logger($"{indent}- 名称: {element.Name}");
Logger($"{indent} 是否为项目: {element.IsItem}");
// 如果是项目,获取详细信息
if (element.IsItem)
{
Logger($"{indent} 项目路径: {element.ItemPath}");
Logger($"{indent} 项目名称: {element.ItemName}");
}
}
}
/// <summary>
/// 获取项目属性
/// </summary>
/// <param name="server">OPC服务器实例</param>
/// <param name="itemPath">项目路径</param>
public void GetItemProperties(TsCDaServer server, string itemPath)
{
if (server == null) return;
try
{
Logger($"获取项目 {itemPath} 的属性");
// 创建OPC项目
OpcItem[] items = new[]
{
new OpcItem(itemPath)
};
// 获取属性
TsCDaItemPropertyCollection[] properties = server.GetProperties(
items,
null, // 所有属性
true // 返回属性值
);
// 打印属性
foreach (var propertyCollection in properties)
{
Logger($"项目 {propertyCollection.ItemPath} 的属性:");
foreach (var property in propertyCollection)
{
dynamic d = property;
if (d.Result.Succeeded())
{
Logger($" 属性: {d.Description}");
Logger($" 值: {OpcConvert.ToString(d.Value)}");
}
}
}
}
catch (Exception ex)
{
Logger($"获取项目属性失败: {ex.Message}");
}
}
}
}
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AppDaBrowser
{
internal class Program
{
static void Main(string[] args)
{
// 创建OPC浏览器实例
OpcDaBrowser browser = new OpcDaBrowser();
try
{
// 1. 发现服务器
var servers = browser.DiscoverServers();
if (servers.Count > 0)
{
// 选择第一个服务器
var selectedServer = servers[1];
// 2. 连接服务器
var server = browser.ConnectToServer(selectedServer.Url.ToString());
if (server != null)
{
// 3. 浏览地址空间
browser.BrowseAddressSpace(server);
// 4. 获取示例项目属性
browser.GetItemProperties(server, "Channel.Device.L1");
// 5. 断开连接
server.Disconnect();
}
}
Console.ReadKey();
}
catch (Exception ex)
{
Console.WriteLine($"发生错误: {ex.Message}");
}
}
}
}

OpcClientSdk 为控制台应用提供了强大的 OPC UA 浏览工具。通过合理设计和使用,可以轻松实现工业设备的通信和数据交互。
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!