chwiede / pyads

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

Unable to read variables from TC3 #8

Closed evanmj closed 7 years ago

evanmj commented 8 years ago

Hi,

I'm trying to get this going again, I'm having trouble getting it to work, connecting to a TwinCAT 3 PLC.

Here is my code:

from pyads import *
with AdsDevice(amsTarget="169.254.70.86.1.1:851", amsSource="10.0.8.18.1.1:851", targetIP = "172.16.6.2") as device:
    io = AdsIO(device)    
    io.Register(SymbolInfo("Normalized_IO.FeederIO[0].TrapdoorCyl.IN.IsRetracted", AdsClient.AdsIndexGroupIn, 8, AdsDatatype.Bool, 0))
    io.Register(SymbolInfo("Normalized_IO.FeederIO[0].TrapdoorCyl.IN.IsExtended", AdsClient.AdsIndexGroupIn, 8, AdsDatatype.Bool, 0))
    io.Initialize()

    io.ReadAll()

    print ("Retracted: " + str(io.Get("Normalized_IO.FeederIO[0].TrapdoorCyl.IN.IsRetracted")))
    print ("Extended: " + str(io.Get("Normalized_IO.FeederIO[0].TrapdoorCyl.IN.IsExtended")))

    io.WriteAll()

When I run the program in various forms, odd things happen.

If I run without supplying the amsSource="10.0.8.18.1.1:851", (or if I type in the default of 0.0.0.0.0.0:32905)... I get "Timeout: could not receive ADS Answer!"

Depending on the source AMS port I use, I get:

Packet dropped:
FROM 169.254.70.86.1.1:100 --> 10.0.8.18.1.1:43043
Command ID:  8
Invoke ID:   0
State Flags: 4
Data Length: 164
Error:       0
Data:
a0 00 00 00 01 00 00 00  ........
40 c3 b2 4b 58 c3 d1 01  @..KX...
01 00 00 00 07 00 00 00  ........
88 00 00 00 30 9c b2 4b  ....0..K
58 c3 d1 01 01 00 00 00  X.......
10 27 00 00 54 77 69 6e  .'..Twin
43 41 54 20 53 79 73 74  CAT Syst
65 6d 00 00 63 00 00 00  em..c...
54 43 50 2f 49 50 20 43  TCP/IP C
6f 6e 6e 65 63 74 69 6f  onnectio
6e 3a 20 53 6f 63 6b 65  n: Socke
74 20 74 6f 20 50 65 65  t to Pee
72 20 4e 61 6d 65 3a 20  r Name:
31 2c 20 50 6f 72 74 3a  1, Port:
20 32 35 35 36 33 20 69   25563 i
73 20 63 6f 6e 6e 65 63  s connec
74 65 64 2c 20 63 75 72  ted, cur
72 65 6e 74 20 73 6f 63  rent soc
6b 65 74 20 77 69 6c 6c  ket will
20 62 65 20 63 6c 6f 73   be clos
65 64 21 00  ed!.

Retracted: False
Extended: False

If I supply amsSource="10.0.8.18.1.1:851", AND the IDE (Twincat XAE) is closed, the program runs as expected with no errors, however I get "False" for both values, when one of them should be reading as "True".

So, in summary, has anyone used this with TC3 yet? It seems the defaults are for TC2. In most cases all I need to do is change 801 -> 851 to access a TC3 Runtime 1 port.

I'm at a loss of what could be going wrong here. Back when it was "working" with no errors, I could see the ADS calls and returns via wireshark, but the data was not correct.

Can you help me out?

Thanks.

kazulmokh commented 7 years ago

Hi, Did you solve the issue? I am trying the same thing with twincat 3 but I get "False" for all the values too. My code is :

from pyads import *

with AdsDevice(amsTarget="192.168.1.110.1.1:851", amsSource="192.168.1.129.1.1:851") as device:

create ads io device, register some variables and initialize

io = AdsIO(device)    
io.Register(SymbolInfo("S_Red", AdsClient.AdsIndexGroupIn, 8, AdsDatatype.Bool, 0))
io.Register(SymbolInfo("L_Red", AdsClient.AdsIndexGroupIn, 8, AdsDatatype.Bool, 0))
io.Initialize()
io.ReadAll()
print ("S_Red: " + str(io.Get("S_Red")))
print ("L_Red: " + str(io.Get("L_Red")))   
io.WriteAll()

Thanks. Nil

chwiede commented 7 years ago

Hi, generally the library is working on Windows with TC3-devices if:

I can't test it reliable because i don't have a TC3 device

Christoph

kazulmokh commented 7 years ago

Hi, Sorry for late reply. First a few clarifications-

