Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Method call with a single float type input argument results in exception in node-opcua server #857

Closed
Graos opened this issue Sep 3, 2020 · 22 comments
Labels

Comments

@Graos
Copy link

Graos commented Sep 3, 2020

Current behavior

Describe the bug
Method call with a single float type input argument results in exception in node-opcua server

To Reproduce
Steps to reproduce the behavior:

  1. Start the server and activate a method call with single floating point input argument.
  2. ......
    3.......

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots

Exception dump

EXCEPTION CAUGHT WHILE PROCESSING REQUEST !! CallRequest
{ /*CallRequest*/
 requestHeader                 /* RequestHeader       */: {
   authenticationToken         /* NodeId              */: ns=0;b=553ce27b08cb864c408a4f0bda4a7515
   timestamp                   /* DateTime            */: 2020-09-03T13:39:35.332Z
   requestHandle               /* UInt32              */: 1001763               0xf4923
   returnDiagnostics           /* UInt32              */: 0               0x0
   auditEntryId                /* UAString            */: null
   timeoutHint                 /* UInt32              */: 10000               0x2710
   additionalHeader            /* ExtensionObject     */: null
 }
 methodsToCall                 /* CallMethodRequest[] */: [
   { /*0*/
     objectId                  /* NodeId              */: ns=8;i=5002
     methodId                  /* NodeId              */: ns=8;i=7002
     inputArguments            /* Variant          [] */: [ /* length =1*/
       Variant(Scalar<Float>, value: 30)
     ]
   }
 ]
};
 display_trace_from_this_project_only =
methodDeclaration.getInputArguments is not a function

 messages  EXCEPTION CAUGHT WHILE PROCESSING REQUEST !!! CallRequest
methodDeclaration.getInputArguments is not a function
TypeError: methodDeclaration.getInputArguments is not a function
    at callMethodHelper (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\node-opcua-address-space\dist\source\helpers\call_helpers.js:28:52)
    at C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\async\dist\async.js:243:13
    at eachOfArrayLike (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\async\dist\async.js:500:13)
    at eachOf (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\async\dist\async.js:551:16)
    at awaitable (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\async\dist\async.js:208:32)
    at _asyncMap (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\async\dist\async.js:241:16)
    at Object.map (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\async\dist\async.js:594:16)
    at Object.awaitable [as map] (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\async\dist\async.js:208:32)
    at C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\node-opcua-server\dist\opcua_server.js:2070:23
    at OPCUAServer._apply_on_SessionObject (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\node-opcua-server\dist\opcua_server.js:1421:13)

Gist
gist:

  • ( ) my request is related to node-opcua acting as a OPCUA SERVER

  • ( ) I have installed node-opcua as a package ( using npm install )

  • Device: _____

  • OS version: _____

    • ( ) Windows : version : 10__
    • ( ) Linux : version : _________
    • ( ) MacOs : version : _________
    • ( ) Raspbian: version : _________
    • ( ) Other : specify :
  • Description of the other OPCUA system I am trying to connect to:

    • Name:UAExpert___
    • Version:_________
    • Manufacturer/Software vendor:_________
    • link : https://
  • node-opcua version: :

  • Node:
    node --version = 2.13.0
@Graos
Copy link
Author

Graos commented Sep 3, 2020

Method call from client captured in wireshark

image

@erossignon
Copy link
Member

erossignon commented Sep 4, 2020

Start the server and activate a method call with single floating point input argument.

Can you elaborate ?

Please show how you have implemented this method in the server. Please provide a gist of a minimum server that reproduce the issue.

@erossignon erossignon added the need more info The issue cannot be resolved as described and need deeper investigation label Sep 4, 2020
@Graos
Copy link
Author

Graos commented Sep 4, 2020

I get this issue even when i don't implement any methods in the top level server application. This is coming directly from the node-opcua

@erossignon
Copy link
Member

erossignon commented Sep 4, 2020

Which server do you start ?
What is namespace 8 ? 11 ?

@Graos
Copy link
Author

Graos commented Sep 4, 2020

