chwiede / pyads

Beckhoff ADS implementation for python
MIT License
48 stars 14 forks source link

Problems in connecting to Beckhoff PLC CX9020 #1

Closed stefanocovino closed 10 years ago

stefanocovino commented 10 years ago

Dear friends,

I have download and installed the pyads library on a linux PC running Fedora. No problem from this side.

However, when I try to connect to a Beckhoff PLC using one of the examples provided in the zip file (deviceinfo.py) on the local network I simply get this message:

Exception in thread Thread-1: Traceback (most recent call last): File "/usr/local/lib/python2.7/threading.py", line 530, in bootstrap_inner self.run() File "/usr/local/lib/python2.7/threading.py", line 483, in run self.__target(_self.args, *_self.__kwargs) File "/usr/local/lib/python2.7/site-packages/pyads/adsclient.py", line 80, in _AsyncRead if (newPacket.InvokeID == self._CurrentInvokeID): AttributeError: 'NoneType' object has no attribute 'InvokeID'

Traceback (most recent call last): File "deviceinfo.py", line 5, in info = device.ReadDeviceInfo() File "/usr/local/lib/python2.7/site-packages/pyads/adsclient.py", line 182, in ReadDeviceInfo return DeviceInfoCommand().Execute(self) File "/usr/local/lib/python2.7/site-packages/pyads/commands/adscommand.py", line 36, in Execute responsePacket = adsClient.SendAndRecv(packet) File "/usr/local/lib/python2.7/site-packages/pyads/adsclient.py", line 134, in SendAndRecv return self.AwaitCommandInvoke() File "/usr/local/lib/python2.7/site-packages/pyads/adsclient.py", line 170, in AwaitCommandInvoke raise Exception("Timout: could not receive ADS Answer!") Exception: Timout: could not receive ADS Answer!

Can you help me to understand where the problem is?

Best regards, Stefano

chwiede commented 10 years ago

Hello Stefano,

It seems that your device is online via IP bit it doesn't answer via ADS protocol.

the provided example does work on a BC9000 bus coupler or similar for me. The library also works on "bigger" devices like CX-series, but these may have different ports:

Look into the manual of your device, and maybe try to connect with Beckhoff's system manager.

It's also important to have any running task on your device. Otherwise it won't communicate over ADS. In my case (BC9000) i'd uploaded an empty program (";").

Don't forget to enter/change your correct amsTarget. That's usually the IP with ".0.0". It's also important to enter the right AMS source id. This is your fedora pc. The example can work without amsSource, because simple bus couplers may have an empty routing table.

Linux doesn't know anything about the ams, so your connection could look like this:

device = AdsDevice(amsTarget="192.168.1.100.0.0:801", amsSource="192.168.1.200.0.0")
info = device.ReadDeviceInfo()

This works with certain conditions:

Let me know if i could help you.

Best regards, Christoph

stefanocovino commented 10 years ago

Hi Cristoph,

thanks for your rapid reply.

Indeed, yes, it helps. I was not using the amsSource piece of information. Actually I have to mandatory indicate a port in it, else I get an error message. Is that one of my choice among those not used in my Fedora PC or it has some specific value?

Cheers, Stefano

chwiede commented 10 years ago

Hi Stefano,

you're right - the port in amsSource must be declared seperated with a colon - i. e. "192.168.1.200:32905". I'd forgotten this in my example. 32905 should be the default one - but as far as i know this port would be used only for ADS notifications, which i haven't implemented (yet). So you could use one of your choice too.

Christoph

stefanocovino commented 10 years ago

Hi Cristoph,

again thank you.

The example now looks like:

from pyads import *

with AdsDevice(amsTarget="192.167.38.223.1.1:851", amsSource="192.167.38.103.1.1:32905") as device: info = device.ReadDeviceInfo() print(info)

I checked the IPs and the port.

Yet I still get this message:

Exception in thread Thread-1: Traceback (most recent call last): File "/usr/local/lib/python2.7/threading.py", line 530, in bootstrap_inner self.run() File "/usr/local/lib/python2.7/threading.py", line 483, in run self.__target(_self.args, *_self.__kwargs) File "/usr/local/lib/python2.7/site-packages/pyads/adsclient.py", line 80, in _AsyncRead if (newPacket.InvokeID == self._CurrentInvokeID): AttributeError: 'NoneType' object has no attribute 'InvokeID'

Traceback (most recent call last): File "deviceinfo.py", line 5, in info = device.ReadDeviceInfo() File "/usr/local/lib/python2.7/site-packages/pyads/adsclient.py", line 182, in ReadDeviceInfo return DeviceInfoCommand().Execute(self) File "/usr/local/lib/python2.7/site-packages/pyads/commands/adscommand.py", line 36, in Execute responsePacket = adsClient.SendAndRecv(packet) File "/usr/local/lib/python2.7/site-packages/pyads/adsclient.py", line 134, in SendAndRecv return self.AwaitCommandInvoke() File "/usr/local/lib/python2.7/site-packages/pyads/adsclient.py", line 170, in AwaitCommandInvoke raise Exception("Timout: could not receive ADS Answer!") Exception: Timout: could not receive ADS Answer!

