OPC 10000-4 specifies all Services needed for OPC UA Historical Access. In particular:
- The Browse Service Set or Query Service Set to detect HistoricalNodes and their configuration.
- The HistoryRead and HistoryUpdate Services of the Attribute Service Set to read and update history of HistoricalDataNodes.
The HistoryRead service has the following parameters (see OPC 10000-4 for details):
- historyReadDetails
- timestampsToReturn
- releaseContinuationPoints
- nodesToRead []
- nodeId
- indexRange
- dataEncoding
- continuationPoint
The HistoryReadDetails is an extensible parameter that can be any of the parameters defined in Table 27. Each of these parameters are described in detail in 6.5. The other parameters listed above can have special requirements described in 6.5.
The return parameter for the HistoryRead service has the following parameter:
- results []
- statusCode
- continuationPoint
- historyData
The historyData parameter is an extensible parameter that is defined in 6.6. The other return parameters can have special meanings assigned either in 6.6 or in 6.5.
Subclause 6.2 defines additional codes and rules that apply to the StatusCode when used for HistoricalDataNodes.
The general structure of the StatusCode is specified in OPC 10000-4. It includes a set of common operational result codes which also apply to historical data and/or Events.
In OPC UA Historical Access the StatusCode is used to indicate the conditions under which a Value or Event was stored, and thereby can be used as an indicator of its usability. Due to the nature of historical data and/or Events, additional information beyond the basic quality and call result code needs to be conveyed to the Client, for example, whether the value is actually stored in the data repository, whether the result was Interpolated, whether all data inputs to a calculation were of good quality, etc.
In the following, Table 25 contains codes with Bad severity indicating a failure; Table 26 contains Good (success) codes.
It is important to note that these are the codes that are specific for OPC UA Historical Access and supplement the codes that apply to all types of data and are therefore defined in OPC 10000-4, OPC 10000-8 and OPC 10000-13.
Table 25 – Bad operation level result codes
Symbolic Id |
Description |
Bad_NoData |
No data exists for the requested time range or Event filter. |
Bad_BoundNotFound |
No data found to provide upper or lower bound value. |
Bad_BoundNotSupported |
Bounding Values are not applicable or the Server has reached its search limit and will not return a bound. |
Bad_DataLost |
Data is missing due to collection started/stopped/lost. |
Bad_DataUnavailable |
Expected data is unavailable for the requested time range due to an un-mounted volume, an off-line historical collection, or similar reason for temporary unavailability. |
Bad_EntryExists |
The data or Event was not successfully inserted because a matching entry exists. |
Bad_NoEntryExists |
The data or Event was not successfully updated because no matching entry exists. |
Bad_TimestampNotSupported |
The Client requested history using a TimestampsToReturn the Server does not support. For example requested ServerTimestamp when Server only supports SourceTimestamp. |
Bad_InvalidArgument |
One or more arguments are invalid or missing. |
Bad_AggregateListMismatch |
The list of Aggregates does not have the same length as the list of operations. |
Bad_AggregateConfigurationRejected |
The Server does not support the specified AggregateConfiguration for the Node. |
Bad_AggregateNotSupported |
The specified Aggregate is not valid for the specified Node. |
Bad_ArgumentsMissing |
See OPC 10000-4 for the description of this result code. |
Bad_TypeDefinitionInvalid |
See OPC 10000-4 for the description of this result code. |
Bad_SourceNodeIdInvalid |
See OPC 10000-4 for the description of this result code. |
Bad_OutOfRange |
See OPC 10000-4 for the description of this result code. |
Bad_NotSupported |
See OPC 10000-4 for the description of this result code. |
Bad_IndexRangeInvalid |
See OPC 10000-4 for the description of this result code. |
Bad_NotWritable |
See OPC 10000-4 for the description of this result code. |
Table 26 – Good operation level result codes
Symbolic Id |
Description |
Good_NoData |
No data exists for the requested time range or Event filter. |
Good_EntryInserted |
The data or Event was successfully inserted into the historical database |
Good_EntryReplaced |
The data or Event field was successfully replaced in the historical database |
Good_DataIgnored |
The Event field was ignored and was not inserted into the historical database. |
It may be noted that there are both Good and Bad Status codes that deal with cases of no data or missing data. In general, Good_NoData is used for cases where no data was found when performing a simple ‘Read’ request. Bad_NoData is used in cases where some action is requested on an interval and no data could be found. The distinction exists if users are attempting an action on a given interval where they would expect data to exist, or would like to be notified that the requested action could not be performed.
Good_NoData is returned for cases such as:
- ReadEventDetails where startTime =endTime
- ReadEventDetails data is requested and does not exist
- ReadRawModifiedDetails where data is requested and does not exist
Bad_NoData is returned for cases such as:
- ReadEventDetails data is requested and underlying historian does not support the requested field
- ReadProcessed where data is requested and does not exist
- Any Delete requests where data does not exist
The above use cases are illustrative examples. Detailed explanations on when each status code is returned are found in 6.5 and 6.8.
The StatusCode in addition contains an informational bit called Semantics Changed (see OPC 10000-4).
UA Servers that implement OPC UA Historical Access should not set this bit; rather they should propagate the StatusCode which has been stored in the data repository. The Client should be aware that the returned data values can have this bit set.
The continuationPoint parameter in the HistoryRead Service is used to mark a point from which to continue the history read if not all values could be returned in one response. The value is opaque for the Client and is only used to maintain the state information for the Server to continue from. For HistoricalDataNode requests, a Server can use the timestamp of the last returned data item if the timestamp is unique. This can reduce the need in the Server to store state information for the ContinuationPoint.
The Client specifies the maximum number of results per operation in the request Message. A Server shall not return more than this number of results but it can return fewer results. The Server allocates a ContinuationPoint if there are more results to return. The Server can return fewer results due to buffer issues or other internal constraints. It can also be required to return a ContinuationPoint due to HistoryRead parameter constraints. If a request is taking a long time to calculate and is approaching the timeout time, the Server can return partial results with a ContinuationPoint. This can be done if the calculation is going to take more time than the Client timeout. In some cases, it can take longer than the Client timeout to calculate even one result. Then the Server can return zero results with a ContinuationPoint that allows the Server to resume the calculation on the next Client read call. For additional discussions regarding ContinuationPoints and HistoryRead please see the individual extensible HistoryReadDetails parameter in 6.5.
If the Client specifies a ContinuationPoint, then the HistoryReadDetails parameter and the TimestampsToReturn parameter shall be the same as in the original call. It is permissible to change the dataEncoding parameter with each request. If the HistoryReadDetails parameter or TimestampsToReturn parameter change the Server can ignore the updated parameters, it can detect any changes to the parameters and report an error or it can process the request as if it was a new request. The exact behaviour is Server specific.
If the Client specifies a ContinuationPoint that is no longer valid, then the Server shall return a Bad_ContinuationPointInvalid error.
If the releaseContinuationPoints parameter is set in the request the Server shall not return any data and shall release all ContinuationPoints passed in the request.
If the ContinuationPoint for an operation is missing or invalid then the StatusCode for the operation shall be Bad_ContinuationPointInvalid.
Historians are not required to be able to store arrays. Optional ConformanceUnits exist to indicate if they support storage of arrays. If a Historian does store arrays, it may not support returning an index range in an array, it may only provide the entire array. ConformanceUnits are provided to indicate if a Historian supports index ranges. For ReadProcessedDetails, some Aggregates do not support arrays (see 6.5.4 for details).
If the Historian does not support index ranges, but an indexRange parameter is provided, then the Server shall return Bad_NotSupported.
If a Historian supports index ranges, the size of the array can change over the time period being retrieved (see Figure 8 for an illustration). For retrieval of index ranges of values, all records that exist in the requested time period are returned. For any Value that does not have any values in the requested index range a status of Bad_IndexRangeNoData is returned. In the illustration the top table indicates the data that was collected by the Historian. The time interval covered by the historical ReadRawModifiedDetails request is labelled in the figure as well as the indexRange that was requested [not all parameters for the request are illustrated]. The results box indicates the timestamps, values and statuses that are returned. It is important to understand that a record is returned for all recorded timestamps, some just indicate a bad status. The status returned can be the bad status that was stored when the data was collected (e.g. Bad_CommunicationFailure) or it can be the result of processing the request for the index range (i.e. Bad_IndexRangeNoData).
Figure 8 - History Array example
Figure 9 provides a second illustration where a different time interval is selected as well as a different index range. This index range [1:2] contains more data and thus less Bad_IndexRangeNoData is returned.
Figure 9 - Historian Array Illustration 2
Historians that store strings may not be able to return substring of stored strings, they can restrict retrieval to the entire string. ConformanceUnits are provided to indicate if the Historian supports processing of substrings for historical retrieval.
All processing for substrings, follow the same rules as for arrays (see NumericRange in OPC 10000-4).
The HistoryRead Service defined in OPC 10000-4 can perform several different functions. The HistoryReadDetails parameter is an Extensible Parameter that specifies which function to perform and the details that are specific to that function. See OPC 10000-4 for the definition of Extensible Parameter. Table 27 lists the symbolic names of the valid Extensible Parameter structures. Some structures will perform different functions based on the setting of its associated parameters. For simplicity the functionality of each structure is listed. For example, text such as ‘using the Read modified functionality’ refers to the function the HistoryRead Service performs using the Extensible Parameter structure ReadRawModifiedDetails with the isReadModified Boolean parameter set to TRUE.
Table 27 – HistoryReadDetails parameter Symbolic Names
Symbolic Name |
Functionality |
Description |
ReadEventDetails |
Read event |
This structure selects a set of Events from the history database by specifying a filter and a time domain for one or more Objects or Views. See 6.5.2.1. When this parameter is specified, the Server returns a HistoryEvent structure for each operation (see 6.6.4). |
ReadEventDetails2 |
Read event |
This structure selects a set of Events from the history database by specifying a filter and a time domain for one or more Objects or Views. See 6.5.2.1. When this parameter is specified, the Server returns a HistoryEvent structure for each operation (see 6.6.4). |
ReadEventDetails2 |
Read event modified |
This structure selects a set of modified Events from the history database by specifying a filter and a time domain for one or more Objects or Views. See 6.5.2.3 When this parameter is specified, the Server returns a HistoryModifiedEvent structure for each operation (see 6.6.4). |
ReadRawModifiedDetails |
Read raw |
This structure selects a set of values from the history database by specifying a time domain for one or more Variables. See 6.5.3.1. When this parameter is specified, the Server returns a HistoryData structure for each operation (see 6.6.2). |
ReadRawModifiedDetails |
Read modified |
This parameter selects a set of ModifiedValues from the history database by specifying a time domain for one or more Variables. See 6.5.3.1. When this parameter is specified, the Server returns a HistoryModifiedData structure for each operation (see 6.6.3). |
ReadProcessedDetails |
Read processed |
This structure selects a set of Aggregate values from the history database by specifying a time domain for one or more Variables. See 6.5.4.1. When this parameter is specified, the Server returns a HistoryData structure for each operation (see 6.6.2) |
ReadAtTimeDetails |
Read at time |
This structure selects a set of raw or interpolated values from the history database by specifying a series of timestamps for one or more Variables. See 6.5.5.1. When this parameter is specified, the Server returns a HistoryData structure for each operation (see Clause 6.6.2). |
ReadAnnotationDataDetails |
Read Annotation Data |
This structure selects a set of Annotation Data from the history database by specifying a series of timestamps for one or more Variables. See 6.5.6.1. When this parameter is specified, the Server returns an Annotation structure for each operation (see Clause 6.6.6). |
The HistoryReadDetails Structure definition in the AddressSpace is shown in Table 28. The Structure is an abstract supertype and contains no fields.
Table 28 – HistoryReadDetails definition
Attribute |
Value |
|||||
BrowseName |
HistoryReadDetails |
|||||
IsAbstract |
True |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the Structure defined in OPC 10000-3 |
||||||
Conformance Units |
||||||
Table 29 defines the ReadEventDetails structure. This parameter is only valid for Objects that have the EventNotifier Attribute set to TRUE (see OPC 10000-3). At least two of the three parameters, numValuesPerNode, startTime, and endTime shall be specified.
Table 29 – ReadEventDetails Structure
Name |
Type |
Description |
ReadEventDetails |
Structure |
Specifies the details used to perform an Event history read. |
numValuesPerNode |
Counter |
The maximum number of Events returned for any Node over the time range. If only one time is specified, the time range shall extend to return this number of Events. The default value of 0 indicates that there is no maximum. |
startTime |
UtcTime |
Beginning of period to read. The default value of DateTime.MinValue indicates that the startTime is unspecified. |
endTime |
UtcTime |
End of period to read. The default value of DateTime.MinValue indicates that the endTime is unspecified. |
Filter |
EventFilter |
A filter used by the Server to determine which HistoricalEventNode should be included. This parameter shall be specified and at least one EventField is required. The EventFilter parameter type is an Extensible parameter type. It is defined and used in the same manner as defined for monitored data items which are specified in OPC 10000-4. This filter also specifies the EventFields that are to be returned as part of the request. |
Its representation in the AddressSpace is defined in Table 30.
Table 30 – ReadEventDetails definition
Attribute |
Value |
|||||
BrowseName |
ReadEventDetails |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the HistoryReadDetails defined in Table 28 |
||||||
Conformance Units |
||||||
The ReadEventDetails structure is used to read the Events from the history database for the specified time domain for one or more HistoricalEventNodes. The ReadEventDetails2 can also be used. The Events are filtered based on the filter structure provided. This filter includes the EventFields that are to be returned. For a complete description of filter refer to OPC 10000-4.
The startTime and endTime are used to filter on the Time field for Events.
The time domain of the request is defined by startTime, endTime, and numValuesPerNode; at least two of these shall be specified. If endTime is less than startTime, or endTime and numValuesPerNode alone are specified then the data will be returned in reverse order with later/newer data provided first as if time were flowing backward. If all three are specified then the call shall return up to numValuesPerNode results going from startTime to endTime, in either ascending or descending order depending on the relative values of startTime and endTime. If numValuesPerNode is 0 then all of the Events in the range are returned. The default value of startTime, endTime or numValuesPerNode is used to indicate not specified.
It is specifically allowed for the startTime and the endTime to be identical. This allows the Client to request the Event(s) at a single instance in time. When the startTime and endTime are identical then time is presumed to be flowing forward. If no data exists at the time specified then the Server shall return the Good_NoData StatusCode.
The standard ContinuationPoint rules (see 6.3) apply. In addition, the following ContinuationPoint rule applies to ReadEventDetails. If a startTime, endTime and numValuesPerNode are all provided, and if more than numValuesPerNode Events exist within that time range for a given Node, then only numValuesPerNode Events per Node are returned along with a ContinuationPoint.
For an interval in which no data exists, the corresponding StatusCode shall be Good_NoData.
The filter parameter is used to determine which historical Events and their corresponding fields are returned. It is possible that the fields of an EventType are available for real time updating, but not available from the Historian. In this case a StatusCode value will be returned for any Event field that cannot be returned. The value of the StatusCode shall be Bad_NoData.
When reading Events, TimestampsToReturn only applies to Event fields that are of type DataValue. If the requested TimestampsToReturn is not supported for an Event field then the returned value of the Event field is the Bad_TimestampNotSupported StatusCode.
Table 29 defines the ReadEventDetails2 structure. The structure is a subtype of ReadEventDetails. This subtype only adds the readModified Boolean. The description provided in 6.5.2.2 applies when readModified Boolean is set to FALSE. This updated structure can be used for all event retrieval operations.
ReadEventDetails2 is only valid for Objects that have the EventNotifier Attribute set to TRUE (see OPC 10000-3). At least two of the three parameters, numValuesPerNode, startTime, and endTime shall be specified.
Table 31 – ReadEventDetails2 Structure
Name |
Type |
Description |
ReadEventDetails2 |
Structure |
Specifies the details used to perform an Event history read. |
readModified |
Boolean |
TRUE for Read Modified functionality |
Its representation in the AddressSpace is defined in Table 30.
Table 32 – ReadEventDetails2 definition
Attribute |
Value |
|||||
BrowseName |
ReadEventDetails2 |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the ReadEventDetails |
||||||
Conformance Units |
||||||
When this structure is used for reading ModifiedEvents (isReadModified is set to TRUE), it reads the ModifiedEvents, modification type, the user identifier, and the timestamp of the modification from the history database for the specified time domain for one or more HistoricalDataNodes. If there are multiple replaced Events the Server shall return all of them. The updateType specifies what Event is returned in the modification record. If the updateType is INSERT the Event is the new Event that was inserted. If the updateType is anything else the Event is the old Event that was changed. See 6.9 HistoryUpdateDetails parameter for details on what updateTypes are available.
The purpose of this function is to read Events from history that have been Modified.
The startTime and endTime are used to filter on the Time field for Events.
The domain of the request is defined by startTime, endTime, and numValuesPerNode; at least two of these shall be specified. If endTime is less than startTime, or endTime and numValuesPerNode alone are specified, then the data shall be returned in reverse order with the later data coming first. If all three are specified then the call shall return up to numValuesPerNode results going from StartTime to EndTime, in either ascending or descending order depending on the relative values of StartTime and EndTime. If numValuesPerNode is 0 then all of the Events in the range are returned.
It is specifically allowed for the startTime and the endTime to be identical. This allows the Client to request the Event(s) at a single instance in time. When the startTime and endTime are identical then time is presumed to be flowing forward. If no Events exists at the time specified then the Server shall return the Good_NoData StatusCode.
The standard ContinuationPoint rules (see 6.3) apply. In addition, the following ContinuationPoint rule applies to ReadEventDetails. If a startTime, endTime and numValuesPerNode are all provided, and if more than numValuesPerNode Events exist within that time range for a given Node, then only numValuesPerNode Events per Node are returned along with a ContinuationPoint.
For an interval in which no Events exists, the corresponding StatusCode shall be Good_NoData.
The filter parameter is used to determine which historical Events and their corresponding fields are returned. It is possible that the fields of an EventType are available for real time updating, but not available from the Historian. In this case a StatusCode value will be returned for any Event field that cannot be returned. The value of the StatusCode shall be Bad_NoData.
When reading Events, TimestampsToReturn only applies to Event fields that are of type DataValue. If the requested TimestampsToReturn is not supported for an Event field then the returned value of the Event field is the Bad_TimestampNotSupported StatusCode.
Table 33 defines the ReadEventDetailsSorted structure. The structure is a subtype of the ReadEventDetails Structure defined in 6.5.2, adding a SortClause used to define the order in which events will be returned by the Server. The Server shall use the SortClause to determine how the filtered rows shall be sorted before the results are returned.
Table 33 – ReadEventDetailsSorted Structure
Name |
Type |
Description |
ReadEventDetailsSorted |
Structure |
Specifies the details used to perform an Event history read. |
SortClause |
SortRuleElement[] |
Sorting rules for the filtered notification that match the EventFilter. The priority of the ordering is evaluated by using the position of the elements in this array, starting with the first element. |
Its representation in the AddressSpace is defined in Table 34.
Table 34 – ReadEventDetailsSorted definition
Attribute |
Value |
|||||
BrowseName |
ReadEventDetailsSorted |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the ReadEventDetails defined in 6.5.2 |
||||||
Conformance Units |
||||||
Table 35 defines the ReadRawModifiedDetails structure. Two of the three parameters, numValuesPerNode, startTime, and endTime shall be specified.
Table 35 – ReadRawModifiedDetails structure
Name |
Type |
Description |
ReadRawModifiedDetails |
Structure |
Specifies the details used to perform a “raw” or “modified” history read. |
isReadModified |
Boolean |
TRUE for Read Modified functionality, FALSE for Read Raw functionality. Default value is FALSE. |
startTime |
UtcTime |
Beginning of period to read. Set to default value of DateTime.MinValue if no specific start time is specified. |
endTime |
UtcTime |
End of period to read. Set to default value of DateTime.MinValue if no specific end time is specified. |
numValuesPerNode |
Counter |
The maximum number of values returned for any Node over the time range. If only one time is specified, the time range shall extend to return this number of values. The default value 0 indicates that there is no maximum. |
returnBounds |
Boolean |
A Boolean parameter with the following values: TRUEBounding Values should be returned FALSEAll other cases |
Its representation in the AddressSpace is defined in Table 30.
Table 36 – ReadRawModifiedDetails definition
Attribute |
Value |
|||||
BrowseName |
ReadRawModifiedDetails |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the HistoryReadDetails defined in Table 28 |
||||||
Conformance Units |
||||||
When this structure is used for reading Raw Values (isReadModified is set to FALSE), it reads the values, qualities, and timestamps from the history database for the specified time domain for one or more HistoricalDataNodes. This parameter is intended for use by a Client that wants the actual data saved within the historian. The actual data can be compressed or can be all RawData collected for the item depending on the historian and the storage rules invoked when the item values were saved. When returnBounds is TRUE, the Bounding Values for the time domain are returned. The optional Bounding Values are provided to allow the Client to interpolate values for the start and end times when trending the actual data on a display.
The time domain of the request is defined by startTime, endTime, and numValuesPerNode; at least two of these shall be specified. If endTime is less than startTime, or endTime and numValuesPerNode alone are specified then the data will be returned in reverse order, with later data coming first as if time were flowing backward. If numValuesPerNode is not specified (set to 0), then all the values in the range are returned. A default value of DateTime.MinValue (see Table 35) is used to indicate when startTime or endTime is not specified. When only startTime (or only endTime) and numValuePerNode is specified, the provided time is used as a starting point and the requested number of values is returned.
The standard ContinuationPoint rules (see 6.3) apply. In addition, the following ContinuationPoint rule applies to ReadRawModifiedDetails If a startTime, endTime and numValuesPerNode are all provided and if more than numValuesPerNode values exist within that time range for a given Node then only numValuesPerNode values per Node shall be returned along with a ContinuationPoint.
It is specifically allowed for the startTime and the endTime to be identical. This allows the Client to request just one value. When the startTime and endTime are identical then time is presumed to be flowing forward. It is specifically not allowed for the Server to return a Bad_InvalidArgument StatusCode if the requested time domain is outside of the Server's range. Such a case shall be treated as an interval in which no data exists.
If Bounding Values are requested and a non-zero numValuesPerNode was specified then any Bounding Values returned are included in the numValuesPerNode count. If numValuesPerNode is 1 then only the start bound is returned (the end bound if the reverse order is needed). If numValuesPerNode is 2 then the start bound and the first data point are returned (the end bound if reverse order is needed). When Bounding Values are requested and no bounding value is found then the corresponding StatusCode entry will be set to Bad_BoundNotFound, a timestamp equal to the start or end time as appropriate, and a value of null. How far back or forward to look in history for Bounding Values is Server dependent.
For an interval in which no data exists, if Bounding Values are not requested, then the corresponding StatusCode shall be Good_NoData. If Bounding Values are requested and one or both exist, then the result code returned is Success and the bounding value(s) are returned.
For cases where there are multiple values for a given timestamp, all but the most recent are considered to be ModifiedValues and the Server shall return the most recent value. If the Server returns a value which hides other values at a timestamp then it shall set the ExtraData bit in the StatusCode associated with that value. The additional values can be retrieved with the isReadModified flag set to true, see 6.5.3.3. If the Server contains additional information regarding a value, such as Annotations, then the ExtraData bit shall also be set.
If the requested TimestampsToReturn is not supported for a Node, the operation shall return the Bad_TimestampNotSupported StatusCode.
When this structure is used for reading ModifiedValues (isReadModified is set to TRUE), it reads the ModifiedValues, StatusCodes, timestamps, modification type, the user identifier, and the timestamp of the modification from the history database for the specified time domain for one or more HistoricalDataNodes. If there are multiple replaced values the Server shall return all of them. The updateType specifies what value is returned in the modification record. If the updateType is INSERT the value is the new value that was inserted. If the updateType is anything else the value is the old value that was changed. See 6.9 HistoryUpdateDetails parameter for details on what updateTypes are available.
The purpose of this function is to read values from history that have been Modified. The returnBounds parameter shall be set to FALSE for this case, otherwise the Server returns a Bad_InvalidArgument StatusCode.
The domain of the request is defined by startTime, endTime, and numValuesPerNode; at least two of these shall be specified. If endTime is less than startTime, or endTime and numValuesPerNode alone are specified, then the data shall be returned in reverse order with the later data coming first. If all three are specified then the call shall return up to numValuesPerNode results going from StartTime to EndTime, in either ascending or descending order depending on the relative values of StartTime and EndTime. If numValuesPerNode is 0 then all of the values in the range are returned. If the Server cannot return all ModifiedValues for a given timestamp in a single response then it shall return ModifiedValues with the same timestamp in subsequent calls.
The standard ContinuationPoint rules (see 6.3) apply. In addition, the following ContinuationPoint rule applies to ReadRawModifiedDetails. If more than numValuesPerNode values exist within that time range for a given Node then only numValuesPerNode values per Node are returned along with a ContinuationPoint.
If a value has been modified multiple times then all values for the time are returned. This means that a timestamp can appear in the array more than once. The order of the returned values with the same timestamp should be from the most recent to oldest modification timestamp, if startTime is less than or equal to endTime. If endTime is less than startTime, then the order of the returned values will be from the oldest modification timestamp to the most recent. It is Server dependent whether multiple modifications are kept or only the most recent.
If the requested TimestampsToReturn is not supported for a Node then the operation shall return the Bad_TimestampNotSupported StatusCode.
Table 37 defines the structure of the ReadProcessedDetails structure.
Table 37 – ReadProcessedDetails structure
Name |
Type |
Description |
ReadProcessedDetails |
Structure |
Specifies the details used to perform a “processed” history read. |
startTime |
UtcTime |
Beginning of period to read. |
endTime |
UtcTime |
End of period to read. |
ProcessingInterval |
Duration |
Interval between returned Aggregate values. The value 0 indicates that there is no ProcessingInterval defined. |
aggregateType[] |
NodeId |
The NodeId of the HistoryAggregate object that indicates the list of Aggregates to be used when retrieving the processed history. See OPC 10000-13 for details. |
AggregateConfiguration |
Aggregate Configuration |
Aggregate configuration structure. |
useServerCapabilitiesDefaults |
Boolean |
As described in OPC 10000-4 AggregateFilter Structure. (also see AggregateConfiguration settings defined in OPC 10000-13, and as described in HistorianConfiguration Objects (see 5.2.2). |
TreatUncertainAsBad |
Boolean |
As described in OPC 10000-13. |
PercentDataBad |
Byte |
As described in OPC 10000-13. |
PercentDataGood |
Byte |
As described in OPC 10000-13. |
UseSlopedExtrapolation |
Boolean |
As described in OPC 10000-13. |
See OPC 10000-13 for details on possible NodeId values for the aggregateType parameter.
Its representation in the AddressSpace is defined in Table 30.
Table 38 – ReadProcessedDetails definition
Attribute |
Value |
|||||
BrowseName |
ReadProcessedDetails |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the HistoryReadDetails defined in Table 28 |
||||||
Conformance Units |
||||||
Historical Access Aggregates |
This structure is used to compute Aggregate values, qualities, and timestamps from data in the history database for the specified time domain for one or more HistoricalDataNodes. The time domain is divided into intervals of duration ProcessingInterval. The specified Aggregate Type is calculated for each interval beginning with startTime by using the data within the next ProcessingInterval.
For example, this function can provide hourly statistics such as Maximum, Minimum, and Average for each item during the specified time domain when ProcessingInterval is 1 hour.
The domain of the request is defined by startTime, endTime, and ProcessingInterval. All three shall be specified. If endTime is less than startTime then the data shall be returned in reverse order with the later data coming first. If startTime and endTime are the same then the Server shall return Bad_InvalidArgument as there is no meaningful way to interpret such a case. If the ProcessingInterval is specified as 0 then Aggregates shall be calculated using one interval starting at startTime and ending at endTime.
The aggregateType[] parameter allows a Client to request multiple Aggregate calculations per requested NodeId. If multiple Aggregates are requested then a corresponding number of entries are required in the NodesToRead array.
For example, to request Min Aggregate for NodeId FIC101, FIC102, and both Min and Max Aggregates for NodeId FIC103 would require NodeId FIC103 to appear twice in the NodesToRead array request parameter.
aggregateType[] |
NodesToRead[] |
Min |
FIC101 |
Min |
FIC102 |
Min |
FIC103 |
Max |
FIC103 |
If the array of Aggregates does not match the array of NodesToRead then the Server shall return a StatusCode of Bad_AggregateListMismatch.
The aggregateConfiguration parameter allows a Client to override the Aggregate configuration settings supplied by the AggregateConfiguration Object on a per call basis. See OPC 10000-13 for more information on Aggregate configurations. If the Server does not support the ability to override the Aggregate configuration settings, then it shall return a StatusCode of Bad_ AggregateConfigurationRejected. If the Aggregate is not valid for the Node then the StatusCode shall be Bad_AggregateNotSupported.
The values used in computing the Aggregate for each interval shall include any value that falls exactly on the timestamp at the beginning of the interval, but shall not include any value that falls directly on the timestamp ending the interval. Thus, each value shall be included only once in the calculation. If the time domain is in reverse order, then we consider the later timestamp to be the one beginning the subinterval, and the earlier timestamp to be the one ending it. Note that this means that simply swapping the start and end times will not result in getting the same values back in reverse order as the intervals being requested in the two cases are not the same.
The standard ContinuationPoint rules (see 6.3) apply.
Refer to OPC 10000-13 for handling of Aggregate specific cases. Not all Aggregates can be applied to arrays, for example calculated value Aggregates can not be performed on arrays (e.g. Minimum, Maximum, Average…). Any Aggregate that can not be applied to an array, shall report Bad_NotSupported for the operation result associated with the given NodeId.
Table 39 defines the ReadAtTimeDetails structure.
Table 39 – ReadAtTimeDetails structure
Name |
Type |
Description |
ReadAtTimeDetails |
Structure |
Specifies the details used to perform an “at time” history read. |
reqTimes [] |
UtcTime |
The entries define the specific timestamps for which values are to be read. |
useSimpleBounds |
Boolean |
Use SimpleBounds to determine the value at the specific timestamp. |
Its representation in the AddressSpace is defined in Table 30.
Table 40 – ReadAtTimeDetails definition
Attribute |
Value |
|||||
BrowseName |
ReadAtTimeDetails |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the HistoryReadDetails defined in Table 28 |
||||||
Conformance Units |
||||||
Historical Access Time Instance |
The ReadAtTimeDetails structure reads the values and qualities from the history database for the specified timestamps for one or more HistoricalDataNodes. This function is intended to provide values to correlate with other values with a known timestamp. For example, a Client may need to read the values of sensors when lab samples were collected.
The order of the values and qualities returned shall match the order of the timestamps supplied in the request.
When no value exists for a specified timestamp, a value shall be Interpolated from the surrounding values to represent the value at the specified timestamp. The interpolation will follow the same rules as the standard Interpolated Aggregate as outlined in OPC 10000-13.
If the useSimpleBounds flag is True and Interpolation is required then simple bounding values will be used to calculate the data value. If useSimpleBounds is False and Interpolation is required then interpolated bounding values will be used to calculate the data value. See OPC 10000-13 for the definition of simple bounding values and interpolated bounding values.
If a value is found for the specified timestamp, then the Server will set the StatusCode InfoBits to be Raw. If the value is Interpolated from the surrounding values, then the Server will set the StatusCode InfoBits to be Interpolated.
The standard ContinuationPoint rules (see 6.3) apply.
If the requested TimestampsToReturn is not supported for a Node, then the operation shall return the Bad_TimestampNotSupported StatusCode.
Table 41 defines the ReadAnnotationDataDetails structure. This request is passed using the NodeId of a node that has an Annotations Property.
Table 41 – ReadAnnotationDataDetails Structure
Name |
Type |
Description |
ReadAnnotationDataDetails |
Structure |
Specifies the details used to perform an “at time” history read. |
reqTimes [] |
UtcTime |
The entries define the specific timestamps for which values are to be read. |
Its representation in the AddressSpace is defined in Table 42
Table 42 – ReadAnnotationDataDetails definition
Attribute |
Value |
|||||
BrowseName |
ReadAnnotationDataDetails |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the HistoryReadDetails defined in Table 28 |
||||||
Conformance Units |
||||||
Historical Access Annotations |
The ReadAnnotationDataDetails structure reads the Annotation Data from the history database for the specified timestamps for one or more HistoricalDataNodes. It will return any annotation that is associated with the given HistoricalDataNodes. The ExtraData bit can indicate that an annotation is present at the given time (it can also indicate that data has been modified at the given time). Annotations can also be returned by ReadRawModifiedDetails using the Annotations Property as the NodeId.
The order of the Annotations Data returned shall match the order of the timestamps supplied in the request.
If Annotation Data is not supported for a HistoricalDataNodes then the StatusCode shall be Bad_HistoryOperationUnsupported.
The standard ContinuationPoint rules (see 6.3) apply.
Table 43 defines the SortRuleElement structure. This structure is used by the ReadEventDetailsSorted Structure DataType defined in 6.5.2.5. It is used to define the order in which events are returned from the Server.
Table 43 – SortRuleElement Structure
Name |
Type |
Description |
SortRuleElement |
Structure |
Sorting rule definition that shall be applied to the filtered records. |
sortOrder |
SortOrderType |
Defines ascending or descending sort of the field. Null values are ordered first before other values when using ascending order and last when using descending order. |
eventField |
SimpleAttributeOperand |
Specifies the event fields on which the filtered results shall be sorted. Valid fields shall be in the SortByEventFields Property of HistoricalEventConfigurationType defined in 5.4.3. |
Its representation in the AddressSpace is defined in Table 44.
Table 44 – SortRuleElement definition
Attribute |
Value |
|||||
BrowseName |
SortRuleElement |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of Structure defined in OPC 10000-3 |
||||||
Conformance Units |
||||||
Table 45 defines the SortOrderType enumeration.
Table 45 – SortOrderType Items
Name |
Value |
Description |
Ascending |
0 |
Ascending Order. |
Descending |
1 |
Descending Order. |
Its representation in the AddressSpace is defined in Table 46.
Table 46 – SortOrderType definition
Attribute |
Value |
|||||
BrowseName |
SortOrderType |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the Enumeration type defined in OPC 10000-5 |
||||||
HasProperty |
Variable |
EnumStrings |
LocalizedText [] |
PropertyType |
|
|
Conformance Units |
||||||
The HistoryRead Service returns different types of data depending on whether the request asked for the value Attribute of a Node or the history Events of a Node. The historyData is an Extensible Parameter whose structure depends on the functions to perform for the HistoryReadDetails parameter. See OPC 10000-4 for details on Extensible Parameters.
Table 47 defines the structure of the HistoryData used for the data to return in a HistoryRead.
Table 47 – HistoryData structure
Name |
Type |
Description |
HistoryData |
Structure |
This structured datatype is a subtype of Structure defined in OPC 10000-3 |
dataValues[] |
DataValue |
An array of values of history data for the Node. The size of the array depends on the requested data parameters. |
Its representation in the AddressSpace is defined in Table 30.
Table 48 – HistoryData definition
Attribute |
Value |
|||||
BrowseName |
HistoryData |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the Structure defined in OPC 10000-3 |
||||||
Conformance Units |
||||||
Historical Access Aggregates |
||||||
Historical Access Time Instance |
||||||
Historical Access Read Raw |
Table 49 defines the structure of the HistoryModifiedData used for the data to return in a HistoryRead when IsReadModified = True. This DataType is a subtype of HistoryData.
Table 49 – HistoryModifiedData structure
Name |
Type |
Description |
HistoryModifiedData |
Structure |
This structured datatype is a subtype of HistoryData (see 6.6.2) |
modificationInfos[] |
ModificationInfo |
|
modificationTime |
UtcTime |
The time the modification was made. Support for this field is optional. A null shall be returned if it is not defined. |
updateType |
HistoryUpdateType |
The modification type for the item. |
userName |
String |
The name of the user that made the modification. Support for this field is optional. A null shall be returned if it is not defined. |
Its representation in the AddressSpace is defined in Table 50
Table 50 – HistoryModifiedData definition
Attribute |
Value |
|||||
BrowseName |
HistoryModifiedData |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the HistoryData defined in OPC 10000-3 |
||||||
Conformance Units |
||||||
Historical Access Annotations |
Table 51 defines the HistoryEvent parameter used for Historical Event reads.
The HistoryEvent defines a table structure that is used to return Event fields to a Historical Read. The structure is in the form of a table consisting of one or more Events, each containing an array of one or more fields. The selection and order of the fields returned for each Event are identical to the selected parameter of the EventFilter.
Table 51 – HistoryEvent structure
Name |
Type |
Description |
HistoryEvent |
Structure |
This structured datatype is a subtype of Structure defined in OPC 10000-3 |
Events [] |
HistoryEventFieldList |
The list of Events being delivered. |
eventFields [] |
BaseDataType |
List of selected Event fields. This will be a one-to-one match with the fields selected in the EventFilter. |
Its representation in the AddressSpace is defined in Table 52.
Table 52 – HistoryEvent definition
Attribute |
Value |
|||||
BrowseName |
HistoryEvent |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the Structure defined in OPC 10000-3 |
||||||
Conformance Units |
||||||
Historical Access Events |
||||||
Historical Access Modified Events |
Table 49 defines the structure of the HistoryEvent parameter used for Historical event reads when the readModified = True.
The HistoryModifyEvent defines a table structure that is used to return Event fields along with modification information to a Historical Read. The structure is in the form of a table consisting of one or more Events, each containing an array of one or more fields. The selection and order of the fields returned for each Event are identical to the selected parameter of the EventFilter. For each Event a modificationInfo record is also returned.
Table 53 – HistoryModifiedEvent structure
Name |
Type |
Description |
HistoryModifiedEvent |
Structure |
This structured datatype is a subtype of HistoryEvent |
modificationInfos[] |
ModificationInfo |
List of modifications (one record for each Event) |
modificationTime |
UtcTime |
The time the modification was made. Support for this field is optional. A null shall be returned if it is not defined. |
updateType |
HistoryUpdateType |
The modification type for the item. |
userName |
String |
The name of the user that made the modification. Support for this field is optional. A null shall be returned if it is not defined. |
Its representation in the AddressSpace is defined in Table 54.
Table 54 – HistoryModifiedEvent definition
Attribute |
Value |
|||||
BrowseName |
HistoryModifiedEvent |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the HistoryEvent |
||||||
Conformance Units |
||||||
Historical Access Modified Events |
Table 47 defines the structure of the Annotation used for the data to return in a HistoryRead.
This DataType describes Annotation structure information for the history data items. Its elements are defined in Table 55.
Table 55 – Annotation Structure
Name |
Type |
Description |
Annotation |
Structure |
|
message |
String |
Annotation message or text. |
userName |
String |
The user that added the Annotation, as supplied by the underlying system. |
annotationTime |
UtcTime |
The time the Annotation was added. This will probably be different than the SourceTimestamp. |
Its representation in the AddressSpace is defined in Table 56.
Table 56 – Annotation definition
Attribute |
Value |
|||||
BrowseName |
Annotation |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the Structure defined in OPC 10000-3 |
||||||
Conformance Units |
||||||
Historical Access Annotations |
Table 57 defines the HistoryUpdate enumeration.
Table 57 – HistoryUpdateType Items
Name |
Value |
Description |
INSERT |
1 |
Data was inserted. |
REPLACE |
2 |
Data was replaced. |
UPDATE |
3 |
Data was inserted or replaced. |
DELETE |
4 |
Data was deleted. |
Its representation in the AddressSpace is defined in Table 58.
Table 58 – HistoryUpdateType definition
Attribute |
Value |
|||||
BrowseName |
HistoryUpdateType |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the 0:Enumeration type defined in OPC 10000-5 |
||||||
0:HasProperty |
Variable |
0:EnumValues |
0:EnumValueType [] |
0:PropertyType |
|
|
Conformance Units |
||||||
Historical Access Modified Events |
||||||
Table 59 defines the PerformUpdateType enumeration.
Table 59 – PerformUpdateType Items
Name |
Value |
Description |
INSERT |
1 |
Data was inserted. |
REPLACE |
2 |
Data was replaced. |
UPDATE |
3 |
Data was inserted or replaced. |
REMOVE |
4 |
Data was deleted. |
Its representation in the AddressSpace is defined in Table 58.
Table 60 – PerformUpdateType definition
Attribute |
Value |
|||||
BrowseName |
PerformUpdateType |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the 0:Enumeration type defined in OPC 10000-5 |
||||||
0:HasProperty |
Variable |
0:EnumValues |
0:EnumValueType [] |
0:PropertyType |
|
|
Conformance Units |
||||||
Historical Access Insert Value |
||||||
Historical Access Delete Value |
||||||
Historical Access Update Value |
||||||
Historical Access Replace Value |
The HistoryUpdate Service defined in OPC 10000-4 can perform several different functions. The historyUpdateDetails parameter is an Extensible Parameter that specifies which function to perform and the details that are specific to that function. See OPC 10000-4 for the definition of Extensible Parameter. Table 61 lists the symbolic names of the valid Extensible Parameter structures. Some structures will perform different functions based on the setting of its associated parameters. For simplicity a functionality of each structure is listed. For example, text such as ‘using the Replace data functionality’ refers to the function the HistoryUpdate Service performs using the Extensible Parameter structure UpdateDataDetails with the performInsertReplace enumeration parameter set to REPLACE.
Table 61 – HistoryUpdateDetails parameter Symbolic Names
Symbolic Name |
Functionality |
Description |
UpdateDataDetails |
Insert data |
This function inserts new values into the history database at the specified timestamps for one or more HistoricalDataNodes The Variable’s value is represented by a composite value defined by the DataValue data type. |
UpdateDataDetails |
Replace data |
This function replaces existing values into the history database at the specified timestamps for one or more HistoricalDataNodes. The Variable’s value is represented by a composite value defined by the DataValue data type. |
UpdateDataDetails |
Update data |
This function inserts or replaces values into the history database at the specified timestamps for one or more HistoricalDataNodes. The Variable’s value is represented by a composite value defined by the DataValue data type. |
UpdateStructureDataDetails |
Insert data |
This function inserts new StructuredHistoryData or Annotations into the history database at the specified timestamps for one or more HistoricalDataNodes. The Variable’s value is represented by a composite value defined by the DataValue data type. |
UpdateStructureDataDetails |
Replace data |
This function replaces existing StructuredHistory Data or Annotations into the history database at the specified timestamps for one or more HistoricalDataNodes. The Variable’s value is represented by a composite value defined by the DataValue data type. |
UpdateStructureDataDetails |
Update data |
This function inserts or replaces StructuredHistoryData or Annotations into the history database at the specified timestamps for one or more HistoricalDataNodes. The Variable’s value is represented by a composite value defined by the DataValue data type. |
UpdateStructureDataDetails |
Remove data |
This function removes StructuredHistoryData or Annotations from the history database at the specified timestamps for one or more HistoricalDataNodes. The Variable’s value is represented by a composite value defined by the DataValue data type. |
UpdateEventDetails |
Insert events |
This function inserts new Events into the history database for one or more HistoricalEventNodes. |
UpdateEventDetails |
Replace events |
This function replaces values of fields in existing Events into the history database for one or more HistoricalEventNodes. |
UpdateEventDetails |
Update events |
This function inserts new Events or replaces existing Events in the history database for one or more HistoricalEventNodes. |
DeleteRawModifiedDetails |
Delete raw |
This function deletes all values from the history database for the specified time domain for one or more HistoricalDataNodes. |
DeleteRawModifiedDetails |
Delete modified |
Some historians can store multiple values at the same Timestamp. This function will delete specified values and qualities for the specified timestamp for one or more HistoricalDataNodes. |
DeleteAtTimeDetails |
Delete at time |
This function deletes all values in the history database for the specified timestamps for one or more HistoricalDataNodes. |
DeleteEventDetails |
Delete event |
This function deletes Events from the history database for the specified filter for one or more HistoricalEventNodes. |
The HistoryUpdate Service is used to update or delete, DataValues, Annotations or Events. For simplicity the term “entry” will be used to mean either DataValue, Annotation, or Event depending on the context in which it is used. Auditing requirements for History Services are described in OPC 10000-4. This description assumes the user issuing the request and the Server that is processing the request support the capability to update entries. See OPC 10000-3 for a description of Attributes that expose the support of Historical Updates.
If the HistoryUpdate Service is called with two or more of DataValues, Events or Annotations in the same call the Server operational limits MaxNodesPerHistoryUpdateData and MaxNodesPerHistoryUpdateEvents (defined in OPC 10000-5) can be ignored. The Server can return the service result code Bad_TooManyOperations if it is not able to handle the combination of DataValues, Events or Annotations. It is recommended to call the HistoryUpdate Service individually with DataValues, Events or Annotations.
Table 62 defines the HistoryUpdateDetails structure.
Table 62 – HistoryUpdateDetails Structure
Name |
Type |
Description |
HistoryUpdateDetails |
Structure |
|
|
|
|
Its representation in the AddressSpace is defined in Table 63.
Table 63 – HistoryUpdateDetails definition
Attribute |
Value |
|||||
BrowseName |
HistoryUpdateDetails |
|||||
IsAbstract |
True |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the Structure DataType defined in OPC 10000-3 |
||||||
Conformance Units |
||||||
Historical Access Update Value |
Table 64 defines the UpdateDataDetails structure.
Table 64 – UpdateDataDetails Structure
Name |
Type |
Description |
UpdateDataDetails |
Structure |
The details for insert, replace, and insert/replace history updates. |
nodeId |
NodeId |
Node id of the Object to be updated. |
performInsertReplace |
PerformUpdateType |
This enumeration determines which action of Insert, Replace, or Update is performed. The Delete enumerated value is not allowed and will result in a Bad_InvalidArgument error. |
updateValues[] |
DataValue |
New values to be inserted or to replace. |
Its representation in the AddressSpace is defined in Table 65.
Table 65 – UpdateDataDetails definition
Attribute |
Value |
|||||
BrowseName |
UpdateDataDetails |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the HistoryUpdateDetails DataType defined in Table 62. |
||||||
Conformance Units |
||||||
Historical Access Insert Value |
||||||
Historical Access Delete Value |
||||||
Historical Access Update Value |
||||||
Historical Access Replace Value |
||||||
|
Setting performInsertReplace = INSERT inserts entries into the history database at the specified timestamps for one or more HistoricalDataNodes. If an entry exists at the specified timestamp, then the new entry shall not be inserted; instead the StatusCode shall indicate Bad_EntryExists.
This function is intended to insert new entries at the specified timestamps, e.g., the insertion of lab data to reflect the time of data collection.
If the Time does not fall within range that can be stored then the related operationResults entry shall indicate Bad_OutOfRange.
Setting performInsertReplace = REPLACE replaces entries in the history database at the specified timestamps for one or more HistoricalDataNodes. If no entry exists at the specified timestamp, then the new entry shall not be inserted; otherwise, the StatusCode shall indicate Bad_NoEntryExists.
This function is intended to replace existing entries at the specified timestamp, e.g., correct lab data that was improperly processed, but inserted into the history database.
Setting performInsertReplace = UPDATE inserts or replaces entries in the history database for the specified timestamps for one or more HistoricalDataNodes. If the item has an entry at the specified timestamp, then the new entry will replace the old one. If there is no entry at that timestamp, then the function will insert the new data.
A Server can create a modified value for a value being replaced or inserted (see 3.1.7) however it is not required.
This function is intended to unconditionally insert/replace values and qualities, e.g., correction of values for bad sensors.
Good as a StatusCode for an individual entry is allowed when the Server is unable to say whether there was already a value at that timestamp. If the Server can determine whether the new entry replaces an entry that was already there, then it should use Good_EntryInserted or Good_EntryReplaced to return that information.
If the Time does not fall within range that can be stored then the related operationResults entry shall indicate Bad_OutOfRange.
Table 64 defines the UpdateStructureDataDetails structure.
Table 66 – UpdateStructureDataDetails Structure
Name |
Type |
Description |
UpdateStructureDataDetails |
Structure |
The details for Structured Data History updates. |
nodeId |
NodeId |
Node id of the Object to be updated. |
performInsertReplace |
PerformUpdateType |
Value determines which action of insert, replace, or update is performed. |
updateValues[] |
DataValue |
New values to be inserted, replaced or removed. Such as Annotation data for Annotations. |
Its representation in the AddressSpace is defined in Table 67.
Table 67 – UpdateStructureDataDetails definition
Attribute |
Value |
|||||
BrowseName |
UpdateStructureDataDetails |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the HistoryUpdateDetails DataType defined in Table 62. |
||||||
Conformance Units |
||||||
Historical Access Structured Data Replace |
||||||
Historical Access Structured Data Update |
||||||
Historical Access Structured Data Insert |
StructuredHistoryData provides metadata describing an entry in the history database. The Server shall define what uniqueness means for each StructuredHistoryData structure type. For example, a Server can only allow one Annotation per timestamp which means the timestamp is the unique key for the structure. Another Server can allow Annotations to exist per user, so a combination of a username and timestamp can be used as the unique key for the structure. In 6.8.3.3, 6.8.3.4, 6.8.3.5, and 6.8.3.6 the terms ‘StructuredHistoryData exists’ and ‘at the specified parameters’ means a matching entry has been found at the specified timestamp using the Server’s criteria for uniqueness.
In the case where the Client wishes to replace a parameter that is part of the uniqueness criteria, then the resulting StatusCode would be Bad_NoEntryExists. The Client shall remove the existing structure and then Insert the new structure.
Setting performInsertReplace = INSERT inserts StructuredHistoryData such as Annotations into the history database at the specified parameters for one or more Properties of HistoricalDataNodes.
If a StructuredHistoryData entry already exists at the specified parameters the StatusCode shall indicate Bad_EntryExists.
If the Time does not fall within range that can be stored then the related operationResults entry shall indicate Bad_OutOfRange.
Setting performInsertReplace = REPLACE replaces StructuredHistoryData such as Annotations in the history database at the specified parameters for one or more Properties of HistoricalDataNodes.
If a StructuredHistoryData entry does not already exist at the specified parameters, then the StatusCode shall indicate Bad_NoEntryExists.
Setting performInsertReplace = UPDATE inserts or replaces StructuredHistoryData such as Annotations in the history database at the specified parameters for one or more Properties of HistoricalDataNodes.
If a StructureHistoryData entry already exists at the specified parameters then it is deleted and the value provided by the Client is inserted. If no existing entry exists then the new entry is inserted.
If an existing entry was replaced successfully then the StatusCode shall be Good_EntryReplaced. If a new entry was created the StatusCode shall be Good_EntryInserted. If the Server cannot determine whether it replaced or inserted an entry then the StatusCode shall be Good.
If the Time does not fall within range that can be stored then the related operationResults entry shall indicate Bad_OutOfRange.
Setting performInsertReplace = REMOVE removes StructuredHistoryData such as Annotations from the history database at the specified parameters for one or more Properties of HistoricalDataNodes.
If a Structure History Data entry exists at the specified parameters it is deleted. If StructuredHistoryData does not already exist at the specified parameters, then the StatusCode shall indicate Bad_NoEntryExists.
Table 68 defines the UpdateEventDetails structure.
Table 68 – UpdateEventDetails Structure
Name |
Type |
Description |
UpdateEventDetails |
Structure |
The details for insert, replace, and insert/replace history Event updates. |
nodeId |
NodeId |
Node id of the Object to be updated. |
performInsertReplace |
PerformUpdateType |
Value determines which action of insert, replace, or update is performed. The Delete enumeration value is not allow and will result in a Bad_InvalidArgument error. |
filter |
EventFilter |
If the history of Notification conforms to the EventFilter, the history of the Notification is updated. |
eventData[] |
HistoryEventFieldList |
List of Event Notifications to be inserted or updated (see 6.6.4 for HistoryEventFieldList definition). |
Its representation in the AddressSpace is defined in Table 69.
Table 69 – UpdateEventDetails definition
Attribute |
Value |
|||||
BrowseName |
UpdateEventDetails |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the HistoryUpdateDetails DataType defined in Table 62. |
||||||
Conformance Units |
||||||
Historical Access Replace Event |
||||||
Historical Access Update Event |
||||||
Historical Access Insert Event |
This function is intended to insert new entries, e.g., backfilling of historical Events.
Setting performInsertReplace = INSERT inserts entries into the Event history database for one or more HistoricalEventNodes. The whereClause parameter of the EventFilter shall be empty. The selectClause shall, as a minimum, provide the following Event fields: EventType, and Time. It is also recommended that the SourceNode and the SourceName fields are provided.
If one of the required fields is not provided then the statusCode shall indicate Bad_ArgumentsMissing. If the historian does not support archiving the specified EventType then the statusCode shall indicate Bad_TypeDefinitionInvalid. If the SourceNode is not a valid source for Events then the related operationResults entry shall indicate Bad_SourceNodeIdInvalid. If the Time does not fall within a range that can be stored then the related operationResults entry shall indicate Bad_OutOfRange. The selectClause shall include all mandatory fields that are configured to be stored for the EventType. If the selectClause does not include a mandatory field then the statusCode shall indicate Bad_ArgumentsMissing. If the selectClause specifies fields which are not valid for the EventType or cannot be saved by the Historian then the related operationResults entry shall indicate Good_DataIgnored. Additional information about the ignored fields shall be provided through DiagnosticInformation related to the operationResults. The symbolicId contains the index of each ignored field separated with a space and the localizedText contains the symbolic names of the ignored fields.
The EventId is a Server generated opaque value and a Client cannot assume that it knows how to create unique EventIds. A Server shall automatically generate an EventId when not provided by the Client. If a Client does specify the EventId in the selectClause and it matches an existing EventId then the statusCode shall indicate Bad_EntryExists.
If any errors occur while processing individual fields then the related operationResults entry shall indicate Bad_InvalidArgument and the invalid fields shall be indicated in the DiagnosticInformation related to the operationResults entry.
The IndexRange parameter of the SimpleAttributeOperand is not valid for insert operations and the StatusCode shall specify Bad_IndexRangeInvalid if one is specified.
A Client can instruct the Server to choose a suitable default value for a field by specifying a value of null. If the Server is not able to select a suitable default then the corresponding entry in the operationResults array for the affected Event shall be Bad_InvalidArgument.
This function is intended to replace fields in existing Event entries, e.g., correct Event data that contained incorrect data due to a bad sensor.
Setting performInsertReplace = REPLACE replaces entries in the Event history database for the specified EventIds for one or more HistoricalEventNodes. The selectClause parameter of the EventFilter shall specify the EventId Property and the eventData shall contain the EventId which will be used to find the Event to be replaced. If no entry exists matching the specified EventId then no replace operation will be performed; instead, the operationResults entry for the eventData entry shall indicate Bad_NoEntryExists. The whereClause parameter of the EventFilter shall be empty.
If the selectClause specifies fields which are not valid for the EventType or cannot be saved or changed by the historian then the operationResults entry for the affected Event shall indicate Good_DataIgnored. Additional information about the ignored fields shall be provided through DiagnosticInformation related to the operationResults. The symbolicId contains the index of each ignored field separated with a space and the localizedText contains the symbolic names of the ignored fields.
If fatal errors occur while processing individual fields then the operationResults entry for the affected Event shall indicate Bad_InvalidArgument and the invalid fields shall be indicated in the DiagnosticInformation related to the operationResults entry.
This function is intended to unconditionally insert/replace Events.
Setting performInsertReplace = UPDATE inserts or replaces entries in the Event history database for the specified filter for one or more HistoricalEventNodes.
The Server will, based on its own criteria, attempt to determine if the Event already exists; if it does exist then the Event will be deleted and the new Event will be inserted (retaining the EventId). If the EventID was provided then the EventID will be used to determine if the Event already exists. If the Event does not exist then a new Event will be inserted, including the generation of a new EventId, if the provided EventId does not match the unique requirements in the Server for EventIds.
All of the restrictions, behaviours, and errors specified for the Insert functionality (see 6.9.4.2) also apply to this function.
If an existing Event entry was replaced successfully then the related operationResults entry shall be Good_EntryReplaced. If a new Event entry was created then the related operationResults entry shall be Good_EntryInserted. If the Server cannot determine whether it replaced or inserted an entry then the related operationResults entry shall be Good.
Table 70 defines the DeleteRawModifiedDetails structure.
Table 70 – DeleteRawModifiedDetails Structure
Name |
Type |
Description |
DeleteRawModifiedDetails |
Structure |
The details for delete raw and delete modified history updates. |
nodeId |
NodeId |
Node id of the Object for which history values are to be deleted. |
isDeleteModified |
Boolean |
TRUE for MODIFIED, FALSE for RAW. Default value is FALSE. |
startTime |
UtcTime |
Beginning of period to be deleted. |
endTime |
UtcTime |
End of period to be deleted. |
Its representation in the AddressSpace is defined in Table 71.
Table 71 – DeleteRawModifiedDetails definition
Attribute |
Value |
|||||
BrowseName |
DeleteRawModifiedDetails |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the HistoryUpdateDetails DataType defined in Table 62. |
||||||
Conformance Units |
||||||
Historical Access Delete Value |
These functions are intended to be used to delete data that has been accidentally entered into the history database, e.g., deletion of data from a source with incorrect timestamps. Both startTime and endTime shall be defined. The startTime shall be less than the endTime, and values up to but not including the endTime are deleted. It is permissible for startTime = endTime, in which case the value at the startTime is deleted.
Setting isDeleteModified = FALSE deletes all Raw entries from the history database for the specified time domain for one or more HistoricalDataNodes.
If no data is found in the time range for a particular HistoricalDataNode, then the StatusCode for that item is Bad_NoData.
Setting isDeleteModified = TRUE deletes all Modified entries from the history database for the specified time domain for one or more HistoricalDataNodes.
If no data is found in the time range for a particular HistoricalDataNode, then the StatusCode for that item is Bad_NoData.
Table 72 defines the structure of the DeleteAtTimeDetails structure.
Table 72 – DeleteAtTimeDetails Structure
Name |
Type |
Description |
DeleteAtTimeDetails |
Structure |
The details for delete raw history updates. |
nodeId |
NodeId |
Node id of the Object for which history values are to be deleted. |
reqTimes [] |
UtcTime |
The entries define the specific timestamps for which values are to be deleted. |
Its representation in the AddressSpace is defined in Table 30.
Table 73 – DeleteAtTimeDetails definition
Attribute |
Value |
|||||
BrowseName |
DeleteAtTimeDetails |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the HistoryUpdateDetails DataType defined in Table 62. |
||||||
Conformance Units |
||||||
Historical Access Delete Value |
The DeleteAtTime structure deletes all raw values, ModifiedValues, and Annotations in the history database for the specified timestamps for one or more HistoricalDataNodes.
This parameter is intended to be used to delete specific data from the history database, e.g., lab data that is incorrect and cannot be correctly reproduced.
Table 74 defines the structure of the DeleteEventDetails structure.
Table 74 – DeleteEventDetails Structure
Name |
Type |
Description |
DeleteEventDetails |
Structure |
The details for delete raw and delete modified history updates. |
nodeId |
NodeId |
Node id of the Object for which history values are to be deleted. |
eventIds [] |
ByteString |
An array of EventIds to identify which Events are to be deleted. |
Its representation in the AddressSpace is defined in Table 30.
Table 75 – DeleteEventDetails definition
Attribute |
Value |
|||||
BrowseName |
DeleteEventDetails |
|||||
IsAbstract |
False |
|||||
References |
NodeClass |
BrowseName |
DataType |
TypeDefinition |
Other |
|
Subtype of the HistoryUpdateDetails DataType defined in Table 62. |
||||||
Conformance Units |
||||||
Historical Access Delete Event |
The DeleteEventDetails structure deletes all Event entries from the history database matching the EventId for one or more HistoricalEventNodes.
If no Events are found that match the specified filter for a HistoricalEventNode, then the StatusCode for that Node is Bad_NoData.