Skip to content

Commit e47c658

Browse files
committed
chore: rename 'Rung' -> 'rung' cause it's less distracting
1 parent ce4c40f commit e47c658

4 files changed

Lines changed: 11 additions & 11 deletions

File tree

docs/blog/complexity-was-never-in-the-logic.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,20 @@ I wrote [ClickNick](https://github.com/ssweber/clicknick) to help with the addre
1010

1111
The logic itself was never complex. Each subroutine is basically a one-page function. But the editor makes it feel enormous. You can't see more than a few rungs at a time, search and replace exist but they're clunky, there's no diff, no way to look at the whole program at once. The bottleneck was always the editor. This [isn't unique to Click](https://blog.jonasneubert.com/2019/10/29/ladder-logic/), either.
1212

13-
I wanted one source of truth. So I turned the cheatsheet into [pyrung](https://ssweber.github.io/pyrung/), a Python library where `with Rung(Start): latch(Motor)` maps directly to a ladder rung. The scan cycle runs for real, timers accumulate, rung order matters. You test with pytest, step through scans in VS Code.
13+
I wanted one source of truth. So I turned the cheatsheet into [pyrung](https://ssweber.github.io/pyrung/), a Python library where `with rung(Start): latch(Motor)` maps directly to a ladder rung. The scan cycle runs for real, timers accumulate, rung order matters. You test with pytest, step through scans in VS Code.
1414

1515
Three rungs that copy a command value based on a state. In pyrung, that's six lines:
1616

1717
```python
18-
with Rung(Cmd_State_Reset):
18+
with rung(Cmd_State_Reset):
1919
copy(1, Cmd_CtrlCmd)
2020
copy(1, Cmd_CmdChgRequestBool)
2121

22-
with Rung(Cmd_State_Start):
22+
with rung(Cmd_State_Start):
2323
copy(2, Cmd_CtrlCmd)
2424
copy(1, Cmd_CmdChgRequestBool)
2525

26-
with Rung(Cmd_State_Stop):
26+
with rung(Cmd_State_Stop):
2727
copy(3, Cmd_CtrlCmd)
2828
copy(1, Cmd_CmdChgRequestBool)
2929
```

docs/blog/these-arent-the-rungs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
### How I reverse-engineered a PLC editor's clipboard format so my bytes could paste without any problems
44

5-
Ladder logic is the visual programming language for industrial controllers, rungs on a rail, each one a circuit that evaluates left to right: `|—[ Contact ]—( Output )|`. For years I haven't been able to test my CLICK PLC programs. I've got dozens of machines whose logic is stuck in an editor with no simulator, no scripting API, and no documented file format. So I built [pyrung](https://ssweber.github.io/pyrung/), a Python DSL where `with Rung(condition): instruction` maps directly to a ladder rung, meaning you can write logic in Python and test it with pytest.
5+
Ladder logic is the visual programming language for industrial controllers, rungs on a rail, each one a circuit that evaluates left to right: `|—[ Contact ]—( Output )|`. For years I haven't been able to test my CLICK PLC programs. I've got dozens of machines whose logic is stuck in an editor with no simulator, no scripting API, and no documented file format. So I built [pyrung](https://ssweber.github.io/pyrung/), a Python DSL where `with rung(condition): instruction` maps directly to a ladder rung, meaning you can write logic in Python and test it with pytest.
66

77
But I don't want to transpose after testing. The missing piece was getting rungs from Python into the CLICK editor without retyping them. There's no documented import format, but I found it does put ctrl-c rungs onto the clipboard in some binary format. Maybe I could figure it out. With an AI that could hold context across hex dumps and structural hypotheses, I decided to give it a go.
88

docs/blog/why-pyrung.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ SOR BST GRT Temp 100 NXB GRT Pressure 50 BND OTE Alarm EOR
4040

4141
**pyladdersim** (flat list):
4242
```python
43-
rung = Rung([Contact("Start"), InvertedContact("Stop"), Output("Lamp")])
43+
rung = rung([Contact("Start"), InvertedContact("Stop"), Output("Lamp")])
4444
```
4545

4646
The structure that makes ladder readable is lost in all of these. The idea of a proper text-based ladder with testability has been [floating around since at least 2000](https://mail.python.org/pipermail/python-list/2000-March/049350.html), but nobody shipped it. A CODESYS Forge user [asked for ladder scripting in Python in 2017](https://forge.codesys.com/forge/talk/Engineering/thread/fdc3d03c95/); the answer was "You can't do Ladder with Scripting."
@@ -50,10 +50,10 @@ The structure that makes ladder readable is lost in all of these. The idea of a
5050
The same two examples:
5151

5252
```python
53-
with Rung(Start | Motor, ~Stop):
53+
with rung(Start | Motor, ~Stop):
5454
out(Motor)
5555

56-
with Rung(any_of(Temp > 100, Pressure > 50)):
56+
with rung(any_of(Temp > 100, Pressure > 50)):
5757
latch(Alarm)
5858
```
5959

docs/index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,10 @@
9090
<div class="pl-block">
9191
<div><span class="pl-kw">with</span> <span class="pl-cls">Program</span>() <span class="pl-kw">as</span> logic:</div>
9292
<div class="pl-blank"></div>
93-
<div id="r1c"> <span class="pl-kw">with</span> <span class="pl-cls">Rung</span>(Start<span class="pl-op">,</span> <span class="pl-op">~</span>Stop):<span class="pl-anno" id="a1c">True</span></div>
93+
<div id="r1c"> <span class="pl-kw">with</span> <span class="pl-cls">rung</span>(Start<span class="pl-op">,</span> <span class="pl-op">~</span>Stop):<span class="pl-anno" id="a1c">True</span></div>
9494
<div id="r1b"> <span class="pl-fn">latch</span>(Motor)<span class="pl-anno" id="a1b">Motor ← True</span></div>
9595
<div class="pl-blank"></div>
96-
<div id="r2c"> <span class="pl-kw">with</span> <span class="pl-cls">Rung</span>(Stop):<span class="pl-anno" id="a2c">False</span></div>
96+
<div id="r2c"> <span class="pl-kw">with</span> <span class="pl-cls">rung</span>(Stop):<span class="pl-anno" id="a2c">False</span></div>
9797
<div id="r2b"> <span class="pl-fn">reset</span>(Motor)<span class="pl-anno" id="a2b">skipped</span></div>
9898
</div>
9999

@@ -150,7 +150,7 @@
150150
})();
151151
</script>
152152

153-
That's ladder logic. Condition on the `Rung`, instruction in the body. It reads like the diagram, runs as a deterministic scan cycle, tests with pytest, and compiles to real hardware.
153+
That's ladder logic. Condition on the `rung`, instruction in the body. It reads like the diagram, runs as a deterministic scan cycle, tests with pytest, and compiles to real hardware.
154154

155155
Ladder logic dominates North American discrete manufacturing, but the tooling hasn't kept up. No version control, no automated testing, no way to simulate without hardware. The Structured Text crowd has options. The ladder crowd doesn't.
156156

0 commit comments

Comments
 (0)