Maybe it it now something related to the PLC configuration?

I of course apologize for my naive questions...

Stefano

chwiede commented 10 years ago

Hi Stefano,

i think your problem is indeed the PLC config, maybe a security setting. For my BC9000 i ended up working with an empty ams table - it's working in a trusted network. So any ams-id is accepted. This link could help: http://infosys.beckhoff.com/english.php?content=../content/1033/bc9000/html/bt_bc9000%20example%20access.htm&id=3130

Nothing to apologize - managing these beckhoff devices is overcomplicated in my opinion - the ads protocol claims to be an "open" protocol, but it's hard to find more documentation then something about basic read/write commands...

The whole Beckhoff "environment" is strong linked with their own software which's running on windows only.

What device are you using? Or is it a virtual device? Twincat 2 or 3?

Good luck! Christoph

stefanocovino commented 10 years ago

Hi Cristoph,

good point, I will check and let you know.

Regarding the Beckhoff hardware, as a matter of fact, in a linux based system, probably it was not a wise choice. I fully agree with your comments. We have Twincat 3.

Stefano

stefanocovino commented 10 years ago

Hi Cristoph,

I am trying to better understand what is wrong with our device.

I executed this piece of code:

from pyads import * import socket, select

d = AdsClient(amsTarget="10.56.2.25.1.1:851", amsSource="10.56.2.4.1.1:32905") d.Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) d.Socket.settimeout(2) d.Socket.connect((d.AdsConnection.TargetIP, d.AdsPortDefault)) ready = select.select([d.Socket], [], [], 0.1) response = d.Socket.recv(d.AdsChunkSizeDefault) print response

and the result is:

response = d.Socket.recv(d.AdsChunkSizeDefault)

socket.timeout: timed out

Assuming that connection data are correct, do you have any hint in what I could check to understand where the problem is?

Bye, Stefano

chwiede commented 10 years ago

Hi Stefano,

The device is CXCX9020. I'd forgotten that.

Christoph

stefanocovino commented 10 years ago

Hi Cristoph,

for the first question unfortunately we could not try yet. I hope to carry out such a test soon. We have no windows computer around. For the second question apparently everything works smoothly. Or, at least, I do no get any error message when I give the commands manually.

Bye, Stefano

chwiede commented 10 years ago

Hi Stefano,

How did you - or did you actually - initialize your cx? Is there a running task (plc project)? Is a boot project installed?

Without at least one running task / plc your Cx will accept incoming tcp, but it won't answer via ads protocol.

Unfortunately, this must be done with twincat plc control or system manager. I don't know any method to do this under Linux...

Christoph Am 22.07.2014 15:12 schrieb "stefanocovino" notifications@github.com:

Hi Cristoph,

for the first question unfortunately we could not try yet. I hope to carry out such a test soon. We have no windows computer around. For the second question apparently everything works smoothly. Or, at least, I do no get any error message when I give the commands manually.

Bye, Stefano

— Reply to this email directly or view it on GitHub https://github.com/chwiede/pyads/issues/1#issuecomment-49736377.

stefanocovino commented 10 years ago

Hi Cristoph,

I managed to verify that the PLC is properly configured (via twincat the connected hardware can be driven), the task is running, etc.

Indeed, trying with your example device info.py:

from pyads import *

with AdsDevice(amsTarget="10.56.2.18.1.1:851", amsSource="10.56.2.4.1.1:32905") as device: info = device.ReadDeviceInfo() print(info)

I now see this (new) error message:

python deviceinfo.py Traceback (most recent call last): File "deviceinfo.py", line 5, in info = device.ReadDeviceInfo() File "/usr/lib/python2.6/site-packages/pyads/adsclient.py", line 182, in ReadDeviceInfo return DeviceInfoCommand().Execute(self) File "/usr/lib/python2.6/site-packages/pyads/commands/adscommand.py", line 40, in Execute raise AdsException(responsePacket.ErrorCode) pyads.adsexception.AdsException: 'target machine not found'

while a direct access to the device:

d = socket.socket(socket.AF_INET, socket.SOCK_STREAM) d.settimeout(2) d.connect(("10.56.2.18",48898)) print d.recv(1024)

still gives a timeout error:

Traceback (most recent call last): File "prova.py", line 18, in print d.recv(1024) socket.timeout: timed out

Cheers, Stefano

chwiede commented 10 years ago

Hello Stefano,

sounds good.

'target machine not found' is an official ads-error message as listet in adsexception.py and it comes as directly answer from your device.

This means your ads-communication is working now.

I've tested the scenario and got the same with a wrong AMS-ID.

My AMS-ID should be: 192.168.50.107.1.1:800 but i tested 192.168.50.107.1.2:800

So I got the error "target machine not found".

The first part is the correct IP-address in both cases, so the tcp-com will work. I guess the last two digits in your ams-target-id are wrong. Maybe you should try 10.56.2.18.0.0:851 or something like this. You can find out your ams-id with twincat or system-manager.

