--- alias: user-guide-automation-controller-workflow-custom render_macros: false tags: - connect iot description: "This documentation outlines two workflow editors for automation tasks and their respective uses" --- # Create a Workflow There are two different workflow editors available: `Data Flow` and `Control Flow`. The `Data Flow` is based on information linkage, it allows visibility and transparency on linking information throughout the execution. The `Data Flow` does not require one deterministic start and finish. It allows for one action to perform multiple parallel actions. The `Control Flow` is based on a more programmatic approach and enforces that a workflow has a start and finish. It is also more focused on actions than one data transmission. Both editors serve to tackle different issues. If there is a high volume of data transmission, `Control Flow` should be used since it is deterministic and insulated from concurrency issues. If the workflow is data driven with data transformations, `Data Flow` brings more transparency. ## Workflow Types This page group gives the user an overview of the operations pertaining to Automation: * [[user-guide-automation-controller-workflow-custom-dataflow]] * [[user-guide-automation-controller-workflow-custom-controlflow]] ## Choosing the Designer Both designers run the same tasks on the same engine. They differ in how long a task instance lives and in how a value reaches an input: * In Data Flow, each task is one instance for the life of the workflow. A link carries each value, and a value that arrives on an input replaces the previous one. * In Control Flow, each occurrence of a trigger runs its own branch, and a task reads earlier results through expressions in its input rows, such as `{{ $onNewFile.FileName }}`. Ask the following questions in order. The first question that applies decides the designer: 1. Can the event that starts the workflow occur more often than about every 100 milliseconds, or can one occurrence start before the previous one ends? Use Control Flow. In Data Flow, the values of overlapping occurrences overwrite each other in the single instance of each task. This applies to triggers such as **On Equipment Event**, **Driver Event**, **Message Bus Listener**, and **On Timer**. 2. Does the work branch, loop, end early, or catch failures? Use Control Flow. **Condition**, **For**, **Foreach**, **Break**, **Return**, **Define Function**, **Throw Error**, and **Try..Catch** exist only in Control Flow. 3. Must the work run once for each item of a list or of a file? Use a **Foreach** in Control Flow. In Data Flow, values emitted on one output in the same moment reach the next task once, with the last value. 4. Must several values be merged, or must a task wait until several values are present? Use Data Flow. **Synchronize**, **Merge Object**, **Merge Array**, and **Switch** exist only in Data Flow. When values from two triggers must meet, in either designer, store one with **Store Data** and retrieve it with **Retrieve Data** when the other trigger fires. 5. Must the workflow switch a trigger on or off, or set the inputs of a trigger at run time? Use Data Flow, where a link into `Activate` or into an input of the trigger does this. In Control Flow, a trigger starts its branch, so no task reaches it. 6. When none of the questions decides: use Data Flow when people must see how data moves, for review or handover, and use Control Flow when the Data Flow canvas has grown too large to read. The tutorials [[tutorials-connectiot-how-values-travel]] and [[tutorials-connectiot-control-flow-in-depth]] show these differences on a running workflow. ### Calling Across Designers A workflow that needs a task of the other designer calls a workflow built in that designer: * From Data Flow, to branch, loop, or handle errors, call a Control Flow function, defined with [[user-guide-automation-task-core-function]], through [[user-guide-automation-task-core-callfunction]]. Call it once per occurrence, for example from the `Success` of a trigger: values that reach a Data Flow **Call Function** in the same moment merge into one call. Give each function a name that is unique in the controller. * From Control Flow, to merge or synchronize values, call a Data Flow sub-workflow, which starts with a **Workflow Start** and ends with a **Workflow End**, through the [[user-guide-automation-task-core-workflow]] task. Each call runs in an execution context of its own. ### Converting a Workflow to the Other Designer Moving a workflow to the other designer is a rewrite, not a translation: * A link from `Success` into `Activate` becomes the order of the tasks in a branch, a link that carries a value becomes an expression in an input row, and a linked `Error` becomes a **Try..Catch**. * In Control Flow, only eight converters are expression functions: `stringify`, `stringToBase64`, `stringToEntityInstance`, `epochToDateTime`, `isEmpty`, `jsonata`, `now`, and `toTime`. A step that uses another converter needs another design, such as a **Code** task. * A part built with tasks of one designer only has no form in the other designer. Build it anew, or call across. * Some tasks store added ports under a suffixed name. Check the name of every added port, as described in [[user-guide-automation-tasks-index#ports-you-add]]. The type of a saved workflow cannot be changed. Create the converted workflow as a new workflow in the target designer, and remove the old one.