Hi, calling a OPCUA method with two InputArguments (ua:String, ua:Int32) does not work. I get a ClassCastException.
result = system.opcua.callMethod("RobotArm", "ns=4;i=532", "ns=4;i=650", ["myArticleId", 100])
java.lang.ClassCastException: java.lang.ClassCastException: class org.eclipse.milo.opcua.sdk.client.nodes.UaVariableNode cannot be cast to class
When calling a method without any InputArguments it works fine:
result = system.opcua.callMethod("RobotArm", "ns=4;i=532", "ns=4;i=653", )
I also turned on the system.opcua.callMethod DEBUG logger. No helpful hints.
Trying to json encode the arguments didn't help either.
The gateway runs on a M1 Mac.
Thanks a lot for help! Toni
Hmm, this hints at a perhaps a data modelling problem in the underlying server...
Any chance you can make this OPC UA connection without security and get a Wireshark capture while you call this method? What server is this?
It would also be useful if you could provide the full error and stack trace from the logs.
I'm using the the opcua-asyncio (GitHub - FreeOpcUa/opcua-asyncio: OPC UA library for python >= 3.7) server. I can invoke the method with the two input arguments with the Prosys OPC UA Browser successfully.
So far I connect to the server without security. So network tracing should be possible.
Oh... I don't expect this to work then. Both of those Python OPC UA implementations are broken and they don't seem to care or respond to my bug reports.
1 Like
At some point I will rewrite the logic in system.opcua.callMethod
that triggers this bug in the Python servers, but it's not a priority right now with all the other work we have going on. It's not a super trivial change.
I see. Well, I guess I have to switch to another OPC UA SDK. Thanks anyway.
My last post in the thread I linked to has some suggestions.
The implementation of system.opcua.callMethod
was refactored in Ignition 8.1.43 to work around this bug in FreeOpcUa-based servers.
Hi Kevin,
I wonder what I'm doing wrong.
I've copied the example form the manual for the copua.callMethod and I get the following response:
|cwdLogger|20Mar2025 20:59:10|MOBZ.DAL.Msbs.mcSample() output values from the callt: [].|
|cwdLogger|20Mar2025 20:59:10|MOBZ.DAL.Msbs.mcSample() list of StatusCodes, one for each input argument: [].|
|cwdLogger|20Mar2025 20:59:10|MOBZ.DAL.Msbs.mcSample() StatusCode for the call: (2150105088L, u'Bad_SubscriptionIdInvalid', u'The subscription id is not valid.').|
The code is below, executed on the gateway using a tag-change script:
def mcSample():
cwdLogging.wrapLog(cwdLogging.logNaam, ("MOBZ.DAL.Msbs.mcSample()" %()), 2)
# Call the Server object's GetMonitoredItems method.
result = system.opcua.callMethod(
"Ignition OPC UA Server",
"ns=0;i=2253",
"ns=0;i=11492",
[1]
)
# Below we print the various elements in the results. The print statements could easily be replaced by something more useful.
# Prints the StatusCode for the call.
cwdLogging.wrapLog(cwdLogging.logNaam, ("MOBZ.DAL.Msbs.mcSample() StatusCode for the call: %s." %( str(result[0])) ), 2)
# Prints the list of StatusCodes, one for each input argument passed to system.opcua.callMethod.
cwdLogging.wrapLog(cwdLogging.logNaam, ("MOBZ.DAL.Msbs.mcSample() list of StatusCodes, one for each input argument: %s." %( result[1]) ), 2)
# Prints the output values from the call.
cwdLogging.wrapLog(cwdLogging.logNaam, ("MOBZ.DAL.Msbs.mcSample() output values from the callt: %s." %( result[2])), 2)
You're calling a standard method in the OPC UA server called GetMonitoredItems and passing a subscription id that doesn't exist, according to the results.
What are you expecting to happen? Are you just trying to get this working before you call a method on some other server?