Indirect Tag Binding in SQL Query

Hi,

I am trying to get list of Machines from database table, and its Current Event (‘RUN’ or ‘STOP’) from SQL Tags in a Table for Summary View. I tried with code like below and in vain:

SELECT MachineId, {[IADemo]MachineStatus/123/Event} -- Instead of 123, I want to use MachineId Column FROM MachineList ;
Is it possible to do like this or Is there any other Better way to the show the Summary View in table or other components.

Regards
Sasi Kumar Kallepalli

No that wont work.

Try this

SELECT MachineId, NULL as "Event" FROM MachineList

In the property change event for the table, try this in FactoryPMI

[code]def runLater(event=event):
import fpmi

if event.propertyName == 'data':
	newData = event.source.data
	for row in range(data.rowcount):
		machineId = newData.getValueAt(row, "MachineId")
		value = fpmi.tag.getTagValue("[IADemo]MachineStatus/%s/Event"%machineId)
		newData = fpmi.dataset.setValue(newData,row,"Event",value)

	event.source.data = newData

fpmi.system.invokeAsynchronous(runLater)
[/code]

In Ignition, the code needs to be modified a bit (if you want to use the actual function, not the alias)

[code]def runLater(event=event):
import system

if event.propertyName == 'data':
	newData = event.source.data
	for row in range(data.rowcount):
		machineId = newData.getValueAt(row, "MachineId")
		value = system.tag.getTagValue("[IADemo]MachineStatus/%s/Event"%machineId)
		newData = system.dataset.setValue(newData,row,"Event",value)

	event.source.data = newData

system.util.invokeAsynchronous(runLater)
[/code]

Now, this assumes the property that changed is called data, which should be true if you are using a table. If you have made a dynamic property, change the references to the new property.

Thank you Kyle.

Regards
Sasi Kumar Kallepalli

Did it work?

I got the values from the Real time Tag. However, I am facing new challenge

Traceback (innermost last):
  File "<event:propertyChange>", line 16, in runLater
java.util.ConcurrentModificationException

in running fpmi.system.invokeAsynchronous function.

Regards
Sasi Kallepalli

You should wrap the callback into the windowing system in a call that puts it on the EDT (event dispatch thread). The reasons are fairly technical. Here is the relevant code:

[code]def runLater(event=event):
import system

if event.propertyName == ‘data’:
newData = event.source.data
for row in range(data.rowcount):
machineId = newData.getValueAt(row, “MachineId”)
value = system.tag.getTagValue("[IADemo]MachineStatus/%s/Event"%machineId)
newData = system.dataset.setValue(newData,row,“Event”,value)

  def callback(event=event, newData=newData):
     event.source.data = newData
  system.util.invokeLater(callback)

system.util.invokeAsynchronous(runLater)[/code]

I like technical… care to share?

Well I’m only guessing because the poster did not provide the entire stack trace to the ConcurrentModificationException, but …

The Vision module is based on the Java Swing windowing toolkit which by design is single-threaded. That means that you should only ever modify visual elements from within the Event Dispatch Thread (a.k.a. EDT). So, when you call a function through [tt]system.util.invokeAsynchronous[/tt], it will be run in a background thread, i.e. not the EDT. So if your background function is going to interact with some visual elements (like setting the dataset of a table), you need to make sure that happens back on the EDT. This is what [tt]system.util.invokeLater[/tt] does, as defined in the User Manual.