Closed hbszjjw closed 1 year ago
I don't know if you can get it working with python-opcua,
But my guess is that you have to init a class instead of passing the class:
ex = ua.ScanData()
I would switch to asyncua which has a sync wrapper for easy porting. Also this library isn't supported so another bonous if you switch to asyncua. The code would look like this:
client.connect()
client.load_type_definitions()
ex = ua.ScanData
identifier = ua.ScanData()
codeType = ''
region = ua.UInt16(3)
offset = ua.UInt32(0)
length = ua.UInt32(10)
password = b''
arguments = [identifier, codeType, region, offset, length, password]
readPoint11 = client.get_node("ns=4;i=5002")
readTag = client.get_node("ns=4;i=7009")
out = readPoint11.call_method(readTag, arguments)
thanks for your suggestion, but I can't set variable as ua.UInt16(3) , maybe beacuse I use opcua package, now I change my code as follows:
eo = ua.ScanData()
# eo.SwitchField = 0
identifier = ua.Variant(eo, ua.VariantType.ExtensionObject)
codeType = ua.Variant('', ua.VariantType.String)
region = ua.Variant(3, ua.VariantType.UInt16)
offset = ua.Variant(0, ua.VariantType.UInt32)
length = ua.Variant(10, ua.VariantType.UInt32)
password = ua.Variant(b'', ua.VariantType.ByteString)
after I run, it throws following error:
Traceback (most recent call last):
File "C:\03_Python_Project\SiemensRfidReader\main.py", line 64, in StartSiemensRfidOpcUaClient
out = readPoint11.call_method(readTag, arguments)
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\common\node.py", line 685, in call_method
return opcua.common.methods.call_method(self, methodid, *args)
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\common\methods.py", line 17, in call_method
result = call_method_full(parent, methodid, *args)
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\common\methods.py", line 40, in call_method_full
result = _call_method(parent.server, parent.nodeid, methodid, to_variant(*args))
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\common\methods.py", line 51, in _call_method
results = server.call(methodstocall)
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\client\ua_client.py", line 602, in call
data = self._uasocket.send_request(request)
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\client\ua_client.py", line 81, in send_request
future = self._send_request(request, callback, timeout, message_type)
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\client\ua_client.py", line 55, in _send_request
binreq = struct_to_binary(request)
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 261, in struct_to_binary
packet.append(to_binary(uatype, val))
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 284, in to_binary
return struct_to_binary(val)
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 256, in struct_to_binary
packet.append(list_to_binary(uatype[6:], val))
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 296, in list_to_binary
pack = [to_binary(uatype, el) for el in val]
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 296, in <listcomp>
pack = [to_binary(uatype, el) for el in val]
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 284, in to_binary
return struct_to_binary(val)
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 256, in struct_to_binary
packet.append(list_to_binary(uatype[6:], val))
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 296, in list_to_binary
pack = [to_binary(uatype, el) for el in val]
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 296, in <listcomp>
pack = [to_binary(uatype, el) for el in val]
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 274, in to_binary
return pack_uatype(vtype, val)
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 192, in pack_uatype
return variant_to_binary(value)
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 373, in variant_to_binary
b.append(pack_uatype_array(var.VariantType, ua.flatten(var.Value)))
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 224, in pack_uatype_array
b = [pack_uatype(vtype, val) for val in array]
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 224, in <listcomp>
b = [pack_uatype(vtype, val) for val in array]
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 192, in pack_uatype
return variant_to_binary(value)
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 378, in variant_to_binary
b.append(pack_uatype(var.VariantType, var.Value))
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 188, in pack_uatype
return extensionobject_to_binary(value)
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 460, in extensionobject_to_binary
Body = struct_to_binary(obj)
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 261, in struct_to_binary
packet.append(to_binary(uatype, val))
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 276, in to_binary
return getattr(Primitives, uatype).pack(val)
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\opcua\ua\ua_binary.py", line 69, in pack
string = string.encode('utf-8')
AttributeError: 'bytes' object has no attribute 'encode'
In asyncua it is working because i implemented it there see: https://github.com/FreeOpcUa/opcua-asyncio/issues/1093 https://github.com/FreeOpcUa/opcua-asyncio/issues/817
thanks, but I still have problems, now I do it like this:
from asyncua.sync import Client, ua
....
identifier = ua.ScanData()
codeType = ''
region = ua.UInt16(3)
offset = ua.UInt32(0)
length = ua.UInt32(10)
password = b''
arguments = [identifier, codeType, region, offset, length, password]
out = readPoint11.call_method(readTag, arguments)
it throws exception:
....
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\asyncua\ua\ua_binary.py", line 564, in extensionobject_to_binary
type_id = ua.extension_object_typeids[obj.__class__.__name__]
KeyError: 'str'
if I do it like this:
eo = ua.ScanData()
eo.SwitchField = 0
identifier = ua.Variant(eo, ua.VariantType.ExtensionObject)
codeType = ua.Variant('', ua.VariantType.String)
region = ua.Variant(3, ua.VariantType.UInt16)
offset = ua.Variant(0, ua.VariantType.UInt32)
length = ua.Variant(10, ua.VariantType.UInt32)
password = ua.Variant(b'', ua.VariantType.ByteString)
it throws exception:
...
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\asyncua\ua\uatypes.py", line 372, in check
raise UaStatusCodeError(self.value)
asyncua.ua.uaerrors._auto.BadArgumentsMissing: "The client did not specify all of the input arguments for the method."(BadArgumentsMissing)
Try client.load_data_type_definitions() instead of load_type_definitions()
thanks, the error is the same, and I checked with WireShark, I found the successful call request by UaExpert, the ArraySzie of InputArguments is 6, but for the failed call request, the ArraySzie of InputArguments is 1, and in Variant[0], it has the another level which is the same as the the successful call request, that means it has one more level. I want to share the picture, but git always shows: Something went really wrong, and we can’t process that file.
May bad the last parameter should be ByteString: identifier = ua.ScanData() codeType = '' region = ua.UInt16(3) offset = ua.UInt32(0) length = ua.UInt32(10) password = ua.ByteString (b'')
I can't use this style assignment, if I do it as follows:
identifier = ua.ScanData()
codeType = ''
region = ua.UInt16(3)
offset = ua.UInt32(0)
length = ua.UInt32(10)
password = ua.ByteString(b'')
it will throw exception:
......
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\asyncua\ua\ua_binary.py", line 564, in extensionobject_to_binary
type_id = ua.extension_object_typeids[obj.__class__.__name__]
KeyError: 'str'
identifier = ua.Variant(ua.ScanData())
codeType = ua.Variant('')
region = ua.Variant(ua.UInt16(3))
offset = ua.Variant(ua.UInt32(0))
length = ua.Variant(ua.UInt32(10))
password = ua.Variant(ua.ByteString (b''))
readPoint11.call_method(readTag, identifier, codeType , region, offset, length , password )
great, It works now, but it still throw another exception:
File "<string>", line 7, in __init__
File "C:\03_Python_Project\SiemensRfidReader\venv\lib\site-packages\asyncua\ua\uatypes.py", line 904, in __post_init__
raise UaError(
asyncua.ua.uaerrors._base.UaError: Non array Variant of type VariantType.ByteString cannot have value None
and I checked with WireShark again, the InputArguments is ok now, but in EncodingMask of ObjectId and MethodId is 0010 (Numeric of arbitrary length) which it is 0001(Four byte encoded Numeric) with UaExpert.
Should not matter, this is more a message length optimistation. How is the response? Can you post either the a complete wireshark trace or content of the response?
If you want the same request use this instead, because from string is not setting the length type: readPoint11 = client.get_node(ua.NodeId(5002, 4)) readTag = client.get_node(ua.NodeId(7009, 4))
it seems I can get the result, but something with the device now, when I read, its error LED blinks, but I check with WireShark, the result is the same as UaExpert, thank you very much, I think the main problem is solved.
and I tested with:
readPoint11 = client.get_node(ua.NodeId(5002, 4))
readTag = client.get_node(ua.NodeId(7009, 4))
the last error still have, if this error happens, I can't read output from Python.
thank you very much, the problem is solved because of some setting in the device, now the error disappears.
I have a question about method call, I have a RFID reader which I have to use method call to read tag, the method name is ReadTag which is declared like:
the problem is I don't know how to assign these structure arguments Identifier and CodeType when method call. I just do it like this:
ScanData is a Union type compose of 4 differents items: ByteString ; String ; Epc ; Custom.
actually I just need set its value to null in UaExpert, but I don't know how to do it in Python.
actually, I don't need assign the arguments Identifier with actual value, just null is ok, and also for code type empty string, but after I run this code, it returns nothing, it only show 'type' in terminal, and even I use print(out), it also show nothing.
can anyone give me instructions about how to use method call with complex arguments, thanks!