AHTC/RGD/RGD.OPCClient/CCommonOPCClient.cs
2025-05-19 09:22:33 +08:00

1080 lines
42 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Opc;
using Opc.Da;
using RGD.Common;
using RGD.DataService;
using System;
using System.Collections.Generic;
using System.Text;
namespace RGD.OPCClient
{
public static class CCommonOPCClient
{
//声明委托
public delegate void WimFrmNotify(int[] _RRword);
//定义一个委托变量
public static WimFrmNotify _notifyer;
//public static DBOperator dbo = new DBOperator();
private static RGD.Model.MDevice devinfo28;
private static int _connectCount = 0;
public static int ConnectCount
{
get { return CCommonOPCClient._connectCount; }
set
{
if (value == 0)
{
_opcError = "";
}
CCommonOPCClient._connectCount = value;
}
}
private static int[] _plcStates;
public static int[] PlcStates
{
get { return CCommonOPCClient._plcStates; }
//set { CCommonOPCClient._plcStates = value; }
}
//对于错误报警、状态信息应该在此建立通用组,并且注册事件,通过值变化检测所有组内的报警信息
public static void OnDataChange(object subscriptionHandle, object requestHandle, ItemValueResult[] values)
{
try
{
foreach (ItemValueResult item in values)
{//处理每一个ItemValueResult
if (item.ClientHandle == null)
{//服务器发过来的无用信息。
continue;
}
//
Array.Copy((Array)item.Value, _plcStates, _plcStates.GetLength(0));
StringBuilder sb = new StringBuilder();
foreach (int i in _plcStates)
{
sb.Append(i + ",");
}
LogUtil.WriteLog("", "OnDataChange回调:" + sb.ToString());
}
//kanbl 回调通知
if (_notifyer != null)
{
if (values.Length <= 0 || values[0].Quality == Quality.Bad)
{
//kanbl
System.Diagnostics.Trace.WriteLine(String.Format("OnDataChange values.Length <= 0 || values[0].Quality == Quality.Bad"));
return;
}
byte[] itemnamevalue = new byte[(int)devinfo28.Dbw2Getlength];
Array.Copy((Array)values[0].Value, itemnamevalue, (int)devinfo28.Dbw2Getlength);
int[] _RRword = new int[(int)devinfo28.Dbw2Getlength];
Array.Copy(itemnamevalue, _RRword, (int)devinfo28.Dbw2Getlength);
//调用
_notifyer(_RRword);
}
}
catch (Exception ex)
{
_opcError = "获取OPC服务器时" + ex.Message;
}
}
//WriteComplete回调
public static void OnWriteComplete(object requestHandle, Opc.IdentifiedResult[] values)
{
/*Console.WriteLine("发生异步写name:{0},value:{1}", values[0].ItemName, values[0].GetType());
if ((int)requestHandle == 2)
Console.WriteLine("事件信号句柄为{0}", requestHandle);*/
}
private static string _PLCconnectionID = "S7:[S7 connection_1]";
/// <summary>
/// 建立PLC连接的ID例如"S7:[S7 connection_1]"
/// 或者"S7:[@LOCALSERVER]"
/// </summary>
public static string PlcConnectionID
{
get { return CCommonOPCClient._PLCconnectionID; }
set { CCommonOPCClient._PLCconnectionID = value; }
}
private static string _opcError;
private static bool _IfConnectOPCServer = false;
private static string _hostname;
/// <summary>
/// OPC Server的机器名称或者IP地址
/// </summary>
public static string Hostname
{
get { return CCommonOPCClient._hostname; }
set { CCommonOPCClient._hostname = value; }
}
private static string _progID;
/// <summary>
/// OPC Server的程序标识例如OPC.SimaticNET
/// </summary>
public static string ProgID
{
get { return CCommonOPCClient._progID; }
set { CCommonOPCClient._progID = value; }
}
public static string OpcError
{
get { return CCommonOPCClient._opcError; }
set { CCommonOPCClient._opcError = value; }
}
private static Opc.Da.Server m_server = null;//定义数据存取服务器
private static Opc.Server[] servers;
private static Opc.Da.Subscription subscription = null;//定义组对象(订阅者)
private static Opc.Da.SubscriptionState state = null;//定义组订阅者状态相当于OPC规范中组的参数
private static Opc.Da.Subscription _readSubscription = null;//定义组对象(订阅者)
private static Opc.Da.SubscriptionState _readstate = null;//定义组订阅者状态相当于OPC规范中组的参数
private static Opc.Da.Subscription _writeSubscription = null;//定义组对象(订阅者)
private static Opc.Da.SubscriptionState _writestate = null;//定义组订阅者状态相当于OPC规范中组的参数
private static Opc.Da.Subscription _tempSubscription = null;//定义组对象(订阅者)
private static Opc.Da.SubscriptionState _tempstate = null;//定义组订阅者状态相当于OPC规范中组的参数
// static private Opc.IDiscovery m_discovery = new OpcCom.ServerEnumerator();//定义枚举基于COM服务器的接口用来搜索所有的此类服务器。
private static Opc.IDiscovery m_discovery = new OpcCom.ServerEnumerator();//定义枚举基于COM服务器的接口用来搜索所有的此类服务器。
/// <summary>
/// 获取主机的所有OPC服务器的标识名称数组
/// </summary>
/// <param name="hostname">主机名称</param>
/// <returns></returns>
public static List<string> GetOpcServers(string hostname)
{
try
{
servers = m_discovery.GetAvailableServers(Specification.COM_DA_20, hostname, null);
//daver表示数据存取规范版本Specification.COMDA_20等于2.0版本。
//host为计算机名null表示不需要任何网络安全认证。
if (servers != null)
{
List<string> ser = new List<string>(); ;
foreach (Opc.Da.Server server in servers)
{
ser.Add(server.Name);
}
return ser;
}
return null;
}
catch (Exception ex)
{
_opcError = "获取OPC服务器时" + ex.Message;
return null;
}
}
/// <summary>
/// 连接指定主机的OPC服务器
/// </summary>
/// <param name="hostname">主机名称</param>
/// <param name="ProgID">OPC服务器程序标识例如"OPC.SimaticNET"</param>
/// <returns></returns>
public static bool ConnectOPCServer(string hostname, string ProgID)
{
try
{
GetOpcServers(hostname);
//if (ProgID.Contains(hostname) == false)
//{
// ProgID = hostname + "." + ProgID;
//}
foreach (Opc.Da.Server server in servers)
{
//server即为需要连接的OPC数据存取服务器。
if (String.Compare(server.Name, ProgID, true) == 0)//为true忽略大小写
{
m_server = server;//建立连接。
break;
}
}
//连接服务器
if (m_server != null)//非空连接服务器
{
m_server.Connect();
_IfConnectOPCServer = true;
CreateItemGroup();
return true;
}
else
{
_IfConnectOPCServer = false;
return false;
}
}
catch (Exception ex)
{
_opcError = "连接OPC数据存取服务器时" + ex.Message;
_IfConnectOPCServer = false;
return false;
}
}
/// <summary>
/// 创建OPC组订阅者定义组内变量名称
/// </summary>
/// <param name="groupname">OPC组订阅者名称</param>
/// <param name="itemnames">指定组内所有变量名称,数组的值举例"S7:[S7 connection_1]DB1,INT1"</param>
/// <returns></returns>
public static Opc.Da.Subscription CreateItemGroup(string groupname, string[] itemnames)
{
string[] itemName;
//定义item列表
Item[] items;
ItemResult[] irs;
try
{
if (_IfConnectOPCServer == false)
{
if (ConnectOPCServer(_hostname, _progID) == false) return null;
}
//设定组状态
state = new Opc.Da.SubscriptionState();//组订阅者状态相当于OPC规范中组的参数
state.Name = groupname;//组名
state.ServerHandle = null;//服务器给该组分配的句柄。
state.ClientHandle = Guid.NewGuid().ToString();//客户端给该组分配的句柄。
state.Active = true;//激活该组。
state.UpdateRate = 100;//刷新频率为100毫秒。
state.Deadband = 0;// 死区值设为0时服务器端该组内任何数据变化都通知组。
state.Locale = null;//不设置地区值。
//添加组
subscription = (Opc.Da.Subscription)m_server.CreateSubscription(state);//创建组
//定义Item列表
//对应类型为:{Byte,Byte,Char,Short,String,Word,Boolean}
itemName = itemnames;//{ "S7:[S7 connection_1]DB1,INT1", "S7:[@LOCALSERVER]DB1,INT20", "S7:[@LOCALSERVER]DB1,INT30", "S7:[@LOCALSERVER]DB1,INT50" };
//定义item列表
items = new Item[itemName.Length];//定义数据项即item
int i;
for (i = 0; i < items.Length; i++)//item初始化赋值
{
items[i] = new Item();//创建一个项Item对象。
items[i].ClientHandle = Guid.NewGuid().ToString();//客户端给该数据项分配的句柄。
items[i].ItemPath = null; //该数据项在服务器中的路径。
items[i].ItemName = itemName[i]; //该数据项在服务器中的名字。
}
//添加Item
irs = subscription.AddItems(items);
return subscription;
}
catch (Exception ex)
{
//if ((m_server == null) || (m_server.IsConnected == false))
//{
_IfConnectOPCServer = false;
//}
_opcError = "创建OPC组时" + ex.Message;
return null;
}
finally
{
itemName = null;
//定义item列表
items = null;
irs = null;
}
}
/// <summary>
/// 创建OPC组订阅者不定义组内变量名称
/// </summary>
/// <param name="groupname">OPC组订阅者名称</param>
/// <returns></returns>
public static Opc.Da.Subscription CreateItemGroup(string groupname)
{
try
{
if (_IfConnectOPCServer == false)
{
if (ConnectOPCServer(_hostname, _progID) == false) return null;
}
//设定组状态
state = new Opc.Da.SubscriptionState();//组订阅者状态相当于OPC规范中组的参数
state.Name = groupname;//组名
state.ServerHandle = null;//服务器给该组分配的句柄。
state.ClientHandle = Guid.NewGuid().ToString();//客户端给该组分配的句柄。
state.Active = true;//激活该组。
state.UpdateRate = 100;//刷新频率为100毫秒。
state.Deadband = 0;// 死区值设为0时服务器端该组内任何数据变化都通知组。
state.Locale = null;//不设置地区值。
//添加组
subscription = (Opc.Da.Subscription)m_server.CreateSubscription(state);//创建组
return subscription;
}
catch (Exception ex)
{
//if ((m_server == null) || (m_server.IsConnected == false))
//{
_IfConnectOPCServer = false;
//}
_opcError = "创建OPC组时" + ex.Message;
return null;
}
}
/// <summary>
/// 创建几个默认组read和write、临时读写组tempGroup
/// </summary>
/// <returns></returns>
public static void CreateItemGroup()
{
try
{
//if (_IfConnectOPCServer == false)
//{
// if (ConnectOPCServer(_hostname, _progID) == false) return ;
//}
#region
devinfo28 = BaseDeviceService.GetDeviceInfo(65534);
//设定读取组状态
_readstate = new Opc.Da.SubscriptionState();//组订阅者状态相当于OPC规范中组的参数
_readstate.Name = "readopc";//组名
_readstate.ServerHandle = null;//服务器给该组分配的句柄。
_readstate.ClientHandle = Guid.NewGuid().ToString();//客户端给该组分配的句柄。
_readstate.Active = true;//激活该组。
_readstate.UpdateRate = 5000;//刷新频率为100毫秒。
_readstate.Deadband = 0;// 死区值设为0时服务器端该组内任何数据变化都通知组。
_readstate.Locale = null;//不设置地区值。
//添加读组
_readSubscription = (Opc.Da.Subscription)m_server.CreateSubscription(_readstate);//创建读取组
//20100221
string[] itemName = new string[1] { _PLCconnectionID + "DB2,byte" + devinfo28.Dbw2Address.ToString() + "," + ((int)devinfo28.Dbw2Getlength).ToString() + "" };//{ "S7:[S7 connection_1]DB1,INT1", "S7:[@LOCALSERVER]DB1,INT20", "S7:[@LOCALSERVER]DB1,INT30", "S7:[@LOCALSERVER]DB1,INT50" };
//定义读item列表
Item[] items = new Item[itemName.Length];//定义数据项即item
int i;
for (i = 0; i < items.Length; i++)//item初始化赋值v
{
items[i] = new Item();//创建一个项Item对象。
items[i].ClientHandle = Guid.NewGuid().ToString();//客户端给该数据项分配的句柄。
items[i].ItemPath = null; //该数据项在服务器中的路径。
items[i].ItemName = itemName[i]; //该数据项在服务器中的名字。
}
//添加读Item
ItemResult[] irs = _readSubscription.AddItems(items);
_plcStates = new int[System.Convert.ToInt32(devinfo28.Dbw2Getlength)];
_readSubscription.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange);
#endregion
//设定写组状态
_writestate = new Opc.Da.SubscriptionState();//组订阅者状态相当于OPC规范中组的参数
_writestate.Name = "writeopc";//组名
_writestate.ServerHandle = null;//服务器给该组分配的句柄。
_writestate.ClientHandle = Guid.NewGuid().ToString();//客户端给该组分配的句柄。
_writestate.Active = true;//激活该组。
_writestate.UpdateRate = 100;//刷新频率为100毫秒。
_writestate.Deadband = 0;// 死区值设为0时服务器端该组内任何数据变化都通知组。
_writestate.Locale = null;//不设置地区值。
//添加写入组
_writeSubscription = (Opc.Da.Subscription)m_server.CreateSubscription(_writestate);//创建写入组
//设定临时读组状态
_tempstate = new Opc.Da.SubscriptionState();//组订阅者状态相当于OPC规范中组的参数
_tempstate.Name = "opctemp";//组名
_tempstate.ServerHandle = null;//服务器给该组分配的句柄。
_tempstate.ClientHandle = Guid.NewGuid().ToString();//客户端给该组分配的句柄。
_tempstate.Active = true;//激活该组。
_tempstate.UpdateRate = 100;//刷新频率为100毫秒。
_tempstate.Deadband = 0;// 死区值设为0时服务器端该组内任何数据变化都通知组。
_tempstate.Locale = null;//不设置地区值。
//添加写入组
_tempSubscription = (Opc.Da.Subscription)m_server.CreateSubscription(_tempstate);//创建写入组
}
catch (Exception ex)
{
//if ((m_server == null) || (m_server.IsConnected == false))
//{
_IfConnectOPCServer = false;
//}
_opcError = "创建OPC组时" + ex.Message;
return;
}
}
/// <summary>
/// 创建OPC组订阅者定义组内变量名称
/// </summary>
/// <param name="plcConnectionID">组态软件中定义的每个PLC连接的标识</param>
/// <param name="groupname">OPC组订阅者名称</param>
/// <param name="itemnames">指定组内所有变量名称,数组的值举例"DB1,INT1"</param>
/// <returns></returns>
public static Opc.Da.Subscription CreateItemGroup(string plcConnectionID, string groupname, string[] itemnames)
{
string[] itemName;
//定义item列表
Item[] items;
ItemResult[] irs;
try
{
if (_IfConnectOPCServer == false)
{
if (ConnectOPCServer(_hostname, _progID) == false) return null;
}
//设定组状态
state = new Opc.Da.SubscriptionState();//组订阅者状态相当于OPC规范中组的参数
state.Name = groupname;//组名
state.ServerHandle = null;//服务器给该组分配的句柄。
state.ClientHandle = Guid.NewGuid().ToString();//客户端给该组分配的句柄。
state.Active = true;//激活该组。
state.UpdateRate = 100;//刷新频率为100毫秒。
state.Deadband = 0;// 死区值设为0时服务器端该组内任何数据变化都通知组。
state.Locale = null;//不设置地区值。
//添加组
subscription = (Opc.Da.Subscription)m_server.CreateSubscription(state);//创建组
//定义Item列表
//对应类型为:{Byte,Byte,Char,Short,String,Word,Boolean}
itemName = itemnames;//{ "S7:[S7 connection_1]DB1,INT1", "S7:[@LOCALSERVER]DB1,INT20", "S7:[@LOCALSERVER]DB1,INT30", "S7:[@LOCALSERVER]DB1,INT50" };
//定义item列表
items = new Item[itemName.Length];//定义数据项即item
int i;
for (i = 0; i < items.Length; i++)//item初始化赋值
{
items[i] = new Item();//创建一个项Item对象。
items[i].ClientHandle = Guid.NewGuid().ToString();//客户端给该数据项分配的句柄。
items[i].ItemPath = null; //该数据项在服务器中的路径。
items[i].ItemName = plcConnectionID + itemName[i]; //该数据项在服务器中的名字。
}
//添加Item
irs = subscription.AddItems(items);
return subscription;
}
catch (Exception ex)
{
//if ((m_server == null) || (m_server.IsConnected == false))
//{
_IfConnectOPCServer = false;
//}
_opcError = "创建OPC组时" + ex.Message;
return null;
}
finally
{
itemName = null;
//定义item列表
items = null;
irs = null;
}
}
/// <summary>
/// 同步读取全部OPC组内变量的值List《变量名+ ":" +变量值》
/// </summary>
/// <param name="subscription">OPC组名称</param>
/// <returns></returns>
public static List<string> SyncReadAllItems(Opc.Da.Subscription subscription)
{
ItemValueResult[] values;
List<string> itemnamevalue;
try
{
if (_IfConnectOPCServer == false)
{
if (ConnectOPCServer(_hostname, _progID) == false) return null;
}
itemnamevalue = new List<string>();
//注册回调事件
//subscription.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange);
//以下测试同步读
//以下读整个组
values = subscription.Read(subscription.Items);
foreach (ItemValueResult value in values)
{
itemnamevalue.Add(value.ItemName + ":" + value.Value);
}
//subscription.RemoveItems(subscription.Items);
//subscription.Dispose();
return itemnamevalue;
}
catch (Exception ex)
{
//if ((m_server == null) || (m_server.IsConnected == false))
//{
_IfConnectOPCServer = false;
//}
_opcError = "同步读数据时:" + ex.Message;
return null;
}
finally
{
values = null;
itemnamevalue = null;
}
}
/// <summary>
/// 读取指定标签数组的数据,返回值:“标签值”组成的数组
/// </summary>
/// <param name="itemnames">标签数组</param>
/// <returns></returns>
public static List<string> SyncReadAllItems(string[] itemnames)
{
Subscription subs;
List<string> itemnamevalue;
ItemValueResult[] values;
try
{
if (_IfConnectOPCServer == false)
{
if (ConnectOPCServer(_hostname, _progID) == false) return null;
}
subs = CreateItemGroup(_PLCconnectionID, Guid.NewGuid().ToString(), itemnames);
itemnamevalue = new List<string>();
values = subs.Read(subs.Items);
foreach (ItemValueResult value in values)
{
itemnamevalue.Add(System.Convert.ToString(value.Value));
}
subs.Dispose();
return itemnamevalue;
}
catch (Exception ex)
{
//if ((m_server == null) || (m_server.IsConnected == false))
//{
_IfConnectOPCServer = false;
//}
_opcError = "同步读数据时:" + ex.Message;
return null;
}
finally
{
itemnamevalue = null;
values = null;
}
}
/// <summary>
/// 读取指定标签名称的数据
/// </summary>
/// <param name="itemname">标签名称</param>
/// <returns></returns>
public static string SyncReadItemValue(string itemname)
{
string[] items = new string[1] { itemname };
Subscription subs = CreateItemGroup(_PLCconnectionID, Guid.NewGuid().ToString(), items);
string itemnamevalue = "";
ItemValueResult[] values = subs.Read(subs.Items);
try
{
if (_IfConnectOPCServer == false)
{
if (ConnectOPCServer(_hostname, _progID) == false) return null;
}
if (values.Length > 0)
{
if (values[0].Value != null)
{
itemnamevalue = values[0].Value.ToString();
}
}
subs.RemoveItems(subs.Items);
subs.Dispose();
return itemnamevalue;
}
catch (Exception ex)
{
//if ((m_server == null) || (m_server.IsConnected == false))
//{
_IfConnectOPCServer = false;
//}
_opcError = "同步读数据时:" + ex.Message;
return null;
}
finally
{
items = null;
subs = null;
itemnamevalue = null;
values = null;
}
}
//20100221
#region OPC
/// <summary>
/// 读取整个_readSubscription组的内容
/// </summary>
/// <returns></returns>
public static byte[] SyncReadAllItems()
{
ItemValueResult[] values;
byte[] itemnamevalue;
try
{
if (_IfConnectOPCServer == false)
{
if (ConnectOPCServer(_hostname, _progID) == false) return null;
}
//List<string> itemnamevalue = new List<string>();
//注册回调事件
//subscription.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange);
//以下测试同步读
//以下读整个组
if (ConnectCount > 3)
{
_opcError = "同步数据时OPC Server没连接到PLC并且超过重复连接次数!请先关闭命令开关,检查通讯线路,确认后重新打开命令开关!";
return null;
}
values = _readSubscription.Read(_readSubscription.Items);
if (values.Length <= 0)
{
_opcError = "同步读数据时OPC Server没连接到PLC!";
return null;
}
if (values[0].Quality == Quality.Bad)
{
ConnectCount++;
_opcError = "同步读数据时OPC Server没连接到PLC!";
return null;
}
itemnamevalue = new byte[(int)devinfo28.Dbw2Getlength];
Array.Copy((Array)values[0].Value, itemnamevalue, (int)devinfo28.Dbw2Getlength);
//subscription.RemoveItems(subscription.Items);
//subscription.Dispose();
return itemnamevalue;
}
catch (Exception ex)
{
//if ((m_server == null) || (m_server.IsConnected == false))
//{
_IfConnectOPCServer = false;
//}
_opcError = "同步读数据时:" + ex.Message;
return null;
}
finally
{
itemnamevalue = null;
values = null;
}
}
/// <summary>
/// 延吉向指定OPC标签组写入数据_writeSubscription组多对多写入
/// </summary>
/// <param name="itemnames"></param>
/// <param name="itemvalue"></param>
/// <returns></returns>
public static bool SyncWriteAllItemValue(string[] itemnames, string[] itemvalue)
{
Item[] items;
ItemValue[] itemvalues;
IdentifiedResult[] ir;
try
{
if (_IfConnectOPCServer == false)
{
if (ConnectOPCServer(_hostname, _progID) == false) return false;
}
if (ConnectCount > 1)
{
_opcError = "同步数据时OPC Server没连接到PLC并且超过重复连接次数!请先关闭命令开关,检查通讯线路,确认后重新打开命令开关!";
return false;
}
//定义item列表
items = new Item[itemnames.Length];//定义数据项即item
int i;
for (i = 0; i < items.Length; i++)//item初始化赋值
{
items[i] = new Item();//创建一个项Item对象。
items[i].ClientHandle = Guid.NewGuid().ToString();//客户端给该数据项分配的句柄。
items[i].ItemPath = null; //该数据项在服务器中的路径。
items[i].ItemName = _PLCconnectionID + itemnames[i]; //该数据项在服务器中的名字。
}
_writeSubscription.AddItems(items);
if (_writeSubscription.Items.Length==8)
{
}
itemvalues = new ItemValue[_writeSubscription.Items.Length];
for (int ii = 0; ii < _writeSubscription.Items.Length; ii++)
{
itemvalues[ii] = new ItemValue((ItemIdentifier)_writeSubscription.Items[ii]);
itemvalues[ii].Value = itemvalue[ii];
}
ir = _writeSubscription.Write(itemvalues);
_writeSubscription.RemoveItems(_writeSubscription.Items);
//_writeSubscription.Dispose();
//GC.Collect();
return true;
}
catch (Exception ex)
{
//if ((m_server == null) || (m_server.IsConnected == false))
//{
_IfConnectOPCServer = false;
//}
_opcError = "同步写数据时:" + ex.Message;
return false;
}
finally
{
items = null;
itemvalues = null;
ir = null;
}
}
/// <summary>
/// 单个标签按字节写入多个byte数据20110515 一对多写入
/// </summary>
/// <param name="itemnames">单个标签的名称,注意:只包含一个元素的数组</param>
/// <param name="itemvalue">要写入的byte数组</param>
/// <returns></returns>
public static bool SyncWriteAllItemValue(string[] itemnames, byte[] itemvalue)
{
try
{
if (_IfConnectOPCServer == false)
{
if (ConnectOPCServer(_hostname, _progID) == false) return false;
}
//定义item列表
Item[] items = new Item[itemnames.Length];//定义数据项即item
int i;
for (i = 0; i < items.Length; i++)//item初始化赋值
{
items[0] = new Item();//创建一个项Item对象。
items[0].ClientHandle = Guid.NewGuid().ToString();//客户端给该数据项分配的句柄。
items[0].ItemPath = null; //该数据项在服务器中的路径。
items[0].ItemName = _PLCconnectionID + itemnames[0]; //该数据项在服务器中的名字。
}
_writeSubscription.AddItems(items);
ItemValue[] itemvalues = new ItemValue[itemnames.Length];
for (int ii = 0; ii < itemnames.Length; ii++)//ii恒等于0
{
itemvalues[ii] = new ItemValue((ItemIdentifier)_writeSubscription.Items[ii]);
itemvalues[ii].Value = itemvalue;//传入object类型20110515
}
IdentifiedResult[] ir = _writeSubscription.Write(itemvalues);
_writeSubscription.RemoveItems(_writeSubscription.Items);
//_writeSubscription.Dispose();
GC.Collect();
return true;
}
catch (Exception ex)
{
//if ((m_server == null) || (m_server.IsConnected == false))
//{
_IfConnectOPCServer = false;
//}
_opcError = "同步写数据时:" + ex.Message;
return false;
}
}
public static bool SyncWriteAllItemValue(StringBuilder[] itemnames, StringBuilder[] itemvalue)
{
Item[] items;
ItemValue[] itemvalues;
IdentifiedResult[] ir;
try
{
if (_IfConnectOPCServer == false)
{
if (ConnectOPCServer(_hostname, _progID) == false) return false;
}
if (ConnectCount > 1)
{
_opcError = "同步数据时OPC Server没连接到PLC并且超过重复连接次数!请先关闭命令开关,检查通讯线路,确认后重新打开命令开关!";
return false;
}
//定义item列表
items = new Item[itemnames.Length];//定义数据项即item
int i;
for (i = 0; i < items.Length; i++)//item初始化赋值
{
items[i] = new Item();//创建一个项Item对象。
items[i].ClientHandle = Guid.NewGuid().ToString();//客户端给该数据项分配的句柄。
items[i].ItemPath = null; //该数据项在服务器中的路径。
items[i].ItemName = itemnames[i].ToString(); //该数据项在服务器中的名字。
}
_writeSubscription.AddItems(items);
itemvalues = new ItemValue[_writeSubscription.Items.Length];
for (int ii = 0; ii < _writeSubscription.Items.Length; ii++)
{
itemvalues[ii] = new ItemValue((ItemIdentifier)_writeSubscription.Items[ii]);
itemvalues[ii].Value = itemvalue[ii];
}
ir = _writeSubscription.Write(itemvalues);
_writeSubscription.RemoveItems(_writeSubscription.Items);
//_writeSubscription.Dispose();
//GC.Collect();
return true;
}
catch (Exception ex)
{
//if ((m_server == null) || (m_server.IsConnected == false))
//{
_IfConnectOPCServer = false;
//}
_opcError = "同步写数据时:" + ex.Message;
return false;
}
finally
{
items = null;
itemvalues = null;
ir = null;
}
}
/// <summary>
/// 延吉读取指定OPC标签组数据_tempSubscription组
/// </summary>
/// <param name="itemnames"></param>
/// <returns></returns>
public static object[] SyncReadItemValues(string[] itemnames)
{
Item[] items;
ItemResult[] irs;
ItemValueResult[] values;
object[] itemnamevalue;
try
{
//string ss; string ss1;
//ss = DateTime.Now.Second.ToString() + "-" + DateTime.Now.Millisecond.ToString();
if (_IfConnectOPCServer == false)
{
if (ConnectOPCServer(_hostname, _progID) == false) return null;
}
//定义item列表
items = new Item[itemnames.Length];//定义数据项即item
int i;
for (i = 0; i < items.Length; i++)//item初始化赋值
{
items[i] = new Item();//创建一个项Item对象。
items[i].ClientHandle = Guid.NewGuid().ToString();//客户端给该数据项分配的句柄。
items[i].ItemPath = null; //该数据项在服务器中的路径。
items[i].ItemName = _PLCconnectionID + itemnames[i]; //该数据项在服务器中的名字。
}
irs = _tempSubscription.AddItems(items);
values = _tempSubscription.Read(_tempSubscription.Items);
if (values[0].Quality == Quality.Bad)
{
_opcError = "同步读数据时OPC Server没连接到PLC!";
return null;
}
itemnamevalue = new object[values.Length];
int k = 0;
foreach (ItemValueResult value in values)
{
itemnamevalue[k] = value.Value;
k++;
}
//Array.Copy(values.[0].Value, itemnamevalue, values.Length);
_tempSubscription.RemoveItems(_tempSubscription.Items);
//_tempSubscription.Dispose();
//GC.Collect();
//ss1 = DateTime.Now.Second.ToString() + "-" + DateTime.Now.Millisecond.ToString();
return itemnamevalue;
}
catch (Exception ex)
{
//if ((m_server == null) || (m_server.IsConnected == false))
//{
_IfConnectOPCServer = false;
//}
_opcError = "同步读数据时:" + ex.Message;
return null;
}
finally
{
items = null;
irs = null;
values = null;
itemnamevalue = null;
}
}
#endregion OPC
//20100221
//#region 延吉同步写、异步读OPC
//static byte[] AsyncReadAllItemNameValue= new byte[(int)devinfo28.Dbw2Getlength];
//static bool AsyncReadOK=false ;
///// <summary>
///// 延吉异步读取整个_readSubscription组的内容
///// </summary>
///// <returns></returns>
//public static void AsyncReadAllItems()
//{
// try
// {
// if (_IfConnectOPCServer == false)
// {
// if (ConnectOPCServer(_hostname, _progID) == false) return ;
// }
// IRequest quest=null ;
// _readSubscription.Read(_readSubscription.Items, Guid.NewGuid().ToString(), OnReadComplete,out quest);
// }
// catch (Exception ex)
// {
// //if ((m_server == null) || (m_server.IsConnected == false))
// //{
// _IfConnectOPCServer = false;
// //}
// _opcError = "异步读数据时:" + ex.Message;
// AsyncReadOK = false;
// return ;
// }
// finally
// {
// }
//}
///// <summary>
///// 延吉向指定OPC标签组同步写入数据_writeSubscription组
///// </summary>
///// <param name="itemnames"></param>
///// <param name="itemvalue"></param>
///// <returns></returns>
//public static bool SyncWriteGroupItemValue(string[] itemnames, string[] itemvalue)
//{
// Item[] items;
// ItemValue[] itemvalues;
// IdentifiedResult[] ir;
// try
// {
// if (AsyncReadOK == false) return false;
// if (_IfConnectOPCServer == false)
// {
// if (ConnectOPCServer(_hostname, _progID) == false) return false;
// }
// //定义item列表
// items = new Item[itemnames.Length];//定义数据项即item
// int i;
// for (i = 0; i < items.Length; i++)//item初始化赋值
// {
// items[i] = new Item();//创建一个项Item对象。
// items[i].ClientHandle = Guid.NewGuid().ToString();//客户端给该数据项分配的句柄。
// items[i].ItemPath = null; //该数据项在服务器中的路径。
// items[i].ItemName = _PLCconnectionID + itemnames[i]; //该数据项在服务器中的名字。
// }
// _writeSubscription.AddItems(items);
// itemvalues = new ItemValue[_writeSubscription.Items.Length];
// for (int ii = 0; ii < _writeSubscription.Items.Length; ii++)
// {
// itemvalues[ii] = new ItemValue((ItemIdentifier)_writeSubscription.Items[ii]);
// itemvalues[ii].Value = itemvalue[ii];
// }
// ir = _writeSubscription.Write(itemvalues);
// _writeSubscription.RemoveItems(_writeSubscription.Items);
// //_writeSubscription.Dispose();
// GC.Collect();
// return true;
// }
// catch (Exception ex)
// {
// //if ((m_server == null) || (m_server.IsConnected == false))
// //{
// _IfConnectOPCServer = false;
// //}
// _opcError = "同步写数据时:" + ex.Message;
// return false;
// }
// finally
// {
// items = null;
// itemvalues = null;
// ir = null;
// }
//}
////ReadComplete回调
//public static void OnReadComplete(object requestHandle, Opc.Da.ItemValueResult[] values)
//{
// /*Console.WriteLine("发生异步读name:{0},value:{1}", values[0].ItemName, values[0].Value);
// if ((int)requestHandle == 1)
// Console.WriteLine("事件信号句柄为{0}", requestHandle);*/
// //不区分请求句柄了直接接收OPC数据
// try
// {
// if (values.Length <= 0)
// {
// _opcError = "异步读数据时OPC Server没连接到PLC!";
// AsyncReadOK = false;
// return ;
// }
// if (values[0].Quality == Quality.Bad)
// {
// _opcError = "异步读数据时OPC Server没连接到PLC!";
// AsyncReadOK = false;
// return ;
// }
// Array.Copy((Array)values[0].Value, AsyncReadAllItemNameValue, AsyncReadAllItemNameValue.GetLength(0));// (int)devinfo28.Dbw2Getlength
// AsyncReadOK = true;
// }
// catch (Exception ex)
// {
// _opcError = "异步读数据时:"+ex.Message ;
// AsyncReadOK = false;
// return;
// }
// finally
// {
// values = null;
// }
//}
//#endregion
/// <summary>
/// 同步向OPC组名称内每个变量写入值
/// </summary>
/// <param name="subscription">OPC组名称</param>
/// <param name="itemvalue">每个变量的值</param>
/// <returns></returns>
}
}