python-opcua
python-opcua copied to clipboard
Unable to get data in proper format for nested tags.
My tags are inside another tag and it is nested. In UA Expert the tree looks like this.
UA Expert is able to fetch the data (both key value pair) for nested tags. how to achieve it in python? I tried something and i am getting the data as well but not in the key value format. It gives me a byte string.
Here is the code:
nodeid = ua.NodeId.from_string('ns=3;s="ERP_Roll_data"."Conveyor"."Mroll"')
attr = ua.ReadValueId()
attr.NodeId = nodeid
# attr.Value = nodeid.
attr.AttributeId = ua.AttributeIds.Value
params.NodesToRead.append(attr)
start = datetime.datetime.now()
result = client.uaclient.read(params)
print(len(result))
for each_result in result:
print(each_result)
is "Mroll" a custom type? did you load type definitions on clientside before reading?
is "Mroll" a custom type? -> I have no idea, i am reading a preprogrammed PLC did you load type definitions on clientside before reading? --> No
Should i search the type definations?
Should i search the type definations?
if its from a plc you should always otherwise all UDT's (userdefined data types) in the plc will be not known correctly on clientside
is there a special reason for using the lowlevel api?
I am new to OPC world. I wanted to do multiple tag acquisition at the same time(since the get_data() was very slow) and this is the only solution i found on internet. So using the same. Thanks for the help. I will check and update tomorrow.
client = Client("opc.tcp://192.168.10.1:4840/")
client.connect()
root = client.get_root_node()
objects = client.get_objects_node()
print("Reading before load typedefinitions:")
node = client.get_node('ns=3;s="Element_Data"."Data"')
print(node.get_value())
client.load_type_definitions() # scan server for custom structures and import them
print("Reading after load typedefinitions:")
node = client.get_node('ns=3;s="Element_Data"."Data"')
print(node.get_value())
client.disconnect()
C:\Users\andre>python c:/Users/andre/Desktop/client_read-custom_structures.py
WARNING:opcua.client.client:Requested session timeout to be 3600000ms, got 30000ms instead
Reading before load typedefinitions:
ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"RAIL_SEGMENT_UDT"), Encoding:1, 29580 bytes)
Reading after load typedefinitions:
RAIL_SEGMENT_UDT(RAIL_Size: 8, RAIL: RAIL_UDT(.... [ !!! i am not allowed to show all the data but you can get the idea !!! ]
C:\Users\andre>
The key word you need to study is ExtensionObject. The client doesn't know how to handle the extension object (custom structure) because it doesn't have the definition. Without this it doesn't know how to unpack the binary data sent from the server into the structure.
Thanks guys, it worked like a charm.
client.load_type_definitions()
How ever i am getting another issue:
If you see in the above screenshot, MRoll -> Roll is an Array (int32).

But python is giving me int32

Parsing is not proper i guess. Roll_Size is come 40, which i guess its the array size. I think the byte mapping is getting messed up, instead of creating an array, and assigning the value into it its assigning the value into next variable.
This is in python: Array value got assigned into Rolls, the same variable is 0 in UAExpert.
Python:

UA Expert:

~~it might be because of the references... does "Roll" has the reference expose its array~~
forget about that...
which PLC Vendor is it Siemens, B&R, Beckhof ???
Its SIEMENS - S7 1200
there was something with the s7-1200 and the extension object! still try to remeber...
it looks like there is no recursion on class build:
from opcua import Client
client = Client("opc.tcp://192.168.10.1:4840/")
client.connect()
struct = client.get_node('ns=3;s="Routen_DB"."Routen"')
before = struct.get_value()
client.load_type_definitions() # scan server for custom structures and import them
after = struct.get_value()
print("before", before)
print("after", after)
print(type(after))
print(after[0])
print(type(after[0]))
print(after[0].DST)
client.disconnect()
OUTPUT:
before [ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes),
ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes), ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"ROUTE_UDT"), Encoding:1, 68 bytes)]
after [ROUTE_UDT(DST_Size: 32, DST: 1), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32,
DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size:
32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0), ROUTE_UDT(DST_Size: 32, DST: 0)]
<class 'list'>
ROUTE_UDT(DST_Size: 32, DST: 1)
<class 'ROUTE_UDT'>
1
should be a list of class "ROUTE_UDT" i guess!?
Appreciate your help @AndreasHeine but there is one small problem: I dont have access to the PLC code. All i have is a OPC UA server. Besides since UA Expert is able to read it, i dont think problem is at server side. It definitely some client side issue only. I am running out of time now. I will recreate the scenario and try to fix the parsing for array after forking from master branch.
Appreciate your help @AndreasHeine but there is one small problem: I dont have acceess to the PLC code. All i have is a OPC UA server. Besides since UA Expert is able to read it, i dont think problem is at server side. It definitely some client side issue only.
sure my previous post proved that there is something missing in the class building out of a extension object in python opcua