Continuationpoint in batch historical read

Questions regarding the use of the .NET SDK 2.0 for Server or Client development or integration into customer products ...

Moderator: uasdknet

Post Reply
kristian.mo
Jr. Member
Jr. Member
Posts: 3
Joined: 15 Feb 2021, 14:12

Continuationpoint in batch historical read

Post by kristian.mo »

Hello, variables are created as Internal like below.

Code: Select all

var newVariable = new CreateVariableSettings()
{
    ...
    AccessLevel = AccessLevels.CurrentRead | AccessLevels.HistoryRead,
    AccessLevelEx = AccessLevels.CurrentRead | AccessLevels.HistoryRead,
    TypeDefinitionId = VariableTypeIds.AnalogItemType,
    ...
};

var var = CreateVariable(Server.DefaultRequestContext, newVariable);
SetVariableConfiguration(var.NodeId, var.BrowseName, NodeHandleType.Internal, null);
I then used the pattern in the demo server for batch historical read as mentioned in other forum posts.

My continuation point type.

Code: Select all

private class HistoryReadRawContinuationPoint : HistoryContinuationPoint
{
    public DateTime TimestampToUse { get; set; }
}

1. Create a dummy result with a value
2. Create a continuation point.
3. Set the continuation point id in the result
4. Update the continuationpoint array with the new point
5. Trigger the callback.

Code: Select all

protected override HistoryReadResult HistoryReadRaw(RequestContext context, ReadRawModifiedDetails details, HistoryDataHandle nodeHandle, string indexRange, QualifiedName dataEncoding, ref HistoryContinuationPoint continuationPoint)
{
	return null;
}

protected override void HistoryReadRaw(RequestContext context, HistoryDataTransactionHandle transaction, ReadRawModifiedDetails details, IList<HistoryDataOperationHandle> operationHandles, IList<HistoryReadValueId> valuesToRead, IList<HistoryContinuationPoint> continuationPoints)
{
	for (int i = 0; i < operationHandles.Count; i++)
	{
		HistoryReadResult result = new()
		{
			HistoryData = new ExtensionObject(new HistoryData
			{
				DataValues = new DataValueCollection
				{
					new UnifiedAutomation.UaBase.DataValue
					{
						SourceTimestamp = details.StartTime,
						StatusCode = StatusCodes.Good,
						Value = 0.23
					}
				}
			})
		};

		HistoryReadRawContinuationPoint continuationPoint = new()
		{
			TimestampToUse = details.StartTime.AddTicks(1)
		};

		result.ContinuationPoint = continuationPoint.Id.ToByteArray();
		continuationPoints[i] = continuationPoint;

		(transaction.Callback as HistoryReadDataCompleteEventHandler)(operationHandles[i], transaction.CallbackData, result, false);
	}
}
I call from a client and get the data back with a continuation point.
When I call from the client again with the continuation point I get a BadContinuationPointInvalid statuscode.

1. Is the HA batch pattern correct? Apart from not being async yet.
2. Do I need to register the continuationpoint with the SDK?
3. And/or do I need to track the points by overriding a function?

kristian.mo
Jr. Member
Jr. Member
Posts: 3
Joined: 15 Feb 2021, 14:12

Re: Continuationpoint in batch historical read

Post by kristian.mo »

You are right. You need to save the continuation point at the session (a continuation point is valid per session).

Code: Select all

                result.ContinuationPoint = continuationPoint.Id.ToByteArray();
                continuationPoints[i] = continuationPoint;

                context.Session.SaveHistoryContinuationPoint(continuationPoint);
Please note: You need to check the coninuation points that are passed to HistoryReadRaw method.

Code: Select all

            for (int i = 0; i < operationHandles.Count; i++)
            {
                if (continuationPoints[i] == null)
                {
                    // get historical values beginning from StartTme
                }
                else
                {
                    // get next historical values
                }
                
Best Regards,
Support Team
Unified Automation GmbH

Post Reply