pjkundert / cpppo

Communications Protocol Python Parser and Originator -- EtherNet/IP CIP
https://hardconsulting.com/products/6-cpppo-enip-api
Other
332 stars 109 forks source link

unreadable tags #46

Open Kraz113 opened 6 years ago

Kraz113 commented 6 years ago

Hi i am approaching this library to have an idea on how to read tags, In my case i have a L73 processor (clx) in a rack and i would like to read a tag from it.

The plc module is in a rack with other modules in it, (some i/o cards, a EN2T module). The ip address i can reach is the one of the ethernet module. My quesitons are:

1)how i connect directly to the CLX i need? can't i specify rack/port of the backplane?

2) (if 1 goes well)if i have a tag XYZ, can i just put "XYZ" as tagname or i need to specify "ProjectName.TagName" when asking for it?

thanks

pjkundert commented 6 years ago

Yes, you can indeed specify the backplane slot to perform I/O operations on.

The default 'route_path' is [{"port": 1, "link": 0}]. This indicates the Backplane ("port": 1), slot 0 ("link": 0). You can specify any other slot X ("link": X), or even multi-hop 'route_path', by putting multiple entries in the route_path list.

I am working on a fairly major update to Cpppo, to provide 3.7 compatiblity (ie. due to the new 'await' keyword), and to provide better support for arbitrary route_path in requests. You can access this new version (presently 4.0.1) using pip/pip2/pip3:

 pip install --upgrade git+https://github.com/pjkundert/cpppo.git@feature-multipath

To simulate something like a backplane with a CPU in slot 3, with a tag something like "This.SCADA" which is an array of 100 DINTs:

python -m cpppo.server.enip --route-path=1/3  -v 'This.SCADA=DINT[100]'

Then to read this, in another terminal on the same host, run:

python -m cpppo.server.enip.client -v --route-path=1/3 'This.SCADA[0-99]'

This actually simulates a Logix Read Tag request, with multiple symbolic name entries in its request path:

"enip.CIP.send_data.CPF.item[1].unconnected_send.request.path.segment[0].symbolic": "This",
"enip.CIP.send_data.CPF.item[1].unconnected_send.request.path.segment[1].symbolic": "SCADA",
"enip.CIP.send_data.CPF.item[1].unconnected_send.request.path.segment[2].element": 0,

Note that this is pretty much all possible right now, in the stock 3.9.7 version of Cpppo, but the route_path components must be specified in JSON, eg: '[{"port": 1, "link": 3}]', eg.:

python -m cpppo.server.enip --route-path='[{"link": 1, "port": 3 }]' -vv 'This.SCADA=DINT[100]'
Kraz113 commented 6 years ago

Thanks for this, the path selection works fine! Say now that i would like to pull data every x ms and put it int my DB. Should i make a loop in python or do we have already such libraries to pull that out?

pjkundert commented 6 years ago

Take a look at: https://github.com/pjkundert/cpppo/blob/master/server/enip/poll_example_many.py

If you replace the import of powerflex_750_series with:

from cpppo.server.enip.get_attribute import proxy

and use and instance of that as the via, you should be able to provide tag names in the targets dict.

Kraz113 commented 6 years ago

Great! Next question that comes naturally is: is there any way to get all the tags at once from a PLC?