.NET Based OPC UA Client/Server SDK  3.3.3.537
History Read – History Read Raw

Prerequisites

A session with the server must be established.

Description

The following dialog shows an example implementation of the History Read service. Press the button “Show Code” to display the corresponding code, and the button “Help” to show this documentation page.

clienttutorials_history_read_raw.png

Press the button “...” right of the field “Variable” to open a window to browse the address space and select a historizing variable. After pressing the button “OK” the NodeId will be shown in the corresponding field.

clienttutorials_read_attribute2.png

You can specify a time range by checking the boxes right of the input fields “Start Time” and “End Time” and entering the desired values. Clicking on the arrow in the input field opens a calendar for picking the date. The time can be entered directly.

clienttutorials_history_read_raw2.png

In addtion you can specify the maximum number of values to be returned in the field “Num Values” and include the bounding values specified above by checking the box right of “Include Bounds”.

On pressing the button “Read History” the response is listed at “History Read Response”. Check the box in front of “Use Asynchronous Pattern” to call “BeginHistoryRead” instead of “HistoryRead”.

clienttutorials_history_read_raw3.png

If a maximum number of values is specified above, a continuation point is set. Pressing the button “Read History” again returns values starting at that continuation point. After pressing the button “Releasse Continuation Point” returned values are starting at the start time specified above.

Sample Code

The following code reads the historical data for a variable in a specified time range and displays the result in a list.

try
{
// get the current session from the parent form.
Session session = m_parent.Session;
// nothing to do if no session.
if (session == null)
{
return;
}
// parse the object id.
NodeId nodeId = NodeId.Parse(NodeIdTB.Text);
ReadRawModifiedDetails details = m_details as ReadRawModifiedDetails;
HistoryReadValueIdCollection nodesToRead = new HistoryReadValueIdCollection();
if (m_nodeToContinue == null)
{
m_dataset.Tables[0].Rows.Clear();
details = new ReadRawModifiedDetails();
details.StartTime = (StartTimeCK.Checked) ? StartTimeDP.Value.ToUniversalTime() : DateTime.MinValue;
details.EndTime = (EndTimeCK.Checked) ? EndTimeDP.Value.ToUniversalTime() : DateTime.MinValue;
details.NumValuesPerNode = (MaxReturnValuesCK.Checked) ? (uint)MaxReturnValuesNP.Value : 0;
details.IsReadModified = false;
details.ReturnBounds = ReturnBoundsCK.Checked;
nodesToRead.Add(new HistoryReadValueId() { NodeId = nodeId });
m_details = details;
m_nodeToContinue = nodesToRead[0];
}
else
{
nodesToRead.Add(m_nodeToContinue);
}
// this is a blocking call so show the wait cursor.
Cursor = Cursors.WaitCursor;
// fetch the history (with a 10s timeout).
List<HistoryDataReadResult> results = session.HistoryReadRaw(
nodesToRead,
details,
new RequestSettings() { OperationTimeout = 10000 });
// check for operation error.
if (StatusCode.IsBad(results[0].StatusCode))
{
m_parent.ShowError(this, "Read history call failed: " + results[0].StatusCode.ToString());
m_details = null;
m_nodeToContinue = null;
return;
}
// update controls.
if (results[0].DataValues != null)
{
foreach (DataValue value in results[0].DataValues)
{
AddValue(value, null);
}
m_dataset.AcceptChanges();
}
// save continuation point.
if (!ByteString.IsNull(results[0].ContinuationPoint))
{
m_nodeToContinue.ContinuationPoint = results[0].ContinuationPoint;
ReleaseContinuationPointBTN.Visible = true;
}
else
{
m_nodeToContinue = null;
ReleaseContinuationPointBTN.Visible = false;
}
}
catch (Exception exception)
{
ExceptionDlg.ShowInnerException(this.Text, exception);
m_nodeToContinue = null;
}
finally
{
Cursor = Cursors.Default;
}