Skip to content

Commit

Permalink
allow effectiveTransitionTime to be passed when setting a TwoStateVar…
Browse files Browse the repository at this point in the history
…ialbe for instance UACondition#setEnableState(true, { effectiveTransitionTime: somedate})
  • Loading branch information
erossignon committed Dec 22, 2023
1 parent 200e233 commit 84b55ee
Show file tree
Hide file tree
Showing 15 changed files with 118 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { NodeId } from "node-opcua-nodeid";
import { StatusCode } from "node-opcua-status-code";
import { TimeZoneDataType } from "node-opcua-types";
import { UtcTime } from "../state_machine/ua_state_machine_type";
import { ISetStateOptions } from "../i_set_state_options";

export interface ConditionSnapshot {
on(eventName: "value_changed", eventHandler: (node: UAVariable, variant: Variant) => void): this;
Expand Down Expand Up @@ -62,7 +63,7 @@ export interface ConditionSnapshot extends EventEmitter {
* @param value {Boolean}
* @return void
*/
setEnabledState(value: boolean): void;
setEnabledState(value: boolean, options?: ISetStateOptions): void;
/**
* @method getEnabledStateAsString
* @return {String}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { NodeId } from "node-opcua-nodeid";
import { UACondition_Base } from "node-opcua-nodeset-ua";
import { StatusCode } from "node-opcua-status-code";
import { TimeZoneDataType } from "node-opcua-types";
import { DataType } from "node-opcua-basic-types";
import { ISetStateOptions } from "../i_set_state_options";
import { UATwoStateVariableEx } from "../../ua_two_state_variable_ex";
import { ConditionInfoOptions } from "./condition_info_i";
import { ConditionSnapshot } from "./condition_snapshot";
import { DataType } from "node-opcua-basic-types";



Expand All @@ -26,6 +27,7 @@ export interface UAConditionHelper {
on(eventName: "branch_deleted", eventHandler: (branchId: string) => void): this;
}


export interface UAConditionHelper extends UABaseEventHelper {
getBranchCount(): number;
getBranches(): ConditionSnapshot[];
Expand All @@ -34,7 +36,7 @@ export interface UAConditionHelper extends UABaseEventHelper {
deleteBranch(branch: ConditionSnapshot): void;
getEnabledState(): boolean;
getEnabledStateAsString(): string;
setEnabledState(requestedEnabledState: boolean): StatusCode;
setEnabledState(requestedEnabledState: boolean, options?: ISetStateOptions): StatusCode;
setReceiveTime(time: Date): void;
setLocalTime(time: TimeZoneDataType): void;
setTime(time: Date): void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { DTEnumValue, UADiscreteItem, UADiscreteItem_Base, UAMultiStateDiscrete_
import { UAProperty, UAVariableT } from "node-opcua-address-space-base";
import { Int64, UInt64 } from "node-opcua-basic-types";
import { LocalizedText } from "node-opcua-data-model";
import { ISetStateOptions } from "../i_set_state_options";

export { UAMultiStateDiscrete } from "node-opcua-nodeset-ua";

Expand All @@ -23,7 +24,7 @@ export interface UAMultiStateDiscreteEx<T, DT extends DataType> extends UAVariab
getValue(): number;
getValueAsString(): string;
getIndex(value: string): number;
setValue(value: string | number): void;
setValue(value: string | number, options?: ISetStateOptions): void;
checkVariantCompatibility(value: Variant): StatusCode;
}

Expand Down Expand Up @@ -56,6 +57,6 @@ export interface UAMultiStateValueDiscreteArrayEx<T, DT extends DataType>
*/
getValueAsString(): string[];
getValueAsNumber(): number[];
setValue(value: string | number | Int64): void;
setValue(value: string | number | Int64, options?: ISetStateOptions): void;
findValueAsText(value: number | UInt64): Variant;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { DataType, Variant } from "node-opcua-variant";
import { Int64, UInt64 } from "node-opcua-basic-types";
import { UAMultiStateValueDiscrete_Base } from "node-opcua-nodeset-ua";
import { UAVariableT } from "node-opcua-address-space-base";
import { ISetStateOptions } from "../i_set_state_options";

/**
* @see https://reference.opcfoundation.org/v104/Core/docs/Part8/5.3.3/#5.3.3.4
Expand All @@ -27,7 +28,7 @@ export interface UAMultiStateValueDiscreteEx<T, DT extends DataType>
getValueAsString(): string;
getValueAsNumber(): number;

setValue(value: string | number | Int64): void;
setValue(value: string | number | Int64, options?: ISetStateOptions): void;

findValueAsText(value: number | UInt64): Variant;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { LocalizedTextLike } from "node-opcua-data-model";
import { DataType } from "node-opcua-variant";
import { UAVariableT } from "node-opcua-address-space-base";
import { UATwoStateDiscrete_Base } from "node-opcua-nodeset-ua";
import { ISetStateOptions } from "../i_set_state_options";

/**
* @see https://reference.opcfoundation.org/v104/Core/VariableTypes/TwoStateDiscreteType/
Expand All @@ -10,5 +11,5 @@ export interface UATwoStateDiscreteEx extends UAVariableT<boolean, DataType.Bool
// --- helpers ---
getValue(): boolean;
getValueAsString(): string;
setValue(value: boolean | LocalizedTextLike): void;
setValue(value: boolean | LocalizedTextLike, options?: ISetStateOptions): void;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface ISetStateOptions {
transitionTime?: Date;
effectiveTransitionTime?: Date;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { UAVariableT } from "node-opcua-address-space-base";
import { LocalizedText } from "node-opcua-data-model";
import { UAStateVariable, UATwoStateVariable_Base } from "node-opcua-nodeset-ua";
import { DataType } from "node-opcua-variant";
import { ISetStateOptions } from "./interfaces/i_set_state_options";

/**
* @see https://reference.opcfoundation.org/v104/Core/docs/Part9/5.2/
Expand All @@ -18,7 +19,7 @@ export interface UATwoStateVariableHelper {
readonly isTrueSubStateOf: UAStateVariable<LocalizedText> | null;

// --- helpers ---
setValue(boolValue: boolean): void;
setValue(boolValue: boolean, options?: ISetStateOptions): void;

getValue(): boolean;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function _setAckedState(
if (ackedState && requestedAckedState) {
return StatusCodes.BadConditionBranchAlreadyAcked;
}
self._set_twoStateVariable("AckedState", requestedAckedState);
self._set_twoStateVariable("AckedState", requestedAckedState,/* effective transition time will be now*/);
return StatusCodes.Good;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { DataType, Variant } from "node-opcua-variant";

import { ConditionSnapshot } from "../../source/interfaces/alarms_and_conditions/condition_snapshot";
import { UtcTime } from "../../source/interfaces/state_machine/ua_state_machine_type";
import { ISetStateOptions } from "../../source/interfaces/i_set_state_options";
import { EventData } from "../event_data";
import { UATwoStateVariableImpl } from "../state_machine/ua_two_state_variable";
import { _setAckedState } from "./condition";
Expand Down Expand Up @@ -136,13 +137,16 @@ const _varTable = {
"EnabledState.EffectiveDisplayName": 1,
"EnabledState.Id": 1,
"EnabledState.TransitionTime": 1,
"EnabledState.EffectiveTransitionTime": 1,
EventId: 1,
EventType: 1,
LocalTime: 1,
SourceName: 1,
SourceNode: 1,
Time: 1
};


type FullBrowsePath = string;
export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnapshot {
public static normalizeName = normalizeName;
Expand Down Expand Up @@ -327,8 +331,8 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
* @param value {Boolean}
* @return void
*/
public setEnabledState(value: boolean): void {
return this._set_twoStateVariable("EnabledState", value);
public setEnabledState(value: boolean, options?: ISetStateOptions): void {
return this._set_twoStateVariable("EnabledState", value, options);
}

/**
Expand Down Expand Up @@ -613,7 +617,7 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
return this._get_twoStateVariable("ConfirmedState");
}

public setConfirmedStateIfExists(confirmedState: boolean): void {
public setConfirmedStateIfExists(confirmedState: boolean, options?: ISetStateOptions): void {
confirmedState = !!confirmedState;
const acknowledgeableCondition = this.condition as UAAcknowledgeableCondition;
if (!acknowledgeableCondition.confirmedState) {
Expand All @@ -622,7 +626,7 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
return;
}
// todo deal with Error code BadConditionBranchAlreadyConfirmed
return this._set_twoStateVariable("ConfirmedState", confirmedState);
return this._set_twoStateVariable("ConfirmedState", confirmedState, options);
}

public setConfirmedState(confirmedState: boolean): void {
Expand All @@ -647,21 +651,21 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
* @method setSuppressedState
* @param suppressed {Boolean}
*/
public setSuppressedState(suppressed: boolean): void {
public setSuppressedState(suppressed: boolean, options?: ISetStateOptions): void {
suppressed = !!suppressed;
this._set_twoStateVariable("SuppressedState", suppressed);
this._set_twoStateVariable("SuppressedState", suppressed, options);
}

public getActiveState(): boolean {
return this._get_twoStateVariable("ActiveState");
}

public setActiveState(newActiveState: boolean): StatusCode {
public setActiveState(newActiveState: boolean, options?: ISetStateOptions): StatusCode {
// xx var activeState = self.getActiveState();
// xx if (activeState === newActiveState) {
// xx return StatusCodes.Bad;
// xx }
this._set_twoStateVariable("ActiveState", newActiveState);
this._set_twoStateVariable("ActiveState", newActiveState, options);
return StatusCodes.Good;
}

Expand Down Expand Up @@ -704,7 +708,7 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
* @param value
* @private
*/
public _set_twoStateVariable(varName: string, value: boolean): void {
public _set_twoStateVariable(varName: string, value: boolean, options?: ISetStateOptions): void {
value = !!value;

const hrKey = ConditionSnapshotImpl.normalizeName(varName);
Expand Down Expand Up @@ -733,7 +737,7 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
// also change ConditionNode if we are on currentBranch
if (this.isCurrentBranch()) {
assert(twoStateNode instanceof UATwoStateVariableImpl);
twoStateNode.setValue(value as boolean);
twoStateNode.setValue(value as boolean, options);
}
this.emit("value_changed", node, variant);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { ConditionInfoOptions } from "../../source/interfaces/alarms_and_conditi
import { UAConditionEx } from "../../source/interfaces/alarms_and_conditions/ua_condition_ex";
import { ConditionSnapshot } from "../../source/interfaces/alarms_and_conditions/condition_snapshot";
import { InstantiateConditionOptions } from "../../source/interfaces/alarms_and_conditions/instantiate_condition_options";
import { ISetStateOptions } from "../../source/interfaces/i_set_state_options";

import { AddressSpacePrivate } from "../address_space_private";
import { _install_TwoStateVariable_machinery } from "../state_machine/ua_two_state_variable";
Expand Down Expand Up @@ -277,7 +278,7 @@ export class UAConditionImpl extends UABaseEventImpl implements UAConditionEx {
* returns {StatusCode} StatusCodes.Good if successful or BadConditionAlreadyEnabled/BadConditionAlreadyDisabled
* @private
*/
public _setEnabledState(requestedEnabledState: boolean): StatusCode {
public _setEnabledState(requestedEnabledState: boolean, options?: ISetStateOptions): StatusCode {
assert(typeof requestedEnabledState === "boolean");

const enabledState = this.getEnabledState();
Expand All @@ -288,7 +289,7 @@ export class UAConditionImpl extends UABaseEventImpl implements UAConditionEx {
return StatusCodes.BadConditionAlreadyDisabled;
}

this._branch0.setEnabledState(requestedEnabledState);
this._branch0.setEnabledState(requestedEnabledState, options);
// conditionNode.enabledState.setValue(requestedEnabledState);

// xx assert(conditionNode.enabledState.id.readValue().value.value === requestedEnabledState,"sanity check 1");
Expand Down Expand Up @@ -346,8 +347,8 @@ export class UAConditionImpl extends UABaseEventImpl implements UAConditionEx {
* @param requestedEnabledState {Boolean}
* @private
*/
public setEnabledState(requestedEnabledState: boolean): StatusCode {
return this._setEnabledState(requestedEnabledState);
public setEnabledState(requestedEnabledState: boolean, options?:ISetStateOptions): StatusCode {
return this._setEnabledState(requestedEnabledState, options);
}

/**
Expand Down Expand Up @@ -491,7 +492,6 @@ export class UAConditionImpl extends UABaseEventImpl implements UAConditionEx {

const branch = this.currentBranch();


const currentDefaultDate = new Date();
const time = conditionInfo.time || currentDefaultDate;
const receiveTime = conditionInfo.receiveTime || currentDefaultDate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { BindVariableOptions, INamespace, UAVariable, UAProperty } from "node-op
import { UAMultiStateDiscrete, UAMultiStateDiscrete_Base } from "node-opcua-nodeset-ua";
import { registerNodePromoter } from "../../source/loader/register_node_promoter";
import { UAVariableImpl } from "../ua_variable_impl";
import { ISetStateOptions } from "../../source/interfaces/i_set_state_options";

import { AddMultiStateDiscreteOptions } from "../../source/address_space_ts";
import { add_dataItem_stuff } from "./add_dataItem_stuff";

Expand All @@ -21,7 +23,7 @@ export interface UAMultiStateDiscreteEx<T, DT extends DataType> extends UAMultiS
getValue(): number;
getValueAsString(): string;
getIndex(value: string): number;
setValue(value: string | number): void;
setValue(value: string | number, options?: ISetStateOptions): void;
checkVariantCompatibility(value: Variant): StatusCode;
}

Expand Down Expand Up @@ -50,13 +52,13 @@ export class UAMultiStateDiscreteImpl<T, DT extends DataType> extends UAVariable
return index;
}

public setValue(value: string | number): void {
public setValue(value: string | number, options?: ISetStateOptions): void {
if (typeof value === "string") {
const index = this.getIndex(value);
if (index < 0) {
throw new Error("UAMultiStateDiscrete#setValue invalid multi state value provided : " + value);
}
return this.setValue(index);
return this.setValue(index, options);
}
const arrayEnumStrings = this.enumStrings.readValue().value.value;
if (value >= arrayEnumStrings.length) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { registerNodePromoter } from "../../source/loader/register_node_promoter
import { coerceEnumValues } from "../../source/helpers/coerce_enum_value";
import { UAMultiStateValueDiscreteEx } from "../../source/interfaces/data_access/ua_multistate_value_discrete_ex";
import { AddMultiStateValueDiscreteOptions } from "../../source/address_space_ts";
import { ISetStateOptions } from "../../source/interfaces/i_set_state_options";
import { UAVariableImpl } from "../ua_variable_impl";

import { add_dataItem_stuff } from "./add_dataItem_stuff";
Expand Down Expand Up @@ -91,7 +92,7 @@ export class UAMultiStateValueDiscreteImpl<T, DT extends DataType>
extends UAVariableImpl
implements UAMultiStateValueDiscreteEx<T, DT>
{
public setValue(value: string | number | Int64): void {
public setValue(value: string | number | Int64, options?: ISetStateOptions): void {
if (typeof value === "string") {
const enumValues = this.enumValues.readValue().value.value;
const selected = enumValues.filter((a: any) => a.displayName.text === value)[0];
Expand All @@ -101,7 +102,7 @@ export class UAMultiStateValueDiscreteImpl<T, DT extends DataType>
throw new Error("cannot find enum string " + value + " in " + enumValues.toString());
}
} else {
this._setValue(coerceUInt64(value));
this._setValue(coerceUInt64(value), options);
}
}

Expand Down Expand Up @@ -162,7 +163,7 @@ export class UAMultiStateValueDiscreteImpl<T, DT extends DataType>
*
* @private
*/
public _setValue(value: Int64): void {
public _setValue(value: Int64, options?: ISetStateOptions): void {
const int32Value = coerceInt64toInt32(value);
// check that value is in bound
if (!this._isValueInRange(int32Value)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import { UAVariableImpl } from "../ua_variable_impl";
import { registerNodePromoter } from "../../source/loader/register_node_promoter";
import { AddTwoStateDiscreteOptions } from "../../source/address_space_ts";
import { UATwoStateDiscreteEx } from "../../source/interfaces/data_access/ua_two_state_discrete_ex";
import { ISetStateOptions } from "../../source/interfaces/i_set_state_options";

import { add_dataItem_stuff } from "./add_dataItem_stuff";


export interface UATwoStateDiscreteImpl {
falseState: UAProperty<LocalizedText, /*c*/ DataType.LocalizedText>;
trueState: UAProperty<LocalizedText, /*c*/ DataType.LocalizedText>;
Expand Down Expand Up @@ -58,15 +60,15 @@ export class UATwoStateDiscreteImpl extends UAVariableImpl implements UATwoState
);
}
}
setValue(value: boolean | LocalizedTextLike): void {
setValue(value: boolean | LocalizedTextLike, options?: ISetStateOptions): void {
if (typeof value === "boolean") {
this.setValueFromSource({ dataType: DataType.Boolean, value });
} else {
const text: string = (typeof value === "string" ? value : value.text) || "";
if (text === this.getTrueStateAsString()) {
this.setValue(true);
this.setValue(true, options);
} else if (text === this.getFalseStateAsString()) {
this.setValue(false);
this.setValue(false, options);
} else {
throw new Error("setValue invalid value " + value);
}
Expand Down

0 comments on commit 84b55ee

Please sign in to comment.