"use strict";
const assert = require("node-opcua-assert").assert;
const _ = require("underscore");
const Namespace = require("../namespace").Namespace;
const DataType = require("node-opcua-variant").DataType;
/**
* @module opcua.address_space
*/
exports.install = function (AddressSpace) {
const UAObjectType = require("./../ua_object_type").UAObjectType;
/**
* @class AddressSpace
* @method addState
* @param component
* @param stateName {string}
* @param stateNumber {number}
* @param isInitialState {boolean}
* @return {UAObject} {StateType|InitialStateType}
*/
AddressSpace.prototype.addState = function (component, stateName, stateNumber, isInitialState) {
return this.getOwnNamespace().addState(component, stateName, stateNumber, isInitialState);
};
Namespace.prototype.addState = function (component, stateName, stateNumber, isInitialState) {
const namespace = this;
const addressSpace = namespace.addressSpace;
isInitialState = !!isInitialState;
assert(component instanceof UAObjectType);
assert(_.isString(stateName));
assert(_.isBoolean(isInitialState));
const initialStateType = addressSpace.findObjectType("InitialStateType");
const stateType = addressSpace.findObjectType("StateType");
let state;
if (isInitialState) {
state = initialStateType.instantiate({
browseName: stateName,
componentOf: component
});
} else {
state = stateType.instantiate({
browseName: stateName,
componentOf: component
});
}
// ensure state number is unique
state.stateNumber.setValueFromSource({
dataType: DataType.UInt32,
value: stateNumber
});
return state;
};
/**
* @method addTransition
* @param component {UAObject}
* @param fromState {StateType|InitialStateType}
* @param toState {StateType|InitialStateType}
* @param transitionNumber {Number}
* @return {UAObject} TransitionType
*/
AddressSpace.prototype.addTransition = function (component, fromState, toState, transitionNumber) {
this.getOwnNamespace().addTransition(component, fromState, toState, transitionNumber);
};
Namespace.prototype.addTransition = function (component, fromState, toState, transitionNumber) {
const namespace = this;
const addressSpace = namespace.addressSpace;
assert(component instanceof UAObjectType);
assert(_.isString(fromState));
assert(_.isString(toState));
assert(_.isFinite(transitionNumber));
const fromStateNode = component.getComponentByName(fromState, component.nodeId.namespace);
// istanbul ignore next
if (!fromStateNode) {
throw new Error("Cannot find state with name " + fromState);
}
assert(fromStateNode.browseName.name.toString() === fromState);
const toStateNode = component.getComponentByName(toState);
// istanbul ignore next
if (!toStateNode) {
throw new Error("Cannot find state with name " + toState);
}
assert(toStateNode && toStateNode.browseName.name.toString() === toState);
const transitionType = addressSpace.findObjectType("TransitionType");
const transition = transitionType.instantiate({
browseName: fromState + "To" + toState + "Transition",
componentOf: component
});
transition.addReference({
referenceType: "ToState",
isForward: true,
nodeId: toStateNode.nodeId
});
transition.addReference({
referenceType: "FromState",
isForward: true,
nodeId: fromStateNode.nodeId
});
transition.transitionNumber.setValueFromSource({
dataType: DataType.UInt32, value: transitionNumber
})
};
};