node-opcua-aggregates 2.178.0 → 2.179.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 (57) hide show
  1. package/dist/aggregates.d.ts +3 -3
  2. package/dist/aggregates.js +20 -12
  3. package/dist/aggregates.js.map +1 -1
  4. package/dist/average.d.ts +1 -1
  5. package/dist/average.js +4 -4
  6. package/dist/average.js.map +1 -1
  7. package/dist/calculate_bad_good.d.ts +1 -1
  8. package/dist/calculate_bad_good.js +4 -4
  9. package/dist/calculate_bad_good.js.map +1 -1
  10. package/dist/common.d.ts +2 -2
  11. package/dist/common.js +12 -4
  12. package/dist/common.js.map +1 -1
  13. package/dist/count.d.ts +1 -1
  14. package/dist/count.js +2 -2
  15. package/dist/count.js.map +1 -1
  16. package/dist/duration_bad.d.ts +1 -1
  17. package/dist/duration_bad.js +2 -2
  18. package/dist/duration_bad.js.map +1 -1
  19. package/dist/duration_good.d.ts +1 -1
  20. package/dist/duration_good.js +2 -2
  21. package/dist/duration_good.js.map +1 -1
  22. package/dist/index.d.ts +9 -9
  23. package/dist/index.js +18 -18
  24. package/dist/index.js.map +1 -1
  25. package/dist/interpolate.d.ts +2 -2
  26. package/dist/interpolate.js +3 -5
  27. package/dist/interpolate.js.map +1 -1
  28. package/dist/interval.d.ts +2 -2
  29. package/dist/interval.js +22 -16
  30. package/dist/interval.js.map +1 -1
  31. package/dist/minmax.d.ts +2 -2
  32. package/dist/minmax.js +4 -5
  33. package/dist/minmax.js.map +1 -1
  34. package/dist/percent_bad.d.ts +1 -1
  35. package/dist/percent_bad.js +1 -1
  36. package/dist/percent_bad.js.map +1 -1
  37. package/dist/percent_good.d.ts +1 -1
  38. package/dist/percent_good.js +2 -2
  39. package/dist/percent_good.js.map +1 -1
  40. package/dist/read_processed_details.d.ts +6 -6
  41. package/dist/read_processed_details.js +14 -12
  42. package/dist/read_processed_details.js.map +1 -1
  43. package/package.json +19 -19
  44. package/source/aggregates.ts +30 -21
  45. package/source/average.ts +6 -6
  46. package/source/calculate_bad_good.ts +8 -9
  47. package/source/common.ts +18 -10
  48. package/source/count.ts +4 -4
  49. package/source/duration_bad.ts +4 -5
  50. package/source/duration_good.ts +5 -6
  51. package/source/index.ts +12 -11
  52. package/source/interpolate.ts +5 -12
  53. package/source/interval.ts +29 -23
  54. package/source/minmax.ts +8 -9
  55. package/source/percent_bad.ts +3 -4
  56. package/source/percent_good.ts +4 -5
  57. package/source/read_processed_details.ts +23 -23
@@ -1,14 +1,13 @@
1
1
  import { extraStatusCodeBits, StatusCode, StatusCodes } from "node-opcua-status-code";
2
2
 
3
- import { Interval, AggregateConfigurationOptions, isUncertain } from "./interval";
4
-
3
+ import { type AggregateConfigurationOptions, type Interval, isUncertain } from "./interval";
5
4
 
6
5
  const a = (s: StatusCode | undefined, options: AggregateConfigurationOptions) =>
7
6
  !s || s === StatusCodes.BadNoData
8
7
  ? StatusCodes.BadNoData
9
8
  : s.isBad() || (options.treatUncertainAsBad && isUncertain(s))
10
- ? StatusCodes.Bad
11
- : StatusCodes.Good;
9
+ ? StatusCodes.Bad
10
+ : StatusCodes.Good;
12
11
 
13
12
  function findLowBound(
14
13
  interval: Interval,
@@ -17,7 +16,7 @@ function findLowBound(
17
16
  const indexStart: number = interval.index;
18
17
 
19
18
  const initialValue = interval.dataValues[indexStart];
20
- if (initialValue.sourceTimestamp!.getTime() === interval.startTime.getTime()) {
19
+ if (initialValue.sourceTimestamp?.getTime() === interval.startTime.getTime()) {
21
20
  return { previousStatus: initialValue.statusCode, previousTime: interval.startTime.getTime(), indexStart: indexStart + 1 };
22
21
  }
23
22
  const previousStatus =
@@ -28,7 +27,6 @@ function findLowBound(
28
27
  return { previousStatus, previousTime, indexStart };
29
28
  }
30
29
 
31
- // eslint-disable-next-line max-statements, complexity
32
30
  export function calculateBadAndGood(
33
31
  interval: Interval,
34
32
  options: AggregateConfigurationOptions
@@ -82,7 +80,10 @@ export function calculateBadAndGood(
82
80
  if (currentStatus === StatusCodes.BadNoData) {
83
81
  partialFlag = extraStatusCodeBits.HistorianPartial;
84
82
  }
85
- const currentTime = dataValue.sourceTimestamp!.getTime();
83
+ if (!dataValue.sourceTimestamp) {
84
+ throw new Error("calculateBadAndGood: dataValue is missing a sourceTimestamp");
85
+ }
86
+ const currentTime = dataValue.sourceTimestamp.getTime();
86
87
 
87
88
  // debugLog(" ", dataValue.sourceTimestamp?.toISOString(), dataValue.statusCode.toString(), dataValue.value.value);
88
89
 
@@ -125,12 +126,10 @@ export function calculateBadAndGood(
125
126
  const percentGood = (durationGood / effectiveProcessingInterval) * 100;
126
127
  const percentBad = (durationBad / effectiveProcessingInterval) * 100;
127
128
 
128
- let percentDataGood = options.percentDataGood === undefined ? 100 : options.percentDataGood;
129
129
  const percentDataBad = options.percentDataBad === undefined ? 100 : options.percentDataBad;
130
130
 
131
131
  if (percentBad >= percentDataBad || (nbGood === 0 && nbUncertain === 0)) {
132
132
  durationGood = 0; // BAD
133
- percentDataGood = -1;
134
133
  // const statusCode = StatusCodes.Bad;
135
134
  //return { durationGood, durationBad, durationUnknown, percentBad, percentGood, statusCode };
136
135
  }
package/source/common.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * @module node-opca-aggregates
3
3
  */
4
- import { SessionContext, UAVariable, ContinuationPointManager, ContinuationPoint } from "node-opcua-address-space";
4
+ import { type ContinuationPoint, ContinuationPointManager, SessionContext, type UAVariable } from "node-opcua-address-space";
5
5
  import { NodeClass } from "node-opcua-data-model";
6
6
  import { DataValue } from "node-opcua-data-value";
7
- import { HistoryData, HistoryReadResult, ReadRawModifiedDetails } from "node-opcua-service-history";
8
- import { StatusCode, StatusCodes } from "node-opcua-status-code";
9
7
  import { coerceNodeId } from "node-opcua-nodeid";
8
+ import { type HistoryData, type HistoryReadResult, ReadRawModifiedDetails } from "node-opcua-service-history";
9
+ import { StatusCode } from "node-opcua-status-code";
10
10
 
11
11
  import { getAggregateConfiguration } from "./aggregates";
12
- import { getInterval, Interval, AggregateConfigurationOptionsEx } from "./interval";
12
+ import { type AggregateConfigurationOptionsEx, getInterval, type Interval } from "./interval";
13
13
 
14
14
  /**
15
15
  * @internal
@@ -40,7 +40,7 @@ function processAggregateData(
40
40
  const dataValue = lambda(interval, aggregateConfiguration);
41
41
 
42
42
  /* c8 ignore next */
43
- if (!dataValue || !dataValue.sourceTimestamp) {
43
+ if (!dataValue?.sourceTimestamp) {
44
44
  // const dataValue = interval.interpolatedValue(aggregateConfiguration);
45
45
  throw Error("invalid DataValue");
46
46
  }
@@ -63,12 +63,14 @@ export function getAggregateData(
63
63
  ): void {
64
64
  /* c8 ignore next */
65
65
  if (node.nodeClass !== NodeClass.Variable) {
66
- return callback(new Error("node must be UAVariable"));
66
+ callback(new Error("node must be UAVariable"));
67
+ return;
67
68
  }
68
69
 
69
70
  /* c8 ignore next */
70
71
  if (processingInterval <= 0) {
71
- return callback(new Error("Invalid processing interval, shall be greater than 0"));
72
+ callback(new Error("Invalid processing interval, shall be greater than 0"));
73
+ return;
72
74
  }
73
75
 
74
76
  const continuationPointManager = new ContinuationPointManager();
@@ -99,7 +101,10 @@ export function getAggregateData(
99
101
  if (err) {
100
102
  return callback(err);
101
103
  }
102
- const historyData = result!.historyData as HistoryData;
104
+ if (!result) {
105
+ return callback(new Error("getAggregateData: expecting a result when err is null"));
106
+ }
107
+ const historyData = result.historyData as HistoryData;
103
108
 
104
109
  const dataValues = historyData.dataValues || [];
105
110
 
@@ -109,9 +114,12 @@ export function getAggregateData(
109
114
  }
110
115
 
111
116
  export function interpolateValue(dataValue1: DataValue, dataValue2: DataValue, date: Date): DataValue {
112
- const t0 = dataValue1.sourceTimestamp!.getTime();
117
+ if (!dataValue1.sourceTimestamp || !dataValue2.sourceTimestamp) {
118
+ throw new Error("interpolateValue: both dataValues must have a sourceTimestamp");
119
+ }
120
+ const t0 = dataValue1.sourceTimestamp.getTime();
113
121
  const t = date.getTime();
114
- const t1 = dataValue2.sourceTimestamp!.getTime();
122
+ const t1 = dataValue2.sourceTimestamp.getTime();
115
123
  const coef1 = (t - t0) / (t1 - t0);
116
124
  const coef2 = (t1 - t) / (t1 - t0);
117
125
  const value = dataValue1.value.clone();
package/source/count.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { UAVariable } from "node-opcua-address-space";
1
+ import type { UAVariable } from "node-opcua-address-space";
2
2
  import { DataValue } from "node-opcua-data-value";
3
3
  import { extraStatusCodeBits, StatusCode, StatusCodes } from "node-opcua-status-code";
4
4
  import { DataType } from "node-opcua-variant";
5
5
 
6
6
  import { getAggregateData } from "./common";
7
- import { Interval, AggregateConfigurationOptions, isUncertain } from "./interval";
7
+ import { type AggregateConfigurationOptions, type Interval, isUncertain } from "./interval";
8
8
 
9
9
  /**
10
10
  * The Count Aggregate retrieves a count of all the raw values within an interval.
@@ -22,7 +22,7 @@ function calculateCountValue(interval: Interval, options: AggregateConfiguration
22
22
  let nbUncertain = 0;
23
23
  let badDuration = 0;
24
24
  let uncertainDuration = 0;
25
- let goodDuration = 0;
25
+ let _goodDuration = 0;
26
26
  for (let i = indexStart; i < indexStart + interval.count; i++) {
27
27
  const dataValue = interval.dataValues[i];
28
28
  if (dataValue.statusCode.equals(StatusCodes.BadNoData)) {
@@ -38,7 +38,7 @@ function calculateCountValue(interval: Interval, options: AggregateConfiguration
38
38
  uncertainDuration += regionDuration;
39
39
  } else if (dataValue.statusCode.isGoodish()) {
40
40
  nbGood++;
41
- goodDuration += regionDuration;
41
+ _goodDuration += regionDuration;
42
42
  }
43
43
  }
44
44
 
@@ -1,11 +1,10 @@
1
- import { UAVariable } from "node-opcua-address-space";
1
+ import type { UAVariable } from "node-opcua-address-space";
2
2
  import { DataValue } from "node-opcua-data-value";
3
- import { DataType } from "node-opcua-variant";
4
3
  import { StatusCodes } from "node-opcua-status-code";
5
-
6
- import { getAggregateData } from "./common";
7
- import { Interval, AggregateConfigurationOptions } from "./interval";
4
+ import { DataType } from "node-opcua-variant";
8
5
  import { calculateBadAndGood } from "./calculate_bad_good";
6
+ import { getAggregateData } from "./common";
7
+ import type { AggregateConfigurationOptions, Interval } from "./interval";
9
8
 
10
9
  function calculateDurationBad(interval: Interval, options: AggregateConfigurationOptions): DataValue {
11
10
  const { durationBad, durationUnknown, statusCode } = calculateBadAndGood(interval, options);
@@ -1,15 +1,14 @@
1
- import { UAVariable } from "node-opcua-address-space";
1
+ import type { UAVariable } from "node-opcua-address-space";
2
2
  import { DataValue } from "node-opcua-data-value";
3
- import { DataType } from "node-opcua-variant";
4
3
  import { StatusCodes } from "node-opcua-status-code";
5
-
6
- import { getAggregateData } from "./common";
7
- import { Interval, AggregateConfigurationOptions } from "./interval";
4
+ import { DataType } from "node-opcua-variant";
8
5
  import { calculateBadAndGood } from "./calculate_bad_good";
6
+ import { getAggregateData } from "./common";
7
+ import type { AggregateConfigurationOptions, Interval } from "./interval";
9
8
 
10
9
  function calculateDurationGood(interval: Interval, options: AggregateConfigurationOptions): DataValue {
11
10
  const { durationGood, durationUnknown, statusCode } = calculateBadAndGood(interval, options);
12
- if (durationUnknown>0 && durationGood ===0) {
11
+ if (durationUnknown > 0 && durationGood === 0) {
13
12
  return new DataValue({
14
13
  sourceTimestamp: interval.startTime,
15
14
  statusCode: StatusCodes.Bad
package/source/index.ts CHANGED
@@ -1,22 +1,23 @@
1
1
  /**
2
2
  * @module node-opca-aggregates
3
3
  */
4
+
5
+ export { AggregateFunction } from "node-opcua-constants";
4
6
  export {
7
+ addAggregateFunctionSupport,
8
+ addAggregateStandardFunctionSupport,
5
9
  addAggregateSupport,
6
- installAggregateConfigurationOptions,
7
10
  getAggregateConfiguration,
8
- addAggregateStandardFunctionSupport,
9
- addAggregateFunctionSupport
11
+ installAggregateConfigurationOptions
10
12
  } from "./aggregates";
11
- export * from "./interpolate";
12
- export * from "./minmax";
13
- export * from "./interval";
14
- export * from "./common";
15
13
  export * from "./average";
16
- export * from "./read_processed_details";
17
- export { AggregateFunction } from "node-opcua-constants";
14
+ export * from "./common";
18
15
  export { getCountData } from "./count";
19
- export { getPercentGoodData } from "./percent_good";
20
- export { getPercentBadData } from "./percent_bad";
21
16
  export { getDurationBadData } from "./duration_bad";
22
17
  export { getDurationGoodData } from "./duration_good";
18
+ export * from "./interpolate";
19
+ export * from "./interval";
20
+ export * from "./minmax";
21
+ export { getPercentBadData } from "./percent_bad";
22
+ export { getPercentGoodData } from "./percent_good";
23
+ export * from "./read_processed_details";
@@ -37,18 +37,13 @@
37
37
  // Bound Bad Does not return a Bad bound except as noted above
38
38
  // Bound Uncertain Returned Uncertain_DataSubNormal if any Bad value(s) was/were skipped to
39
39
  // calculate the bounding value.
40
- import { UAVariable } from "node-opcua-address-space";
40
+ import type { UAVariable } from "node-opcua-address-space";
41
41
  import { assert } from "node-opcua-assert";
42
42
  import { DataValue } from "node-opcua-data-value";
43
43
  import { StatusCode, StatusCodes } from "node-opcua-status-code";
44
44
 
45
45
  import { getAggregateData, interpolateValue } from "./common";
46
- import {
47
- _findGoodDataValueBefore,
48
- adjustProcessingOptions,
49
- AggregateConfigurationOptionsEx,
50
- Interval,
51
- } from "./interval";
46
+ import { _findGoodDataValueBefore, type AggregateConfigurationOptionsEx, adjustProcessingOptions, type Interval } from "./interval";
52
47
 
53
48
  /*
54
49
  For any intervals containing regions where the StatusCodes are Bad,
@@ -63,10 +58,10 @@ import {
63
58
  export function interpolatedValue(interval: Interval, options: AggregateConfigurationOptionsEx): DataValue {
64
59
  options = adjustProcessingOptions(options);
65
60
 
66
- assert(Object.prototype.hasOwnProperty.call(options, "useSlopedExtrapolation"));
67
- assert(Object.prototype.hasOwnProperty.call(options, "treatUncertainAsBad"));
61
+ assert(Object.hasOwn(options, "useSlopedExtrapolation"));
62
+ assert(Object.hasOwn(options, "treatUncertainAsBad"));
68
63
 
69
- const bTreatUncertainAsBad = options.treatUncertainAsBad!;
64
+ const bTreatUncertainAsBad = options.treatUncertainAsBad || false;
70
65
 
71
66
  const steppedValue = (previousDataValue: DataValue): DataValue => {
72
67
  if (!previousDataValue.statusCode) {
@@ -105,7 +100,6 @@ export function interpolatedValue(interval: Interval, options: AggregateConfigur
105
100
  // else interpolate
106
101
  const interpVal = interpolateValue(prev2.dataValue, prev1.dataValue, interval.startTime);
107
102
 
108
- // tslint:disable:no-bitwise
109
103
  if (prev2.index + 1 < prev1.index || prev1.index < interval.dataValues.length - 1) {
110
104
  // some bad data exist in between = change status code
111
105
  const mask = 0x0000ffffff;
@@ -163,7 +157,6 @@ export function interpolatedValue(interval: Interval, options: AggregateConfigur
163
157
  const interpolatedDataValue = interpolateValue(before.dataValue, next.dataValue, interval.startTime);
164
158
 
165
159
  if (before.index + 1 < next.index || !next.dataValue.statusCode.isGood() || !before.dataValue.statusCode.isGood()) {
166
- // tslint:disable:no-bitwise
167
160
  // some bad data exist in between = change status code
168
161
  const mask = 0x0000ffffff;
169
162
  const extraBits = interpolatedDataValue.statusCode.value & mask;
@@ -2,25 +2,31 @@
2
2
  * @module node-opca-aggregates
3
3
  */
4
4
  import { DataValue } from "node-opcua-data-value";
5
- import { StatusCode, StatusCodes } from "node-opcua-status-code";
6
- import { AggregateConfigurationOptions } from "node-opcua-types";
5
+ import { type StatusCode, StatusCodes } from "node-opcua-status-code";
6
+ import type { AggregateConfigurationOptions } from "node-opcua-types";
7
+
7
8
  export { AggregateConfigurationOptions } from "node-opcua-types";
8
9
 
9
10
  export interface AggregateConfigurationOptionsEx extends AggregateConfigurationOptions {
10
11
  stepped?: boolean;
11
12
  }
12
13
 
13
-
14
14
  export function isGoodish2(statusCode: StatusCode, { treatUncertainAsBad }: { treatUncertainAsBad?: boolean }): boolean {
15
15
  if (statusCode.isGoodish()) return true;
16
16
  if (isUncertain(statusCode)) return !treatUncertainAsBad;
17
17
  return false;
18
18
  }
19
19
 
20
-
21
20
  export function isUncertain(statusCode: StatusCode): boolean {
22
21
  return (statusCode.value & 0x40000000) === 0x40000000 && statusCode.value !== StatusCodes.BadNoData.value;
23
22
  }
23
+ function sourceTimestampMs(dataValue: DataValue): number {
24
+ if (!dataValue.sourceTimestamp) {
25
+ throw new Error("expecting dataValue to have a sourceTimestamp");
26
+ }
27
+ return dataValue.sourceTimestamp.getTime();
28
+ }
29
+
24
30
  export interface IntervalOptions {
25
31
  startTime: Date;
26
32
  dataValues: DataValue[];
@@ -86,9 +92,9 @@ export function adjustProcessingOptions(options: AggregateConfigurationOptionsEx
86
92
  options = options || {};
87
93
  options.treatUncertainAsBad = options.treatUncertainAsBad || false;
88
94
  options.useSlopedExtrapolation = options.useSlopedExtrapolation || false;
89
- options.stepped = options.stepped! || false;
90
- options.percentDataBad = parseInt(options.percentDataBad as any, 10);
91
- options.percentDataGood = parseInt(options.percentDataGood as any, 10);
95
+ options.stepped = options.stepped || false;
96
+ options.percentDataBad = parseInt(String(options.percentDataBad ?? 0), 10);
97
+ options.percentDataGood = parseInt(String(options.percentDataGood ?? 0), 10);
92
98
  return options;
93
99
  }
94
100
 
@@ -126,7 +132,7 @@ export class Interval {
126
132
  return false;
127
133
  }
128
134
  const dataValue1 = this.dataValues[index];
129
- return this.startTime.getTime() === dataValue1!.sourceTimestamp!.getTime();
135
+ return this.startTime.getTime() === sourceTimestampMs(dataValue1);
130
136
  }
131
137
 
132
138
  /**
@@ -144,14 +150,14 @@ export class Interval {
144
150
 
145
151
  public toString(): string {
146
152
  let str = "";
147
- str += "startTime " + this.startTime.toUTCString() + "\n";
148
- str += "start " + this.index + " ";
149
- str += "count " + this.count + " ";
150
- str += "isPartial " + this.isPartial + "\n";
153
+ str += `startTime ${this.startTime.toUTCString()}\n`;
154
+ str += `start ${this.index} `;
155
+ str += `count ${this.count} `;
156
+ str += `isPartial ${this.isPartial}\n`;
151
157
  if (this.index >= 0) {
152
158
  for (let i = this.index; i < this.index + this.count; i++) {
153
159
  const dataValue = this.dataValues[i];
154
- str += " " + dataValue.sourceTimestamp!.toUTCString() + dataValue.statusCode.toString();
160
+ str += ` ${dataValue.sourceTimestamp?.toUTCString()}${dataValue.statusCode.toString()}`;
155
161
  str += dataValue.value ? dataValue.value.toString() : "";
156
162
  str += "\n";
157
163
  }
@@ -170,16 +176,16 @@ export class Interval {
170
176
  if (i < 0) {
171
177
  return e;
172
178
  }
173
- const lastTimestamp = this.dataValues[i].sourceTimestamp!;
174
- return Math.min(e, lastTimestamp.getTime() + 1);
179
+ const lastTimestamp = this.dataValues[i].sourceTimestamp;
180
+ return lastTimestamp ? Math.min(e, lastTimestamp.getTime() + 1) : e;
175
181
  }
176
182
 
177
183
  /**
178
- *
184
+ *
179
185
  * @returns the interval duration
180
186
  */
181
187
  duration() {
182
- const t1 = this.dataValues[this.index].sourceTimestamp!.getTime();
188
+ const t1 = sourceTimestampMs(this.dataValues[this.index]);
183
189
  const e = this.getEffectiveEndTime();
184
190
  return e - t1;
185
191
  }
@@ -188,9 +194,9 @@ export class Interval {
188
194
  * returns the region duration starting at index and finishing at index+1 or end limit of the interval
189
195
  */
190
196
  regionDuration(index: number): number {
191
- const t1 = this.dataValues[index].sourceTimestamp!.getTime();
197
+ const t1 = sourceTimestampMs(this.dataValues[index]);
192
198
  const e = this.getEffectiveEndTime();
193
- const t2 = index < this.dataValues.length - 1 ? Math.min(this.dataValues[index + 1].sourceTimestamp!.getTime(), e) : e;
199
+ const t2 = index < this.dataValues.length - 1 ? Math.min(sourceTimestampMs(this.dataValues[index + 1]), e) : e;
194
200
  return t2 - t1;
195
201
  }
196
202
  }
@@ -199,7 +205,7 @@ export function getInterval(startTime: Date, processingInterval: number, indexHi
199
205
  let count = 0;
200
206
  let index = -1;
201
207
  for (let i = indexHint; i < dataValues.length; i++) {
202
- if (dataValues[i].sourceTimestamp!.getTime() < startTime.getTime()) {
208
+ if (sourceTimestampMs(dataValues[i]) < startTime.getTime()) {
203
209
  continue;
204
210
  }
205
211
  index = i;
@@ -208,7 +214,7 @@ export function getInterval(startTime: Date, processingInterval: number, indexHi
208
214
 
209
215
  if (index >= 0) {
210
216
  for (let i = index; i < dataValues.length; i++) {
211
- if (dataValues[i].sourceTimestamp!.getTime() >= startTime.getTime() + processingInterval) {
217
+ if (sourceTimestampMs(dataValues[i]) >= startTime.getTime() + processingInterval) {
212
218
  break;
213
219
  }
214
220
  count++;
@@ -219,11 +225,11 @@ export function getInterval(startTime: Date, processingInterval: number, indexHi
219
225
  let isPartial = false;
220
226
  if (
221
227
  index + count >= dataValues.length &&
222
- dataValues[dataValues.length - 1].sourceTimestamp!.getTime() < startTime.getTime() + processingInterval
228
+ sourceTimestampMs(dataValues[dataValues.length - 1]) < startTime.getTime() + processingInterval
223
229
  ) {
224
230
  isPartial = true;
225
231
  }
226
- if (index <= 0 && dataValues[0].sourceTimestamp!.getTime() > startTime.getTime()) {
232
+ if (index <= 0 && sourceTimestampMs(dataValues[0]) > startTime.getTime()) {
227
233
  isPartial = true;
228
234
  }
229
235
 
package/source/minmax.ts CHANGED
@@ -52,18 +52,17 @@
52
52
  // No End Bound Not Applicable
53
53
  // Bound Bad Not Applicable
54
54
  // Bound Uncertain Not Applicable
55
- import { UAVariable } from "node-opcua-address-space";
55
+ import type { UAVariable } from "node-opcua-address-space";
56
56
  import { DataValue } from "node-opcua-data-value";
57
57
  import { StatusCode, StatusCodes } from "node-opcua-status-code";
58
- import { Variant } from "node-opcua-variant";
58
+ import type { Variant } from "node-opcua-variant";
59
59
 
60
60
  import { getAggregateData } from "./common";
61
- import { AggregateConfigurationOptions, Interval } from "./interval";
61
+ import type { AggregateConfigurationOptions, Interval } from "./interval";
62
62
 
63
- // eslint-disable-next-line max-statements
64
63
  function calculateIntervalMinOrMaxValue(
65
64
  interval: Interval,
66
- options: AggregateConfigurationOptions,
65
+ _options: AggregateConfigurationOptions,
67
66
  predicate: (a: Variant, b: Variant) => "equal" | "select" | "reject"
68
67
  ): DataValue {
69
68
  // debugLog(interval.toString());
@@ -94,7 +93,7 @@ function calculateIntervalMinOrMaxValue(
94
93
  if (!selectedValue) {
95
94
  selectedValue = dataValue.value;
96
95
  counter = 1;
97
- if (i === indexStart && dataValue.sourceTimestamp!.getTime() === interval.startTime.getTime()) {
96
+ if (i === indexStart && dataValue.sourceTimestamp?.getTime() === interval.startTime.getTime()) {
98
97
  isRaw = true;
99
98
  }
100
99
  continue;
@@ -138,7 +137,7 @@ function calculateIntervalMinOrMaxValue(
138
137
  return new DataValue({
139
138
  sourceTimestamp: interval.startTime,
140
139
  statusCode: statusCode as StatusCode,
141
- value: selectedValue!
140
+ value: selectedValue
142
141
  });
143
142
  }
144
143
 
@@ -217,7 +216,7 @@ export function getMinData(
217
216
  endDate: Date,
218
217
  callback: (err: Error | null, dataValues?: DataValue[]) => void
219
218
  ): void {
220
- return getAggregateData(node, processingInterval, startDate, endDate, calculateIntervalMinValue, callback);
219
+ getAggregateData(node, processingInterval, startDate, endDate, calculateIntervalMinValue, callback);
221
220
  }
222
221
 
223
222
  export function getMaxData(
@@ -227,5 +226,5 @@ export function getMaxData(
227
226
  endDate: Date,
228
227
  callback: (err: Error | null, dataValues?: DataValue[]) => void
229
228
  ): void {
230
- return getAggregateData(node, processingInterval, startDate, endDate, calculateIntervalMaxValue, callback);
229
+ getAggregateData(node, processingInterval, startDate, endDate, calculateIntervalMaxValue, callback);
231
230
  }
@@ -1,10 +1,9 @@
1
- import { UAVariable } from "node-opcua-address-space";
1
+ import type { UAVariable } from "node-opcua-address-space";
2
2
  import { DataValue } from "node-opcua-data-value";
3
3
  import { DataType } from "node-opcua-variant";
4
-
5
- import { getAggregateData } from "./common";
6
- import { Interval, AggregateConfigurationOptions } from "./interval";
7
4
  import { calculateBadAndGood } from "./calculate_bad_good";
5
+ import { getAggregateData } from "./common";
6
+ import type { AggregateConfigurationOptions, Interval } from "./interval";
8
7
 
9
8
  function calculatePercentBad(interval: Interval, options: AggregateConfigurationOptions): DataValue {
10
9
  const { percentBad, statusCode } = calculateBadAndGood(interval, options);
@@ -1,11 +1,10 @@
1
- import { UAVariable } from "node-opcua-address-space";
1
+ import type { UAVariable } from "node-opcua-address-space";
2
2
  import { DataValue } from "node-opcua-data-value";
3
- import { DataType } from "node-opcua-variant";
4
3
  import { StatusCodes } from "node-opcua-status-code";
5
-
6
- import { getAggregateData } from "./common";
7
- import { Interval, AggregateConfigurationOptions } from "./interval";
4
+ import { DataType } from "node-opcua-variant";
8
5
  import { calculateBadAndGood } from "./calculate_bad_good";
6
+ import { getAggregateData } from "./common";
7
+ import type { AggregateConfigurationOptions, Interval } from "./interval";
9
8
 
10
9
  function calculatePercentGood(interval: Interval, options: AggregateConfigurationOptions): DataValue {
11
10
  //
@@ -1,21 +1,19 @@
1
+ import type { ContinuationData, ISessionContext, UAVariable } from "node-opcua-address-space";
1
2
  import { AggregateFunction } from "node-opcua-constants";
2
- import { ISessionContext, UAVariable, ContinuationData } from "node-opcua-address-space";
3
- import { NumericRange } from "node-opcua-numeric-range";
4
- import { QualifiedNameLike } from "node-opcua-data-model";
5
- import { CallbackT, StatusCodes } from "node-opcua-status-code";
6
- import { DataValue } from "node-opcua-data-value";
7
- import { NodeId } from "node-opcua-nodeid";
8
- import { HistoryData, HistoryReadResult, ReadProcessedDetails } from "node-opcua-service-history";
9
-
10
- import { getMinData, getMaxData } from "./minmax";
11
-
12
- import { getInterpolatedData } from "./interpolate";
3
+ import type { QualifiedNameLike } from "node-opcua-data-model";
4
+ import type { DataValue } from "node-opcua-data-value";
5
+ import type { NodeId } from "node-opcua-nodeid";
6
+ import type { NumericRange } from "node-opcua-numeric-range";
7
+ import { HistoryData, HistoryReadResult, type ReadProcessedDetails } from "node-opcua-service-history";
8
+ import { type CallbackT, StatusCodes } from "node-opcua-status-code";
13
9
  import { getAverageData } from "./average";
14
10
  import { getCountData } from "./count";
11
+ import { getDurationBadData } from "./duration_bad";
12
+ import { getDurationGoodData } from "./duration_good";
13
+ import { getInterpolatedData } from "./interpolate";
14
+ import { getMaxData, getMinData } from "./minmax";
15
15
  import { getPercentBadData } from "./percent_bad";
16
16
  import { getPercentGoodData } from "./percent_good";
17
- import { getDurationGoodData } from "./duration_good";
18
- import { getDurationBadData } from "./duration_bad";
19
17
 
20
18
  function _buildResult(err: Error | null, dataValues: DataValue[] | undefined, callback2: CallbackT<HistoryReadResult>) {
21
19
  if (err) {
@@ -85,11 +83,11 @@ function applyAggregate(
85
83
  }
86
84
  export function readProcessedDetails(
87
85
  variable: UAVariable,
88
- context: ISessionContext,
86
+ _context: ISessionContext,
89
87
  historyReadDetails: ReadProcessedDetails,
90
- indexRange: NumericRange | null,
91
- dataEncoding: QualifiedNameLike | null,
92
- continuationData: ContinuationData,
88
+ _indexRange: NumericRange | null,
89
+ _dataEncoding: QualifiedNameLike | null,
90
+ _continuationData: ContinuationData,
93
91
  callback: CallbackT<HistoryReadResult>
94
92
  ): void {
95
93
  // OPC Unified Architecture, Part 11 27 Release 1.03
@@ -143,12 +141,14 @@ export function readProcessedDetails(
143
141
  const startTime = historyReadDetails.startTime;
144
142
  const endTime = historyReadDetails.endTime;
145
143
  if (!startTime || !endTime) {
146
- return callback(null, new HistoryReadResult({ statusCode: StatusCodes.BadInvalidArgument }));
144
+ callback(null, new HistoryReadResult({ statusCode: StatusCodes.BadInvalidArgument }));
145
+ return;
147
146
  }
148
147
  if (startTime.getTime() === endTime.getTime()) {
149
148
  // Start = End Int = Anything No intervals. Returns a Bad_InvalidArgument StatusCode,
150
149
  // regardless of whether there is data at the specified time or not
151
- return callback(null, new HistoryReadResult({ statusCode: StatusCodes.BadInvalidArgument }));
150
+ callback(null, new HistoryReadResult({ statusCode: StatusCodes.BadInvalidArgument }));
151
+ return;
152
152
  }
153
153
 
154
154
  const aggregateTypes: NodeId[] = historyReadDetails.aggregateType || [];
@@ -157,9 +157,9 @@ export function readProcessedDetails(
157
157
  // starting at startTime and ending at endTime.
158
158
  const processingInterval = historyReadDetails.processingInterval || endTime.getTime() - startTime.getTime();
159
159
 
160
- // tslint:disable-next-line: prefer-for-of
161
- if (!historyReadDetails.aggregateType || historyReadDetails.aggregateType.length !== 1) {
162
- return callback(null, new HistoryReadResult({ statusCode: StatusCodes.BadInternalError }));
160
+ if (historyReadDetails.aggregateType?.length !== 1) {
161
+ callback(null, new HistoryReadResult({ statusCode: StatusCodes.BadInternalError }));
162
+ return;
163
163
  }
164
- return applyAggregate(variable, processingInterval, startTime, endTime, aggregateTypes[0], callback);
164
+ applyAggregate(variable, processingInterval, startTime, endTime, aggregateTypes[0], callback);
165
165
  }