Exemplo n.º 1
0
        public void WriteDict(Dictionary <string, ushort> valueDict)
        {
            using (var session = Session.Create(_config, new ConfiguredEndpoint(null, _endpointDesc,
                                                                                EndpointConfiguration.Create(_config)), false, "", 60000, null, null).GetAwaiter().GetResult())
            {
                StatusCodeCollection     results = null;
                DiagnosticInfoCollection infos   = null;

                session.Write(null,
                              GetWriteValueCollection(valueDict),
                              out results, out infos);


                if (results.Any(sc => StatusCode.IsNotGood(sc)))
                {
                    var messageBuilder = new StringBuilder();

                    for (int i = 0; i < results.Count; i++)
                    {
                        if (StatusCode.IsNotGood(results[i]))
                        {
                            messageBuilder.AppendLine($"{valueDict.ElementAt(i).Key}: {StatusCodes.GetBrowseName(results[i].Code)}");
                        }
                    }

                    throw new KepServerWriteException(messageBuilder.ToString());
                }
            }
        }
Exemplo n.º 2
0
        public override DataValue Compute(IAggregationContext context, TimeSlice bucket, AggregateState state)
        {
            List <DataValue> l  = new List <DataValue>(bucket.Values);
            DataValue        dv = l.Count > 0 ? GetDataValue(l) : null;

            if (SteppedVariable && dv == null)
            {
                dv = bucket.LateBound.Value;
            }

            DataValue  retval = new DataValue();
            StatusCode code   = StatusCodes.BadNoData;

            if (dv != null)
            {
                code = StatusCode.IsNotGood(dv.StatusCode)
                    ? StatusCodes.UncertainDataSubNormal
                    : StatusCodes.Good;
                retval.SourceTimestamp = dv.SourceTimestamp;
                retval.Value           = dv.Value;
                code.AggregateBits     = AggregateBits.Raw;
                if (bucket.Incomplete)
                {
                    code.AggregateBits |= AggregateBits.Partial;
                }
            }
            else
            {
                retval.SourceTimestamp = bucket.From;
            }
            retval.StatusCode = code;
            return(retval);
        }
Exemplo n.º 3
0
        internal async Task <object[]> CallMethodAsync(UaItem item, object[] inputArguments)
        {
            var session = Session;

            if (session != null && session.Connected)
            {
                try
                {
                    var callRequest = new CallRequest {
                        MethodsToCall = { new CallMethodRequest {
                                              ObjectId = item.StartNodeId, MethodId = item.ResolvedNodeId, InputArguments = inputArguments.Select(a => new Variant(a)).ToArray()
                                          } }
                    };
                    var callResponse = await session.CallAsync(callRequest).ConfigureAwait(false);

                    for (int i = 0; i < callResponse.Results.Count; i++)
                    {
                        if (StatusCode.IsNotGood(callResponse.Results[i].StatusCode))
                        {
                            Trace.TraceError("Error calling method with MethodId {0} : {1}", callRequest.MethodsToCall[i].MethodId, callResponse.Results[i].StatusCode);
                        }
                    }
                    return(callResponse.Results[0].OutputArguments.Select(a => a.Value).ToArray());
                }
                catch (Exception ex)
                {
                    Trace.TraceError("Error calling method with MethodId {0} : {1}", item.ResolvedNodeId, ex.Message);
                }
            }
            else
            {
                Trace.TraceError("Error calling method with MethodId {0} : {1}", item.ResolvedNodeId, "Session is null or not connected");
            }
            return(null);
        }
