Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Jira Legacy
showSummaryfalse
serverJIRA (mqidentity.atlassian.net)
serverId77fb3325-4051-36d9-bcc7-761f62050707
keyDOCS-36

 

Table of Contents
minLevel3
outlinetrue
stylenone

...

Code Block
languagexml
titleNon-repeatable workflow example
linenumberstrue
placeholder for example of non-repeatable workflow<AppFacet name="CSVLoader">
    <String name="destModelName" />
    <String name="DriverId" />
    <String name="ParkingLotId" />
    <String name="fileName" KnownBy="csvLoaderAc" Update="auto" />
    <Action name="csvLoaderAc" documentation="Data Facet to load CSV Data">
        <Workflow Limit="1" Live="1" Timeout="-1">
            <Task name="Main">
                <Event name="Argument" as="ActionArgument" />
                <Invoke name="CSVDataLoader" waitFor="Argument">
                    <FacetScript>
                        <Log Message="Loading file..."/>
                        <LoadFromCSV fileName="[%:Event.Argument.fileName.Value:%]" 
                                     destModelName="[%:Event.Argument.destModelName.Value:%]"
                                     DriverId="[%:Event.Argument.DriverId.Value:%]"
                                     ParkingLotId="[%:Event.Argument.ParkingLotId.Value:%]" />
                        <Log Message="Loading complete!!!"/>
                    </FacetScript>
                </Invoke>
                <Output name="ActionResult">
                    <Value>
                        <Log Message="Output file name: [%:Event.Argument.fileName.Value:%]"/>
                        <fileName>[%:Event.Argument.fileName.Value:%]</fileName>
                    </Value>
                </Output>
            </Task>
        </Workflow>
    </Action>
</AppFacet>

b. Repeatable (multi-run, stream) workflows

...

Note
titleUse While = "true" in the first task

Due to the current compiler limitation, you must use While = "true" for the first task that appears in your workflow definition (source code) in order for the compiler to recognize that this is a repeatable workflow. You do not need to specify While = "true" for the subsequent tasks in the same workflow definition.

Code Block
languagexml
titleRepeatable workflow example
linenumberstrue
<ThingFacet Name="TempFacetSerial">
    <Number Name="tempValue" update="auto" KnownBy="SerialReadAction" />
    <String Name="unit" default="Celsius" Documentation="Celsius or Fahrenheit" />
    <String Name="peripheral" />
    <String Name="interfacePort" />
    <String Name="interface" />
    <String Name="uniqueId" default="56789" />
    <String Name="baudrate" />
    <String Name="format" default="ascii" />
    <String Name="operation" />
    <String Name="payload" />

    <Action Name="SerialReadAction" Documentation="Start the serial port">
        <Workflow Limit="1" Live="1" Timeout="-1">
            <Task name="Main" while="true">
                <Event name="Argument" as="ActionArgument" />

                <Invoke name="InvokeSerialRead" waitFor="Argument" get="perif://">
                    <Message>
                        <Value>
                            <InterfacePort>"[%:Event.Argument.interfacePort.Value:%]"
                            </InterfacePort>
                            <Baudrate>"[%:Event.Argument.baudrate.Value:%]"</Baudrate>
                            <Interface>"[%:Event.Argument.interface.Value:%]"</Interface>
                            <UniqueId>"[%:Event.Argument.uniqueId.Value:%]"</UniqueId>
                            <Operation>"[%:Event.Argument.operation.Value:%]"</Operation>
                            <format>"[%:Event.Argument.format.Value:%]"</format>
                            <Payload>"[%:Event.Argument.payload.Value:%]"</Payload>
                            <Peripheral>"[%:Event.Argument.peripheral.Value:%]"</Peripheral>
                        </Value>
                    </Message>
                </Invoke>
                <Output name="Result" as="ActionResult">
                    <Value>
                        <tempValue>
                            [%:Invoke.InvokeSerialRead.Message.Value/number(
                            substring-before(substring-after("[%:Invoke.InvokeSerialRead.Message.Value:%]",
                            '#TCB:'), '#')):%]
                        </tempValue>
                    </Value>
                </Output>

            </Task>
        </Workflow>
    </Action>
</ThingFacet>

Non-waiting versus externally-activated workflows

...

Code Block
languagexml
titleExample of non-waiting workflow
linenumberstrue
Placeholder for example of non-waiting workflow<Action name="SetOutput">
  <Workflow Limit="1" Live="1" Timeout="-1">
    <Task name="Step1">
      <Input name="Argument" type="string" kind="literal" value="Hello World!"/>
      <Output name="Result" type="string" value="Step1 says '[:Input.Argument:]'"/>
    </Task>
    <Task name="Step2">
      <Input name="Argument" type="string" value="Step1.Result"/>
      <Output name="Result" type="string" value="Step2 says that '[:Input.Argument:]'"/>
    </Task>
    <Task name="Step3">
      <Input name="Argument" type="string" value="Step2.Result"/>
      <Output name="Result" type="string" value="Step3 says that '[:Input.Argument:]'"/>
    </Task>
    <Task name="Step4">
      <Input name="Argument" type="string" value="Step3.Result"/>
      <Output name="Result" type="string" value="Step4 says that '[:Input.Argument:]'"/>
    </Task>
  </Workflow>
</Action>

b. Externally-activated workflows

...

