예제 #1
0
        void StartMonitoring()
        {
            foreach (var item in MonitoredMeasurements)
            {
                var nodeId = OpcUaHelper.FindNode(item.Path, ObjectIds.ObjectsFolder, l_session);
                var sub    = new Subscription
                {
                    PublishingInterval = item.MonitorResolution,
                    PublishingEnabled  = true,
                    LifetimeCount      = 0,
                    KeepAliveCount     = 0,
                    DisplayName        = item.Path,
                    Priority           = byte.MaxValue
                };
                MonitoredItem monitoredItem = new MonitoredItem()
                {
                    StartNodeId      = nodeId,
                    AttributeId      = Attributes.Value,
                    DisplayName      = item.Name,
                    SamplingInterval = item.MonitorResolution
                };

                sub.AddItem(monitoredItem);
                l_session.AddSubscription(sub);

                sub.Create();
                sub.ApplyChanges();
                monitoredItem.Notification += (monitored, args) =>
                {
                    var p = (MonitoredItemNotification)args.NotificationValue;
                    MonitorData(item, p.Value);
                };
            }
        }
예제 #2
0
        void ReadMeasurement(PolledMeasurement measurement)
        {
            OpcMetric metric = new OpcMetric();

            metric.Measurement = (MeasurementDto)measurement;

            if (!l_session.Connected)
            {
                l_logger.ErrorFormat(string.Format("Server not connected. Cannot read path {0}.", measurement.Name));
                throw new Exception(string.Format("Server not connected. Cannot read path {0}.", measurement.Name));
            }
            var nodesToRead = OpcUaHelper.GetReadValueIdCollection(measurement.Path, l_session);
            DataValueCollection      results;
            DiagnosticInfoCollection diag;

            l_session.Read(
                requestHeader: null,
                maxAge: 0,
                timestampsToReturn: TimestampsToReturn.Neither,
                nodesToRead: nodesToRead,
                results: out results,
                diagnosticInfos: out diag);
            var val = results[0];

            metric.OpcValue = val.Value;

            metric.Opcstatus = val.StatusCode.ToString();
            if (OpcHelper.QualifyMetric(ref metric, l_cache))
            {
                l_cache[metric.Measurement.Name] = metric.OpcValue;
                l_metricCollection.Add(metric);
            }
        }
