isAlarmActive with polling rate

I feel like maybe I am missing something here, but when I try to use the isAlarmActive expression with a polling rate as a binding in perspective, I cant give it a polling rate without it failing. Unfortunately the documentation only shows it with multiple tags, not with a polling rate.

Here is what I have:

isAlarmActive("[MyProvider]MyFolder/MyTagWithAnAlarm", "MyAlarmName", 5000)

Here is the error:
image

I can force it to poll by doing this, but Its kind of a cheeky workaround

if(now(5000) != "", isAlarmActive("[MyProvider]MyFolder/MyTagWithAnAlarm"), "")
1 Like

From a glance at the code, I think thereā€™s no ability to specify a poll rate on the gateway because it shouldnā€™t be necessary. On the gateway we should be able to directly hook into the tags with listeners, and get triggered value changes.

So then as a clarification, I am not seeing the binding auto-reevaluate when the alarm is triggered

However it does auto-reevaluate by binding directly to the alarm isActive tag path

so is this part of the user manual a typo then?

isAlarmActive(tagPath, [alarmName], [pollRate])

  • Parameters

String tagPath - The Tag path to search for active alarms. Supports the wildcard ā€˜*ā€™.

String alarmName - The name of the alarm to search for. Supports the wildcard ā€˜*ā€™. [optional]

Integer pollRate - The poll rate in milliseconds. Only applicable in the Client scope. [optional]

  • Returns

Boolean - True if an alarm is active; False if no active alarms were found.

Which part?

The part about being able to set a poll rate?

The user manual already states itā€™s only applicable in Client scope.

Perspective is not ā€œClientā€ scope. Weā€™ve been making an effort to say ā€œVision Clientā€ where applicable in the user manual to try to make that more clear, looks like we missed a spot.

ah ok, that makes sense. I didnā€™t realize the distinction. Is there anyway to add that to perspective? My binding seems to respond when an alarm goes from in-active to active, but when the alarm clears it doesnā€™t change.

I think Paulā€™s original point here is that polling isnā€™t necessary in the gateway. If the binding isnā€™t behaving properly then it might be a bug.

Is your execution mode currently set to Event Driven?

edit: assuming this is on an Expression Tag

Iā€™m using it on a property binding to set a style class when an alarm is active

I think we already have an issue for thisā€¦ Iā€™m going to update it and put it in the backlog, hopefully for next sprint.

1 Like

JD, Iā€™m having the same issue. The function works as long as I click apply in the ā€˜Edit Bindingā€™ window after an alarm state change so there seems to be no automatic polling.

Iā€™m having the same problem. I want to highlight certain urgent alarms by making a slow-flashing style class on the root of the view. One of them is if our main database goes unavailable. It works fine if I bind directly to the tag, but I have a 30 second active delay on it. The transition doesnā€™t get caught.

Thanks

I'm back. Is there any progress on this? Example, I have two tags, [default]Temp/Alarm Test and
[default]Temp/Alarm Test 3

I am using
isAlarmActive("[default]Temp/Alarm*")

bound to a label. That label doesn't change live. However, if I bind either one of the alarms to the label
isAlarmActive("[default]Temp/Alarm Test")
, those labels will change. Also, I can do:

isAlarmActive("[default]Temp/Alarm Test") ||
isAlarmActive("[default]Temp/Alarm Test 3")

And that will change live, which is fine here, but I will soon be implementing 30+ tags into a folder that I want to check to see if any of them go active, and I don't want to have to type them all out and maintain the list if a tag changes.

Thanks

This is how I do it:

New script in Scripting -> Project Library -> "templates" (or whatever you want to call it) with the following code:

def getActiveChildrenAlarms(tagPath):
	
	# Check if tag path is not empty
	if tagPath!='':
		# Split the tag path to get the tag name
		splitPath = tagPath.split(']')
		# Create a filter to get all alarms that have the tag name in their path
		filter = ['*%s*' % splitPath[-1]]
		# Get all active alarms for the filter
		states = ['ActiveUnacked','ActiveAcked']
		activeAlarms = system.alarm.queryStatus(Path = filter,state = states)
		# Create a list of alarms and their states
		ret = []
		for alarm in activeAlarms:
			item = {
				'name': str(alarm.getName()),
				'state': str(alarm.getState())
			}
			ret.append(item)
	else:
		# Return an empty list if tag path is empty
		ret = []
	
	return ret

Create a view prop called "rootTagPath" which holds the tag path, i.e. [default]SBR/Basin1/Basin1Mixer

Then I have a custom prop object called motorAlarms with an expression + script transform binding:

This lets you bind something such as a style class like so:

Can't promise this is the most efficient method, but it works. I'm sure @pturmel will tell me I'm doing something stupid.

This is an absurdly expensive system call, especially with wildcards. Don't call it from a UI. Call it from a timer event, with parameters that will satisfy all users. Divvy up the results into project script top-level dictionaries (or dataset or document tags, perhaps) that UI consumers can hit with near-zero latency.

Haha. I figured there would be something

1 Like

That particular function, called in a Vision runScript binding, will bring a high-latency (VPN, WAN) client to screeching halt. Perspective is a bit more tolerant, but still not a good idea.

Here is what I have done. I made a tag that calls isAlarmActive, Made it Fixed Rate Execution mode and set the poll rate to 1,000. Seems to work. I don't know if the poll rate is too fast? I would like for it to react relatively quickly, but don't want to suck down all the resources doing it.
image