介绍如何使用GodSharpOpcDa库从OPC DA服务器读取数据,并通过MQTT协议将数据发送到ThingsBoard。所有代码全部是AI生成。
1. 环境准备
在开始之前,确保以下环境已准备好:
OPC DA服务器:例如Kepware。
ThingsBoard实例:可以是本地部署或云端实例。
.NET开发环境:Visual Studio。
NuGet包:
GodSharp.Opc.Da (2022.308.10)
GodSharp.Opc.Da.OpcNetApi (2022.308.10)
MQTTnet (4.3.7.1207)
Newtonsoft.Json (13.0.3)
用Visual Studio新建控制台应用,框架选.NET6.0
打开新建的项目,右键属性设置目标平台
右键打开NuGet管理器安装NuGet包
必须安装对应的版本。
GodsharpOPC 项目网址:https://github.com/godsharp/opcsample
官方示例代码:
using GodSharp.Opc.Da; // 引入GodSharp OPC DA库
using GodSharp.Opc.Da.Options; // 引入GodSharp OPC DA选项库
using System; // 引入系统基础库
using System.Collections.Generic; // 引入泛型集合库
using System.Linq; // 引入LINQ库
namespace GodSharpOpcDaSample // 定义命名空间
{
internal class Program // 定义Program类
{
private static void Main(string[] args) // 主函数入口
{
/*
* KEPware.KEPServerEx.V4
* Kepware.KEPServerEX.V6
* Mitsubishi.MXOPC.7
*/
Console.WriteLine("Hello GodSharpOpcDaSample!"); // 输出欢迎信息
var write = 1000; // 定义一个变量用于写入值
// 初始化数据信息
// 组 `Name`, `ClientHandle` 是唯一且必需的,`UpdateRate` 也是必需的。
// 标签 `ItemName`, `ClientHandle` 是唯一且必需的。
var groups = new List<GroupData> // 定义组数据列表
{
new GroupData // 定义第一个组
{
Name = "default", UpdateRate = 100, ClientHandle = 010, IsSubscribed = true, // 组名、更新速率、客户端句柄、是否订阅
Tags = new List<Tag> // 定义标签列表
{
new Tag("Test.Simulator.Booleans.B0001", 011), // 定义标签1
new Tag("Test.Simulator.Numbers.N0001", 012), // 定义标签2
new Tag("Test.Simulator.Characters.C0001", 013) // 定义标签3
}
},
new GroupData // 定义第二个组
{
Name = "group1", UpdateRate = 100, ClientHandle = 100,IsSubscribed = true, // 组名、更新速率、客户端句柄、是否订阅
Tags = new List<Tag> // 定义标签列表
{
new Tag("Test.Simulator.Booleans.B0002", 101), // 定义标签1
new Tag("Test.Simulator.Numbers.N0002", 102), // 定义标签2
new Tag("Test.Simulator.Characters.C0002", 103) // 定义标签3
}
},
new GroupData // 定义第三个组
{
Name = "group2", UpdateRate = 100, ClientHandle = 200,IsSubscribed = false, // 组名、更新速率、客户端句柄、是否订阅
Tags = new List<Tag> // 定义标签列表
{
new Tag("Test.Simulator.Booleans.B0003", 201), // 定义标签1
new Tag("Test.Simulator.Numbers.N0003", 202), // 定义标签2
new Tag("Test.Simulator.Characters.C0003", 203) // 定义标签3
}
}
};
var server = new ServerData // 定义服务器数据
{
Host = "127.0.0.1", // 服务器主机地址
ProgId = "Kepware.KEPServerEX.V6", // 服务器程序ID
// 初始化数据信息,连接后会自动添加到客户端
// 如果为null,则需要手动添加组和标签
Groups = groups // 组数据
};
var client = DaClientFactory.Instance.CreateOpcNetApiClient(new DaClientOptions( // 创建OPC DA客户端
server,
OnDataChangedHandler, // 数据变化回调
OnShoutdownHandler, // 服务器关闭回调
OnAsyncReadCompletedHandler, // 异步读取完成回调
OnAsyncWriteCompletedHandler)); // 异步写入完成回调
Console.WriteLine("connect to server ..."); // 输出连接服务器信息
client.Connect(); // 连接服务器
/*
// 手动添加组和标签
Console.WriteLine($"connect to server {client.Server.ProgId}:{client.Connected}");
Console.WriteLine($"add group to server ...");
client.Add(new Group() {Name = "default", UpdateRate = 100, ClientHandle = 010});
client.Add(new Group() {Name = "group1", UpdateRate = 100, ClientHandle = 100});
client.Add(new Group() {Name = "group2", UpdateRate = 100, ClientHandle = 200});
Console.WriteLine($"add items to groups ...");
client.Groups["default"].Add(new Tag("Channel1.Device1.Bool", 001));
client.Groups["default"].Add(new Tag("Channel1.Device1.Heartbeat", 010));
client.Groups["default"].Add(new Tag("Channel1.Device1.RunMode", 011));
client.Groups["group1"].Add(
new Tag("Channel1.Device1.Group1.Code", 100),
new Tag("Channel1.Device1.Group1.Number", 101));
client.Groups["group2"].Add(new Tag("Channel1.Device1.Group2.Code", 200));
client.Groups["group2"].Add(new Tag("Channel1.Device1.Group2.Number", 201));
*/
//var props = client.GetItemProperties("Test.Simulator.Booleans.B0001");
Console.WriteLine($"waitting Reads ..."); // 输出等待读取信息
Console.ReadLine(); // 等待用户输入
foreach (var group in client.Groups.Values) // 遍历所有组
{
if (group.Tags.Count == 0) continue; // 如果组中没有标签则跳过
var results = group.Reads(group.Tags.Values.Select(x => x.ItemName)?.ToArray()); // 同步读取标签值
foreach (var item in results) // 遍历读取结果
{
Console.WriteLine(
$"Sync Read {
item.Result.ItemName}:{
item.Result.Value},{
item.Result.Quality} / {
item.Result.Timestamp} / {
item.Ok}|{
item.Code}"); // 输出读取结果
}
}
Console.WriteLine($"waitting ReadsAsync ..."); // 输出等待异步读取信息
Console.ReadLine(); // 等待用户输入
foreach (var group in client.Groups.Values) // 遍历所有组
{
if (group.Tags.Count == 0