node-opcua-address-space 2.113.0 → 2.113.2

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/dist/source/interfaces/alarms_and_conditions/condition_info_i.d.ts +2 -0
  2. package/dist/source/interfaces/alarms_and_conditions/condition_snapshot.d.ts +14 -6
  3. package/dist/source/interfaces/alarms_and_conditions/ua_condition_ex.d.ts +3 -2
  4. package/dist/source/interfaces/data_access/ua_multistate_discrete_ex.d.ts +2 -1
  5. package/dist/source/interfaces/data_access/ua_multistate_value_discrete_ex.d.ts +2 -1
  6. package/dist/source/interfaces/data_access/ua_two_state_discrete_ex.d.ts +2 -1
  7. package/dist/source/interfaces/i_condition_variable_type_setter_options.d.ts +3 -0
  8. package/dist/source/interfaces/i_condition_variable_type_setter_options.js +3 -0
  9. package/dist/source/interfaces/i_condition_variable_type_setter_options.js.map +1 -0
  10. package/dist/source/interfaces/i_set_state_options.d.ts +4 -0
  11. package/dist/source/interfaces/i_set_state_options.js +3 -0
  12. package/dist/source/interfaces/i_set_state_options.js.map +1 -0
  13. package/dist/source/ua_two_state_variable_ex.d.ts +2 -1
  14. package/dist/src/alarms_and_conditions/condition.d.ts +2 -1
  15. package/dist/src/alarms_and_conditions/condition.js +2 -2
  16. package/dist/src/alarms_and_conditions/condition.js.map +1 -1
  17. package/dist/src/alarms_and_conditions/condition_snapshot_impl.d.ts +20 -11
  18. package/dist/src/alarms_and_conditions/condition_snapshot_impl.js +72 -33
  19. package/dist/src/alarms_and_conditions/condition_snapshot_impl.js.map +1 -1
  20. package/dist/src/alarms_and_conditions/ua_condition_impl.d.ts +3 -2
  21. package/dist/src/alarms_and_conditions/ua_condition_impl.js +13 -26
  22. package/dist/src/alarms_and_conditions/ua_condition_impl.js.map +1 -1
  23. package/dist/src/data_access/ua_multistate_discrete_impl.d.ts +3 -2
  24. package/dist/src/data_access/ua_multistate_discrete_impl.js +2 -2
  25. package/dist/src/data_access/ua_multistate_discrete_impl.js.map +1 -1
  26. package/dist/src/data_access/ua_multistate_value_discrete_impl.d.ts +3 -2
  27. package/dist/src/data_access/ua_multistate_value_discrete_impl.js +3 -3
  28. package/dist/src/data_access/ua_multistate_value_discrete_impl.js.map +1 -1
  29. package/dist/src/data_access/ua_two_state_discrete_impl.d.ts +2 -1
  30. package/dist/src/data_access/ua_two_state_discrete_impl.js +3 -3
  31. package/dist/src/data_access/ua_two_state_discrete_impl.js.map +1 -1
  32. package/dist/src/state_machine/ua_two_state_variable.d.ts +2 -1
  33. package/dist/src/state_machine/ua_two_state_variable.js +10 -8
  34. package/dist/src/state_machine/ua_two_state_variable.js.map +1 -1
  35. package/dist/src/ua_reference_type_impl.d.ts +1 -1
  36. package/dist/tsconfig_common.tsbuildinfo +1 -1
  37. package/package.json +2 -2
  38. package/source/interfaces/alarms_and_conditions/condition_info_i.ts +4 -0
  39. package/source/interfaces/alarms_and_conditions/condition_snapshot.ts +13 -8
  40. package/source/interfaces/alarms_and_conditions/ua_condition_ex.ts +4 -2
  41. package/source/interfaces/data_access/ua_multistate_discrete_ex.ts +2 -1
  42. package/source/interfaces/data_access/ua_multistate_value_discrete_ex.ts +2 -1
  43. package/source/interfaces/data_access/ua_two_state_discrete_ex.ts +2 -1
  44. package/source/interfaces/i_condition_variable_type_setter_options.ts +5 -0
  45. package/source/interfaces/i_set_state_options.ts +4 -0
  46. package/source/ua_two_state_variable_ex.ts +2 -1
  47. package/src/alarms_and_conditions/condition.ts +4 -2
  48. package/src/alarms_and_conditions/condition_snapshot_impl.ts +75 -38
  49. package/src/alarms_and_conditions/ua_condition_impl.ts +14 -27
  50. package/src/data_access/ua_multistate_discrete_impl.ts +5 -3
  51. package/src/data_access/ua_multistate_value_discrete_impl.ts +5 -4
  52. package/src/data_access/ua_two_state_discrete_impl.ts +5 -3
  53. package/src/state_machine/ua_two_state_variable.ts +14 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-opcua-address-space",