Following are the namespaces loaded in the server. Have attached also the nodeset file to load into the server. For instance SetMachSpeed method from namespace 8 causes the above exception. Any method execution from the namespace index 8 leads to the above exception.

Namespace[0] = http://opcfoundation.org/UA/
Namespace[1] = urn:NodeOPCUA-Server-default
Namespace[2] = http://opcfoundation.org/UA/DI/
Namespace[3] = http://fdi-cooperation.com/OPCUA/FDI5/
Namespace[4] = http://fdi-cooperation.com/OPCUA/FDI7/
Namespace[5] = http://opcfoundation.org/UA/ADI/
Namespace[6] = http://opcfoundation.org/UA/PackML
Namespace[7] = http://opcfoundation.org/UA/schemas/FDT/1.0/
Namespace[8] = http://abbminden.org/uacompanionmodelabbtest/
UaCompanionModel.zip

image

@Graos
Copy link
Author

Graos commented Sep 4, 2020

Hint : getMethodDeclaration_ArgumentList(addressSpace, objectId, methodId) in callhelpers.js returns a wrong response even though the parameters passed are the correct ones. Seems like the method declaration NodeID is not properly adjusted when the namespace index is changed inside the server.

@erossignon
Copy link
Member

erossignon commented Sep 6, 2020

On my side the namespace to use is 7... and it works well;

here is the gist for the sample server I am using

const { OPCUAServer, nodesets } = require("node-opcua");


(async () => {

    const server = new OPCUAServer({
        nodeset_filename: [
            nodesets.standard,
            "./UACompanionModel.xml"
        ]
    });

    await server.initialize();

    await server.start();
    const endpointUrl = server.endpoints[0].endpointDescriptions()[0].endpointUrl;
    console.log(endpointUrl);

})();

image
image
you should not assume that the nodeId namespace in the final addressSpace in your server will match the namespace of the xml files.
image
image

And the client code:

const { OPCUAClient, Variant, DataType } = require("node-opcua");

const endpointUri = "opc.tcp://STERFIVEPC2:26543";
(async () => {

    const client = OPCUAClient.create({
        endpoint_must_exist: false
    });
    client.on("backoff", () => console.log("Backoff"));
    await client.connect(endpointUri);


    const session = await client.createSession();

    const result = await session.call({
        objectId: "ns=7;i=5002",
        methodId: "ns=7;i=7002",
        inputArguments: [
            new Variant({ dataType: DataType.Float, value: 10 })
        ]
    });
    console.log(result.toString());
    await session.close();
    await client.disconnect();
})();

The client code can be improved this way, if you don't want to assume how namespace index will be setup .

const { OPCUAClient, Variant, DataType } = require("node-opcua");

const endpointUri = "opc.tcp://STERFIVEPC2:26543";
(async () => {

    const client = OPCUAClient.create({
        endpoint_must_exist: false
    });
    client.on("backoff", () => console.log("Backoff"));
    await client.connect(endpointUri);


    const session = await client.createSession();

    await session.readNamespaceArray();
    const nsABB = session.getNamespaceIndex("http://abbminden.org/uacompanionmodelabbtest/");

    const result = await session.call({
        objectId: `ns=${nsABB};i=5002`,
        methodId: `ns=${nsABB};i=7002`,
        inputArguments: [
            new Variant({ dataType: DataType.Float, value: 10 })
        ]
    });
    console.log(result.toString());
    await session.close();
    await client.disconnect();
})();

running the sample on unbound methods

Server output will be :

Method ns=7;i=7002 5:SetMachSpeed_ has not been bound

because the method is not bound in your server implementation with a SetMachSpeed_ implementation function that performed the expected action.

In UAExpert , if you call the method you will see:
image

With the client script above you should see:
image

This is working as expected.

Please provide more detailed info on how you have implemented the server on your side. Providing a small sample code will help finding the difference with what I have shown here.

@Graos
Copy link
Author

Graos commented Sep 6, 2020

The only difference i see from your example to my server code is the nodesets that have been loaded into the server. I had to load the Opc.Ua.Di.NodeSet2.xml also that's why for me the namespace abbtest has moved to 8. I have never assumed the namespace in server to be same as the nodeset file. I always get the namespace from the server after the nodeset is initialised for all the operation. with the below code without any method being binded i always get the problem as stated before for SetMachSpeed.

Server code:

 NODESET_FILENAMES_DI_BASED : [
".\\node_modules\\node-opcua-nodesets\\nodesets\\Opc.Ua.NodeSet2.xml",
".\\node_modules\\node-opcua-nodesets\\nodesets\\Opc.Ua.Di.NodeSet2.xml",
"UaCompanionModel.xml"
],
function createAndInitialiseOpcUaServer() {
    // Let create an instance of OPCUAServer
    server = new opcua.OPCUAServer({
        port: CONFIGURATION_SWITCH.SERVER_LISTENING_PORT,        // the port of the listening socket of the server
        nodeset_filename: CONFIGURATION_SWITCH.NODESET_FILENAMES_GENERIC,
        userCertificateManager: {
            allowAnonymous: true,
            automaticallyAcceptUnknownCertificate: true
        },
        buildInfo: {
            productName: PRODUCT_NAME,
            softwareVersion: SOFTWARE_VERSION,
            buildNumber: BUILD_NUMBER,
            buildDate: new Date()
        }
    });
    server.serverCertificateManager.automaticallyAcceptUnknownCertificate = true;
    // the server needs to be initialized first. During initialisation,
    // the server will construct its default namespace.
    server.initialize(appInit);
}

When i changed the Nodeset load to only standard nodeset and the companionmodel nodeset see below i get the following error

    NODESET_FILENAMES_GENERIC : [
".\\node_modules\\node-opcua-nodesets\\nodesets\\Opc.Ua.NodeSet2.xml",
 "UaCompanionModel.xml"
],

Node-OpcUa stack version :  ^2.13.0
OPC UA Server is initialized.Starting App initialisation
Namespace[0] = http://opcfoundation.org/UA/
Namespace[1] = urn:NodeOPCUA-Server-default
Namespace[2] = http://fdi-cooperation.com/OPCUA/FDI5/
Namespace[3] = http://fdi-cooperation.com/OPCUA/FDI7/
Namespace[4] = http://opcfoundation.org/UA/ADI/
Namespace[5] = http://opcfoundation.org/UA/PackML
Namespace[6] = http://opcfoundation.org/UA/schemas/FDT/1.0/
Namespace[7] = http://abbminden.org/uacompanionmodelabbtest/
Namespace[8] = http://opcfoundation.org/UA/DI/
C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\node-opcua-address-space\dist\src\ua_variable.js:879
            throw new Error("cannot find dataType " + this.dataType.toString());
            ^

Error: cannot find dataType ns=8;i=6244
    at UAVariable.getDataTypeNode (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\node-opcua-address-space\dist\src\ua_variable.js:879:19)
    at UAVariable.get dataTypeObj [as dataTypeObj] (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\node-opcua-address-space\dist\src\ua_variable.js:884:21)
    at C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\OpcUaServer.js:238:279
    at Array.forEach (<anonymous>)
    at installValueChangeTrigger (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\OpcUaServer.js:231:19)
    at appInit (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\OpcUaServer.js:451:5)
    at Immediate.<anonymous> (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\node-opcua-server\dist\opcua_server.js:593:25)
    at processImmediate (internal/timers.js:456:21)

@erossignon
Copy link
Member

erossignon commented Sep 6, 2020

