ottowayi / pycomm3

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

Device Discovery #91

Closed AndrewStuhr closed 3 years ago

AndrewStuhr commented 3 years ago

Hey, hope all is well!

I was recently using pylogix to discover PLC's on my network (https://github.com/dmroeder/pylogix/blob/master/examples/20_discover_devices.py). That got me wondering whether pycomm3 can do this. I couldn't find anything, but thought I'd check with you in case I missed it. If not, have you considered adding device discovery. Not sure how much work it would take to add, but I think it would be a dope feature to have!

ottowayi commented 3 years ago

No there isn't currently any discover functionality. I'm not opposed to adding, I've just never had a need for it. I will look into it and see if I can get something working soon.

ottowayi commented 3 years ago

I think I have an initial working version, you should be able to do this:

from pycomm3 import CIPDriver  #or LogixDriver or SLCDriver

print(CIPDriver.discover())

This is in the develop branch, so you can pull from there and test it out if you want.

AndrewStuhr commented 3 years ago

I created a virtual environment and installed the devolopment branch. Here's what I'm getting when running the code. Any thoughts?

image

ottowayi commented 3 years ago

Sorry I broke some stuff. I'm working with a friend and doing a lot of internal changes right now and some of that was done in develop and not it's own branch. If you checkout this commit it should work.

Edit: Nevermind, it was a really simple fix. It should work now if you pull.

AndrewStuhr commented 3 years ago

livingTribunal

AndrewStuhr commented 3 years ago

Sweet, it worked!

On a separate note, do you have any ideas for how to get the slot number that actually has tags to read from? After discovering a new device on the network, I'd like to know which slot to use, too.

ottowayi commented 3 years ago

Do you mean find which slot number the PLC is in? Yeah that's possible, I don't have a script ready to go but it should be possible using discover() to find the IPs, then use the get_module_info() method on each slot to find the one with a device type for PLCs. RSLinx does more complicated stuff using the Port object to build the tree. But, you may find it simple enough that if the product name starts with '1756' you know it's a ControlLogix rack which can have a max of 17 slots, so you could just start looping thru them until you find the plc.

ottowayi commented 3 years ago

this feature is included in v1.0.0b1, it can be installed using pip install pycomm3==1.0.0b1

Colt-H commented 3 years ago

I have been playing with this a little bit and was having issues getting my Stratix switch to show up. I could see the packet coming back in wireshark.

I removed and response.raw[12:20] == context: from _broadcast_discover and was able to see the packet correctly. The sender context coming back from the Stratix is '00000000000'. I'm not sure if this is related, but if you look at the broadcast packet in wireshark, it shows the first part of the sender context under "Max Response Delay". I'm not sure how to verify if the issue is Pycomm or device related. If you have any ideas on how to verify one way or the other, I can try it.

I apologize for the awful screenshot, but it does include both packets in wireshark, the logs, and the code I modified. I don't have any image processing software on here. I also attached the log, but the logging doesn't return a lot on the discover method.

Screenshot from 2021-02-22 22-48-02 pycomm3_V1.0.0_Discover.log

ottowayi commented 3 years ago

Yeah I think that is correct. I sort of copied what pylogix was doing and they're matching context, but reading the CIP spec it just has both request and response context values at 0. I will get this fixed, thanks

Edit: just pushed the fix to develop

ottowayi commented 3 years ago

added in v1.0.0