public NodeHandle FindBranchNodeHandle(ISystemContext systemContext, NodeHandle initialHandle, CallMethodRequest methodToCall)
        {
            NodeHandle nodeHandle = initialHandle;

            if (IsAckConfirm(methodToCall.MethodId))
            {
                AlarmHolder holder = GetAlarmHolder(methodToCall.ObjectId);

                if (holder != null)
                {
                    if (holder.HasBranches())
                    {
                        byte[] eventId = GetEventIdFromAckConfirmMethod(methodToCall);

                        if (eventId != null)
                        {
                            BaseEventState state = holder.GetBranch(eventId);

                            if (state != null)
                            {
                                nodeHandle = new NodeHandle();

                                nodeHandle.NodeId    = methodToCall.ObjectId;
                                nodeHandle.Node      = state;
                                nodeHandle.Validated = true;
                            }
                        }
                    }
                }
            }

            return(nodeHandle);
        }
        private AlarmHolder GetAlarmHolder(NodeId node)
        {
            AlarmHolder alarmHolder = null;

            Type nodeIdType = node.Identifier.GetType();

            if (nodeIdType.Name == "String")
            {
                string unmodifiedName = node.Identifier.ToString();

                // This is bad, but I'm not sure why the NodeName is being attached with an underscore, it messes with this lookup.
                string name = unmodifiedName.Replace("Alarms_", "Alarms.");

                string mapName = name;
                if (name.EndsWith(AlarmDefines.TRIGGER_EXTENSION) || name.EndsWith(AlarmDefines.ALARM_EXTENSION))
                {
                    int lastDot = name.LastIndexOf(".");
                    mapName = name.Substring(0, lastDot);
                }

                if (m_alarms.ContainsKey(mapName))
                {
                    alarmHolder = m_alarms[mapName];
                }
            }

            return(alarmHolder);
        }
        public ServiceResult OnStartBranch(
            ISystemContext context,
            NodeState node,
            IList <object> inputArguments,
            IList <object> outputArguments)
        {
            // all arguments must be provided.
            UInt32 seconds;

            if (inputArguments.Count < 1)
            {
                return(StatusCodes.BadArgumentsMissing);
            }

            try
            {
                seconds = (UInt32)inputArguments[0];
            }
            catch
            {
                return(new ServiceResult(StatusCodes.BadInvalidArgument));
            }

            ServiceResult result = ServiceResult.Good;

            Dictionary <string, SourceController> sourceControllers = GetUnitAlarms(node);

            if (sourceControllers == null)
            {
                result = StatusCodes.BadNodeIdUnknown;
            }

            if (sourceControllers != null)
            {
                Utils.LogInfo("Starting up Branch for alarm group {0}", GetUnitFromNodeId(node.NodeId));

                lock (m_alarms)
                {
                    foreach (SourceController sourceController in sourceControllers.Values)
                    {
                        IList <IReference> references = new List <IReference>();
                        sourceController.Source.GetReferences(SystemContext, references, ReferenceTypes.HasCondition, false);
                        foreach (IReference reference in references)
                        {
                            string identifier = (string)reference.TargetId.ToString();
                            if (m_alarms.ContainsKey(identifier))
                            {
                                AlarmHolder holder = m_alarms[identifier];
                                holder.SetBranching(true);
                                holder.Start(seconds);
                                bool updated = holder.Controller.Update(SystemContext);
                                holder.Update(updated);
                            }
                        }
                    }
                }
            }

            return(result);
        }
        public ServiceResult OnWriteAlarmTrigger(
            ISystemContext context,
            NodeState node,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            ref object value,
            ref StatusCode statusCode,
            ref DateTime timestamp)
        {
            Dictionary <string, SourceController> sourceControllers = GetUnitAlarms(node);

            if (sourceControllers == null)
            {
                return(StatusCodes.BadNodeIdUnknown);
            }

            if (sourceControllers != null)
            {
                SourceController sourceController = GetSourceControllerFromNodeState(node, sourceControllers);

                if (sourceController == null)
                {
                    return(StatusCodes.BadNodeIdUnknown);
                }

                Utils.LogInfo("Manual Write {0} to {1}", value, node.NodeId);

                lock (m_alarms)
                {
                    sourceController.Source.Value = value;
                    Type valueType = value.GetType();
                    sourceController.Controller.ManualWrite(value);
                    IList <IReference> references = new List <IReference>();
                    sourceController.Source.GetReferences(SystemContext, references, ReferenceTypes.HasCondition, false);
                    foreach (IReference reference in references)
                    {
                        string identifier = (string)reference.TargetId.ToString();
                        if (m_alarms.ContainsKey(identifier))
                        {
                            AlarmHolder holder = m_alarms[identifier];
                            holder.Update(true);
                        }
                    }
                }
            }

            return(Opc.Ua.StatusCodes.Good);
        }
        private void DoSimulation(object state)
        {
            if (m_allowEntry)
            {
                m_allowEntry = false;

                lock (m_alarms)
                {
                    m_success++;
                    try
                    {
                        foreach (SourceController controller in m_triggerMap.Values)
                        {
                            bool updated = controller.Controller.Update(SystemContext);

                            IList <IReference> references = new List <IReference>();
                            controller.Source.GetReferences(SystemContext, references, ReferenceTypes.HasCondition, false);
                            foreach (IReference reference in references)
                            {
                                string identifier = (string)reference.TargetId.ToString();
                                if (m_alarms.ContainsKey(identifier))
                                {
                                    AlarmHolder holder = m_alarms[identifier];
                                    holder.Update(updated);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Utils.LogInfo(ex, "Alarm Loop Exception");
                    }
                }
                m_allowEntry = true;
            }
            else
            {
                if (m_success > 0)
                {
                    m_missed++;
                    Utils.LogInfo("Alarms: Missed Loop {1} Success {2}", m_missed, m_success);
                }
            }
        }
        public ServiceResult OnEnd(
            ISystemContext context,
            NodeState node,
            IList <object> inputArguments,
            IList <object> outputArguments)
        {
            ServiceResult result = ServiceResult.Good;

            Dictionary <string, SourceController> sourceControllers = GetUnitAlarms(node);

            if (sourceControllers == null)
            {
                result = StatusCodes.BadNodeIdUnknown;
            }

            if (sourceControllers != null)
            {
                Utils.LogInfo("Stopping alarm group {0}", GetUnitFromNodeId(node.NodeId));

                lock (m_alarms)
                {
                    foreach (SourceController sourceController in sourceControllers.Values)
                    {
                        IList <IReference> references = new List <IReference>();
                        sourceController.Source.GetReferences(SystemContext, references, ReferenceTypes.HasCondition, false);
                        foreach (IReference reference in references)
                        {
                            string identifier = (string)reference.TargetId.ToString();
                            if (m_alarms.ContainsKey(identifier))
                            {
                                AlarmHolder holder = m_alarms[identifier];
                                holder.ClearBranches();
                            }
                        }

                        sourceController.Controller.Stop();
                    }
                }
            }

            return(result);
        }