dmroeder / pylogix

Read/Write data from Allen Bradley Compact/Control Logix PLC's
Apache License 2.0
598 stars 182 forks source link

Do I need to use routing? #241

Closed cstrutton closed 11 months ago

cstrutton commented 11 months ago

I have a case where I think I need to use routing.
I have a 1756-A4/C backplane with 3 slots. Slot 1 has a 1756-EN2T, 1756-EN2T/D set to 192.168.1.1 Slot 2 has a 1756-EN2TR, 1756-EN2TR/C set to 192.168.1.2 Slot 3 has a 1756-L71 LOGIX5571 that I am trying to talk to.

I am connected to the network attached to Slot 2.
When I try to read a tag from 192.168.1.2, I get forward open failed errors Do I need to use routing to navigate the backplane?

dmroeder commented 11 months ago

This would not be an example of routing. Make sure the IP Address of your computer is on the same subnet as the EN2TR (not the same address) and you can ping the card. You need to set ProcessorSlot = 3.

Now I'm assuming you are numbering your slots correctly, slot 3 is the far right slot (far left is slot 0). They are numbered 0-3, not 1-4

cstrutton commented 11 months ago

This is what I see in RSLinx. Can't reach any tags using slot 3. I use the same code to read dozens of other machines without issue. That is why I thought routing was needed.

When I connect using WhosActive in Studio5000, I have to open the backplane and select the processor directly...

image

TheFern2 commented 11 months ago

Share screenshot of ipconfig

Here's the blog for routing https://roederhard.blogspot.com/2020/02/routing-and-pylogix.html?m=1 Routing is needed when you're going in and out ethernet modules on different ips.

Based on your screenshot I don't think you need routing you just need to be able to ping either 192.168.1.2 or 10.4.42.48 then you should be able to read tags on the L71.

Can you expand 01 on your previous screenshot and share screenshot of again just for completeness.

dmroeder commented 11 months ago

It looks like NAT is involved here, which is why you see 2 IP addresses. Your EN2TR probably has the IP address of 10.4.42.48, some device is translating that to the address 192.168.1.2. You likely need to configure a gateway address for your computer. The GW address will be the address of the device doing the translation.

cstrutton commented 11 months ago

Thanks for the quick replies. I appreciate your help getting this figured out.

Here is the updated RSLinx grab. Interestingly enough, when I connect to the 192.168.1.1 network and set the plc IP to 192.168.1.1, I can read the plc with no problem. But, when connected there, I can't see any of the other devices on the network (the machine is 150' long with several sub-machines connected to the xxx.2 network that I need to access). image

