public void EncodeDecodeNetworkMessage()
        {
            var payload = new Dictionary <string, DataValue> {
                { "1", new DataValue(new Variant(5), StatusCodes.Good, DateTime.Now) },
                { "2", new DataValue(new Variant(0.5), StatusCodes.Good, DateTime.Now) },
                { "3", new DataValue("abcd") }
            };

            var message = new DataSetMessage {
                DataSetWriterId = "WriterId",
                MetaDataVersion = new ConfigurationVersionDataType {
                    MajorVersion = 1, MinorVersion = 1
                },
                SequenceNumber     = ++_currentSequenceNumber,
                Status             = StatusCodes.Good,
                Timestamp          = DateTime.UtcNow,
                MessageContentMask = (uint)(
                    JsonDataSetMessageContentMask.DataSetWriterId |
                    JsonDataSetMessageContentMask.SequenceNumber |
                    JsonDataSetMessageContentMask.MetaDataVersion |
                    JsonDataSetMessageContentMask.Timestamp |
                    JsonDataSetMessageContentMask.Status),
                Payload = new DataSet(payload)
                {
                    FieldContentMask = (uint)(DataSetFieldContentMask.StatusCode | DataSetFieldContentMask.SourceTimestamp)
                }
            };

            var networkMessage = new NetworkMessage {
                MessageId   = Guid.NewGuid().ToString(), // TODO
                MessageType = "ua-data",
                Messages    = new List <DataSetMessage>(),
                PublisherId = "PublisherId"
            };

            networkMessage.Messages.Add(message);
            networkMessage.MessageContentMask = (uint)(
                JsonNetworkMessageContentMask.PublisherId |
                JsonNetworkMessageContentMask.NetworkMessageHeader |
                JsonNetworkMessageContentMask.SingleDataSetMessage);

            byte[] buffer;
            string json;
            var    context = new ServiceMessageContext();

            using (var stream = new MemoryStream()) {
                using (var encoder = new JsonEncoderEx(stream, context)) {
                    networkMessage.Encode(encoder);
                }
                buffer = stream.ToArray();
                json   = buffer.ToBase16String();
            }

            using (var stream = new MemoryStream(buffer)) {
                using (var decoder = new JsonDecoderEx(stream, context)) {
                    var result = decoder.ReadEncodeable(null, typeof(NetworkMessage)) as NetworkMessage;
                    Assert.Equal(networkMessage, result);
                }
            }
        }
 /// <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);
         }
     }
 }
Esempio n. 3
0
        public void TD50XSample()
        {
            var bytes   = new byte[] { 0xF0, 0x41, 0x10, 0x00, 0x00, 0x00, 0x00, 0x07, 0x12, 0x00, 0x00, 0x00, 0x00, 0x58, 0x28, 0xF7 };
            var message = new MidiMessage(bytes);
            var parsed  = DataSetMessage.TryParse(message, ModuleIdentifier.TD50X.ModelIdLength, out var dataSetMessage);

            Assert.True(parsed);
            Assert.AreEqual(0, dataSetMessage.Address);
            Assert.AreEqual(1, dataSetMessage.Data.Length);
            Assert.AreEqual(0x58, dataSetMessage.Data[0]);
        }
        public void EncodeDecodeNetworkMessageFull()
        {
            var payload = new Dictionary <string, DataValue> {
                ["abcd"] = new DataValue(new Variant(1234), StatusCodes.Good, DateTime.Now, DateTime.UtcNow),
                ["http://microsoft.com"]      = new DataValue(new Variant(-222222222), StatusCodes.Bad, DateTime.MinValue, DateTime.Now),
                ["1111111111111111111111111"] = new DataValue(new Variant(false), StatusCodes.Bad, DateTime.UtcNow, DateTime.MinValue),
                ["@#$%^&*()_+~!@#$%^*(){}"]   = new DataValue(new Variant(new byte[] { 0, 2, 4, 6 }), StatusCodes.Good),
                ["1245"] = new DataValue(new Variant("hello"), StatusCodes.Bad, DateTime.Now, DateTime.MinValue),
                ["..."]  = new DataValue(new Variant(new Variant("imbricated")))
            };

            var message = new DataSetMessage {
                DataSetWriterId = "WriterId",
                MetaDataVersion = new ConfigurationVersionDataType {
                    MajorVersion = 1, MinorVersion = 1
                },
                SequenceNumber     = ++_currentSequenceNumber,
                Status             = StatusCodes.Good,
                Timestamp          = DateTime.UtcNow,
                Picoseconds        = 1234,
                MessageContentMask = (uint)(
                    JsonDataSetMessageContentMask.DataSetWriterId |
                    JsonDataSetMessageContentMask.SequenceNumber |
                    JsonDataSetMessageContentMask.MetaDataVersion |
                    JsonDataSetMessageContentMask.Timestamp |
                    JsonDataSetMessageContentMask.Status),
                Payload = new DataSet(payload, (uint)(
                                          DataSetFieldContentMask.StatusCode |
                                          DataSetFieldContentMask.SourceTimestamp |
                                          DataSetFieldContentMask.ServerTimestamp |
                                          DataSetFieldContentMask.SourcePicoSeconds |
                                          DataSetFieldContentMask.ServerPicoSeconds))
            };

            var networkMessage = new NetworkMessage {
                MessageId      = Guid.NewGuid().ToString(), // TODO
                MessageType    = "ua-data",
                Messages       = new List <DataSetMessage>(),
                PublisherId    = "PublisherId",
                DataSetClassId = "1234"
            };

            networkMessage.Messages.Add(message);
            networkMessage.MessageContentMask = (uint)(
                JsonNetworkMessageContentMask.PublisherId |
                JsonNetworkMessageContentMask.NetworkMessageHeader |
                JsonNetworkMessageContentMask.SingleDataSetMessage |
                JsonNetworkMessageContentMask.DataSetClassId);

            byte[] buffer;
            var    context = new ServiceMessageContext();

            using (var stream = new MemoryStream()) {
                using (var encoder = new JsonEncoderEx(stream, context)) {
                    networkMessage.Encode(encoder);
                }
                buffer = stream.ToArray();
            }

            ConvertToOpcUaUniversalTime(networkMessage);

            using (var stream = new MemoryStream(buffer)) {
                using (var decoder = new JsonDecoderEx(stream, context)) {
                    var result = decoder.ReadEncodeable(null, typeof(NetworkMessage)) as NetworkMessage;
                    Assert.Equal(networkMessage, result);
                }
            }
        }
        /// <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);
                }
            }
        }