How to control the return StatusCode from a UAMethod call on the server #1347
-
I am writing a simulation in which the client will call a method that has no OutputArguments. I know this "hijacking" of the status code is not a great idea. But I'm simulating a commercial server that implemented that logic (don't do it) and I have no choice. This would not be a problem in other languages and SDK's (like C and the open62541) where the method callbacks are designed to return a StatusCode. This Python API seems to be designed to return the Output arguments instead (which I kind of like because of Python ability to return multiple results). However, how can I control the result of a call on the server? Thanks for any help. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 5 replies
-
Raise the corresponding error for BadInvalidArgument do this:
|
Beta Was this translation helpful? Give feedback.
-
Thank you @schroeder- . Here's a short example (cut down version of the examples): import asyncio
import logging
from asyncua import ua, uamethod, Server
# method to be exposed through server
def func(parent, variant):
print("func method call with parameters: ", variant.Value)
ret = False
if variant.Value == 42:
raise ua.UaStatusCodeError(ua.StatusCodes.BadInvalidArgument)
if variant.Value % 2 == 0:
ret = True
return [ua.Variant(ret, ua.VariantType.Boolean)]
async def main():
logging.basicConfig(level=logging.WARN)
# now set up our server
server = Server()
await server.init()
# server.set_endpoint("opc.tcp://localhost:4840/freeopcua/server/")
server.set_endpoint("opc.tcp://0.0.0.0:48404/freeopcua/server/")
server.set_server_name("FreeOpcUa Example Server")
# set up our own namespace
uri = "http://examples.freeopcua.github.io"
idx = await server.register_namespace(uri)
# get Objects node, this is where we should put our custom stuff
objects = server.nodes.objects
# populating our address space
await objects.add_folder(idx, "myEmptyFolder")
myobj = await objects.add_object(idx, "MyObject")
myvar = await myobj.add_variable(idx, "MyVariable", 6.7)
await myvar.set_writable() # Set MyVariable to be writable by clients
myarrayvar = await myobj.add_variable(idx, "myarrayvar", [6.7, 7.9])
await myobj.add_variable(
idx, "myStronglytTypedVariable", ua.Variant([], ua.VariantType.UInt32)
)
await myobj.add_property(idx, "myproperty", "I am a property")
await myobj.add_method(idx, "mymethod", func, [ua.VariantType.Int64], [ua.VariantType.Boolean])
async with server:
while True:
await asyncio.sleep(1)
if __name__ == "__main__":
asyncio.run(main()) I might not have understood your answer completely (sorry). The client still reports just a |
Beta Was this translation helpful? Give feedback.
-
You have to wrap the error code in ua.StatusCode: def func(parent, variant):
print("func method call with parameters: ", variant.Value)
ret = False
if variant.Value == 42:
return ua.StatusCode(ua.StatusCodes.BadInvalidArgument)
if variant.Value % 2 == 0:
ret = True
return [ua.Variant(ret, ua.VariantType.Boolean)] |
Beta Was this translation helpful? Give feedback.
You have to wrap the error code in ua.StatusCode: