SCLS/SSWCS_JXDL(2019)/OPCClient/CCommonOPCClient.cs
2025-05-19 09:45:29 +08:00

1185 lines
47 KiB
C#
Raw Permalink 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 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; }
}
/// <summary>
/// 20110309订阅的组内标签数据变化事件
/// </summary>
/// <param name="subscriptionHandle">客户端句柄</param>
/// <param name="requestHandle">请求句柄</param>
/// <param name="values">标签值数组</param>
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]";
/// <summary>
/// 建立PLC连接的ID例如"S7:[S7 connection_1]"
/// 或者"S7:[@LOCALSERVER]"
/// </summary>
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;
/// <summary>
/// OPC Server的机器名称或者IP地址
/// </summary>
public static string Hostname
{
get { return CCommonOPCClient._hostname; }
set { CCommonOPCClient._hostname = value; }
}
static private 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; }
}
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服务器的接口用来搜索所有的此类服务器。
/// <summary>
/// 《设备索引,对应设备订阅》
/// </summary>
public static SubscriptionCollection SubscriptionGroup = new SubscriptionCollection();//定义组对象集合(订阅者集合)//20110309
//static Model.MDevice devinfo;//20110309
/// <summary>
/// 20110309每个设备创建一个订阅和DataChange事件
/// </summary>
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);
}
}
/// <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 = 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;
}
}
/// <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 = 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;
}
}
/// <summary>
/// 创建几个默认组read和write、临时读写组tempGroup
/// </summary>
/// <returns></returns>
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<dv.Count;i++)
// {
// itemName[i] = dv[i]["F_S7Connection"] + Model.CGeneralFunction.DBGet + ",byte"
// + dv[i]["F_DBW2Address"].ToString() + "," + ((int)dv[i]["F_DBWGetLength"]).ToString();
// }
// //{ "S7:[S7 connection_1]DB1,INT1", "S7:[@LOCALSERVER]DB1,INT20", "S7:[@LOCALSERVER]DB1,INT30", "S7:[@LOCALSERVER]DB1,INT50" };
//}
//else
//{
// return ;
//}
////定义读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);
#endregion
//设定写组状态
_writestate = new Opc.Da.SubscriptionState();//组订阅者状态相当于OPC规范中组的参数
_writestate.Name = "writeopc";//组名
_writestate.ServerHandle = null;//服务器给该组分配的句柄。
_writestate.ClientHandle = Guid.NewGuid().ToString();//客户端给该组分配的句柄。
_writestate.Active = true;//激活该组。
_writestate.UpdateRate = 50;//刷新频率为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 = 50;//刷新频率为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 = 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;
}
}
/// <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>
/// 读取指定S7Connection所有DB1对应标签数组的数据返回值“标签值”组成的数组
/// </summary>
/// <param name="S7Connection">OPC连接</param>
/// <returns></returns>
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;
}
}
/// <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 > 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;
}
}
/// <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);
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;
}
}
/// <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
//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>
}
}