/// <summary> /// Values of existing CONDITION events are updated the forwarded to TheGlobal for further processing /// per subscription per server instance /// </summary> /// <param name="EventNotification"></param> /// <param name="areas"></param> /// <param name="newCond"></param> private void ProcessCondition(EventNotification EventNotification, string[] areas, OPCCondition newCond) { try { newCond.ClearChangeMask(); newCond.SetMessage(EventNotification.Message); newCond.SetSeverity(EventNotification.Severity); newCond.SetSubconditionName(EventNotification.SubConditionName); newCond.SetActive((EventNotification.NewState & OpcRcw.Ae.Constants.CONDITION_ACTIVE) != 0); // The UA server generates unique identifiers in the form of guids. how to map these to COM-style cookies? // For now, just increment a static DWORD counter from the OPCCondition constructor and assign //newCond.Cookie = EventNotification.Cookie; newCond.SetTime(EventNotification.ActiveTime); newCond.EventId = EventNotification.EventId; newCond.EventCategory = EventNotification.EventCategory; newCond.SetQuality((short)EventNotification.Quality); newCond.ActorID = EventNotification.EventType == OpcRcw.Ae.Constants.TRACKING_EVENT ? EventNotification.ActorID : ""; newCond.SetEnable((EventNotification.NewState & OpcRcw.Ae.Constants.CONDITION_ENABLED) != 0); newCond.SetIsAcked((EventNotification.NewState & OpcRcw.Ae.Constants.CONDITION_ACKED) != 0); newCond.SetAckRequired(EventNotification.AckRequired); newCond.ConditionId = EventNotification.ConditionId; newCond.AcknowledgeMethod = EventNotification.AcknowledgeMethod; OPCSubcondition subCond = new OPCSubcondition(newCond.SubconditionName, newCond.Message, "", newCond.Severity); newCond.push_back_subcondition(subCond); for (int i = 0; i < areas.Length; i++) { newCond.push_back_area(areas[i]); } // Insert standard attribute "AckComment" newCond.push_back_attrval(Global.TheGlobal.StdAttrIds[0], newCond.AckComment); // Insert standard attribute "Areas" newCond.push_back_attrval(Global.TheGlobal.StdAttrIds[1], areas); foreach (KeyValuePair <int, object> kvp in EventNotification.EventAttributes) { newCond.push_back_attrval(kvp.Key, kvp.Value); } if (newCond.IsEnabled()) { lock (Global.TheGlobal) { Global.TheGlobal.NotifyClients(EventNotification.SourceID, EventNotification.ConditionName, newCond); } } } catch (Exception e) { Utils.Trace(e, "Unexpected error in ProcessCondition"); } // Utils.Trace("ProcessCondition - END Source: {0}, condition: {1}, conditionstate: {2}", // EventNotification.SourceID, EventNotification.ConditionName, newCond.NewState); }
/// <summary> /// Force a refresh for all active conditions and inactive, unacknowledged conditions whose event notifications match the filter of the event subscription. /// </summary> /// <param name="dwConnection">The OLE Connection number returned from IConnectionPoint::Advise. This is passed to help the server determine which OPC event sink to call when the request completes.</param> public void Refresh(int dwConnection) { try { if (m_RefreshID != 0 || m_RefreshQ.Count != 0) { throw ComUtils.CreateComException("Refresh", ResultIds.E_BUSY); } m_RefreshID = dwConnection; // Foe each source walk through all associated conditions. If the condition is "refreshable", i.e. Active or // inactive/unacknowledged, then create an event and push it on to the subscription's refresh queue SourceMap sourceMap = SourceMap.TheSourceMap; foreach (KeyValuePair <string, ConditionMap> kvp in sourceMap) { string sourceName = kvp.Key; ConditionMap conditionMap = kvp.Value; foreach (KeyValuePair <string, OPCCondition> kvpCond in conditionMap) { string conditionName = kvpCond.Key; OPCCondition cond = kvpCond.Value; if (cond.IsEnabled() && (cond.IsActive() || !cond.IsAcked())) { OnEventClass OEClass = new OnEventClass(sourceName, conditionName, cond); if (MatchesFilter(OEClass)) { m_RefreshQ.Enqueue(OEClass); } } } } if (m_RefreshQ.Count > 0) { ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadWork), null); } else { CancelRefresh(dwConnection); } } catch (Exception e) { Utils.Trace(e, "Unexpected error in Refresh"); throw ComUtils.CreateComException(e); } }