Build a single library of reusable .seq modules (Cylinder, Actuator, Handling) that adapts to monostable or bistable valves, optional feedback sensors, and multi-step command strings across your entire production line.
Each reusable module exposes a standard command/acknowledgment interface to the master coordination sequence:
| Dynamic Variable | Type | Role |
|---|---|---|
{cmd} |
STRING |
Command string sent by the master sequence (for example, "E", "ER", "ODCU1DOUC2") |
{execute} |
BOOL |
Handshake start flag set by the master sequence |
{done} |
BOOL |
Completion flag set by the module when all operations in {cmd} finish |
{error} |
BOOL |
Watchdog timeout flag set if a physical sensor fails to respond in time |
{idx} / {len} |
INT |
Current character index (1..{len}) and total length of {cmd} |
{op} |
STRING |
Current 1-character operation extracted via MID({cmd}, 1, {idx}) |
lib/cylinder.seq and open it in the Sequence Editor.Bistable ValvebistableOFFlib/actuator.seq, create two independent options (fb_on and fb_off) to switch between sensor feedback ({is_on} / {is_off} with a 3000 ms watchdog) and fixed 500 ms timer confirmation.Instead of triggering one movement at a time, a module can execute a sequence of operations encoded in {cmd} (for example, "ER" to extend then retract):
Idle -> NextOp): Select the transition and press A to attach transition actions that initialize the loop:
MOVE: {idx} := 1LEN: {len} := LEN({cmd})NextOp: Add a pulse (P) action with the MID instruction to extract the current operation character:
MID: {op} := MID({cmd}, 1, {idx})NextOp:
{op} == "E" -> Extending{op} == "R" -> RetractingStepDone: Select the loop transition ({idx} < {len} -> NextOp), press A, and attach an ADD transition action ({idx} := {idx} + 1) to advance to the next character. When {idx} >= {len}, transition to Complete and set {done}.Retracting step of Cylinder, add the {retract} action (N qualifier).{retract} action and select Option -> bistable (Present when option is ON).bistable to verify both configurations on the canvas.from automation_machine import Sequence, StepType, ActionQualifier, ActionInstruction
class Cylinder(Sequence):
dynamic = True
def setup(self):
self.declare_option("bistable", "Bistable Valve", "Drive retract solenoid coil", default=False)
s_idle = self.add_step(StepType.INITIAL, name="Idle")
s_next = self.add_step(StepType.NORMAL, name="NextOp")
s_ext = self.add_step(StepType.NORMAL, name="Extending")
s_ret = self.add_step(StepType.NORMAL, name="Retracting")
s_step_done = self.add_step(StepType.NORMAL, name="StepDone")
s_complete = self.add_step(StepType.NORMAL, name="Complete")
s_idle.add_action("{done}", "Reset done", qualifier=ActionQualifier.R)
s_next.add_action("{op}", "Extract command char", qualifier=ActionQualifier.P, instruction=ActionInstruction.MID, src="{cmd}", length="1", pos="{idx}")
s_ext.add_action("{extend}", "Extend coil", qualifier=ActionQualifier.N)
with self.option("bistable"):
s_ret.add_action("{retract}", "Retract coil", qualifier=ActionQualifier.N)
s_complete.add_action("{done}", "Signal done", qualifier=ActionQualifier.S)
s_complete.add_action("{execute}", "Clear execute", qualifier=ActionQualifier.R)
t_start = self.add_transition(s_idle, s_next, condition="{execute}")
t_start.add_action("{idx}", "Init index", instruction=ActionInstruction.MOVE, src="1")
t_start.add_action("{len}", "Command length", instruction=ActionInstruction.LEN, src="{cmd}")
self.add_transition(s_next, s_ext, condition='{op} == "E"')
self.add_transition(s_next, s_ret, condition='{op} == "R"')
self.add_transition(s_ext, s_step_done, condition="{is_extended}")
self.add_transition(s_ret, s_step_done, condition="{is_retracted}")
t_more = self.add_transition(s_step_done, s_next, condition="{idx} < {len}")
t_more.add_action("{idx}", "Next char", instruction=ActionInstruction.ADD, src1="{idx}", src2="1")
self.add_transition(s_step_done, s_complete, condition="{idx} >= {len}")
self.add_transition(s_complete, s_idle, condition="NOT {execute}")
Cylinder()
main.machine -> Instances and add instances of Cylinder (for example, clamp with bistable = OFF, and asm_z with bistable = ON).MOVE: clamp_cmd := "E"R: clamp_doneS: clamp_executeclamp_done in the next transition condition to confirm completion.{variable} placeholders and instancesLEN, MID, CONCAT, and string manipulation