public async Task ReadHistoryRawValues()
        {
            // describe this client application.
            var clientDescription = new ApplicationDescription
            {
                ApplicationName = "Workstation.UaClient.FeatureTests",
                ApplicationUri  = $"urn:{System.Net.Dns.GetHostName()}:Workstation.UaClient.FeatureTests",
                ApplicationType = ApplicationType.Client
            };

            // place to store certificates
            var certificateStore = new DirectoryStore("./pki");

            // create a 'UaTcpSessionChannel', a client-side channel that opens a 'session' with the server.
            var channel = new UaTcpSessionChannel(
                clientDescription,
                certificateStore,
                new AnonymousIdentity(),      // the anonymous identity
                "opc.tcp://localhost:48010"); // the endpoint of Unified Automation's UaCPPServer.

            try
            {
                // try opening a session and reading a few nodes.
                await channel.OpenAsync();

                Console.WriteLine($"Opened session with endpoint '{channel.RemoteEndpoint.EndpointUrl}'.");
                Console.WriteLine($"SecurityPolicy: '{channel.RemoteEndpoint.SecurityPolicyUri}'.");
                Console.WriteLine($"SecurityMode: '{channel.RemoteEndpoint.SecurityMode}'.");
                Console.WriteLine($"UserIdentityToken: '{channel.UserIdentity}'.");

                Console.WriteLine("\nCheck if DataLogger active.");

                // check if DataLoggerActive is true. If not, then call method StartLogging.
                var req = new ReadRequest
                {
                    NodesToRead = new[] {
                        new ReadValueId {
                            NodeId = NodeId.Parse("ns=2;s=Demo.History.DataLoggerActive"), AttributeId = AttributeIds.Value
                        }
                    },
                };
                var res = await channel.ReadAsync(req);

                if (StatusCode.IsBad(res.Results[0].StatusCode))
                {
                    throw new InvalidOperationException("Error reading 'Demo.History.DataLoggerActive'. ");
                }
                var isActive = res.Results[0].GetValueOrDefault <bool>();

                if (!isActive)
                {
                    Console.WriteLine("Activating DataLogger.");

                    var req1 = new CallRequest
                    {
                        MethodsToCall = new[] {
                            new CallMethodRequest {
                                ObjectId = NodeId.Parse("ns=2;s=Demo.History"), // parent node
                                MethodId = NodeId.Parse("ns=2;s=Demo.History.StartLogging")
                            },
                        },
                    };
                    var res1 = await channel.CallAsync(req1);

                    if (StatusCode.IsBad(res1.Results[0].StatusCode))
                    {
                        throw new InvalidOperationException("Error calling method 'Demo.History.StartLogging'.");
                    }
                    Console.WriteLine("Note: Datalogger has just been activated, so there will be little or no history data to read.");
                    Console.WriteLine("      Try again in 1 minute.");
                }

                Console.WriteLine("\nReading history for last 1 minute(s).");

                // A continuation point is returned if there are more values to return than the
                // limit set by parameter NumValuesPerNode. A client should continue calling HistoryRead
                // until the continuation point returns null.
                byte[] cp = null;

                do
                {
                    var req2 = new HistoryReadRequest
                    {
                        HistoryReadDetails = new ReadRawModifiedDetails
                        {
                            StartTime        = DateTime.UtcNow.Add(TimeSpan.FromSeconds(-60)), // set start time to 1 minute ago
                            EndTime          = DateTime.UtcNow,
                            NumValuesPerNode = 100,                                            // sets limit. if there are more values to return then a continuation point is returned.
                            ReturnBounds     = false,                                          // set true to return interpolated values for the start and end times
                        },
                        TimestampsToReturn        = TimestampsToReturn.Both,
                        ReleaseContinuationPoints = false, // set true to abandon returning any remaining values from this interval
                        NodesToRead = new[] {
                            new HistoryReadValueId {
                                NodeId = NodeId.Parse("ns=2;s=Demo.History.DoubleWithHistory"), ContinuationPoint = cp
                            },
                        },
                    };

                    var res2 = await channel.HistoryReadAsync(req2);

                    if (StatusCode.IsGood(res2.Results[0].StatusCode))
                    {
                        var historyData = res2.Results[0].HistoryData as HistoryData;

                        Console.WriteLine($"Found {historyData.DataValues.Length} value(s) for node '{req2.NodesToRead[0].NodeId}':");

                        foreach (var dv in historyData.DataValues)
                        {
                            Console.WriteLine($"Read {dv.Value}, q: {dv.StatusCode}, ts: {dv.SourceTimestamp}");
                        }

                        cp = res2.Results[0].ContinuationPoint;
                        // if ContinuationPoint is null, then there is no more data to return.
                        if (cp == null)
                        {
                            break;
                        }
                    }
                    else
                    {
                        Console.WriteLine($"HistoryRead return statuscode: {res2.Results[0].StatusCode}");
                        break;
                    }
                } while (cp != null); // loop while ContinuationPoint is not null.

                Console.WriteLine($"\nClosing session '{channel.SessionId}'.");
                await channel.CloseAsync();
            }
            catch (Exception ex)
            {
                await channel.AbortAsync();

                Console.WriteLine(ex.Message);
            }
        }
