Indirect tag write from scripting

I am trying to do a python script that indirectly get info from a tag. If it were an expression I would write {1}/Interlock where {1} is Root Container.TagPath but I am not sure how to make this in the scripting section. Any advice?

1 Like

Where are you writing this script? On a button, in an event handler, in a tag event? What do you have so far?

Yes, on a button. The script is finished but I was referring to tags directly as it was easier to test that way. I want to not be able to run the script for any tag that is passed in. My first line is ā€œdatasetPath = ā€˜[default]Z1/G1U01/Interlockā€™ā€ but that is only for the Z1/G1U01 tag and I would like to be able to use it for others.

firstThing = "Z1"
secondThing = "G1U01"

path = '[default]%s/%s/Interlock' %(firstThing,secondThing)
1 Like

Or same thing more 2.7esque

firstThing = "Z1"
secondThing = "G1U01"

path = '[default]{}/{}/Interlock'.format(firstThing,secondThing)

The two variables obviously donā€™t need to be set to static strings. You can link these to what you need: component property values, other tag values, function argument values, etc.

6 Likes

Thanks! Only problem now is I am getting an error that says " File ā€œevent:actionPerformedā€, line 13, in
ValueError: list.index(x): x not in list" for the last line in this chunk of code below. I am not sure why especially because the column is definitely called InterlockedTag

firstThing = "Root Container"
secondThing = "TagPath"
datasetPath = '[default]{}/{}/Interlock'.format(firstThing, secondThing)

dataIn = system.dataset.toPyDataSet(system.tag.readBlocking([datasetPath])[0].value)

headers = list(dataIn.getColumnNames())

tagList  = dataIn.getColumnAsList(headers.index("InterlockedTag"))

what is the value of headers?

The headers are InterlockedTag (string), StatusForGood (boolean), and ColorNum (int). This is for the same table as on an earlier post you helped me with haha :sweat_smile:

put print headers before the tagList line and post the output here. Not that I donā€™t trust you. :wink:

Also, do the same thing for your datasetPath. Then see if you have a tag that exists at that location. Iā€™m guessing you donā€™t have a folder called ā€˜Root Containerā€™

Or a subfolder called TagPath

If you want to reference a property of the window's root container, you need to use a proper reference to it instead of static strings. Use the property picker icon in the top right of the script editor to select a property from the Window.

This is what I get in the output console when I print headersā€¦ I am not sure why the headers did not print there. I have used Root Container.TagPath before in indirect binding but not in scripting.

[]
10:19:13.406 [AWT-EventQueue-0] ERROR com.inductiveautomation.ignition.client.util.gui.ErrorUtil - <HTML>Error executing script for event:&nbsp;<code><b>actionPerformed</b></code><BR>on component:&nbsp;<code><b>Button</b></code>.
com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last):
  File "<event:actionPerformed>", line 14, in <module>
ValueError: list.index(x): x not in list

	at org.python.core.Py.ValueError(Py.java:339)
	at org.python.core.PyList._index(PyList.java:614)
	at org.python.core.PyList.list_index(PyList.java:586)
	at org.python.core.PyList.list_index(PyList.java:582)
	at org.python.core.PyList$list_index_exposer.__call__(Unknown Source)
	at org.python.core.PyObject.__call__(PyObject.java:484)
	at org.python.pycode._pyx132.f$0(<event:actionPerformed>:25)
	at org.python.pycode._pyx132.call_function(<event:actionPerformed>)
	at org.python.core.PyTableCode.call(PyTableCode.java:171)
	at org.python.core.PyCode.call(PyCode.java:18)
	at org.python.core.Py.runCode(Py.java:1614)
	at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:799)
	at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.runActions(ActionAdapter.java:206)
	at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.invoke(ActionAdapter.java:297)
	at com.inductiveautomation.factorypmi.application.binding.action.RelayInvocationHandler.invoke(RelayInvocationHandler.java:57)
	at com.sun.proxy.$Proxy60.actionPerformed(Unknown Source)
	at java.desktop/javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at java.desktop/javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at java.desktop/javax.swing.plaf.basic.BasicButtonListener.focusLost(Unknown Source)
	at java.desktop/java.awt.AWTEventMulticaster.focusLost(Unknown Source)
	at java.desktop/java.awt.AWTEventMulticaster.focusLost(Unknown Source)
	at java.desktop/java.awt.Component.processFocusEvent(Unknown Source)
	at java.desktop/java.awt.Component.processEvent(Unknown Source)
	at java.desktop/java.awt.Container.processEvent(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.KeyboardFocusManager.redispatchEvent(Unknown Source)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.KeyboardFocusManager.dispatchAndCatchException(Unknown Source)
	at java.desktop/java.awt.KeyboardFocusManager.processCurrentLightweightRequests(Unknown Source)
	at java.desktop/java.awt.KeyboardFocusManager$4.run(Unknown Source)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
Caused by: org.python.core.PyException: Traceback (most recent call last):
  File "<event:actionPerformed>", line 14, in <module>
ValueError: list.index(x): x not in list

	... 51 common frames omitted

Actually, I meant print datasetPath :slight_smile:

So, since the tag [default]Root Container/TagPath/Interlock doesnā€™t exist, it will give you an empty dataset. Thatā€™s why the header list is empty.

Ahh, that makes sense. So if I have a custom property on my vision window that is the tag path I want the script to run but this will change while I am running the project, how can I link these dynamically/indirectly?

Use the object picker button/icon in the top right of the script editor, it's a square with 2- 3 horizontal lines in it from memory

1 Like

Sorry, I didnā€™t see that! I have done that now but I am still getting the same error for the last line.
This is what I have:

datasetPath = event.source.parent.TagPath

# Read the dataset tag. Convert to PyDataSet for easier iteration.
dataIn = system.dataset.toPyDataSet(system.tag.readBlocking([datasetPath])[0].value)

#Get column names. Coerce it to a list to use the same names in the new dataset.
headers = list(dataIn.getColumnNames())

# Get tag paths as a list
tagList  = dataIn.getColumnAsList(headers.index("InterlockedTag"))

print datasetPath
print headers

Putting things in like this can help you troubleshoot your script.

When I print the datasetPath it works properly but then gets an error on this line:

dataIn = system.dataset.toPyDataSet(system.tag.readBlocking([datasetPath][0].value))

saying that " File ā€œevent:actionPerformedā€, line 6, in
AttributeError: ā€˜unicodeā€™ object has no attribute ā€˜valueā€™". I donā€™t know if the headers print out correctly because I canā€™t get past this line. This was working before I tried to make the tagpath dynamic.

Thereā€™s a small typo, that line should look like this:

dataIn = system.dataset.toPyDataSet(system.tag.readBlocking([datasetPath])[0].value)

It was correct in your earlier post

Ah thank you. I am still getting an error for that line though. " File ā€œevent:actionPerformedā€, line 6, in
TypeError: toPyDataSet(): 1st arg canā€™t be coerced to com.inductiveautomation.ignition.common.Dataset" Do you know how I can fix this?