node-opcua-aggregates 2.54.0 → 2.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/.mocharc.yml +7 -7
  2. package/LICENSE +20 -20
  3. package/bin/sample_aggregate_server.js +14 -14
  4. package/dist/aggregates.js +2 -2
  5. package/dist/aggregates.js.map +1 -1
  6. package/dist/average.js +6 -5
  7. package/dist/average.js.map +1 -1
  8. package/dist/common.js +12 -2
  9. package/dist/common.js.map +1 -1
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/interpolate.d.ts +1 -1
  13. package/dist/interpolate.js +8 -12
  14. package/dist/interpolate.js.map +1 -1
  15. package/dist/minmax.js +3 -2
  16. package/dist/minmax.js.map +1 -1
  17. package/dist/read_processed_details.d.ts +2 -2
  18. package/dist/read_processed_details.js +41 -38
  19. package/dist/read_processed_details.js.map +1 -1
  20. package/nyc.config.js +16 -16
  21. package/package.json +17 -15
  22. package/source/aggregates.ts +284 -277
  23. package/source/average.ts +71 -74
  24. package/source/common.ts +23 -10
  25. package/source/index.ts +11 -17
  26. package/source/interpolate.ts +14 -20
  27. package/source/interval.ts +3 -3
  28. package/source/minmax.ts +231 -231
  29. package/source/read_processed_details.ts +149 -139
  30. package/dist2/aggregates.d.ts +0 -7
  31. package/dist2/aggregates.js +0 -201
  32. package/dist2/aggregates.js.map +0 -1
  33. package/dist2/average.d.ts +0 -3
  34. package/dist2/average.js +0 -61
  35. package/dist2/average.js.map +0 -1
  36. package/dist2/common.d.ts +0 -8
  37. package/dist2/common.js +0 -89
  38. package/dist2/common.js.map +0 -1
  39. package/dist2/index.d.ts +0 -11
  40. package/dist2/index.js +0 -29
  41. package/dist2/index.js.map +0 -1
  42. package/dist2/interpolate.d.ts +0 -16
  43. package/dist2/interpolate.js +0 -135
  44. package/dist2/interpolate.js.map +0 -1
  45. package/dist2/interval.d.ts +0 -49
  46. package/dist2/interval.js +0 -165
  47. package/dist2/interval.js.map +0 -1
  48. package/dist2/minmax.d.ts +0 -18
  49. package/dist2/minmax.js +0 -149
  50. package/dist2/minmax.js.map +0 -1
  51. package/dist2/read_processed_details.d.ts +0 -6
  52. package/dist2/read_processed_details.js +0 -116
  53. package/dist2/read_processed_details.js.map +0 -1
