/// <summary>
        /// Get the delegate for an operator
        /// </summary>
        /// <param name="opCode">Operation</param>
        /// <returns>The delegate</returns>
        public static RDXOpCode GetOperator(ContosoOpcNodeOpCode opCode)
        {
            switch (opCode)
            {
            case ContosoOpcNodeOpCode.Nop: return(Nop);

            case ContosoOpcNodeOpCode.Diff: return(Diff);

            case ContosoOpcNodeOpCode.Avg: return(Avg);

            case ContosoOpcNodeOpCode.Sum: return(Sum);

            case ContosoOpcNodeOpCode.Last: return(Last);

            case ContosoOpcNodeOpCode.Count: return(Count);

            case ContosoOpcNodeOpCode.Max: return(Max);

            case ContosoOpcNodeOpCode.Min: return(Min);

            case ContosoOpcNodeOpCode.Const: return(Const);

            case ContosoOpcNodeOpCode.SubMaxMin: return(SubMaxMin);

            case ContosoOpcNodeOpCode.Timespan: return(Timespan);

            default:
                break;
            }
            return(null);
        }
Beispiel #2
0
 /// <summary>
 /// Ctor for a Contoso OPC UA node, specifying alert related information.
 /// </summary>
 public ContosoOpcUaNode(
     string opcUaNodeId,
     string opcUaSymbolicName,
     List <ContosoPerformanceRelevance> opcUaNodeRelevance,
     ContosoOpcNodeOpCode opCode,
     string units,
     bool visible,
     double?constValue,
     double?minimum,
     double?maximum,
     List <ContosoAlertActionDefinition> minimumAlertActionDefinitions,
     List <ContosoAlertActionDefinition> maximumAlertActionDefinitions,
     ContosoPushPinCoordinates imagePushpin,
     string warning
     )
     : base(opcUaNodeId, opcUaSymbolicName)
 {
     Relevance           = opcUaNodeRelevance;
     OpCode              = opCode;
     Units               = units;
     Visible             = visible;
     ConstValue          = constValue;
     Minimum             = minimum;
     Maximum             = maximum;
     MinimumAlertActions = minimumAlertActionDefinitions;
     MaximumAlertActions = maximumAlertActionDefinitions;
     Last         = new ContosoDataItem();
     ImagePushpin = imagePushpin;
     WarningValue = warning;
 }
        /// <summary>
        /// Get the value of an operation for OPC UA server Node Id
        /// </summary>
        /// <param name="opCode">Operation to get the value</param>
        /// <param name="appUri">The OPC UA server application Uri</param>
        /// <param name="nodeId">The node id in the OPC UA server namespace</param>
        /// <returns>The value</returns>
        private double GetValue(ContosoOpcNodeOpCode opCode, string appUri, string nodeId)
        {
            double?value       = null;
            var    appUriIndex = _result.Dimension.IndexOf(appUri);
            var    nodeIdIndex = _result.Aggregate.Dimension.IndexOf(nodeId);

            if (appUriIndex >= 0 && nodeIdIndex >= 0)
            {
                if (opCode == ContosoOpcNodeOpCode.SubMaxMin)
                {
                    double?max = _result.Aggregate.Aggregate.Measures.TryGetPropertyMeasure <double?>(new int[] { appUriIndex, nodeIdIndex, (int)RDXOpcUaQueries.AggregateIndex.Max });
                    if (max == null)
                    {
                        value = 0.0;
                    }
                    else
                    {
                        value = max - _result.Aggregate.Aggregate.Measures.TryGetPropertyMeasure <double?>(new int[] { appUriIndex, nodeIdIndex, (int)RDXOpcUaQueries.AggregateIndex.Min });
                    }
                }
                else
                {
                    value = _result.Aggregate.Aggregate.Measures.TryGetPropertyMeasure <double?>(new int[] { appUriIndex, nodeIdIndex, RDXUtils.AggregatedOperatorIndex(opCode) });
                }
            }
            // The node/station is inactive or there were no events in the searchspan!
            if (value == null)
            {
                value = 0.0;
            }
            return((double)value);
        }
        /// <summary>
        /// Calls the delegate for an operator.
        /// </summary>
        /// <param name="opCode">Operation to execute</param>
        /// <param name="rdxQuery">Query info.</param>
        /// <param name="opcUaNode">Topology node.</param>
        public static Task CallOperator(ContosoOpcNodeOpCode opCode, RDXOeeKpiQuery rdxQuery, ContosoOpcUaNode opcUaNode)
        {
            RDXOpCode opCodeFunc = GetOperator(opCode);

            if (opCodeFunc == null)
            {
                return(Task.CompletedTask);
            }
            return(opCodeFunc(rdxQuery, opcUaNode));
        }
