Instruction Set API
Tier: Stable Core
Instruction blocks, conditions, and copy/casting modifiers.
pyrung.out
out(
target: Tag | BlockRange | ImmediateRef,
oneshot: bool = False,
) -> Tag | BlockRange | ImmediateRef
Output coil instruction (OUT).
Sets target to True when rung is true. Resets to False when rung goes false.
Example
with Rung(Button): out(Light) out(Y.select(1, 4))
pyrung.latch
Latch/Set instruction (SET).
Sets target to True. Unlike OUT, does NOT reset when rung goes false. Use reset() to turn off.
Example
with Rung(StartButton): latch(MotorRunning) latch(C.select(1, 8))
pyrung.reset
Reset/Unlatch instruction (RST).
Sets target to its default value (False for bits, 0 for ints).
Example
with Rung(StopButton): reset(MotorRunning) reset(C.select(1, 8))
pyrung.copy
copy(
source: Any,
target: Tag | IndirectRef | IndirectExprRef,
oneshot: bool = False,
) -> Tag | IndirectRef | IndirectExprRef
Copy instruction (CPY/MOV).
Copies source value to target.
Example
with Rung(Button): copy(5, StepNumber)
pyrung.run_function
run_function(
fn: Callable[..., dict[str, Any]],
ins: dict[
str, Tag | IndirectRef | IndirectExprRef | Any
]
| None = None,
outs: dict[str, Tag | IndirectRef | IndirectExprRef]
| None = None,
*,
oneshot: bool = False,
) -> None
Execute a synchronous function when rung power is true.
pyrung.run_enabled_function
run_enabled_function(
fn: Callable[..., dict[str, Any]],
ins: dict[
str, Tag | IndirectRef | IndirectExprRef | Any
]
| None = None,
outs: dict[str, Tag | IndirectRef | IndirectExprRef]
| None = None,
) -> None
Execute a synchronous function every scan with rung enabled state.
pyrung.blockcopy
Block copy instruction.
Copies values from source BlockRange to dest BlockRange. Both ranges must have the same length.
Example
with Rung(CopyEnable): blockcopy(DS.select(1, 10), DD.select(1, 10))
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
Any
|
Source BlockRange or IndirectBlockRange from .select(). |
required |
dest
|
Any
|
Dest BlockRange or IndirectBlockRange from .select(). |
required |
oneshot
|
bool
|
If True, execute only once per rung activation. |
False
|
pyrung.fill
Fill instruction.
Writes a constant value to every element in a BlockRange.
Example
with Rung(ClearEnable): fill(0, DS.select(1, 100))
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
Any
|
Value to write (literal, Tag, or Expression). |
required |
dest
|
Any
|
Dest BlockRange or IndirectBlockRange from .select(). |
required |
oneshot
|
bool
|
If True, execute only once per rung activation. |
False
|
pyrung.pack_bits
Pack BOOL tags from a BlockRange into a register destination.
pyrung.pack_text
pack_text(
source_range: Any,
dest: Any,
*,
allow_whitespace: bool = False,
oneshot: bool = False,
) -> None
Pack Copy text mode: parse a TXT/CHAR range into a numeric destination.
pyrung.pack_words
Pack two 16-bit tags from a BlockRange into a 32-bit destination.
pyrung.unpack_to_bits
Unpack a register source into BOOL tags in a BlockRange.
pyrung.unpack_to_words
Unpack a 32-bit register source into two 16-bit tags in a BlockRange.
pyrung.calc
Calc instruction.
Evaluates an expression and stores the result in dest, with truncation to the destination tag's bit width (modular wrapping).
Key differences from copy(): - Truncates result to destination tag's type width - Division by zero produces 0 (not infinity) - Infers decimal/hex behavior from referenced tag types
Example
with Rung(Enable): calc(DS1 * DS2 + DS3, Result) calc(MaskA & MaskB, MaskResult)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
expression
|
Any
|
Expression, Tag, or literal to evaluate. |
required |
dest
|
Tag
|
Destination tag (type determines truncation width). |
required |
oneshot
|
bool
|
If True, execute only once per rung activation. |
False
|
Returns:
| Type | Description |
|---|---|
Tag
|
The dest tag. |
pyrung.call
Call a subroutine instruction.
Executes the named subroutine when the rung is true. Accepts either a string name or a @subroutine-decorated function.
Example
with Rung(Button): call("init_sequence")
with subroutine("init_sequence"): with Rung(): out(Light)
Or with decorator:
@subroutine("init") def init_sequence(): with Rung(): out(Light)
with Program() as logic: with Rung(Button): call(init_sequence)
pyrung.return_early
Return from the current subroutine.
Example
with subroutine("my_sub"): with Rung(Abort): return_early()
pyrung.count_up
Count Up instruction (CTU) - Click-style.
Creates a counter that increments every scan while the rung condition is True.
Use rise() on the condition for edge-triggered counting.
Example
with Rung(rise(PartSensor)): count_up(done_bit, acc, preset=100).reset(ResetBtn)
This is a terminal instruction. Requires .reset() chaining.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
done_bit
|
Tag
|
Tag to set when accumulator >= preset. |
required |
accumulator
|
Tag
|
Tag to increment while rung condition is True. |
required |
preset
|
Tag | int
|
Target value (Tag or int). |
required |
Returns:
| Type | Description |
|---|---|
CountUpBuilder
|
Builder for chaining .down() and .reset(). |
pyrung.count_down
Count Down instruction (CTD) - Click-style.
Creates a counter that decrements every scan while the rung condition is True.
Use rise() on the condition for edge-triggered counting.
Example
with Rung(rise(Dispense)): count_down(done_bit, acc, preset=25).reset(Reload)
This is a terminal instruction. Requires .reset() chaining.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
done_bit
|
Tag
|
Tag to set when accumulator <= -preset. |
required |
accumulator
|
Tag
|
Tag to decrement while rung condition is True. |
required |
preset
|
Tag | int
|
Target value (Tag or int). |
required |
Returns:
| Type | Description |
|---|---|
CountDownBuilder
|
Builder for chaining .reset(). |
pyrung.event_drum
event_drum(
*,
outputs: Sequence[Tag],
events: Sequence[Condition | Tag],
pattern: Sequence[Sequence[bool | int]],
current_step: Tag,
completion_flag: Tag,
) -> EventDrumBuilder
pyrung.search
search(
condition: str,
value: Any,
search_range: BlockRange | IndirectBlockRange,
result: Tag,
found: Tag,
continuous: bool = False,
oneshot: bool = False,
) -> Tag
Search instruction.
Scans a selected range and writes the first matching address into result.
Writes found True on hit; on miss writes result=-1 and found=False.
pyrung.shift
Shift register instruction builder.
Data input comes from current rung power. Use .clock(...) then .reset(...) to finalize and add the instruction.
Example
with Rung(DataBit): shift(C.select(2, 7)).clock(ClockBit).reset(ResetBit)
pyrung.on_delay
on_delay(
done_bit: Tag,
accumulator: Tag,
*,
preset: Tag | int,
unit: TimeUnit = TimeUnit.Tms,
) -> OnDelayBuilder
On-Delay Timer instruction (TON/RTON) - Click-style.
Accumulates time while rung is true.
Example
with Rung(MotorRunning): on_delay(done_bit, acc, preset=5000) # TON on_delay(done_bit, acc, preset=5000).reset(ResetBtn) # RTON
Without .reset(), this is TON and remains composable in-rung. With .reset(), this is RTON and becomes terminal in the current flow.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
done_bit
|
Tag
|
Tag to set when accumulator >= preset. |
required |
accumulator
|
Tag
|
Tag to increment while enabled. |
required |
preset
|
Tag | int
|
Target value in time units (Tag or int). |
required |
unit
|
TimeUnit
|
Time unit for accumulator (default: Tms). |
Tms
|
Returns:
| Type | Description |
|---|---|
OnDelayBuilder
|
Builder for optional .reset() chaining. |
pyrung.off_delay
off_delay(
done_bit: Tag,
accumulator: Tag,
*,
preset: Tag | int,
unit: TimeUnit = TimeUnit.Tms,
) -> OffDelayBuilder
Off-Delay Timer instruction (TOF) - Click-style.
Done bit is True while enabled. After disable, counts until preset, then done bit goes False. Auto-resets when re-enabled.
Example
with Rung(MotorCommand): off_delay(done_bit, acc, preset=10000)
Off-delay timers are composable in-rung (not terminal).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
done_bit
|
Tag
|
Tag that stays True for preset time after rung goes false. |
required |
accumulator
|
Tag
|
Tag to increment while disabled. |
required |
preset
|
Tag | int
|
Delay time in time units (Tag or int). |
required |
unit
|
TimeUnit
|
Time unit for accumulator (default: Tms). |
Tms
|
Returns:
| Type | Description |
|---|---|
OffDelayBuilder
|
Builder for the off_delay instruction. |
pyrung.time_drum
time_drum(
*,
outputs: Sequence[Tag],
presets: Sequence[Tag | int],
unit: TimeUnit = TimeUnit.Tms,
pattern: Sequence[Sequence[bool | int]],
current_step: Tag,
accumulator: Tag,
completion_flag: Tag,
) -> TimeDrumBuilder
pyrung.rise
Rising edge contact (RE).
True only on 0->1 transition. Requires PLCRunner to track previous values.
Example
with Rung(rise(Button)): latch(MotorRunning) # Latches on button press, not while held
pyrung.fall
Falling edge contact (FE).
True only on 1->0 transition. Requires PLCRunner to track previous values.
Example
with Rung(fall(Button)): reset(MotorRunning) # Resets when button is released
pyrung.all_of
all_of(
*conditions: Condition
| Tag
| ImmediateRef
| tuple[Condition | Tag | ImmediateRef, ...]
| list[Condition | Tag | ImmediateRef],
) -> AllCondition
AND condition - true when all sub-conditions are true.
This is equivalent to comma-separated rung conditions, but useful when building
grouped condition trees with any_of() or &.
Example
with Rung(all_of(Ready, AutoMode)): out(StartPermissive)
Equivalent operator form:
with Rung((Ready & AutoMode) | RemoteStart): out(StartPermissive)
pyrung.any_of
OR condition - true when any sub-condition is true.
Use this to combine multiple conditions with OR logic within a rung. Multiple conditions passed directly to Rung() are ANDed together.
Example
with Rung(Step == 1, any_of(Start, CmdStart)): out(Light) # True if Step==1 AND (Start OR CmdStart)
Also works with | operator:
with Rung(Step == 1, Start | CmdStart): out(Light)
Grouped AND inside OR (explicit):
with Rung(any_of(Start, all_of(AutoMode, Ready), RemoteStart)): out(Light)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conditions
|
Condition | Tag | ImmediateRef
|
Conditions to OR together. |
()
|
Returns:
| Type | Description |
|---|---|
AnyCondition
|
AnyCondition that evaluates True if any sub-condition is True. |
pyrung.immediate
Wrap a tag or block range as an immediate operand.