package/source/average.ts CHANGED
@@ -1,74 +1,71 @@
1
- import { UAVariable } from "node-opcua-address-space";
2
- import { DataValue } from "node-opcua-data-value";
3
- import { Variant, DataType } from "node-opcua-variant";
4
- import { getAggregateData } from "./common";
5
- import { Interval, AggregateConfigurationOptions, isGood } from "./interval";
6
- import { StatusCode, StatusCodes } from "node-opcua-status-code";
7
-
8
- function calculateIntervalAverageValue(
9
- interval: Interval,
10
- options: AggregateConfigurationOptions
11
- ): DataValue {
12
-
13
- const indexStart = interval.index;
14
- let statusCode: StatusCode;
15
- let isPartial = interval.isPartial;
16
-
17
- let isRaw = false;
18
- let hasBad = false;
19
-
20
- const values: number[] = [];
21
-
22
- for (let i = indexStart; i < indexStart + interval.count; i++) {
23
-
24
- const dataValue = interval.dataValues[i];
25
-
26
- if (dataValue.statusCode === StatusCodes.BadNoData) {
27
- isPartial = true;
28
- continue;
29
- }
30
-
31
- if (!isGood(dataValue.statusCode)) {
32
- hasBad = true;
33
- continue;
34
- }
35
- values.push(dataValue.value.value);
36
- }
37
-
38
- if (isRaw) {
39
- if (hasBad) {
40
- statusCode = StatusCodes.UncertainDataSubNormal;
41
- } else {
42
- statusCode = StatusCodes.Good;
43
- }
44
- } else if (hasBad) {
45
- statusCode = StatusCode.makeStatusCode(StatusCodes.UncertainDataSubNormal, "HistorianCalculated");
46
- } else {
47
- statusCode = StatusCode.makeStatusCode(StatusCodes.Good, "HistorianCalculated");
48
- }
49
- if (values.length === 0) {
50
- return new DataValue({
51
- sourceTimestamp: interval.startTime,
52
- statusCode: StatusCodes.BadNoData,
53
- });
54
- }
55
- const mean = values.reduce((p, c) => p + c, 0) / values.length;
56
-
57
- return new DataValue({
58
- sourceTimestamp: interval.startTime,
59
- statusCode: statusCode as StatusCode,
60
- value: {
61
- dataType: DataType.Double, value: mean
62
- }
63
- });
64
- }
65
-
66
- export function getAverageData(
67
- node: UAVariable,
68
- processingInterval: number,
69
- startDate: Date,
70
- endDate: Date,
71
- callback: (err: Error | null, dataValues?: DataValue[]) => void
72
- ) {
73
- return getAggregateData(node, processingInterval, startDate, endDate, calculateIntervalAverageValue, callback);
74
- }
1
+ import { UAVariable } from "node-opcua-address-space";
2
+ import { DataValue } from "node-opcua-data-value";
3
+ import { Variant, DataType } from "node-opcua-variant";
4
+ import { StatusCode, StatusCodes } from "node-opcua-status-code";
5
+
6
+ import { getAggregateData } from "./common";
7
+ import { Interval, AggregateConfigurationOptions, isGood } from "./interval";
8
+
9
+ function calculateIntervalAverageValue(interval: Interval, options: AggregateConfigurationOptions): DataValue {
10
+ const indexStart = interval.index;
11
+ let statusCode: StatusCode;
12
+ let isPartial = interval.isPartial;
13
+
14
+ const isRaw = false;
15
+ let hasBad = false;
16
+
17
+ const values: number[] = [];
18
+
19
+ for (let i = indexStart; i < indexStart + interval.count; i++) {
20
+ const dataValue = interval.dataValues[i];
21
+
22
+ if (dataValue.statusCode === StatusCodes.BadNoData) {
23
+ isPartial = true;
24
+ continue;
25
+ }
26
+
27
+ if (!isGood(dataValue.statusCode)) {
28
+ hasBad = true;
29
+ continue;
30
+ }
31
+ values.push(dataValue.value.value);
32
+ }
33
+
34
+ if (isRaw) {
35
+ if (hasBad) {
36
+ statusCode = StatusCodes.UncertainDataSubNormal;
37
+ } else {
38
+ statusCode = StatusCodes.Good;
39
+ }
40
+ } else if (hasBad) {
41
+ statusCode = StatusCode.makeStatusCode(StatusCodes.UncertainDataSubNormal, "HistorianCalculated");
42
+ } else {
43
+ statusCode = StatusCode.makeStatusCode(StatusCodes.Good, "HistorianCalculated");
44
+ }
45
+ if (values.length === 0) {
46
+ return new DataValue({
47
+ sourceTimestamp: interval.startTime,
48
+ statusCode: StatusCodes.BadNoData
49
+ });
50
+ }
51
+ const mean = values.reduce((p, c) => p + c, 0) / values.length;
52
+
53
+ return new DataValue({
54
+ sourceTimestamp: interval.startTime,
55
+ statusCode: statusCode as StatusCode,
56
+ value: {
57
+ dataType: DataType.Double,
58
+ value: mean
59
+ }
60
+ });
61
+ }
62
+
63
+ export function getAverageData(
64
+ node: UAVariable,
65
+ processingInterval: number,
66
+ startDate: Date,
67
+ endDate: Date,
68
+ callback: (err: Error | null, dataValues?: DataValue[]) => void
69
+ ): void {
70
+ getAggregateData(node, processingInterval, startDate, endDate, calculateIntervalAverageValue, callback);
71
+ }
package/source/common.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  /**
2
2
  * @module node-opca-aggregates
3
3
  */
4
- import { SessionContext, UAVariable } from "node-opcua-address-space";
4
+ import { SessionContext, UAVariable, ContinuationPointManager, ContinuationPoint } from "node-opcua-address-space";
5
5
  import { NodeClass } from "node-opcua-data-model";
6
6
  import { DataValue } from "node-opcua-data-value";
7
7
  import { HistoryData, HistoryReadResult, ReadRawModifiedDetails } from "node-opcua-service-history";
8
8
  import { StatusCode } from "node-opcua-status-code";
9
+ import { coerceNodeId } from "node-opcua-nodeid";
9
10
 
10
11
  import { getAggregateConfiguration } from "./aggregates";
11
12
  import { getInterval, Interval, AggregateConfigurationOptionsEx } from "./interval";
@@ -56,7 +57,6 @@ function processAggregateData(
56
57
  setImmediate(() => {
57
58
  callback(null, results);
58
59
  });
59
-
60
60
  }
61
61
 
