wf_uri
can be used as a "wf" identifier in the start_workflow actionNote: This is similar to the Task Browser component, but only fetches the workflow associated with the given template, rather than executing it separately.
The action can be used as follows:
<get_workflow_from_template id="get_workflow_from_template"> <param name="template">NameOfTemplate</param> </get_workflow_from_template>
Result handling:
<rule id="extracted"> <expression><![CDATA[ #{event:command} == 'WORKFLOW_EXTRACTED']]></expression> <actions> <action id="start_workflow" type="start_workflow"> <param name="wf">#{event:payload.wf_uri}</param> </action> </actions> </rule> <rule id="extraction_error"> <expression><![CDATA[ #{event:command} == 'WORKFLOW_EXTRACTION_ERROR']]></expression> <actions> <finish_workflow id="finish_workflow"> <output> <param name="wf_error" type="bool">true</param> </output> </finish_workflow> </actions> </rule>
Sets or updates the parameters of a workflow or a step.
Identifier: setvar
{global::my_value}
in direct references or appcontext.global.my_value
in Javascript).#{user_session::my_value}
) but the values will be deleted when the user signs out.Minimal
<setvar id="increase_step"> <context_update> <param name="current_step">#{current_step}+1</param> </context_update> </setvar>
All options
<setvar id="next_step"> <context_of>root</context_of> <context_update> <param name="current_step_index" type="long">#{current_step}+1</param> <param name="step" type="object">?{context.steps[context.current_step_index]}?</param> </context_update> </setvar>
Downloads one or more specified assets.
Identifier: download_assets
<download_assets id="test"> <asset_uris>xai:/assets/hops_02?version=1</asset_uris> </download_assets> <download_assets id="test"> <list name="asset_uris" listType="UNNAMED"> <elem>xai:/assets/hops_02?version=1</elem> <elem>xai:/assets/hops_01?version=1</elem> <elem>xai:/assets/hops_03?version=1</elem> </list> </download_assets>
Sets a timer with the option to set specific delays and periods. The period or the timer ends when the step changes.
Identifier: timer
To start a timer that triggers the REFRESH
event after 5 seconds (5000 ms) the first time and after that every 2 seconds (2000 ms), you could use this:
<timer id="trigger_refresh" command="REFRESH" delay="5000" period="2000"/>
This action is designed to retrieve JSON data over a REST API. It supports the POST and GET data request types.
Identifier: rest_request
"https://myfcc.com/sampledata/enginedata"
"GET"
"$.rpm" //check Jayway JsonPath for more examples
\<list name="rest_params" listType="NAMED"> \<param name="serial" type="string">1337\</param> \</list>
5000
"sensor_value"
Let's consider a JsonPath given the following JSON structure:
[{ "color"="blue", "id"=87427, "name"="Blueforce87427", "position"={ "datetime"="2017-07-20T13: 58: 47.947513+02: 00", "positionX"=2722, "positionY"=2, "positionZ"=3980 } }{ "color"="red", "id"=11111, "name"="Opfor11111", "position"={ "datetime"="2017-07-20T13: 58: 47.947513+02: 00", "positionX"=3222, "positionY"=232, "positionZ"=4000 } }]
You can use the following JsonPath
strings to retrieve data from the endpoint:
1. JsonPath:
$[0]['name']
2. Returned string:
Blueforce87427
3. JsonPath:
$[0]['position']
4. Returned string:
[{ "datetime"="2022-07-27T13:58:47.925260+02:00, "positionX"=2722, "positionY"= 2, "positionZ"= 3980 }]
5. JsonPath:
$[*]
6. Returned string:
Whole array with both objects
Minimal
<rest_request id="my_rest_test0"> <param name="rest_url" type="string">https://alex.dev.ubimax.com/sampledata/enginedata</param> <param name="request_type" type="string">POST</param> <param name="value_path" type="string">$.rpm</param> <list name="rest_params" listType="NAMED"> <param name="serial" type="string">1337</param> </list> </rest_request>
All options
<rest_request id="my_rest_test0"> <param name="rest_url" type="string">https://alex.dev.ubimax.com/sampledata/enginedata</param> <param name="request_type" type="string">POST</param> <param name="value_path" type="string">$.rpm</param> <param name="repeat_every_ms" type="string">5000</param> <param name="payload_path" type="string">myPayload</param> <list name="rest_params" listType="NAMED"> <param name="serial" type="string">1337</param> </list> </rest_request>
Sends a generic message with customizable properties to the Frontline connector. These are handled via the DefaultInspectionRequestHandler.class
attribute.
Identifier: send_commit_message
Note: Properties are internally converted to a map and their values can be a collection of recursive conversions. The final map is stored as a JSON string in the payload string of the message and primitive values such as string, numeric, and boolean are stored inside the properties map field. This makes the message very flexible when communicating with the integration service.
There are three possible outcomes when sending a commit message:
A timeout occurs when no response is received after the specified time. This happens due to the message getting lost in the network or the server requiring too much time to process the result.
An error in this case generally means unexpected behaviour such as failure to send messages due to either network errors or server errors. Expected error handling (e.g., handling an invalid state in the process) is done via a successful response.
All responses generate an input event with the send_commit_message
modality. The command is one of RESPONSE_OK, RESPONSE_TIMEOUT
or RESPONSE_ERROR
.
Messages contain a payload
object that contains additional data for the response. In the case of error
and timeout
, the payload contains the "type" and "identifier" fields set to the same values as used in the request. This can be used to identify errors for specific requests if needed.
In the case of a success, these fields are not present but the "status" field is set to a numeric value (defined by the handler in the integration service). This value can be used to handle error cases that are expected in the process. In all cases, the "response" field contains a string defined by the integration service that can be used to differentiate the response further.
In addition to the status and response values, the integration service can define additional properties to be sent back with the event. These properties are available as context variables at the time of event handling. An example of this would be sending back an error message from the customer WMS for error handling or additional information to process the successful commit (see below for fragments of this).
<send_commit_message id="pre_task_request" type="PRE_TASK_REQUEST" connection_timeout="600"> <properties> <param name="group" type="string">#{group}</param> <param name="aisle" type="string">#{aisle}</param> </properties> </send_commit_message> <send_commit_message id="complete_inspection" type="COMPLETE_INSPECTION" connection_timeout="1500"> <param name="identifier">#{cockpit_id}</param> </send_commit_message>
The value for the identifier is not valid to be set as a tag attribute – this should be possible with future iterations of the creator.
<send_commit_message id="send_asset_info" type="PHOTO" connection_timeout="60"> <properties> <param name="asset_uri" type="string">#{event:payload.media_file}</param> <param name="order_id" type="string">?{pickOrder.name}?</param> <param name="group_id" type="string">?{pickOrder.groups[activeGroup].label}?</param> <param name="customer_reference">?{pickOrder.groups[activeGroup].picks[0].article.customerReference}?</param> <param name="amount" type="string">?{pickOrder.groups[activeGroup].picks[0].amountOpen}?</param> </properties> </send_commit_message>
This example step just expects an image asset URI (media_file) as input:
<step id="send_asset" uitemplate="WAIT" persist="false" screen_lock_enabled="false" debug_mode="false"> <actions> <action id="upload_media" type="trigger_upload_asset"> <param name="asset_uri">#{media_file}</param> <param name="delete_after_upload" type="bool">true</param> <param name="upload_immediately" type="bool">true</param> <param name="upload_immediately_delete_on_failure" type="bool">true</param> </action> <send_commit_message id="send_asset_info" type="PHOTO" connection_timeout="200"> <properties> <param name="asset_uri" type="string">#{event:payload.asset_uri}</param> <param name="asset_name" type="string">#{event:payload.asset_name}</param> <param name="asset_version" type="string">#{event:payload.asset_version}</param> </properties> </send_commit_message> <ui_notification id="show_nok" type="WARN"> <duration>SHORT</duration> <message>Picture NOT OK</message> </ui_notification> <ui_notification id="show_upload_error" type="ERROR"> <duration>SHORT</duration> <message>Media upload failed</message> </ui_notification> <ui_notification id="show_commit_error" type="ERROR"> <duration>SHORT</duration> <message>Commit failed</message> </ui_notification> </actions> <states> <onresume> <rule id="auto_exec"> <expression>1</expression> <actions> <action ref="upload_media"/> </actions> </rule> </onresume> <onevent> <rule id="upload_ok"> <expression> <![CDATA[#{event(trigger_upload_asset):command} == 'OK']]> </expression> <actions> <action ref="send_asset_info"/> </actions> </rule> <rule id="upload_error"> <expression> <![CDATA[#{event(trigger_upload_asset):command} == 'ERROR' || #{event(trigger_upload_asset):command} == 'NETWORK_ERROR' || #{event(trigger_upload_asset):command} == 'INTERNAL_ERROR']]> </expression> <actions> <action ref="show_upload_error"/> <action ref="finish"/> </actions> </rule> <rule id="commit_ok_ok"> <expression> <![CDATA[#{event(send_commit_message):command} == 'RESPONSE_OK' && #{event(send_commit_message):payload.response} == 'OK']]> </expression> <actions> <action ref="finish_workflow"/> </actions> </rule> <rule id="commit_ok_nok"> <expression> <![CDATA[#{event(send_commit_message):command} == 'RESPONSE_OK' && #{event(send_commit_message):payload.response} != 'OK']]> </expression> <actions> <action ref="show_nok"/> <action ref="goto_take_picture"/> </actions> </rule> <rule id="commit_error_or_timeout"> <expression> <![CDATA[#{event(send_commit_message):command} == 'RESPONSE_ERROR' || #{event(send_commit_message):command} == 'RESPONSE_TIMEOUT']]> </expression> <actions> <action ref="show_commit_error"/> <action ref="goto_take_picture"/> </actions> </rule> </onevent> </states> </step>
<actions> <!-- dialog references variables set by the commit message response for error handling --> <ui_dialog id="sap_error" type="Error" title="Error"> <message><![CDATA[#{sap_message}<br>Continue to '#{sap_material}/#{sap_position}'?]]></message> <buttons> <button> <text>ANDRRES_fw</text> <command>SAP_FIX</command> <focused>true</focused> </button> <button> <text>ANDRRES_bw</text> <command>DO_NOT_TRY_AGAIN</command> </button> </buttons> </ui_dialog> <!-- more actions [...] --> </actions> <!-- more WF code [...] --> <onevent> <!-- Technical success but check for SAP response --> <rule id="success"> <expression><![CDATA[#{event:command} == 'RESPONSE_OK' && #{event:payload.status} == 0 ]]></expression> <actions> <ui_notification id="show_done" type="INFO"> <duration>SHORT</duration> <message>#{cockpit_id} completed...</message> </ui_notification> <action ref="close_ds_task"/> <action ref="finish_workflow"/> </actions> </rule> <rule id="sap_error_in_success"> <expression><![CDATA[#{event:command} == 'RESPONSE_OK' && #{event:payload.status} == 500 ]]></expression> <actions> <!-- variables are automatically set when the event is handled and can be used in the action --> <action ref="sap_error"/> </actions> </rule> <rule id="unknown_error_in_success"> <expression><![CDATA[#{event:command} == 'RESPONSE_OK' && #{event:payload.status} != 0 && #{event:payload.status} != 500 ]]></expression> <actions> <action ref="completion_error"/> </actions> </rule> <rule id="request_error"> <expression><![CDATA[#{event:command} == 'RESPONSE_ERROR']]></expression> <actions> <action ref="completion_error"/> </actions> </rule> <rule id="request_timeout"> <expression><![CDATA[#{event:command} == 'RESPONSE_TIMEOUT']]></expression> <actions> <action ref="completion_error"/> </actions> </rule> </onevent>
<send_commit_message id="send_mqtt" type="FRONTLINE_MQTT" connection_timeout="200"> <properties> <param name="mqtt" type="string"><![CDATA[?{ var mqtt = { topic: "MY/TOPIC", content: "MY CONTENT" }; var stringmqtt = JSON.stringify(mqtt); stringmqtt;}?]]> </param> </properties> </send_commit_message>
Here is an example of handling code in the connector, inside the "Inspection" request handler.
@Override public CommitMessageResponse handleCommitMessage(CommitMessage aCommit) { if("COMPLETE_INSPECTION".equals(aCommit.getType())) { String evaluation = aCommit.getIdentifier(); // HANDLE EVENT // [CODE] if(isSuccess) { log.info("Completion success!"); return new CommitMessageResponse(aCommit, 0, "Success!"); } // HANDLE ERROR CommitMessageResponse cmr = new CommitMessageResponse(aCommit, 500, "SAP Error!"); cmr.addProperties("sap_message", cr.getMessage()); // 'cr' is an object specific to the custom code cmr.addProperties("sap_material", cr.getMaterial()); cmr.addProperties("sap_position", cr.getPosition()); return cmr; } // OTHER MESSAGES
The properties added in the error case will be available to the workflow when the event is handled.
Adds an attachment to the task results of the current step.
Identifier: add_attachment
Note: You need to enable reporting for your component in the workflow tag. Otherwise, the action will have no effect. Here's an example of how you can do this: <workflow [...] reporting="true"></workflow>
Note: You can also set your own type.
Minimal
<add_attachment id="add_attachment"> <param name="type" type="string">documentation-comment</param> <param name="content" type="string">#{current_comment}</param> </add_attachment>
All options
<add_attachment id="document_barcode"> <param name="type" type="string">barcode-content</param> <param name="content" type="string">#{code}</param> <param name="override" type="bool">false</param> </add_attachment>
Retrieves the last attachment added for a particular attachment data type.
Identifier: get_attachment_content
Note: You also have the option to add your own attachment type if it is not already on the list of available types.
Minimal
<get_attachment_content id="get_attachment_content"> <param name="type" type="string">documentation-comment</param> <param name="write_to" type="string">current_comment</param> </get_attachment_content>
All options
<get_attachment_content id="get_attachment_content"> <param name="type" type="string">documentation-comment</param> <param name="write_to" type="string">current_comment</param> <param name="write_if_empty" type="bool">true</param> </get_attachment_content>
Used to change the state of a module. For example, you can use it to deactivate speech input recognition.
Identifier: module_state
<module_state id="resume_speech" module_name="de.ubimax.android.speechrecognition.SpeechRecognitionModule" change_state_to="resume"/> <module_state id="pause_speech" module_name="de.ubimax.android.speechrecognition.SpeechRecognitionModule" change_state_to="pause"/>
Logs off the client.
Identifier: logoff
<logoff id="myaction"/>