Code Block
languagexml
titleExample of externally-activated workflow
linenumberstrue
Placeholder for example of externally-activated workflows.<Action name="SetOutput">
  <Workflow Limit="1" Live="1" Timeout="-1">
    <Task name="Step1">
      <Event name="Argument" as="ActionArgument" />
      <Output name="Result" type="string" value="Step1 says '[:Event.Argument:]'"/>
    </Task>
    <Task name="Step2">
      <Input name="Argument" type="string" value="Step1.Result"/>
      <Output name="Result" type="string" value="Step2 says that '[:Input.Argument:]'"/>
    </Task>
    <Task name="Step3">
      <Input name="Argument" type="string" value="Step2.Result"/>
      <Output name="Result" type="string" value="Step3 says that '[:Input.Argument:]'"/>
    </Task>
    <Task name="Step4">
      <Input name="Argument" type="string" value="Step3.Result"/>
      <Output name="Result" type="string" value="Step4 says that '[:Input.Argument:]'"/>
    </Task>
  </Workflow>
</Action>

Externally-continued versus internally continued workflows

...

Code Block
languagexml
titleExample of externally-continued workflow
linenumberstrue
Placeholder for example of externally-continued workflow<Action Name="SerialReadAction" Documentation="Start the serial port">
  <Workflow Limit="1" Live="1" Timeout="-1">
    <Task name="Main" while="true">
      <Event name="Argument" as="ActionArgument" />
      <Invoke name="InvokeSerialRead" waitFor="Argument" get="perif://">
        <Message>
          <Value>
            <InterfacePort>
              "[%:Event.Argument.interfacePort.Value:%]"
            </InterfacePort>
            <Baudrate>
              "[%:Event.Argument.baudrate.Value:%]"
            </Baudrate>
            <Interface>
              "[%:Event.Argument.interface.Value:%]"
            </Interface>
            <UniqueId>
              "[%:Event.Argument.uniqueId.Value:%]"
            </UniqueId>
            <Operation>
              "[%:Event.Argument.operation.Value:%]"
            </Operation>
            <format>
              "[%:Event.Argument.format.Value:%]"
            </format>
            <Payload>
              "[%:Event.Argument.payload.Value:%]"
            </Payload>
            <Peripheral>
              "[%:Event.Argument.peripheral.Value:%]"
            </Peripheral>
          </Value>
        </Message>
      </Invoke>
      <Log
           Message="Invoke --> [%:Invoke.InvokeSerialRead.Message.Value.received:%]" />
      <Output name="Result" as="ActionResult">
        <Value>
          <tempValue>
            [%:Invoke.InvokeSerialRead.Message.Value/number(
            substring-before(substring-after("[%:Invoke.InvokeSerialRead.Message.Value:%]",
            '#TCB:'), '#')):%]
          </tempValue>
        </Value>
      </Output>
    </Task>
  </Workflow>
</Action>

b. Internally continued workflows

...

In such workflows, it is a good practice to have a Timeout modifier on the workflow. 

expand

Workflow instances run on top of pipelines, that is, they use pipelines to be instantiate, trigger or communicate. We call the pipeline that instantiate a workflow instance the originating pipeline. Based on the relationship between the workflow and its originating pipeline, workflow can be categorized into non-repeatable workflows and repeatable workflows.

In non-repeatable workflow, the originating pipeline waits until the workflow completes. In repeating working, the originating pipeline does not wait. The workflow, after being instantiated, may be triggered by a different pipeline.
Code Block
language
xml
titleunused notes
Info
iconfalse
Example for Internally continued workflows
<ThingFacet Name="PhidgetRFID">
  <Sid Name="RFIDId" />
  <String Name="ReadTag" Update="auto" KnownBy="PhidgetReadRFIDTagAc" />
  <String Name="WriteTag" KnownBy="PhidgetWriteRFIDTagAc" />
  <String Name="RFIDURL" Default="phid://" />
  <String Name="InterfaceType" />
  <String Name="InterfaceIndex" />
  <Unique Name="RFIDIndex" Value="InterfaceIndex" />
  <DateTime Name="timestamp" Format="$SimpleDateFormat(yyyy-MM-dd'T'HH:mm:ss'Z')" />
  <AA>
    [:#o#Output.ActionArgument:]
  </AA>
  <Action Name="PhidgetReadRFIDTagAc" Documentation="Read the Tag Automatically in the vicinity">
    <Workflow Limit="1" Live="1" Timeout="-1">
      <Task name="Main" while="true">
        <Event name="Argument" as="ActionArgument" />
        <Invoke name="ReadValue" waitFor="Argument"
                get="[%:Event.Argument.RFIDURL.Value:%]" SerialNumber="[%:Event.Argument.InterfaceIndex.Value:%]"
                DeviceType="[%:Event.Argument.InterfaceType.Value:%]" />
        <Output name="Result" as="ActionResult">
          <Value>
            <ReadTag>
              [%:[%:@Output:%]Invoke.ReadValue.Message.Value:%]
            </ReadTag>
          </Value>
        </Output>
      </Task>
    </Workflow>
  </Action>
  <Action Name="PhidgetWriteRFIDTagAc" Documentation="Write the Tag Value to RFID in the vicinity">
    <Workflow Limit="1" Live="1" Timeout="-1">
      <Task name="Main" while="true">
        <Output name="ActionArgument" as="ActionArgument" />
        <Invoke name="WriteValue" waitFor="ActionArgument"
                skip-if="[%:[:AA:].WriteTag/no-value(Value):%]" post="[%:[:AA:].RFIDURL.Value:%]"
                SerialNumber="[%:[:AA:].InterfaceIndex.Value:%]"
                SensorType="WriteTag" DeviceType="[%:[:AA:].InterfaceType.Value:%]">
          <Message Type="text" Value="[%:[:AA:].WriteTag.Value:%]" />
        </Invoke>
        <Output name="Result" as="ActionResult">
          <Value>
            <WriteTag>
              [%:[%:@Output:%]Invoke.WriteValue.Message.Value:%]
            </WriteTag>
          </Value>
        </Output>
      </Task>
    </Workflow>
  </Action>
</ThingFacet>