예제 #3
0
        //bool QualifyMetric(ref OpcMetric metric)
        //{
        //    if (PointHasGoodOrDifferentBadStatus(metric))
        //    {
        //        if (!l_cache.ContainsKey(metric.Measurement.Name))
        //        {
        //            l_cache.Add(metric.Measurement.Name, metric.OpcValue);
        //            metric.Measurement.LastOpcstatus = metric.Opcstatus;
        //            metric.Measurement.LastValue = metric.OpcValue;
        //        }
        //        else
        //        {
        //            object lastvalue;
        //            l_cache.TryGetValue(metric.Measurement.Name, out lastvalue);
        //            metric.Measurement.LastValue = lastvalue;
        //        }


        //        if (!PointIsValid(metric) || !PointMatchesType(metric))
        //        {
        //            // Set de default value for the type specified
        //            l_logger.ErrorFormat("Invalid point: measurement.name<{0}>, measurement.path<{1}>, metric.value<{2}>", metric.Measurement.Name, metric.Measurement.Path, metric.OpcValue.ToString());
        //            switch (metric.Measurement.DataType)
        //            {
        //                case "number":
        //                    metric.OpcValue = 0;
        //                    break;
        //                case "boolean":
        //                    metric.OpcValue = false;
        //                    break;
        //                case "string":
        //                    metric.OpcValue = "";
        //                    break;
        //                default:
        //                    l_logger.Error("No valid datatype, ignoring point");
        //                    break;
        //            }
        //            return false;
        //        }
        //    }
        //    // Check for deadband
        //    if (PointIsWithinDeadband(metric)) return false;
        //    if (!PointMatchesType(metric))
        //    {
        //        l_logger.ErrorFormat("Invalid type returned from OPC. Ignoring point {0}", metric.Measurement.Name);
        //        return false;
        //    }
        //    return true;
        //}
        //bool PointMatchesType(OpcMetric metric)
        //{
        //    var match = (metric.OpcValue.IsNumber() && metric.Measurement.DataType == "number")
        //        || metric.OpcValue.IsBoolean() && metric.Measurement.DataType == "boolean"
        //        || metric.OpcValue.IsString() && metric.Measurement.DataType == "string";

        //    if (!match)
        //    {
        //        //log here

        //    }
        //    return match;
        //}
        //bool PointIsValid(OpcMetric p)
        //{
        //    // check if the value is a type that we can handle (number or a bool).
        //    return (p.OpcValue != null && (p.OpcValue.IsBoolean() || p.OpcValue.IsNumber())) || p.OpcValue.IsString();

        //}
        //bool PointHasGoodOrDifferentBadStatus(OpcMetric p)
        //{
        //    var curr = p.Opcstatus;
        //    var prev = p.Measurement.LastOpcstatus;

        //    if (curr == "Good" || curr != prev) return true;
        //    return false;
        //}


        //bool PointIsWithinDeadband(OpcMetric metric)
        //{
        //    // some vars for shorter statements later on.
        //    var curr = metric.OpcValue;
        //    var prev = metric.Measurement.LastValue;
        //    var dba = metric.Measurement.DeadbandAbsolute;
        //    var dbr = metric.Measurement.DeadbandRelative;

        //    // return early if the type of the previous value is not the same as the current.
        //    // this will also return when this is the first value and prev is still undefined.
        //    if (curr.GetType() != prev.GetType()) return false;

        //    // calculate deadbands based on value type. For numbers, make the
        //    // calculations for both absolute and relative if they are set. For bool,
        //    // just check if a deadband has been set and if the value has changed.

        //    if (curr.IsNumber())
        //    {

        //        if (dba > 0 && Math.Abs(Convert.ToDecimal(curr) - Convert.ToDecimal(prev)) < dba)
        //        {
        //            return true;
        //        }
        //        if (dbr > 0 && Math.Abs(Convert.ToDecimal(curr) - Convert.ToDecimal(prev)) < Math.Abs(Convert.ToDecimal(prev)) * dbr)
        //        {
        //            // console.log("New value is within relative deadband.", p);
        //            return true;

        //        }
        //    }
        //    else if (curr.IsBoolean())
        //    {
        //        if (dba > 0 && prev == curr)
        //            // console.log("New value is within bool deadband.", p);
        //            return true;

        //    }
        //    else if (curr.IsString())
        //        return true;
        //    return false;

        //}
        #endregion

        #region methods
        private Session InitializeSession(Uri url, X509Certificate2 applicationCertificate = null)
        {
            var certificateValidator = new CertificateValidator();

            certificateValidator.CertificateValidation += (sender, eventArgs) =>
            {
                if (ServiceResult.IsGood(eventArgs.Error))
                {
                    eventArgs.Accept = true;
                }
                else if ((eventArgs.Error.StatusCode.Code == StatusCodes.BadCertificateUntrusted) && true) // AutoAcceptUntrustedCertificates = true;
                {
                    eventArgs.Accept = true;
                }
                else
                {
                    throw new Exception(string.Format("Failed to validate certificate with error code {0}: {1}, statusCode: {2}", eventArgs.Error.Code, eventArgs.Error.AdditionalInfo, eventArgs.Error.StatusCode));
                }
            };
            // Build the application configuration
            var appInstance = new ApplicationInstance
            {
                ApplicationType          = ApplicationType.Client,
                ConfigSectionName        = "Odenwald",
                ApplicationConfiguration = new ApplicationConfiguration
                {
                    ApplicationUri       = url.ToString(),
                    ApplicationName      = "Odenwald",
                    ApplicationType      = ApplicationType.Client,
                    CertificateValidator = certificateValidator,
                    ServerConfiguration  = new ServerConfiguration
                    {
                        MaxSubscriptionCount     = 100,
                        MaxMessageQueueSize      = 10,
                        MaxNotificationQueueSize = 100,
                        MaxPublishRequestCount   = 20
                    },
                    SecurityConfiguration = new SecurityConfiguration
                    {
                        AutoAcceptUntrustedCertificates = true
                    },
                    TransportQuotas = new TransportQuotas
                    {
                        OperationTimeout      = 600000,
                        MaxStringLength       = 1048576,
                        MaxByteStringLength   = 1048576,
                        MaxArrayLength        = 65535,
                        MaxMessageSize        = 4194304,
                        MaxBufferSize         = 65535,
                        ChannelLifetime       = 600000,
                        SecurityTokenLifetime = 3600000
                    },
                    ClientConfiguration = new ClientConfiguration
                    {
                        DefaultSessionTimeout   = 60000,
                        MinSubscriptionLifetime = 10000
                    },
                    DisableHiResClock = true
                }
            };

            // Assign a application certificate (when specified)
            if (applicationCertificate != null)
            {
                appInstance.ApplicationConfiguration.SecurityConfiguration.ApplicationCertificate = new CertificateIdentifier(applicationCertificate);
            }

            // Find the endpoint to be used
            var endpoints = OpcUaHelper.SelectEndpoint(url, false);//UseMessageSecurity = false;

            // Create the OPC session:
            var session = Session.Create(
                configuration: appInstance.ApplicationConfiguration,
                endpoint: new ConfiguredEndpoint(
                    collection: null,
                    description: endpoints,
                    configuration: EndpointConfiguration.Create(applicationConfiguration: appInstance.ApplicationConfiguration)),
                updateBeforeConnect: false,
                checkDomain: false,
                sessionName: "Odenwald",
                sessionTimeout: 60000U,
                identity: null,
                preferredLocales: new string[] { });

            return(session);
        }