3
- "version": "2.113.0",
3
+ "version": "2.113.2",
4
4
  "description": "pure nodejs OPCUA SDK - module address-space",
5
5
  "main": "./dist/src/index_current.js",
6
6
  "types": "./dist/source/index.d.ts",
@@ -84,7 +84,7 @@
84
84
  "internet of things"
85
85
  ],
86
86
  "homepage": "http://node-opcua.github.io/",
87
- "gitHead": "36db335391fedd39726990a1b37f7768da16466a",
87
+ "gitHead": "d72e73db4c07d27ea2da81ccbd258e63ad6c640b",
88
88
  "files": [
89
89
  "dist",
90
90
  "distHelpers",
@@ -10,6 +10,10 @@ export interface ConditionInfoOptions {
10
10
  quality?: StatusCode | null;
11
11
  severity?: UInt16 | null;
12
12
  retain?: boolean | null;
13
+
14
+ time?: Date | null;
15
+ receiveTime?: Date | null;
16
+
13
17
  }
14
18
 
15
19
  export interface ConditionInfo {
@@ -10,20 +10,25 @@ import { NodeId } from "node-opcua-nodeid";
10
10
  import { StatusCode } from "node-opcua-status-code";
11
11
  import { TimeZoneDataType } from "node-opcua-types";
12
12
  import { UtcTime } from "../state_machine/ua_state_machine_type";
13
+ import { ISetStateOptions } from "../i_set_state_options";
14
+ import { IConditionVariableTypeSetterOptions } from "../i_condition_variable_type_setter_options";
13
15
 
14
16
  export interface ConditionSnapshot {
15
- on(eventName: "value_changed", eventHandler: (node: UAVariable, variant: Variant) => void): this;
17
+ on(
18
+ eventName: "valueChanged",
19
+ eventHandler: (node: UAVariable, variant: Variant, options: { sourceTimestamp: Date }) => void
20
+ ): this;
16
21
  }
17
22
 
18
-
19
23
  export interface ConditionSnapshot extends EventEmitter {
20
24
  // static normalizeName = normalizeName;
21
25
 
26
+ emit(eventName: "valueChanged", node: UAVariable, variant: Variant, options: { sourceTimestamp: Date }): boolean;
27
+ emit(eventName: string | symbol): boolean;
22
28
  condition: BaseNode;
23
29
  eventData: IEventData | null;
24
30
  branchId: NodeId | null;
25
31
 
26
-
27
32
  /**
28
33
  * @method getBrandId
29
34
  * @return {NodeId}
@@ -62,7 +67,7 @@ export interface ConditionSnapshot extends EventEmitter {
62
67
  * @param value {Boolean}
63
68
  * @return void
64
69
  */
65
- setEnabledState(value: boolean): void;
70
+ setEnabledState(value: boolean, options?: ISetStateOptions): void;
66
71
  /**
67
72
  * @method getEnabledStateAsString
68
73
  * @return {String}
@@ -86,7 +91,7 @@ export interface ConditionSnapshot extends EventEmitter {
86
91
  * @method setComment
87
92
  * @param txtMessage {LocalizedText}
88
93
  */
89
- setComment(txtMessage: LocalizedTextLike): void;
94
+ setComment(txtMessage: LocalizedTextLike, options?: IConditionVariableTypeSetterOptions): void;
90
95
  /**
91
96
  *
92
97
  * @method setMessage
@@ -129,7 +134,7 @@ export interface ConditionSnapshot extends EventEmitter {
129
134
  * @method setQuality
130
135
  * @param quality {StatusCode}
131
136
  */
132
- setQuality(quality: StatusCode): void;
137
+ setQuality(quality: StatusCode, options?: IConditionVariableTypeSetterOptions): void;
133
138
  /**
134
139
  * @method getQuality
135
140
  * @return {StatusCode}
@@ -169,7 +174,7 @@ export interface ConditionSnapshot extends EventEmitter {
169
174
  * @method setSeverity
170
175
  * @param severity {UInt16}
171
176
  */
172
- setSeverity(severity: UInt16): void;
177
+ setSeverity(severity: UInt16, options?: IConditionVariableTypeSetterOptions): void;
173
178
 
174
179
  /**
175
180
  * @method getSeverity
@@ -188,7 +193,7 @@ export interface ConditionSnapshot extends EventEmitter {
188
193
  * @method setLastSeverity
189
194
  * @param severity {UInt16}
190
195
  */
191
- setLastSeverity(severity: UInt16): void;
196
+ setLastSeverity(severity: UInt16, options?: IConditionVariableTypeSetterOptions): void;
192
197
  /**
193
198
  * @method getLastSeverity
194
199
  * @return {UInt16}
@@ -4,10 +4,11 @@ import { NodeId } from "node-opcua-nodeid";
4
4
  import { UACondition_Base } from "node-opcua-nodeset-ua";
5
5
  import { StatusCode } from "node-opcua-status-code";
6
6
  import { TimeZoneDataType } from "node-opcua-types";
7
+ import { DataType } from "node-opcua-basic-types";
8
+ import { ISetStateOptions } from "../i_set_state_options";
7
9
  import { UATwoStateVariableEx } from "../../ua_two_state_variable_ex";
8
10
  import { ConditionInfoOptions } from "./condition_info_i";
9
11
  import { ConditionSnapshot } from "./condition_snapshot";
10
- import { DataType } from "node-opcua-basic-types";
11
12
 
12
13
 
13
14
 
@@ -26,6 +27,7 @@ export interface UAConditionHelper {
26
27
  on(eventName: "branch_deleted", eventHandler: (branchId: string) => void): this;
27
28
  }
28
29
 
30
+
29
31
  export interface UAConditionHelper extends UABaseEventHelper {
30
32
  getBranchCount(): number;
31
33
  getBranches(): ConditionSnapshot[];
@@ -34,7 +36,7 @@ export interface UAConditionHelper extends UABaseEventHelper {
34
36
  deleteBranch(branch: ConditionSnapshot): void;
35
37
  getEnabledState(): boolean;
36
38
  getEnabledStateAsString(): string;
37
- setEnabledState(requestedEnabledState: boolean): StatusCode;
39
+ setEnabledState(requestedEnabledState: boolean, options?: ISetStateOptions): StatusCode;
38
40
  setReceiveTime(time: Date): void;
39
41
  setLocalTime(time: TimeZoneDataType): void;
40
42
  setTime(time: Date): void;
@@ -13,6 +13,7 @@ import { DataType, Variant } from "node-opcua-variant";
13
13
  import { StatusCode } from "node-opcua-status-code";
14
14
  import { UAMultiStateDiscrete_Base } from "node-opcua-nodeset-ua";
15
15
  import { UAVariableT } from "node-opcua-address-space-base";
16
+ import { ISetStateOptions } from "../i_set_state_options";
16
17
 
17
18
  export { UAMultiStateDiscrete } from "node-opcua-nodeset-ua";
18
19
 
@@ -21,6 +22,6 @@ export interface UAMultiStateDiscreteEx<T, DT extends DataType> extends UAVariab
21
22
  getValue(): number;
22
23
  getValueAsString(): string;
23
24
  getIndex(value: string): number;
24
- setValue(value: string | number): void;
25
+ setValue(value: string | number, options?: ISetStateOptions): void;
25
26
  checkVariantCompatibility(value: Variant): StatusCode;
26
27
  }
@@ -5,6 +5,7 @@ import { DataType, Variant } from "node-opcua-variant";
5
5
  import { Int64, UInt64 } from "node-opcua-basic-types";
6
6
  import { UAMultiStateValueDiscrete_Base } from "node-opcua-nodeset-ua";
7
7
  import { UAVariableT } from "node-opcua-address-space-base";
8
+ import { ISetStateOptions } from "../i_set_state_options";
8
9
 
9
10
  /**
10
11
  * @see https://reference.opcfoundation.org/v104/Core/docs/Part8/5.3.3/#5.3.3.4
@@ -27,7 +28,7 @@ export interface UAMultiStateValueDiscreteEx<T, DT extends DataType>
27
28
  getValueAsString(): string;
28
29
  getValueAsNumber(): number;
29
30
 
30
- setValue(value: string | number | Int64): void;
31
+ setValue(value: string | number | Int64, options?: ISetStateOptions): void;
31
32
 
32
33
  findValueAsText(value: number | UInt64): Variant;
33
34
  }
@@ -2,6 +2,7 @@ import { LocalizedTextLike } from "node-opcua-data-model";
2
2
  import { DataType } from "node-opcua-variant";
3
3
  import { UAVariableT } from "node-opcua-address-space-base";
4
4
  import { UATwoStateDiscrete_Base } from "node-opcua-nodeset-ua";
5
+ import { ISetStateOptions } from "../i_set_state_options";
5
6
 
6
7
  /**
7
8
  * @see https://reference.opcfoundation.org/v104/Core/VariableTypes/TwoStateDiscreteType/
@@ -10,5 +11,5 @@ export interface UATwoStateDiscreteEx extends UAVariableT<boolean, DataType.Bool
10
11
  // --- helpers ---
11
12
  getValue(): boolean;
12
13
  getValueAsString(): string;
13
- setValue(value: boolean | LocalizedTextLike): void;
14
+ setValue(value: boolean | LocalizedTextLike, options?: ISetStateOptions): void;
14
15
  }
@@ -0,0 +1,5 @@
1
+
2
+
3
+ export interface IConditionVariableTypeSetterOptions {
4
+ sourceTimestamp?: Date;
5
+ }
@@ -0,0 +1,4 @@
1
+ export interface ISetStateOptions {
2
+ transitionTime?: Date;
3
+ effectiveTransitionTime?: Date;
4
+ }
@@ -5,6 +5,7 @@ import { UAVariableT } from "node-opcua-address-space-base";
5
5
  import { LocalizedText } from "node-opcua-data-model";
6
6
  import { UAStateVariable, UATwoStateVariable_Base } from "node-opcua-nodeset-ua";
7
7
  import { DataType } from "node-opcua-variant";
8
+ import { ISetStateOptions } from "./interfaces/i_set_state_options";
8
9
 
9
10
  /**
10
11
  * @see https://reference.opcfoundation.org/v104/Core/docs/Part9/5.2/
@@ -18,7 +19,7 @@ export interface UATwoStateVariableHelper {
18
19
  readonly isTrueSubStateOf: UAStateVariable<LocalizedText> | null;
19
20
 
20
21
  // --- helpers ---
21
- setValue(boolValue: boolean): void;
22
+ setValue(boolValue: boolean, options?: ISetStateOptions): void;
22
23
 
23
24
  getValue(): boolean;
24
25
 
@@ -6,13 +6,15 @@ import { assert } from "node-opcua-assert";
6
6
  import { LocalizedText, LocalizedTextLike } from "node-opcua-data-model";
7
7
  import { minDate } from "node-opcua-basic-types";
8
8
  import { StatusCode, StatusCodes } from "node-opcua-status-code";
9
+ import { ISetStateOptions } from "../../source/interfaces/i_set_state_options";
9
10
  import { ConditionSnapshotImpl } from "./condition_snapshot_impl";
10
11
 
11
12
  export function _setAckedState(
12
13
  self: ConditionSnapshotImpl,
13
14
  requestedAckedState: boolean,
14
15
  conditionEventId?: Buffer,
15
- comment?: string | LocalizedText | LocalizedTextLike
16
+ comment?: string | LocalizedText | LocalizedTextLike,
17
+ options?: ISetStateOptions
16
18
  ): StatusCode {
17
19
  assert(self instanceof ConditionSnapshotImpl);
18
20
 
@@ -21,7 +23,7 @@ export function _setAckedState(
21
23
  if (ackedState && requestedAckedState) {
22
24
  return StatusCodes.BadConditionBranchAlreadyAcked;
23
25
  }
24
- self._set_twoStateVariable("AckedState", requestedAckedState);
26
+ self._set_twoStateVariable("AckedState", requestedAckedState, options);
25
27
  return StatusCodes.Good;
26
28
  }
27
29
 
@@ -16,7 +16,9 @@ import { TimeZoneDataType } from "node-opcua-types";
16
16
  import { DataType, Variant } from "node-opcua-variant";
17
17
 
18
18
  import { ConditionSnapshot } from "../../source/interfaces/alarms_and_conditions/condition_snapshot";
19
+ import { IConditionVariableTypeSetterOptions } from "../../source/interfaces/i_condition_variable_type_setter_options";
19
20
  import { UtcTime } from "../../source/interfaces/state_machine/ua_state_machine_type";
21
+ import { ISetStateOptions } from "../../source/interfaces/i_set_state_options";
20
22
  import { EventData } from "../event_data";
21
23
  import { UATwoStateVariableImpl } from "../state_machine/ua_two_state_variable";
22
24
  import { _setAckedState } from "./condition";
@@ -35,7 +37,6 @@ function _visit(self: any, node: BaseNode, prefix: string): void {
35
37
  for (const aggregate of aggregates) {
36
38
  if (aggregate.nodeClass === NodeClass.Variable) {
37
39
  const name = aggregate.browseName.toString();
38
-
39
40
  const key = prefix + name;
40
41
 
41
42
  // istanbul ignore next
@@ -64,7 +65,7 @@ function _installOnChangeEventHandlers(self: any, node: BaseNode, prefix: string
64
65
  for (const aggregate of aggregates) {
65
66
  if (aggregate.nodeClass === NodeClass.Variable) {
66
67
  const name = aggregate.browseName.toString();
67
-
68
+
68
69
  const key = prefix + name;
69
70
 
70
71
  // istanbul ignore next
@@ -91,7 +92,7 @@ function _ensure_condition_values_correctness(self: any, node: BaseNode, prefix:
91
92
  for (const aggregate of aggregates) {
92
93
  if (aggregate.nodeClass === NodeClass.Variable) {
93
94
  const name = aggregate.browseName.toString();
94
-
95
+
95
96
  const key = prefix + name;
96
97
 
97
98
  const snapshot_value = self._map[key].toString();
@@ -136,6 +137,7 @@ const _varTable = {
136
137
  "EnabledState.EffectiveDisplayName": 1,
137
138
  "EnabledState.Id": 1,
138
139
  "EnabledState.TransitionTime": 1,
140
+ "EnabledState.EffectiveTransitionTime": 1,
139
141
  EventId: 1,
140
142
  EventType: 1,
141
143
  LocalTime: 1,
@@ -143,6 +145,7 @@ const _varTable = {
143
145
  SourceNode: 1,
144
146
  Time: 1
145
147
  };
148
+
146
149
  type FullBrowsePath = string;
147
150
  export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnapshot {
148
151
  public static normalizeName = normalizeName;
@@ -234,7 +237,7 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
234
237
  return variant.value;
235
238
  }
236
239
 
237
- public _set_var(varName: string, dataType: DataType, value: unknown): void {
240
+ public _set_var(varName: string, dataType: DataType, value: unknown, options?: IConditionVariableTypeSetterOptions): void {
238
241
  const key = normalizeName(varName);
239
242
  // istanbul ignore next
240
243
  if (!Object.prototype.hasOwnProperty.call(this._map, key)) {
@@ -249,11 +252,21 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
249
252
  value
250
253
  });
251
254
 
252
- if (this._map[key + ".SourceTimestamp"]) {
253
- this._map[key + ".SourceTimestamp"] = new Variant({
255
+ const sourceTimestamp = options?.sourceTimestamp || new Date();
256
+ const sourceTimestampKey = key + ".SourceTimestamp";
257
+ if (this._map[sourceTimestampKey]) {
258
+ // from spec 1.03 : 5.3 condition variables
259
+ // a condition VariableType has a sourceTimeStamp exposed property
260
+ // SourceTimestamp indicates the time of the last change of the Value of this ConditionVariable.
261
+ // It shall be the same time that would be returned from the Read Service inside the DataValue
262
+ // structure for the ConditionVariable Value Attribute.
263
+ const variant = new Variant({
254
264
  dataType: DataType.DateTime,
255
- value: new Date()
265
+ value: sourceTimestamp
256
266
  });
267
+ this._map[sourceTimestampKey] = variant;
268
+ const node = this._node_index[sourceTimestampKey];
269
+ this.emit("valueChanged", node, variant, { sourceTimestamp });
257
270
  }
258
271
 
259
272
  const variant = this._map[key];
@@ -264,7 +277,7 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
264
277
  return;
265
278
  }
266
279
  assert(node.nodeClass === NodeClass.Variable);
267
- this.emit("value_changed", node, variant);
280
+ this.emit("valueChanged", node, variant, { sourceTimestamp });
268
281
  }
269
282
 
270
283
  /**
@@ -327,8 +340,8 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
327
340
  * @param value {Boolean}
328
341
  * @return void
329
342
  */
330
- public setEnabledState(value: boolean): void {
331
- return this._set_twoStateVariable("EnabledState", value);
343
+ public setEnabledState(value: boolean, options?: ISetStateOptions): void {
344
+ return this._set_twoStateVariable("EnabledState", value, options);
332
345
  }
333
346
 
334
347
  /**
@@ -359,9 +372,9 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
359
372
  * @method setComment
360
373
  * @param txtMessage {LocalizedText}
361
374
  */
362
- public setComment(txtMessage: LocalizedTextLike): void {
375
+ public setComment(txtMessage: LocalizedTextLike, options?: IConditionVariableTypeSetterOptions): void {
363
376
  const txtMessage1 = coerceLocalizedText(txtMessage);
364
- this._set_var("Comment", DataType.LocalizedText, txtMessage1);
377
+ this._set_var("Comment", DataType.LocalizedText, txtMessage1, options);
365
378
  }
366
379
 
367
380
  /**
@@ -412,8 +425,8 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
412
425
  * @method setQuality
413
426
  * @param quality {StatusCode}
414
427
  */
415
- public setQuality(quality: StatusCode): void {
416
- this._set_var("Quality", DataType.StatusCode, quality);
428
+ public setQuality(quality: StatusCode, options?: IConditionVariableTypeSetterOptions): void {
429
+ this._set_var("Quality", DataType.StatusCode, quality, options);
417
430
  }
418
431
 
419
432
  /**
@@ -458,13 +471,15 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
458
471
  * @method setSeverity
459
472
  * @param severity {UInt16}
460
473
  */
461
- public setSeverity(severity: UInt16): void {
474
+ public setSeverity(severity: UInt16, options?: IConditionVariableTypeSetterOptions): void {
462
475
  assert(isFinite(severity), "expecting a UInt16");
463
476
 
464
477
  // record automatically last severity
465
478
  const lastSeverity = this.getSeverity();
466
- this.setLastSeverity(lastSeverity);
467
- this._set_var("Severity", DataType.UInt16, severity);
479
+ const sourceTimestamp = this.getSeveritySourceTimestamp();
480
+ this.setLastSeverity(lastSeverity, { sourceTimestamp });
481
+
482
+ this._set_var("Severity", DataType.UInt16, severity, options);
468
483
  }
469
484
 
470
485
  /**
@@ -477,6 +492,10 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
477
492
  const value = this._get_var("Severity");
478
493
  return +value;
479
494
  }
495
+ public getSeveritySourceTimestamp(): Date {
496
+ const c = this.condition as UAConditionImpl;
497
+ return c.severity.readValue().sourceTimestamp || new Date();
498
+ }
480
499
 
481
500
  /*
482
501
  * as per spec 1.0.3 - part 9:
@@ -489,9 +508,9 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
489
508
  * @method setLastSeverity
490
509
  * @param severity {UInt16}
491
510
  */
492
- public setLastSeverity(severity: UInt16): void {
511
+ public setLastSeverity(severity: UInt16, options?: IConditionVariableTypeSetterOptions): void {
493
512
  severity = +severity;
494
- return this._set_var("LastSeverity", DataType.UInt16, severity);
513
+ return this._set_var("LastSeverity", DataType.UInt16, severity, options);
495
514
  }
496
515
 
497
516
  /**
@@ -523,8 +542,8 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
523
542
  * @param time {Date} : UTCTime
524
543
  */
525
544
  public setReceiveTime(time: UtcTime): void {
526
- assert(time instanceof Date);
527
- return this._set_var("ReceiveTime", DataType.DateTime, time);
545
+ if (!(time instanceof Date)) { throw new Error("setReceiveTime expecting a Date")};
546
+ return this._set_var("ReceiveTime", DataType.DateTime, time, { sourceTimestamp: time });
528
547
  }
529
548
 
530
549
  /**
@@ -537,8 +556,7 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
537
556
  * @param time {Date}
538
557
  */
539
558
  public setTime(time: Date): void {
540
- assert(time instanceof Date);
541
- return this._set_var("Time", DataType.DateTime, time);
559
+ return this._set_var("Time", DataType.DateTime, time, { sourceTimestamp: time });
542
560
  }
543
561
 
544
562
  /**
@@ -601,10 +619,9 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
601
619
  return this._get_twoStateVariable("AckedState");
602
620
  }
603
621
 
604
- public setAckedState(ackedState: boolean): StatusCode {
622
+ public setAckedState(ackedState: boolean, options?: ISetStateOptions): StatusCode {
605
623
  ackedState = !!ackedState;
606
-
607
- return _setAckedState(this, ackedState);
624
+ return _setAckedState(this, ackedState, undefined, undefined, options);
608
625
  }
609
626
 
610
627
  public getConfirmedState(): boolean {
@@ -613,7 +630,7 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
613
630
  return this._get_twoStateVariable("ConfirmedState");
614
631
  }
615
632
 
616
- public setConfirmedStateIfExists(confirmedState: boolean): void {
633
+ public setConfirmedStateIfExists(confirmedState: boolean, options?: ISetStateOptions): void {
617
634
  confirmedState = !!confirmedState;
618
635
  const acknowledgeableCondition = this.condition as UAAcknowledgeableCondition;
619
636
  if (!acknowledgeableCondition.confirmedState) {
@@ -622,7 +639,7 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
622
639
  return;
623
640
  }
624
641
  // todo deal with Error code BadConditionBranchAlreadyConfirmed
625
- return this._set_twoStateVariable("ConfirmedState", confirmedState);
642
+ return this._set_twoStateVariable("ConfirmedState", confirmedState, options);
626
643
  }
627
644
 
628
645
  public setConfirmedState(confirmedState: boolean): void {
@@ -647,29 +664,48 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
647
664
  * @method setSuppressedState
648
665
  * @param suppressed {Boolean}
649
666
  */
650
- public setSuppressedState(suppressed: boolean): void {
667
+ public setSuppressedState(suppressed: boolean, options?: ISetStateOptions): void {
651
668
  suppressed = !!suppressed;
652
- this._set_twoStateVariable("SuppressedState", suppressed);
669
+ this._set_twoStateVariable("SuppressedState", suppressed, options);
653
670
  }
654
671
 
655
672
  public getActiveState(): boolean {
656
673
  return this._get_twoStateVariable("ActiveState");
657
674
  }
658
675
 
659
- public setActiveState(newActiveState: boolean): StatusCode {
676
+ public setActiveState(newActiveState: boolean, options?: ISetStateOptions): StatusCode {
660
677
  // xx var activeState = self.getActiveState();
661
678
  // xx if (activeState === newActiveState) {
662
679
  // xx return StatusCodes.Bad;
663
680
  // xx }
664
- this._set_twoStateVariable("ActiveState", newActiveState);
681
+ this._set_twoStateVariable("ActiveState", newActiveState, options);
665
682
  return StatusCodes.Good;
666
683
  }
667
684
 
668
- // tslint:disable:no-empty
685
+ public setLatchedState(newLatchedState: boolean, options?: ISetStateOptions): StatusCode {
686
+ this._set_twoStateVariable("LatchedState", newLatchedState, options);
687
+ return StatusCodes.Good;
688
+ }
689
+ public getLatchedState(): boolean {
690
+ return this._get_twoStateVariable("LatchedState");
691
+ }
692
+ public setOutOfServiceState(newOutOfServiceState: boolean, options?: ISetStateOptions): StatusCode {
693
+ this._set_twoStateVariable("OutOfServiceState", newOutOfServiceState, options);
694
+ return StatusCodes.Good;
695
+ }
696
+ public getOutOfServiceState(): boolean {
697
+ return this._get_twoStateVariable("OutOfServiceState");
698
+ }
699
+ public setSilentState(newSilentState: boolean, options?: ISetStateOptions): StatusCode {
700
+ this._set_twoStateVariable("SilentState", newSilentState, options);
701
+ return StatusCodes.Good;
702
+ }
703
+ public getSilentState(): boolean {
704
+ return this._get_twoStateVariable("SilentState");
705
+ }
669
706
  public setShelvingState(): void {
670
- // todo
707
+ throw new Error("Method not implemented.");
671
708
  }
672
-
673
709
  public toString(): string {
674
710
  // public condition: any = null;
675
711
  // public eventData: any = null;
@@ -704,7 +740,7 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
704
740
  * @param value
705
741
  * @private
706
742
  */
707
- public _set_twoStateVariable(varName: string, value: boolean): void {
743
+ public _set_twoStateVariable(varName: string, value: boolean, options?: ISetStateOptions): void {
708
744
  value = !!value;
709
745
 
710
746
  const hrKey = ConditionSnapshotImpl.normalizeName(varName);
@@ -733,9 +769,10 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
733
769
  // also change ConditionNode if we are on currentBranch
734
770
  if (this.isCurrentBranch()) {
735
771
  assert(twoStateNode instanceof UATwoStateVariableImpl);
736
- twoStateNode.setValue(value as boolean);
772
+ twoStateNode.setValue(value as boolean, options);
737
773
  }
738
- this.emit("value_changed", node, variant);
774
+ const sourceTimestamp = options?.effectiveTransitionTime || new Date();
775
+ this.emit("valueChanged", node, variant, { sourceTimestamp });
739
776
  }
740
777
 
741
778
  protected _get_twoStateVariable(varName: string): any {
@@ -41,6 +41,7 @@ import { ConditionInfoOptions } from "../../source/interfaces/alarms_and_conditi
41
41
  import { UAConditionEx } from "../../source/interfaces/alarms_and_conditions/ua_condition_ex";
42
42
  import { ConditionSnapshot } from "../../source/interfaces/alarms_and_conditions/condition_snapshot";
43
43
  import { InstantiateConditionOptions } from "../../source/interfaces/alarms_and_conditions/instantiate_condition_options";
44
+ import { ISetStateOptions } from "../../source/interfaces/i_set_state_options";
44
45
 
45
46
  import { AddressSpacePrivate } from "../address_space_private";
46
47
  import { _install_TwoStateVariable_machinery } from "../state_machine/ua_two_state_variable";
@@ -214,9 +215,8 @@ export class UAConditionImpl extends UABaseEventImpl implements UAConditionEx {
214
215
  // the implication of this convention is that interacting with the condition variable
215
216
  // shall be made by using branch0, any value change made
216
217
  // using the standard setValueFromSource mechanism will not be work properly.
217
- this._branch0.on("value_changed", (node: UAVariable, variant: Variant) => {
218
- assert(node.nodeClass === NodeClass.Variable);
219
- node.setValueFromSource(variant);
218
+ this._branch0.on("valueChanged", (node: UAVariable, variant: Variant, options: { sourceTimestamp: Date }) => {
219
+ node.setValueFromSource(variant, StatusCodes.Good, options.sourceTimestamp);
220
220
  });
221
221
  }
222
222
 
@@ -277,7 +277,7 @@ export class UAConditionImpl extends UABaseEventImpl implements UAConditionEx {
277
277
  * returns {StatusCode} StatusCodes.Good if successful or BadConditionAlreadyEnabled/BadConditionAlreadyDisabled
278
278
  * @private
279
279
  */
280
- public _setEnabledState(requestedEnabledState: boolean): StatusCode {
280
+ public _setEnabledState(requestedEnabledState: boolean, options?: ISetStateOptions): StatusCode {
281
281
  assert(typeof requestedEnabledState === "boolean");
282
282
 
283
283
  const enabledState = this.getEnabledState();
@@ -288,7 +288,7 @@ export class UAConditionImpl extends UABaseEventImpl implements UAConditionEx {
288
288
  return StatusCodes.BadConditionAlreadyDisabled;
289
289
  }
290
290
 
291
- this._branch0.setEnabledState(requestedEnabledState);
291
+ this._branch0.setEnabledState(requestedEnabledState, options);
292
292
  // conditionNode.enabledState.setValue(requestedEnabledState);
293
293
 
294
294
  // xx assert(conditionNode.enabledState.id.readValue().value.value === requestedEnabledState,"sanity check 1");
@@ -346,8 +346,8 @@ export class UAConditionImpl extends UABaseEventImpl implements UAConditionEx {
346
346
  * @param requestedEnabledState {Boolean}
347
347
  * @private
348
348
  */
349
- public setEnabledState(requestedEnabledState: boolean): StatusCode {
350
- return this._setEnabledState(requestedEnabledState);
349
+ public setEnabledState(requestedEnabledState: boolean, options?: ISetStateOptions): StatusCode {
350
+ return this._setEnabledState(requestedEnabledState, options);
351
351
  }
352
352
 
353
353
  /**
@@ -491,11 +491,13 @@ export class UAConditionImpl extends UABaseEventImpl implements UAConditionEx {
491
491
 
492
492
  const branch = this.currentBranch();
493
493
 
494
- const now = new Date();
494
+ const currentDefaultDate = new Date();
495
+ const time = conditionInfo.time || currentDefaultDate;
496
+ const receiveTime = conditionInfo.receiveTime || currentDefaultDate;
495
497
  // install the eventTimestamp
496
498
  // set the received Time
497
- branch.setTime(now);
498
- branch.setReceiveTime(now);
499
+ branch.setTime(time);
500
+ branch.setReceiveTime(receiveTime);
499
501
 
500
502
  // note : in 1.04 LocalTime property is optional
501
503
  if (Object.prototype.hasOwnProperty.call(this, "localTime")) {
@@ -515,11 +517,11 @@ export class UAConditionImpl extends UABaseEventImpl implements UAConditionEx {
515
517
 
516
518
  if (Object.prototype.hasOwnProperty.call(conditionInfo, "severity") && conditionInfo.severity !== null) {
517
519
  assert(isFinite(conditionInfo.severity!));
518
- branch.setSeverity(conditionInfo.severity!);
520
+ branch.setSeverity(conditionInfo.severity!, { sourceTimestamp: time });
519
521
  }
520
522
  if (Object.prototype.hasOwnProperty.call(conditionInfo, "quality") && conditionInfo.quality !== null) {
521
523
  assert(conditionInfo.quality instanceof StatusCode);
522
- branch.setQuality(conditionInfo.quality!);
524
+ branch.setQuality(conditionInfo.quality!, { sourceTimestamp: time });
523
525
  }
524
526
  if (Object.prototype.hasOwnProperty.call(conditionInfo, "retain") && conditionInfo.retain !== null) {
525
527
  assert(typeof conditionInfo.retain === "boolean");
@@ -1206,12 +1208,6 @@ function _create_new_branch_id() {
1206
1208
  return makeNodeId(randomGuid(), 1);
1207
1209
  }
1208
1210
 
1209
- function _update_sourceTimestamp<T, DT extends DataType>(this: UAConditionVariable<T, DT>, dataValue: DataValue /*, indexRange*/) {
1210
- this.sourceTimestamp.setValueFromSource({
1211
- dataType: DataType.DateTime,
1212
- value: dataValue.sourceTimestamp
1213
- });
1214
- }
1215
1211
 
1216
1212
  // tslint:disable:no-console
1217
1213
  function _install_condition_variable_type<T, DT extends DataType>(node: UAConditionVariable<T, DT>) {
@@ -1225,15 +1221,6 @@ function _install_condition_variable_type<T, DT extends DataType>(node: UACondit
1225
1221
  }
1226
1222
  node.accessLevel = makeAccessLevelFlag("CurrentRead");
1227
1223
 
1228
- // from spec 1.03 : 5.3 condition variables
1229
- // a condition VariableType has a sourceTimeStamp exposed property
1230
- // SourceTimestamp indicates the time of the last change of the Value of this ConditionVariable.
1231
- // It shall be the same time that would be returned from the Read Service inside the DataValue
1232
- // structure for the ConditionVariable Value Attribute.
1233
-
1234
- assert(node.typeDefinitionObj.browseName.toString() === "ConditionVariableType");
1235
- assert(node.sourceTimestamp.browseName.toString() === "SourceTimestamp");
1236
- node.on("value_changed", _update_sourceTimestamp);
1237
1224
  }
1238
1225
 
1239
1226
  /**