We seem to be diverging from the original issue:
````methodDeclaration.getInputArguments is not a function```
Let's try to focus on this one.

nodeset

  • the UaCompanionModel.xml seems to aggregate many standard namespaces. I would suggest you generate a nodeset.xml file that only contains the definition of the nodes from http://abbminden.org/uacompanionmodelabbtest/ , and in this case import each other necessary standard namespace individually in the nodeset_filename array (fdi/di/adi etc...).

investigating Error: cannot find dataType ns=8;i=6244

  • Looking into the node set file, ns=8;i=6244 is from the DI namespace so it is namespace 6 in the xm file, right ?

  • it appears that this matches

  <UAVariable DataType="DeviceHealthEnumeration" ParentNodeId="ns=6;i=5075" NodeId="ns=6;i=6244" BrowseName="3:DiagnosticStatus">
        <DisplayName>DiagnosticStatus</DisplayName>
        <Description>General health status of the analyser</Description>
        <References>
            <Reference ReferenceType="HasTypeDefinition">i=2365</Reference>
            <Reference ReferenceType="Organizes" IsForward="false">ns=6;i=5039</Reference>
            <Reference ReferenceType="HasComponent" IsForward="false">ns=6;i=5075</Reference>
        </References>
    </UAVariable>

So ns=8;i=6244 is a VariableType not a DataType and I guess that the error tell us exactly this.
I suspect there must be some mismatch in in the OpcUAServer.js file

   at installValueChangeTrigger (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\OpcUaServer.js:231:19)
    at appInit (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\OpcUaServer.js:451:5)

Can you provide this code ?
(May be a private code review is required, please contact me directly in this case for this support issue)

@erossignon erossignon added the please subscribe to support.sterfive.com for help ( go https://support.sterfive.com for professional support if no answer from community) label Sep 6, 2020
@Graos
Copy link
Author

Graos commented Sep 6, 2020

http://abbminden.org/uacompanionmodelabbtest/ is the namespace which contains object instances whose types are from different companion model namespaces. I think this is intended and the nodeset file generated is complete. Now the question is if I load standard noset and DI nodeset along with companion model nodeset i get the issue ````methodDeclaration.getInputArguments is not a function```. Is it intentional? However if I dont load the DI nodeset then i don't see this issue at least. Can you please throw light on this?

@erossignon
Copy link
Member

  • If you load the DI namespace and you complete companion.xml file you will end-up with unpredicable results as nodes will be duplicated. I suspect that node-opcua will fail and raise an exception. you cannot load the same model twice. Hence the behavior you are describing. On my side, I have a error raised by the await server.initialze(); method if I attempt to load the standard name space + di + you full namespace . This is expected.

  • the common practice is to create a xml nodeset file per namespace.

  • Obviously, each namespace will refer to other external standard namespaces. DI / ADI /FTI/PackML/ Vision are standard namespace that are not intended to be duplicated or merged inside your own companion namespace.

  • I would recommend that you seperate your ObjectType/VariableType and DataType into a namespace and your instances on an other.

a typical example looks like

    const server = new OPCUAServer({
        nodeset_filename: [
            nodesets.standard,
            nodesets.di,
            nodesets.adi,
           nodesets.fti,
           nodesets.machineVision,
            nodesets.robotics,
            "./MyOwnObjetTypeThatMayReferToDiandADIModel.xml",
            "./MyOwnObjectInstances.xml", 
        ]
    });

Note:

  • the nodesets gives you access to the standard node sets from DI, ADI, PackM,AutoID, Vision, etc... in a convenient way.
  • nodesets.standard resovles to the full path name of the standard UA namespace ( inside the node-opcua-nodesets module)
  • if the standard nodeset you are looking for is not expsed by nodesets then you can simple point to the corresponding file instead.
    * Instances can also be generated on the fly at server startup, there are convenient tools that allows you to instantiate complex ObjectType/VariableType. I rarely use external namespace to create object instances, but rather use a programatic way to generate them on fly; Both approaches are of course valid. its up to you, I find direct programmatic instantiation more convenient as you do not have to use a external modeler.

I hope this will help.

@Graos
Copy link
Author

Graos commented Sep 6, 2020

