/// <summary> /// Removes OPC Item from OPC Group /// </summary> /// <param name="opcID">OPC item name</param> /// <returns>sucessfully removed or not</returns> /// OPCID is the Datapoint Name public bool RemoveOPCItem(string opcID) { string Function_Name = "RemoveOPCItem"; LogHelper.Trace(CLASS_NAME, Function_Name, "Function_Entered"); lock (m_opcDataDicObj) { if (!m_opcDataIndexDic.ContainsKey(opcID)) { LogHelper.Info(CLASS_NAME, Function_Name, "Function_Exited"); return(true); } //remove from OPC Group int handleClient = m_opcDataIndexDic[opcID]; if (!m_opcDataDic.ContainsKey(handleClient)) { //error LogHelper.Info(CLASS_NAME, Function_Name, "Function_Exited"); return(false); } OPCDataItem opcDataItemVar = m_opcDataDic[handleClient]; try { int[] serverhandles = new int[1] { opcDataItemVar.HandleServer }; int[] remerrors; if (m_OPCGroup != null) { m_OPCGroup.RemoveItems(serverhandles, out remerrors); } //remove from internal map m_opcDataIndexDic.Remove(opcID); m_opcDataDic.Remove(handleClient); m_OPCDataSeqNum--; } catch (Exception localException) { LogHelper.Error(CLASS_NAME, Function_Name, localException); //if (localException.Message.Contains("The RPC server is unavailable.")) // Fixed issue - related to System Language, to avoid it used Error code if (localException.Message.Contains("0x800706BA")) { //when opc server is crashed. throw localException; } return(false); } } LogHelper.Trace(CLASS_NAME, Function_Name, "Function_Exited"); return(true); }
/// <summary> /// Remove all registered OPC items /// </summary> /// <returns>true: successfully; false: failed</returns> public bool RemoveAllOPCItem() { string Function_Name = "RemoveAllOPCItem"; LogHelper.Trace(CLASS_NAME, Function_Name, "Function_Entered"); bool removeSuccess = true; int totalCount = 0; int count = 0; Dictionary <int, OPCDataItem> opcDataCopy = null; lock (m_opcDataDicObj) { totalCount = m_OPCDataSeqNum; opcDataCopy = new Dictionary <int, OPCDataItem>(m_opcDataDic); } for (; count < totalCount; count++) { OPCDataItem opcDataItem = opcDataCopy[count]; bool ret = true; try { ret = RemoveOPCItem(opcDataItem.ID); } catch (Exception exception) { //when opcserver crashed ClearDataItems(); lock (m_opcDataDicObj) { NotifyShutDownToObservers(); m_opcSrvConnectFlag = false; } throw exception; } if (ret != true) { removeSuccess = false; } } lock (m_opcDataDicObj) { if (m_opcDataIndexDic.Count != 0) { //todo error //not possible } } ClearDataItems(); LogHelper.Trace(CLASS_NAME, Function_Name, "Function_Exited"); return(removeSuccess); }
/// <summary> /// Add unique OPC item to group /// </summary> /// <param name="opcID">OPC Item name</param> /// <returns>false - not added to OPC group, true - added successfully</returns> public bool AddOPCItem(string opcID) { string Function_Name = "AddOPCItem"; LogHelper.Trace(CLASS_NAME, Function_Name, string.Format("Function_Entered for datapoint {0}", opcID)); if (opcID.Trim() == "") { LogHelper.Debug(CLASS_NAME, Function_Name, "New Datapoint name is empty.Function_Exited with return value false."); return(false); } int currentSeq = 0; OPCDataItem opcDataItemVar = null; lock (m_opcDataDicObj) { if (m_opcDataIndexDic.ContainsKey(opcID)) { LogHelper.Info(CLASS_NAME, Function_Name, "Already the datapoint is added.Function_Exited"); return(true); } currentSeq = m_OPCDataSeqNum++; opcDataItemVar = new OPCDataItem(opcID, currentSeq); //add to internal map m_opcDataIndexDic.Add(opcID, currentSeq); m_opcDataDic.Add(currentSeq, opcDataItemVar); } if (!IsOPCServerConnected()) { LogHelper.Debug(CLASS_NAME, Function_Name, "OPC Server is not connect. Reconnect before adding datapoints."); return(false); } try { LogHelper.Trace(CLASS_NAME, Function_Name, "Connect to OPC Group"); //connect to OPC Group OPCItemDef[] aD = new OPCItemDef[1]; aD[0] = new OPCItemDef(opcID, true, currentSeq, VarEnum.VT_EMPTY); OPCItemResult[] arrRes; { lock (m_opcDataDicObj) { m_OPCGroup.AddItems(aD, out arrRes); } } if (arrRes == null) { LogHelper.Info(CLASS_NAME, Function_Name, "OPC Group AddItems() return null(cant not find handle server). Function Exited with return value false."); return(false); } if (arrRes[0].Error != HRESULTS.S_OK) { LogHelper.Info(CLASS_NAME, Function_Name, string.Format("OPC Group AddItems() return Error code({0}, not OK) for DataPoint = {1}. Function Exited with return value false.", arrRes[0].Error, opcID)); lock (m_opcDataDicObj) { m_OPCDataSeqNum--; m_opcDataIndexDic.Remove(opcID); m_opcDataDic.Remove(currentSeq); m_TotryQuene.Add(opcID); } return(false); } opcDataItemVar.HandleServer = arrRes[0].HandleServer; OPCACCESSRIGHTS itmAccessRights = arrRes[0].AccessRights; TypeCode itmTypeCode = VT2TypeCode(arrRes[0].CanonicalDataType); if ((itmAccessRights & OPCACCESSRIGHTS.OPC_READABLE) != 0) { int cancelID; lock (m_opcDataDicObj) { m_OPCGroup.Refresh2(OPCDATASOURCE.OPC_DS_DEVICE, 7788, out cancelID); } } else { LogHelper.Info(CLASS_NAME, Function_Name, "Can find a handle server, but not have access right.Function Exited with return value false."); return(false); } } catch (COMException localException) { LogHelper.Error(CLASS_NAME, Function_Name, string.Format("{0} for DataPoint - {1}", localException.ToString(), opcID)); // if (localException.Message.Contains("The RPC server is unavailable.")) // Fixed issue - related to System Language, to avoid it used Error code if (localException.Message.Contains("0x800706BA")) { lock (m_opcDataDicObj) { m_opcSrvConnectFlag = false; } } return(false); } catch (Exception exception) { LogHelper.Error(CLASS_NAME, Function_Name, string.Format("{0} for DataPoint - {1}", exception.ToString(), opcID)); return(false); } LogHelper.Trace(CLASS_NAME, Function_Name, "Function_Exited"); return(true); }
/// <summary> /// Checks whether OPC Server is connected or not. If not, try to connect again. /// Also checks whether there is need to recreate group and connect OPC Items to it. /// </summary> /// <returns>true - OPC Server is connected, false - not connected</returns> public bool ReconnectAndAddToOPC() { string Function_Name = "ReconnectAndAddToOPC"; LogHelper.Trace(CLASS_NAME, Function_Name, "Function_Entered"); bool bReConnect = false; if (!IsOPCServerConnected()) { DateTime currrentTime = DateTime.Now; // check elapsed time between shutdown event and now before reconnecting //to avoid false shutdown event raised if (m_ShutdownEventTime != null) { DateTime shutDownTime = (DateTime)m_ShutdownEventTime; TimeSpan elapsedTime = currrentTime - shutDownTime; LogHelper.Info(CLASS_NAME, Function_Name, string.Format("Elapsed time for shutdown = {0}", elapsedTime.TotalSeconds)); if (elapsedTime.TotalMilliseconds < 5000) { double sleepTime = 5000 - elapsedTime.TotalMilliseconds; System.Threading.Thread.Sleep((int)sleepTime); } m_ShutdownEventTime = null; } InitializeServer(m_OPCSrvName, m_OPCGroupName); if (!IsOPCServerConnected()) { LogHelper.Error(CLASS_NAME, Function_Name, "Cannot able to connect to OPC Server.Function_Exited with return value false."); return(false); } bReConnect = true; } if (IsNeedToReCreateOPCGrp() && !bReConnect) { ReleaseOPC(); InitializeServer(m_OPCSrvName, m_OPCGroupName); if (!IsOPCServerConnected() || (GetOPCGrp() == null)) { LogHelper.Error(CLASS_NAME, Function_Name, "Cannot able to connect to OPC Server.Function_Exited with return value false."); return(false); } bReConnect = true; } if (bReConnect) { //reconnect the datapoints to OPC Grp int count = 0; List <string> opcDataCopyList = new List <string>(); lock (m_opcDataDicObj) { if ((m_OPCDataSeqNum == 0) && (m_TotryQuene.Count == 0)) { //no datapoints to be added return(true); } for (count = 0; count < m_OPCDataSeqNum; count++) { OPCDataItem opcDataItemVar = m_opcDataDic[count]; opcDataCopyList.Add(opcDataItemVar.ID); } foreach (string opcID in m_TotryQuene) { opcDataCopyList.Add(opcID); } } ClearDataItems(); foreach (string opcItemID in opcDataCopyList) { bool ret = AddOPCItem(opcItemID); //if (!ret) //{ //todo //} } } LogHelper.Trace(CLASS_NAME, Function_Name, "Function_Exited"); return(true); }