Example #1
0
        public override bool WriteTag(TagId tag, string value)
        {
            try
            {
                groupWrite.RemoveItems(groupWrite.Items);
                List <Item>      writeList = new List <Item>();
                List <ItemValue> valueList = new List <ItemValue>();

                Item itemToWrite = new Item();
                itemToWrite.ItemName = tag.TagName;
                ItemValue itemValue = new ItemValue(itemToWrite);
                itemValue.Value = value;

                writeList.Add(itemToWrite);
                valueList.Add(itemValue);
                groupWrite.AddItems(writeList.ToArray());
                for (int i = 0; i < valueList.Count; i++)
                {
                    valueList[i].ServerHandle = groupWrite.Items[i].ServerHandle;
                }

                groupWrite.Write(valueList.ToArray());
                return(true);
            }
            catch (Exception ex)
            {
                logger.Logged("Error", "Не удалось записать значние OPC DA сервера {" + tag.TagName + "[" + value + "]}: {" + ex.Message + "}", "OpcDaPoller", "WriteTag");
                return(false);
            }
        }
Example #2
0
        public void WriteData(string[] itemName, int[] value)
        {
            groupWrite.RemoveItems(groupWrite.Items);

            List <Item>      writeList = new List <Item>();
            List <ItemValue> valueList = new List <ItemValue>();

            for (int x = 0; x < itemName.Length; x++)
            {
                Item itemToWrite = new Item();
                itemToWrite.ItemName = itemName[x];
                ItemValue itemValue = new ItemValue(itemToWrite);
                itemValue.Value = value[x];
                writeList.Add(itemToWrite);
                valueList.Add(itemValue);
            }



            //IMPORTANT:
            //#1: assign the item to the group so the items gets a ServerHandle
            groupWrite.AddItems(writeList.ToArray());
            // #2: assign the server handle to the ItemValue
            for (int i = 0; i < valueList.Count; i++)
            {
                valueList[i].ServerHandle = groupWrite.Items[i].ServerHandle;
            }
            // #3: write
            groupWrite.Write(valueList.ToArray());
        }
Example #3
0
        /// <summary>
        /// Add items (according to "itemList" parameter) into OPC.Subscription
        /// </summary>
        /// <param name="itemList"></param>
        /// <param name="updateRate"></param>
        /// <returns></returns>
        public bool AddItems(Opc.Da.Item[] itemList, int updateRate = 0)
        {
            var state = new Opc.Da.SubscriptionState();

            try
            {
                // Remove items
                if (Items != null)
                {
                    Subscription.RemoveItems(Items);
                }

                state.Active = false;
                Subscription.ModifyState((int)Opc.Da.StateMask.Active, state);

                state.UpdateRate = updateRate > 0 ? updateRate : 1000;
                Subscription.ModifyState((int)Opc.Da.StateMask.UpdateRate, state);

                foreach (var item in itemList)
                {
                    item.ClientHandle = Guid.NewGuid().ToString();
                }

                Items   = Subscription.AddItems(itemList);
                Advised = false;
                return(true);
            }
            catch (Exception e)
            {
                //MessageBox.Show(ex.Message);
                throw e;
            }
        }
Example #4
0
 /// <summary>
 /// 断开OPC连接
 /// </summary>
 public void OPC_disconnect()
 {
     OpcGroupClasssubscription.DataChanged -= new Opc.Da.DataChangedEventHandler(this.OnDataChange); //取消回调事件
     OpcGroupClasssubscription.RemoveItems(OpcGroupClasssubscription.Items);                         //移除组内item
     //结束:释放各资源
     OpcGroupClassm_server.CancelSubscription(OpcGroupClasssubscription);                            //m_server前文已说明,通知服务器要求删除组。
     OpcGroupClasssubscription.Dispose();                                                            //强制.NET资源回收站回收该subscription的所有资源。
     OpcGroupClassm_server.Disconnect();                                                             //断开服务器连接
     //不相关的
 }
