Combing multiple rosters to a single roster

Hi all, I am trying to create a roster which contains the users of three other rosters and i only require this new roster for a notification block. I am asked to make a notification pipeline for medium level alarms but different operators are to be called upon based on the machines. so I have to create 10 different rosters in total if I want to achieve this but i can do this if i am able to merge the existing rosters together and return the merged roster to the notification block. Is there any ways to do that ?

You can dynamically produce any desired roster using a "calculated" roster. It is just a script that yields the contacts to use at that moment.

But I want to get the contacts from the roster so that in the future if i have to change a personnel I should only have to edit the roster. Is this possible with calculated roster?

https://docs.inductiveautomation.com/display/DOC81/system.roster.getRosters
https://docs.inductiveautomation.com/display/DOC81/system.roster.getRoster

I tried using this system function but it still does not return the userlist. I am sharing the code that i used in the calculated roster as well :

Your code has a lot of problems.

Chiefly:

  1. You're not returning the contact infos as a list of possible contact infos
  2. You're not differentiating between SMS, email, or phone numbers, which you would want to do.
  3. You don't need to call system.user.getUser if you use system.roster.getRoster(), which directly returns User objects
  4. Hardcoding in default to the system.user.getUser function is also a bad idea.
  5. You're returning in the wrong format anyways: you're returning something like:
[
  { "Maintenance Roster": [
    { "joe": [contactInfo] }
    ]
  }
]

But you need to return a direct list of user-like objects; see the manual:
https://docs.inductiveautomation.com/display/DOC81/Notification+Block#NotificationBlock-Calculated

A generic mergeRosters suitable for use in a calculated roster script would be something like this:

	def mergeRosters(*rosterNames):
		return [
		    dict(username = user.get(user.Username), **{ci.contactType: ci.value for ci in user.contactInfo})
			for rosterName in rosterNames
			for user in system.roster.getRoster(rosterName).users
		]
	
	return mergeRosters("day shift", "night shift")
1 Like

I tried this code like u said it returned an error in gateway log :

java.lang.ClassCastException: class java.lang.String cannot be cast to class java.util.List (java.lang.String and java.util.List are in module java.base of loader 'bootstrap')

def calculateRoster(event, builder):
	def mergeRosters(*rosterNames):
			return [
			    dict(username = user.get(user.Username), **{ci.contactType: ci.value for ci in user.contactInfo})
				for rosterName in rosterNames
				for user in system.roster.getRoster({rosterName}).users
			]
		
	[userList] = mergeRosters(['TEST', 'TEST2'])
	return userList

You're not calling it correctly. Look at the code I posted, and compare it to yours:

	[userList] = mergeRosters(['TEST', 'TEST2'])
	return userList

You're unnecessarily wrapping the return value in a list, and you're unnecessarily wrapping the input value to the function in a list.

I made the corrections as u said and now the error displays :

org.python.core.PyException: TypeError: getRoster(): 1st arg can't be coerced to String

def calculateRoster(event, builder):
	def mergeRosters(*rosterNames):
		return [
				dict(username = user.get(user.Username), **{ci.contactType: ci.value for ci in user.contactInfo})
				for rosterName in rosterNames
				for user in system.roster.getRoster({rosterName}).users
				]
			
	userList = mergeRosters("TEST", "TEST2")
	return userList

That's still not the code I gave you; why are you wrapping rostername in curly braces? That's making a set.

2 Likes

Sorry about that, now when I take off the curly braces it seems to return an error like :

java.lang.ClassCastException: class java.lang.String cannot be cast to class java.util.List (java.lang.String and java.util.List are in module java.base of loader 'bootstrap')

i have also posted the code i used again please do tell me if there is anything wrong with the script.

def mergeRosters(*rosterNames):
			return [
			    dict(username = user.get(user.Username), **{ci.contactType: ci.value for ci in user.contactInfo})
				for rosterName in rosterNames
				for user in system.roster.getRoster(rosterName).users
			]
		
	return mergeRosters("TEST", "TEST2")

Is the indentation like this in your script, or did the copy-paste mess it up ?

def mergeRosters(*rosterNames):
			return [
			    dict(username = user.get(user.Username), **{ci.contactType: [ci.value] for ci in user.contactInfo})
				for rosterName in rosterNames
				for user in system.roster.getRoster(rosterName).users
			]
		
	return mergeRosters("TEST", "TEST2")

Think I was missing one set of square brackets, to put the contact infos into a list.

thank you the script now works and sends emails with the combined roster