WPF OPC读写和订阅
WPF OPC数据读写
安装 OpcUaHelper
MainWindow.xaml
<Window x:Class="HSAPP.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:HSAPP"
FontSize="30"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<StackPanel>
<TextBlock x:Name="showValueText" Text="123"></TextBlock>
<Button Content="连接OPC" Margin="20" Click="ConnectOPCUA"></Button>
<Button Content="读写OPC数据" Click="ReadData"></Button>
<Button Content="读写OPC数据" Click="ReadData"></Button>
</StackPanel>
</Grid>
</Window>
MainWindow.xaml.cs
opc.tcp://localhost:5018 为OPC服务器的地址
使用 opcUaClient.ConnectServer(“opc.tcp://localhost:5018”); 连接服务器
可以使用OPC连接工具(Softing OPC Client)查看读取数据的Tag
使用 opcUaClient.ReadNode(“ns=7;s=TEST_VALUE”); 读取数据
using Opc.Ua;
using Opc.Ua.Client;
using OpcUaHelper;
namespace TESTAPP
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
// OPC连接对象
OpcUaClient opcUaClient = null;
MySqlConnection conn;
float testValue = 0;
public MainWindow()
{
InitializeComponent();
opcUaClient = new OpcUaClient();
}
private async void ConnectOPCUA(object sender, RoutedEventArgs e)
{
try
{
// 连接OPC
opcUaClient.UserIdentity = new UserIdentity(new AnonymousIdentityToken());
await opcUaClient.ConnectServer("opc.tcp://localhost:5018");
}
catch (Exception ex)
{
MessageBox.Show("连接失败");
}
}
public void ReadData(object sender, RoutedEventArgs e)
{
// 读取数据
Double value = opcUaClient.ReadNode<Double>("ns=7;s=TEST_VALUE");
showValueText.Text = value.ToString();
MessageBox.Show("读取数据:" + value.ToString(),"提示");
// 写入数据
opcUaClient.WriteNode<Double>("ns=7;s=TEST_VALUE",12.34);
// 读取字符串
string testString = opcUaClient.ReadNode<string>("ns=9;s=TEST_STRING");
showValueText.Text = testString.ToString();
MessageBox.Show("读取数据:" + testString.ToString(), "提示");
// 写入字符串
opcUaClient.WriteNode<string>("ns=9;s=TEST_STRING", "back hello word");
}
}
}
运行效果
第一次点击读写按钮后,读取的是OPC服务器原始值
读取OPC模拟量
读取OPC字符串
第二次点击读写按钮后,读取的是设置的OPC服务器值
读取之前写入模拟量
读取之前写入字符串
WPF OPC数据订阅
单点订阅
MainWindow.xaml.cs
public void SubData(object sender, RoutedEventArgs e)
{
//单节点数据订阅
opcUaClient.AddSubscription("TEST_VALUE", "ns=7;s=TEST_VALUE", SubCallback);
//取消单节点数据订阅
//m_OpcUaClient.RemoveSubscription("TEST_VALUE");
}
//1-单节点数据订阅的回调函数
private void SubCallback(string key, MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args)
{
// 判断Key是否存在和确定调用线程是否为关联的线程。
if (!showValueText.Dispatcher.CheckAccess() && key == "TEST_VALUE")
{
// 提取key对应的数据
MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
string value = notification.Value.WrappedValue.Value.ToString();
// 在关联的线程上同步执行
showValueText.Dispatcher.Invoke(new Action(() => {
showValueText.Text = value;
}));
}
}
运行效果
连接OPC服务器,订阅OPC数据后,当其他OPC客户端写这个数据后,showValueText控件数据会实时改变
多点订阅
private string[] OPCNodeTags = null;
private void button5_Click( object sender, EventArgs e )
{
// 多个节点的订阅
OPCNodeTags = new string[]
{
"ns=7;s=TEST_VALUE1",
"ns=7;s=TEST_VALUE2",
"ns=7;s=TEST_VALUE3",
};
m_OpcUaClient.AddSubscription( "TEST_VALUE_LIST", OPCNodeTags, SubListCallback );
}
private void SubCallback(string key, MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args)
{
if(key == "TEST_VALUE_LIST")
{
// 需要区分出来每个不同的节点信息
MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
if (monitoredItem.StartNodeId.ToString( ) == OPCNodeTags[0])
{
MessageBox.show(notification.Value.WrappedValue.Value.ToString( ),"提示1");
}
}
}