Giter VIP home page Giter VIP logo

pylogix's Introduction

pylogix

PyPI PyPI Versions MicroPython PyPI - Downloads

WARNING: There is a possibility of a scam using the pylogix name. Be careful with anything claiming to be pylogix. https://www.notpylogix.com

Pylogix is a communication driver that lets you easily read/write values from tags in Rockwell Automation ControlLogix, CompactLogix, and Micro8xx PLCs over Ethernet I/P using Python. Only PLCs that are programmed with RSLogix5000/Studio5000 or Connected Components Workbench (Micro8xx), models like PLC5, SLC, and MicroLogix are not supported. They use a different protocol, which I have no plans to support. You can also connect to RSEmulate, but it may require additional configuration. See the Emulate document for more information.

Many devices support CIP objects that allow for automatic discovery (like RSLinx does), which pylogix can discover but will likely not be able to interact with in any other meaningful way. Pylogix is only intended to talk to the above-mentioned PLCs and is only tested against them. It likely will not communicate with any other brands.

For general support or questions, I created a discord. Feel free to join and ask questions, and I'll do my best to help promptly.

Getting Started

There are no dependencies, so you can get going quickly without installing other prerequisite packages. Both python2 and python3 are supported.

Installing

Install pylogix with pip (Latest version):

pylogix@pylogix-kde:~$ pip install pylogix

To install previous version before major changes (0.3.7):

pylogix@pylogix-kde:~$ pip install pylogix==0.3.7

To upgrade to the latest version:

pylogix@pylogix-kde:~$ pip install pylogix --upgrade

Alternatively, you can clone the repo and manually install it:

pylogix@pylogix-kde:~$ git clone https://github.com/dmroeder/pylogix.git
pylogix@pylogix-kde:~$ cd pylogix
pylogix@pylogix-kde:~/pylogix$ python setup.py install --user

Verifying Installation

To verify the installation on Linux, open the terminal and use the following commands:

pylogix@pylogix-kde:~$ python3
Python 3.8.5 (default, Jan 27 2021, 15:41:15) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pylogix
>>> pylogix.__version__
'0.7.10'

Your First Script:

The cloned repository will come with many examples, I'll give one here. We'll read one simple tag and print out the value. All methods will return the Response class, which contains TagName, Value and Status.

from pylogix import PLC
with PLC() as comm:
    comm.IPAddress = '192.168.1.9'
    ret = comm.Read('MyTagName')
    print(ret.TagName, ret.Value, ret.Status)

NOTE: If your PLC is in a slot other than zero (like can be done with ControLogix), then you can specify the slot with the following:

comm.ProcessorSlot = 2

NOTE: If you are working with a Micro8xx PLC, you must set the Micro800 flag since the path is different:

comm.Micro800 = True

Optionally set a specific maximum size for requests/replies. If not specified, defaults to try a Large, then a Small Forward Open (for Implicit, "Connected" sessions).

comm.ConnectionSize = 508

Installing MicroPython

Checkout Documentation

Other Features

Pylogix has features other than simply reading/writing. See the documentation for more info, see the examples directory simple use cases for the various methods.

FAQ

Here's a list of frequent asked questions. faq

Authors

  • Burt Peterson - Initial work
  • Dustin Roeder - Maintainer - dmroeder
  • Fernando B. (TheFern2) - Contributor - TheFern2
  • Joe Ryan - Contributor - jryan
  • Perry Kundert - Contributor - pjkundert

License

This project is licensed under Apache 2.0 License - see the LICENSE file for details.

Acknowledgments

  • Archie of AdvancedHMI for all kinds pointers and suggestions.
  • Thanks to ottowayi for general python and good practice advice.
  • Thanks to all of the users that have tested and provided feedback.
  • Joe Ryan for Omron testing and feedback

pylogix's People

Contributors

aansel-plenty avatar amber-vale avatar bengood avatar caprinux avatar clau72 avatar david-2d3fe9 avatar dgilbank avatar dmroeder avatar drbitboy avatar garrett92 avatar georgemakrakis avatar gilsand avatar githubdragonfly avatar jprogin avatar nusaqib avatar philipphaefele avatar pjkundert avatar sdmolt avatar thefern2 avatar tobiasht avatar treavorj avatar william-brumble avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pylogix's Issues

