pylogix: reading and writing Rockwell Logix PLC tags from Python over EtherNet/IP
Read/Write data from Allen Bradley Compact/Control Logix PLC's
At a glance
- What is it?
- pylogix is a dependency-free Python driver that speaks EtherNet/IP to Allen Bradley ControlLogix, CompactLogix and Micro8xx PLCs, returning a Response object with tag name, value and status for every call. It suits engineers wiring a Python service to a running machine, and it is deliberately limited to one vendor family.
- Who is it for?
- pylogix fits an engineer who needs to read or write tags on a Rockwell Logix PLC from Python, on a bench or in a service that talks to running equipment, and it does not fit anyone working with PLC5, SLC or MicroLogix hardware or with a non-Rockwell brand.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 52 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One vendor family, one protocol, and the limits that come with it
Pylogix is a communication driver that lets you read and write values from tags in Rockwell Automation ControlLogix, CompactLogix and Micro8xx PLCs over Ethernet I/P using Python.
The vendor restriction is stated as plainly as it can be. Only PLCs programmed with RSLogix5000/Studio5000 or Connected Components Workbench for the Micro8xx are supported, and models like PLC5, SLC and MicroLogix are not, because they use a different protocol which the author has no plans to support. The same honesty extends to other brands: the readme says pylogix is only intended to talk to the mentioned PLCs, is only tested against them, and will likely not communicate with any other brands.
That is a narrow scope, and for an industrial driver narrow scope is a feature. The alternative, a general CIP stack that speaks to anything with CIP objects, would be more flexible and would also talk to devices pylogix cannot meaningfully drive. The readme notes that many devices support CIP objects allowing automatic discovery, like RSLinx does, and that pylogix can discover them but will likely not be able to interact with them in any other meaningful way.
The audience is therefore engineers and integrators who need a Python process to talk to a specific running machine, for monitoring, for a test rig, or for a data pipeline. The topics list the full set: allen-bradley, cip, ethernet-ip, rockwell-automation, plc, and the three controller families.
Installing, and the awkwardness of a global pip install
There are no dependencies, which the readme points out as the reason you can get going quickly without installing other prerequisite packages. Both python2 and python3 are supported.
The install is a normal pip command:
pylogix@pylogix-kde:~$ pip install pylogixThe readme also documents how to pin an older version before the major changes in 0.3.7, and how to upgrade:
pylogix@pylogix-kde:~$ pip install pylogix==0.3.7pylogix@pylogix-kde:~$ pip install pylogix --upgradeAnd the manual route from a clone, which matters if you want to work against the source rather than the published package:
pylogix@pylogix-kde:~$ git clone https://github.com/dmroeder/pylogix.git
pylogix@pylogix-kde:~$ cd pylogix
pylogix@pylogix-kde:~/pylogix$ python setup.py install --userThe setup.py is a plain setuptools script, with the version read from the package itself rather than hardcoded, and the classifiers list Python 2.7 and Python 3.6 and the Apache Software License. That is a sign of a package that has been around long enough to have pre-3.7 Python in its history, which the readme's python2 support claim confirms.
Verifying the install is a two-line check in the interpreter:
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'One practical warning belongs with the install rather than in a footnote. The readme carries a red warning about the possibility of a scam using the pylogix name, and asks people to be careful with anything claiming to be pylogix, pointing at a notpylogix.com address. For a package that talks to industrial controllers, a lookalike on PyPI is a supply chain problem with real consequences, so installing by name from the official source is worth more care than usual.
The Response object: tag name, value and status on every call
The API is built around a single return type. The readme is explicit that all methods return the Response class, which contains TagName, Value and Status.
That is a better design than returning a bare value, because a PLC read can fail in several distinguishable ways: the tag does not exist, the tag exists but the value is a fault, or the read timed out. A bare value would flatten those into an exception or a wrong number. A Response object with a Status field lets the caller decide what a bad status means for their application.
The first script is short, and it shows the shape of the whole library:
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)Two details in those five lines carry the design. The PLC object is a context manager, so the session is opened and closed around your block of work rather than left dangling, which matters for a device that only tolerates so many concurrent connections. And the address is a property set after construction, not a constructor argument, so the same object shape works whether you are pointing at a real controller or a simulator.
The examples directory shows how far the API goes. There are numbered files for reading a simple tag, reading the program scope, reading arrays, reading multiple tags, reading in a loop, reading the first instance, and two examples about reading faster, and the same set again for writing, plus a write to SQL, device discovery, getting and setting the PLC clock, and tag discovery at the controller, program and all-tags level, with a save_tags example. The readme points at that directory for simple use cases, and the deeper documentation is in docs/Documentation.md.
Processor slot and the Micro800 flag are where connections fail
Two settings on the comm object decide whether the driver can reach the controller at all, and the readme documents both as required for particular hardware.
The first is the processor slot. If your PLC is in a slot other than zero, as can be done on a ControlLogix, you set it explicitly:
comm.ProcessorSlot = 2The second is the Micro800 flag. If you are working with a Micro8xx PLC you must set it, because the path is different:
comm.Micro800 = TrueThe reason both exist is the same. EtherNet/IP addressing is not a single flat namespace: the session path encodes which module you are talking to, and a ControlLogix with several cards in a chassis needs the slot number to disambiguate. A Micro800 has a different path structure again, which is why it needs a separate flag rather than a slot number.
The failure mode when these are wrong is worth predicting, because it is not a clean error. A wrong path means the request reaches something that is not the controller, so you get a failed read or an empty response rather than a message saying the slot is wrong. For someone commissioning a new setup, that is the first thing to check when reads return nothing, ahead of cabling, IP addressing and firewall rules.
The library also supports connecting to RSEmulate, Rockwell's simulator, which the readme says may require additional configuration, with a dedicated Emulate document linked for that.
MicroPython support, through a separate package layout
Pylogix is not only for CPython. There is a MicroPython port, and the readme points at a separate document for installing it.
The mechanics are visible in the repository. Alongside the pylogix/ package there is an upylogix/ directory, and a package.json at the root that is not a Node manifest in the usual sense. It is a list of URL mappings that pair the compiled module files with their GitHub sources:
"urls": [
[
"pylogix/__init__.mpy",
"github:dmroeder/pylogix/upylogix/__init__.mpy"
],
[
"pylogix/eip.mpy",
"github:dmroeder/pylogix/upylogix/eip.mpy"
],Each entry pairs a .mpy filename with the upstream path in the upylogix directory, and the version key at the end of that file is 1.1.6. MicroPython compiles Python to .mpy bytecode, and those files are the compiled artefacts, so the mapping tells a MicroPython tool where to fetch each module.
The separate directory is a good structure for the goal. The MicroPython build has to shed the parts of the library that do not fit on a microcontroller, and keeping the ported modules in their own tree means the CPython package is not carrying a second implementation around. The badge in the readme claims MicroPython 1.20.0 or later, and there is an examples/01_micropython_example/ directory to match.
The practical use case is an edge device reading a machine directly, with no server in between, which is the kind of deployment where a CPython-only driver would simply not run.
Apache-2.0, a maintained fork history, and the shape of the project today
The project is licensed under Apache 2.0, with the LICENSE.txt file in the repository as the reference. The authors section credits Burt Peterson for the initial work, Dustin Roeder as maintainer, and Fernando B., Joe Ryan and Perry Kundert as contributors, and the acknowledgements thank others for pointers, general advice, and testing.
The repository is not archived, and the last push was on 2026-09-01. There are no GitHub releases, so the version history lives in the code and in the changelog rather than in tags, and the version the readme's verification snippet prints is 0.7.10, well past the 0.3.7 boundary the readme calls out as the last pre-major-change release.
The dependency-free claim is the other thing worth noting. There is no requirement for a CIP stack, no native extension, no socket wrapper dependency. The EtherNet/IP implementation lives in the library itself, in the eip module for the client and lgx_comm, lgx_device, lgx_response, lgx_tag and lgx_uvendors modules for the protocol, device handling, responses, tag definitions and the vendor CIP identity list, with utils alongside. A driver with no dependencies is easier to drop onto a target machine, which is exactly the situation industrial integration work tends to be in.
The project also maintains a support channel on Discord, and a FAQ document for the questions that come up repeatedly, both linked from the readme. For a library whose users are often the only person who understands the machine, a place to ask questions matters as much as the code.
Editorial conclusion
pylogix fits an engineer who needs to read or write tags on a Rockwell Logix PLC from Python, on a bench or in a service that talks to running equipment, and it does not fit anyone working with PLC5, SLC or MicroLogix hardware or with a non-Rockwell brand. Before wiring it into a machine, read the FAQ and the Emulate document linked in the readme, and set the processor slot and the Micro800 flag correctly for your controller, since a wrong path produces failed reads rather than a clear error.
Frequently asked questions
Which PLCs does pylogix support?
Rockwell Automation ControlLogix, CompactLogix and Micro8xx controllers over Ethernet I/P, meaning PLCs programmed with RSLogix5000/Studio5000 or Connected Components Workbench for the Micro8xx. PLC5, SLC and MicroLogix models use a different protocol and are not supported, and the readme says it will likely not communicate with other brands.
How do I install pylogix and check that it works?
Run pip install pylogix, since there are no dependencies, then open a Python interpreter and check pylogix.__version__ after importing pylogix. The readme also documents installing a pinned older version with pip install pylogix==0.3.7, upgrading with --upgrade, and installing from a clone with python setup.py install --user.
How do I read a tag from a Logix PLC with pylogix?
Create a PLC object as a context manager, set its IPAddress, and call Read with the tag name. The call returns a Response object with TagName, Value and Status, and the readme notes that all methods return that class.
What do ProcessorSlot and Micro800 do in pylogix?
They set the session path to the right module. ProcessorSlot is needed when the controller is not in slot zero, as can happen on a ControlLogix, and Micro800 must be set to True for a Micro8xx PLC because the path differs. The readme documents both as comm.ProcessorSlot and comm.Micro800 properties.
Does pylogix work with MicroPython?
Yes. There is a separate upylogix directory in the repository with compiled .mpy modules for MicroPython 1.20.0 or later, and the root package.json maps each .mpy file to its source path. Installation instructions are in the separate MicroPython document linked from the readme.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/dmroeder-pylogix)Was this useful?