modra-alan
modra-alan

Reputation: 11

How to access a nested structure using PyADS

I have two structures defined in TwinCAT3 like so:

TYPE ADSUWDisplay :
STRUCT
    sYarn : STRING;
    sNextYarn : STRING;
    lLength : REAL;
    iPosition : INT;
    sYarnSpec : STRING;
    iPackageCount : INT;
    iPackageTotalCount : INT;
    iCount : INT;
    iTotalCount : INT;
    sUpcomingYarn : STRING;
    sUpcomingYarnSpec : STRING;
    sUWMessage : STRING;
    sThreadUp : STRING;
END_STRUCT
END_TYPE

TYPE ADSRemoteDisplay :
STRUCT
    iUW : INT;
    iCount : INT;
    sState : STRING
    iStateNo : INT;
    sRobotMessage : STRING;
    adsUWDisplay : ARRAY[0..5] OF ADSUWDisplay;
END_STRUCT
END_TYPE

As you can see, ADSUWDisplay is nested inside ADSRemoteDisplay.

How can I access ADSUWDisplay using PyADS?

More specifically, how do I declare my Structure defs for use in pyads.connection.read_structure_by_name()?

Upvotes: 1

Views: 1148

Answers (2)

Anže
Anže

Reputation: 181

As far as I checked out the code it seems like you can't have nested structures. The code checked the type and if it's not one of predetermined types it returns an error. Se function dict_from_bytes in

https://pyads.readthedocs.io/en/latest/_modules/pyads/ads.html

Maybe if you define it as an array of bytes and parse it in python.

Edit: As one of the answers pointed out. It is possible with read_by_name and ctypes.Structure.

Upvotes: 0

Roald
Roald

Reputation: 3007

You can read out a struct as follows, from the pyads docs:

Use the parameter structure_def to define the structure and array_size to define the size of the array.

 >>> structure_def = (
         ("i", pyads.PLCTYPE_INT, 1),
         ("s", pyads.PLCTYPE_STRING, 1)
     )
 >>> symbol = plc.get_symbol("MyStructure", structure_def=structure_def, array_size=2)
 >>> symbol.write([{"i": 1, " "s": "foo"}, {"i": 2, "s": "bar"}])
 >>> symbol.read()
[{"i": 1, " "s": "foo"}, {"i": 2, "s": "bar"}]

Not sure how to define a nested struct. I guess you can try to add a nested tuple in structure_def, e.g.:

structure_def = (
         ("i", pyads.PLCTYPE_INT, 1),
         (
             ("s1", pyads.PLCTYPE_STRING, 1),
             ("s2", pyads.PLCTYPE_STRING, 1)
         )
     )

Upvotes: 1

Related Questions