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]"; /// /// 建立PLC连接的ID,例如:"S7:[S7 connection_1]" /// 或者"S7:[@LOCALSERVER]" /// 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; /// /// OPC Server的机器名称或者IP地址 /// public static string Hostname { get { return CCommonOPCClient._hostname; } set { CCommonOPCClient._hostname = value; } } private static 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; } } 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服务器的接口,用来搜索所有的此类服务器。 /// /// 获取主机的所有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 = 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; } } /// /// 创建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 = 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; } } /// /// 创建几个默认组:read和write、临时读写组tempGroup /// /// 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; } } /// /// 创建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 = 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; } } /// /// 同步读取全部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; } } /// /// 读取指定标签数组的数据,返回值:“标签值”组成的数组 /// /// 标签数组 /// public static List SyncReadAllItems(string[] itemnames) { Subscription subs; List itemnamevalue; ItemValueResult[] values; try { if (_IfConnectOPCServer == false) { if (ConnectOPCServer(_hostname, _progID) == false) return null; } subs = CreateItemGroup(_PLCconnectionID, Guid.NewGuid().ToString(), itemnames); itemnamevalue = new List(); 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; } } /// /// 读取指定标签名称的数据 /// /// 标签名称 /// 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 > 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; } } /// /// 延吉向指定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); 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; } } /// /// 单个标签,按字节写入多个byte数据20110515 一对多写入 /// /// 单个标签的名称,注意:只包含一个元素的数组 /// 要写入的byte数组 /// 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; } } /// /// 延吉读取指定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 同步读、写OPC //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组名称 /// 每个变量的值 /// } }