Exemple #2
0
        public async Task ReadHistorical()
        {
            var channel = new UaTcpSessionChannel(
                localDescription,
                certificateStore,
                new AnonymousIdentity(),
                "opc.tcp://localhost:48010",
                loggerFactory: loggerFactory);

            await channel.OpenAsync();

            logger.LogInformation($"Opened session with endpoint '{channel.RemoteEndpoint.EndpointUrl}'.");
            logger.LogInformation($"SecurityPolicy: '{channel.RemoteEndpoint.SecurityPolicyUri}'.");
            logger.LogInformation($"SecurityMode: '{channel.RemoteEndpoint.SecurityMode}'.");
            logger.LogInformation($"Activated session '{channel.SessionId}'.");

            var historyReadRequest = new HistoryReadRequest
            {
                HistoryReadDetails = new ReadRawModifiedDetails
                {
                    StartTime      = DateTime.UtcNow - TimeSpan.FromMinutes(10),
                    EndTime        = DateTime.UtcNow,
                    ReturnBounds   = true,
                    IsReadModified = false
                },
                NodesToRead = new[]
                {
                    new HistoryReadValueId
                    {
                        NodeId = NodeId.Parse("ns=2;s=Demo.History.DoubleWithHistory")
                    }
                },
            };
            var historyReadResponse = await channel.HistoryReadAsync(historyReadRequest);

            var result = historyReadResponse.Results[0];

            StatusCode.IsGood(result.StatusCode)
            .Should().BeTrue();
            logger.LogInformation($"HistoryRead response status code: {result.StatusCode}, HistoryData count: {((HistoryData)result.HistoryData).DataValues.Length}.");

            if (false) // UaCPPserver does not appear to store event history.
            {
                var historyReadRequest2 = new HistoryReadRequest
                {
                    HistoryReadDetails = new ReadEventDetails
                    {
                        StartTime = DateTime.UtcNow - TimeSpan.FromMinutes(10),
                        EndTime   = DateTime.UtcNow,
                        Filter    = new EventFilter // Use EventHelper to select all the fields of AlarmCondition.
                        {
                            SelectClauses = EventHelper.GetSelectClauses <AlarmCondition>()
                        }
                    },
                    NodesToRead = new[]
                    {
                        new HistoryReadValueId
                        {
                            NodeId = NodeId.Parse("ns=2;s=Demo.History.DoubleWithHistory")
                        }
                    },
                };
                var historyReadResponse2 = await channel.HistoryReadAsync(historyReadRequest2);

                var result2 = historyReadResponse2.Results[0];
                StatusCode.IsGood(result2.StatusCode)
                .Should().BeTrue();
                logger.LogInformation($"HistoryRead response status code: {result2.StatusCode}, HistoryEvent count: {((HistoryEvent)result2.HistoryData).Events.Length}.");

                // Use EventHelper to create AlarmConditions from the HistoryEventFieldList
                var alarms = ((HistoryEvent)result2.HistoryData).Events.Select(e => EventHelper.Deserialize <AlarmCondition>(e.EventFields));
            }
            logger.LogInformation($"Closing session '{channel.SessionId}'.");
            await channel.CloseAsync();
        }
Exemple #3
0
        public async Task ReadHistorical()
        {
            var channel = new UaTcpSessionChannel(
                this.localDescription,
                this.certificateStore,
                null,
                EndpointUrl);

            await channel.OpenAsync();

            Console.WriteLine($"Opened session with endpoint '{channel.RemoteEndpoint.EndpointUrl}'.");
            Console.WriteLine($"SecurityPolicy: '{channel.RemoteEndpoint.SecurityPolicyUri}'.");
            Console.WriteLine($"SecurityMode: '{channel.RemoteEndpoint.SecurityMode}'.");
            Console.WriteLine($"Activated session '{channel.SessionId}'.");

            var historyReadRequest = new HistoryReadRequest
            {
                HistoryReadDetails = new ReadRawModifiedDetails
                {
                    StartTime      = DateTime.UtcNow - TimeSpan.FromMinutes(10),
                    EndTime        = DateTime.UtcNow,
                    ReturnBounds   = true,
                    IsReadModified = false
                },
                NodesToRead = new[]
                {
                    new HistoryReadValueId
                    {
                        NodeId = NodeId.Parse("ns=2;s=MyLevel")
                    }
                },
            };
            var historyReadResponse = await channel.HistoryReadAsync(historyReadRequest);

            var result = historyReadResponse.Results[0];

            Assert.IsTrue(StatusCode.IsGood(result.StatusCode));
            Console.WriteLine($"HistoryRead response status code: {result.StatusCode}, HistoryData count: {((HistoryData)result.HistoryData.Body).DataValues.Length}.");

            var historyReadRequest2 = new HistoryReadRequest
            {
                HistoryReadDetails = new ReadEventDetails
                {
                    StartTime = DateTime.UtcNow - TimeSpan.FromMinutes(10),
                    EndTime   = DateTime.UtcNow,
                    Filter    = new EventFilter // Use EventHelper to select all the fields of AlarmCondition.
                    {
                        SelectClauses = EventHelper.GetSelectClauses <AlarmCondition>()
                    }
                },
                NodesToRead = new[]
                {
                    new HistoryReadValueId
                    {
                        NodeId = NodeId.Parse("ns=2;s=MyDevice")
                    }
                },
            };
            var historyReadResponse2 = await channel.HistoryReadAsync(historyReadRequest2);

            var result2 = historyReadResponse2.Results[0];

            Assert.IsTrue(StatusCode.IsGood(result2.StatusCode));
            Console.WriteLine($"HistoryRead response status code: {result2.StatusCode}, HistoryEvent count: {((HistoryEvent)result2.HistoryData.Body).Events.Length}.");

            // Use EventHelper to create AlarmConditions from the HistoryEventFieldList
            var alarms = ((HistoryEvent)result2.HistoryData.Body).Events.Select(e => EventHelper.Deserialize <AlarmCondition>(e.EventFields));

            Console.WriteLine($"Closing session '{channel.SessionId}'.");
            await channel.CloseAsync();
        }