Skip to main content

Write ladder logic in Python. Simulate it. Test it. Deploy it -- Currently targets AutomationDirect CLICK PLC and CircuitPython ProductivityOpen P1AM-200.

Project description

pyrung

Ladder logic in Python that reads like ladder, scans like a PLC, and deploys to real hardware.

pyrung turns Python's with block into a ladder rung — condition on the rail, instructions in the body.

from pyrung import Bool, PLCRunner, Program, Rung, out

Button = Bool("Button")
Light = Bool("Light")

with Program() as logic:
    with Rung(Button):
        out(Light)

runner = PLCRunner(logic)
with runner.active():
    Button.value = True
    runner.step()
    assert Light.value is True

Why?

Ladder is still the dominant programming language in North American manufacturing, but ladder programmers have no git, no pytest, no CI. They draw logic in a vendor GUI, download to hardware, and hope. pyrung lets you write and test logic in Python first, then deploy it — same source, three paths:

  • pyrung_to_ladder() encodes your rungs for ClickNick, a companion editor for Click Programming Software
  • Generate a self-contained CircuitPython scan loop for a P1AM-200
  • Run as an emulated Click over Modbus — spin up two pyrung programs and test them talking to each other, no hardware required

The code reads like a ladder diagram. with Rung(Start | Motor, ~Stop): out(Motor) is a seal-in circuit, and it looks like one. There's no if/else. Power flows through the rung or it doesn't. The scan cycle is deterministic, timers accumulate the same way, rung order matters the same way. What you learn in pyrung transfers directly to a real ladder editor.

Who's this for?

Controls engineers who want to test Click PLC logic without hardware. The Click dialect handles address mapping, memory bank validation, and nickname and ladder file export. Have an existing project? ClickNick imports it.

Python developers entering industrial automation. pyrung teaches you ladder logic in the language and tools you already have. The VS Code debugger lets you step through scans and watch power flow rung by rung. Start with the learning guide.

Makers and P1AM-200 users who want a real scan loop without writing the plumbing. The CircuitPython dialect generates a complete program from the same logic you write and test on your laptop.

Quick start

# Requires Python 3.11+
uv add pyrung

A motor with start/stop logic

from pyrung import Bool, Program, Rung, latch, reset

Start = Bool("Start")
Stop = Bool("Stop")
Running = Bool("Running")

with Program() as logic:
    with Rung(Start):
        latch(Running)
    with Rung(Stop):
        reset(Running)

Test it

from pyrung import PLCRunner

runner = PLCRunner(logic)
with runner.active():
    Start.value = True
    runner.step()
    assert Running.value is True

    # Release start — motor stays latched
    Start.value = False
    runner.step()
    assert Running.value is True

    Stop.value = True
    runner.step()
    assert Running.value is False

Map to Click hardware when you're ready

from pyrung.click import TagMap, x, y

mapping = TagMap({
    Start:   x[1],    # Physical input  → X001
    Stop:    x[2],    # Physical input  → X002
    Running: y[1],    # Physical output → Y001
})

mapping.validate(logic)                # Checks against Click constraints
mapping.to_nickname_file("motor.csv")  # For Click programming software

What's included

Core engine

Coils, latches, timers, counters, branching, subroutines, structured tags, and edge detection. Every scan is a pure function — same inputs, same outputs — so you can fork, rewind, and diff any state in history.

Click PLC dialect

Hardware address mapping, memory bank validation, Modbus instructions, and nickname and ladder file export.

CircuitPython dialect

Generate a self-contained scan loop for the P1AM-200 with 35 supported I/O modules, SD-backed retentive storage, watchdog, and Modbus TCP.

VS Code debugger

Step through scans rung by rung, set breakpoints, force tags, diff states, and time-travel through scan history.

Disclaimers

  • Simulation is best-effort. pyrung models Click PLC behavior as closely as practical, but it is not a certified simulator. You are responsible for verifying your program on real hardware before production use.
  • Modbus is unauthenticated. The emulated Click Modbus interface and CircuitPython Modbus TCP server listen on the network with no encryption or access control — standard for Modbus, but keep them off untrusted networks.

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

pyrung-0.3.1.tar.gz (1.6 MB view details)

Uploaded Source

Built Distribution

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

pyrung-0.3.1-py3-none-any.whl (347.8 kB view details)

Uploaded Python 3

File details

Details for the file pyrung-0.3.1.tar.gz.

File metadata

  • Download URL: pyrung-0.3.1.tar.gz
  • Upload date:
  • Size: 1.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pyrung-0.3.1.tar.gz
Algorithm Hash digest
SHA256 5e1ca9bd22ec65307a7ac0a2141862ad6dd224d64682c531ad57ff0f3656f48c
MD5 afa5a4e3f389622883c8a9842fcb33a9
BLAKE2b-256 030b32c5ef597e7f9c390a86b16c1efbe3fcbca58b9b8cf4b288ac6174a043bb

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyrung-0.3.1.tar.gz:

Publisher: publish.yml on ssweber/pyrung

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyrung-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: pyrung-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 347.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pyrung-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3dcdc51ef78c7a92e4751d6fdae3cc06a33f9c434fcca07cab2e37c66049ad58
MD5 7556aba5a02a60ff9bdaea0bae15cc8b
BLAKE2b-256 c44d6ff0fd3e27a8f328158533cd20105000bdc42bb571c147d523ee3aba9874

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyrung-0.3.1-py3-none-any.whl:

Publisher: publish.yml on ssweber/pyrung

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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