Beispiel #5
0
 /// <summary>
 /// Test if opcode requires a unique OPC UA Node Id.
 /// </summary>
 private static bool OpCodeRequiresOpcUaNode(ContosoOpcNodeOpCode opCode)
 {
     switch (opCode)
     {
     case ContosoOpcNodeOpCode.Const:
     case ContosoOpcNodeOpCode.Timespan:
     case ContosoOpcNodeOpCode.Nop:
         return(false);
     }
     return(true);
 }
 /// <summary>
 /// Test if operator can be aggregated by RDX
 /// </summary>
 /// <param name="opCode"></param>
 /// <returns>True if operator is aggregated</returns>
 public static bool IsAggregatedOperator(ContosoOpcNodeOpCode opCode)
 {
     switch (opCode)
     {
     case ContosoOpcNodeOpCode.Avg:
     case ContosoOpcNodeOpCode.Sum:
     case ContosoOpcNodeOpCode.Count:
     case ContosoOpcNodeOpCode.Max:
     case ContosoOpcNodeOpCode.Min:
     case ContosoOpcNodeOpCode.SubMaxMin:
         return(true);
     }
     return(false);
 }
        /// <summary>
        /// Return scale factor for opcode display in a time series.
        /// </summary>
        private static double OpCodeScaleFactor(ContosoOpcNodeOpCode opcode, TimeSpan interval, TimeSpan scaledInterval)
        {
            switch (opcode)
            {
            case ContosoOpcNodeOpCode.SubMaxMin:
            case ContosoOpcNodeOpCode.Sum:
                return(scaledInterval.TotalSeconds / interval.TotalSeconds);

            case ContosoOpcNodeOpCode.Max:
            case ContosoOpcNodeOpCode.Min:
            case ContosoOpcNodeOpCode.Avg:
                return(1.0);
            }
            throw new Exception("Invalid op code for operation");
        }
        /// <summary>
        /// Return the index of an operator result in a query measure.
        /// </summary>
        /// <param name="opCode">Operation</param>
        /// <returns>The index</returns>
        public static int AggregatedOperatorIndex(ContosoOpcNodeOpCode opCode)
        {
            switch (opCode)
            {
            case ContosoOpcNodeOpCode.Avg: return((int)RDXOpcUaQueries.AggregateIndex.Average);

            case ContosoOpcNodeOpCode.Sum: return((int)RDXOpcUaQueries.AggregateIndex.Sum);

            case ContosoOpcNodeOpCode.Count: return((int)RDXOpcUaQueries.AggregateIndex.Count);

            case ContosoOpcNodeOpCode.Max: return((int)RDXOpcUaQueries.AggregateIndex.Max);

            case ContosoOpcNodeOpCode.Min: return((int)RDXOpcUaQueries.AggregateIndex.Min);
            }
            return(0);
        }
Beispiel #9
0
        /// <summary>
        /// Adds an OPC UA Node to this OPC UA server topology node.
        /// </summary>
        public void AddOpcServerNode(
            string opcUaNodeId,
            string opcUaSymbolicName,
            List <ContosoPerformanceRelevance> opcUaNodeRelevance,
            ContosoOpcNodeOpCode opCode,
            string units,
            bool visible,
            double?constValue,
            double?minimum,
            double?maximum,
            List <ContosoAlertActionDefinition> minimumAlertActionDefinitions,
            List <ContosoAlertActionDefinition> maximumAlertActionDefinitions,
            ContosoPushPinCoordinates imagePushpin,
            string warning)
        {
            foreach (var node in NodeList)
            {
                if (OpCodeRequiresOpcUaNode(opCode) &&
                    node.NodeId == opcUaNodeId
                    )
                {
                    throw new Exception(string.Format("The OPC UA node with NodeId '{0}' and SymbolicName '{1}' does already exist. Please change.", opcUaNodeId, opcUaSymbolicName));
                }
            }
            ContosoOpcUaNode opcUaNodeObject = new ContosoOpcUaNode(
                opcUaNodeId,
                opcUaSymbolicName,
                opcUaNodeRelevance,
                opCode,
                units,
                visible,
                constValue,
                minimum,
                maximum,
                minimumAlertActionDefinitions,
                maximumAlertActionDefinitions,
                imagePushpin,
                warning);

            NodeList.Add(opcUaNodeObject);
        }
 /// <summary>
 /// Call the operator on a query and node.
 /// Gets value from cache if operation is supported,
 /// if not forwards the call to single query engine.
 /// </summary>
 /// <param name="opCode">Operation to get the value</param>
 /// <param name="rdxQuery">The query</param>
 /// <param name="opcUaNode">The Topology node </param>
 public async Task CallOperator(ContosoOpcNodeOpCode opCode, RDXOeeKpiQuery rdxQuery, ContosoOpcUaNode opcUaNode)
 {
     if (RDXUtils.IsAggregatedOperator(opCode) &&
         _task != null)
     {
         _result = await _task;
         if (_result != null)
         {
             double?value = GetValue(opCode, rdxQuery.AppUri, opcUaNode.NodeId);
             if (value != null)
             {
                 opcUaNode.Last.Value = (double)value;
                 opcUaNode.Last.Time  = rdxQuery.SearchSpan.To;
                 opcUaNode.UpdateRelevance(rdxQuery.TopologyNode);
             }
         }
         return;
     }
     // issue a single query if the operator can not be handled from aggregated values
     await RDXContosoOpCodes.CallOperator(opCode, rdxQuery, opcUaNode);
 }