Exemplo n.º 4
0
        internal async Task SetValueAsync(UaItem item, DataValue value)
        {
            item.CacheValue = value;
            NotifyPropertyChanged(item.DisplayName);
            var session = Session;

            if (session != null && session.Connected)
            {
                try
                {
                    var writeRequest = new WriteRequest {
                        NodesToWrite = { new WriteValue {
                                             NodeId = item.ResolvedNodeId, AttributeId = (uint)item.AttributeId, Value = value
                                         } }
                    };
                    var writeResponse = await session.WriteAsync(writeRequest).ConfigureAwait(false);

                    for (int i = 0; i < writeResponse.Results.Count; i++)
                    {
                        if (StatusCode.IsNotGood(writeResponse.Results[i]))
                        {
                            Trace.TraceError("Error writing value for NodeId {0} : {1}", writeRequest.NodesToWrite[i].NodeId, writeResponse.Results[i]);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError("Error writing value for NodeId {0} : {1}", item.ResolvedNodeId, ex.Message);
                }
            }
            else
            {
                Trace.TraceError("Error writing value for NodeId {0} : {1}", item.ResolvedNodeId, "Session is null or not connected");
            }
        }
Exemplo n.º 5
0
 protected override StatusCode ComputeStatus(IAggregationContext context, int numGood, int numBad, TimeSlice bucket)
 {
     StatusCode code = base.ComputeStatus(context, numGood, numBad, bucket);
     if (bucket.EarlyBound.Value == null || StatusCode.IsNotGood(bucket.EarlyBound.Value.StatusCode))
         code = StatusCodes.Uncertain;
     return code;
 }
 /// <summary>
 /// Produce network messages from the data set message model
 /// </summary>
 /// <param name="messages"></param>
 /// <param name="encoding"></param>
 /// <returns></returns>
 private IEnumerable <NetworkMessage> GetNetworkMessages(
     IEnumerable <DataSetMessageModel> messages,
     MessageEncoding encoding)
 {
     // TODO: Honor single message
     // TODO: Group by writer
     foreach (var message in messages)
     {
         if (message.WriterGroup?.MessageType
             .GetValueOrDefault(MessageEncoding.Json) == encoding)
         {
             var networkMessage = new NetworkMessage()
             {
                 MessageContentMask = message.WriterGroup
                                      .MessageSettings.NetworkMessageContentMask
                                      .ToStackType(message.WriterGroup?.MessageType),
                 PublisherId    = message.PublisherId,
                 DataSetClassId = message.Writer?.DataSet?
                                  .DataSetMetaData?.DataSetClassId.ToString(),
                 MessageId = message.SequenceNumber.ToString()
             };
             var notificationQueues = message.Notifications.GroupBy(m => m.NodeId)
                                      .Select(c => new Queue <MonitoredItemNotificationModel>(c.ToArray())).ToArray();
             while (notificationQueues.Where(q => q.Any()).Any())
             {
                 var payload = notificationQueues
                               .Select(q => q.Any() ? q.Dequeue() : null)
                               .Where(s => s != null)
                               .ToDictionary(
                     s => s.NodeId.ToExpandedNodeId(message.ServiceMessageContext.NamespaceUris)
                     .AsString(message.ServiceMessageContext),
                     s => s.Value);
                 var dataSetMessage = new DataSetMessage()
                 {
                     DataSetWriterId = message.Writer.DataSetWriterId,
                     MetaDataVersion = new ConfigurationVersionDataType {
                         MajorVersion = message.Writer?.DataSet?.DataSetMetaData?
                                        .ConfigurationVersion?.MajorVersion ?? 1,
                         MinorVersion = message.Writer?.DataSet?.DataSetMetaData?
                                        .ConfigurationVersion?.MinorVersion ?? 0
                     },
                     MessageContentMask = (message.Writer?.MessageSettings?.DataSetMessageContentMask)
                                          .ToStackType(message.WriterGroup?.MessageType),
                     Timestamp      = message.TimeStamp ?? DateTime.UtcNow,
                     SequenceNumber = message.SequenceNumber,
                     Status         = payload.Values.Any(s => StatusCode.IsNotGood(s.StatusCode)) ?
                                      StatusCodes.Bad : StatusCodes.Good,
                     Payload = new DataSet(payload, (uint)message.Writer?.DataSetFieldContentMask.ToStackType())
                 };
                 networkMessage.Messages.Add(dataSetMessage);
             }
             yield return(networkMessage);
         }
     }
 }
        /// <summary>
        /// Calculates the DurationInStateZero and DurationInStateNonZero aggregates for the timeslice.
        /// </summary>
        protected DataValue ComputeDurationInState(TimeSlice slice, bool isNonZero)
        {
            // get the values in the slice.
            List <DataValue> values = GetValuesWithSimpleBounds(slice);

            // check for empty slice.
            if (values == null)
            {
                return(GetNoDataValue(slice));
            }

            // get the regions.
            List <SubRegion> regions = GetRegionsInValueSet(values, false, true);

            double duration = 0;

            for (int ii = 0; ii < regions.Count; ii++)
            {
                if (StatusCode.IsNotGood(regions[ii].StatusCode))
                {
                    continue;
                }

                if (isNonZero)
                {
                    if (regions[ii].StartValue != 0)
                    {
                        duration += regions[ii].Duration;
                    }
                }
                else
                {
                    if (regions[ii].StartValue == 0)
                    {
                        duration += regions[ii].Duration;
                    }
                }
            }

            // set the timestamp and status.
            DataValue value = new DataValue();

            value.WrappedValue    = new Variant(duration, TypeInfo.Scalars.Double);
            value.SourceTimestamp = GetTimestamp(slice);
            value.ServerTimestamp = GetTimestamp(slice);
            value.StatusCode      = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);
            value.StatusCode      = GetTimeBasedStatusCode(regions, value.StatusCode);

            // return result.
            return(value);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Unpack with a default value
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataValue"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static T GetValueOrDefault <T>(this DataValue dataValue,
                                              T defaultValue = default)
        {
            if (dataValue == null)
            {
                return(defaultValue);
            }
            if (StatusCode.IsNotGood(dataValue.StatusCode))
            {
                return(defaultValue);
            }
            var value = dataValue.Value;

            while (typeof(T).IsEnum)
            {
                try {
                    return((T)Enum.ToObject(typeof(T), value));
                }
                catch {
                    break;
                }
            }
            while (!typeof(T).IsInstanceOfType(value))
            {
                try {
                    return(value.As <T>());
                }
                catch {
                    break;
                }
            }
            try {
                return((T)value);
            }
            catch {
                return(defaultValue);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Checks if the value is good according to the configuration rules.
        /// </summary>
        /// <param name="value">The value to test.</param>
        /// <returns>True if the value is good.</returns>
        public bool IsGood(DataValue value)
        {
            if (value == null)
            {
                return(false);
            }

            if (_configuration.TreatUncertainAsBad)
            {
                if (StatusCode.IsNotGood(value.StatusCode))
                {
                    return(false);
                }
            }
            else
            {
                if (StatusCode.IsBad(value.StatusCode))
                {
                    return(false);
                }
            }

            return(true);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Calculates the StdDev, Variance, StdDev2 and Variance2 aggregates for the timeslice.
        /// </summary>
        protected DataValue ComputeTimeAverage(TimeSlice slice, bool useSimpleBounds, int valueType)
        {
            // get the values in the slice.
            List <DataValue> values = null;

            if (useSimpleBounds)
            {
                values = GetValuesWithSimpleBounds(slice);
            }
            else
            {
                values = GetValuesWithInterpolatedBounds(slice);
            }

            // check for empty slice.
            if (values == null || values.Count == 0)
            {
                return(GetNoDataValue(slice));
            }

            // get the regions.
            List <SubRegion> regions = GetRegionsInValueSet(values, !useSimpleBounds, Stepped);

            double total                = 0;
            double totalDuration        = 0;
            bool   nonGoodRegionsExists = false;

            for (int ii = 0; ii < regions.Count; ii++)
            {
                double duration = regions[ii].Duration / 1000.0;

                if (StatusCode.IsNotBad(regions[ii].StatusCode))
                {
                    total         += (regions[ii].StartValue + regions[ii].EndValue) * duration / 2;
                    totalDuration += duration;
                }

                if (StatusCode.IsNotGood(regions[ii].StatusCode))
                {
                    nonGoodRegionsExists = true;
                }
            }

            // check if no good data.
            if (totalDuration == 0)
            {
                return(GetNoDataValue(slice));
            }

            // select the result.
            double result = 0;

            switch (valueType)
            {
            case 1: { result = total / totalDuration; break; }

            case 2: { result = total; break; }
            }

            // set the timestamp and status.
            DataValue value = new DataValue();

            value.WrappedValue    = new Variant(result, TypeInfo.Scalars.Double);
            value.SourceTimestamp = GetTimestamp(slice);
            value.ServerTimestamp = GetTimestamp(slice);

            if (useSimpleBounds)
            {
                value.StatusCode = GetTimeBasedStatusCode(regions, value.StatusCode);
            }
            else
            {
                value.StatusCode = StatusCodes.Good;

                if (nonGoodRegionsExists)
                {
                    value.StatusCode = StatusCodes.UncertainDataSubNormal;
                }
            }

            value.StatusCode = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);

            // return result.
            return(value);
        }
        /// <summary>
        /// Calculates the Delta2 aggregate for the timeslice.
        /// </summary>
        protected DataValue ComputeDelta2(TimeSlice slice)
        {
            // get the values in the slice.
            List <DataValue> values = GetValuesWithSimpleBounds(slice);

            // check for empty slice.
            if (values == null || values.Count == 0)
            {
                return(GetNoDataValue(slice));
            }

            DataValue start = values[0];
            DataValue end   = values[values.Count - 1];

            // check for bad bounds.
            if (StatusCode.IsBad(start.StatusCode) || StatusCode.IsBad(end.StatusCode))
            {
                return(GetNoDataValue(slice));
            }

            // convert to doubles.
            double   startValue   = 0;
            TypeInfo originalType = null;

            try
            {
                startValue   = CastToDouble(start);
                originalType = start.WrappedValue.TypeInfo;
            }
            catch (Exception)
            {
                startValue = Double.NaN;
            }

            double endValue = 0;

            try
            {
                endValue = CastToDouble(end);
            }
            catch (Exception)
            {
                endValue = Double.NaN;
            }

            // check for bad bounds.
            if (Double.IsNaN(startValue) || Double.IsNaN(endValue))
            {
                return(GetNoDataValue(slice));
            }

            DataValue value = new DataValue();

            value.SourceTimestamp = GetTimestamp(slice);
            value.ServerTimestamp = GetTimestamp(slice);

            if (StatusCode.IsNotGood(start.StatusCode) || StatusCode.IsNotGood(end.StatusCode))
            {
                value.StatusCode = StatusCodes.UncertainDataSubNormal;
            }

            value.StatusCode = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);

            // calculate delta.
            double delta = endValue - startValue;

            if (originalType != null && originalType.BuiltInType != BuiltInType.Double)
            {
                object delta2 = TypeInfo.Cast(delta, TypeInfo.Scalars.Double, originalType.BuiltInType);
                value.WrappedValue = new Variant(delta2, originalType);
            }
            else
            {
                value.WrappedValue = new Variant(delta, TypeInfo.Scalars.Double);
            }

            // return result.
            return(value);
        }
        /// <summary>
        /// Produce network messages from the data set message model
        /// </summary>
        /// <param name="messages"></param>
        /// <param name="encoding"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        private IEnumerable <NetworkMessage> GetNetworkMessages(
            IEnumerable <DataSetMessageModel> messages, MessageEncoding encoding,
            IServiceMessageContext context)
        {
            if (context?.NamespaceUris == null)
            {
                // Declare all notifications in messages as dropped.
                int totalNotifications = messages.Sum(m => m?.Notifications?.Count() ?? 0);
                NotificationsDroppedCount += (uint)totalNotifications;
                _logger.Warning("Namespace is empty, dropped {totalNotifications} values", totalNotifications);
                yield break;
            }

            // TODO: Honor single message
            // TODO: Group by writer
            foreach (var message in messages)
            {
                if (message.WriterGroup?.MessageType
                    .GetValueOrDefault(MessageEncoding.Json) == encoding)
                {
                    var networkMessage = new NetworkMessage()
                    {
                        MessageContentMask = message.WriterGroup
                                             .MessageSettings.NetworkMessageContentMask
                                             .ToStackType(message.WriterGroup?.MessageType),
                        PublisherId    = message.PublisherId,
                        DataSetClassId = message.Writer?.DataSet?
                                         .DataSetMetaData?.DataSetClassId.ToString(),
                        DataSetWriterGroup = message.WriterGroup.WriterGroupId,
                        MessageId          = message.SequenceNumber.ToString()
                    };
                    var notificationQueues = message.Notifications
                                             .GroupBy(m => !string.IsNullOrEmpty(m.Id) ?
                                                      m.Id :
                                                      !string.IsNullOrEmpty(m.DisplayName) ?
                                                      m.DisplayName :
                                                      m.NodeId)
                                             .Select(c => new Queue <MonitoredItemNotificationModel>(c.ToArray()))
                                             .ToArray();

                    while (notificationQueues.Any(q => q.Any()))
                    {
                        var payload = notificationQueues
                                      .Select(q => q.Any() ? q.Dequeue() : null)
                                      .Where(s => s != null)
                                      .ToDictionary(
                            //  Identifier to show for notification in payload of IoT Hub method
                            //  Prio 1: Id = DataSetFieldId - if already configured
                            //  Prio 2: Id = DisplayName - if already configured
                            //  Prio 3: NodeId as configured
                            s => !string.IsNullOrEmpty(s.Id) ?
                            s.Id :
                            !string.IsNullOrEmpty(s.DisplayName) ?
                            s.DisplayName :
                            s.NodeId,
                            s => s.Value);

                        var dataSetMessage = new DataSetMessage()
                        {
                            DataSetWriterId = message.Writer.DataSetWriterId,
                            MetaDataVersion = new ConfigurationVersionDataType {
                                MajorVersion = message.Writer?.DataSet?.DataSetMetaData?
                                               .ConfigurationVersion?.MajorVersion ?? 1,
                                MinorVersion = message.Writer?.DataSet?.DataSetMetaData?
                                               .ConfigurationVersion?.MinorVersion ?? 0
                            },
                            MessageContentMask = (message.Writer?.MessageSettings?.DataSetMessageContentMask)
                                                 .ToStackType(message.WriterGroup?.MessageType),
                            Timestamp      = message.TimeStamp ?? DateTime.UtcNow,
                            SequenceNumber = message.SequenceNumber,
                            Status         = payload.Values.Any(s => StatusCode.IsNotGood(s.StatusCode)) ?
                                             StatusCodes.Bad : StatusCodes.Good,
                            Payload = new DataSet(payload, (uint)message.Writer?.DataSetFieldContentMask.ToStackType())
                        };
                        networkMessage.Messages.Add(dataSetMessage);
                    }
                    yield return(networkMessage);
                }
            }
        }