This is my ifconfig. eth1 is connected to the network device in slot 2. I can ping 192.168.1.2 but not 192.168.1.1. The extra ip's on eth0 are aliases that I use to expose devices to my plant network using iptables one-to-one NAT. Again, this same setup is reading a couple of dozen other devices without issue. The only difference is the second network card.

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.4.45.101 netmask 255.255.192.0 broadcast 10.4.63.255 inet6 fe80::48bb:2dff:fe10:40fe prefixlen 64 scopeid 0x20 ether 4a:bb:2d:10:40:fe txqueuelen 1000 (Ethernet) RX packets 34920138 bytes 4459501774 (4.4 GB) RX errors 1 dropped 0 overruns 0 frame 0 TX packets 42145848 bytes 3976511681 (3.9 GB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device interrupt 37

eth0:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.4.42.48 netmask 255.255.192.0 broadcast 10.4.63.255 ether 4a:bb:2d:10:40:fe txqueuelen 1000 (Ethernet) device interrupt 37

eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.4.43.201 netmask 255.255.192.0 broadcast 10.4.63.255 ether 4a:bb:2d:10:40:fe txqueuelen 1000 (Ethernet) device interrupt 37

eth0:2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.4.43.202 netmask 255.255.192.0 broadcast 10.4.63.255 ether 4a:bb:2d:10:40:fe txqueuelen 1000 (Ethernet) device interrupt 37

eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.1.250 netmask 255.255.255.0 broadcast 192.168.1.255 inet6 fe80::48bb:ffff:fec9:8a89 prefixlen 64 scopeid 0x20 ether 4a:bb:ff:c9:8a:89 txqueuelen 1000 (Ethernet) RX packets 44671310 bytes 3643088813 (3.6 GB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 25035731 bytes 3547343434 (3.5 GB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1000 (Local Loopback) RX packets 5948 bytes 605748 (605.7 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 5948 bytes 605748 (605.7 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

cstrutton commented 11 months ago

This is the code I am using to test.

from pylogix import PLC comm = PLC('192.168.1.2') comm.slot=3 comm.Read('always_off') Response(TagName=always_off, Value=None, Status=Forward open failed)

TheFern2 commented 11 months ago

Well if you can ping 192.168.1.2 then you should be good imo. Shouldn't the L71 slot be 2? assuming ENT2 is slot0, and ENTR slot 1, no? Have you tried comm.slot=2?

dmroeder commented 11 months ago

Well if you can ping 192.168.1.2 then you should be good imo. Shouldn't the L71 slot be 2? assuming ENT2 is slot0, and ENTR slot 1, no? Have you tried comm.slot=2?

The number to the left is the slot number. Slot 0 is empty in his case. The controller is in slot 3.

cstrutton commented 11 months ago

This backplane is numbered from 1, not 0. see rslinx images above. studio 5000 is using AB_ETHIP-1\192.168.1.2\3 as a path.

I am thinking they are doing something funky with the network on this system. 192.168.1.1 and 1.2 cant see each other. I am just looking at the card configuration to see if I can see anything...

cstrutton commented 11 months ago

I was able to work around it. It looks like the 192.168.1.1 was set up to allow connection from the front panel programming port to the PLC only. The rest of the machine was hidden.

I worked around it by connecting the 192.168.1.1 switch to the 192.168.1.2 switch. A bit crude, but nothing bad happened.

I would still like to understand why I cant direct connect.

dmroeder commented 11 months ago

The 2 cards can't "see" each other directly because they are not networked together. Let's say your chassis has 4 EN2T's in it. From left to right, 192.168.1.10, 192.168.1.20, 192.168.1.30 and 192.168.1.40. You plug into slot 3, the only address that shows up in RSLinx would be 192.168.1.40. You can browse the backplane to see the other cards, but that doesn't put them on the same network together, the cards are isolated from each other.

The only reason RSLinx can see them is because it has the special ability to tunnel through the backplane to discover them.

Your setup is confusing to me. It seems that you are physically connected to slot 2, but are wanting to access the PLC via slot 1's IP address. That doesn't make sense. Just because they have IP addresses on the same subnet doesn't put them on the same network together.

cstrutton commented 11 months ago

When I am physically connected to slot 2 (card set to 192.168.1.2) rslinx can see the plc in slot 192.168.1.2. pylogix can not see it at .1 or .2. when I am physically connected to slot 1 (card set to 192.168.1.1) pylogix can see the plc at 192.168.1.1. When I am connected to slot 1, I cant see any of the devices connected to .2 network.
Yes, the integrator loves to overcomplicate things. I have 4 other cells built by them so I would love to figure this out with out having to jump the 2 networks together.

cstrutton commented 11 months ago

Ok, so I think I figured it out.
I can connect to either 192.168.1.1 or .2 adapters. From there instead of specifying slot 3, I added comm.Route([(1,3)]. That told it to go through the backplane and out slot 3.

from pylogix import PLC comm = PLC('192.168.1.2') comm.Route = [(1, 3)] comm.Read('always_off') Response(TagName=always_off, Value=False, Status=Success)

Just needed to wrap my head around AllenBradly routing.

Thanks again for all your patience.

dmroeder commented 11 months ago

@cstrutton Try this instead:

from pylogix import PLC
comm = PLC("192.168.1.2")
comm.ProcessorSlot = 3
print(comm.Read("always_off"))

"comm.slot" is the incorrect syntax. It is comm.ProcessorSlot

I realize that you have it working, based on your result, I don't think you need to use Route, just correctly set the processor slot.

Edit: For pylogix, comm.ProcessorSlot = 3 is the same thing as comm.Route = [(1, 3)] https://github.com/dmroeder/pylogix/blob/master/pylogix/lgx_comm.py#L520C8-L526

Route only needs to be used when you need to use one chassis to access another chassis. If you are staying within the same chassis, you simply need to tell pylogix which slot the controller is in.

TheFern2 commented 11 months ago

Well if you can ping 192.168.1.2 then you should be good imo. Shouldn't the L71 slot be 2? assuming ENT2 is slot0, and ENTR slot 1, no? Have you tried comm.slot=2?

The number to the left is the slot number. Slot 0 is empty in his case. The controller is in slot 3.

I missed the syntax oops, I usually give slot value in the PLC instance, shouldn't python throw an error for inexistent class variable? or does it dynamically create slot on the fly. The joy of dynamic languages.

dmroeder commented 11 months ago

It will create it.

TheFern2 commented 11 months ago

It will create it.

That's bad, python creators should have made a super class like Final to avoid dynamically creating new variables on the fly. This would result in a warning on any statically type language.

Just a quick search and it is possible in python to throw an AttributeError https://docs.python.org/3.8/reference/datamodel.html#slots I will look into it, should be an easy implementation.

cstrutton commented 11 months ago

Omg... I am so sorry for wasting your time!  It's been a long year here... slot is the parameter for the constructor so I just used that when testing.  Interestingly enough... comm.Route = [(1,3)] did work.  And now I think I understand routing better.Get Outlook for AndroidFrom: dmroeder @.>Sent: Tuesday, December 19, 2023 12:37:22 p.m.To: dmroeder/pylogix @.>Cc: Chris Strutton @.>; Author @.>Subject: Re: [dmroeder/pylogix] Do I need to use routing? (Issue #241) The 2 cards can't "see" each other directly because they are not networked together. Let's say your chassis has 4 EN2T's in it. From left to right, 192.168.1.10, 192.168.1.20, 192.168.1.30 and 192.168.1.40. You plug into slot 3, the only address that shows up in RSLinx would be 192.168.1.40. You can browse the backplane to see the other cards, but that doesn't put them on the same network together, the cards are isolated from each other. The only reason RSLinx can see them is because it has the special ability to tunnel through the backplane to discover them. Your setup is confusing to me. It seems that you are physically connected to slot 2, but are wanting to access the PLC via slot 1's IP address. That doesn't make sense. Just because they have IP addresses on the same subnet doesn't put them on the same network together.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you authored the thread.Message ID: @.***>

TheFern2 commented 11 months ago

Omg... I am so sorry for wasting your time!  It's been a long year here... slot is the parameter for the constructor so I just used that when testing.  Interestingly enough... comm.Route = [(1,3)] did work.  And now I think I understand routing better.Get Outlook for AndroidFrom: dmroeder @.>Sent: Tuesday, December 19, 2023 12:37:22 p.m.To: dmroeder/pylogix @.>Cc: Chris Strutton @.>; Author @.>Subject: Re: [dmroeder/pylogix] Do I need to use routing? (Issue #241) The 2 cards can't "see" each other directly because they are not networked together. Let's say your chassis has 4 EN2T's in it. From left to right, 192.168.1.10, 192.168.1.20, 192.168.1.30 and 192.168.1.40. You plug into slot 3, the only address that shows up in RSLinx would be 192.168.1.40. You can browse the backplane to see the other cards, but that doesn't put them on the same network together, the cards are isolated from each other. The only reason RSLinx can see them is because it has the special ability to tunnel through the backplane to discover them. Your setup is confusing to me. It seems that you are physically connected to slot 2, but are wanting to access the PLC via slot 1's IP address. That doesn't make sense. Just because they have IP addresses on the same subnet doesn't put them on the same network together.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you authored the thread.Message ID: @.***>

No worries, we like helping people, yeah we should make both of these the same name. I think one came later. Either way slots will benefit the library and avoid silly mistakes in the future.

dmroeder commented 11 months ago

Oh yeah, good points @TheFern2