I have power plants that I intend to represent in Vision as two templates, a summary template (name, power, status), and a detail template (process diagram). These are shown on the same window, with the summary template in a Template Canvas. I've scripted it so when an operator clicks on a summary template it is highlighted and the larger detail template updates for the current plant. There are also subtemplates to change what a set of buttons do based on which unit is selected.
The problem is that when the window is first opened, a summary template isn't highlighted, and subtemplates are not populated with a default value. I have attempted event scripting with "onWindowOpened" or equivalent, but the Template Canvas has not populated with templates by then, so I do not have anything to pull from or activate. The script I tried is shown below.
oneLineTemplate = system.gui.getParentWindow(event).getComponentForPath('Root Container.TGUOneLine')
templateRepeater = system.gui.getParentWindow(event).getComponentForPath('Root Container.Template Canvas')
templates = templateRepeater.getAllTemplates()
selectedTemplate = templates[0]
for template in templates:
template.Selected = 0
selectedTemplate.Selected = 1
text = selectedTemplate.UnitNumber
oneLineTemplate.UnitNumber = text
If the operator has clicked on something, everything works fine. It is the initializing that doesn't work. I'm working on something shown below. Boxed in red is the Template Canvas. Below that is the DetailTemplate. If there is another way to get a similar effect, I would be interested.
Move your initialization script to your template repeater's propertyChange event handler, and nest it under the componentRunning event.
Example:
if event.propertyName == 'componentRunning':
# initialize here
If there is still a problem with loading delays interfering with your ability to manipulate templates, put your initialization script into a function, and call it with invokeLater
The main advantage of this approach for your use case is that componentRunning can't run before the component exists, but note that in the designer, preview mode must be on before the window is opened for this event to occur.
That did it. I had to use a delay on invokeLater as well. Perhaps it is because I am using a Template Canvas instead of the template Repeater? It is the first time I've used either so I do not know the limitations.
Do you know where I could find additional useful propertyNames documented? The manual does not have that listed anywhere.
You can always just throw a temporary print event.propertyName in the propertyChange event handler, and then keep an eye on the diagnostic console as you interact with the component. I have often done this when exploring or familiarizing myself with a component.
I'm not aware of any component that doesn't have componentRunning, so you can pretty much always use that to call your initialization scripts.
The issue for Template Canvas is that componentRunning triggers before the template is loaded. Is there a state that triggers after the canvas has loaded?
I will preface this by saying I have a solution that is functional. It isn't as elegant as I'd like, but that is fine. I'm continuing the discussion because I'm interested in learning about other alternatives or more about scripting Ignition.
I considered scripting the templates on their own, but I have assumed that it will just highlight on all of them, and if I re-used the template on other screens that would not necessarily be desirable. I just want the first of all the loaded templates to execute the script.
Template repeaters and canvases use significant resources to dynamically display components at run time, so loading delays are expected. Using invoke later to schedule initialization is perfectly valid approach.
That said, if all you're doing is setting the first template to highlighted, you could add a column to the canvas dataset for this Boolean parameter, and simply set the first row to True and all of the other rows to False.