/// <summary> /// Called during incoming event processing and as a result of a client-initiated Refresh. /// Forwards to each server instance for further processing. /// </summary> /// <param name="Source"></param> /// <param name="Condition"></param> /// <param name="cond"></param> public void NotifyClients(string Source, string Condition, OPCCondition cond) { OnEventClass OEClass = new OnEventClass(Source, Condition, cond); foreach (ComAeProxy s in m_EvServerSet) { s.ProcessNewEvent(OEClass); } }
/// <summary> /// If the event type is CONDITION_EVENT then update any existing record of the condition and adjust /// state and change mask. /// </summary> /// <param name="EventNotification"></param> /// <param name="areas"></param> public void ProcessEventNotificationList(EventNotification EventNotification, string[] areas) { SourceMap sourceMap = SourceMap.TheSourceMap; try { lock (sourceMap) { OPCCondition cond; if (EventNotification.EventType == OpcRcw.Ae.Constants.CONDITION_EVENT) { ConditionMap conditionMap; if (sourceMap.TryGetValue(EventNotification.SourceID, out conditionMap) == false) { conditionMap = new ConditionMap(); sourceMap.Add(EventNotification.SourceID, conditionMap); } if (conditionMap.TryGetValue(EventNotification.ConditionName, out cond) == false) { cond = new OPCCondition(); cond.EventType = EventNotification.EventType; conditionMap.Add(EventNotification.ConditionName, cond); } ProcessCondition(EventNotification, areas, cond); // When the condition has transitioned to Acked (if ack required) and inactive or disabled // then remove it from the condition source/condition database if ((!cond.IsActive() || !cond.IsEnabled()) && (cond.IsAcked() || !cond.AckRequired)) conditionMap.Remove(EventNotification.ConditionName); } else // a tracking or simple event { cond = new OPCCondition(); cond.EventType = EventNotification.EventType; ProcessCondition(EventNotification, areas, cond); } } } catch (Exception e) { Utils.Trace(e, "Unexpected error in ProcessEventNotificationList"); } }
/// <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); }