Flow Action
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.
Overview
Section titled “Overview”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.
Requirements
Section titled “Requirements”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.
Input/Output
Section titled “Input/Output”Inputs
Section titled “Inputs”- 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.
Outputs
Section titled “Outputs”- Pass-through CHOP output (the input CHOP is passed through unchanged).
Usage Examples
Section titled “Usage Examples”Triggering Next Step on a button press
Section titled “Triggering Next Step on a button press”- Wire a button or momentary CHOP signal into the Flow Action input.
- On the Action page, set Do to
Next Step. - Set On to
Off→Onso the trigger fires only on the rising edge. - Leave During as
*to allow triggering from any step. - Pulse Refresh Steps to populate the step menus from the connected FlowController.
- When the CHOP signal rises from 0 to 1, Flow Action calls NextStep on the FlowController.
Jumping to a specific step
Section titled “Jumping to a specific step”- Set Do to
Go To Step. - Set To to the step name you want to jump to (populated after pulsing Refresh Steps).
- Set On to your preferred edge mode.
- Trigger fires and calls GoToStep on the FlowController.
Triggering only during a specific step
Section titled “Triggering only during a specific step”- Set Do to
Next Step(or any action). - Set During to the step name this trigger should be active for.
- 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.
Adding a guard condition
Section titled “Adding a guard condition”- In the Only If Python parameter, enter any expression that evaluates to
TrueorFalse. - Examples:
op('sensor1')['active'][0] == 1orparent().par.Mystate.eval() == 'ready' - 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”- On the Advanced page, set Target to
Context. - Enter a Key name for the context value (e.g.
recording_path). - In Value, write any Python expression that returns the data — for example
op('file_picker1').par.File.eval(). - Set When to
Before ActionorAfter Actiondepending on whether the FlowController should receive the data before or after the step transition. - When triggered, Flow Action calls
fc.Set(key, value)at the chosen timing, then fires the configured action.
Using Decision mode for branching logic
Section titled “Using Decision mode for branching logic”- Set Do to
Decision. - On the Decision page, add one or more route rows using the sequence control.
- For each route, enter a Python expression in If that evaluates to
Truewhen that branch should fire. - Set Do for the route to
pulse,setvalue, or leave asnothing. - If Do is
pulseorsetvalue, fill in Op with the target operator reference and Par with the parameter name string. - Set Then Go To for the route:
Stayexecutes the action without transitioning,Next Routecontinues evaluating subsequent routes,Next Stepadvances the flow, or select a named step to jump directly. - Routes are evaluated top to bottom. The first route whose If expression is true and whose Then Go To is not
Next Routedetermines the final outcome.
Triggering on flow step entry
Section titled “Triggering on flow step entry”- Set On to
Step Enter. - Set During to the step name you want to react to entering.
- 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.
Best Practices
Section titled “Best Practices”- 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 Enteredge mode instead of CHOP-based triggers when you want to react purely to flow state changes, not external signals.
Troubleshooting
Section titled “Troubleshooting”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.
Parameters
Section titled “Parameters”Action
Section titled “Action”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}'
op('flow_action').par.Refresh Pulse Refresh step menus from FlowController
- Default:
False
op('flow_action').par.Trigger Pulse - Default:
False
op('flow_action').par.Guard Python Guard expression - trigger only fires if this evaluates to True
- Default:
"" (Empty String)
Decision
Section titled “Decision”op('flow_action').par.Route Sequence - Default:
0
op('flow_action').par.Route0if Python - Default:
"" (Empty String)
op('flow_action').par.Route0op OP - Default:
"" (Empty String)
op('flow_action').par.Route0par Str - Default:
"" (Empty String)
op('flow_action').par.Route0val Str - Default:
"" (Empty String)
Advanced
Section titled “Advanced”op('flow_action').par.Outputkey Str Context key name (only used when Target=Context)
- Default:
"" (Empty String)
op('flow_action').par.Outputvalue Python Value to send - supports expressions: 'hello', op('chop1')['chan1'], op('dat1').text
- Default:
"" (Empty String)
op('flow_action').par.Targetcomp OP Only set if FlowAction is outside the target component
- Default:
"" (Empty String)
Changelog
Section titled “Changelog”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