ottowayi / pycomm3

A Python Ethernet/IP library for communicating with Allen-Bradley PLCs.
MIT License
394 stars 88 forks source link

[BUG] - Discovery causing Network Unreachable #167

Closed uprightcarrion closed 2 years ago

uprightcarrion commented 3 years ago

Pre-checks

Description Running device discovery causes connection failed exception

Target PLC Model: L82ES Firmware Revision: 33 Other Devices in CIP Path:

Code Sample

from pycomm3 import LogixDriver as ld

addr = '192.168.1.1/0'
with ld(addr, init_tags=True, init_program_tags=True) as plc:
    #print( plc.get_plc_info())
    for info, value in plc.get_plc_info().items():
        print(info, value)
    devices = plc.discover()
    print(devices)

Additional context

> python test.py 
vendor Rockwell Automation/Allen-Bradley
product_type Programmable Logic Controller
product_code 212
revision {'major': 33, 'minor': 11}
status b'`1'
serial 0122d417
product_name 1756-L82ES/B
keyswitch REMOTE RUN
Traceback (most recent call last):
  File "test.py", line 8, in <module>
    devices = plc.discover()
  File "/home/tdesroches/.local/share/virtualenvs/EIP_Tag_Backup_Tool-E5eFIQi8/lib/python3.8/site-packages/pycomm3/cip_driver.py", line 243, in discover
    devices += cls._broadcast_discover(None, message, request)
  File "/home/tdesroches/.local/share/virtualenvs/EIP_Tag_Backup_Tool-E5eFIQi8/lib/python3.8/site-packages/pycomm3/cip_driver.py", line 261, in _broadcast_discover
    sock.sendto(message, ("255.255.255.255", 44818))
OSError: [Errno 101] Network is unreachable

You can see from the output I'm making the connection to the PLC, however as soon as I run the discovery I get this connection error. Is there some steps I'm missing or is this a bug?

ottowayi commented 2 years ago

The discover method is intended to be used to discover available Ethernet/IP devices on your network, here describes how it works. It is also a class method of CIPDriver, meaning you do not need an instance of a driver to use it. So the way you're doing it should be exactly the same as doing just devices = CIPDriver.discover(). As for the error itself, I'm not sure what could be causing it. But it does appear I'm missing some error handling on that call, because you should never see the exception and at worst get back an empty list. And depending on your network setup, you might not get any results if the routers between you and the devices filter broadcasts.

Do you get the same issue if you just run:

from pycomm3 import LogixDriver

devices = LogixDriver.discover()
print(devices)

TIP: get_plc_info is called as part of the driver connection and init_tags is True by default, so your example can be shortened to:

from pycomm3 import LogixDriver as ld

addr = '192.168.1.1/0'
with ld(addr, init_program_tags=True) as plc:
    for info, value in plc.info.items():
        print(info, value)
tdesroches commented 2 years ago

I tried without the instance and I get the same error. This is an unusually complicated network for us so I'll leave it for now and try it on a simpler one at another time.

Good tip thanks!

tdesroches commented 2 years ago

OK follow up, I plugged directly into the switch at the panel and discovery works fine. I think this can be closed unless you want to leave it open to catch the exception.

ottowayi commented 2 years ago

fixed in v1.2.2