Triggers - ResgreenGroup/Botway-Documentation GitHub Wiki
Current Location: Home->Customizing BotWay->Triggers
Triggers are a powerful tool in BotWay that allows for interaction with the world. They are conditional statements that can be used to cause an action to be taken; for instance, a Stacklight can be turned on when a vehicle arrives at a specified location. Data from devices, tags, time information, location information, and many more data elements can act as a condition to set off the trigger.
-
User must be logged in as Admin before they can edit triggers. In the Toolbar of the Map Display, click the "Edit Triggers" button. This will open a dialogue window called "Edit Triggers" that will display all created triggers and allow the user to create new triggers and delete or edit existing ones. In order to create a new trigger, click the "Add" button in the top-left of the window. Once the "Add" button is clicked, the "Edit" button turns into the "Save" button.
Image: Trigger creation. -
Each trigger has a Condition and one or more Actions. First, the condition needs to be established; after clicking "add" the cursor will move to the input line next to the upper Test button. In this line, the user will need to input conditions for the new trigger to activate using standard JAVA logic. Triggers always evaluate the condition to "True" or "False." When the condition evaluates to "True" the trigger is set off and the actions associated with it are performed. Many aspects of BotWay are tokenized for use in creating trigger conditions. Usable Conditional operators and tokens are shown in the tables below.
-
The upper test button can be used before finalizing the conditions in order to verify their functionality; this will evaluate the condition based on current BotWay conditions. Real-time changes to the physical environment may change the evaluation of the condition, so testing multiple times may be necessary. Once the evaluation behaves as desired, the trigger condition can be saved by selecting the "save" button on the top of the window.
-
Now that the trigger is saved, its condition and ID number should appear in the top half of the page in the first table. The next step is to select this trigger and press the "add" button on the lower half of the page to add an Action. Each trigger can have one or more output actions associated with it. Once the "add" button is clicked the bottom-right table becomes editable.
-
In the bottom-right table, there is eight fields. Not all are going to be filled/need to be filled. The top field is a drop down menu in which you select what type of action will be undergone, one attached to a robot ("ROBOT"), one attached to a device ("DEVICE"), or one attached to our messaging function("MSG"). Upon type selection, you must now select the target ID, also a dropdown menu. If you selected "MSG", you must select if you are sending to a phone number or sending to an email. If you selected "DEVICE", you must select from the list of available devices, made up of every device that has connected to the computer before. If you select ("ROBOT"), you must select from the list of available robots, also made up of every robot that has connected to the computer before.
-
The data input in the rest of the fields differs based on the data type or target Id. If you have EMAIL selected as the target Id, you must input the email it is being sent to, the subject of the email, and the message of the email.
![](https://private-user-images.githubusercontent.com/163035943/353137096-6880a861-9176-4cb2-923f-af13249801f9.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkyODg0MzEsIm5iZiI6MTczOTI4ODEzMSwicGF0aCI6Ii8xNjMwMzU5NDMvMzUzMTM3MDk2LTY4ODBhODYxLTkxNzYtNGNiMi05MjNmLWFmMTMyNDk4MDFmOS5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjExJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxMVQxNTM1MzFaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1mYTQ0NzBiZGM0Mzg5MjZlOWRkMDA3M2UwNTFlNzIzOWMzZGRkZTcxNzg5NTdjZjZkMTA0NjUxMDNjMzM2MGMwJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.Oofn-wvnP7DF88-hpXJAn0qefz00o9F1zdPPM2aVBz4)
Image: Emailing.
If you have SMS selected, you must input the number you are sending to and the message of the email. When inputting the phone number, you must put it all as one line with no dashes, including the country code (+1). Example phone number (+18881234567).
For robots, the value is the type of action that the device is being told to perform. The other four fields, marked data 1-4, fluctuate in function from device to device. For example, for the wireless Stacklight the first three Data fields are for RGB values between 0 and 255 (color selection), and the fourth field is for blinking pattern. Meanwhile, for the Scissorlift cart, Data 1 requires a value between 0 and 100 that indicates what percent of its maximum height to raise its platform to while the fields Data 2-4 do nothing. For RGGI devices, a full description of usable values for these fields can be found on their accessories wiki page.
- Once the action table is filled, click the "save" button on the toolbar in the middle of the page. Steps 4-6 can be repeated many times for each created trigger to instruct changes in multiple devices when the trigger is activated. When the trigger is triggered, the associated actions are carried out sequentially in the order of their creation.
Operator | Description | Example | Evaluation |
---|---|---|---|
== | Is Equal to | 1 == 2 | false |
> | Is Greater Than | 1 > 2 | false |
< | Is Less Than | 1 < 2 | true |
>= | Is Greater Than or Equal To | 1 >= 2 | false |
<= | Is Less Than or Equal To | 1 <= 2 | true |
&& | Logical AND | (4 > 3) && (3 <= -5) | false |
|| | Logical OR | (4 > 3) || (3 <= -5) | true |
! | Logical NOT | !true | false |
Operator | Description | Example | Evaluation |
---|---|---|---|
+ | Addition | 1 + 2 | 3 |
- | Subtraction | 10 - 4 | 6 |
/ | Division | 6 / 5 | 1.2 |
% | Modulo -- remainder | 15 % 6 | 3 |
When writing the conditions for a trigger, placeholders, called tokens, can be used as substitutes for any actual information needed at the time of evaluation but that is unknown when writing the condition. Tokens are delimited by percent symbols. For example, if robot V1's route is needed for a trigger, the token %R.V1.Route% can be used. When the trigger is evaluated, the token, %R.V1.Route%, will be replaced with the actual route robot V1 is on at that time. The expression is then evaluated according to the logic of the trigger.
Tokens | Output Type | Notes | Example Output |
---|---|---|---|
%R.V1.Batt% | Number | Battery Voltage. | 22.9 |
%R.V1.Tag% | Text | Outputs the Tag that the vehicle is at. | A55 |
%R.V1.Route% | Text | Outputs the route that the vehicle is on. | B1 |
%R.V1.Speed% | Number | Outputs vehicle speed in meters per second or percentage of maximum speed. | 2 |
%R.V1.CommLoss% | True, False | Outputs "true" if the vehicle is not communicating with BotWay and "false" otherwise | false |
%R.V1.Error% | NONE / UNKNOWN / E_STOP / BUMPER_STOP / TRACK_LOSS / PAYLOAD_ERROR / LOW_VOLTAGE / NO_CHARGE / NETWORK_LOSS / BOTWAY_LOSS / TAG_NOT_FOUND | Outputs the type of error when inquired. The abbreviations for all listed errors are enumerated in this table. | E_STOP |
%R.V1.Status% | IDLE / STOPPED / NAVIGATING / DISABLED / OFFLINE / CHARGING / WAITING_HUMAN_EVENT / WAITING_EXTERNAL_EVENT / WAITING_INTERNAL_EVENT / MANUAL_MODE | Outputs vehicle condition. Abbreviations for all available statuses are enumerated in this table. | WAITING |
%R.V1.JOBSTATUS% | UNKNOWN / NONE / ASSIGNED / EXECUTING | Outputs the current status of the job | NONE |
%R.V1.CycleStatus% | 0, 1 | Outputs "1" if a cycle is in process and outputs "0" otherwise. | 1 |
%R.V1.MinCycleTime% | Number | Outputs smallest time to complete a cycle in HH:MM:SS | 00:02:13 |
%R.V1.MaxCycleTime% | Number | Outputs longest time to complete a cycle in HH:MM:SS | 00:27:08 |
%R.V1.LastCycleTime% | Number | Outputs time taken to complete most recent cycle in HH:MM:SS | 00:15:51 |
%R.V1.TotalCycleTime% | Number | Outputs total amount of time spent running cycles in HH:MM:SS | 02:09:11 |
%R.V1.ArrivalStatus% | UNKNOWN, NONE, ARRIVED, AT_TAG, DEPARTED | Outputs arrival/departure status of vehicle. | AT_TAG |
Tokens | Output Type | Notes | Example Output |
---|---|---|---|
%T.145.IsOccupied% | True, False | Indicates whether or not a robot is at the tag | true |
%T.145.Vehicle%, %T.145.Robot% | Text | Outputs the name of the robot that this tag. | V12 |
%T.145.Route% | Text | Outputs the route of the robot that is at this tag. | B1 |
%T.145.TrafficStatus% | UNOCCUPIED, OCCUPIED, LOCKED, WAITING | Outputs traffic status the tag. | WAITING |
%T.145.ArrivalStatus% | ARRIVED, AT, DEPARTED | the first time a robot reaches a tag, its arrival status is set to "arrived." The next update cycle sets its arrival status to "at." Robot's arrival status is set to "departed" if it is still "navigating" while its arrival status is set to "at." | ARRIVED |
Tokens | Output Type | Notes | Example Output |
---|---|---|---|
%B.VD00001.2.Status% | Pressed, Unpressed | Indicates whether or not a button is pressed | Pressed |
Tokens | Output Type | Notes | Example Output |
---|---|---|---|
%Sys.Time% | HH:mm:ss | Outputs timestamp in 24 hour clock with format Hours : Minutes : seconds | 18:15:22 |
%Sys.Version% | VX.X.X | Outputs BotWay Version. | V2.5.10 |
%Q.queue.Paused% | True, False | Outputs true if the job queue is paused and false otherwise | true |
%Q.queue.Count% | Number | Outputs the number of queued jobs. | 21 |
%Stage.Status% | UNKNOWN, OK, EMPTY, FULL | Outputs state of entire staging area for Dynamic Staging. | EMPTY |
%Stage.Cell.Status% | NONE, EMPTY, LHF, LHF_PALLET, LHF_FULL | Outputs state of storage spot Cell for staging of material in Dynamic Staging. | LHF_FULL |
Operator | Description | Example | Evaluation |
---|---|---|---|
. | one character wildcard | "B150".matches("B.50") | true |
"BQ50".matches("B.50") | true | ||
"BQ150".matches("B.50") | false | ||
.* | many character wildcard | "B150".matches("B.*50") | true |
"BQ50".matches("B.*50") | true | ||
"BQ150".matches("B.*50") | true | ||
"BQ151".matches("B.*50") | false | ||
[a] | require included character | "A100".matches("[A]100") | true |
"a100".matches("[A]100") | false | ||
"B100".matches("[A]100") | false | ||
[a,b] | require any character in list | "A100".matches("[A,B]100") | true |
"B100".matches("[A,B]100") | true | ||
"b100".matches("[A,B]100") | false | ||
[n-m] | require number in range | "A100".matches("A[2-3]00") | false |
"A200".matches("A[2-3]00") | true | ||
"A300".matches("A[2-3]00") | true | ||
"A400".matches("A[2-3]00") | false | ||
[a-b] | require character in range | "A100".matches("[B-C]100") | false |
"B100".matches("[B-C]100") | true | ||
"C100".matches("[B-C]100") | true | ||
"D100".matches("[B-C]100") | false | ||
"b100".matches("[B-C]100") | false | ||
[a-b, x-z] | require character in either range | "A100".matches("[B-C, J-L]100")) | false |
"B100".matches("[B-C, J-L]100") | true | ||
"K100".matches("[B-C, J-L]100") | true | ||
"F100".matches("[B-C, J-L]100")) | false | ||
{n} | require n repeats | "A2_10".matches("A{2}_10") | false |
"AA_10".matches("A{2}_10") | true | ||
"AAA_10".matches("A{2}_10") | false | ||
"AA_20".matches("A{2}_10") | false |
For more information on Regular Expressions see: https://en.wikipedia.org/wiki/Regular_expression
Note: for these examples:
Robot V01 is at Tag St128 on Route A200.
Robot V10 is at Tag H17 on Route A201.
Robot V11 is at Tag H22 on Route B100.
Trigger | After Token Replacement | Evaluation | Notes |
---|---|---|---|
%Sys.Time%.charAt(7) > '5' | '15:29:38'.charAt(7) > '5' | true | Evaluates to true whenever the last digit of the time is greater than 5 |
%T.H17.Vehicle% == 'V11' | 'V10' == 'V11' | false | Evaluates to true whenever tag H17 has robot V11 |
%T.H17.isOccupied% | true | true | Evaluates to true whenever tag H17 has any robot |
%R.V01.Route% == 'A201' | 'A200' == 'A201' | false | Evaluates to whether or not robot V01 is on route A201 |
%T.St128.Route%.matches([A,B].00) | 'A200'.matches([A,B].00) | true | Evaluates to true if tag St128 has a robot that is on any route that begins with A or B, followed by a single character, and ends with 00 |
%Q.A.Count% > 5 | 8 > 5 | true | Evaluates to true whenever the number or queued jobs in queue 'A' is greater than 5 |