62
62
  export function getAggregateData(
@@ -66,8 +66,7 @@ export function getAggregateData(
66
66
  endDate: Date,
67
67
  lambda: (interval: Interval, aggregateConfiguration: AggregateConfigurationOptionsEx) => DataValue,
68
68
  callback: (err: Error | null, dataValues?: DataValue[]) => void
69
- ) {
70
-
69
+ ): void {
71
70
  /* istanbul ignore next */
72
71
  if (node.nodeClass !== NodeClass.Variable) {
73
72
  throw new Error("node must be UAVariable");
@@ -78,17 +77,30 @@ export function getAggregateData(
78
77
  throw new Error("Invalid processing interval, shall be greater than 0");
79
78
  }
80
79
 
81
- const context = new SessionContext();
80
+ const continuationPointManager = new ContinuationPointManager();
81
+ const context = new SessionContext({
82
+ session: {
83
+ continuationPointManager,
84
+ getSessionId: () => coerceNodeId("i=0")
85
+ }
86
+ });
82
87
  const historyReadDetails = new ReadRawModifiedDetails({
83
88
  endTime: endDate,
84
89
  startTime: startDate,
90
+ isReadModified: false,
91
+ numValuesPerNode: 0
92
+ // returnBounds: true,
85
93
  });
86
94
  const indexRange = null;
87
95
  const dataEncoding = null;
88
- const continuationPoint = null;
89
- node.historyRead(context, historyReadDetails, indexRange, dataEncoding, continuationPoint,
96
+ const continuationPoint: ContinuationPoint | null = null;
97
+ node.historyRead(
98
+ context,
99
+ historyReadDetails,
100
+ indexRange,
101
+ dataEncoding,
102
+ { continuationPoint },
90
103
  (err: Error | null, result?: HistoryReadResult) => {
91
-
92
104
  /* istanbul ignore next */
93
105
  if (err) {
94
106
  return callback(err);
@@ -98,10 +110,11 @@ export function getAggregateData(
98
110
  const dataValues = historyData.dataValues || [];
99
111
 
100
112
  processAggregateData(node, processingInterval, startDate, endDate, dataValues, lambda, callback);
101
- });
113
+ }
114
+ );
102
115
  }
103
116
 
104
- export function interpolateValue(dataValue1: DataValue, dataValue2: DataValue, date: Date) {
117
+ export function interpolateValue(dataValue1: DataValue, dataValue2: DataValue, date: Date): DataValue {
105
118
  const t0 = dataValue1.sourceTimestamp!.getTime();
106
119
  const t = date.getTime();
107
120
  const t1 = dataValue2.sourceTimestamp!.getTime();
package/source/index.ts CHANGED
@@ -1,17 +1,11 @@
1
- /**
2
- * @module node-opca-aggregates
3
- */
4
- export {
5
- addAggregateSupport,
6
- installAggregateConfigurationOptions,
7
- getAggregateConfiguration,
8
- } from "./aggregates";
9
- export * from "./interpolate";
10
- export * from "./minmax";
11
- export * from "./interval";
12
- export * from "./common";
13
- export * from "./average";
14
- export * from "./read_processed_details";
15
- export {
16
- AggregateFunction
17
- } from "node-opcua-constants";
1
+ /**
2
+ * @module node-opca-aggregates
3
+ */
4
+ export { addAggregateSupport, installAggregateConfigurationOptions, getAggregateConfiguration } from "./aggregates";
5
+ export * from "./interpolate";
6
+ export * from "./minmax";
7
+ export * from "./interval";
8
+ export * from "./common";
9
+ export * from "./average";
10
+ export * from "./read_processed_details";
11
+ export { AggregateFunction } from "node-opcua-constants";
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @module node-opca-aggregates
2
+ * @module node-opcua-aggregates
3
3
  */
4
4
  // excerpt from OPC Unified Architecture, Part 13 21 Release 1.04
5
5
  //
@@ -47,7 +47,8 @@ import {
47
47
  _findGoodDataValueBefore,
48
48
  adjustProcessingOptions,
49
49
  AggregateConfigurationOptionsEx,
50
- Interval, isBad,
50
+ Interval,
51
+ isBad,
51
52
  isGood
52
53
  } from "./interval";
53
54
 
@@ -62,11 +63,10 @@ import {
62
63
  If for an interval neither ratio applies then that interval is Uncertain_DataSubNormal.
63
64
  */
64
65
  export function interpolatedValue(interval: Interval, options: AggregateConfigurationOptionsEx): DataValue {
65
-
66
66
  options = adjustProcessingOptions(options);
67
67
 
68
- assert(Object.prototype.hasOwnProperty.call(options,"useSlopedExtrapolation"));
69
- assert(Object.prototype.hasOwnProperty.call(options,"treatUncertainAsBad"));
68
+ assert(Object.prototype.hasOwnProperty.call(options, "useSlopedExtrapolation"));
69
+ assert(Object.prototype.hasOwnProperty.call(options, "treatUncertainAsBad"));
70
70
 
71
71
  const bTreatUncertainAsBad = options.treatUncertainAsBad!;
72
72
 
@@ -77,10 +77,9 @@ export function interpolatedValue(interval: Interval, options: AggregateConfigur
77
77
  const interpValue = new DataValue({
78
78
  sourceTimestamp: interval.startTime,
79
79
  statusCode: StatusCodes.Bad,
80
- value: previousDataValue.value,
80
+ value: previousDataValue.value
81
81
  });
82
- interpValue.statusCode =
83
- StatusCode.makeStatusCode(StatusCodes.UncertainDataSubNormal, "HistorianInterpolated");
82
+ interpValue.statusCode = StatusCode.makeStatusCode(StatusCodes.UncertainDataSubNormal, "HistorianInterpolated");
84
83
  return interpValue;
85
84
  };
86
85
 
@@ -93,7 +92,7 @@ export function interpolatedValue(interval: Interval, options: AggregateConfigur
93
92
  return new DataValue({
94
93
  sourceTimestamp: interval.startTime,
95
94
  statusCode: StatusCodes.BadNoData,
96
- value: undefined,
95
+ value: undefined
97
96
  });
98
97
  }
99
98
  if (!options.useSlopedExtrapolation) {
@@ -111,13 +110,12 @@ export function interpolatedValue(interval: Interval, options: AggregateConfigur
111
110
  // tslint:disable:no-bitwise
112
111
  if (prev2.index + 1 < prev1.index || prev1.index < interval.dataValues.length - 1) {
113
112
  // some bad data exist in between = change status code
114
- const mask = 0x0000FFFFFF;
113
+ const mask = 0x0000ffffff;
115
114
  const extraBits = interpVal.statusCode.value & mask;
116
115
  interpVal.statusCode = StatusCode.makeStatusCode(StatusCodes.UncertainDataSubNormal, extraBits);
117
116
  }
118
117
 
119
118
  return interpVal;
120
-
121
119
  }
122
120
 
123
121
  /* istanbul ignore next */
@@ -166,16 +164,12 @@ export function interpolatedValue(interval: Interval, options: AggregateConfigur
166
164
  // x is a value at ‘x’ and Tx is the timestamp associated with Vx.
167
165
  const interpolatedDataValue = interpolateValue(before.dataValue, next.dataValue, interval.startTime);
168
166
 
169
- if (before.index + 1 < next.index
170
- || !isGood(next.dataValue.statusCode)
171
- || !isGood(before.dataValue.statusCode)
172
- ) {
167
+ if (before.index + 1 < next.index || !isGood(next.dataValue.statusCode) || !isGood(before.dataValue.statusCode)) {
173
168
  // tslint:disable:no-bitwise
174
169
  // some bad data exist in between = change status code
175
- const mask = 0x0000FFFFFF;
170
+ const mask = 0x0000ffffff;
176
171
  const extraBits = interpolatedDataValue.statusCode.value & mask;
177
- interpolatedDataValue.statusCode =
178
- StatusCode.makeStatusCode(StatusCodes.UncertainDataSubNormal, extraBits);
172
+ interpolatedDataValue.statusCode = StatusCode.makeStatusCode(StatusCodes.UncertainDataSubNormal, extraBits);
179
173
  }
180
174
  // check if uncertain or bad value exist between before/next
181
175
  // todo
@@ -196,6 +190,6 @@ export function getInterpolatedData(
196
190
  startDate: Date,
197
191
  endDate: Date,
198
192
  callback: (err: Error | null, dataValues?: DataValue[]) => void
199
- ) {
200
- return getAggregateData(node, processingInterval, startDate, endDate, interpolatedValue, callback);
193
+ ): void {
194
+ getAggregateData(node, processingInterval, startDate, endDate, interpolatedValue, callback);
201
195
  }
@@ -117,7 +117,7 @@ export class Interval {
117
117
  /**
118
118
  * returns true if a raw data exists at start
119
119
  */
120
- public hasRawDataAsStart() {
120
+ public hasRawDataAsStart(): boolean {
121
121
  const index = this.index;
122
122
  if (index < 0) {
123
123
  return false;
@@ -131,11 +131,11 @@ export class Interval {
131
131
  * just preceding this interval
132
132
  * @returns {*}
133
133
  */
134
- public beforeStartDataValue(bTreatUncertainAsBad: boolean) {
134
+ public beforeStartDataValue(bTreatUncertainAsBad: boolean): DataValueWithIndex {
135
135
  return _findGoodDataValueBefore(this.dataValues, this.index, bTreatUncertainAsBad);
136
136
  }
137
137
 
138
- public nextStartDataValue(bTreatUncertainAsBad: boolean) {
138
+ public nextStartDataValue(bTreatUncertainAsBad: boolean): DataValueWithIndex {
139
139
  return _findGoodDataValueAfter(this.dataValues, this.index, bTreatUncertainAsBad);
140
140
  }
141
141