Example #5
0
 /// <summary>
 /// 断开与OPC服务连接,并释放资源
 /// </summary>
 public void Disconect()
 {
     itemIndexDic.Clear();
     //移除组内item
     subscription.RemoveItems(subscription.Items);
     //通知服务器要求删除组。
     m_server.CancelSubscription(subscription);
     subscription.Dispose();
     m_server.Disconnect();
 }
Example #6
0
 /// <summary>
 /// 断开OPC服务器连接
 /// </summary>
 private void DisConnect()
 {
     if (m_server != null)
     {
         m_subscription.RemoveItems(m_subscription.Items);
         // 结束:释放各资源
         m_server.CancelSubscription(m_subscription); // m_server前文已说明,通知服务器要求删除组。
         m_subscription.Dispose();                    // 强制.NET资源回收站回收该subscription的所有资源。
         m_server.Disconnect();                       // 断开服务器连接
     }
 }
Example #7
0
 /// <summary>
 /// OPC断开连接
 /// </summary>
 public void mOpc_DisConn()
 {
     try
     {
         if (m_Server != null)
         {
             subscription.RemoveItems(subscription.Items);
             //结束:释放各资源
             m_Server.CancelSubscription(subscription); //m_server前文已说明,通知服务器要求删除组。
             subscription.Dispose();                    //强制.NET资源回收站回收该subscription的所有资源。
             m_Server.Disconnect();
         }
     }
     catch (Exception ex)
     {
         throw new Exception("OPC断开函数(mOpc_DisConn)异常:" + ex.ToString());
     }
 }
        /// <summary>
        /// 断开OPC服务器连接
        /// </summary>
        private void DisConnect()
        {
            if (m_server != null)
            {
                m_subscription.RemoveItems(m_subscription.Items);
                // 结束:释放各资源
                m_server.CancelSubscription(m_subscription); // m_server前文已说明,通知服务器要求删除组。
                m_subscription.Dispose();                    // 强制.NET资源回收站回收该subscription的所有资源。
                m_server.Disconnect();                       // 断开服务器连接
            }

            if (null != m_timer)
            {
                m_timer.Stop();
                m_timer.Close();
                m_timer.Dispose();
            }

            m_lstItemValueResult = null;
            m_lstAckTelegram     = null;
        }