When I tried the device.ReadDeviceInfo with above parameters I do get a response with TC version. Does that mean I have configured the routes correctly? If I have what can be wrong? I am a student working on a project related to communication between Ubuntu system and TC device. So pardon me if I am doing some silly mistakes or asking some stupid questions. Appreciate your help.

Thanks Nil

chwiede commented 7 years ago

Hello Nil,

You're welcome.

If you get a device info your ams id's seems to be correct.

If reading /writing variables fails, check their names. May be it's case sensitive, global vars must start with a point. (".fValue")

If writing fails, be sure to write correct data type (float/int)

I cannot test Linux and tc3 because I've no hardware for that combination.

Windows and tc3 is working, we use this in our company. In this case - and if the sps is secured - correct credentials are needed.

Good luck

Christoph

Am 04.01.2017 15:55 schrieb "kazulmokh" notifications@github.com:

Hi, Sorry for late reply. First a few clarifications-

  • I am using Beckhoff C6920 running TC3 and a PC running Ubuntu
  • I am trying to use this library on PC running Ubuntu.
  • Is it possible to do that?
  • What do you mean by correct credentials?
  • Lastly as far as I understand
  • target-IP = C6920 IP
  • target-AMS = C6920 AMS net id
  • source-AMS = (PC IP).1.1

When I tried the device.ReadDeviceInfo with above parameters I do get a response with TC version. Does that mean I have configured the routes correctly? If I have what can be wrong? I am a student working on a project related to communication between Ubuntu system and TC device. So pardon me if I am doing some silly mistakes or asking some stupid questions. Appreciate your help.

Thanks Nil

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/chwiede/pyads/issues/8#issuecomment-270389371, or mute the thread https://github.com/notifications/unsubscribe-auth/ABknTPuhbVjRk_yOxuFPPX2bp55Os--Uks5rO7LFgaJpZM4IzUKy .

evanmj commented 7 years ago

I have not gotten it to work, but I believe my problem might have been not providing the leading "." on the global variable names. I can't recall now if I tried that back then. I'm trying to connect local<->local now and I can't get it to work, but it is likely something odd on my system.

kazulmokh commented 7 years ago

Hey Christoph,

Thanks for your input. I tried to read global variables with "." but still got them as "False". I will try again with a new project tomorrow.

Nil

evanmj commented 7 years ago

I'll reopen for now, and try again on my end soon.

kazulmokh commented 7 years ago

Hi Evan,

Update: Still no luck reading the variables. Do I have to change the "Index group" and/or "Index offset" values?

Nil

evanmj commented 7 years ago

I've not tried again yet. I'll give it another shot now... I should have a few minutes.

evanmj commented 7 years ago

Still no luck on my end. I know I had it connecting at one point in the past, but I can't even get that far now.

    raise Exception("Timeout: could not receive ADS Answer!")
Exception: Timeout: could not receive ADS Answer!

My code is:

from pyads import *
with AdsDevice(amsTarget="172.16.6.39.1.1:851", amsSource="172.16.6.39.1.1:800") as device:
    io = AdsIO(device)    
    io.Register(SymbolInfo(".bBlink", AdsClient.AdsIndexGroupIn, 8, AdsDatatype.Bool, 0))
    io.Initialize()

I've tried every combo I can of null amsSource, I've tried specifying TargetIP, etc.

I know my TC system is fine, I'm able to talk to it with the .NET based ADS.dll w/o any problems.

chwiede commented 7 years ago

Ok now i get what you are trying.

Problem here is use of AdsIO - that's an abstract top layer for summarized communication using the process image.

I've added a easier sample with commit 66b5cef6 - You can try device.ReadByName(...) or device.WriteByName(...).

If performance is of concern retrieve SymbolHandles via device.GetSymbolHandle, cache them, and use e. g. device.ReadByHandle

To use AdsIO properly correct index group and offsets are necessary. The provided sample was written for a bus coupler, a real sps might have different index groups/offsets than "AdsClient.AdsIndexGroupIn". But i don't know how to get this values within twincat.

