node-opcua-pseudo-session
Version:
pure nodejs OPCUA SDK - module pseudo-session
94 lines (90 loc) • 3.67 kB
text/typescript
import { NodeId, NodeIdLike } from "node-opcua-nodeid";
import { BrowsePath, makeBrowsePath } from "node-opcua-service-translate-browse-path";
import { BrowseDirection, QualifiedNameLike, coerceQualifiedName } from "node-opcua-data-model";
import { IBasicSessionAsync } from "./basic_session_interface";
export async function findInTypeOrSuperType(
session: IBasicSessionAsync,
browsePath: BrowsePath
): Promise<{ nodeId: NodeId } | { nodeId: null; err: Error }> {
const nodeId = browsePath.startingNode;
const result = await session.translateBrowsePath(browsePath);
if (result.statusCode.isGood()) {
return { nodeId: result.targets![0].targetId as NodeId };
}
// cannot be found here, go one step up
const br = await session.browse({
nodeId,
referenceTypeId: "HasSubtype",
browseDirection: BrowseDirection.Inverse,
includeSubtypes: true,
nodeClassMask: 0,
resultMask: 0
});
if (br.statusCode.isNotGood()) {
// cannot find typeDefinition
return { nodeId: null, err: new Error("cannot find typeDefinition") };
}
const typeDefinition = br.references![0].nodeId;
browsePath = new BrowsePath({
startingNode: typeDefinition,
relativePath: browsePath.relativePath
});
return await findInTypeOrSuperType(session, browsePath);
}
/**
*
* find a MethodId in a object or in its super type
*
* note:
* - methodName is a browse name and may therefore be prefixed with a namespace index.
* - if method is not found on the object specified by nodeId, then the findMethodId will
* recursively browse up the hierarchy of object typeDefinition Node
* until it reaches the root type. and try to find the first method that matches the
* provided name.
*
* @param session
* @param nodeId the nodeId of the object to find
* @param methodName the method name to find prefixed with a namespace index (unless ns=0)
* ( e.g "Add" or "Add" or "1:BumpCounter" )
*/
export async function findMethodId(
session: IBasicSessionAsync,
nodeId: NodeIdLike,
methodName: QualifiedNameLike
): Promise<{ methodId: NodeId } | { methodId: null; err: Error }> {
const browsePath = makeBrowsePath(nodeId, "/" + coerceQualifiedName(methodName).toString());
const result = await session.translateBrowsePath(browsePath);
if (result.statusCode.isNotGood()) {
const br = await session.browse({
nodeId,
referenceTypeId: "HasTypeDefinition",
browseDirection: BrowseDirection.Forward,
includeSubtypes: true,
nodeClassMask: 0,
resultMask: 0
});
if (br.statusCode.isNotGood()) {
// cannot find typeDefinition
return { methodId: null, err: new Error("cannot find typeDefinition") };
}
const typeDefinition = br.references![0].nodeId;
// need to find method on objectType
const browsePath = makeBrowsePath(typeDefinition, "/" + methodName);
const result = await findInTypeOrSuperType(session, browsePath);
if (!result.nodeId) {
return { err: result.err, methodId: null };
}
return { methodId: result.nodeId };
}
result.targets = result.targets || [];
if (result.targets.length > 0) {
const methodId = result.targets[0].targetId as NodeId;
return { methodId };
}
/* c8 ignore next */
else {
// cannot find objectWithMethodNodeId
const err = new Error(" cannot find " + methodName + " Method");
return { methodId: null, err };
}
}