Example #9
0
        public void Work()
        {
            int i = 5;

            if (i == 1)
            {
                url    = new Opc.URL("opcda://192.168.0.4/OPC.PHDServerDA.1");
                server = new Opc.Da.Server(fact, null);
                server.Connect(url, new Opc.ConnectData(new System.Net.NetworkCredential()));

                Opc.Da.Item[] itemCollection = new Opc.Da.Item[1];
                itemCollection[0] = new Opc.Da.Item {
                    ItemName = "RTOS.TEST.PV", MaxAge = -1
                };
                Opc.Da.ItemValueResult[] result = server.Read(itemCollection);

                Console.WriteLine(result[0].Value);
                server.Disconnect();
            }
            else if (i == 2)
            {
                url    = new Opc.URL("opcda://192.168.0.4/OPC.PHDServerDA.1");
                server = new Opc.Da.Server(fact, null);
                server.Connect(url, new Opc.ConnectData(new System.Net.NetworkCredential()));

                groupState              = new Opc.Da.SubscriptionState();
                groupState.Name         = "Group";
                groupState.ServerHandle = null;
                groupState.ClientHandle = Guid.NewGuid().ToString();
                groupState.Active       = true;
                groupState.UpdateRate   = 1000;
                groupState.Deadband     = 0;
                groupState.Locale       = null;

                groupRead = (Opc.Da.Subscription)server.CreateSubscription(groupState);


                string[] itemName = { "RTOS.TEST.PV", "RTOR.TI1237.DACA.PV" };

                Opc.Da.Item[] items = new Opc.Da.Item[2];

                for (int j = 0; j < items.Length; j++)
                {
                    items[j] = new Opc.Da.Item();
                    items[j].ClientHandle = Guid.NewGuid().ToString();
                    items[j].ItemPath     = null;
                    items[j].ItemName     = itemName[j];
                }

                groupRead.AddItems(items);
                //groupRead.DataChanged += new Opc.Da.DataChangedEventHandler(group_DataChanged);

                Opc.Da.ItemValueResult[] results = groupRead.Read(groupRead.Items);
                foreach (ItemValueResult result in results)
                {
                    Console.WriteLine("{0},{1},{2},{3}", result.ItemName, result.Value, result.Quality, result.Timestamp);
                }
                //groupRead.DataChanged -= new Opc.Da.DataChangedEventHandler(group_DataChanged);

                groupRead.RemoveItems(groupRead.Items);
                server.CancelSubscription(groupRead);
                groupRead.Dispose();
                server.Disconnect();
            }
            else if (i == 3)
            {
                url    = new Opc.URL("opcda://192.168.0.4/OPC.PHDServerDA.1");
                server = new Opc.Da.Server(fact, null);
                server.Connect(url, new Opc.ConnectData(new System.Net.NetworkCredential()));

                groupState              = new Opc.Da.SubscriptionState();
                groupState.Name         = "Group";
                groupState.ServerHandle = null;
                groupState.ClientHandle = Guid.NewGuid().ToString();
                groupState.Active       = true;
                groupState.UpdateRate   = 1000;
                groupState.Deadband     = 0;
                groupState.Locale       = null;

                groupWrite = (Opc.Da.Subscription)server.CreateSubscription(groupState);

                string[] itemName = { "RTOS.TEST.PV", "RTOS.TEST2.PV" };

                Opc.Da.Item[] items = new Opc.Da.Item[2];

                for (int j = 0; j < items.Length; j++)
                {
                    items[j] = new Opc.Da.Item();
                    items[j].ClientHandle = Guid.NewGuid().ToString();
                    items[j].ItemPath     = null;
                    items[j].ItemName     = itemName[j];
                }

                groupWrite.AddItems(items);

                //groupRead.DataChanged += new Opc.Da.DataChangedEventHandler(group_DataChanged);

                Opc.Da.ItemValue[] writeValues = new Opc.Da.ItemValue[groupWrite.Items.Length];
                for (int k = 0; k < groupWrite.Items.Length; k++)
                {
                    writeValues[k] = new Opc.Da.ItemValue((ItemIdentifier)groupWrite.Items[k]);
                }

                writeValues[0].Value = 5;
                writeValues[1].Value = 6;

                groupWrite.Write(writeValues);

                Console.WriteLine("Press any key to close...");
                Console.ReadLine();

                //groupRead.DataChanged -= new Opc.Da.DataChangedEventHandler(group_DataChanged);

                groupWrite.RemoveItems(groupWrite.Items);
                server.CancelSubscription(groupWrite);
                groupWrite.Dispose();
                server.Disconnect();
            }
            else if (i == 4)
            {
                url       = new Opc.URL("opchda://192.168.0.4/OPC.PHDServerHDA.1");
                serverHda = new Opc.Hda.Server(fact, null);
                serverHda.Connect(url, new Opc.ConnectData(new System.Net.NetworkCredential()));

                try
                {
                }
                catch (Opc.ConnectFailedException opcConnEx)
                {
                    Console.WriteLine(string.Format("Could not connect to server {0}", "OPC.PHDServerHDA.1"));
                    Console.WriteLine(opcConnEx.ToString());
                }

                Console.WriteLine("Are we connected? " + serverHda.IsConnected);

                string[] itemName = { "RTOS.TEST.PV", "RTOS.TEST2.PV" };

                Opc.Hda.Trend groupHda = new Trend(serverHda);

                groupHda.Name        = "HDA";
                groupHda.AggregateID = AggregateID.NOAGGREGATE;
                DateTime startTime = DateTime.Now.AddHours(-1);
                DateTime endTime   = DateTime.Now;
                groupHda.StartTime     = new Opc.Hda.Time(startTime);
                groupHda.EndTime       = new Opc.Hda.Time(endTime);
                groupHda.MaxValues     = 0;
                groupHda.IncludeBounds = false;

                serverHda.Trends.Add(groupHda);

                Opc.Hda.Item[] items = new Opc.Hda.Item[2];
                for (int m = 0; m < 2; m++)
                {
                    items[m]              = new Opc.Hda.Item();
                    items[m].ItemName     = itemName[m];
                    items[m].ItemPath     = null;
                    items[m].ClientHandle = Guid.NewGuid().ToString();
                }

                IdentifiedResult[] identifiedResult = serverHda.CreateItems(items);

                if (identifiedResult != null)
                {
                    foreach (IdentifiedResult item in identifiedResult)
                    {
                        if (item.ResultID.Succeeded())
                        {
                            groupHda.Items.Add(new Opc.Hda.Item(item));
                        }
                    }
                }

                Opc.Hda.ItemValueCollection[] results = groupHda.ReadRaw();

                Opc.Hda.ItemValueCollection result1 = results[0];

                foreach (Opc.Hda.ItemValue result in result1)
                {
                    Console.WriteLine("{0},{1},{2}", result.Value, result.Quality, result.Timestamp);
                }

                serverHda.Disconnect();
            }
            else if (i == 5)
            {
                url       = new Opc.URL("opchda://192.168.0.4/OPC.PHDServerHDA.1");
                serverHda = new Opc.Hda.Server(fact, null);
                serverHda.Connect(url, new Opc.ConnectData(new System.Net.NetworkCredential()));

                try
                {
                }
                catch (Opc.ConnectFailedException opcConnEx)
                {
                    Console.WriteLine(string.Format("Could not connect to server {0}", "OPC.PHDServerHDA.1"));
                    Console.WriteLine(opcConnEx.ToString());
                }

                Console.WriteLine("Are we connected? " + serverHda.IsConnected);

                string[] itemName = { "RTOR.TI1237.DACA.PV", "RTOS.TEST2.PV" };

                Opc.Hda.Trend groupHda = new Trend(serverHda);

                groupHda.Name        = "HDA";
                groupHda.AggregateID = AggregateID.AVERAGE;

                DateTime startTime = DateTime.Now.AddHours(-1);
                DateTime endTime   = DateTime.Now;
                //TimeSpan span = endTime.Subtract(startTime);
                //int calcInterval = ((int)span.TotalSeconds);
                //groupHda.ResampleInterval = (decimal)calcInterval;

                //DateTime startTime = new DateTime(2020, 6, 12, 9, 0, 0, 0);
                //DateTime endTime = new DateTime(2020, 6, 12, 10, 0, 0, 0);
                int calcInterval = 300;
                groupHda.ResampleInterval = (decimal)calcInterval;


                groupHda.StartTime     = new Opc.Hda.Time(startTime);
                groupHda.EndTime       = new Opc.Hda.Time(endTime);
                groupHda.MaxValues     = 0;
                groupHda.IncludeBounds = false;

                serverHda.Trends.Add(groupHda);

                Opc.Hda.Item[] items = new Opc.Hda.Item[2];
                for (int m = 0; m < 2; m++)
                {
                    items[m]              = new Opc.Hda.Item();
                    items[m].ItemName     = itemName[m];
                    items[m].ItemPath     = null;
                    items[m].ClientHandle = Guid.NewGuid().ToString();
                }

                IdentifiedResult[] identifiedResult = serverHda.CreateItems(items);

                if (identifiedResult != null)
                {
                    foreach (IdentifiedResult item in identifiedResult)
                    {
                        if (item.ResultID.Succeeded())
                        {
                            groupHda.Items.Add(new Opc.Hda.Item(item));
                        }
                    }
                }

                Opc.Hda.ItemValueCollection[] results = groupHda.ReadProcessed();

                Opc.Hda.ItemValueCollection result1 = results[0];

                foreach (Opc.Hda.ItemValue result in result1)
                {
                    Console.WriteLine("{0},{1},{2}", result.Value, result.Quality, result.Timestamp);
                }

                serverHda.Disconnect();
            }
        }
