예제 #1
0
        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;
                }
            }
        }
예제 #2
0
        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());
            }
        }
예제 #3
0
        /// <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");
            }
        }
예제 #4
0
        /// <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");
            }
        }
예제 #5
0
        /// <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());
            }
        }
        /// <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");
            }
        }
예제 #7
0
        /// <summary>
        /// Encodes a dataSet field
        /// </summary>
        private void EncodeField(JsonEncoder encoder, Field field)
        {
            string fieldName = field.FieldMetaData.Name;

            Variant valueToEncode = field.Value.WrappedValue;

            // The StatusCode.Good value is not encoded cor3ectly then it shall be ommited
            if (valueToEncode == StatusCodes.Good && m_fieldTypeEncoding != FieldTypeEncodingMask.Variant)
            {
                valueToEncode = Variant.Null;
            }
            switch (m_fieldTypeEncoding)
            {
            case FieldTypeEncodingMask.Variant:
                // If the DataSetFieldContentMask results in a Variant representation,
                // the field value is encoded as a Variant encoded using the reversible OPC UA JSON Data Encoding
                // defined in OPC 10000-6.
                encoder.ForceNamespaceUri = false;
                encoder.WriteVariant(fieldName, valueToEncode, true);
                break;

            case FieldTypeEncodingMask.RawData:
                // If the DataSetFieldContentMask results in a RawData representation,
                // the field value is a Variant encoded using the non-reversible OPC UA JSON Data Encoding
                // defined in OPC 10000-6
                encoder.ForceNamespaceUri = true;

                encoder.WriteVariant(fieldName, valueToEncode, false);
                break;

            case FieldTypeEncodingMask.DataValue:
                DataValue dataValue = new DataValue();

                dataValue.WrappedValue = valueToEncode;

                if ((FieldContentMask & DataSetFieldContentMask.StatusCode) != 0)
                {
                    dataValue.StatusCode = field.Value.StatusCode;
                }

                if ((FieldContentMask & DataSetFieldContentMask.SourceTimestamp) != 0)
                {
                    dataValue.SourceTimestamp = field.Value.SourceTimestamp;
                }

                if ((FieldContentMask & DataSetFieldContentMask.SourcePicoSeconds) != 0)
                {
                    dataValue.SourcePicoseconds = field.Value.SourcePicoseconds;
                }

                if ((FieldContentMask & DataSetFieldContentMask.ServerTimestamp) != 0)
                {
                    dataValue.ServerTimestamp = field.Value.ServerTimestamp;
                }

                if ((FieldContentMask & DataSetFieldContentMask.ServerPicoSeconds) != 0)
                {
                    dataValue.ServerPicoseconds = field.Value.ServerPicoseconds;
                }

                // If the DataSetFieldContentMask results in a DataValue representation,
                // the field value is a DataValue encoded using the non-reversible OPC UA JSON Data Encoding
                encoder.ForceNamespaceUri = true;
                encoder.WriteDataValue(fieldName, dataValue, false);
                break;
            }
        }
예제 #8
0
        /// <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());
            }
        }