Utilities for AutomationDirect CLICK PLCs: Modbus TCP client/server, address helpers, nickname CSV I/O, and DataView CDV I/O.
Project description
pyclickplc
Utilities for AutomationDirect CLICK PLCs: Modbus TCP client/server, address helpers, nickname CSV I/O, and DataView CDV I/O.
Documentation: https://ssweber.github.io/pyclickplc/ LLM docs index: https://ssweber.github.io/pyclickplc/llms.txt LLM full context: https://ssweber.github.io/pyclickplc/llms-full.txt
Installation
uv add pyclickplc
# or
pip install pyclickplc
Requires Python 3.11+. Modbus client/server functionality depends on pymodbus.
Choose Your Interface
ClickClient: async API for directasyncioapplications.ModbusService: sync + polling API for UI/event-driven applications that do not want to manage an async loop.
Native Python Type Contract
All read/write APIs operate on native Python values.
| Bank family | Python type | Examples |
|---|---|---|
X, Y, C, T, CT, SC |
bool |
True, False |
DS, DD, DH, TD, CTD, SD, XD, YD |
int |
42, 0x1234 |
DF |
float |
3.14 |
TXT |
str |
"A" |
read() methods return ModbusResponse, keyed by canonical normalized addresses ("DS1", "X001"):
- lookups are normalized (
resp["ds1"]resolves"DS1") - single index reads like
await plc.ds[1]return a bare native Python value
Quickstart (ClickClient, async)
import asyncio
from pyclickplc import ClickClient, read_csv
tags = read_csv("nicknames.csv")
async def main():
async with ClickClient("192.168.1.10", 502, tags=tags) as plc:
# Bank accessors
await plc.ds.write(1, 100)
ds1 = await plc.ds[1]
df_values = await plc.df.read(1, 3)
await plc.y.write(1, True)
# String address interface
await plc.addr.write("df1", 3.14)
df1 = await plc.addr.read("DF1")
# Tag interface (case-insensitive)
await plc.tag.write("mytag", 42.0)
tag_value = await plc.tag.read("MyTag")
print(ds1, df_values, df1, tag_value)
asyncio.run(main())
ModbusService (sync + polling)
from pyclickplc import ModbusService, ReconnectConfig
def on_values(values):
print(values) # ModbusResponse keyed by canonical normalized addresses
svc = ModbusService(
poll_interval_s=0.5,
reconnect=ReconnectConfig(delay_s=0.5, max_delay_s=5.0),
on_values=on_values,
)
svc.connect("192.168.1.10", 502, device_id=1, timeout=1)
svc.set_poll_addresses(["DS1", "DF1", "Y1"])
print(svc.read(["DS1", "DF1"]))
print(svc.write({"DS1": 100, "Y1": True, "X1": True})) # X1 is not writable
svc.disconnect()
Error Model
- Validation and address parsing failures raise
ValueError. - Transport/protocol failures raise
OSErrorfor reads. ModbusService.write()returns per-address outcomes (ok+error) instead of raising per-item validation failures.
Addressing Nuances
- Address strings are canonical normalized (
x1->X001,ds1->DS1). X/Yare sparse address families; not every numeric value is valid.XD/YDaccessors are display-indexed (0..8) by default.XD0u/YD0uare explicit upper-byte aliases for advanced use cases.
See the addressing guide for details:
Other Features
- Modbus simulator:
ClickServer,MemoryDataProvider,run_server_tui - CLICK nickname CSV I/O:
read_csv,write_csv,AddressRecordMap - CLICK DataView CDV I/O:
read_cdv,write_cdv,verify_cdv,check_cdv_file
Server docs:
- Guide: https://ssweber.github.io/pyclickplc/guides/server/
- API: https://ssweber.github.io/pyclickplc/reference/api/server/
v0.1 API Stability
pyclickplc v0.1 follows a “stable core, evolving edges” policy.
- Stable core: client/service/server/file I/O/address/validation APIs surfaced in the docs site primary navigation.
- Advanced/evolving: low-level Modbus mapping helpers and bank metadata (
ModbusMapping,plc_to_modbus,BANKS, etc.).
Development
uv sync --all-extras --dev # Install dependencies
make test # Run tests (uv run pytest)
make lint # Lint (codespell, ruff, ty)
make docs-build # Build docs (mkdocs + mkdocstrings)
make docs-serve # Serve docs locally
make # All of the above
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
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 pyclickplc-0.1.0.tar.gz.
File metadata
- Download URL: pyclickplc-0.1.0.tar.gz
- Upload date:
- Size: 122.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e8832a81b92c829e5d0691c9516720af72cef7d8bdd794f785b16a034e4c118d
|
|
| MD5 |
76add8afb4652061d10f5f8dfebe4fe8
|
|
| BLAKE2b-256 |
b5ed003596602158fbc859a03d7b710c9f9be3d35e3a5cadfd0a9906f08c1285
|
Provenance
The following attestation bundles were made for pyclickplc-0.1.0.tar.gz:
Publisher:
publish.yml on ssweber/pyclickplc
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyclickplc-0.1.0.tar.gz -
Subject digest:
e8832a81b92c829e5d0691c9516720af72cef7d8bdd794f785b16a034e4c118d - Sigstore transparency entry: 1003684640
- Sigstore integration time:
-
Permalink:
ssweber/pyclickplc@61c23bf06009b4da79cfb179009c669d72fa1091 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/ssweber
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@61c23bf06009b4da79cfb179009c669d72fa1091 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pyclickplc-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pyclickplc-0.1.0-py3-none-any.whl
- Upload date:
- Size: 49.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
148d20d14b0a512cf610440b21ff49215c2d70471ddcf660b93e5d9407d0d6da
|
|
| MD5 |
004573663fc9aef15c09498ba6b141e9
|
|
| BLAKE2b-256 |
063492814d0c31dcbfa9e3861625cfd0b248249f5ac6d47c2030f09eeea226e8
|
Provenance
The following attestation bundles were made for pyclickplc-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on ssweber/pyclickplc
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyclickplc-0.1.0-py3-none-any.whl -
Subject digest:
148d20d14b0a512cf610440b21ff49215c2d70471ddcf660b93e5d9407d0d6da - Sigstore transparency entry: 1003684644
- Sigstore integration time:
-
Permalink:
ssweber/pyclickplc@61c23bf06009b4da79cfb179009c669d72fa1091 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/ssweber
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@61c23bf06009b4da79cfb179009c669d72fa1091 -
Trigger Event:
release
-
Statement type: