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
icon 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
icon.

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.

Accessing Alarm Properties
You can access any of the alarm properties through the event object in a calculated roster. Properties are stored as a dictionary and can be accessed in the same way.
# properties can be accessed directly using the dictionary format
# event["propertyname"]
# get the alarm name
alarmName = event["name"]
# get an associated data property named "Machine Area"
associatedArea = event["Machine Area"]
Calculated Rosters
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 | Data Type |
---|
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. It will be used for acknowledgement and auditing purposes, so it is important you create meaningful 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.
The following feature is new in Ignition version 8.1.8
Click here to check out the other new features
The extraProps key can be used to set arbitrary user properties as of 8.1.8. This is useful when trying to set a user property not mentioned above. For example, if you needed to set the language for a user on a calculated roster to Spanish so that the Voice Notification module uses a Spanish voice, the user would be configured as follows:
user1 = {"username":"bob", "phone":["5550100"], "extraProps":{"language":["es_ES"]}}
The extraProps key can be used to set the following user properties. Technically it can be used to set any user property. See the User object. The value for each key must be a list. In addition, extraProps can be used to set user properties that are registered by modules. For example, the SMS module registers a user pin setting, which can be set with the user.pin key:
user1 = {"username":"bob", "phone":["5550100"], "extraProps":{"user.pin":["1234"]}}
| 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 opt instead to use the builder, the builder object has a few extra methods that it can use besides what were listed above.
- add() - Adds all previous info as a single dictionary.
- build() - Returns 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 the alarm name property
alarmName = event["name"]
# don't send notification for some alarms
if alarmName in ["Diagnostic Alarm", "Joe's Test Alarm"]:
# return an empty list so no one will be emailed
return []
else:
# 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
if({Group}= "A","Group A","Group B")
Ignore User Schedules
The following feature is new in Ignition version
8.1.13
Click here to check out the other new features
This setting allows the notification block to ignore the schedules of any of the users in the roster, notifying users that would normally be "off shift." This setting is available on the Direct and Expression roster types.