Example #10
0
        /// <summary>
        /// 注册Opc数据项集合
        /// </summary>
        /// <param name="opcDataItems"></param>
        private void registerOpcDataItems(IList <OpcDataItem> opcDataItems)
        {
            this.OpcDataItems   = opcDataItems;
            daemonTimer.Enabled = false;
            daemonTimer.Stop();

            //如果未连接那么返回
            if (!this.IsConnected)
            {
                if (!Equals(null, OnErrorHappened))
                {
                    OnErrorHappened(this, new OpcErrorEventArgs(OpcResult.E_FAIL, "Opc服务器未连接,请先连接在订阅数据项", null));
                }
                return;
            }
            #region 没有数据项那么清空所有订阅

            //如果订阅的DataItem没有,那么清空现在所有订阅
            if (Equals(null, opcDataItems) || opcDataItems.Count() < 1)
            {
                if (!Equals(this.opcServer.Subscriptions, null) && this.opcServer.Subscriptions.Count > 0)
                {
                    foreach (Opc.Da.Subscription thisSubscription in this.opcServer.Subscriptions)
                    {
                        thisSubscription.RemoveItems(thisSubscription.Items);
                        thisSubscription.DataChanged -= ThisSubscription_DataChanged;
                        this.opcServer.CancelSubscription(thisSubscription);
                        thisSubscription.Dispose();
                    }
                    this.opcServer.Subscriptions.Clear();

                    //订阅项取消后通知外部程序
                    if (!Equals(null, OnLogHappened))
                    {
                        OnLogHappened(this, new OpcHelper.OpcLogEventArgs("已经取消所有订阅"));
                    }
                    return;
                }
            }

            #endregion   数据项需要更新或者删除

            //根据要订阅的新数据项,增加或者移除现在的订阅
            if (!IsConnected)
            {
                if (!Equals(null, OnLogHappened))
                {
                    OnLogHappened(this, new OpcLogEventArgs("Opc服务器已断开"));
                }
                return;
            }
            //根据更新频率分组
            var dataItemGroups = from a in opcDataItems
                                 group a by a.UpdateRate into g
                                 select new { UpdateRate = g.Key, DataItems = g };

            //循环每组订阅对象,查询是否实际订阅,有则更新,没有则新建
            foreach (var dataItemGroup in dataItemGroups)
            {
                Opc.Da.Subscription thisSubscription = this.opcServer.Subscriptions.Cast <Opc.Da.Subscription>().FirstOrDefault(a => a.State.UpdateRate == dataItemGroup.UpdateRate);
                //未找到已经订阅的组,那么新建组并添加订阅项
                if (Equals(null, thisSubscription))
                {
                    if (!IsConnected)
                    {
                        if (!Equals(null, OnLogHappened))
                        {
                            OnLogHappened(this, new OpcLogEventArgs("Opc服务器已断开"));
                        }
                        return;
                    }
                    #region 增加订阅

                    //创建订阅组。订阅组状态的名称是更新频率
                    Opc.Da.Subscription newSubscription = this.opcServer.CreateSubscription
                                                              (CreateSubscriptionState(dataItemGroup.UpdateRate.ToString(), dataItemGroup.UpdateRate))
                                                          as Opc.Da.Subscription;//创建组
                    //创建opc订阅项
                    var opcItems = ConvertItems(dataItemGroup.DataItems);
                    //添加订阅项
                    var results = newSubscription.AddItems(opcItems.ToArray());
                    newSubscription.DataChanged += ThisSubscription_DataChanged;
                    //订阅的结果通过事件通知给外部调用程序
                    foreach (var v in results)
                    {
                        if (!IsConnected)
                        {
                            if (!Equals(null, OnLogHappened))
                            {
                                OnLogHappened(this, new OpcLogEventArgs("Opc服务器已断开"));
                            }
                            return;
                        }
                        //订阅成功更新状态
                        if (v.ResultID == Opc.ResultID.S_OK)
                        {
                            OpcResult opcResult = OpcResult.Unknow;
                            Enum.TryParse <OpcResult>(v.ResultID.ToString(), out opcResult);
                            OpcDataItems.FirstOrDefault(a => a.Name == v.ItemName).Quality = opcResult;
                        }
                        //未订阅成功,异常事件通知
                        else if (v.ResultID == Opc.ResultID.S_OK && !Equals(null, OnDataChanged))
                        {
                            OnDataChanged(this, new OpcDataEventArgs(OpcResult.DataItemRegistered,
                                                                     dataItemGroup.DataItems.FirstOrDefault(a => a.Name == v.ItemName)));
                        }
                        else if (v.ResultID != Opc.ResultID.S_OK && !Equals(null, OnErrorHappened))
                        {
                            OpcResult opcResult = OpcResult.Unknow;
                            Enum.TryParse <OpcResult>(v.ResultID.ToString(), out opcResult);
                            this.OpcDataItems.FirstOrDefault(a => a.Name == v.ItemName).Quality = opcResult;
                            OnErrorHappened(this, new OpcErrorEventArgs(opcResult, "订阅数据项时发生错误" + v.ResultID.Name, null));
                        }
                    }//end foreach
                    #endregion
                }
                else//已经有订阅组,那么更新订阅项
                {
                    if (!IsConnected)
                    {
                        if (!Equals(null, OnLogHappened))
                        {
                            OnLogHappened(this, new OpcLogEventArgs("Opc服务器已断开"));
                        }
                        return;
                    }
                    #region 已经有订阅组,那么更新订阅项

                    //查询要新增加的点,
                    IList <OpcDataItem> newItems = new List <OpcDataItem>();
                    foreach (var v in dataItemGroup.DataItems)
                    {
                        if (!thisSubscription.Items.Any(a => a.ItemName == v.Name))
                        {
                            newItems.Add(v);
                        }
                    }
                    var opcItems = ConvertItems(newItems);
                    //添加订阅项
                    var addResults = thisSubscription.AddItems(opcItems.ToArray());

                    //订阅的结果通过事件通知给外部调用程序
                    foreach (var v in addResults)
                    {
                        if (!IsConnected)
                        {
                            if (!Equals(null, OnLogHappened))
                            {
                                OnLogHappened(this, new OpcLogEventArgs("Opc服务器已断开"));
                            }
                            return;
                        }
                        //订阅成功更新状态
                        if (v.ResultID == Opc.ResultID.S_OK)
                        {
                            OpcResult opcResult = OpcResult.Unknow;
                            Enum.TryParse <OpcResult>(v.ResultID.ToString(), out opcResult);
                            OpcDataItems.FirstOrDefault(a => a.Name == v.ItemName).Quality = opcResult;
                        }
                        //未订阅成功,异常事件通知
                        else if (v.ResultID == Opc.ResultID.S_OK && !Equals(null, OnDataChanged))
                        {
                            OnDataChanged(this, new OpcDataEventArgs(OpcResult.DataItemRegistered,
                                                                     dataItemGroup.DataItems.FirstOrDefault(a => a.Name == v.ItemName)));
                        }
                        else if (v.ResultID != Opc.ResultID.S_OK && !Equals(null, OnErrorHappened))
                        {
                            OpcResult opcResult = OpcResult.Unknow;
                            Enum.TryParse <OpcResult>(v.ResultID.ToString(), out opcResult);
                            this.OpcDataItems.FirstOrDefault(a => a.Name == v.ItemName).Quality = opcResult;
                            OnErrorHappened(this, new OpcErrorEventArgs(opcResult, "订阅数据项时发生错误:" + v.ItemName + " 无效,OpcResult=" + v.ResultID.Name, null));
                        }
                    }//end foreach

                    //查询要删除的点,
                    IList <Opc.Da.Item> deleteItems = new List <Opc.Da.Item>();
                    foreach (var v in thisSubscription.Items)
                    {
                        if (!dataItemGroup.DataItems.Any(a => a.Name == v.ItemName))
                        {
                            deleteItems.Add(v);
                        }
                    }

                    //删除已经订阅点
                    var deleteResults = thisSubscription.RemoveItems(deleteItems.ToArray());
                    //订阅的结果通过事件通知给外部调用程序
                    foreach (var v in deleteResults)
                    {
                        if (!IsConnected)
                        {
                            if (!Equals(null, OnLogHappened))
                            {
                                OnLogHappened(this, new OpcLogEventArgs("Opc服务器已断开"));
                            }
                            return;
                        }
                        //未订阅成功,异常事件通知
                        if (v.ResultID == Opc.ResultID.S_OK && !Equals(null, OnDataChanged))
                        {
                            OpcDataItem tmp2 = new OpcDataItem(v.ItemName, thisSubscription.State.UpdateRate, "", "", OpcResult.DataItemUnregistered);
                            OnDataChanged(this, new OpcDataEventArgs(OpcResult.DataItemUnregistered, tmp2));
                        }
                        else if (v.ResultID != Opc.ResultID.S_OK && !Equals(null, OnErrorHappened))
                        {
                            OnErrorHappened(this, new OpcErrorEventArgs(OpcResult.E_FAIL, "取消订阅数据项时发生错误" + v.ResultID.Name, null));
                        }
                    }//end foreach
                    //删除订阅项后没有item了,那么删除thisSubscription
                    if (thisSubscription.Items.Count() < 1)
                    {
                        thisSubscription.DataChanged -= ThisSubscription_DataChanged;
                        string name = thisSubscription.Name;
                        //this.opcServer.Subscriptions.Remove(thisSubscription);
                        this.opcServer.CancelSubscription(thisSubscription);
                        thisSubscription.Dispose();//
                        if (!Equals(null, OnLogHappened))
                        {
                            OnLogHappened(this, new OpcLogEventArgs("Subscription " + name + " 已经从订阅组中移除"));
                        }
                        name = null;
                    }
                    #endregion
                }
            }//end foreach (var dataItemGroup in dataItemGroups)
            //删除订阅项后没有item了,那么删除subscription
            foreach (var subscription in this.opcServer.Subscriptions.Cast <Opc.Da.Subscription>())
            {
                var isHave = dataItemGroups.Any(a => a.UpdateRate == subscription.State.UpdateRate);

                if (!isHave)
                {
                    subscription.DataChanged -= ThisSubscription_DataChanged;
                    string name = subscription.Name;
                    //his.opcServer.Subscriptions.Remove(thisSubscription);
                    this.opcServer.CancelSubscription(subscription);
                    subscription.Dispose();//
                    if (!Equals(null, OnLogHappened))
                    {
                        OnLogHappened(this, new OpcLogEventArgs("Subscription " + name + " 已经从订阅组中移除"));
                    }
                    name = null;
                }
            }
            if (!Equals(null, OnLogHappened))
            {
                OnLogHappened(this, new OpcLogEventArgs("OPC Subscriptions Count:" + this.opcServer.Subscriptions.Count + "."));
            }
            daemonTimer.Enabled = true;
            daemonTimer.Start();
        }