Perspective Button, Auto Click Every Minute

I would like to have a Button. The button has the script configured on Action Performed. How can I configure button so that action performed script runs every 1 minute without clicking the button.
I have seen Timer and doClick() function used to achieve similar thing in Vision Module.

What would be the best practices to do such thing in Perspective Module.

  1. Move your button logic into a script library.
  2. Call your script every minute from a Gateway Event Timer Script.
5 Likes

Hi zacht,

Thank you for your answer.

I am fairly new to Python and Ignition as a whole. I want to run the script and queries based on the selection I get from the Dropdown menu on that particular view. So, my script uses a lot of getValue or getText from other component.
Can you suggest me some ways to handle these things from Project Script Library. Is there other alternative ways to do it.

Do you need to run this in more than once at a time (once for every active session) or just once across the whole gateway?

Assuming the latter, you could bind the dropdowns to memory tags and read the values into your script using system.tag.readBlocking.

If you need to run an instance of the script for every session that's running you might be able to put something together with system.perspective.getSessionInfo and system.util.sendMessage.

My question is, why do you need to call the script periodically?
Can you post your script so we have an idea of what you're trying to do, as I suspect you should be going about it in a different way

Hi nminchin,

We have same type of machines numbered from 1 to 15. Each machine has same type of dashboard containing Downtime Table, Waste Table, OEE Charts etc. We have used the Sepasoft MES Analysis to get the Downtime data.

I have written the following script for action performed event on a button. The reason I want to run the script every minute is to run the MES Analysis every minute and update the Downtime table without having to click the button again if current view is active.

def runAction(self, event):
	
	startdate=self.parent.custom.startdatetime
	enddate=self.parent.custom.enddatetime
	path=self.getSibling("Line").props.selectedMESObject.equipmentPath

	downtime_data=perspective.mesanalysis.getdowntime(path,startdate,enddate)
	pydowntimedata=system.dataset.toPyDataSet(downtime_data)
	
	list={}
	for row in pydowntimedata:
		st=str(row['Equipment State Name'])
		if st not in list:
			list[st]=[st,0,0.0]
		mins=float(row['Unplanned Downtime'])
		list[st]=[st,list[st][1]+1,list[st][2]+mins]
		
		tableHeader = ['Equipment States','Occurance','Downtime Mins']
		tableData = []
		for row in list:
			tableData.append(list[row])
		tabledata = system.dataset.toDataSet(tableHeader,tableData)
		tabledata=system.dataset.sort(tabledata,'Downtime Mins',False)
		self.parent.parent.parent.getChild("DashBoard").getChild("Downtime Table").getChild("Table").props.data=tabledata

The vast majority of this script is just adjusting a dataset for display.

It appears that the real work occurs in the perspective.mesanalysis.getdowntime() function. Is it possible to "hard code" the equipment paths?

For instance, something like this in a Gateway Timer Script:

paths = ('EquipmentPath1','EquipmentPath2')
tagPaths = ['Tag\Path\For\EquipmentPath1\DataSet','Tag\Path\For\EquipmentPath2\DataSet']
endDate = system.date.now()
startDate = system.date.addMinutes(endDate,-1)
tagValues = [perspective.mesanalysis.getdowntime(path,startDate,endDate) for path in paths]
system.tag.writeBlocking(tagPaths,tagValues)

On the other hand, is there perhaps an Indentation error in your script? It looks like you are building and sorting a dataset, for every row in the data? You should probably not do that. Not to mention you have two different declarations of row in the same scope.

Also, you should definitely not use list as a variable, because you're overwritting the python built-in in that scope.

I would expect something more like this:

	states = {}
	for row in pydowntimedata:
		st=str(row['Equipment State Name'])
		if st not in states:
			states[st]=[st,0,0.0]
		mins=float(row['Unplanned Downtime'])
		states[st]=[st,states[st][1]+1,states[st][2]+mins]
		
	tableHeader = ['Equipment States','Occurance','Downtime Mins']
	tableData = [val for state,val in states.iteritems()]
	tabledata = system.dataset.toDataSet(tableHeader,tableData)
	tabledata=system.dataset.sort(tabledata,'Downtime Mins',False)
	self.parent.parent.parent.getChild("DashBoard").getChild("Downtime Table").getChild("Table").props.data=tabledata

As far as calling the script for different conditions/scopes (e.g., button and/or time) I would think one of the following would work:

  1. Like @zacht mentioned, utilize a Gateway Event Timer Script. See details from the manual:
    Gateway Event Scripts - Ignition User Manual 8.1 - Ignition Documentation

  2. Utilize message handlers (assuming you have Perspective), see details from the manual:
    Component Message Handlers - Ignition User Manual 8.1 - Ignition Documentation

Of course, both have their use case. You would need to do some research to determine which would work best for your scenario.