locka99/opcua

gen_nodeset.js outputs ill formated NodeIDs when using "." as a separating character for Node definitions

Opened this issue · 0 comments

I am currently testing different OPC stacks with a customised NodeSet2.xml and found that the current version of the code generator strips any strings using "." as a separating character inside the Node definitions.

Currently NodeIDs are formatted like this: "device.subgroup.variable" (using NodeSet2.xml & an additional csv file).
I am using these strings for ID definition, since these wont change if a had to recompile a model using the UA-ModelCompiler and also to group Nodes together.

Currently, when using gen_nodeset.js the following code is generated:

fn add_object_13(address_space: &mut AddressSpace) {
    // Object
    let browse_name = "1:IndicatorX001";
    let display_name = "IndicatorX001";
    let node_id = NodeId::new(2, "indicator");
    let mut node = Object::new(&node_id, browse_name, display_name, EventNotifier::empty());
    node.set_description(LocalizedText::from("A generic Water Level Sensor for Testing"));
    let _ = address_space.insert(node, Some(&[
        (&NodeId::new(2, "indicator"), &ReferenceTypeId::HasComponent, ReferenceDirection::Forward),
        (&NodeId::new(2, "indicator"), &ReferenceTypeId::HasComponent, ReferenceDirection::Forward),
        (&NodeId::new(2, "indicator"), &ReferenceTypeId::HasComponent, ReferenceDirection::Forward),
        (&NodeId::new(2, "indicator"), &ReferenceTypeId::HasComponent, ReferenceDirection::Forward),
        (&NodeId::new(2, "indicator"), &ReferenceTypeId::HasComponent, ReferenceDirection::Forward),
        (&NodeId::new(0, 85), &ReferenceTypeId::Organizes, ReferenceDirection::Inverse),
        (&NodeId::new(2, 76), &ReferenceTypeId::HasTypeDefinition, ReferenceDirection::Forward),
    ]));
} 

All the referenced variables share the same ID "indicator" after generation, which causes the server to panic, since i created circular dependencies on all new nodes.

Instead the generated code should look like this:

fn add_object_13(address_space: &mut AddressSpace) {
    // Object
    let browse_name = "1:IndicatorX001";
    let display_name = "IndicatorX001";
    let node_id = NodeId::new(2, "indicator");
    let mut node = Object::new(&node_id, browse_name, display_name, EventNotifier::empty());
    node.set_description(LocalizedText::from("A generic Water Level Sensor for Testing"));
    let _ = address_space.insert(node, Some(&[
        (&NodeId::new(2, "indicator.device"), &ReferenceTypeId::HasComponent, ReferenceDirection::Forward),
        (&NodeId::new(2, "indicator.io"), &ReferenceTypeId::HasComponent, ReferenceDirection::Forward),
        (&NodeId::new(2, "indicator.meas"), &ReferenceTypeId::HasComponent, ReferenceDirection::Forward),
        (&NodeId::new(2, "indicator.diag"), &ReferenceTypeId::HasComponent, ReferenceDirection::Forward),
        (&NodeId::new(2, "indicator.alarm"), &ReferenceTypeId::HasComponent, ReferenceDirection::Forward),
        (&NodeId::new(0, 85), &ReferenceTypeId::Organizes, ReferenceDirection::Inverse),
        (&NodeId::new(2, 76), &ReferenceTypeId::HasTypeDefinition, ReferenceDirection::Forward),
    ]));
}

I found the current implementation for gen_nodeset.js parses the NodeSet2.xml correctly, but strips the IDs when generating the NodeIDs from the actual string inside utils.js, because of the used regex:

// Parses a string node id into an object with
exports.parse_node_id = function (node_id) {
    // let re = /(?:ns=([0-9]+);)?(i|b|s|g)=([a-zA-Z0-9\-]+)/;
    let re = /(?:ns=([0-9]+);)?(i|b|s|g)=([a-zA-Z0-9\-.]+)/;
    let m = node_id.toString().match(re);
    if (m) {
        return {
            ns: m[1] ? m[1] : 0,
            type: m[2],
            value: m[3],
        };
    } else {
        return null;
    }
}

Changing the regex (adding the "." at the end) seems to work, but im not sure if this is intended for the parser.
Open62541 and asyncio seem to work fine using these strings for NodeIDs.
Is there any specific reason this should fail the code generation or is it just missing a character inside the regex group?