Components are written in XML and you can implement desired behavior by writing down its rules, which are if A then B statements.
For example, The requirement is that while inspecting a machine if the user presses the button "Camera", then the device's internal camera starts.
The same rule could be expressed a bit closer to the implementation as:
If we are in the step
"inspect_machine" and an event
occurs with the command
"Camera" then execute action
"start_camera".
The typical structural frame of a component is as follows:
<workflow [ATTRIBUTES]> <context> [...] </context> // Data variables, optional <rules> [...] </rules> // If [Expression] then [actions]; optional <actions> [...] </actions> // optional <steps> <step [ATTRIBUTES]> <states> <onresume> [...] </onresume> // optional <onevent> [...] </onevent> // optional [...] </states> <mapping> [...] </mapping> </step> [...] </steps> </workflow>
Before going forward with an example, below is an overview of the XML tags:
To better understand the structure of components, we will use an example of an Image Choice component.
The user selects between the two options "Apple" and "Pear". The same component will be used for this training and will be improved as we go forward.
The UI below displays how this component would appear while executing on the Frontline Workplace smart glass application.
The workflow is:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <workflow xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" wfd_version="1.0" reporting="false" id="choice" name="choice" descriptor="Choice component" startstep="choose" xsi:noNamespaceSchemaLocation="../../../configuration/workflow.xsd"> <steps> <step id="choose" descriptor="the user selects between two options" uitemplate="ChoiceScreen"> <states> <onevent> <rule id="menu_button_selection"> <expression>#{event:command} == 'APPLE' || #{event:command} == 'PEAR'</expression> <actions> <finish_workflow id="finish_workflow"> <output> <param name="selected_button" type="string">#{event:command}</param> </output> </finish_workflow> </actions> </rule> </onevent> </states> </step> </steps> </workflow>
1. The workflow tag contains an attribute startstep="choose". This is used to select which step will be performed first after initializing the component.
2. <step id="choose"...
is used to refer to a choice that will be further displayed using uitemplate="ChoiceScreen"
. ChoiceScreen is a file that defines what is displayed on the screen while we are in this step.
As explained, the behavior of a component is defined using rules. A rule consists of an expression (or condition) and which action to take when that condition is True. Each rule is assigned to one of the states <onenter>
, <onresume>
, <onleave>
, <onevent>
or <onpause>
. Rules will only be checked when the component is in that state (e.g., onenter - when the component is first started).
3. The <rule id="menu_button_selection">
is assigned to the <onevent>
state. Whenever an event occurs, all rules given to this state will be checked. Here, <expression>#{event:command} == 'APPLE' || #{event:command} == 'PEAR'</expression>
checks whether the event contains a specific command. Such an event would be activated when a button with the name "APPLE" or "PEAR" is triggered either by voice command or pressing it on the screen.
4. If a rule expression evaluates to true, the set of actions in the rule's <actions>
tag is executed. In this example, the finish_workflow
action is used. This immediately leaves the component once the user has chosen one of the two options, and passes on which choice was made in a <output>
parameter so that we can create different transitions in the workflow diagram based on that choice.
Suppose you want to extend our choice component to send a message containing the user's choice back to the Frontline Connector (which could in turn communicate this information to a backend system). Think about the following questions:
Actions are the basic building blocks we can use. They range from changing what the user sees (colours, text, notifications,...) to controlling the flow of the program (transition to the next step) by managing data and communicating with the Frontline Connector or external devices.
First of all, you might argue that communicating with the Frontline Connector is a separate functionality and should have its own component. You would be absolutely right: separating the communication aspect into its own components would make both components more reusable. On the other hand, sometimes you want to simplify the process flow shown in the Frontline Creator Interface for your customer by keeping multiple functionalities together in a single component. For now, let's assume we combine both functionalities in one component.
Previously, you were told that steps are equivalent to screens. So why would you have more than one step if the additional functionality is just backend communication?
The answer is maintainability and reusability. Maintainability, because when making changes to the communication aspect, you will only have to look at that step and not read any of the other code. Reusability, because you could also send different messages using the same step if the component becomes even more complex.
In the same way, it would be a good idea to make two separate components of these two functionalities. It is a good idea to at least create separate steps if you combine them into one component. Just make the screen look the same or add a progress notification acknowledgement from the Connector. As such we suggest having 2 steps here, e.g., "choice" and "message_connector".
The main purpose of this question is to make you familiar with the 'Actions' catalogue. Here are examples of actions you might use in the implementation process:
With this, you have now finished the first lesson. The next lesson will be about scopes and encompass your first practical assignment.