You might try the following example (I've not testet it):

#!/usr/bin/python2

from pyads import *  

with AdsDevice(amsTarget="172.16.6.39.1.1:851", amsSource="172.16.6.39.1.1:800") as device:

    # create ads io device... 
    io = AdsIO(device)

    #register some variables... 
    variables = {"switch": ".bSwitch",
                 "light": ".bLight"}

    for key, value in variables.iteritems():
        handle = device.GetSymbolHandle(value)
        io.Register(SymbolInfo(key, 0xf005, handle, AdsDatatype.Bool, 0))

    # and initialize   
    io.Initialize()

    # map input "switch" cyclic to output "light" 
    while 1:
        io.ReadAll()
        io.Set("light", io.Get("switch"))       
        io.WriteAll()     

Good luck,

Christoph

evanmj commented 7 years ago

Thanks for the new example. The code runs, but I'm still getting a timeout connecting:

C:\Python27>python.exe c:\Users\evan.jensen\Documents\pyads\evantest.py
Traceback (most recent call last):
  File "c:\Users\evan.jensen\Documents\pyads\evantest.py", line 13, in <module>
    handle = device.GetSymbolHandle(value)
  File "c:\Users\evan.jensen\Documents\pyads\pyads\adsdevice.py", line 15, in GetSymbolHandle
    symbolData = self.ReadWrite(0xF003, 0x0000, 4, variableName + '\x00').Data
  File "c:\Users\evan.jensen\Documents\pyads\pyads\adsclient.py", line 210, in ReadWrite
    return ReadWriteCommand(indexGroup, indexOffset, readLen, dataToWrite).Execute(self)
  File "c:\Users\evan.jensen\Documents\pyads\pyads\commands\adscommand.py", line 36, in Execute
    responsePacket = adsClient.SendAndRecv(packet)
  File "c:\Users\evan.jensen\Documents\pyads\pyads\adsclient.py", line 134, in SendAndRecv
    return self.AwaitCommandInvoke()
  File "c:\Users\evan.jensen\Documents\pyads\pyads\adsclient.py", line 170, in AwaitCommandInvoke
    raise Exception("Timeout: could not receive ADS Answer!")
Exception: Timeout: could not receive ADS Answer!

My 'PLC' is local, and I can connect from other local apps using ADS.dll, so that should rule out any virus protection, firewall, network issues, etc.

I also tried the fully qualified names in TC3 style: "Global_Variables.bSwitch"

Any other ideas?

evanmj commented 7 years ago

I get the same response running this code:

from pyads import *  

with AdsDevice(amsTarget="172.16.6.39.1.1:800") as device:
    info = device.ReadDeviceInfo()
    print(info)

I shouldn't need a route, right? I think I have one setup properly anyway, and it works from ADS.dll, so I don't think that would be the issue...

chwiede commented 7 years ago

OK if deviceinfo raises a timeout there's a general problem with the connection.

You could debug communication with Wireshark.

I'm not the expert for tc3 configuration, maybe I can ask a colleague tomorrow.

Christoph

Am 09.01.2017 20:28 schrieb "evanmj" notifications@github.com:

I get the same response running this code:

from pyads import *

with AdsDevice(amsTarget="172.16.6.39.1.1:851") as device: info = device.ReadDeviceInfo() print(info)

I shouldn't need a route, right? I think I have one setup properly anyway, and it works from ADS.dll, so I don't think that would be the issue...

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/chwiede/pyads/issues/8#issuecomment-271382408, or mute the thread https://github.com/notifications/unsubscribe-auth/ABknTAe_caDWxUFM2DW6Lj36VW9Sd9fzks5rQopSgaJpZM4IzUKy .

evanmj commented 7 years ago

Thanks, I'll shark it and see if it leaves the network port with a request.

evanmj commented 7 years ago

I'm having quite odd behavior now. I've tried to connect up to another remote machine, which at least shows some data in wireshark making it to the network. (maybe local routes don't hit the network stack, I'm not sure). Anyway, the results vary... mostly now I'm getting ADS error 6, Target port not found.

At least that is a step in the right direction, as I see a send and receive from the remote system.

I get the same thing in the new IO example using ports 800 and 851. In TC3, 851 should be the runtime 1 port, which is what I always use from the ADS dll.... I think I've come back full circle to the original post at the top of this thread, I was just slowed down trying to talk to my own local PLC instance.

EDIT: It might be talking about the variable. now... Ugh. Trying that now.

evanmj commented 7 years ago

Ugh, still no. I'm about to give up.

The wireshark packet returned from the PLC gives error 6 (target port not found), and gives the name I provided in this line:

device.WriteByName(".bTest", AdsDatatype.Bool, boolean_value)

So, I tried every iteration I could think of with fully qualified names in TC3 style, and I added the {attribute 'Tc2GvlVarNames'} to my globals to make them act like TC2 did....

I dunno. Anyone who used this with success in TC3, and you post your code?

Thanks.

chwiede commented 7 years ago

Did some tests today. After all it seems tc3 support is buggy or not implemented correctly.

Sps sends responses, but they are not recognized.

evanmj commented 7 years ago

Thank you. I'm glad I'm not crazy. I'm sorry I don't have more time and skillset to dig deeper and actually contribute to the project. If I find a place for this in a future project I'll do my best to dig deeper. It is more preference for me to work in python than .NET, plus it adds linux support in theory which I love.

Close this if you'd like as "not supported", or we can try to work through it. I'm happy to test, but the dev curve might be a bit higher than I have time for currently.

chwiede commented 7 years ago

Closing as not supported.