const assert = require("node-opcua-assert").assert;
const util = require("util");
const address_space = require("../address_space");
const DataType = require("node-opcua-variant").DataType;
const Variant = require("node-opcua-variant").Variant;
const VariantArrayType = require("node-opcua-variant").VariantArrayType;
const add_dataItem_stuff = require("./UADataItem").add_dataItem_stuff;
const coerceLocalizedText = require("node-opcua-data-model").coerceLocalizedText;
const _ = require("underscore");
const Namespace = require("../namespace").Namespace;
const UAVariable = require("../ua_variable").UAVariable;
/**
* @class UAMultiStateDiscreteType
* @constructor
*/
function UAMultiStateDiscreteType() {
}
util.inherits(UAMultiStateDiscreteType,UAVariable);
UAMultiStateDiscreteType.prototype.getValue = function() {
return this.readValue().value.value;
};
/**
* @method getValueAsString
* @return {String}
*/
UAMultiStateDiscreteType.prototype.getValueAsString = function() {
const index = this.getValue();
const arr = this.enumStrings.readValue().value.value;
assert(_.isArray(arr));
return arr[index].text.toString();
};
UAMultiStateDiscreteType.prototype.getIndex = function(value) {
const arr = this.enumStrings.readValue().value.value;
assert(_.isArray(arr));
const index = arr.findIndex(function(a) { return a.text === value;});
return index;
};
UAMultiStateDiscreteType.prototype.setValue = function(value) {
if (typeof(value) === "string") {
const index = this.getIndex(value);
assert(index>=0," invalid multi state value provided");
return this.setValue(index);
}
assert(_.isFinite(value));
return this.setValueFromSource(new Variant({ dataType: DataType.UInt32, value: value }));
};
module.exports.install = function(AddressSpace) {
/**
*
* @method addMultiStateDiscrete
* @param options {Object}
* @param options.browseName {String}
* @param [options.nodeId {NodeId}]
* @param [options.value {UInt32} = 0 ]
* @param options.enumStrings {String[]} an array containing the String associated with each enumeration value, starting from 0 onward
* @return {Object|UAVariable}
*/
AddressSpace.prototype.addMultiStateDiscrete = function(options) {
this._resolveRequestedNamespace(options).addMultiStateDiscrete(options);
};
Namespace.prototype.addMultiStateDiscrete = function(options) {
const namespace = this;
const addressSpace = namespace.addressSpace;
assert(addressSpace instanceof AddressSpace);
assert(options.hasOwnProperty("enumStrings"));
assert(!options.hasOwnProperty("ValuePrecision"));
const multiStateDiscreteType = addressSpace.findVariableType("MultiStateDiscreteType");
assert(multiStateDiscreteType, "expecting MultiStateDiscreteType to be defined , check nodeset xml file");
// todo : if options.typeDefinition is specified, check that type is SubTypeOf MultiStateDiscreteType
options.value = ( options.value === undefined) ? 0 : options.value;
const variable = namespace.addVariable(_.extend(options,{
typeDefinition: multiStateDiscreteType.nodeId,
dataType: "UInteger",
valueRank: -2,
value: new Variant({ dataType: DataType.UInt32, value: options.value })
}));
add_dataItem_stuff(variable,options);
const enumStrings = options.enumStrings.map(function(value) {
return coerceLocalizedText(value)
});
const enumStringsNode = namespace.addVariable({
modellingRule: options.modellingRule ? "Mandatory" : undefined,
propertyOf: variable,
typeDefinition: "PropertyType",
browseName: {name:"EnumStrings",namespaceIndex:0},
dataType: "LocalizedText",
accessLevel: "CurrentRead", //| CurrentWrite",
userAccessLevel: "CurrentRead",// CurrentWrite",
minimumSamplingInterval: 0,
value: new Variant({
dataType: DataType.LocalizedText,
arrayType: VariantArrayType.Array,
value: enumStrings
})
});
const handler = variable.handle_semantic_changed.bind(variable);
enumStringsNode.on("value_changed",handler);
variable.install_extra_properties();
assert(variable.enumStrings.browseName.toString() === "EnumStrings");
Object.setPrototypeOf(variable, UAMultiStateDiscreteType.prototype);
return variable;
};
};