Thanks. That was indeed clear. Now coming to the other problem Error: cannot find dataType ns=8;i=6244
What i was doing is collect all the variables from the address space and based on its data type change its value at a certain time interval. I access the following properties of the UAVariable instance (basenode.dataTypeObj.basicDataType) to know its basic data type. The Exception is raised when trying to access the UAVariable "DeviceHealth"(NodeId: ns=7("http://abbminden.org/uacompanionmodelabbtest/");i=6293) of type (ns=8(http://opcfoundation.org/UA/DI/);i=6244=> DeviceHealthInformation)which belongs to the parent object "ADI_AcousticSpectrometerDevice1". Why for this variable whose type is a subtype of enumeration have this issue ? I somehow feel that Enumeration subtypes nodes are not properly handled. I have not found a way to get the basic data type(i=29 Enumeration) for the type subtypes from Enumeration basedatatype. Let me know if you need any more information.

@erossignon erossignon added bug and removed need more info The issue cannot be resolved as described and need deeper investigation please subscribe to support.sterfive.com for help ( go https://support.sterfive.com for professional support if no answer from community) labels Sep 6, 2020
@erossignon
Copy link
Member

I was able to reprduce the behavior you described with this server

const { OPCUAServer, nodesets } = require("node-opcua");


(async () => {

    const server = new OPCUAServer({
        nodeset_filename: [
            nodesets.standard,
            nodesets.di,
            "./UACompanionModel.xml"
        ]
    });

    await server.initialize();

    await server.start();
    const endpointUrl = server.endpoints[0].endpointDescriptions()[0].endpointUrl;
    console.log(endpointUrl);

})();

a translation of namespace was missing on the XML MethodDefinitionId attributes

@Graos
Copy link
Author

Graos commented Sep 7, 2020

will this change solve Error: cannot find dataType ns=8;i=6244 issue as well? Please see my comment above

@erossignon
Copy link
Member

Yes sure.

@erossignon
Copy link
Member

it should be now fixed in node-opcua@2.14.0. please confirm

@erossignon erossignon reopened this Sep 7, 2020
@Graos
Copy link
Author

Graos commented Sep 7, 2020

I still get the Error: cannot find dataType ns=8;i=6244 issue
Node-OpcUa stack version : ^2.14.0
OPC UA Server is initialized.Starting App initialisation
Namespace[0] = http://opcfoundation.org/UA/
Namespace[1] = urn:NodeOPCUA-Server-default
Namespace[2] = http://fdi-cooperation.com/OPCUA/FDI5/
Namespace[3] = http://fdi-cooperation.com/OPCUA/FDI7/
Namespace[4] = http://opcfoundation.org/UA/ADI/
Namespace[5] = http://opcfoundation.org/UA/PackML
Namespace[6] = http://opcfoundation.org/UA/schemas/FDT/1.0/
Namespace[7] = http://abbminden.org/uacompanionmodelabbtest/
Namespace[8] = http://opcfoundation.org/UA/DI/
C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\node-opcua-address-space\dist\src\ua_variable.js:879
throw new Error("cannot find dataType " + this.dataType.toString());
^

Error: cannot find dataType ns=8;i=6244
at UAVariable.getDataTypeNode (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\node-opcua-address-space\dist\src\ua_variable.js:879:19)
at UAVariable.get dataTypeObj [as dataTypeObj] (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\node-opcua-address-space\dist\src\ua_variable.js:884:21)
at C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\OpcUaServer.js:240:46
at Array.forEach ()
at installValueChangeTrigger (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\OpcUaServer.js:232:19)
at appInit (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\OpcUaServer.js:464:5)
at Immediate. (C:\Users\degarao\Desktop\JSBooks\Project\JavascriptApplication\node_modules\node-opcua-server\dist\opcua_server.js:604:21)
at processImmediate (internal/timers.js:456:21)

@Graos
Copy link
Author

Graos commented Sep 7, 2020

getMethodDeclaration_ArgumentList(addressSpace, objectId, methodId) is resolved in 2.14.0 But for this I need to load the di nodeset as well along with companion model xml file.

@erossignon
Copy link
Member

Yes, this is expected as the UaCompanionModel.xml contains many namespaces but not the DI, for this reason the DI must be explicitly loaded ( see my previous gist)

@erossignon
Copy link
Member

@Graos Please confirmat that adding the di model helped you to get the expected behavior

@Graos
Copy link
Author

Graos commented Sep 16, 2020

I can confirm that when i used di model in the namespace the above described issue is not seen.

@erossignon
Copy link
Member

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants