我有一个 OPC-DA 服务器,SCADA 软件将变量及其值写入其中,因此我想使用 C# 同步读取它们。我已经编写了我的算法,但我无法读取变量。该代码创建一个订阅,或者可能创建一个在其中写入自己的变量和值的组实例,但我不希望这样。我只需要从 OPC 服务器读取值。
我已经在 OPC Server 之间建立了连接,但我没有到达将变量写入 OPC Server 的变量。
问题出在哪里,我无法意识到。你能提出一个解决方案吗?
我的代码:
class OpcFunctions
{
Opc.Da.Server Server = null;
OpcCom.Factory Factory = new OpcCom.Factory();
Opc.Da.Item[] Items;
Opc.Da.Subscription Group;
Opc.IRequest myReq;
Opc.Da.WriteCompleteEventHandler WriteEventHandler;
Opc.Da.ReadCompleteEventHandler ReadEventHandler;
public void GetOpcServers(TreeView OpcServerTreeList, ListBox OpcConnectionUrlListBox)
{
try
{
OpcCom.ServerEnumerator myServerEnumerator = new OpcCom.ServerEnumerator();
Opc.Server[] Servers = myServerEnumerator.GetAvailableServers(Opc.Specification.COM_DA_20);
ListServers(Servers,OpcServerTreeList,OpcConnectionUrlListBox);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ListServers(Opc.Server[] OpcServerList , TreeView OpcServerTreeList, ListBox OpcConnectionUrlListBox)
{
try
{
OpcServerTreeList.Nodes.Clear();
OpcConnectionUrlListBox.Items.Clear();
foreach(Opc.Server myServer in OpcServerList)
{
TreeNode myTreeNode = new TreeNode(myServer.Name);
myTreeNode.Nodes.Add(myServer.Url.HostName + ":" + myServer.Url.Path + ":" + myServer.Url.Port);
myTreeNode.Nodes.Add(myServer.Url.ToString());
myTreeNode.Nodes.Add(myServer.IsConnected.ToString());
OpcServerTreeList.Nodes.Add(myTreeNode);
OpcConnectionUrlListBox.Items.Add(myServer.Url.ToString());
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public bool ConnectOpcServer(string OpcUrl)
{
Opc.URL Url = new Opc.URL(OpcUrl);
Server = new Opc.Da.Server(Factory, null);
try
{
Server.Connect(Url, new Opc.ConnectData(new System.Net.NetworkCredential()));
Opc.Da.SubscriptionState GroupState = new Opc.Da.SubscriptionState();
GroupState.Name = "Group1";
GroupState.Active = true;
Group = (Opc.Da.Subscription)Server.CreateSubscription(GroupState);
Group.DataChanged += new Opc.Da.DataChangedEventHandler(GroupDataChanged);
Items = Group.AddItems(Items);
ReadEventHandler = new Opc.Da.ReadCompleteEventHandler(ReadCompleteCallback);
Group.Read(Group.Items, 123, ReadCompleteCallback, out myReq);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
return false;
}
return true;
}
void GroupDataChanged(object subscriptionHandle, object requestHandle, Opc.Da.ItemValueResult[] values)
{
uint order = 1;
foreach (Opc.Da.ItemValueResult chitem in values)
{
myWriteLogList(order, chitem.Timestamp, chitem.ItemName, chitem.Value.ToString(), chitem.Quality.ToString());
++order;
}
}
void myWriteLogList(uint order, DateTime timestamp, string name, string value, string signalquality)
{
SettingsUI.OpcExplorer.dataGridViewOpcExplorer.BeginInvoke((MethodInvoker)delegate
{
SettingsUI.OpcExplorer.dataGridViewOpcExplorer.Rows.Add(null,order,timestamp,name,value,signalquality);
});
}
void ReadCompleteCallback(object clientHandle, Opc.Da.ItemValueResult[] results)
{
uint order = 1;
foreach (Opc.Da.ItemValueResult readResult in results)
{
myWriteLogList(order, readResult.Timestamp, readResult.ItemName, readResult.Value.ToString(), readResult.Quality.ToString());
++order;
}
}
}