node-opcua-client-dynamic-extension-object
Advanced tools
Comparing version 2.5.0-alpha.2 to 2.5.0-alpha.3
@@ -0,0 +0,0 @@ import { StructuredTypeSchema } from "node-opcua-factory"; |
@@ -174,5 +174,32 @@ "use strict"; | ||
} | ||
function sortStructure(dataTypeDefinitions) { | ||
const dataTypeDefinitionsSorted = []; | ||
const _visited = {}; | ||
const _map = {}; | ||
for (const d of dataTypeDefinitions) { | ||
_map[d.dataTypeNodeId.toString()] = d; | ||
} | ||
function _visit(d) { | ||
const hash = d.dataTypeDefinition.toString(); | ||
if (_visited[hash]) { | ||
return; | ||
} | ||
for (const f of d.dataTypeDefinition.fields || []) { | ||
const ddd = _map[f.dataType.toString()]; | ||
if (!ddd) { | ||
continue; | ||
} | ||
_visit(ddd); | ||
} | ||
_visited[hash] = d; | ||
dataTypeDefinitionsSorted.push(d); | ||
} | ||
for (const d of dataTypeDefinitions) { | ||
_visit(d); | ||
} | ||
return dataTypeDefinitionsSorted; | ||
} | ||
function _extractDataTypeDictionaryFromDefinition(session, dataTypeDictionaryNodeId, dataTypeFactory) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
console.log(chalk.bgRed("_extractDataTypeDictionaryFromDefinition")); | ||
node_opcua_assert_1.assert(dataTypeFactory, "expecting a dataTypeFactory"); | ||
const dataTypeDescriptions = yield _getDataTypeDescriptions(session, dataTypeDictionaryNodeId); | ||
@@ -193,2 +220,3 @@ const dataTypeNodeIds = yield _enrichWithDescriptionOf(session, dataTypeDescriptions); | ||
index++; | ||
debugLog("in ... populateDataTypeManager"); | ||
/* istanbul ignore next */ | ||
@@ -201,3 +229,2 @@ if (dataValue.statusCode !== node_opcua_status_code_1.StatusCodes.Good) { | ||
const className = dataTypeDescription.browseName.name; | ||
console.log("xxx processing dataType", className, dataTypeNodeId.toString()); | ||
dataTypeDefinitions.push({ className, dataTypeNodeId, dataTypeDefinition }); | ||
@@ -207,5 +234,4 @@ } | ||
// to do put in logicial order | ||
console.log("---------------------------------"); | ||
console.log("---------------------------------"); | ||
for (const { className, dataTypeNodeId, dataTypeDefinition } of dataTypeDefinitions) { | ||
const dataTypeDefinitionsSorted = sortStructure(dataTypeDefinitions); | ||
for (const { className, dataTypeNodeId, dataTypeDefinition } of dataTypeDefinitionsSorted) { | ||
if (dataTypeFactory.hasStructuredType(className)) { | ||
@@ -216,9 +242,3 @@ continue; | ||
try { | ||
const schema = yield _convertDataTypeDefinitionToStructureTypeSchema(session, className, dataTypeDefinition, dataTypeFactory, cache); | ||
schema.dataTypeNodeId = dataTypeNodeId; | ||
schema.id = dataTypeNodeId; | ||
const encodings = yield _findEncodings(session, dataTypeNodeId); | ||
schema.encodingDefaultBinary = node_opcua_nodeid_1.makeExpandedNodeId(encodings.binaryEncodingNodeId); | ||
schema.encodingDefaultXml = node_opcua_nodeid_1.makeExpandedNodeId(encodings.xmlEncodingNodeId); | ||
schema.encodingDefaultJson = node_opcua_nodeid_1.makeExpandedNodeId(encodings.jsonEncodingNodeId); | ||
const schema = yield _convertDataTypeDefinitionToStructureTypeSchema(session, dataTypeNodeId, className, dataTypeDefinition, dataTypeFactory, cache); | ||
console.log(chalk.red("Registering "), chalk.cyan(className.padEnd(30, " ")), schema.dataTypeNodeId.toString()); | ||
@@ -264,2 +284,5 @@ const Constructor = node_opcua_schemas_1.createDynamicObjectConstructor(schema, dataTypeFactory); | ||
const dataTypeFactory2 = dataTypeManager.getDataTypeFactory(dataTypeDictionaryNodeId.namespace); | ||
if (!dataTypeFactory2) { | ||
throw new Error("cannot find dataTypeFactort for namespace " + dataTypeDictionaryNodeId.namespace); | ||
} | ||
yield _extractDataTypeDictionaryFromDefinition(session, dataTypeDictionaryNodeId, dataTypeFactory2); | ||
@@ -418,24 +441,4 @@ return; | ||
exports.populateDataTypeManager = populateDataTypeManager; | ||
function getDataTypeDefinition(session, dataTypeNodeId, | ||
// tslint:disable-next-line: no-shadowed-variable | ||
dataTypeManager) { | ||
function getHasEncodingDefaultBinary(session, dataTypeNodeId) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// DataType | ||
// | 1 | ||
// | n | ||
// +- HasEncoding-> "Default Binary" (O)[DataTypeEncodingType] | ||
// | | ||
// +-- HasDescription -> "MyItemType" (V)[DataTypeDescriptionType] | ||
// | | ||
// +- ComponentOf -> Schema(V) [] | ||
// | | ||
// +- ComponentOf -> OPC Binary(V)[DataTypeSystemType] | ||
// | ||
// Note that in 1.04 compliant server, DataType definition might be available | ||
// in a DataTypeDefinition attributes of the DataType object | ||
// However this is a brand new aspect of the specification and is not widely implemented | ||
// it is also optional | ||
// It will takes time for old opcua server to be refurbished and we may have to | ||
// keep the current method to access type definition from embedded xsd. | ||
// | ||
const nodeToBrowse1 = { | ||
@@ -481,2 +484,7 @@ browseDirection: node_opcua_service_browse_1.BrowseDirection.Forward, | ||
} | ||
return encodingReference.nodeId; | ||
}); | ||
} | ||
function getDefinition(session, defaultBinaryEncodingNodeId) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const nodeToBrowse2 = { | ||
@@ -486,3 +494,3 @@ browseDirection: node_opcua_service_browse_1.BrowseDirection.Forward, | ||
nodeClassMask: node_opcua_data_model_1.makeNodeClassMask("Variable"), | ||
nodeId: encodingReference.nodeId, | ||
nodeId: defaultBinaryEncodingNodeId, | ||
referenceTypeId: node_opcua_nodeid_1.resolveNodeId("HasDescription"), | ||
@@ -499,3 +507,17 @@ resultMask: node_opcua_data_model_1.makeResultMask("NodeId | ReferenceType | BrowseName | NodeClass | TypeDefinition") | ||
}); | ||
const name = nameDataValue.value.value; | ||
if (nameDataValue.statusCode !== node_opcua_status_code_1.StatusCodes.Good) { | ||
throw new Error("Cannot find ... " + definitionRef.nodeId.toString()); | ||
} | ||
/* | ||
const name = nameDataValue.value.value as string; | ||
if (!name) { | ||
console.log(nameDataValue.toString()); | ||
throw new Error("Cannot find ... " + name + " " + definitionRef.nodeId.toString()); | ||
} | ||
*/ | ||
return definitionRef.nodeId; | ||
}); | ||
} | ||
function getSchemaNode(session, definitionRefNodeId) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// find parent node to access the xsd File | ||
@@ -506,3 +528,3 @@ const nodeToBrowse3 = { | ||
nodeClassMask: node_opcua_data_model_1.makeNodeClassMask("Variable"), | ||
nodeId: definitionRef.nodeId, | ||
nodeId: definitionRefNodeId, | ||
referenceTypeId: node_opcua_nodeid_1.resolveNodeId("HasComponent"), | ||
@@ -514,2 +536,30 @@ resultMask: node_opcua_data_model_1.makeResultMask("NodeId | ReferenceType | BrowseName | NodeClass | TypeDefinition") | ||
const schemaNode = result3.references[0].nodeId; | ||
return schemaNode; | ||
}); | ||
} | ||
function getDataTypeDefinition(session, dataTypeNodeId, | ||
// tslint:disable-next-line: no-shadowed-variable | ||
dataTypeManager) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// DataType | ||
// | 1 | ||
// | n | ||
// +- HasEncoding-> "Default Binary" (O)[DataTypeEncodingType] | ||
// | | ||
// +-- HasDescription -> "MyItemType" (V)[DataTypeDescriptionType] | ||
// | | ||
// +- ComponentOf -> Schema(V) [] | ||
// | | ||
// +- ComponentOf -> OPC Binary(V)[DataTypeSystemType] | ||
// | ||
// Note that in 1.04 compliant server, DataType definition might be available | ||
// in a DataTypeDefinition attributes of the DataType object | ||
// However this is a brand new aspect of the specification and is not widely implemented | ||
// it is also optional | ||
// It will takes time for old opcua server to be refurbished and we may have to | ||
// keep the current method to access type definition from embedded xsd. | ||
// | ||
const defaultBinaryEncodingNodeId = yield getHasEncodingDefaultBinary(session, dataTypeNodeId); | ||
const definitionRefNodeId = yield getDefinition(session, defaultBinaryEncodingNodeId); | ||
const schemaNode = yield getSchemaNode(session, definitionRefNodeId); | ||
const dataTypeFactory = dataTypeManager.getDataTypeFactoryForNamespace(schemaNode.namespace); | ||
@@ -520,2 +570,3 @@ /* istanbul ignore next */ | ||
} | ||
const name = yield (yield session.read({ nodeId: dataTypeNodeId, attributeId: node_opcua_data_model_1.AttributeIds.BrowseName })).value.value.name; | ||
const schema = dataTypeFactory.getStructuredTypeSchema(name); | ||
@@ -584,3 +635,3 @@ return schema; | ||
if (cache[key]) { | ||
return cache[key].category; | ||
return cache[key].schema; | ||
} | ||
@@ -649,2 +700,3 @@ if (subTypeNodeId.namespace === 0 && subTypeNodeId.value < 29) { | ||
break; | ||
default: | ||
case "complex": | ||
@@ -658,10 +710,11 @@ case "enumeration": | ||
if (dataTypeDefinitionDataValue.statusCode !== node_opcua_status_code_1.StatusCodes.Good) { | ||
console.log(dataTypeDefinitionDataValue.toString()); | ||
throw new Error(" Cannot find dataType Definition!"); | ||
} | ||
const definition = dataTypeDefinitionDataValue.value.value; | ||
schema = yield _convertDataTypeDefinitionToStructureTypeSchema(session, fieldTypeName, definition, dataTypeFactory, cache); | ||
// schema = await _convertDataTypeDefinitionToStructureTypeSchema(session, fieldTypeName, definition, dataTypeFactory, cache); | ||
schema = dataTypeFactory.getStructuredTypeSchema(fieldTypeName); | ||
break; | ||
} | ||
} | ||
node_opcua_assert_1.assert(schema, "expecting a schema here"); | ||
const v2 = { | ||
@@ -676,4 +729,15 @@ category, | ||
} | ||
function _convertDataTypeDefinitionToStructureTypeSchema(session, name, definition, dataTypeFactory, cache) { | ||
function _setupEncodings(session, dataTypeNodeId, schema) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
schema.dataTypeNodeId = dataTypeNodeId; | ||
schema.id = dataTypeNodeId; | ||
const encodings = yield _findEncodings(session, dataTypeNodeId); | ||
schema.encodingDefaultBinary = node_opcua_nodeid_1.makeExpandedNodeId(encodings.binaryEncodingNodeId); | ||
schema.encodingDefaultXml = node_opcua_nodeid_1.makeExpandedNodeId(encodings.xmlEncodingNodeId); | ||
schema.encodingDefaultJson = node_opcua_nodeid_1.makeExpandedNodeId(encodings.jsonEncodingNodeId); | ||
return schema; | ||
}); | ||
} | ||
function _convertDataTypeDefinitionToStructureTypeSchema(session, dataTypeNodeId, name, definition, dataTypeFactory, cache) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (definition instanceof node_opcua_types_1.StructureDefinition) { | ||
@@ -691,2 +755,3 @@ switch (definition.structureType) { | ||
name: fieldD.name, | ||
schema, | ||
}; | ||
@@ -696,3 +761,2 @@ if (fieldD.valueRank === 1) { | ||
} | ||
field.schema = schema; | ||
field.category = category; | ||
@@ -703,3 +767,3 @@ fields.push(field); | ||
const baseType = a ? a.fieldTypeName : "ExtensionObject"; | ||
const os = { | ||
const os = new node_opcua_factory_1.StructuredTypeSchema({ | ||
baseType, | ||
@@ -709,9 +773,6 @@ fields, | ||
name, | ||
}; | ||
return new node_opcua_factory_1.StructuredTypeSchema(os); | ||
}); | ||
console.log(os); | ||
return yield _setupEncodings(session, dataTypeNodeId, os); | ||
} | ||
else if (definition instanceof node_opcua_types_1.EnumDefinition) { | ||
// | ||
console.log("xxxx Ignoring enumeration !!!!"); | ||
} | ||
throw new Error("Not Implemented"); | ||
@@ -718,0 +779,0 @@ }); |
@@ -6,3 +6,2 @@ import { ConstructorFunc, DataTypeFactory } from "node-opcua-factory"; | ||
namespaceArray: string[]; | ||
private readonly dataTypeFactoryMap; | ||
private readonly dataTypeFactoryMapByNamespace; | ||
@@ -17,2 +16,3 @@ constructor(); | ||
getExtensionObjectConstructorFromBinaryEncoding(binaryEncodingNodeId: NodeId): ConstructorFunc; | ||
toString(): string; | ||
} |
@@ -6,2 +6,3 @@ "use strict"; | ||
*/ | ||
const util = require("util"); | ||
const node_opcua_assert_1 = require("node-opcua-assert"); | ||
@@ -12,3 +13,2 @@ const node_opcua_factory_1 = require("node-opcua-factory"); | ||
this.namespaceArray = []; | ||
this.dataTypeFactoryMap = {}; | ||
this.dataTypeFactoryMapByNamespace = {}; | ||
@@ -51,8 +51,24 @@ /* */ | ||
if (!Constructor) { | ||
throw new Error("getExtensionObjectConstructorFromBinaryEncoding cannot find constructor for " + binaryEncodingNodeId.toString()); | ||
throw new Error("getExtensionObjectConstructorFromBinaryEncoding cannot find constructor for binaryEncoding " + binaryEncodingNodeId.toString()); | ||
} | ||
return Constructor; | ||
} | ||
toString() { | ||
const l = []; | ||
function write(...args) { | ||
l.push(util.format.apply(util.format, args)); | ||
} | ||
write("ExtraDataTypeMananager"); | ||
for (let n = 0; n < this.namespaceArray.length; n++) { | ||
write("-----------", this.namespaceArray[n]); | ||
const dataFactory = this.dataTypeFactoryMapByNamespace[n]; | ||
if (!dataFactory) { | ||
continue; | ||
} | ||
write(dataFactory.toString()); | ||
} | ||
return l.join("\n"); | ||
} | ||
} | ||
exports.ExtraDataTypeManager = ExtraDataTypeManager; | ||
//# sourceMappingURL=extra_data_type_manager.js.map |
@@ -0,0 +0,0 @@ /** |
@@ -0,0 +0,0 @@ "use strict"; |
@@ -0,0 +0,0 @@ import { DataValue } from "node-opcua-data-value"; |
@@ -0,0 +0,0 @@ "use strict"; |
import { Variant } from "node-opcua-variant"; | ||
import { ExtraDataTypeManager } from "./extra_data_type_manager"; | ||
export declare function resolveDynamicExtensionObject(variant: Variant, extraDataType: ExtraDataTypeManager): Promise<void>; | ||
export declare function resolveDynamicExtensionObject(variant: Variant, dataTypeManager: ExtraDataTypeManager): Promise<void>; |
@@ -15,5 +15,5 @@ "use strict"; | ||
const node_opcua_variant_1 = require("node-opcua-variant"); | ||
function resolveDynamicExtensionObjectV(opaque, extraDataType) { | ||
function resolveDynamicExtensionObjectV(opaque, dataTypeManager) { | ||
try { | ||
const Constructor = extraDataType.getExtensionObjectConstructorFromBinaryEncoding(opaque.nodeId); | ||
const Constructor = dataTypeManager.getExtensionObjectConstructorFromBinaryEncoding(opaque.nodeId); | ||
const object = new Constructor(); | ||
@@ -30,3 +30,3 @@ const stream = new node_opcua_binary_stream_1.BinaryStream(opaque.buffer); | ||
} | ||
function resolveDynamicExtensionObject(variant, extraDataType) { | ||
function resolveDynamicExtensionObject(variant, dataTypeManager) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -42,3 +42,3 @@ if (variant.dataType !== node_opcua_variant_1.DataType.ExtensionObject) { | ||
} | ||
const obj = resolveDynamicExtensionObjectV(v, extraDataType); | ||
const obj = resolveDynamicExtensionObjectV(v, dataTypeManager); | ||
return obj; | ||
@@ -52,3 +52,3 @@ }); | ||
} | ||
variant.value = resolveDynamicExtensionObjectV(variant.value, extraDataType); | ||
variant.value = resolveDynamicExtensionObjectV(variant.value, dataTypeManager); | ||
}); | ||
@@ -55,0 +55,0 @@ } |
{ | ||
"name": "node-opcua-client-dynamic-extension-object", | ||
"version": "2.5.0-alpha.2", | ||
"version": "2.5.0-alpha.3", | ||
"description": "pure nodejs OPCUA SDK - module client-dynamic-extension-object", | ||
@@ -15,15 +15,15 @@ "main": "./dist/index.js", | ||
"node-opcua-binary-stream": "^2.5.0-alpha.0", | ||
"node-opcua-data-model": "^2.5.0-alpha.1", | ||
"node-opcua-data-value": "^2.5.0-alpha.1", | ||
"node-opcua-data-model": "^2.5.0-alpha.3", | ||
"node-opcua-data-value": "^2.5.0-alpha.3", | ||
"node-opcua-debug": "^2.5.0-alpha.0", | ||
"node-opcua-extension-object": "^2.5.0-alpha.0", | ||
"node-opcua-factory": "^2.5.0-alpha.0", | ||
"node-opcua-extension-object": "^2.5.0-alpha.3", | ||
"node-opcua-factory": "^2.5.0-alpha.3", | ||
"node-opcua-nodeid": "^2.5.0-alpha.0", | ||
"node-opcua-pseudo-session": "^2.5.0-alpha.1", | ||
"node-opcua-schemas": "^2.5.0-alpha.1", | ||
"node-opcua-service-browse": "^2.5.0-alpha.1", | ||
"node-opcua-service-translate-browse-path": "^2.5.0-alpha.1", | ||
"node-opcua-pseudo-session": "^2.5.0-alpha.3", | ||
"node-opcua-schemas": "^2.5.0-alpha.3", | ||
"node-opcua-service-browse": "^2.5.0-alpha.3", | ||
"node-opcua-service-translate-browse-path": "^2.5.0-alpha.3", | ||
"node-opcua-status-code": "^2.5.0-alpha.0", | ||
"node-opcua-types": "^2.5.0-alpha.1", | ||
"node-opcua-variant": "^2.5.0-alpha.1" | ||
"node-opcua-types": "^2.5.0-alpha.3", | ||
"node-opcua-variant": "^2.5.0-alpha.3" | ||
}, | ||
@@ -45,3 +45,3 @@ "author": "Etienne Rossignon", | ||
"homepage": "http://node-opcua.github.io/", | ||
"gitHead": "b56b01a361c4741405cebd24c199e495eae37cd6" | ||
"gitHead": "6147dcbfbecdb8b72a3d331dd2859cbdf3e3e181" | ||
} |
@@ -28,2 +28,5 @@ // tslint:disable: no-console | ||
StructuredTypeSchema, | ||
BasicTypeSchema, | ||
TypeSchemaBase, | ||
TypeDefinition, | ||
} from "node-opcua-factory"; | ||
@@ -235,3 +238,37 @@ import { | ||
} | ||
interface IDataTypeDefInfo { | ||
className: string; | ||
dataTypeNodeId: NodeId; | ||
dataTypeDefinition: StructureDefinition | ||
} | ||
type DataTypeDefinitions = Array<IDataTypeDefInfo>; | ||
function sortStructure(dataTypeDefinitions: DataTypeDefinitions) { | ||
const dataTypeDefinitionsSorted: IDataTypeDefInfo[] = []; | ||
const _visited: { [key: string]: IDataTypeDefInfo } = {}; | ||
const _map: { [key: string]: IDataTypeDefInfo } = {}; | ||
for (const d of dataTypeDefinitions) { | ||
_map[d.dataTypeNodeId.toString()] = d; | ||
} | ||
function _visit(d: IDataTypeDefInfo) { | ||
const hash = d.dataTypeDefinition.toString(); | ||
if (_visited[hash]) { | ||
return; | ||
} | ||
for (const f of d.dataTypeDefinition.fields || []) { | ||
const ddd = _map[f.dataType.toString()]; | ||
if (!ddd) { | ||
continue; | ||
} | ||
_visit(ddd); | ||
} | ||
_visited[hash] = d; | ||
dataTypeDefinitionsSorted.push(d); | ||
} | ||
for (const d of dataTypeDefinitions) { | ||
_visit(d); | ||
} | ||
return dataTypeDefinitionsSorted; | ||
} | ||
async function _extractDataTypeDictionaryFromDefinition( | ||
@@ -243,3 +280,3 @@ session: IBasicSession, | ||
console.log(chalk.bgRed("_extractDataTypeDictionaryFromDefinition")); | ||
assert(dataTypeFactory, "expecting a dataTypeFactory"); | ||
@@ -254,3 +291,3 @@ const dataTypeDescriptions = await _getDataTypeDescriptions(session, dataTypeDictionaryNodeId); | ||
const cache: any = {}; | ||
const cache: { [key: string]: Cache } = {}; | ||
const dataValuesWithDataTypeDefinition = await session.read(nodesToRead); | ||
@@ -260,3 +297,3 @@ | ||
const dataTypeDefinitions: Array<{ className: string, dataTypeNodeId: NodeId, dataTypeDefinition: StructureDefinition }> = []; | ||
const dataTypeDefinitions: DataTypeDefinitions = []; | ||
@@ -269,2 +306,3 @@ let index = 0; | ||
index++; | ||
debugLog("in ... populateDataTypeManager"); | ||
@@ -279,3 +317,2 @@ /* istanbul ignore next */ | ||
const className = dataTypeDescription.browseName.name!; | ||
console.log("xxx processing dataType", className, dataTypeNodeId.toString()); | ||
dataTypeDefinitions.push({ className, dataTypeNodeId, dataTypeDefinition }); | ||
@@ -285,6 +322,5 @@ } | ||
// to do put in logicial order | ||
const dataTypeDefinitionsSorted = sortStructure(dataTypeDefinitions); | ||
console.log("---------------------------------"); | ||
console.log("---------------------------------"); | ||
for (const { className, dataTypeNodeId, dataTypeDefinition } of dataTypeDefinitions) { | ||
for (const { className, dataTypeNodeId, dataTypeDefinition } of dataTypeDefinitionsSorted) { | ||
if (dataTypeFactory.hasStructuredType(className)) { | ||
@@ -296,11 +332,4 @@ continue; | ||
const schema = await _convertDataTypeDefinitionToStructureTypeSchema( | ||
session, className, dataTypeDefinition, dataTypeFactory, cache); | ||
session, dataTypeNodeId, className, dataTypeDefinition, dataTypeFactory, cache); | ||
schema.dataTypeNodeId = dataTypeNodeId; | ||
schema.id = dataTypeNodeId; | ||
const encodings = await _findEncodings(session, dataTypeNodeId); | ||
schema.encodingDefaultBinary = makeExpandedNodeId(encodings.binaryEncodingNodeId); | ||
schema.encodingDefaultXml = makeExpandedNodeId(encodings.xmlEncodingNodeId); | ||
schema.encodingDefaultJson = makeExpandedNodeId(encodings.jsonEncodingNodeId); | ||
console.log(chalk.red("Registering "), chalk.cyan(className.padEnd(30, " ")), schema.dataTypeNodeId.toString()); | ||
@@ -361,2 +390,5 @@ const Constructor = createDynamicObjectConstructor(schema, dataTypeFactory) as ConstructorFuncWithSchema; | ||
const dataTypeFactory2 = dataTypeManager.getDataTypeFactory(dataTypeDictionaryNodeId.namespace); | ||
if (!dataTypeFactory2) { | ||
throw new Error("cannot find dataTypeFactort for namespace " + dataTypeDictionaryNodeId.namespace); | ||
} | ||
await _extractDataTypeDictionaryFromDefinition(session, dataTypeDictionaryNodeId, dataTypeFactory2); | ||
@@ -544,27 +576,7 @@ return; | ||
export async function getDataTypeDefinition( | ||
async function getHasEncodingDefaultBinary( | ||
session: IBasicSession, | ||
dataTypeNodeId: NodeId, | ||
// tslint:disable-next-line: no-shadowed-variable | ||
dataTypeManager: ExtraDataTypeManager | ||
): Promise<StructuredTypeSchema> { | ||
dataTypeNodeId: NodeId | ||
): Promise<NodeId> { | ||
// DataType | ||
// | 1 | ||
// | n | ||
// +- HasEncoding-> "Default Binary" (O)[DataTypeEncodingType] | ||
// | | ||
// +-- HasDescription -> "MyItemType" (V)[DataTypeDescriptionType] | ||
// | | ||
// +- ComponentOf -> Schema(V) [] | ||
// | | ||
// +- ComponentOf -> OPC Binary(V)[DataTypeSystemType] | ||
// | ||
// Note that in 1.04 compliant server, DataType definition might be available | ||
// in a DataTypeDefinition attributes of the DataType object | ||
// However this is a brand new aspect of the specification and is not widely implemented | ||
// it is also optional | ||
// It will takes time for old opcua server to be refurbished and we may have to | ||
// keep the current method to access type definition from embedded xsd. | ||
// | ||
const nodeToBrowse1 = { | ||
@@ -578,2 +590,3 @@ browseDirection: BrowseDirection.Forward, | ||
}; | ||
const result1 = await session.browse(nodeToBrowse1); | ||
@@ -618,3 +631,7 @@ | ||
} | ||
return encodingReference.nodeId; | ||
} | ||
async function getDefinition(session: IBasicSession, defaultBinaryEncodingNodeId: NodeId): Promise<NodeId> { | ||
const nodeToBrowse2 = { | ||
@@ -624,3 +641,3 @@ browseDirection: BrowseDirection.Forward, | ||
nodeClassMask: makeNodeClassMask("Variable"), | ||
nodeId: encodingReference.nodeId, | ||
nodeId: defaultBinaryEncodingNodeId, | ||
referenceTypeId: resolveNodeId("HasDescription"), | ||
@@ -639,4 +656,16 @@ resultMask: makeResultMask("NodeId | ReferenceType | BrowseName | NodeClass | TypeDefinition") | ||
}); | ||
if (nameDataValue.statusCode !== StatusCodes.Good) { | ||
throw new Error("Cannot find ... " + definitionRef.nodeId.toString()); | ||
} | ||
/* | ||
const name = nameDataValue.value.value as string; | ||
if (!name) { | ||
console.log(nameDataValue.toString()); | ||
throw new Error("Cannot find ... " + name + " " + definitionRef.nodeId.toString()); | ||
} | ||
*/ | ||
return definitionRef.nodeId; | ||
} | ||
async function getSchemaNode(session: IBasicSession, definitionRefNodeId: NodeId) { | ||
// find parent node to access the xsd File | ||
@@ -647,3 +676,3 @@ const nodeToBrowse3 = { | ||
nodeClassMask: makeNodeClassMask("Variable"), | ||
nodeId: definitionRef.nodeId, | ||
nodeId: definitionRefNodeId, | ||
referenceTypeId: resolveNodeId("HasComponent"), | ||
@@ -655,3 +684,37 @@ resultMask: makeResultMask("NodeId | ReferenceType | BrowseName | NodeClass | TypeDefinition") | ||
const schemaNode = result3.references![0]!.nodeId; | ||
return schemaNode; | ||
} | ||
export async function getDataTypeDefinition( | ||
session: IBasicSession, | ||
dataTypeNodeId: NodeId, | ||
// tslint:disable-next-line: no-shadowed-variable | ||
dataTypeManager: ExtraDataTypeManager | ||
): Promise<StructuredTypeSchema> { | ||
// DataType | ||
// | 1 | ||
// | n | ||
// +- HasEncoding-> "Default Binary" (O)[DataTypeEncodingType] | ||
// | | ||
// +-- HasDescription -> "MyItemType" (V)[DataTypeDescriptionType] | ||
// | | ||
// +- ComponentOf -> Schema(V) [] | ||
// | | ||
// +- ComponentOf -> OPC Binary(V)[DataTypeSystemType] | ||
// | ||
// Note that in 1.04 compliant server, DataType definition might be available | ||
// in a DataTypeDefinition attributes of the DataType object | ||
// However this is a brand new aspect of the specification and is not widely implemented | ||
// it is also optional | ||
// It will takes time for old opcua server to be refurbished and we may have to | ||
// keep the current method to access type definition from embedded xsd. | ||
// | ||
const defaultBinaryEncodingNodeId = await getHasEncodingDefaultBinary(session, dataTypeNodeId); | ||
const definitionRefNodeId = await getDefinition(session, defaultBinaryEncodingNodeId); | ||
const schemaNode = await getSchemaNode(session, definitionRefNodeId); | ||
const dataTypeFactory = dataTypeManager.getDataTypeFactoryForNamespace(schemaNode.namespace); | ||
@@ -663,2 +726,3 @@ | ||
} | ||
const name = await (await session.read({ nodeId: dataTypeNodeId, attributeId: AttributeIds.BrowseName })).value.value.name; | ||
@@ -699,3 +763,3 @@ const schema = dataTypeFactory.getStructuredTypeSchema(name); | ||
session: IBasicSession, | ||
cache: any, | ||
cache: { [key: string]: Cache }, | ||
dataTypeNodeId: NodeId | ||
@@ -732,5 +796,5 @@ ): Promise<FieldCategory> { | ||
session: IBasicSession, | ||
cache: any, | ||
cache: { [key: string]: Cache }, | ||
dataTypeNodeId: NodeId | ||
): Promise<BasicTypeDefinition> { | ||
): Promise<TypeDefinition> { | ||
const subTypeNodeId = await findSuperType(session, dataTypeNodeId); | ||
@@ -740,3 +804,3 @@ console.log("subTypeNodeId of ", dataTypeNodeId.toString(), " is ", subTypeNodeId.toString()); | ||
if (cache[key]) { | ||
return cache[key].category; | ||
return cache[key].schema; | ||
} | ||
@@ -761,3 +825,3 @@ if (subTypeNodeId.namespace === 0 && subTypeNodeId.value < 29) { | ||
fieldTypeName: string; | ||
schema: any; | ||
schema: TypeDefinition; | ||
category: FieldCategory; | ||
@@ -795,3 +859,3 @@ } | ||
let schema: any; | ||
let schema: TypeDefinition; | ||
let category: FieldCategory = FieldCategory.enumeration; | ||
@@ -807,3 +871,3 @@ | ||
category = FieldCategory.enumeration; | ||
schema = dataTypeFactory.getEnumeration(fieldTypeName!); | ||
schema = dataTypeFactory.getEnumeration(fieldTypeName!)!; | ||
} else { | ||
@@ -820,2 +884,3 @@ | ||
break; | ||
default: | ||
case "complex": | ||
@@ -830,3 +895,2 @@ case "enumeration": | ||
if (dataTypeDefinitionDataValue.statusCode !== StatusCodes.Good) { | ||
console.log(dataTypeDefinitionDataValue.toString()); | ||
throw new Error(" Cannot find dataType Definition!"); | ||
@@ -836,3 +900,4 @@ } | ||
const definition = dataTypeDefinitionDataValue.value.value; | ||
schema = await _convertDataTypeDefinitionToStructureTypeSchema(session, fieldTypeName, definition, dataTypeFactory, cache); | ||
// schema = await _convertDataTypeDefinitionToStructureTypeSchema(session, fieldTypeName, definition, dataTypeFactory, cache); | ||
schema = dataTypeFactory.getStructuredTypeSchema(fieldTypeName); | ||
break; | ||
@@ -842,2 +907,3 @@ } | ||
assert(schema, "expecting a schema here"); | ||
const v2: Cache = { | ||
@@ -852,8 +918,24 @@ category, | ||
async function _setupEncodings( | ||
session: IBasicSession, | ||
dataTypeNodeId: NodeId, | ||
schema: StructuredTypeSchema | ||
): Promise<StructuredTypeSchema> { | ||
schema.dataTypeNodeId = dataTypeNodeId; | ||
schema.id = dataTypeNodeId; | ||
const encodings = await _findEncodings(session, dataTypeNodeId); | ||
schema.encodingDefaultBinary = makeExpandedNodeId(encodings.binaryEncodingNodeId); | ||
schema.encodingDefaultXml = makeExpandedNodeId(encodings.xmlEncodingNodeId); | ||
schema.encodingDefaultJson = makeExpandedNodeId(encodings.jsonEncodingNodeId); | ||
return schema; | ||
} | ||
async function _convertDataTypeDefinitionToStructureTypeSchema( | ||
session: IBasicSession, | ||
dataTypeNodeId: NodeId, | ||
name: string, | ||
definition: DataTypeDefinition, | ||
dataTypeFactory: DataTypeFactory, | ||
cache: any | ||
cache: { [key: string]: Cache } | ||
): Promise<StructuredTypeSchema> { | ||
@@ -876,2 +958,3 @@ | ||
name: fieldD.name!, | ||
schema, | ||
}; | ||
@@ -882,3 +965,2 @@ | ||
} | ||
field.schema = schema; | ||
field.category = category; | ||
@@ -891,3 +973,3 @@ fields.push(field); | ||
const os: StructuredTypeOptions = { | ||
const os = new StructuredTypeSchema({ | ||
baseType, | ||
@@ -898,9 +980,8 @@ fields, | ||
// xx fields: definition.fields! | ||
}; | ||
return new StructuredTypeSchema(os); | ||
} else if (definition instanceof EnumDefinition) { | ||
// | ||
console.log("xxxx Ignoring enumeration !!!!"); | ||
}); | ||
console.log(os); | ||
return await _setupEncodings(session, dataTypeNodeId, os); | ||
} | ||
throw new Error("Not Implemented"); | ||
} |
/** | ||
* @module node-opcua-client-dynamic-extension-object | ||
*/ | ||
import * as util from "util"; | ||
import assert from "node-opcua-assert"; | ||
@@ -9,2 +11,3 @@ import { | ||
getStandartDataTypeFactory, | ||
StructuredTypeSchema, | ||
} from "node-opcua-factory"; | ||
@@ -23,3 +26,2 @@ import { | ||
private readonly dataTypeFactoryMap: { [key: string]: DataTypeFactory } = {}; | ||
private readonly dataTypeFactoryMapByNamespace: { [key: number]: DataTypeFactory } = {}; | ||
@@ -76,6 +78,22 @@ | ||
if (!Constructor) { | ||
throw new Error("getExtensionObjectConstructorFromBinaryEncoding cannot find constructor for " + binaryEncodingNodeId.toString()); | ||
throw new Error("getExtensionObjectConstructorFromBinaryEncoding cannot find constructor for binaryEncoding " + binaryEncodingNodeId.toString()); | ||
} | ||
return Constructor; | ||
} | ||
public toString(): string { | ||
const l: string[] = []; | ||
function write(...args: [any, ...any[]]) { | ||
l.push(util.format.apply(util.format, args)); | ||
} | ||
write("ExtraDataTypeMananager"); | ||
for (let n = 0; n < this.namespaceArray.length; n++) { | ||
write("-----------", this.namespaceArray[n]); | ||
const dataFactory = this.dataTypeFactoryMapByNamespace[n]; | ||
if (!dataFactory) { | ||
continue; | ||
} | ||
write(dataFactory.toString()); | ||
} | ||
return l.join("\n"); | ||
} | ||
} |
@@ -0,0 +0,0 @@ /** |
@@ -0,0 +0,0 @@ import { DataValue } from "node-opcua-data-value"; |
@@ -9,7 +9,7 @@ import { BinaryStream } from "node-opcua-binary-stream"; | ||
opaque: OpaqueStructure, | ||
extraDataType: ExtraDataTypeManager | ||
dataTypeManager: ExtraDataTypeManager | ||
): ExtensionObject { | ||
try { | ||
const Constructor = extraDataType.getExtensionObjectConstructorFromBinaryEncoding(opaque.nodeId); | ||
const Constructor = dataTypeManager.getExtensionObjectConstructorFromBinaryEncoding(opaque.nodeId); | ||
const object = new Constructor(); | ||
@@ -28,3 +28,3 @@ const stream = new BinaryStream(opaque.buffer); | ||
variant: Variant, | ||
extraDataType: ExtraDataTypeManager | ||
dataTypeManager: ExtraDataTypeManager | ||
): Promise<void> { | ||
@@ -43,3 +43,3 @@ | ||
} | ||
const obj = resolveDynamicExtensionObjectV(v as OpaqueStructure, extraDataType); | ||
const obj = resolveDynamicExtensionObjectV(v as OpaqueStructure, dataTypeManager); | ||
return obj; | ||
@@ -55,4 +55,4 @@ }); | ||
variant.value = resolveDynamicExtensionObjectV( | ||
variant.value as OpaqueStructure, extraDataType); | ||
variant.value as OpaqueStructure, dataTypeManager); | ||
} |
@@ -0,0 +0,0 @@ { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
339386
27
2044