Skip to content

Flow Action

v0.1.0New

Flow Action connects a CHOP signal to a FlowController and fires step-transition commands whenever that signal crosses a configured threshold. You wire any CHOP into the input, choose which channel to watch, pick the edge type that should trigger, and select what the FlowController should do. Multiple Flow Action operators can coexist inside the same component, each watching a different signal and targeting a different step transition.

When the monitored CHOP channel crosses the selected edge condition — rising, falling, both edges, while high, or on any value change — Flow Action calls the matching FlowController method. Before firing, it can optionally check whether the flow is on a particular step (the During filter) and evaluate a Python guard expression. On trigger, it can also inject data into the FlowController’s context, send an update, or pass a result to Finish, all configurable from the Advanced page.

The Decision action extends this with a branching sequence: each route evaluates a condition and, when matched, can pulse a parameter, set a value on any operator, and then route to a named step, the next step, or end the flow.

Flow Action must be placed inside a component that has a flow_controller operator registered as iop.LOPflow. If the operator lives outside that component, point the Target Component parameter on the Advanced page to the correct component and the operator will resolve iop.LOPflow from there instead.

  • in1: Any CHOP. The Channel (in1) parameter lets you select which channel within that CHOP to monitor. Leave it blank or use * to monitor all channels.
  • Pass-through CHOP output (the input CHOP is passed through unchanged).
  1. Wire a button or momentary CHOP signal into the Flow Action input.
  2. On the Action page, set Do to Next Step.
  3. Set On to Off→On so the trigger fires only on the rising edge.
  4. Leave During as * to allow triggering from any step.
  5. Pulse Refresh Steps to populate the step menus from the connected FlowController.
  6. When the CHOP signal rises from 0 to 1, Flow Action calls NextStep on the FlowController.
  1. Set Do to Go To Step.
  2. Set To to the step name you want to jump to (populated after pulsing Refresh Steps).
  3. Set On to your preferred edge mode.
  4. Trigger fires and calls GoToStep on the FlowController.
  1. Set Do to Next Step (or any action).
  2. Set During to the step name this trigger should be active for.
  3. When the CHOP edge fires, Flow Action checks the FlowController’s current step first. If it does not match During, the trigger is silently skipped.
  1. In the Only If Python parameter, enter any expression that evaluates to True or False.
  2. Examples: op('sensor1')['active'][0] == 1 or parent().par.Mystate.eval() == 'ready'
  3. If the expression returns False (or raises an error), the trigger is skipped. Guard errors fail closed — a broken expression always prevents triggering.

Injecting data alongside a step transition

Section titled “Injecting data alongside a step transition”
  1. On the Advanced page, set Target to Context.
  2. Enter a Key name for the context value (e.g. recording_path).
  3. In Value, write any Python expression that returns the data — for example op('file_picker1').par.File.eval().
  4. Set When to Before Action or After Action depending on whether the FlowController should receive the data before or after the step transition.
  5. When triggered, Flow Action calls fc.Set(key, value) at the chosen timing, then fires the configured action.
  1. Set Do to Decision.
  2. On the Decision page, add one or more route rows using the sequence control.
  3. For each route, enter a Python expression in If that evaluates to True when that branch should fire.
  4. Set Do for the route to pulse, setvalue, or leave as nothing.
  5. If Do is pulse or setvalue, fill in Op with the target operator reference and Par with the parameter name string.
  6. Set Then Go To for the route: Stay executes the action without transitioning, Next Route continues evaluating subsequent routes, Next Step advances the flow, or select a named step to jump directly.
  7. Routes are evaluated top to bottom. The first route whose If expression is true and whose Then Go To is not Next Route determines the final outcome.
  1. Set On to Step Enter.
  2. Set During to the step name you want to react to entering.
  3. When the FlowController moves to that step, Flow Action fires automatically — no CHOP edge needed. The internal Script CHOP watches step transitions and calls the trigger once per step entry.
  • Pulse Refresh Steps any time you add or rename steps in the FlowController. The To, During, and Decision route destination menus are all populated from this refresh.
  • Use During filters liberally. Scoping each Flow Action to the step it belongs to prevents accidental triggers from stale CHOP signals between steps.
  • Keep Only If expressions simple and side-effect-free. The guard runs on every CHOP edge event, so heavy computation here will cook every frame when the signal is active.
  • Place Flow Action operators inside the same component as the FlowController when possible. The Target Component override on the Advanced page adds a level of indirection that is harder to trace during debugging.
  • Use Step Enter edge mode instead of CHOP-based triggers when you want to react purely to flow state changes, not external signals.

Status field shows “No iop.LOPflow found” Flow Action could not locate a FlowController. Confirm that a flow_controller operator is present and registered as iop.LOPflow within the same component, or set Target Component on the Advanced page to the component containing the FlowController. Pulse Refresh Steps after correcting the connection.

Action is silently skipped (“flow is not running”) Most actions (Next Step, Go To Step, Update, Finish, Wait For Continue, Decision) require the flow to be in a running state. Start Flow is the only action that works when the flow is idle. Use a separate Flow Action set to Start Flow to begin the flow before other actions become active.

“Start skipped: flow is already running” Start Flow only fires when the flow is not yet running. If you need to restart a flow, finish it first with a Finish action before triggering Start again.

