基本信息
源码名称:OPC通讯实例(OPC Unified Automation client)
源码大小:10.91M
文件格式:.rar
开发语言:C#
更新时间:2020-01-09
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):78630559
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
OPC Unified Automation client 源码
OPC Unified Automation client 源码
/******************************************************************************
** Copyright (c) 2006-2018 Unified Automation GmbH All rights reserved.
**
** Software License Agreement ("SLA") Version 2.7
**
** Unless explicitly acquired and licensed from Licensor under another
** license, the contents of this file are subject to the Software License
** Agreement ("SLA") Version 2.7, or subsequent versions
** as allowed by the SLA, and You may not copy or use this file in either
** source code or executable form, except in compliance with the terms and
** conditions of the SLA.
**
** All software distributed under the SLA is provided strictly on an
** "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
** AND LICENSOR HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
** LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
** PURPOSE, QUIET ENJOYMENT, OR NON-INFRINGEMENT. See the SLA for specific
** language governing rights and limitations under the SLA.
**
** Project: .NET based OPC UA Client Server SDK
**
** Description: OPC Unified Architecture Software Development Kit.
**
** The complete license agreement can be found here:
** http://unifiedautomation.com/License/SLA/2.7/
******************************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using UnifiedAutomation.UaBase;
using UnifiedAutomation.UaClient;
namespace UnifiedAutomation.Sample
{
public partial class MainForm : Form
{
#region Connect and Disconnect Server
/// <summary>
/// Connect to the UA server and read the namespace table.
/// The connect is based on the Server URL entered in the Form
/// The read of the namespace table is used to detect the namespace index
/// of the namespace URI entered in the Form and used for the variables to read
/// </summary>
private void connect()
{
if (m_session == null)
{
// Create a session
m_session = new Session(m_application);
// attach to events
m_session.ConnectionStatusUpdate = new ServerConnectionStatusUpdateEventHandler(Session_ServerConnectionStatusUpdate);
}
m_session.UseDnsNameAndPortFromDiscoveryUrl = UseDnsNameAndPortFromDiscoveryUrl.Checked;
// Step 1 ----------------------------------------------------
// Connect to the server with no security
m_session.Connect(txtServerUrl.Text, SecuritySelection.None);
// Step 2 ----------------------------------------------------
// Search for the namespace URI entered in the user interface
// The namespace table is automatically read from the server and provided as property of the session
// Index in the namespace table is used as namespace index for the NodeIds in the example
ushort i;
for (i = 0; i < m_session.NamespaceUris.Count; i )
{
if (m_session.NamespaceUris[i] == txtNamespaceUri.Text)
{
m_NameSpaceIndex = i;
}
}
// Check if the namespace was found
if (m_NameSpaceIndex == 0)
{
throw new Exception("Namespace " txtNamespaceUri.Text " not found in server namespace table");
}
}
/// <summary>
/// Disconnect from the UA server.
/// </summary>
private void disconnect()
{
// Disconnect from Server
m_session.Disconnect();
m_subscription = null;
}
/// <summary>
/// receive updates about session state.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Session_ServerConnectionStatusUpdate(Session sender, ServerConnectionStatusUpdateEventArgs e)
{
if (InvokeRequired)
{
BeginInvoke(new ServerConnectionStatusUpdateEventHandler(Session_ServerConnectionStatusUpdate), sender, e);
return;
}
// check that the current session matches the session that raised the event.
if (!Object.ReferenceEquals(m_session, sender))
{
return;
}
lock (this)
{
bool allowEditing = true;
switch (e.Status)
{
case ServerConnectionStatus.Disconnected:
m_bConnected = false;
allowEditing = false;
// update status label
lblConnectionState.Text = "Disconnected";
// update buttons
btnConnect.Text = "Connect";
btnMonitor.Text = "Monitor";
break;
case ServerConnectionStatus.Connected:
m_bConnected = true;
allowEditing = true;
// update status label
lblConnectionState.Text = "Connected";
// update buttons
btnConnect.Text = "Disconnect";
break;
case ServerConnectionStatus.ConnectionWarningWatchdogTimeout:
// update status label
lblConnectionState.Text = "ConnectionWarningWatchdogTimeout";
break;
case ServerConnectionStatus.ConnectionErrorClientReconnect:
// update status label
lblConnectionState.Text = "ConnectionErrorClientReconnect";
break;
case ServerConnectionStatus.ServerShutdownInProgress:
// update status label
lblConnectionState.Text = "ServerShutdownInProgress";
break;
case ServerConnectionStatus.ServerShutdown:
// update status label
lblConnectionState.Text = "ServerShutdown";
break;
case ServerConnectionStatus.SessionAutomaticallyRecreated:
// update status label
lblConnectionState.Text = "SessionAutomaticallyRecreated";
break;
case ServerConnectionStatus.Connecting:
// update status label
lblConnectionState.Text = "Connecting";
break;
case ServerConnectionStatus.LicenseExpired:
// update status label
lblConnectionState.Text = "LicenseExpired";
break;
}
// Toggle Textboxes
txtServerUrl.Enabled = !m_bConnected;
txtNamespaceUri.Enabled = !m_bConnected;
// Toggle action buttons
btnMonitor.Enabled = allowEditing;
btnRead.Enabled = allowEditing;
btnReadAsync.Enabled = allowEditing;
btnWrite.Enabled = allowEditing;
btnWriteAsync.Enabled = allowEditing;
}
}
#endregion
#region Read and Write Variable Values
/// <summary>
/// Reads the values of the two variables entered in the From.
/// The NodeIds used for the Read are constructed from the identifier entered
/// in the Form and the namespace index detected in the connect method
/// </summary>
private void read()
{
// Step 1 --------------------------------------------------
// Prepare nodes to read
// Add the two variable NodeIds to the list of nodes to read
// NodeId is constructed from
// - the identifier text in the text box
// - the namespace index collected during the server connect
ReadValueIdCollection nodesToRead = new ReadValueIdCollection();
nodesToRead.Add(new ReadValueId()
{
NodeId = new NodeId(txtIdentifier1.Text, m_NameSpaceIndex),
AttributeId = Attributes.Value
});
nodesToRead.Add(new ReadValueId()
{
NodeId = new NodeId(txtIdentifier2.Text, m_NameSpaceIndex),
AttributeId = Attributes.Value
});
// Step 2 --------------------------------------------------
// Read the values from the server
List<DataValue> results = m_session.Read(nodesToRead);
// Step 3 --------------------------------------------------
// Update GUI with results
// Print result for first variable - check first the result code
if (StatusCode.IsGood(results[0].StatusCode))
{
// The node succeeded - print the value as string
txtRead1.Text = results[0].WrappedValue.ToString();
txtRead1.BackColor = Color.White;
}
else
{
// The node failed - print the symbolic name of the status code
txtRead1.Text = results[0].StatusCode.ToString();
txtRead1.BackColor = Color.Red;
}
// Print result for second variable - check first the result code
if (StatusCode.IsGood(results[1].StatusCode))
{
// The node succeeded - print the value as string
txtRead2.Text = results[1].WrappedValue.ToString();
txtRead2.BackColor = Color.White;
}
else
{
// The node failed - print the symbolic name of the status code
txtRead2.Text = results[1].StatusCode.ToString();
txtRead2.BackColor = Color.Red;
}
}
/// <summary>
/// Write 2 values to the variables entered in the From.
/// The NodeId used for the Write is constructed from the identifier entered
/// in the Form and the namespace index detected in the connect method
/// </summary>
private void write()
{
// Step 1 --------------------------------------------------
// Get values to write and convert them to the right data type
if (m_TypeItem1 == BuiltInType.Null || m_TypeItem2 == BuiltInType.Null)
{
// Read variable data types from server
readDataTypes();
}
// Get values from GUI and convert them to the right data type
DataValue val1 = new DataValue();
val1.Value = TypeUtils.Cast(txtWrite1.Text, m_TypeItem1);
DataValue val2 = new DataValue();
val2.Value = TypeUtils.Cast(txtWrite2.Text, m_TypeItem2);
// Step 2 --------------------------------------------------
// Prepare nodes to write including the values to write
List<WriteValue> nodesToWrite = new List<WriteValue>();
nodesToWrite.Add(new WriteValue()
{
NodeId = new NodeId(txtIdentifier1.Text, m_NameSpaceIndex),
AttributeId = Attributes.Value,
Value = val1
});
nodesToWrite.Add(new WriteValue()
{
NodeId = new NodeId(txtIdentifier2.Text, m_NameSpaceIndex),
AttributeId = Attributes.Value,
Value = val2
});
// Step 3 --------------------------------------------------
// Write values to server
List<StatusCode> results = m_session.Write(nodesToWrite);
// Step 4 --------------------------------------------------
// Update GUI with results
// check results
if (StatusCode.IsGood(results[0]))
{
// write succeeded - reset background color
txtWrite1.BackColor = Color.White;
}
else
{
// write failed - print the symbolic name of the status code
txtWrite1.Text = results[0].ToString();
txtWrite1.BackColor = Color.Red;
}
if (StatusCode.IsGood(results[1]))
{
// write succeeded - reset background color
txtWrite2.BackColor = Color.White;
}
else
{
// write failed - print the symbolic name of the status code
txtWrite2.Text = results[1].ToString();
txtWrite2.BackColor = Color.Red;
}
}
#endregion
#region Monitoring of Variable Values
/// <summary>
/// Start monitoring by creating a subscription and monitored items
/// </summary>
private void startMonitoring()
{
// Step 1 --------------------------------------------------
// Create and initialize subscription
m_subscription = new Subscription(m_session);
m_subscription.PublishingEnabled = true;
m_subscription.PublishingInterval = 100;
// Data change events will be received through Subscription_DataChanged
m_subscription.DataChanged = new DataChangedEventHandler(Subscription_DataChanged);
// Create subscription on server
m_subscription.Create();
// Step 2 --------------------------------------------------
// Prepare variables to monitor as data monitored item
List<MonitoredItem> monitoredItems = new List<MonitoredItem>();
// The corresponding result text box gets assigned as user data
// Default is monitoring Value attributes
monitoredItems.Add(new DataMonitoredItem(new NodeId(txtIdentifier1.Text, m_NameSpaceIndex)) { UserData = txtMonitored1 });
monitoredItems.Add(new DataMonitoredItem(new NodeId(txtIdentifier2.Text, m_NameSpaceIndex)) { UserData = txtMonitored2 });
// Step 3 --------------------------------------------------
// Create monitored items on server
List<StatusCode> results = m_subscription.CreateMonitoredItems(monitoredItems);
// Step 4 --------------------------------------------------
// Display any errors.
for (int ii = 0; ii < results.Count; ii )
{
TextBox textBox = monitoredItems[ii].UserData as TextBox;
if (textBox != null)
{
if (StatusCode.IsBad(results[ii]))
{
textBox.Text = results[ii].ToString();
textBox.BackColor = Color.Red;
}
else
{
textBox.Text = String.Empty;
textBox.BackColor = Color.White;
}
}
}
}
/// <summary>
/// Stop monitoring by deleting the subscription
/// </summary>
private void stopMonitoring()
{
// Delete subscription from server
// Monitored items are deleted together with the subscription
m_subscription.Delete();
m_subscription = null;
}
/// <summary>
/// Receive datachange notifications.
/// </summary>
/// <param name="subscription"></param>
/// <param name="e"></param>
private void Subscription_DataChanged(Subscription subscription, DataChangedEventArgs e)
{
// Need to make sure this method is called on the UI thread because it updates UI controls.
if (InvokeRequired)
{
BeginInvoke(new DataChangedEventHandler(Subscription_DataChanged), subscription, e);
return;
}
try
{
// Check that the subscription has not changed.
if (!Object.ReferenceEquals(m_subscription, subscription))
{
return;
}
foreach (DataChange change in e.DataChanges)
{
// Get text box for displaying value from user data
TextBox textBox = change.MonitoredItem.UserData as TextBox;
if (textBox != null)
{
// Print result for variable - check first the result code
if (StatusCode.IsGood(change.Value.StatusCode))
{
// The node succeeded - print the value as string
textBox.Text = change.Value.WrappedValue.ToString();
textBox.BackColor = Color.White;
}
else
{
// The node failed - print the symbolic name of the status code
textBox.Text = change.Value.StatusCode.ToString();
textBox.BackColor = Color.Red;
}
}
}
}
catch (Exception exception)
{
ExceptionDlg.Show("Error in DataChanged callback", exception);
}
}
#endregion
#region Async Read Variable Values with callback
/// <summary>
/// Reads the values of the two variables entered in the From.
/// The NodeIds used for the Read are constructed from the identifier entered
/// in the Form and the namespace index detected in the connect method
/// using the async read method
/// </summary>
private void readAsync()
{
// Step 1 --------------------------------------------------
// Prepare nodes to read
// Add the two variable NodeIds to the list of nodes to read
// NodeId is constructed from
// - the identifier text in the text box
// - the namespace index collected during the server connect
ReadValueIdCollection nodesToRead = new ReadValueIdCollection();
nodesToRead.Add(new ReadValueId()
{
NodeId = new NodeId(txtIdentifier1.Text, m_NameSpaceIndex),
AttributeId = Attributes.Value
});
nodesToRead.Add(new ReadValueId()
{
NodeId = new NodeId(txtIdentifier2.Text, m_NameSpaceIndex),
AttributeId = Attributes.Value
});
// use list of objects as user data - add the text fields
List<object> lstObjects = new List<object>();
lstObjects.Add(txtRead1);
lstObjects.Add(txtRead2);
// Step 2 --------------------------------------------------
// Read the values from the server
m_session.BeginRead(nodesToRead, 0, TimestampsToReturn.Both, null, OnReadComplete, lstObjects);
// Read results will be received through OnReadComplete
}
/// <summary>
/// Receive results from async read
/// </summary>
/// <param name="result"></param>
private void OnReadComplete(IAsyncResult result)
{
// Need to make sure this method is called on the UI thread because it updates UI controls.
if (this.InvokeRequired)
{
// Asynchronous execution of the AsyncCallback delegate.
this.BeginInvoke(new AsyncCallback(OnReadComplete), result);
return;
}
List<DataValue> results = null;
try
{
results = m_session.EndRead(result);
List<object> lstObjects = (List<object>)result.AsyncState;
if (lstObjects.Count == results.Count)
{
for (int i = 0; i < results.Count; i )
{
object obj = lstObjects[i];
if (obj.GetType() == typeof(TextBox))
{
// Get the according item
TextBox txtBox = (TextBox)obj;
if (StatusCode.IsGood(results[i].StatusCode))
{
// Reading the node succeeded - print the value as string
txtBox.Text = results[i].Value.ToString();
txtBox.BackColor = Color.White;
}
else
{
// Reading the node failed - print error code
txtBox.Text = results[i].StatusCode.ToString();
txtBox.BackColor = Color.Red;
}
}
else
{
// error
}
}
}
else
{
// error
}
}
catch (Exception exception)
{
ExceptionDlg.Show("OnReadComplete failed", exception);
}
}
#endregion
#region Async Write Variable Values with callback
/// <summary>
/// Write 2 values to the variables entered in the From.
/// The NodeId used for the Write is constructed from the identifier entered
/// in the Form and the namespace index detected in the connect method
/// using the async write method
/// </summary>
private void writeAsync()
{
// Step 1 --------------------------------------------------
// Get values to write and convert them to the right data type
if (m_TypeItem1 == BuiltInType.Null || m_TypeItem2 == BuiltInType.Null)
{
readDataTypes();
}
// Get values from GUI and convert them to the right data type
DataValue val1 = new DataValue();
val1.Value = TypeUtils.Cast(txtWrite1.Text, m_TypeItem1);
DataValue val2 = new DataValue();
val2.Value = TypeUtils.Cast(txtWrite2.Text, m_TypeItem2);
// Step 2 --------------------------------------------------
// Prepare nodes to write including the values to write
List<WriteValue> nodesToWrite = new List<WriteValue>();
nodesToWrite.Add(new WriteValue()
{
NodeId = new NodeId(txtIdentifier1.Text, m_NameSpaceIndex),
AttributeId = Attributes.Value,
Value = val1
});
nodesToWrite.Add(new WriteValue()
{
NodeId = new NodeId(txtIdentifier2.Text, m_NameSpaceIndex),
AttributeId = Attributes.Value,
Value = val2
});
// use list of objects as user data - add the text fields
List<object> lstObjects = new List<object>();
lstObjects.Add(txtRead2);
lstObjects.Add(txtRead1);
// Step 3 --------------------------------------------------
// Write values to server
m_session.BeginWrite(nodesToWrite, OnWriteComplete, lstObjects);
// Write results will be received through OnWriteComplete
}
/// <summary>
/// Receive results from async write
/// </summary>
/// <param name="result"></param>
private void OnWriteComplete(IAsyncResult result)
{
// Need to make sure this method is called on the UI thread because it updates UI controls.
if (this.InvokeRequired)
{
// Asynchronous execution of the AsyncCallback delegate.
this.BeginInvoke(new AsyncCallback(OnWriteComplete), result);
return;
}
List<StatusCode> results = null;
try
{
results = m_session.EndWrite(result);
List<object> lstObjects = (List<object>)result.AsyncState;
if (lstObjects.Count == results.Count)
{
for (int i = 0; i < results.Count; i )
{
object obj = lstObjects[i];
if (obj.GetType() == typeof(TextBox))
{
// Get the according item
TextBox txtBox = (TextBox)obj;
if (StatusCode.IsNotGood(results[i]))
{
// Writing the node failed - print error code
txtBox.Text = results[i].ToString();
txtBox.BackColor = Color.Red;
}
}
else
{
// error
}
}
}
else
{
// error
}
}
catch (Exception exception)
{
ExceptionDlg.Show("OnWriteComplete failed", exception);
}
}
#endregion
#region Read data types of variables from server
/// <summary>
/// Read the type informatin for both variables configured.
/// </summary>
private void readDataTypes()
{
// Add the two variable NodeIds to the list of nodes to read
// NodeId is constructed from
// - the identifier text in the text box
// - the namespace index collected during the server connect
ReadValueIdCollection nodesToRead = new ReadValueIdCollection();
nodesToRead.Add(new ReadValueId()
{
NodeId = new NodeId(txtIdentifier1.Text, m_NameSpaceIndex),
AttributeId = Attributes.DataType
});
nodesToRead.Add(new ReadValueId()
{
NodeId = new NodeId(txtIdentifier2.Text, m_NameSpaceIndex),
AttributeId = Attributes.DataType
});
// Read the datatypes
List<DataValue> results = null;
try
{
results = m_session.Read(nodesToRead, 0, TimestampsToReturn.Neither, null);
// check the result code
if (StatusCode.IsGood(results[0].StatusCode))
{
// The node succeeded - save buildInType for later use
m_TypeItem1 = TypeUtils.GetBuiltInType((NodeId)results[0].Value);
}
else
{
throw new Exception("Read datatype failed for item " txtIdentifier1.Text);
}
// check the result code
if (StatusCode.IsGood(results[1].StatusCode))
{
// The node succeeded - save buildInType for later use
m_TypeItem2 = TypeUtils.GetBuiltInType((NodeId)results[1].Value);
}
else
{
throw new Exception("Read datatype failed for item " txtIdentifier1.Text);
}
}
catch (Exception exception)
{
ExceptionDlg.Show("Read datatype failed", exception);
throw exception;
}
}
#endregion
#region Construction
public MainForm(ApplicationInstance applicationInstance)
{
m_application = applicationInstance;
InitializeComponent();
Application.ApplicationExit = Application_ApplicationExit;
}
#endregion
#region Application EventHandlers
private void Application_ApplicationExit(object sender, EventArgs e)
{
if (m_session != null && m_session.ConnectionStatus == ServerConnectionStatus.Connected)
{
m_session.Disconnect();
}
}
#endregion
#region Fields
private ApplicationInstance m_application = null;
private Session m_session = null;
private bool m_bConnected = false;
private Subscription m_subscription = null;
private UInt16 m_NameSpaceIndex = 0;
private BuiltInType m_TypeItem1;
private BuiltInType m_TypeItem2;
#endregion
#region User actions
/// <summary>
/// Handle event for connect button
/// </summary>
private void btnConnect_Click(object sender, EventArgs e)
{
if (m_bConnected)
{
try
{
disconnect();
}
catch (Exception exception)
{
ExceptionDlg.Show(null, exception);
}
}
else
{
try
{
connect();
}
catch (Exception exception)
{
ExceptionDlg.Show("Connect failed", exception);
}
}
}
/// <summary>
/// Handle event for Read button
/// </summary>
private void btnRead_Click(object sender, EventArgs e)
{
try
{
read();
}
catch (Exception exception)
{
ExceptionDlg.Show(null, exception);
}
}
/// <summary>
/// Handle event for ReadAsync button
/// </summary>
private void btnReadAsync_Click(object sender, EventArgs e)
{
try
{
readAsync();
}
catch (Exception exception)
{
ExceptionDlg.Show("Read failed", exception);
}
}
/// <summary>
/// Handle event for Write button
/// </summary>
private void btnWrite_Click(object sender, EventArgs e)
{
try
{
write();
}
catch (Exception exception)
{
ExceptionDlg.Show("Write failed", exception);
}
}
/// <summary>
/// Handle event for WriteAsync button
/// </summary>
private void btnWriteAsync_Click(object sender, EventArgs e)
{
try
{
writeAsync();
}
catch (Exception exception)
{
ExceptionDlg.Show("Write failed", exception);
}
}
/// <summary>
/// Starts the monitoring of the values of the two variables entered in the From.
/// The NodeIds used for the monitoring are constructed from the identifier entered
/// in the Form and the namespace index detected in the connect method
/// </summary>
private void btnMonitor_Click(object sender, EventArgs e)
{
if (m_subscription == null)
{
// create the subscription
try
{
startMonitoring();
btnMonitor.Text = "Stop";
}
catch (Exception exception)
{
ExceptionDlg.Show("Create subscription failed", exception);
m_subscription = null;
btnMonitor.Text = "Monitor";
}
}
else
{
try
{
stopMonitoring();
btnMonitor.Text = "Monitor";
txtMonitored1.Text = "";
txtMonitored2.Text = "";
}
catch (Exception exception)
{
ExceptionDlg.Show("Stopping monitoring failed", exception);
}
}
}
#endregion
}
}