Accessing Task Specific Tags

I am able to read/write to controller tags in the main task no problem. Is there a syntax to read/write to tags in subtasks?

Failed to register session

Hi,

While trying to connect using your instructions, I get the error "Failed to register session" for both lines labeled 1 and 2. Could you help me?

I guess it might be an authorization issue, since the PLC Server has a username and password set. Are there any authorization methods in this module? If so, I was unable to find them.

Code -

from eip import PLC
test = PLC()
test.IPAddress = "192.168.3.3"
test.Port = 4048
print test.GetTagList()  #1
print test.GetPLCTime()  #2

Writing to a read-only tag exception

Making an issue just for record purposes, as we've already talked about it offline.

Issue:
The problem was found sort of by accident, I have two configuration files with tags in it, and I can save their online values, and later on I would attempt to load (write to plc). One tag was giving me problem, and Dustin found out it was indeed a read only tag. The configuration files probably shouldn't have read only tags, but I don't make those configuration files. Hence the problem.

image

  • When writing to a tag that doesn't exist a try/except works as expected.
  • When writing to a tag that exists, but is read-only program raises an exception with a traceback.

A few ideas, custom errors for the above two Errors, and whatever other ones.

... except (TagNotFoundError, ReadOnlyError, OtherError):
...     pass

https://docs.python.org/3/tutorial/errors.html User defined exceptions 8.5, I don't know if custom errors are needed or if you can just use the existing cip codes in eip.py somehow.

MultiRead timing out

Hi!
I'm able to read individual tags with no issue, but when I try to do a MultiRead, I get the following error:

