How to display all machine data using templates on single click

Hi,
here I am using one template. I have taken this template in main screen for 2 machines.
I have written the script on multistate button calling named query. the script is working its is displaying total parts.

But can you suggest any other way of writing script to get the data for all templates on the screen.
without using if statement can we do this. because still I need to add other 5 machine data, so how to avoid repetition.

def runAction(self, event):
    inputtime = self.props.controlValue
    allmachines = ['R17_Rougher','R17_Honor']
		
    for i in allmachines:
		
	  	parameters = {"InputTime":inputtime,"MachineName":i}
	  	system.perspective.print(i)
		dataIn = system.db.runNamedQuery("select_TotalGoodParts_MES",parameters)	
		   
		if i == 'R17_Rougher':
			self.getSibling("SimpleMachineView1").props.params.TotalYield = dataIn
			#break
			pass

		else:
			self.getSibling("SimpleMachineView2").props.params.TotalYield = dataIn

by clicking on multistate button I am getting the data

Have you considered to use the flex repeater component.

With this you give the path of the template view and with your script you can create instances.

do we need to use flex repeater for template then in main view script we should use the path right.
I will try.
thank you

test_2023-07-11_1357.zip (12.7 KB)
here i quick example

My first thought would be to include the named query within the View Template itself. Pass in the period to the template, and pass the parameter into the named query and it will automatically re-execute whenever the parameter changes.

As for the script itself (I suggest you not use it, as per above), but as a learning example, you can improve this like so:

def runAction(self, event):
    inputtime = self.props.controlValue
    allmachines = ['R17_Rougher','R17_Honor']
		
    for machine in allmachines:
	  	parameters = {"InputTime": inputtime, "MachineName": machine}
	  	system.perspective.print(machine)
		dataIn = system.db.runNamedQuery("select_TotalGoodParts_MES", parameters)
		self.getSibling(machine).props.params.TotalYield = dataIn

You would also need to name all of you view template instances to "R17_Rougher", "R17_Honour", etc.
Again, I don't suggest you use this!

You're going to want to use the Flex Repeater component, but I advise against handing off a parameter to each instance and letting the instances run a parameterized query; it would work, but there's a better way. Modify the query to return data for a subset of specified machines, and then use the returned data to populate the instances property of the Flex Repeater.

Pseudo-code:

allmachines = ['R17_Rougher','R17_Honor']
query = "select myColumn from TotalGoodParts where name in ({0})".format(','.join(['?' for machine in allmachines]))
myYields = system.db.runPrepQuery(query, "MyDB")
# convert yields from PyDataSet to list
instances = [{"dataIn": myYield} for myYield in myYields]
self.getSibling("MyFlexRepeater").props.instances = instances

Alternatively, you could just bind FlexRepeater.props.instances against your parameterized Named Query, and include the Multi-State Button as a param of the query. The binding is a much better way to go.

1 Like

This is far more efficient, but was more work to explain on my phone :smile:

The binding route is much cleaner. In the following screenshot, I've bound FlexRepeater.props.instances to a Named Query. My Named Query happens to only take in one value, but this could easily be expanded to accept several values. My transform converts the returned PyDataSet to a json object so the Flex Repeater knows what to do with the values.

But even this approach can be a headache because of the PyDataSet conversion, so I went back and modified my NamedQuery to alias the returned quantity, and I also modified the returned value to be json. This allowed me to remove my transform entirely, and pass the pure data right into the binding.

Hi all,

Thank you for all your guidance. It will be helpful for my further work.

I got it in a simple way. Please check the code below.

def runAction(self, event):
	inputtime = self.props.controlValue
		
		#machinename = self.getSibling("SimpleMachineView").props.params.MachineName
		
	allmachines = ['R17_Rougher','R17_Honor']
	
	j=0
	
	for i in allmachines:
				
		parameters = {"InputTime":inputtime,"MachineName":i}
		system.perspective.print(i)
		TotalGoodParts = system.db.runNamedQuery("select_TotalGoodParts_MES",parameters)	
		system.perspective.print(TotalGoodParts)
		j=j+1
		Str="SimpleMachineView"+str(j)
		system.perspective.print(Str)
		self.getSibling(Str).props.params.TotalYield = TotalGoodParts
        
        	
		```

That solution has multiple concerns which will make it a long-term maintenance headache:

  1. If the number of machines ever changes, this script will either begin logging exceptions to the Gateway logs or you'll have an Embedded View which is empty/stale because you've hard-coded j to always depend upon the count of machines. If you ever add a machine without adding an Embedded View, you'll see exceptions because a component could not be found. If you remove machines you'll have an Embedded View present which never updates.
  2. You're performing a Query for each item. I highly recommend finding a way to get all of your data from a single query. If you have many sessions using this View on a regular basis you're going to have a lot of traffic for no reason.
  3. Dynamically building component names in a script is very fragile. If you rename even one of the Embedded Views, or if you put them into a container in an effort to organize your View, this script will stop working.

The use of a pure binding has many benefits, including:

  • no scripting is necessary.
  • reduced number of queries.
  • If the Flex Repeater is renamed or moved into a container the binding will immediately fault and inform you that the path has been broken (as opposed to the script route where it will not fail until executed).
1 Like

I'll throw in as well, that you're using a coordinate View, but this type of content is very much more suited to a flex View with emdebed flex containers. It'll be significantly easier to develop and modify with flexs, with more options

ya your right, I will consider all your points, I will try the method what you suggested.
Thanks..