Dive into secure and efficient coding practices with our curated list of the top 10 examples showcasing 'node-opcua-service-history' in functional components in JavaScript. Our advanced machine learning engine meticulously scans each line of code, cross-referencing millions of open source libraries to ensure your implementation is not just functional, but also robust and secure. Elevate your React applications to new heights by mastering the art of handling side effects, API calls, and asynchronous operations with confidence and precision.
assert(context instanceof SessionContext);
assert(callback instanceof Function);
const nodeId = nodeToRead.nodeId;
const indexRange = nodeToRead.indexRange;
const dataEncoding = nodeToRead.dataEncoding;
const continuationPoint = nodeToRead.continuationPoint;
timestampsToReturn = (_.isObject(timestampsToReturn)) ? timestampsToReturn : TimestampsToReturn.Neither;
const obj = this.__findObject(nodeId) as UAVariable;
if (!obj) {
// may be return BadNodeIdUnknown in dataValue instead ?
// Object Not Found
callback(null, new HistoryReadResult({ statusCode: StatusCodes.BadNodeIdUnknown }));
return;
} else {
if (!obj.historyRead) {
// note : Object and View may also support historyRead to provide Event historical data
// todo implement historyRead for Object and View
const msg = " this node doesn't provide historyRead! probably not a UAVariable\n "
+ obj.nodeId.toString() + " " + obj.browseName.toString() + "\n"
+ "with " + nodeToRead.toString() + "\n"
+ "HistoryReadDetails " + historyReadDetails.toString();
if (doDebug) {
console.log(chalk.cyan("ServerEngine#_historyReadSingleNode "),
chalk.white.bold(msg));
}
const err = new Error(msg);
});
return callback(null, result);
}
} else if (isMinDate(historyReadRawModifiedDetails.startTime!)) {
// start time is not specified
// end time is specified
maxNumberToExtract = historyReadRawModifiedDetails.numValuesPerNode;
isReversed = true;
reverseDataValue = false;
if (historyReadRawModifiedDetails.numValuesPerNode === 0) {
// when start time is not specified
// and end time is specified
// numValuesPerNode shall be greater than 0
const result = new HistoryReadResult({
statusCode: StatusCodes.BadHistoryOperationUnsupported // should be an error
});
return callback(null, result);
}
} else {
// start time is specified
// end time is specified
if (historyReadRawModifiedDetails.endTime!.getTime() < historyReadRawModifiedDetails.startTime!.getTime()) {
reverseDataValue = true;
const tmp = historyReadRawModifiedDetails.endTime;
historyReadRawModifiedDetails.endTime = historyReadRawModifiedDetails.startTime;
historyReadRawModifiedDetails.startTime = tmp;
}
}
node._historyReadRawAsync(
(err: Error | null, dataValues?: DataValue[]) => {
if (err || !dataValues) {
return callback(err);
}
// now make sure that only the requested number of value is returned
if (historyReadRawModifiedDetails.numValuesPerNode >= 1) {
if (dataValues.length === 0) {
const result1 = new HistoryReadResult({
historyData: new HistoryData({ dataValues: [] }),
statusCode: StatusCodes.GoodNoData
});
return callback(null, result1);
} else {
const remaining = dataValues;
dataValues = remaining.splice(0, historyReadRawModifiedDetails.numValuesPerNode);
if (remaining.length > 0 && !isMinDate(historyReadRawModifiedDetails.endTime)) {
continuationPoint = createContinuationPoint();
context.continuationPoints = context.continuationPoints || {};
context.continuationPoints[continuationPoint.toString("hex")] = {
dataValues: remaining
};
}
}
if (!cnt) {
// invalid continuation point
const result1 = new HistoryReadResult({
historyData: new HistoryData({ dataValues: [] }),
statusCode: StatusCodes.BadContinuationPointInvalid
});
return callback(null, result1);
}
const dataValues = cnt.dataValues.splice(0, historyReadRawModifiedDetails.numValuesPerNode);
if (cnt.dataValues.length > 0) {
//
} else {
context.continuationPoints[continuationPoint.toString("hex")] = null;
continuationPoint = null;
}
const result2 = new HistoryReadResult({
continuationPoint: continuationPoint || undefined,
historyData: new HistoryData({ dataValues }),
statusCode: StatusCodes.Good
});
return callback(null, result2);
}
// todo add special treatment for when startTime > endTime
// ( in this case series must be return in reverse order )
let maxNumberToExtract = 0;
let isReversed = false;
let reverseDataValue = false;
if (isMinDate(historyReadRawModifiedDetails.endTime!)) {
// end time is not specified
maxNumberToExtract = historyReadRawModifiedDetails.numValuesPerNode;
// 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.
// A Server does not have to create a modification record for data when it is first added to the
// historical collection. If it does then it shall set the ExtraData bit and the Client can read the
// modification record using a ReadModified call. If the data is subsequently modified the Server
// shall create a second modification record which is returned along with the original
// modification record whenever a Client uses the ReadModified call if the Server supports
// multiple modification records per timestamp.
// If the requested TimestampsToReturn is not supported for a Node then the operation shall
// return the BadTimestampNotSupported StatusCode.
// todo : provide correct implementation
const result = new HistoryReadResult({
historyData: new HistoryData({ dataValues: [] }),
statusCode: StatusCodes.BadUnexpectedError
});
return callback(null, result);
}
// For cases where there are multiple values for a given timestamp, all but the most recent are
// considered to be Modified values 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. If the Server contains additional information
// regarding a value then the ExtraData bit shall also be set. It indicates that ModifiedValues are
// available for retrieval, see 6.4.3.3.
//
// If the requested TimestampsToReturn is not supported for a Node, the operation shall return
// the Bad_TimestampNotSupported StatusCode.
if (continuationPoint) {
const cnt = context.continuationPoints
? context.continuationPoints[continuationPoint.toString("hex")] : null;
if (!cnt) {
// invalid continuation point
const result1 = new HistoryReadResult({
historyData: new HistoryData({ dataValues: [] }),
statusCode: StatusCodes.BadContinuationPointInvalid
});
return callback(null, result1);
}
const dataValues = cnt.dataValues.splice(0, historyReadRawModifiedDetails.numValuesPerNode);
if (cnt.dataValues.length > 0) {
//
} else {
context.continuationPoints[continuationPoint.toString("hex")] = null;
continuationPoint = null;
}
const result2 = new HistoryReadResult({
continuationPoint: continuationPoint || undefined,
historyData: new HistoryData({ dataValues }),
statusCode: StatusCodes.Good
(err: Error | null, result?: any) => {
if (err && !result) {
result = new HistoryReadResult({ statusCode: StatusCodes.BadInternalError });
}
historyData.push(result);
async.setImmediate(cbNode);
// it's not guaranteed that the historical read process is really asynchronous
});
}, (err?: Error | null) => {
// follow the same rules as the standard Interpolated Aggregate as outlined in Part 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
// Part 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.
// If the read request is taking a long time to calculate then the Server may return zero results
// with a ContinuationPoint that allows the Server to resume the calculation on the next Client
// HistoryRead call.
// If the requested TimestampsToReturn is not supported for a Node, then the operation shall
// return the Bad_TimestampNotSupported StatusCode.
// todo provide correct implementation
const result = new HistoryReadResult({
historyData: new HistoryData({ dataValues: [] }),
statusCode: StatusCodes.BadHistoryOperationUnsupported
});
return callback(null, result);
} else {
const result = new HistoryReadResult({
historyData: new HistoryData({ dataValues: [] }),
statusCode: StatusCodes.BadHistoryOperationUnsupported
});
return callback(null, result);
}
}
// 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 sub interval, 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.
// If an Aggregate is taking a long time to calculate then the Server can return partial results
// with a continuation point. This might be done if the calculation is going to take more time th an
// the Client timeout hint. In some cases it may take longer than the Client timeout hint to
// calculate even one Aggregate result. Then the Server may return zero results with a
// continuation point that allows the Server to resume the calculation on the next Client read
// call.
// todo provide correct implementation
const result = new HistoryReadResult({
historyData: new HistoryData({ dataValues: [] }),
statusCode: StatusCodes.BadHistoryOperationUnsupported
});
return callback(null, result);
} else if (historyReadDetails instanceof ReadAtTimeDetails) {
// Release 1.03 28 OPC Unified Architecture, Part 11
// 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 Part 13.
// considered to be Modified values 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. If the Server contains additional information
// regarding a value then the ExtraData bit shall also be set. It indicates that ModifiedValues are
// available for retrieval, see 6.4.3.3.
//
// If the requested TimestampsToReturn is not supported for a Node, the operation shall return
// the Bad_TimestampNotSupported StatusCode.
if (continuationPoint) {
const cnt = context.continuationPoints
? context.continuationPoints[continuationPoint.toString("hex")] : null;
if (!cnt) {
// invalid continuation point
const result1 = new HistoryReadResult({
historyData: new HistoryData({ dataValues: [] }),
statusCode: StatusCodes.BadContinuationPointInvalid
});
return callback(null, result1);
}
const dataValues = cnt.dataValues.splice(0, historyReadRawModifiedDetails.numValuesPerNode);
if (cnt.dataValues.length > 0) {
//
} else {
context.continuationPoints[continuationPoint.toString("hex")] = null;
continuationPoint = null;
}
const result2 = new HistoryReadResult({
continuationPoint: continuationPoint || undefined,
historyData: new HistoryData({ dataValues }),
statusCode: StatusCodes.Good
});