public void Test_WriteSingleEncodeableWithName() { var expected = "{\"bar_1\":{\"Foo\":\"bar_1\"}}"; TestContext.Out.WriteLine("Expected:"); _ = PrettifyAndValidateJson(expected); using (var encodeable = new FooBarEncodeable()) { using (var encoder = new JsonEncoder(Context, true, false)) { encoder.WriteEncodeable(encodeable.Foo, encodeable, typeof(FooBarEncodeable)); var encoded = encoder.CloseAndReturnText(); TestContext.Out.WriteLine("Encoded:"); TestContext.Out.WriteLine(encoded); TestContext.Out.WriteLine("Formatted Encoded:"); _ = PrettifyAndValidateJson(encoded); Assert.That(encoded, Is.EqualTo(expected)); } } }
public void Test_WriteMultipleEncodeablesWithFieldNames() { var expected = "{\"bar_1\":{\"Foo\":\"bar_1\"},\"bar_2\":{\"Foo\":\"bar_2\"},\"bar_3\":{\"Foo\":\"bar_3\"}}"; TestContext.Out.WriteLine("Expected:"); _ = PrettifyAndValidateJson(expected); var encodeables = new List <FooBarEncodeable> { new FooBarEncodeable(), new FooBarEncodeable(), new FooBarEncodeable() }; try { var encoder = new JsonEncoder(Context, true, null, false); foreach (var encodeable in encodeables) { encoder.WriteEncodeable(encodeable.Foo, encodeable, typeof(FooBarEncodeable)); } var encoded = encoder.CloseAndReturnText(); TestContext.Out.WriteLine("Encoded:"); TestContext.Out.WriteLine(encoded); TestContext.Out.WriteLine("Formatted Encoded:"); _ = PrettifyAndValidateJson(encoded); Assert.That(encoded, Is.EqualTo(expected)); } finally { encodeables.ForEach(e => e.Dispose()); } }
public void Test_WriteMultipleEncodeablesWithoutFieldNames(bool topLevelIsArray, string expected) { TestContext.Out.WriteLine("Expected:"); _ = PrettifyAndValidateJson(expected); var encodeables = new List <FooBarEncodeable> { new FooBarEncodeable(), new FooBarEncodeable(), new FooBarEncodeable() }; try { var encoder = new JsonEncoder(Context, true, null, topLevelIsArray); foreach (var encodeable in encodeables) { encoder.WriteEncodeable(null, encodeable, typeof(FooBarEncodeable)); } var encoded = encoder.CloseAndReturnText(); TestContext.Out.WriteLine("Encoded:"); TestContext.Out.WriteLine(encoded); TestContext.Out.WriteLine("Formatted Encoded:"); _ = PrettifyAndValidateJson(encoded); Assert.That(encoded, Is.EqualTo(expected)); } finally { encodeables.ForEach(e => e.Dispose()); } }
private void RunWriteEncodeableArrayTest(string fieldName, List <FooBarEncodeable> encodeables, string expected, bool topLevelIsArray, bool noExpectedValidation = false) { try { if (!noExpectedValidation) { TestContext.Out.WriteLine("Expected:"); _ = PrettifyAndValidateJson(expected); } var encoder = new JsonEncoder(Context, true, null, topLevelIsArray); encoder.WriteEncodeableArray( fieldName, encodeables.Cast <IEncodeable>().ToList(), typeof(FooBarEncodeable)); var encoded = encoder.CloseAndReturnText(); TestContext.Out.WriteLine("Encoded:"); TestContext.Out.WriteLine(encoded); TestContext.Out.WriteLine("Formatted Encoded:"); _ = PrettifyAndValidateJson(encoded); Assert.That(encoded, Is.EqualTo(expected)); } finally { encodeables.ForEach(e => e.Dispose()); } }
private void PrintValueAsJson(string name, DataValue value) { var jsonEncoder = new JsonEncoder(m_session.MessageContext, JsonReversible); jsonEncoder.WriteDataValue(name, value); var textbuffer = jsonEncoder.CloseAndReturnText(); // prettify using (var stringWriter = new StringWriter()) { try { using (var stringReader = new StringReader(textbuffer)) { var jsonReader = new JsonTextReader(stringReader); var jsonWriter = new JsonTextWriter(stringWriter) { Formatting = Formatting.Indented, Culture = CultureInfo.InvariantCulture }; jsonWriter.WriteToken(jsonReader); Console.WriteLine(stringWriter.ToString()); } } catch (Exception ex) { Console.WriteLine("Failed to format the JSON output:", ex.Message); Console.WriteLine(textbuffer); Console.WriteLine(stringWriter.ToString()); ExitCode = ExitCode.ErrorJSONDecode; throw; } } }
public void TestFieldValueEscapedArray(string fieldname, string foo, string expected) { TestContext.Out.WriteLine("Expected:"); _ = PrettifyAndValidateJson(expected); using (var encodeable = new FooBarEncodeable(fieldname, foo)) { var list = new List <IEncodeable>() { encodeable, encodeable }; using (var encoder = new JsonEncoder(Context, true)) { encoder.WriteEncodeableArray(encodeable.FieldName, list, typeof(FooBarEncodeable)); var encoded = encoder.CloseAndReturnText(); TestContext.Out.WriteLine("Encoded:"); TestContext.Out.WriteLine(encoded); TestContext.Out.WriteLine("Formatted Encoded:"); _ = PrettifyAndValidateJson(encoded); Assert.That(encoded, Is.EqualTo(expected)); } } }
/// <summary> /// Encodes the object and returns the resulting byte array. /// </summary> /// <returns></returns> public override byte[] Encode() { ServiceMessageContext messageContext = new ServiceMessageContext(); messageContext.NamespaceUris = ServiceMessageContext.GlobalContext.NamespaceUris; messageContext.ServerUris = ServiceMessageContext.GlobalContext.ServerUris; bool topLevelIsArray = !HasNetworkMessageHeader && !HasSingleDataSetMessage; using (JsonEncoder encoder = new JsonEncoder(messageContext, false, null, topLevelIsArray)) { // handle no header if (HasNetworkMessageHeader) { Encode(encoder); } else if (DataSetMessages != null && DataSetMessages.Count > 0) { if (HasSingleDataSetMessage) { // encode single dataset message JsonDataSetMessage jsonDataSetMessage = DataSetMessages[0] as JsonDataSetMessage; if (jsonDataSetMessage != null) { if (!jsonDataSetMessage.HasDataSetMessageHeader) { // (UA Specs:) If the NetworkMessageHeader and the DataSetMessageHeader bits are not set // and SingleDataSetMessage bit is set, the NetworkMessage // is a JSON object containing the set of name/value pairs defined for a single DataSet. jsonDataSetMessage.EncodePayload(encoder, false); } else { // If the SingleDataSetMessage bit of the NetworkMessageContentMask is set, // the content of the Messages field is a JSON object containing a single DataSetMessage. jsonDataSetMessage.Encode(encoder); } } } else { // If the NetworkMessageHeader bit of the NetworkMessageContentMask is not set, // the NetworkMessage is the contents of the Messages field (e.g. a JSON array of DataSetMessages). foreach (var message in DataSetMessages) { JsonDataSetMessage jsonDataSetMessage = message as JsonDataSetMessage; if (jsonDataSetMessage != null) { jsonDataSetMessage.Encode(encoder); } } } } byte[] bytes = System.Text.Encoding.ASCII.GetBytes(encoder.CloseAndReturnText()); return(bytes); } }
public void JsonEncoder_Constructor_Streamwriter_Reflection2() { using (var jsonEncoder = new JsonEncoder(m_context, false, false, m_memoryStream, true, StreamSize)) { TestEncoding(jsonEncoder); var result = jsonEncoder.CloseAndReturnText(); } }
public void JsonEncoder_Constructor2() { using (var jsonEncoder = new JsonEncoder(m_context, false)) { TestEncoding(jsonEncoder); _ = jsonEncoder.CloseAndReturnText(); } }
private void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e) { try { MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification; if (notification == null) { return; } DataValue value = notification.Value as DataValue; if (value == null) { return; } using (var encoder = new JsonEncoder(monitoredItem.Subscription.Session.MessageContext, false)) { string applicationURI = monitoredItem.Subscription.Session.Endpoint.Server.ApplicationUri; encoder.WriteString("ApplicationUri", applicationURI); encoder.WriteString("DisplayName", monitoredItem.DisplayName); encoder.WriteNodeId("MonitoredItem", monitoredItem.ResolvedNodeId); // suppress output of server timestamp in json by setting it to minvalue value.ServerTimestamp = DateTime.MinValue; encoder.WriteDataValue("Value", value); string json = encoder.CloseAndReturnText(); var properties = new Dictionary <string, string>(); properties.Add("content-type", "application/opcua+uajson"); properties.Add("deviceName", Id); if (SharedAccessKey != null) { properties.Add("source", "mapping"); properties.Add("deviceKey", SharedAccessKey); } try { Module.Publish(new Message(json, properties)); } catch (Exception ex) { Console.WriteLine("Opc.Ua.Client.SampleModule: Failed to publish message, dropping..."); Console.WriteLine(ex.ToString()); } } } catch (Exception exception) { Console.WriteLine("Opc.Ua.Client.SampleModule: Error processing monitored item notification."); Console.WriteLine(exception.ToString()); } }
public void Constructor_Default(bool useReversible, bool topLevelIsArray) { var context = new ServiceMessageContext(); var jsonEncoder = new JsonEncoder(context, useReversible, topLevelIsArray); TestEncoding(jsonEncoder, topLevelIsArray); var result = jsonEncoder.CloseAndReturnText(); Assert.IsNotEmpty(result); Assert.NotNull(result); TestContext.Out.WriteLine("Result:"); _ = PrettifyAndValidateJson(result); }
/// <summary> /// The notification that the data for a monitored item has changed on an OPC UA server /// </summary> public static void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args) { try { if (args.NotificationValue == null || monitoredItem.Subscription.Session == null) { return; } MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification; if (notification == null) { return; } DataValue value = notification.Value as DataValue; if (value == null) { return; } JsonEncoder encoder = new JsonEncoder(monitoredItem.Subscription.Session.MessageContext, false); string applicationURI = monitoredItem.Subscription.Session.Endpoint.Server.ApplicationUri; encoder.WriteString("ApplicationUri", (applicationURI + (string.IsNullOrEmpty(ShopfloorDomain) ? "" : $":{ShopfloorDomain}"))); encoder.WriteString("DisplayName", monitoredItem.DisplayName); // write NodeId as ns=x;i=y NodeId nodeId = monitoredItem.ResolvedNodeId; encoder.WriteString("NodeId", new NodeId(nodeId.Identifier, nodeId.NamespaceIndex).ToString()); // suppress output of server timestamp in json by setting it to minvalue value.ServerTimestamp = DateTime.MinValue; encoder.WriteDataValue("Value", value); string json = encoder.CloseAndReturnText(); // add message to fifo send queue Trace(Utils.TraceMasks.OperationDetail, "Enqueue a new message:"); Trace(Utils.TraceMasks.OperationDetail, " ApplicationUri: " + (applicationURI + (string.IsNullOrEmpty(ShopfloorDomain) ? "" : $":{ShopfloorDomain}"))); Trace(Utils.TraceMasks.OperationDetail, $" DisplayName: {monitoredItem.DisplayName}"); Trace(Utils.TraceMasks.OperationDetail, $" Value: {value}"); Program.IotHubMessaging.Enqueue(json); } catch (Exception e) { Trace(e, "Error processing monitored item notification"); } }
/// <summary> /// The notification that the data for a monitored item has changed on an OPC UA server. /// </summary> public void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args) { try { if (args == null || args.NotificationValue == null || monitoredItem == null || monitoredItem.Subscription == null || monitoredItem.Subscription.Session == null) { return; } MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification; if (notification == null) { return; } DataValue value = notification.Value as DataValue; if (value == null) { return; } JsonEncoder encoder = new JsonEncoder(monitoredItem.Subscription.Session.MessageContext, false); string applicationURI = monitoredItem.Subscription.Session.Endpoint.Server.ApplicationUri; encoder.WriteString("ApplicationUri", (applicationURI + (string.IsNullOrEmpty(ShopfloorDomain) ? "" : $":{ShopfloorDomain}"))); encoder.WriteString("DisplayName", monitoredItem.DisplayName); // use the node Id as configured, to also have the namespace URI in case of a ExpandedNodeId. encoder.WriteString("NodeId", ConfigNodeId); // suppress output of server timestamp in json by setting it to minvalue value.ServerTimestamp = DateTime.MinValue; encoder.WriteDataValue("Value", value); string json = encoder.CloseAndReturnText(); // add message to fifo send queue Trace(Utils.TraceMasks.OperationDetail, $"Enqueue a new message from subscription {monitoredItem.Subscription.Id} (publishing interval: {monitoredItem.Subscription.PublishingInterval}, sampling interval: {monitoredItem.SamplingInterval}):"); Trace(Utils.TraceMasks.OperationDetail, " ApplicationUri: " + (applicationURI + (string.IsNullOrEmpty(ShopfloorDomain) ? "" : $":{ShopfloorDomain}"))); Trace(Utils.TraceMasks.OperationDetail, $" DisplayName: {monitoredItem.DisplayName}"); Trace(Utils.TraceMasks.OperationDetail, $" Value: {value}"); IotHubCommunication.Enqueue(json); } catch (Exception e) { Trace(e, "Error processing monitored item notification"); } }
public void WhenServerUrisAreLessThanNamespaces_ShouldNotThrowAndMustReturnCorrectServerUris() { //arrange UInt32 uriVersion = 1234; var namespaceTable = new NamespaceTable(new List <string> { Namespaces.OpcUa, "http://bar", "http://foo" }); var expectedServerUri = "http://foobar"; var serverUris = new StringTable(new[] { Namespaces.OpcUa, expectedServerUri }); var context = new ServiceMessageContext { NamespaceUris = namespaceTable, ServerUris = serverUris }; string result; using (var jsonEncoder = new JsonEncoder(context, true)) { var envelope = new SessionLessServiceMessage { UriVersion = uriVersion, NamespaceUris = context.NamespaceUris, ServerUris = context.ServerUris, Message = null }; //act and validate it does not throw Assert.DoesNotThrow(() => { envelope.Encode(jsonEncoder); }); result = jsonEncoder.CloseAndReturnText(); } var jObject = JObject.Parse(result); Assert.IsNotNull(jObject); UInt32 version = jObject["UriVersion"].ToObject <UInt32>(); Assert.AreEqual(uriVersion, version); var serverUrisToken = jObject["ServerUris"]; Assert.IsNotNull(serverUrisToken); var serverUrisEncoded = serverUrisToken.ToObject <string[]>(); Assert.IsNotNull(serverUrisEncoded); Assert.AreEqual(1, serverUrisEncoded.Length); Assert.Contains(expectedServerUri, serverUrisEncoded); }
/// <summary> /// The notification that the data for a monitored item has changed on an OPC UA server /// </summary> public static void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e) { try { if (e.NotificationValue == null || monitoredItem.Subscription.Session == null) { return; } MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification; if (notification == null) { return; } DataValue value = notification.Value as DataValue; if (value == null) { return; } JsonEncoder encoder = new JsonEncoder(monitoredItem.Subscription.Session.MessageContext, false); string applicationURI = monitoredItem.Subscription.Session.Endpoint.Server.ApplicationUri; encoder.WriteString("ApplicationUri", applicationURI); encoder.WriteString("DisplayName", monitoredItem.DisplayName); // write NodeId as ns=x;i=y NodeId nodeId = monitoredItem.ResolvedNodeId; encoder.WriteString("NodeId", new NodeId(nodeId.Identifier, nodeId.NamespaceIndex).ToString()); // suppress output of server timestamp in json by setting it to minvalue value.ServerTimestamp = DateTime.MinValue; encoder.WriteDataValue("Value", value); string json = encoder.CloseAndReturnText(); // add message to fifo send queue m_sendQueue.Enqueue(json); } catch (Exception exception) { Trace("Error processing monitored item notification: " + exception.ToString()); } }
public void Constructor_Stream() { var context = new ServiceMessageContext(); var memoryStream = new MemoryStream(); using (var jsonEncoder = new JsonEncoder(context, true, false, memoryStream, true)) { TestEncoding(jsonEncoder); } var result1 = Encoding.UTF8.GetString(memoryStream.ToArray()); Assert.IsNotEmpty(result1); TestContext.Out.WriteLine("Result1:"); _ = PrettifyAndValidateJson(result1); // recycle the StreamWriter, ensure the result is equal using (var jsonEncoder = new JsonEncoder(context, true, false, memoryStream, true)) { TestEncoding(jsonEncoder); } var result2 = Encoding.UTF8.GetString(memoryStream.ToArray()); Assert.IsNotEmpty(result2); TestContext.Out.WriteLine("Result2:"); _ = PrettifyAndValidateJson(result2); Assert.AreEqual(result1, result2); // recycle the StreamWriter, ensure the result is equal, // use reflection to return result in external stream using (var jsonEncoder = new JsonEncoder(context, true, false, memoryStream, false)) { TestEncoding(jsonEncoder); var result3 = jsonEncoder.CloseAndReturnText(); Assert.IsNotEmpty(result3); TestContext.Out.WriteLine("Result3:"); _ = PrettifyAndValidateJson(result3); Assert.AreEqual(result1, result3); } // ensure the memory stream was closed Assert.Throws <ArgumentException>(() => _ = new StreamWriter(memoryStream)); }
public void Test_WriteSingleEncodeableWithoutName(bool topLevelIsArray, string expected) { TestContext.Out.WriteLine("Expected:"); _ = PrettifyAndValidateJson(expected); using (var encodeable = new FooBarEncodeable()) { var encoder = new JsonEncoder(Context, true, null, topLevelIsArray); encoder.WriteEncodeable(null, encodeable, typeof(FooBarEncodeable)); var encoded = encoder.CloseAndReturnText(); TestContext.Out.WriteLine("Encoded:"); TestContext.Out.WriteLine(encoded); TestContext.Out.WriteLine("Formatted Encoded:"); _ = PrettifyAndValidateJson(encoded); Assert.That(encoded, Is.EqualTo(expected)); } }
public void TestFieldValueEscapedVariant(string fieldname, string foo, string expected) { TestContext.Out.WriteLine("Expected:"); _ = PrettifyAndValidateJson(expected); using (var encodeable = new FooBarEncodeable(fieldname, foo)) { var variant = new Variant(new ExtensionObject(encodeable)); // non reversible to save some space var encoder = new JsonEncoder(Context, false); encoder.WriteVariant(encodeable.FieldName, variant); var encoded = encoder.CloseAndReturnText(); TestContext.Out.WriteLine("Encoded:"); TestContext.Out.WriteLine(encoded); TestContext.Out.WriteLine("Formatted Encoded:"); _ = PrettifyAndValidateJson(encoded); Assert.That(encoded, Is.EqualTo(expected)); } }
/// <summary> /// The notification that the data for a monitored item has changed on an OPC UA server. /// </summary> public void MonitoredItemNotificationEventHandler(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e) { try { if (e == null || e.NotificationValue == null || monitoredItem == null || monitoredItem.Subscription == null || monitoredItem.Subscription.Session == null) { return; } if (!(e.NotificationValue is MonitoredItemNotification notification)) { return; } if (!(notification.Value is DataValue value)) { return; } MessageData messageData = new MessageData(); if (IotCentralMode) { // for IoTCentral we use the DisplayName as the key in the telemetry and the Value as the value. if (monitoredItem.DisplayName != null) { // use the DisplayName as reported in the MonitoredItem messageData.DisplayName = monitoredItem.DisplayName; } if (value.Value != null) { // use the Value as reported in the notification event argument encoded with the OPC UA JSON endcoder JsonEncoder encoder = new JsonEncoder(monitoredItem.Subscription.Session.MessageContext, false); value.ServerTimestamp = DateTime.MinValue; value.SourceTimestamp = DateTime.MinValue; value.StatusCode = StatusCodes.Good; encoder.WriteDataValue("Value", value); string valueString = encoder.CloseAndReturnText(); // we only want the value string, search for everything till the real value starts // and get it string marker = "{\"Value\":{\"Value\":"; int markerStart = valueString.IndexOf(marker, StringComparison.InvariantCulture); messageData.PreserveValueQuotes = true; if (markerStart >= 0) { // we either have a value in quotes or just a value int valueLength; int valueStart = marker.Length; if (valueString.IndexOf("\"", valueStart, StringComparison.InvariantCulture) >= 0) { // value is in quotes and two closing curly brackets at the end valueStart++; valueLength = valueString.Length - valueStart - 3; } else { // value is without quotes with two curly brackets at the end valueLength = valueString.Length - marker.Length - 2; messageData.PreserveValueQuotes = false; } messageData.Value = valueString.Substring(valueStart, valueLength); } Logger.Debug($" IoTCentral key: {messageData.DisplayName}"); Logger.Debug($" IoTCentral values: {messageData.Value}"); } } else { // update the required message data to pass only the required data to HubCommunication EndpointTelemetryConfiguration telemetryConfiguration = GetEndpointTelemetryConfiguration(EndpointUrl); // the endpoint URL is required to allow HubCommunication lookup the telemetry configuration messageData.EndpointUrl = EndpointUrl; if (telemetryConfiguration.NodeId.Publish == true) { messageData.NodeId = OriginalId; } if (telemetryConfiguration.MonitoredItem.ApplicationUri.Publish == true) { messageData.ApplicationUri = (monitoredItem.Subscription.Session.Endpoint.Server.ApplicationUri + (string.IsNullOrEmpty(OpcSession.PublisherSite) ? "" : $":{OpcSession.PublisherSite}")); } if (telemetryConfiguration.MonitoredItem.DisplayName.Publish == true && monitoredItem.DisplayName != null) { // use the DisplayName as reported in the MonitoredItem messageData.DisplayName = monitoredItem.DisplayName; } if (telemetryConfiguration.Value.SourceTimestamp.Publish == true && value.SourceTimestamp != null) { // use the SourceTimestamp as reported in the notification event argument in ISO8601 format messageData.SourceTimestamp = value.SourceTimestamp.ToString("o", CultureInfo.InvariantCulture); } if (telemetryConfiguration.Value.StatusCode.Publish == true && value.StatusCode != null) { // use the StatusCode as reported in the notification event argument messageData.StatusCode = value.StatusCode.Code; } if (telemetryConfiguration.Value.Status.Publish == true && value.StatusCode != null) { // use the StatusCode as reported in the notification event argument to lookup the symbolic name messageData.Status = StatusCode.LookupSymbolicId(value.StatusCode.Code); } if (telemetryConfiguration.Value.Value.Publish == true && value.Value != null) { // use the Value as reported in the notification event argument encoded with the OPC UA JSON endcoder JsonEncoder encoder = new JsonEncoder(monitoredItem.Subscription.Session.MessageContext, false); value.ServerTimestamp = DateTime.MinValue; value.SourceTimestamp = DateTime.MinValue; value.StatusCode = StatusCodes.Good; encoder.WriteDataValue("Value", value); string valueString = encoder.CloseAndReturnText(); // we only want the value string, search for everything till the real value starts // and get it string marker = "{\"Value\":{\"Value\":"; int markerStart = valueString.IndexOf(marker, StringComparison.InvariantCulture); messageData.PreserveValueQuotes = true; if (markerStart >= 0) { // we either have a value in quotes or just a value int valueLength; int valueStart = marker.Length; if (valueString.IndexOf("\"", valueStart, StringComparison.InvariantCulture) >= 0) { // value is in quotes and two closing curly brackets at the end valueStart++; valueLength = valueString.Length - valueStart - 3; } else { // value is without quotes with two curly brackets at the end valueLength = valueString.Length - marker.Length - 2; messageData.PreserveValueQuotes = false; } messageData.Value = valueString.Substring(valueStart, valueLength); } } // currently the pattern processing is done here, which adds runtime to the notification processing. // In case of perf issues it can be also done in CreateJsonMessageAsync of IoTHubMessaging.cs. // apply patterns messageData.ApplyPatterns(telemetryConfiguration); Logger.Debug($" ApplicationUri: {messageData.ApplicationUri}"); Logger.Debug($" EndpointUrl: {messageData.EndpointUrl}"); Logger.Debug($" DisplayName: {messageData.DisplayName}"); Logger.Debug($" Value: {messageData.Value}"); } // add message to fifo send queue if (monitoredItem.Subscription == null) { Logger.Debug($"Subscription already removed. No more details available."); } else { Logger.Debug($"Enqueue a new message from subscription {(monitoredItem.Subscription == null ? "removed" : monitoredItem.Subscription.Id.ToString(CultureInfo.InvariantCulture))}"); Logger.Debug($" with publishing interval: {monitoredItem.Subscription.PublishingInterval} and sampling interval: {monitoredItem.SamplingInterval}):"); } HubCommunication.Enqueue(messageData); } catch (Exception ex) { Logger.Error(ex, "Error processing monitored item notification"); } }
/// <summary> /// The notification that the data for a monitored item has changed on an OPC UA server /// </summary> public static void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e) { try { if (e.NotificationValue == null || monitoredItem.Subscription.Session == null) { return; } MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification; if (notification == null) { return; } DataValue value = notification.Value as DataValue; if (value == null) { return; } JsonEncoder encoder = new JsonEncoder(monitoredItem.Subscription.Session.MessageContext, false); string applicationURI = monitoredItem.Subscription.Session.Endpoint.Server.ApplicationUri; encoder.WriteString("ApplicationUri", applicationURI); encoder.WriteString("DisplayName", monitoredItem.DisplayName); // write NodeId as ns=x;i=y NodeId nodeId = monitoredItem.ResolvedNodeId; encoder.WriteString("NodeId", new NodeId(nodeId.Identifier, nodeId.NamespaceIndex).ToString()); // suppress output of server timestamp in json by setting it to minvalue value.ServerTimestamp = DateTime.MinValue; encoder.WriteDataValue("Value", value); string json = encoder.CloseAndReturnText(); byte[] bytes = new UTF8Encoding(false).GetBytes(json); // publish var properties = new Dictionary <string, string>(); properties.Add("content-type", "application/opcua+uajson"); properties.Add("deviceName", m_deviceName); if (m_accessKey != null) { properties.Add("source", "mapping"); properties.Add("deviceKey", m_accessKey); } try { Publish(new Message(json, properties)); Trace("Opc.Ua.Publisher.Module: Published: " + json + " from " + m_deviceName); } catch (Exception ex) { Trace("Opc.Ua.Publisher.Module: Failed to publish message, dropping..."); Trace(ex.ToString()); } } catch (Exception exception) { Trace("Opc.Ua.Publisher.Module: Error processing monitored item notification: " + exception.ToString()); } }