Skip to content

Commit

Permalink
add extract filed in pseudo session
Browse files Browse the repository at this point in the history
  • Loading branch information
erossignon committed Jul 15, 2023
1 parent 53c90b3 commit 8318259
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -133,20 +133,20 @@ export async function findActiveConditions(session: ClientSession): Promise<Even

await promise;

// now shut down susbscription
// now shut down subscription
await subscription.terminate();

return acknowledgeableConditions;
}

export async function acknwoledgeAllConditions(session: ClientSession, message: string): Promise<void> {
export async function acknowledgeAllConditions(session: ClientSession, message: string): Promise<void> {
try {
let conditions = await findActiveConditions(session);
if (conditions.length === 0) {
debugLog("Warning: cannot find conditions ");
}

// filter acknowledgable conditions (no acked yet)
// filter acknowledgeable conditions (no acked yet)
conditions = conditions.filter((pojo) => pojo.ackedState.id.value === false);

const promises: Array<Promise<StatusCode>> = [];
Expand Down
161 changes: 161 additions & 0 deletions packages/node-opcua-pseudo-session/source/extract_fields.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import { AttributeIds, BrowseDirection, NodeClassMask, QualifiedName, stringToQualifiedName } from "node-opcua-data-model";
import { NodeId, NodeIdLike, resolveNodeId } from "node-opcua-nodeid";
import { BrowseDescriptionOptions } from "node-opcua-service-browse";
import { NodeClass } from "node-opcua-types";

import { IBasicSession } from "./basic_session_interface";

const doDebug = false;

/**
*
* recursively work down an node definition and find
* the components and property ...
* also navigate the sub
* @param session the session
* @param nodeId the object to investigate , could be the nodeId of a Object/Variable/ObjectType or VariableType.
* @returns a array of {path: QualifiedName[], nodeId: NodeId}}
*
* @private
*/
export async function extractFields(
session: IBasicSession,
nodeId: NodeIdLike
): Promise<{ path: QualifiedName[]; nodeId: NodeId }[]> {
const _duplicateMap: any = {};

const fields1: { path: QualifiedName[]; nodeId: NodeId }[] = [];

function addField(parent: QualifiedName[], browseName: QualifiedName, nodeId: NodeId) {
const e = [...parent, browseName];
const key = simpleBrowsePathToString(e);

// istanbul ignore next
doDebug && console.log("adding field ", key);

if (!_duplicateMap[key]) {
fields1.push({ path: e, nodeId });
_duplicateMap[key] = e;
}
}

interface S {
browseName: QualifiedName;
nodeToBrowse: BrowseDescriptionOptions;
}
interface IStackElement {
parent: QualifiedName[];
nodeId: NodeId;
}
const stack: IStackElement[] = [];
function _pushInvestigation(parent: QualifiedName[], objectId: NodeId) {
stack.push({
parent,
nodeId: objectId
});
}
async function _flushPendingInvestigations() {
if (stack.length === 0) {
return;
}
const extracted = stack.splice(0);
const nodesToBrowse = extracted.map((e: IStackElement) => {
const { parent, nodeId } = e;
const b: BrowseDescriptionOptions = {
browseDirection: BrowseDirection.Forward,
includeSubtypes: true,
nodeClassMask: NodeClassMask.Object | NodeClassMask.Variable,
nodeId,
referenceTypeId: "HasChild",
resultMask: 63
};
return b;
});
const results = await session.browse(nodesToBrowse);

for (let index = 0; index < results.length; index++) {
const result = results[index];
const parent = extracted[index].parent;
if (!result.references || result.references.length === 0) continue;

// istanbul ignore next
doDebug &&
console.log(
"exploring",
simpleBrowsePathToString(parent),
result.references.map((a) => a.browseName.toString())
);

for (const ref of result.references) {
if (ref.nodeClass === NodeClass.Variable) {
addField(parent, ref.browseName, ref.nodeId);
}
_pushInvestigation([...parent, ref.browseName], ref.nodeId);
}
}
await _flushPendingInvestigations();
}

async function _investigateTopLevel(parent: QualifiedName[], eventNodeId: NodeIdLike) {
const browseDescriptionForInverseSubType: BrowseDescriptionOptions = {
browseDirection: BrowseDirection.Inverse,
includeSubtypes: true,
nodeClassMask: NodeClassMask.ObjectType,
nodeId: eventNodeId,
referenceTypeId: resolveNodeId("HasSubtype"),
resultMask: 63
};
const nodeToBrowse2: BrowseDescriptionOptions = {
browseDirection: BrowseDirection.Forward,
includeSubtypes: true,
nodeClassMask: NodeClassMask.Object | NodeClassMask.Variable,
nodeId: eventNodeId,
referenceTypeId: resolveNodeId("HasChild"),
resultMask: 63
};
const nodesToBrowse = [browseDescriptionForInverseSubType, nodeToBrowse2];
const browseResults = await session.browse(nodesToBrowse);
const [browseResultForInverseSubType, browseResultForChildren] = browseResults;

if (browseResultForChildren && browseResultForChildren.references) {
for (const ref of browseResultForChildren.references) {
if (ref.nodeClass === NodeClass.Variable) {
addField(parent, ref.browseName, ref.nodeId);
}
_pushInvestigation([...parent, ref.browseName], ref.nodeId);
}
}
await _flushPendingInvestigations();

if (browseResultForInverseSubType && browseResultForInverseSubType.references) {
const promises = [];
for (const reference of browseResultForInverseSubType.references) {
// istanbul ignore next
doDebug && console.log(" investigating super-type", reference.browseName.toString());
promises.push(_investigateTopLevel([], reference.nodeId));
}
await Promise.all(promises);
}
}

// istanbul ignore next
doDebug &&
console.log(
"investigating ",
nodeId.toString(),
(await session.read({ nodeId: nodeId, attributeId: AttributeIds.BrowseName })).value.value.toString()
);
await _investigateTopLevel([], nodeId);
return fields1;
}


export function simpleBrowsePathToString(bp: QualifiedName[]): string {
return bp.map((qn) => qn.toString()).join(".");
}
export function simpleBrowsePathsToString(simpleBrowsePathArray: QualifiedName[][]): string[] {
return simpleBrowsePathArray.map(simpleBrowsePathToString);
}
export function stringPathToSimpleBrowsePath(bp: string): QualifiedName[] {
return bp.split(".").map((s) => stringToQualifiedName(s));
}
11 changes: 6 additions & 5 deletions packages/node-opcua-pseudo-session/source/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
/**
* @module node-opcua-pseudo-session
*/
export * from "./basic_session_interface";
export * from "./basic_session_ex";
export * from "./basic_session_interface";
export * from "./basic_session_with_subscription";
export * from "./browse_all";
export * from "./read_operational_limits";
export * from "./create_monitored_items_limit";
export * from "./basic_session_with_subscription";
export * from "./extract_fields";
export * from "./find_basic_datatype";
export * from "./get_builtin_datatype";
export * from "./find_structure_datatype";
export * from "./get_child_by_browse_name";
export * from "./get_builtin_datatype";
export * from "./get_child_by_browse_name";
export * from "./read_operational_limits";

0 comments on commit 8318259

Please sign in to comment.