>>> tags1
['HEDS.Shift_Number', 'HEDS.Status', 'HEDS.Shift_Hours']
>>> values1 = t1.MultiRead(*tags1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "eip.py", line 109, in MultiRead
    return _multiRead(self, args)
  File "eip.py", line 260, in _multiRead
    InitialRead(self, t, b)
  File "eip.py", line 1152, in InitialRead
    retData = self.Socket.recv(1024)
socket.timeout: timed out

Additionally, when I was trying to generate some sample output for this post, then second time I tried within the same python session, this was the result:

>>> tags1[0]
'HEDS.Shift_Number'
>>> v1 = t1.Read(tags1[0])
>>> print(v1)
2
>>> tags1
['HEDS.Shift_Number', 'HEDS.Status', 'HEDS.Shift_Hours']
>>> values = t1.MultiRead(*tags1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "eip.py", line 109, in MultiRead
    return _multiRead(self, args)
  File "eip.py", line 260, in _multiRead
    InitialRead(self, t, b)
  File "eip.py", line 1162, in InitialRead
    raise Exception('Failed to read initial tag: ' + cipErrorCodes[status]) 
KeyError: -1

Any thoughts? I've already increased the timeout value (socket.settimeout) to 10 (line 484)

Thanks for any help you can provide!

tags that are aliases

The example.py ex_getTags() correctly prints the datatype of tags that are aliases, but ex_read() and ex_write() fail on tags that are aliases because they find a datatype of 2 which is not one of the elements in self.CIPTypes

reading a tag of type UDT

I see pylogix is parsing the UDT members when retrieving the tag list which is awesome. I don't seem to be able to read a tag that is an instance of a UDT. The CPU I am using is a 1756-L75 and the firmware version is 32.

I have a test program with the following controller scoped tags:
image

I am using pylogix to get the tag list and read each tag:

from pylogix import PLC
with PLC() as comm:
    comm.IPAddress = '192.168.197.4'
    tags = comm.GetTagList()
    
    for t in tags:     
        print("tag: ", t.TagName, ". dt:", t.DataType,  ". size:", t.Size)
        if (t.DataType.strip() != ""):
            print("value: ", comm.Read(t.TagName))

I get the following output. (I have added a bunch of prints in eip.py)

t:  b'p\x00^\x00\x01\x00g\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xa1\x00\x04\x00\x01\x00\x00 \xb1\x00J\x00\x05\x00\xcc\x00\x00\x00\x00\x00\xca\x00\x00\x00\x00\x00\x00\x00\xc4\x00\x04\x00\x00\x00my_UDT;nHAEA\x00udt_member1_real\x00udt_member2_dint\x00\x00\xc0\xcdC>'
size:  16
p:  b'\x00\x00\xca\x00\x00\x00\x00\x00\x00\x00\xc4\x00\x04\x00\x00\x00my_UDT;nHAEA\x00udt_member1_real\x00udt_member2_dint\x00\x00\xc0\xcdC>'
p_length:  68
going to take the last  16  bytes of p as memberBytes
memberBytes:  b'my_UDT;nHAEA\x00udt_member1_real\x00udt_member2_dint\x00\x00\xc0\xcdC>'
members:  [b'my_UDT;nHAEA', b'udt_member1_real', b'udt_member2_dint', b'', b'\xc0\xcdC>']
tempplate key: my_UDT
t:  b'p\x00b\x00\x01\x00g\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xa1\x00\x04\x00\x01\x00\x00 \xb1\x00N\x00\x06\x00\xcc\x00\x00\x00\x00\x00\xc4\x00\x00\x00\x00\x00\x00\x00\xc4\x00\x04\x00\x00\x00my_UDT2;nEAEA\x00udt2_member1_dint1\x00udt2_member1_dint2\x00#\xec\xfa\x9c'
size:  16
p:  b'\x00\x00\xc4\x00\x00\x00\x00\x00\x00\x00\xc4\x00\x04\x00\x00\x00my_UDT2;nEAEA\x00udt2_member1_dint1\x00udt2_member1_dint2\x00#\xec\xfa\x9c'
p_length:  72
going to take the last  16  bytes of p as memberBytes
memberBytes:  b'my_UDT2;nEAEA\x00udt2_member1_dint1\x00udt2_member1_dint2\x00#\xec\xfa\x9c'
members:  [b'my_UDT2;nEAEA', b'udt2_member1_dint1', b'udt2_member1_dint2', b'#\xec\xfa\x9c']
tempplate key: my_UDT2
tag:  Program:MainProgram . dt:  . size: 0
tag:  my_dint . dt: DINT . size: 0
value:  8765
tag:  my_UDT_tag_instance . dt: my_UDT . size: 0
line 22, in <module>
    print("value: ", comm.Read(t.TagName))

  File "..\pylogix\eip.py", line 90, in Read
    return _readTag(self, tag, count, datatype)

  File "..\pylogix\eip.py", line 232, in _readTag
    return _parseReply(self, tag, elements, retData)

  File "..\pylogix\eip.py", line 1349, in _parseReply
    vals = _getReplyValues(self, tag, elements, data)

  File "..\pylogix\eip.py", line 1382, in _getReplyValues
    vals.append(str(s.decode('utf-8')))

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf6 in position 2: invalid start byte

It appears to be seeing the datatype as 160 and thinking that is string. If I had zero values in the UDT members it would sometimes print out random characters instead of dumping.

I have attached a wireshark pcap.
read_UDT_tag.pcap.zip

More than one call to .GetTagList() results in error

I get the following when making consecutive calls to GetTagList():

C:\Users\Jake\Downloads\pylogix-master>python
Python 2.7.11 (v2.7.11:6d1b6a68f775, Dec  5 2015, 20:40:30) [MSC v.1500 64 bit (
AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from eip import PLC
>>> test=PLC()
>>> test.IPAddress="192.168.45.92"
>>> test.GetTagList()
[<eip.LGXTag instance at 0x000000000248D808>, <eip.LGXTag instance at 0x00000000
0248DC48>, <eip.LGXTag instance at 0x000000000248DC08>, <eip.LGXTag instance at
0x000000000248DC88>, <eip.LGXTag instance at 0x000000000248DCC8>, <eip.LGXTag in
stance at 0x000000000248DD48>]
>>> test.GetTagList()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "eip.py", line 114, in GetTagList
    return _getTagList(self)
  File "eip.py", line 292, in _getTagList
    forwardOpenFrame = _buildTagRequestPacket(self, partial=False)
  File "eip.py", line 611, in _buildTagRequestPacket
    request = _buildTagListRequest(self, partial)
  File "eip.py", line 890, in _buildTagListRequest
    TLRequest += pack('<BB', 0x24, self.Offset)
struct.error: ubyte format requires 0 <= number <= 255
>>>```

Precision on real tags with decimals

It looks like when a real value has decimal values we are gaining precision on the return value, or is it losing precision?

online values:

image

return values:

-1.0000000200408773e+20
0.9999989867210388
0.10000000149011612
0.009999999776482582
0.003329999977722764
1000000000.0
5.0

I did some debugging and returnvalue is already rounded off when it gets returned in L1201. I will debug some more tomorrow, and see what else I can find.

image

pylogix/eip.py

Lines 1195 to 1203 in 6dc0842

elif datatype == 218:
index = 52+(counter*dataSize)
NameLength = unpack_from('<B', data, index)[0]
s = data[index+1:index+1+NameLength]
vals.append(str(s.decode('utf-8')))
else:
returnvalue = unpack_from(CIPFormat, data, index)[0]
vals.append(returnvalue)

I found this link which looks like our problem. https://stackoverflow.com/q/39619636/1013828

How do I write to an array of short int in the PLC ?

Hello,

I need to write to an array of short integers (2 bytes) in the PLC.
I am defining my array like this:

self.__B40: [int] = []

However, when setting bit 15 of one of the list elements the pylogix library throws this error:

CRITICAL EXCEPTION:short format requires (-32768) <= number <= 32767 in plc_write_tag_array(<pylogix_eip.PLC object at 0x04309B10>,B40[0],([1, -65520, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 5207, 0, 5269, 0, 5273, 0, 4251, 0, 4253, 0, 4254, 0, 4255, 0, 4258, 0, 4259, 0, 4260, 0, 4261, 0, 4262, 0, 4263, 0, 5290, 0, 5292, 0, 5295, 0, 4279, 0, 4297, 0, 4096, 0, 4104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 560, 8192, 568, 8192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],))

The offending list element is set as follows:

def set_b40_bit(self, dint, bit):
self.__B40[dint] = self.__B40[dint] | (1 << bit)

and then:

set_b40_bit(1, 15)

Any ideas on how to deal with this ?
Thank you !!

Error

I have this message when I try to run the programme: NameError: global name 'pack' is not defined

What this mean?

GetTagList function bug?

I found a little bug in the 'GetTagList' function ... the taglist is never emptied, so when the function is called twice or more (for the same PLC), it adds the tags that are already in the list, again.
So to fix this I had to access the global list and empty it every time the function is called.

Nothing too disturbing, but ...

multiParser on micro820 returns empty

works on single tag, but multiTag still have problem
stripped = data[50:] # stripped is empty but data [0:50} there are bytes
if I unpack_from('<H', data, 0)[0] , it shows 112

Micro820

Hey I am trying to read data from Micro820 PLC and tag i am trying to read is DV tag.
Can your code be helpful to me?

Determining if connection is lost

Once the socket is connected, how can you determine if the PLC goes away?

I get an unpack_from requires a buffer argument error from the Read function when I attempt to read after the PLC goes away (line 165 in the eip.py file). The reData value would be empty and the unpack_from function requires data to be present.

I'm only reading values every few minutes. I don't know if it would be better to ping the PLC IP, restart a connection, build a function to see if the PLC is still present, or build a better error trap in the Read function.

Thanks!

Error: unpack_from requires a buffer of at least 4 bytes

I'm running into an issue with this library. I'm setting up a function, then running it twice as two concurrent threads.

This function waits for a rising edge on a given Bool tag, then reads from a string tag. It does this continuously (wait for rising edge, read. wait for rising edge, read...).

This function works fine alone, and even works fine as a thread as long as there is only one thread. When I want to start both threads, I get the error "unpack_from requires a buffer of at least 4 bytes"
Here is the traceback:

Exception in thread 1:
Traceback (most recent call last):
File "C:\Python27\lib\threading.py", line 801, in __bootstrap_inner
self.run()
File "C:\Python27\lib\threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "C:\LogixInterface\main.py", line 90, in readOnTrigger
triggerFunc(PLC, triggerTag, trigStateOrEdgeType)
File "C:\LogixInterface\main.py", line 15, in waitForEdge
oldVal = PLC.Read(tagName)
File "C:\Python27\lib\eip.py", line 81, in Read
return _readTag(self, args[0], 1)
File "C:\Python27\lib\eip.py", line 148, in _readTag
if not _connect(self): return None
File "C:\Python27\lib\eip.py", line 439, in _connect
self.OTNetworkConnectionID = unpack_from('<I', retData, 44)[0]
error: unpack_from requires a buffer of at least 4 bytes

Then shortly afterwards, Thread 2 also fails with this Traceback:

Exception in thread 2:
Traceback (most recent call last):
File "C:\Python27\lib\threading.py", line 801, in __bootstrap_inner
self.run()
File "C:\Python27\lib\threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "C:\LogixInterface\main.py", line 102, in writeOnTrigger
triggerFunc(PLC, triggerTag, trigStateOrEdgeType)
File "C:\LogixInterface\main.py", line 15, in waitForEdge
oldVal = PLC.Read(tagName)
File "C:\Python27\lib\eip.py", line 81, in Read
return _readTag(self, args[0], 1)
File "C:\Python27\lib\eip.py", line 151, in _readTag
InitialRead(self, t, b)
File "C:\Python27\lib\eip.py", line 1059, in InitialRead
retData = self.Socket.recv(1024)
timeout: timed out

Any idea what's going on here? Like I said, if I just run a single thread, I get no error and everything is happy, but as soon as I want to run two I get the unpack error followed by a timeout.

I've attached my code in case you want to see what I'm trying.
main.txt

test.Read("tagname") returns None

HI,

First, thank you for this amazing library.

As mentioned, I am able to connect to the PLC and extract the tag list. However, when I try to print a tag value, it shows None. e.g.

value = test.Read("testbit")
print (value)
None

screen shot 2018-10-29 at 2 35 48 pm

Library Download and usage

I know this isn't an issue with the library you have provided. I am completely new to python and I am trying to get this going on windows 7. I have downloaded python v 2.7 and started doing a lot of research and practice on the coding part but I have no idea how to get this library into python so I can begin writing code. To use this code to get the tag information. Any information would be greatly appreciated because I am struggling greatly. I am a skilled plc programmer but it is a big jump from ladder logic to structured text. Thank you in advance.

Reading Tags From a SLC 500 or Micrologix

I realize that this library is not intended for reading from these processors, but i was wondering whats really preventing it?
the communications seems like it should be similar, I.E. instead of reading a tag named "MyTag4" you would read/write a tag named "N7:0/0"

I actually gave it a try, but it was a no-go.

Identifying which tags are multidimensional?

Just want to say thank you for this library!
I have a project which I will be going up to 6 or 7 plcs and doing some data monitoring.
Using your library is there a method for determining which tags have an array rather than a single variable? Working on a script which provide a live update of the variables as the machine is running. Thanks again for all your work on this library.

Pylogix

Hai sir frequently its disconnected supposes i ask the data in while loop it work 30 sec and i ask every 1 sec it work 15 min i ask every 500 ms it WOR 6 min i can't find out pblm

read array of boolean

I have an array of booleans of length 127.
why the function Read("arrayName", 127) gives me error?

I can only read one bit at a time with the function Read("arrayName[index]")

STRING32 Read/Write

Hi, have any easier way to read/write user defined strings than char by char in DATA array?

I have two UDT Strings called 'STRING32' (with 32 max size) and 'STRING64' (with 64 max size).

ControlLogix Usage

Hi, I'm having an issue with a PLC ControlLogix 5571. When I connect to the PLC and try to read some tags I get the message "Path destination unknown" for any tag that I try. But I've managed to connect to the PLC and read those same tags using another driver in C# created by Allen Bradly. I'm also using the same configurations of IP and Slot.

Is there any step that I'm missing for ControlLogix usage?

Any help would be appreciated.

Multi-Dimensional Arrays?

First off, this is awesome! Big help to get me up and going.

Second, thanks for the rickroll.

Third, I'm trying to read a multi-dimensional array. Something like: MyTag.Data_Storage[0,0] but the code doesn't seem to parse the response very well. I'm digging in, but wondering if this is something you've had working and/or tested?

Thanks!

Using this library with Omron PLC

Hi,

I am trying to use this library with an Omron PLC. I want to get the PLC time just to make sure the communication works. I am getting the following error:
File "C:\Python26\pylogix-master\plcread.py", line 5, in <module> comm.GetPLCTime() File "C:\Python26\pylogix-master\eip.py", line 115, in GetPLCTime return _getPLCTime(self) File "C:\Python26\pylogix-master\eip.py", line 336, in _getPLCTime raise Exception('Failed to get PLC time, ' + err) Exception: Failed to get PLC time, Path destination unknown
It seems like the PLC gets the request and replies, but it is not sending back any values. My thinking goes to the initial parameters in init function. I changed VendorID to match Omrons ID and I changed SerialNumber to Omron's serial number. What else I have to change to make the PLC give me back its time?
Maybe I am mistaken and it is completely something else that causes the problem?

Thanks in advance
Dhiaa Eddin Anabtawi

Failing to receive data when closing the connection

Hello,

When I call the Close() method, the execution does not reach self.Connect.Close(), which means that the TCP session with the PLC remains active (seen with Wireshark).
This is due to this line:

retData = recv_data(self)

Is this call to recv_data() necessary? It fails only in this case (via the Close() method), when self.Socket.recv(4096) is called:

part = self.Socket.recv(4096)

For the moment, simply commenting the first line is enough for me.

Speeding up reads

Hello dmroeder ,

First and foremost, thanks so much for making this module, it is much appreciated!

I'm currently reading about 100 Boolean per second, and I'd like to read faster. I have a list of 440 tags in a variable called 'final_list', and I'm looping through each individual tag and executing a read command using the Pylogix module. This is my code:

pylogixcode

Looping and individual reads might be slowing it down, but it seems we need to because of the 500 byte limit you mentioned in the 05_read_multiple_tags.py example. I've also tried following the fast read example, 09_multi_read_faster.py, but I can't seem to get it to work. We've tried putting the data into tuples and nested arrays and neither worked. Here is a picture with the tuples example:

readFasterEx

I'd like to be able to read faster, about 1000 tags per second. Have you ever been able to read this fast with PyLogix? If so, do you have any recommendations for speeding this up? I've been thinking about using Cython to speed up execution time, what are your thoughts?

Thanks,

proximo

Connection Lost

Hello,

I am using a Raspberry Pi 3B+ & Compact Logix L23E PLC and I am having issues connecting the two.

The variable "x1" is a bool tag that has External read/write access.
I can ping the PLC from the Pi.
I have not added any Ethernet modules to the PLC for communication to the Pi.

Any suggestions would be great. Thanks!

Ran on the Raspberry PI:

pi@raspberrypi:~/pylogix $ python
Python 2.7.13 (default, Sep 26 2018, 18:42:22)
[GCC 6.3.0 20170516] on linux2
Type "help", "copyright", "credits" or "license" for more information.

from eip import PLC
test = PLC()
test.IPAddress = "192.168.1.155"
value = test.Read("x1")
Traceback (most recent call last):
File "", line 1, in
File "eip.py", line 90, in Read
return _readTag(self, args[0], 1)
File "eip.py", line 160, in _readTag
InitialRead(self, t, b)
File "eip.py", line 1175, in InitialRead
raise ValueError(cipErrorCodes[status])
ValueError: Connection lost

Values with GetTagList

First off great job on the this. Made it fairly painless to connect to a PLC.
My issue though: When I use your GetTagList, I can pull in name and type no problem, but no value.
Im trying to grab all the tags names and values and write them to a libre file. To do this I have tried combining your "multiple log example' with your "get all tags example" by trying to inject the tags = with the whole t.TagName list. It always fail when It tries to read the values.

Any help on this would be great appreciated.

Micrologix Read/Write strings

Hi
I'm testing yourl library and is really really awesome !!
I have a problem when try to read and write a string, thi is code

              print c.rea_tag('ST9:0',1)

what I doing wrong ?
Thx 4 ur help!!

Multi-read failed

Hi, thank you for this awsome library, it is helping me a lot!

But I've been having an issue with multi-reads. I'm using the PLCs Micro850 and CompactLogix L18ERM, but multi-read doesn't seem to work in either of them. On CompactLogix I get the message "Multi-read failed, Embedded service error" and on Micro850 I get "Multi-read failed, Service not supported". Currently I'm calling the function Read with only an array of tags as parameter.
When I read each tag individually it works fine, but I need to read lots of data all the time, so multi-read would be really important.

Do you have any clue about why multi-read is not working for me?

Thanks in advance.

Reading Local Variable from Micro820

Hi,
i'm trying to read local variable from Micro 820, but i'm getting error:

Analog value: 0
Digital value: False
Traceback (most recent call last):
  File "C:/Users/mglow/Documents/Projects/RaspberryPi And Rockwell Communication/Python/main.py", line 11, in <module>
    own_value = comm.Read('Program:MAIN.MyOutput')
  File "C:\Users\mglow\Documents\Projects\RaspberryPi And Rockwell Communication\Python\venv\lib\site-packages\pylogix\eip.py", line 90, in Read
    return _readTag(self, tag, count, datatype)
  File "C:\Users\mglow\Documents\Projects\RaspberryPi And Rockwell Communication\Python\venv\lib\site-packages\pylogix\eip.py", line 203, in _readTag
    InitialRead(self, t, b, dt)
  File "C:\Users\mglow\Documents\Projects\RaspberryPi And Rockwell Communication\Python\venv\lib\site-packages\pylogix\eip.py", line 1506, in InitialRead
    raise ValueError('Failed to read tag: {}'.format(err))
ValueError: Failed to read tag: Path destination unknown

Process finished with exit code 1

Python code:

from pylogix import PLC
from socket import timeout # This is raised when no connection with PLC

with PLC() as comm:
    comm.Micro800 = True
    comm.IPAddress = "192.168.178.58"
    analog_value = comm.Read('_IO_EM_AI_00')
    print(f'Analog value: {analog_value}')
    digital_value = comm.Read('_IO_EM_DI_00')
    print(f'Digital value: {digital_value}')
    own_value = comm.Read('Program:MAIN.MyOutput')
    print(f"My own value from SUBPROGRAM: {own_value}")

On Micro 820 i've created a Program MAIN and inside local variables "MyOutput".

I will be grateful for all tips related to this problem:)
btw. i've seen #8, but there is no clear answer

ENBT EXCP 0300

I need two different programs to connect to a PLC to pick up different information. But the CLP ethernet card shows the 'EXCP 0300' fault when I do this. Do I need to do something different for this case?

Path Segment Error

When running a test script for reading a tag I encounter the 'Path Segment Error.'

test = PLC()
test.ProcessorSlot = 1
test.IPAddress = '192.168.1.1'
value = test.Read('para_scale')
print(value)
test.close()

I know that the PLC can be seen by using the .Discover() method. It outputs:

with PLC() as comm:
devices = comm.Discover()
for device in devices:
print(device.IPAddress)
print (' Product Code:'+ device.ProductName + ' ' +str(device.ProductCode))

192.168.1.1
Product Code:1756-L82E/B 165

I am very excited to use this library.
Thank you

Can this library work with Omron PLC?

I have an Omron NX1P PLC which supports CIP communication. Here is the link to the manual of the controller I am using which states that.

https://www.google.com/url?sa=t&source=web&rct=j&url=https://assets.omron.eu/downloads/manual/en/v2/sysmac_nx_csg320_users_manual_en.pdf&ved=2ahUKEwjl7NC_5PjhAhVFiHAKHf2iCX8QFjAAegQIBhAC&usg=AOvVaw06v95OrpSrpuhi-QEevZqf

Also I have tried using cpppo python library for CIP connection. The github project link is https://github.com/pjkundert/cpppo

I have been able to successfully identify the PLC on the network by using broadcast option using the command

python -m cpppo.server.enip.client --udp --broadcast --list-identity -a 192.168.1.255

This brings me to my question, can I use this module to read my PLC which I believe supports CIP and have evidence for backing it up? Or I am completely wrong and lost :(

If this library supports my PLC, can you help me in someway to create tags for/from the variables that the MAIN program is currently using.

Please help and thanks in advance for your time :)

Inconsistent MultiRead errors

Hello,
I'm seeing some errors while using MultiRead. I do not have issues if I loop single reads over the list of tag names. For example:

>>> test1 = eip.PLC()
>>> test1.IPAddress = cell1.ipAddr
>>> data1 = test1.MultiRead(*tags)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "eip.py", line 109, in MultiRead
    return _multiRead(self, args)
  File "eip.py", line 285, in _multiRead
    status = unpack_from('<h', retData, 48)[0]
struct.error: unpack_from requires a buffer of at least 2 bytes
>>> data1 = []
>>> for i in range(len(tags)):
...     data1.append(test1.Read(tags[i]))
... 
>>> data1
[2, 2, 6.210262298583984, 1.1434727907180786, 0.19440944492816925, 4.872259616851807, 85, 0.0, 13.68673324584961, 0.0, 0.0, 157404, 48.4294319152832, 0.0, 0.0, 0.21454083919525146, True]
>>> data1 = test1.MultiRead(*tags)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "eip.py", line 109, in MultiRead
    return _multiRead(self, args)
  File "eip.py", line 285, in _multiRead
    status = unpack_from('<h', retData, 48)[0]
struct.error: unpack_from requires a buffer of at least 2 bytes

For multiple PLCs I'm able to use MultiRead with no issue, but they are all CompactLogix with Ethernet built into the processor. The two PLCs I'm having issues with are different, however. They are a 1768-L43 and a 1756-L75 with separate ethernet cards.

Returning tagValue and DataType with Read()

Great library.

One possible improvement I have that you might consider is the option to return the DataType along with the tag value when read() is called.

Like other users I'm sure, I am reading a giant list of tags that are all explicitly defined by the end user in an Excel sheet. They could be nested tags, UDTs, or array subscripts, so it is not possible to call GetTagList() and return an array that contains all the tags I need.

To improve speed, I would still like to read the tags with the data type explicitly defined if I have that information.

The idea here is that if I don't have the datatype, I can read the tag without it, cache the datatype on return, and then use it to improve speed the next time I read that tag.

I've created an external function to accomplish this, but I think it would be neat if it was a built-in feature.

Again, great work!

getTagList Not Checking for Status

After sending the tag list request, the _getTagList function doesn't check for a valid status before calling extractTagPacket, causing an exception if the status is bad.

Should probably ensure that the status isn't bad (ie. 5) before extracting.

Unexpected Individual Read Result from Array

Question: I have a file with 18000 or so tags. I read all 1800 tags, then check current status in the PLC, then write to file. Roughly takes 37s for the whole operations.

Program:MyProgram.MyTag[0]
Program:MyProgram.MyTag[1]
...
Program:MyProgram.MyTag[299]

I am doing the read tags as follows:
test.Read(tag)

If I run my program it will raise an exception "Read failed Unkown Error" exactly at:
Program:MyProgram.MyTag[160]

My first thought was that maybe I was reading the tags too quickly, so I added a sleep(1) in between reads but exactly at 160 the exception is thrown.

I figure maybe there's a limit, tags from 0 to 159 are read fine is boolean and I print out to the console to check True and False were coming across. As a test I deleted all tags from this array starting at [160]. I checked the whole file and no other array went over 160. After deleting 160-299 lines from that array tag, I ran the program and it executed fine read all tags and wrote to the file.

Am I overlooking something? Have you come across this before?

Get Micrologix 1100 status

Hi,
I am trying to get the status (because there is no tags in this PLC) there is a way to get it?

Thanks

p.s
you are doing great work, thank you

Read UDT Array

How can I read all the elements or just one selected of a UDT array?

Ex.: My UDT:

Products

  • Code
  • Name
  • Counter

So I try to read a Products_DB array of Products [300], but when I try to read from Read ('Products_DB', 300) it returns only the code for each position and not all elements.

Any way to solve this?

Communication with Emulate 5000

When there is no plc hardware, I try to simulate the PLC with Emulate 5000.
But the program seems to be unable to discover any Ethernet I/P devices.
May I ask can Emulate 5000 simulate the communication process?
Thanks for your time.

Question about tag syntax

Maybe I am doing this wrong, or there is no way to parse the tag as it stands.

This works:
Program:DW_Fast.VP_WRK_CreepEncoderALastscan
But this doesn't:
Program:DW_Fast.DW_VP.INP_DWAEncoderPresentValue
both tags are DINT

I am assuming pylogix can only take program, and tag without having anything else in the middle with a dot?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.