using System;
using System.Collections.Generic;
using System.Text;
using Opc;
using Opc.Da;
using OpcCom;
using System.Threading;
using System.Data;
using DBFactory;
namespace OPCClient
{
public static class CCommonOPCClient
{
public static DBOperator dbo = new DBOperator();
//20110216
private static int _connectCount = 0;
public static int ConnectCount
{
get { return CCommonOPCClient._connectCount; }
set {
if (value == 0)
{
_opcError = "";
}
CCommonOPCClient._connectCount = value;
}
}
// 20120427南昌,S7连接标志 1- B
static StringBuilder sbc = new StringBuilder();
public static int[] ErrorCount = new int[2] {0,0 };
private static int[] _plcStates=null ;
public static int[] PlcStates
{
get { return CCommonOPCClient._plcStates; }
//set { CCommonOPCClient._plcStates = value; }
}
///
/// 20110309订阅的组内标签数据变化事件
///
/// 客户端句柄
/// 请求句柄
/// 标签值数组
public static void OnDataChange(object subscriptionHandle, object requestHandle, ItemValueResult[] values)
{
//根据subscriptionHandle对应设备索引,依据设备种类(不同类型设备通讯数据帧不同)
//分别处理:完成,报警,光电开关,PLC发起的请求
try
{
//devinfo = Model.CGetInfo.GetDeviceInfo(System.Convert.ToInt32(subscriptionHandle));
//foreach (ItemValueResult item in values)
//{//处理每一个ItemValueResult
// if (item.ClientHandle == null)
// {//服务器发过来的无用信息。
// continue;
// }
// //按设备类型拆分通讯协议
// switch(devinfo.DeviceKind)
// {
// #region 堆垛机
// case 1:
// break;
// #endregion
// #region 类输送机
// case 2:
// break;
// #endregion
// #region 穿梭车RGV
// case 4:
// break;
// #endregion
// #region 条形码字符串信息
// case 7:
// break;
// #endregion
// #region 现场触摸屏
// case 22:
// break;
// #endregion
// #region 一号工程码字符串信息
// case 21:
// break;
// #endregion
// #region 机器人码垛信息
// case 24:
// break;
// #endregion
// }
//}
}
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);*/
}
static private string _PLCconnectionID = "S7:[S7 connection_1]";
///
/// 建立PLC连接的ID,例如:"S7:[S7 connection_1]"
/// 或者"S7:[@LOCALSERVER]"
///
public static string PlcConnectionID
{
get { return CCommonOPCClient._PLCconnectionID; }
set { CCommonOPCClient._PLCconnectionID = value; }
}
static private string _opcError;
static private bool _IfConnectOPCServer=false ;
static private string _hostname;
///
/// OPC Server的机器名称或者IP地址
///
public static string Hostname
{
get { return CCommonOPCClient._hostname; }
set { CCommonOPCClient._hostname = value; }
}
static private string _progID;
///
/// OPC Server的程序标识,例如:OPC.SimaticNET
///
public static string ProgID
{
get { return CCommonOPCClient._progID; }
set { CCommonOPCClient._progID = value; }
}
public static string OpcError
{
get { return CCommonOPCClient._opcError; }
set { CCommonOPCClient._opcError = value; }
}
static private Opc.Da.Server m_server = null;//定义数据存取服务器
static private Opc.Server[] servers;
static private Opc.Da.Subscription subscription = null;//定义组对象(订阅者)
static private Opc.Da.SubscriptionState state = null;//定义组(订阅者)状态,相当于OPC规范中组的参数
static private Opc.Da.Subscription _readSubscription = null;//定义组对象(订阅者)
static private Opc.Da.SubscriptionState _readstate = null;//定义组(订阅者)状态,相当于OPC规范中组的参数
static private Opc.Da.Subscription _writeSubscription = null;//定义组对象(订阅者)
static private Opc.Da.SubscriptionState _writestate = null;//定义组(订阅者)状态,相当于OPC规范中组的参数
static private Opc.Da.Subscription _tempSubscription = null;//定义组对象(订阅者)
static private Opc.Da.SubscriptionState _tempstate = null;//定义组(订阅者)状态,相当于OPC规范中组的参数
static private Opc.IDiscovery m_discovery = new OpcCom.ServerEnumerator();//定义枚举基于COM服务器的接口,用来搜索所有的此类服务器。
///
/// 《设备索引,对应设备订阅》
///
public static SubscriptionCollection SubscriptionGroup = new SubscriptionCollection();//定义组对象集合(订阅者集合)//20110309
//static Model.MDevice devinfo;//20110309
///
/// 20110309每个设备创建一个订阅和DataChange事件
///
public static void CreateSubscriptionGroup()
{
if (_IfConnectOPCServer == false)
{
_hostname = CommonClassLib.AppSettings.GetValue("HostName");
_progID = CommonClassLib.AppSettings.GetValue("OPCProgID");
if (ConnectOPCServer(_hostname, _progID) == false) return ;
}
DataView dv = dbo.ExceSQL("SELECT F_DeviceIndex, F_DBW2Address, F_DBWGetLength, F_S7Connection FROM T_Base_Device where F_DBW2Address >=0 and F_DBWGetLength>0 order by F_DeviceIndex asc").Tables[0].DefaultView;
for (int i = 0; i < dv.Count; i++)
{
//设定设备订阅状态
_tempstate = new Opc.Da.SubscriptionState();//组(订阅者)状态,相当于OPC规范中组的参数
_tempstate.Name = dv[i]["F_DeviceIndex"].ToString();//组名
_tempstate.ServerHandle = null;//服务器给该组分配的句柄。
_tempstate.ClientHandle = dv[i]["F_DeviceIndex"].ToString();//客户端给该组分配的句柄。
_tempstate.Active = true;//激活该组。
_tempstate.UpdateRate = 100;//刷新频率为100毫秒。
_tempstate.Deadband = 0;// 死区值,设为0时,服务器端该组内任何数据变化都通知组。
_tempstate.Locale = null;//不设置地区值。
//添加设备订阅
_tempSubscription = (Opc.Da.Subscription)m_server.CreateSubscription(_tempstate);//创建设备订阅
//添加标签
////定义读item列表
Item[] items = new Item[1];//定义数据项,即item
for (int ii = 0; ii < items.Length; ii++)//item初始化赋值
{
items[ii] = new Item();//创建一个项Item对象。
items[ii].ClientHandle = Guid.NewGuid().ToString();//客户端给该数据项分配的句柄。
items[ii].ItemPath = null; //该数据项在服务器中的路径。
items[ii].ItemName = dv[i]["F_S7Connection"].ToString() +
Model.CGeneralFunction.DBGet + ",byte" +
dv[i]["F_DBW2Address"].ToString() + "," +
(System.Convert.ToInt32(dv[i]["F_DBWGetLength"])).ToString(); //该数据项在服务器中的名字。
}
//添加读Item
ItemResult[] irs = _tempSubscription.AddItems(items);
//添加事件
_tempSubscription.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange);
SubscriptionGroup.Add(_tempSubscription);
//_tempSubscription.RemoveItems(_tempSubscription.Items);
}
}
///
/// 获取主机的所有OPC服务器的标识名称数组
///
/// 主机名称
///
public static List 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 ser =new List();;
foreach (Opc.Da.Server server in servers)
{
ser.Add(server.Name);
}
return ser;
}
return null;
}
catch (Exception ex)
{
_opcError = "获取OPC服务器时:" + ex.Message;
return null;
}
}
///
/// 连接指定主机的OPC服务器
///
/// 主机名称
/// OPC服务器程序标识例如:"OPC.SimaticNET"
///
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;
}
}
///
/// 创建OPC组(订阅者),定义组内变量名称
///
/// OPC组(订阅者)名称
/// 指定组内所有变量名称,数组的值举例"S7:[S7 connection_1]DB1,INT1"
///
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 = 50;//刷新频率为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;
}
}
///
/// 创建OPC组(订阅者),不定义组内变量名称
///
/// OPC组(订阅者)名称
///
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 = 50;//刷新频率为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;
}
}
///
/// 创建几个默认组:read和write、临时读写组tempGroup
///
///
public static void CreateItemGroup()
{
try
{
//if (_IfConnectOPCServer == false)
//{
// if (ConnectOPCServer(_hostname, _progID) == false) return ;
//}
#region 建立读全部标签组
//20110216
//设定读取组状态
_readstate = new Opc.Da.SubscriptionState();//组(订阅者)状态,相当于OPC规范中组的参数
_readstate.Name = "readopc";//组名
_readstate.ServerHandle = null;//服务器给该组分配的句柄。
_readstate.ClientHandle = Guid.NewGuid().ToString();//客户端给该组分配的句柄。
_readstate.Active = true;//激活该组。
_readstate.UpdateRate = 50;//刷新频率为100毫秒。
_readstate.Deadband = 0;// 死区值,设为0时,服务器端该组内任何数据变化都通知组。
_readstate.Locale = null;//不设置地区值。
//添加读组
_readSubscription = (Opc.Da.Subscription)m_server.CreateSubscription(_readstate);//创建读取组
//20110216
//string[] itemName;
//DataView dv = dbo.ExceSQL("SELECT F_S7Connection,F_DBW2Address,F_DBWGetLength FROM T_Base_Device WHERE (F_DeviceKindIndex = 28)").Tables[0].DefaultView;
//if (dv.Count > 0)
//{
// itemName=new string[dv.Count];
// for(int i=0;i
/// 创建OPC组(订阅者),定义组内变量名称
///
/// 组态软件中定义的每个PLC连接的标识
/// OPC组(订阅者)名称
/// 指定组内所有变量名称,数组的值举例"DB1,INT1"
///
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 = 50;//刷新频率为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;
}
}
///
/// 同步读取全部OPC组内变量的值,List《变量名+ ":" +变量值》
///
/// OPC组名称
///
public static List SyncReadAllItems(Opc.Da.Subscription subscription)
{
ItemValueResult[] values;
List itemnamevalue;
try
{
if (_IfConnectOPCServer == false)
{
if (ConnectOPCServer(_hostname, _progID) == false) return null;
}
itemnamevalue = new List();
//注册回调事件
//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;
}
}
///
/// 读取指定S7Connection所有DB1对应标签数组的数据,返回值:“标签值”组成的数组
///
/// OPC连接
///
public static byte[] SyncReadAllItems(string S7Connection)
{//20110216
ItemValueResult[] values;
byte[] itemnamevalue;
try
{
if (_IfConnectOPCServer == false)
{
if (ConnectOPCServer(_hostname, _progID) == false) return null;
}
_readSubscription.RemoveItems(_readSubscription.Items);
string[] itemName= new string[1];
DataView dv = dbo.ExceSQL("SELECT F_DBW2Address,F_DBWGetLength FROM T_Base_Device WHERE (F_DeviceKindIndex = 28 and F_S7Connection='"+S7Connection+"')").Tables[0].DefaultView;
if (dv.Count > 0)
{
itemName[0] = S7Connection + Model.CGeneralFunction.DBGet + ",byte"+ dv[0]["F_DBW2Address"].ToString() + "," + (System.Convert.ToInt32( dv[0]["F_DBWGetLength"])).ToString();
}
else
{
return null ;
}
//定义读item列表
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
ItemResult[] irs = _readSubscription.AddItems(items);
//_plcStates = new int[System.Convert.ToInt32(devinfo28.Dbw2Getlength)];
//_readSubscription.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange);
// 每个S7连接有一个单独的计数
sbc.Remove(0, sbc.Length);
sbc = sbc.Append(S7Connection.Substring(S7Connection.Length - 2, 1));
int ConnectID = 0;
switch (S7Connection.Substring(S7Connection.Length - 2, 1))
{
case "A":
ConnectID = 9; // 10号堆垛机
break;
case "B":
ConnectID = 10; // 输送机连接
break;
default:
ConnectID = System.Convert.ToInt32(sbc.ToString()) - 1;
break;
}
if (ErrorCount[ConnectID] > 1)
{
_opcError = "同步数据时:OPC Server没连接到PLC,并且超过重复连接次数!请先关闭命令开关,检查通讯线路,确认后重新打开命令开关!";
return null;
}
//if (ConnectCount > 1)
//{
// _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)
{
ErrorCount[ConnectID]++;
//ConnectCount++;
_opcError = "同步读数据时:OPC Server没连接到PLC!";
return null;
}
else if (values[0].Quality == Quality.Good)
{
// 读取成功后,计数清零
ErrorCount[ConnectID] = 0;
}
Array arr = (Array)values[0].Value;
itemnamevalue = new byte[arr.GetLength(0)];
Array.Copy(arr, itemnamevalue, arr.GetLength(0));
_readSubscription.RemoveItems(_readSubscription.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;
}
}
///
/// 读取指定标签名称的数据
///
/// 标签名称
///
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
///
/// 延吉读取整个_readSubscription组的内容
///
///
public static byte[] SyncReadAllItems()
{
ItemValueResult[] values;
byte[] itemnamevalue;
try
{
if (_IfConnectOPCServer == false)
{
if (ConnectOPCServer(_hostname, _progID) == false) return null;
}
//List itemnamevalue = new List();
//注册回调事件
//subscription.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange);
//以下测试同步读
//以下读整个组
if (ConnectCount > 1)
{
_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;
}
Array arr = (Array)values[0].Value;
itemnamevalue = new byte[arr.GetLength(0)];
Array.Copy(arr, itemnamevalue, arr.GetLength(0));
//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;
}
}
///
/// 延吉向指定OPC标签组写入数据(_writeSubscription组)
///
///
///
///
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);
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;
}
}
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 = _PLCconnectionID + 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].ToString();
}
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;
}
}
///
/// 延吉读取指定OPC标签组数据(_tempSubscription组)
///
///
///
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
//20100221
//#region 延吉同步写、异步读OPC
//static byte[] AsyncReadAllItemNameValue= new byte[(int)devinfo28.Dbw2Getlength];
//static bool AsyncReadOK=false ;
/////
///// 延吉异步读取整个_readSubscription组的内容
/////
/////
//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
// {
// }
//}
/////
///// 延吉向指定OPC标签组同步写入数据(_writeSubscription组)
/////
/////
/////
/////
//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
///
/// 同步向OPC组名称内每个变量写入值
///
/// OPC组名称
/// 每个变量的值
///
}
}