Production-grade Modbus TCP/RTU driver for Python (import name: pymod).
Project description
bacsys-pymod
Production-grade Modbus TCP / RTU driver for Python. Library + one-shot CLI.
Distribution name
bacsys-pymod, import namepymod.
import pymod
with pymod.Client.tcp("10.0.0.5", 502, unit_id=1) as c:
results = c.read([
pymod.Holding(start=0, count=10, dtype="float32"),
pymod.Coil(start=0, count=16),
pymod.Holding(start=0, count=2, dtype="bit", bit_index=8),
])
for r in results:
print(r.values if r.ok else f"failed: {r.error}")
Highlights
- Modbus TCP with concurrent connections and request pipelining (TID demultiplexing).
- Modbus RTU over a serial port — sequentialized internally, safe to share across callers.
- Modbus RTU over TCP for serial-to-Ethernet gateways (Moxa-style).
- All standard function codes (FC01/02/03/04/05/06/15/16) plus a registration hook for custom FCs.
- Heterogeneous batch reads — pass a list of typed items (Holding, Input, Coil, Discrete) and the planner coalesces adjacent same-area ranges into the minimum number of Modbus requests.
- Typed values —
int16,uint16,int32,uint32,float32,int64,uint64,float64, plus bit extraction from registers. - All four PLC byte/word orderings (ABCD / CDAB / BADC / DCBA) configurable per item.
- Sync facade for Flask / scripts / REPL —
pymod.Client.tcp(...)is a normal blocking object backed by an internal asyncio loop. - Server mode — callback-based, no internal datastore. Bring your own data, use it for protocol bridging (e.g. Modbus → BACnet / MQTT).
pymodCLI —read,write,scan,serve, plus an interactive--guidewizard.- Python 3.11+, pure Python (one runtime dep:
pyserial),mypy --strictclean.
Install
pip install bacsys-pymod
Once installed:
import pymod
print(pymod.__version__)
…and the pymod CLI is on PATH.
Quick examples
TCP — sync client (Flask, scripts, REPL)
import pymod
client = pymod.Client.tcp("127.0.0.1", 502, unit_id=1, timeout_s=0.5)
client.connect()
try:
results = client.read([pymod.Holding(start=0, count=10, dtype="int16")])
print(results[0].values)
finally:
client.close()
TCP — async client
import asyncio, pymod
async def main():
async with pymod.AsyncClient.tcp("127.0.0.1", 502, unit_id=1) as c:
results = await c.read([pymod.Holding(start=0, count=10, dtype="int16")])
print(results[0].values)
asyncio.run(main())
Serial RTU
client = pymod.Client.rtu("COM5", baudrate=9600, parity="N", unit_id=1)
…the rest of the API is identical to the TCP client.
Modbus TCP server (callback-based)
import asyncio, pymod
async def on_read(area, address, count):
return store.read(area, address, count)
async def on_write(area, address, values):
store.write(area, address, values)
async def main():
async with pymod.Server(host="0.0.0.0", port=502,
on_read=on_read, on_write=on_write):
await asyncio.Future()
asyncio.run(main())
The server has no internal datastore — the host application owns the data, the server is just a Modbus protocol terminator. Perfect for bridging Modbus to other industrial protocols.
CLI
pymod read --host 127.0.0.1 --port 502 --area holding --start 0 --count 10 --dtype int16
pymod write --host 127.0.0.1 --port 502 --area holding --start 0 --values 1,2,3 --dtype uint16
pymod scan --host 127.0.0.1 --port 502
pymod serve --host 0.0.0.0 --port 5020 --holding 0=100,1=200
pymod --guide # interactive wizard
Each subcommand has detailed --help.
Documentation
Full docs at https://bacsys-pymod.readthedocs.io/.
License
MIT. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bacsys_pymod-0.1.0.tar.gz.
File metadata
- Download URL: bacsys_pymod-0.1.0.tar.gz
- Upload date:
- Size: 8.8 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
44c221a8ba23e5153d306fd24b7376d12e5fd6ac0561e503c721ee258b53ca52
|
|
| MD5 |
2c29597659af71323d2a2381c1388c1d
|
|
| BLAKE2b-256 |
98f3ceefa3e9cf3d85460970e63de80ea3238895efc646f59df9409dcde4a222
|
File details
Details for the file bacsys_pymod-0.1.0-py3-none-any.whl.
File metadata
- Download URL: bacsys_pymod-0.1.0-py3-none-any.whl
- Upload date:
- Size: 54.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f809c41818a6c4324b0ddf18f08f1102b2a8140fe560b1410e4a30564649aef1
|
|
| MD5 |
d13cb08f9acb27b032d340dbc0003638
|
|
| BLAKE2b-256 |
0760a08f1f6d1f5b05a54d530968ffa2734833a0fee3bfbac691fc06a8457b51
|