Decision: “No route matched or all routes used Next Route” All route conditions returned False, or every matched route had Then Go To set to Next Route with no final destination route. Add a catch-all final route with an If of True to guarantee at least one route always resolves.

Guard expression error → trigger not firing Guard errors fail closed. Open the operator’s Logger to see the exception. Verify the expression syntax, that all referenced operators exist, and that the expression returns a boolean-compatible value.

Step menus show “(no controller)” or “(no steps)” The FlowController has no steps defined yet, or the connection was not resolved at init time. Define steps in the FlowController and pulse Refresh Steps.

Status (Status) op('flow_action').par.Status Str

Connection status to FlowController

Default:
op('./Logger/logs')[1,2] if op('./Logger/logs')[1,2] else f'{me.name}'
Refresh Steps (Refresh) op('flow_action').par.Refresh Pulse

Refresh step menus from FlowController

Default:
False
Action Header
Do (Action) op('flow_action').par.Action Menu

What action to perform when triggered

Default:
start
Options:
start, nextstep, gotostep, finish, waitforcontinue, decision, update
To (Goto) op('flow_action').par.Goto Menu
Default:
init
Options:
init, recording, done, end
Trigger Header
Trigger (Trigger) op('flow_action').par.Trigger Pulse
Default:
False
On (Edge) op('flow_action').par.Edge Menu

When to trigger based on CHOP signal. 'Step Enter' triggers when flow enters the step specified in 'During'.

Default:
offToOn
Options:
offToOn, onToOff, both, whileOn, valueChange, stepEnter
Channel (in1) (Channel) op('flow_action').par.Channel StrMenu

Select which CHOP channel to monitor

Default:
"" (Empty String)
Menu Options:
  • * (*)
During (Duringstep) op('flow_action').par.Duringstep Menu

Only trigger when flow is on this step

Default:
*
Options:
*, init, recording, done, end
Only If (Guard) op('flow_action').par.Guard Python

Guard expression - trigger only fires if this evaluates to True

Default:
"" (Empty String)
(Route) op('flow_action').par.Route Sequence
Default:
0
If (Route0if) op('flow_action').par.Route0if Python
Default:
"" (Empty String)
Do (Route0do) op('flow_action').par.Route0do Menu
Default:
nothing
Options:
nothing, update, pulse, setvalue
Op (Route0op) op('flow_action').par.Route0op OP
Default:
"" (Empty String)
Par (Route0par) op('flow_action').par.Route0par Str
Default:
"" (Empty String)
Val (Route0val) op('flow_action').par.Route0val Str
Default:
"" (Empty String)
Then Go To2 (Route0goto) op('flow_action').par.Route0goto Menu
Default:
stay
Options:
stay, nextroute, nextstep, init, recording, done, end, end
Data Output Header
Target (Outputtarget) op('flow_action').par.Outputtarget Menu

Where to send data: Context (fc.Set), Update (fc.SendUpdate), Result (fc.Finish)

Default:
none
Options:
none, context, update, result
Key (Outputkey) op('flow_action').par.Outputkey Str

Context key name (only used when Target=Context)

Default:
"" (Empty String)
Value (Outputvalue) op('flow_action').par.Outputvalue Python

Value to send - supports expressions: 'hello', op('chop1')['chan1'], op('dat1').text

Default:
"" (Empty String)
Result Type (Outputresulttype) op('flow_action').par.Outputresulttype Menu

Status type for Update and Result targets

Default:
success
Options:
success, warning, error
When (Outputwhen) op('flow_action').par.Outputwhen Menu

Timing of data output relative to the main action (not used for Result)

Default:
before
Options:
before, after
Controller Header
Target Component (Targetcomp) op('flow_action').par.Targetcomp OP

Only set if FlowAction is outside the target component

Default:
"" (Empty String)
v0.1.02026-03-12
  • Replace data injection with output target system (Context/Update/Result with before/after timing) - Add Step Enter edge mode with reactive scriptCHOP dependency tracking - Add Stay goto option for executing actions without step transition - Route actions use OP + parameter name references instead of eval'd expressions - Guard expression context uses relative op() from FlowAction parent
  • Rename flow_trigger to flow_action - Update manifest name and repository fields - Update README title and documentation URL
  • Pass source (operator path) on all FlowController calls - Source enables audit trail via FlowState observer
  • Changed parameter page name from Trigger to Action - Added Start Flow action to Action menu - Added Finish Flow action to Action menu - Added Decision mode to Action menu - Changed During step menu label from (any) to * - Hid Status parameter label (set to empty string) - Replaced all par.Status assignments with logger.log calls - Added _refresh_route_menus helper method for Decision mode route menus - Added flow running status checks before executing all actions except start - Changed trigger UI pulse to only fire after successful action execution - Added early returns for actions when flow is not running - Added Decision mode implementation with route sequence evaluation - Added _execute_decision method for evaluating routes and executing actions - Added _execute_route_action method for pulse, setvalue, and sendupdate actions - Fixed GoToStep to return early if no target step selected - Fixed log message formatting (removed unnecessary f-strings)
  • Add extends field to manifest
  • Update README with proper description and structure - Fix manifest.json description and category
  • Initial commit