I have a UDT set up that has 5 tanks. Each tank has a state value and if this value = 6 then the tank has a fault condition. Different people are responsible for taking care of different tanks and the users are all in a database. I want to use a calculated roster to dynamically send the user responsible for that tank a notification if that tank has a fault. In my database query I want to extract the UDT parameter containing the tank number and then use that in my calculated roster to say first get the tank number, then look into the database and determine who to contact if that tank has a fault.
How would I get this tank number in the calculated roster script?
Use Alarm Associated data at the bottom of the tag’s Alarm Setup. Send the tank number to the active pipeline.
Then construct your contact list dynamically using a calculated roster in your pipeline
Not sure where you’re storing users and credentials, so there’s some pseudocode below.
faultedTank = event.tank_number
for u in range(userSource): #pseudo
uName = ...
email = ...
uTemp = {"username":uName,"email":[email]}
roster.append(uTemp)
return roster
Thank you! @pascal.fragnoud and @amarks So I have let’s say an associated data in my alarms called TankNum and then I bound that to Tank number. If I want to bring that into my calculated roster it would be something like the script below, correct?
FaultedTank = event.TankNum
data = system.db.runQuery ("SELECT X.contact, UserData.username FROM (
SELECT * from UserContact) as X
LEFT OUTER JOIN UserData ON X.user_id = UserData.id
WHERE UserData.id = (SELECT user_id FROM Tank where Tank_Number = FaultedTank) ")
for row in data:
builder.username(row["username"]).email([row["emailaddress"]]).add()
userList = builder.build()
return userList
I’ve not used the builder much, so I can’t comment on that, but I’d suggest using a named query and system.db.runNamedQuery rather than having the query in your roster script.
You can trigger an alarm and use the gateway’s Status > Logs log to see if it’s working properly and/or toggling the pipeline’s Test Mode.
I’m not sure if the builder works in the script console, but I typically test my scripts with it and print it out so I can verify it’s returning what I expect.
Also, you’ll need to do for row in range(data.getRowCount()) rather than for row in data as the returned data from the query is not iterable.
I feel like my named query is not correct.
so FaultedTank = event.TankNum will return multiple numbers as a dataset, correct? As long as we have faulted tank it will return their numbers. So it can probably return tank numbers 3, 10, 15, …, right?
But the way I set up my query it will only accept 1 value.
FaultedTanksArry = event.TankNum
for FaultedTank in FaultedTanksArry:
data = system.db.runQuery ("SELECT X.contact, UserData.username FROM (
SELECT * from UserContact) as X
LEFT OUTER JOIN UserData ON X.user_id = UserData.id
WHERE UserData.id = (SELECT user_id FROM Tank where Tank_Number = FaultedTank) ")
for row in data:
builder.username(row["username"]).email([row["emailaddress"]]).add()
userList = builder.build()
return userList
Thank you, Victor! None of them works I still get errors: Unable to parse calculated roster. Roster '<calculated>' has no users, notification for 1 alarm will go undelivered.
Each alarm will start in the pipeline with it's own associated data. So, let's say Tank 1 and Tank 3 are faulted. You'll have two alarms and two notifications to send. You'll have 2 separate, unrelated instances of event.TankNum one will be 1 and one will be 3.
FaultedTank = event["TankNum"]
data = system.db.runQuery("SELECT X.contact, UserData.username FROM (SELECT * from UserContact) as X LEFT OUTER JOIN UserData ON X.user_id = UserData.id WHERE UserData.id = (SELECT user_id FROM Tank where Tank_Number = FaultedTank) ")
for row in data:
builder.username(row["username"]).email([row["contact_value"]]).add()
userList = builder.build()
return userList
It is working when I delete the first line and then make Tank_Number = (to a number like 10) but otherwise is not working I also tried:
FaultedTanksArry = event.TankNum
for FaultedTank in FaultedTanksArry: