Closed Deville-ee closed 6 years ago
Please try to run the tests by calling
$ python setup.py test
Do the tests pass or are you getting errors? If the tests pass the problem must be somewhere else...
Have you added a route on the target machine? You need to manually add a route on your target PLC to allow it to send the response to the right place. This is handled automatically with the TwinCAT router on Windows, however there's no equivalent with the Linux version.
To add the route on the target you'll need the IP address (or hostname) of your Linux machine, and its AMS address. You can get the AMS address like this:
>>> remote_ip = '192.168.0.100' # Replace with target IP
>>> adr = pyads.AmsAddr('127.0.0.1.1.1', pyads.PORT_SPS1) # Replace with target AMS address
>>> pyads.add_route(adr, remote_ip)
# NOTE: get_local_address() won't work properly until you've added a route as above
>>> pyads.get_local_address()
'192.168.1.10.1.1'
Then you can login to the remote machine (PLC), open up the TwinCAT router UI and add a static route using these details (set the 'Remote Route' to None).
You can also use the new-style Connection
class. This class takes care of the routing automatically on connect and disconnect.
Yes I should have mentioned that. The connection class will automatically add the local route, but you will still need to manually add a return route on the target PLC from my experience.
Thanks for your help, guys. Very kind..
@ dabrowne Yes I tried al sorts of variants of this setup, and we do get a AMS address like expected but the connection itself failes. The testserver ( $ python -m pyads.testserver ) also works and I can even poll for dummy variables like indicated within the official documentation.
pyads.open_port()
30000
remote_ip='192.16.17.9'
adr=pyads.AmsAddr('127.0.0.1.1.1', pyads.PORT_SPS1)
pyads.add_route(adr,remote_ip)
2017-09-25T11:59:25+0200 Info: Connecting to 192.16.17.9
2017-09-25T11:59:25+0200 Info: connection closed by remote
pyads.get_local_address()
<AmsAddress 192.16.17.10.1.1:30000>
@MrLeeh Pytest was not installed but after installation it gave me this output back: ( For the record: I ran the command in the pyads folder )
$ python setup.py test
running test
running egg_info
writing pyads.egg-info/PKG-INFO
writing dependency_links to pyads.egg-info/dependency_links.txt
writing top-level names to pyads.egg-info/top_level.txt
reading manifest file 'pyads.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'pyads.egg-info/SOURCES.txt'
running build_ext
=======================test session starts ========================
platform linux -- Python 3.6.2, pytest-3.2.2, py-1.4.34, pluggy-0.4.0
rootdir: /run/media/wouter/DATA/Workspace-IE/Firmware/Beckhoff Cx5120/pyads, inifile: tox.ini
collected 29 items
tests/test_ads.py .
tests/test_connection_class.py ................
tests/test_integration.py ............
====== 29 passed in 4.56 seconds ============
@MrLeeh It was not clear to me the new .Connections style was a replacement for the old manual implementation so I gave it a try. I needed to open a port first as you can see in the following terminal output.
import pyads
plc=pyads.Connection('192.16.17.9.1.1' , 851 )
pyads.get_local_address()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.6/site-packages/pyads/ads.py", line 72, in get_local_address
return adsGetLocalAddressEx(port)
File "/usr/lib/python3.6/site-packages/pyads/pyads_ex.py", line 160, in adsGetLocalAddressEx
raise ADSError(error_code)
pyads.pyads.ADSError: ADSError: ads-port not opened (1864)
import pyads
pyads.open_port()
30000
plc=pyads.Connection('192.16.17.9.1.1' , 851 )
pyads.get_local_address()
<AmsAddress 0.0.0.0.1.1:30000>
plc.open()
2017-09-25T12:25:43+0200 Info: Connecting to 192.16.17.9
2017-09-25T12:25:43+0200 Info: connection closed by remote
plc.pyads.get_local_address()
<AmsAddress 192.16.17.10.1.1:30000>
@wouterjoris Yes, to get the local address you still need to call pyads.open_port()
. Maybe I could add a more convenient function as static method of pyads.Connection
that opens and closes the port itself and returns the local address.
Did your routing work now? I could imagine you run into trouble because you are mixing the remote ip with to local AMSAddr. I think it should be:
>>> remote_ip = '192.168.0.100' # Replace with target IP
>>> remote_ams_addr = '192.168.0.100.1.1' # Could be different, depends on your target
>>> adr = pyads.AmsAddr(remote_ams_addr, pyads.PORT_SPS1) # Replace with target AMS address
>>> pyads.add_route(adr, remote_ip)
I think this last tip of you certainly is most helpful. I did mixup those addresses. But the problem however stays the same: "connection closed by remote"
As @dabrowne already pointed out; I also should add a route on the PLC side. This seems not to work in Twincat3 runtime. I always get the error: 1800 device busy.
There is also the option of a broadcast search but I don't see a response out of pyads. Is pyads meant to answer to these multicasts?
Have a look if your Firewall is active. I just had the same issue here. If you deactivate the firewalls on both sides you should be able to see the other side via Broadcast Search.
@wouterjoris The linux AMS router won't answer the multicast request as far as I know. It's very different to the Windows implementation in that it doesn't actually exist as it's own process, it's just a c++ library which is invoked by the pyads module. On Windows the router is always running as a daemon so it is able to answer the multicasts.
@MrLeeh @dabrowne
>>> plc.read_device_info()
('PLC Server', <pyads.structs.AdsVersion object at 0x7fa9db636cf8>)
I finally got a reply from the PLC. :-)
I installed twincat 2 on the PLC ( V2.11.2259 ) where I could add a route back to my PC. Twincat3 ( V3.1.4022.2) runtime does not seem to work at this point. I have some more testing to do to confirm this for sure but it makes me hopeful now I have a working connection running.
Thanks again for the assistance!
Happy that it works for you now. However TwinCAT3 should work too. I'm doing my testing with TwinCAT3 ... but from a Windows PC. This works well. Would be nice to know if it is a general issue with Linux and TwinCAT3 or maybe just a setting thing. Let us know if you found anything ;)
Greetings
The connection with TC3 works on Windows. For the Linux case only TC2 works for now.
So my idea was to switch runtimes within the TC3 VC2013 environment in order to program the PLC but this seems quite a hassle too. The PLC won't run if it's programmed with TC3 while switching back to TC2.
I'll let you know for sure if I manage to get some progress in the situation but I'm a bit out of ideas at the moment.
kind greetings Wouter
I'm happily using a TC3 PLC with a Linux pyads client. I suspect that the issue may be separate from pyads as the manual route failed on the PLC.
I added my routes by logging into the PLC with remote desktop (or if you have a monitor attached, just working on the PLC directly), right clicking on the TwinCAT icon on the taskbar and going router > edit routes > add
. You should also be able to do the same from TwinCAT Engineering (Visual Studio) on your Windows machine, but this is just another option to try.
Here's a screenshot of the configuration just to make extra sure. Note that your linux machine will need a static IP. Also note that Remote Route is set to None. Route name can be whatever you like, normally it's set to the Hostname of your client.
Yes, I finally got a working connection with TC3.
>>> plc.read_device_info()
('Plc30 App', <pyads.structs.AdsVersion object at 0x7f9beaca6a20>)
For some reason I was not able to add a route on the PLC to the master Linux machine so I used the same settings with my Windows machine using Twincat 3 VC2013. ( which I need anyway to program the PLC. ) Once setup the route could be added on the PLC and this works all the same when switched back to Linux.
I must say I'm not impressed with the Beckhoff software provisions but like they say here at the office: Once you get it running your good to go. :o)
I'm happy with the working connection and thanks you again for the kind help.
Kind greetings Wouter
Hi reader, I have to communicate a PLC (Beckhoff CX9020) with a raspberri pi thru python, and I have been hitting my head against the wall for the past 3 days. For the record, I have the communication going well with TwinCAT and I can read variables with python if I do it from Windows. It seems like the issue is very related to this thread, I tried following but I couldn't solve the puzzle. I need help, please contact
The connection class will automatically add the local route, but you will still need to manually add a return route on the target PLC from my experience.
how do I add the route?
Thanks for your help, guys. Very kind..
@ dabrowne Yes I tried al sorts of variants of this setup, and we do get a AMS address like expected but the connection itself failes. The testserver ( $ python -m pyads.testserver ) also works and I can even poll for dummy variables like indicated within the official documentation.
pyads.open_port() 30000 remote_ip='192.16.17.9' adr=pyads.AmsAddr('127.0.0.1.1.1', pyads.PORT_SPS1) pyads.add_route(adr,remote_ip) 2017-09-25T11:59:25+0200 Info: Connecting to 192.16.17.9 2017-09-25T11:59:25+0200 Info: connection closed by remote pyads.get_local_address() <AmsAddress 192.16.17.10.1.1:30000>
I mannaged to make something similar to this to work, so I know my AmsAdress... what do I do with it? any help is more than welcome
Hello Sofia,
could please you post the code you used to establish the connection. You will need to create a route on the PLC for the communication to work. Did you use add_route_to_plc for this?
Freundliche Grüße Stefan Lehmann
Am 24.02.2021 08:51 schrieb Sofia:
Hi reader, I have to communicate a PLC (Beckhoff CX9020) with a raspberri pi thru python, and I have been hitting my head against the wall for the past 3 days. For the record, I have the communication going well with TwinCAT and I can read variables with python if I do it from Windows. It seems like the issue is very related to this thread, I tried following but I couldn't solve the puzzle. I need help, please contact
The connection class will automatically add the local route, but you will still need to manually add a return route on the target PLC from my experience.
how do I add the route?
Thanks for your help, guys. Very kind..
@ dabrowne Yes I tried al sorts of variants of this setup, and we do get a AMS address like expected but the connection itself failes. The testserver ( $ python -m pyads.testserver ) also works and I can even poll for dummy variables like indicated within the official documentation.
pyads.open_port() 30000 remote_ip='192.16.17.9' adr=pyads.AmsAddr('127.0.0.1.1.1', pyads.PORT_SPS1) pyads.add_route(adr,remote_ip) 2017-09-25T11:59:25+0200 Info: Connecting to 192.16.17.9 2017-09-25T11:59:25+0200 Info: connection closed by remote
pyads.get_local_address() <AmsAddress 192.16.17.10.1.1:30000>
I mannaged to make something similar to this to work, so I know my AmsAdress... what do I do with it? any help is more than welcome
-- You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub [1], or unsubscribe [2].
Links:
[1] https://github.com/stlehmann/pyads/issues/34#issuecomment-784871191 [2] https://github.com/notifications/unsubscribe-auth/ABDNGBQQJ5LK6KRYDXHB5ADTASVWXANCNFSM4D4F6LTA
Hello Stefan Lehmann,
I somehow managed to make th connection work from linux. I wanted to let you know that the method "add_route_to_plc" gives me a timed_out every time. I had to add the route manually from TwinCAT and it worked (after lots of tweaks to my code).
import pyads
pyads.open_port()
pyads.set_local_address(CLIENT_NETID)
pyads.close_port()
# pass
# connect to plc and open connection
# route is added automatically to client on Linux, on Windows use the TwinCAT router
plc = pyads.Connection(TARGET_ADS, 851, TARGET_IP)
plc.open()
# check the connection state
state = plc.read_state()
print(state)
this gives me a connection status of "(5, 0)". The thing is, now I need to have 2 simultaneous connections to the PLC and when I run the above code I get disconected from the PLC in TwinCAT3 on Windows. Any ideas on how to have 2 (or more) open connections to the PLC?
The most issues we had with route_to_plc so far were because the parameter names are a bit confusing and got mixed up. Would you mind sending the code you used for that so we can investigate?
Hi Stefan. After much hitting my head against the plc, I discovered that the problem was not pyads but the program the plc was running... it had an overflow problem, so all I was trying was being savotaged by unexpected problems on the side. Sorry to make you worry about pyads, and thank you for your help, time and attention.
The other day I was trying to connect to a Beckhoff CX5120 PLC running windows and TC3 runtime. We managed to connect via a windows machine and read back some PLC variables. Our master machine is a Linux PC so windows is no option in this case.
On Linux ( Arch ) however, the pyads 2.2 package does not work, it seems the AMS server is not working properly. Netstat tells me a tcp connection is opened but when I try to make a ADS connection it fails with a timeout. Is there a good way to debug this thing? What kind of information can I collect in order to get to a working sollution?