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); } } }
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); } } }