Expression
The Expression roster type makes it possible to dynamically choose a single, predefined roster from within the pipeline. The expression can make use of Tag values, alarm properties and associated data. The alarm properties are accessible from the Alarm Properties (
) button located on the right side of the panel. Associated data can be manually entered using the "{" and "}" characters. A list of rosters is available from the On-Call Rosters (
) button.

if({Group}= "A","Group A","Group B")
The above expression checks for associated data named "Group" on the alarm. If the value is equal to "A", the Group A roster is used, otherwise the Group B roster will be notified.
When should I use quotation marks on the Roster name?
It is recommended to always place quotation marks around roster names. However, it is not always required for notifications to be sent out successfully.
If the expression consists of only the name of the roster, then quotes can be omitted. For example, specifying that a Notification block should always use the Roster named "Operators" could look like the following with quotes:
//This expression will evaluate successfully.
"Operators"
Which would return the string Operators, a valid Roster.
However, quotation marks could be removed in this scenario. This normally causes a syntax error, because strings in expressions must be encased in quotation marks. However, in this case the Notification block will assume you simply typed out the name of the roster, so the following example will also successfully use the Operators roster:
//This will fail to evaluate as an expression, so the block will instead look for a roster named "Operators",
//and the users will still be notified.
Operators
However, if the expression is any more complicated than the above example, such as using an expression function, then quotation marks must be used. The following example would check the priority of the alarm. If the alarm's priority was "critical", then the High Priority Roster would be notified. For all other priorities, the Low Priority Roster would be used.
//This expression will evaluate successfully.
if({priority} > 3, "High Priority Roster", "Low Priority Roster")
However, if the quotes were removed from the roster names, the expression would fail with a syntax error:
//This expression will fail, so all the text is assumed to the name of a Roster
if({priority} > 3, High Priority Roster, Low Priority Roster)
When this expression fails, the Notification block will assume that the text is actually the name of a roster, and will attempt to use a roster named "if({priority} > 3, High Priority Roster, Low Priority Roster)". For this reason, it is a good idea to always place quotes around Roster names, as well as check your expressions for syntax errors.
Calculated
The Calculated roster type allows you to use scripting to create a roster at that time using scripting. This becomes extremely useful for situations when you are not sure who should be contacted at the time. Instead of creating an on-call roster for each possible combination of users, you can determine who needs to be notified in the script based on the circumstances of the alarm, and then build the roster to fit that scenario. While this is extremely powerful and offers the most flexibility, it is the most difficult to configure, so you should only use it when absolutely necessary.

The Calculated roster type requires a return value which is a list of dictionaries, where each dictionary is a set of contact information. The contacts that you use are specific to that instance, meaning neither the user nor contact information have to exist on the Gateway. This can either be done manually, by putting together dictionaries with the appropriate contact info and then placing them into a list, or you can use the builder to put together the list for you. Both end up with the same results, so we advise that you use the one that you find easier. The builder has a set of methods which align with the key:value pairs the dictionary is expecting.
Name | Description | Datatype |
---|
username | A username for this particular user. Note: this can be anything that you want, the user does not have to exist in the Gateway. This will be used for acknowledgement and auditing purposes, so it is important you create meaning usernames. | String |
firstname | A first name for this particular user. | String |
lastname | A last name for this particular user. | String |
email | A list of possible email address for the user. | List of Strings |
phone | A list of possible phone numbers for the user for voice notification purposes. | List of Strings |
sms | A list of possible SMS numbers for the user for SMS notification purposes. | List of Strings |
extraProps | Extra properties that can be added to a user. This is useful when dealing with any third party functionality. | Dictionary of Lists |
User Data Created Manually
When putting together a dictionary manually, you can use some or all of the properties listed in the table above. You can create as many dictionaries of users as you want, adding in as much or as little contact info. Once you have your dictionaries created, you then need to place them in a list. You then need to use that list as the return value, which the pipeline will use to determine who to contact.
# create your user dictionaries
user1 = {"username":"mary", "email":["mary@company.com"]}
user2 = {"username":"john", "firstname":"John", "lastname":"Smith", "email":["john@company.com"], "phone":["1234567890"], "sms":["8905671234"]}
# create a list of the user data
userList = [user1, user2]
# return the user data
return userList
You can use this in conjunction with a database query to dynamically create a list of user information. See below for an example using the Builder.
User Data Created with the Builder
If you instead opt to use the builder, the builder object has a few extra methods that it can use besides what were listed above.
- add() - will add all previous info as a single dictionary.
- build() - will return the completed list of dictionaries.
The builder object is used by calling consecutive methods on it. Using the same info as the example above, you can add all of the contact info to the builder on a single line.
# Here, we are putting together contact information in our builder using one big string of code.
# Notice that even though it is one long string of code, we are adding both users.
# The first add() at the end of Mary's information acts as a divider between the details, adding hers first.
# The second add() at the end of the code will then add all of John's information.
builder.username("mary").email(['mary@company.com']).add().username('john').firstname('John').lastname('Smith').email(['john@comapny.com']).phone(['1234567890']).sms(['8905671234']).add()
While the above will work just fine, it may be a bit confusing to put together. However, you don't have to add all of the users at once like that. You can instead break it up, making sure to call add at the end of each user's information.
# Here, I still add all of the same contact information to my builder, but this time, I do it in two stages.
# The difference here is that I have to call builder again in the second line when adding John's information.
builder.username("mary").email(['mary@company.com']).add()
builder.username('john').firstname('John').lastname('Smith').email(['john@comapny.com']).phone(['1234567890']).sms(['8905671234']).add()
This can be really useful as it can allow you to add users one at a time, making use of flow control methods like a for loop. You can then use external information, such as database records or Ignition's built in user and security functions to determine who to add.
# This would grab a table from the database that contains a username, email address, and SMS number.
# We must specify the database connection name because this is in the gateway scope.
data = system.db.runQuery("SELECT username, emailaddress, smsnumber FROM user_info_table", "DB")
# loop through the returned query data
for row in data:
# add users to the builder row by row
# note the extra [] in the email and sms functions
builder.username(row["username"]).email([row["emailaddress"]]).sms([row["smsnumber"]]).add()
Once you have all of the appropriate contact information added to the builder, you then call build() on the builder object. This will give us a new built object. We then return our userList as before. Using our example from above:
# get user information from the database
data = system.db.runQuery("SELECT username, emailaddress, smsnumber FROM user_info_table", "DB")
# loop through the returned query data
for row in data:
# add each user to the builder
builder.username(row["username"]).email([row["emailaddress"]]).sms([row["smsnumber"]]).add()
# use the builder object's build() function to create the finished list of data
userList = builder.build()
return userList