Skip to main content

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 name pymod.

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 valuesint16, 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).
  • pymod CLIread, write, scan, serve, plus an interactive --guide wizard.
  • Python 3.11+, pure Python (one runtime dep: pyserial), mypy --strict clean.

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bacsys_pymod-0.1.0.tar.gz (8.8 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bacsys_pymod-0.1.0-py3-none-any.whl (54.1 kB view details)

Uploaded Python 3

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

Hashes for bacsys_pymod-0.1.0.tar.gz
Algorithm Hash digest
SHA256 44c221a8ba23e5153d306fd24b7376d12e5fd6ac0561e503c721ee258b53ca52
MD5 2c29597659af71323d2a2381c1388c1d
BLAKE2b-256 98f3ceefa3e9cf3d85460970e63de80ea3238895efc646f59df9409dcde4a222

See more details on using hashes here.

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

Hashes for bacsys_pymod-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f809c41818a6c4324b0ddf18f08f1102b2a8140fe560b1410e4a30564649aef1
MD5 d13cb08f9acb27b032d340dbc0003638
BLAKE2b-256 0760a08f1f6d1f5b05a54d530968ffa2734833a0fee3bfbac691fc06a8457b51

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page