good luck! Christoph

stefanocovino commented 10 years ago

Hi Cristoph,

I managed to install libads and it works with the same parameters of my last message. If I try the AdsClient example I get:

[root@remos examples]# ./AdsApiClient AdsState: 44 DeviceState: 24564 Name: Version: 224 Revision: 108 Build: 44

So, the AmsId should be correct, I think.

While I can probably use libads for my task I would anyway try to find the problem with pyads. Do you have any possible suggestion?

Stefano

stefanocovino commented 10 years ago

Hi Cristoph,

by the way, if one checks via twincat the address of the PLC can read its value (10.56.2.18.1.1 in my case) but also a different address: 5.24.233.215.1.1. Do you know what is this?

chwiede commented 10 years ago

Hi Stefano,

thats weird... i don't know how to set this up on a CX. As far as i know the ams-id doesn't have to go with the ip-address. It can be totally different. Maybe two ams-ids are possible on a single device. Something about this in the documentation of the cx (http://infosys.beckhoff.com/content/1033/cx9020_hw/index.html?id=1455)?

With pyads you could try this:

from pyads import *

connection = AdsConnection()
connection.TargetIP = "10.56.2.18" #your ip address
connection.TargetAmsID = "5.24.233.215.1.1" #ams id
connection.TargetAmsPort = 851 #ams port

connection.SourceAmsID = "10.56.2.4.1.1" #ams source id
connection.SourceAmsPort = 32905 #ams source port

with AdsDevice(adsConnection=connection) as device:
    info = device.ReadDeviceInfo()
    print(info)

In my case the output (for a BC9100) is:

COUPLER_PLC (Version 177.0.0)

Christoph

chwiede commented 10 years ago

Well another possible hint: Insert this code into adscommand.py, line 44 and try to get deviceinfo.

print(vars(result))
stefanocovino commented 10 years ago

Hi Cristoph,

I try later your second suggestion. However, the first advice seems to work fine:

from pyads import *

connection = AdsConnection() connection.TargetIP = "10.56.2.18" #your ip address connection.TargetAmsID = "5.24.233.215.1.1" #ams id connection.TargetAmsPort = 851 #ams port

connection.SourceAmsID = "10.56.2.4.1.1" #ams source id connection.SourceAmsPort = 32905 #ams source port

with AdsDevice(adsConnection=connection) as device: ... info = device.ReadDeviceInfo() ... print(info) ... Plc30 App (Version 3.1.1100)

This sounds encouraging, I guess.

In addition, please let me say that the only fact that you are trying to solve the problem is already ramemarkable.

Bye, Stefano

stefanocovino commented 10 years ago

Dear Cristoph,

I am also glad to say than now the library works very well. Apparently it was everything in the mess between the IP address and the AMD ID.

Thanks a lot for your support.

Stefano

chwiede commented 10 years ago

Hi Stefano,

You're welcome. Glad to hear that everything works for you now.

Feedback is always welcome.

Good luck with your project,

Christoph Am 29.07.2014 12:01 schrieb "stefanocovino" notifications@github.com:

Dear Cristoph,

I am also glad to say than now the library works very well. Apparently it was everything in the mess between the IP address and the AMD ID.

Thanks a lot for your support.

Stefano

— Reply to this email directly or view it on GitHub https://github.com/chwiede/pyads/issues/1#issuecomment-50457230.

PyRule commented 9 years ago

Hello chwiede,

I have an option to buy a C6330 IPC complete with twincat license. Will pyads work with it?

Best regards,

Roel

chwiede commented 9 years ago

Hello Roel,

i can't guarantee for this. If you can communicate with your IPC via ADS, pyads may communicate with your IPC. Running pyads on your IPC doesn't make sense for me, because you have to run it on Windows with TwinCat PLC anyway.

I'd developed this library for a simple buscoupler (without os), and i can't test every device.

Best of luck,

Christoph

PyRule commented 9 years ago

Hi Chistoph,

Thanks, I don't need it to run on the IPC itself so that's fine. I want the unit becuase it has ethercat. So can I connect remotely to the IPC and use pyads, or do I really need a buscoupler unit for example an ethercat buscoupler?

Best reagrds,

Roel

2015-02-01 10:32 GMT+01:00 Christoph Wiedemann notifications@github.com:

Hello Roel,

i can't guarantee for this. If you can communicate with your IPC via ADS, pyads may communicate with your IPC. Running pyads on your IPC doesn't make sense for me, because you have to run it on Windows with TwinCat PLC anyway.

I'd developed this library for a simple buscoupler (without os), and i can't test every device.

Best of luck,

Christoph

— Reply to this email directly or view it on GitHub https://github.com/chwiede/pyads/issues/1#issuecomment-72357951.

chwiede commented 9 years ago

Hi,

if your IPC as a running PLC or "runtime system", you might be able to communicate (read variables, write variables) with it over pyads. Communication with a soft-sps also works.

But i cannot garantuee for anything, because i'm not affiliated with Beckhoff in any way.

The buscouple BC9100 is not needed - but it's the only device which i can test.