Template Canvas, like the Template Repeater, will repeat templates. However, you are not limited to one template, size, position, or parameters. For this example, I created a new window and added a Template Canvas.
This time, I want to use two different templates with my data type AI_STD: Alarm Analog and Scaling Analog templates. Also, I wanted to get rid of the scroll bars by displaying only enough data that would fit on one page. As the display size can change from computer to computer, the number of templates added to each page will vary. To access other pages, I created a third template, Page Button, to add page buttons dynamically to each page.
This is a screenshot of the result:
This is a screenshot of the result:
I added the following custom properties: blanks, page, path, totalpages. Blanks adds spaces between the tags. Page is the current page to display. Path is the parent path to look for my tag data type: AI_STD. Totalpage is the total number of pages needed.
I created a new script called “template_analog_TC”. This script will return the desired templates with the correct parameters for each tag, if they are on the desired page, and add page buttons horizontally across the bottom as needed. I call this script anytime the 'page' property changes using the propertyChange event handler on the Template Canvas.
The tricky part is getting the buttons to set the 'page' property on the Template Canvas.
The easiest way I found was go to the Top Level and drill back down.
Here is the code for the actionPerformed on the event handler of the button.
So I can now make all my analog pages dynamically and they fit on to any size monitor.
def template_analog_TC(event):
import system
#Let's get the custom properties from the event.
path = event.source.getPropertyValue('path')
blanks = event.source.getPropertyValue('blanks')
canvas_height = event.source.height
page = event.source.getPropertyValue('page')
# Create the rows for the dataset
rows = []
tags = system.tag.browseTags(parentPath = path, udtParentType = 'AI_STD', sort ="ASC")
row_count = 0
page_count = 1
x = 0
y = 0
height = 35
width = 1050
layup = 'n/a'
template = 'Items/Alarm Analog V2'
template2 = 'Items/Scaling Analog V2'
width2 = 975
template3 = 'Items/Page Button'
height3 = 50
width3 = 125
maxheight = int(canvas_height) - int(height3) # Don't want to cover the buttons to change pages.
for tag in tags:
#print "On line 267, This tag ", tag.name, " has row count: ", row_count
readtags = [tag.path + "/USESCALE", tag.path + "/USEHHALM", tag.path + "/USEHALM", tag.path + "/USELALM", tag.path + "/USELLALM"]
scl,hh,h,l,ll = system.tag.readAll(readtags)
temprows = []
if scl.value:
name = tag.name + "SCALE"
y = height * row_count
parameters = '{"TagPath":' +'"'+ tag.path +'"'+'}'
row = [name, template2, layup, x, y, width2, height, parameters]
temprows.append(row)
row_count += 1
name = tag.name + "SCL"
y = height * row_count
parameters = '{"Alarm":"ALM", "TagPath":' +'"'+ tag.path +'"'+'}'
row = [name, template, layup, x, y, width, height, parameters]
temprows.append(row)
row_count += 1
if hh.value:
name = tag.name + "HHALM"
y = height * row_count
parameters = '{"Alarm":"HHALM", "TagPath":' +'"'+ tag.path +'"'+'}'
row = [name, template, layup, x, y, width, height, parameters]
temprows.append(row)
row_count += 1
if h.value:
name = tag.name + "HALM"
y = height * row_count
parameters = '{"Alarm":"HALM", "TagPath":' +'"'+ tag.path +'"'+'}'
row = [name, template, layup, x, y, width, height, parameters]
temprows.append(row)
row_count += 1
if l.value:
name = tag.name + "LALM"
y = height * row_count
parameters = '{"Alarm":"LALM", "TagPath":' +'"'+ tag.path +'"'+'}'
row = [name, template, layup, x, y, width, height, parameters]
temprows.append(row)
row_count += 1
if ll.value:
name = tag.name + "LLALM"
y = height * row_count
parameters = '{"Alarm":"LLALM", "TagPath":' +'"'+ tag.path +'"'+'}'
row = [name, template, layup, x, y, width, height, parameters]
temprows.append(row)
row_count += 1
if (scl.value or hh.value or h.value or l.value or ll.value) and blanks: #Add a blank space for separation between tags.
row_count += 1
if ((not scl.value) and (not hh.value) and (not h.value) and (not l.value) and (not ll.value)): # There is nothing to add.
print "This tag ,", tag.name, " is not used..."
if (y < maxheight): # Yes, these will fit on the page...
if (page == page_count): # Add these rows
rows = rows + temprows
else:
page_count += 1
row_count = 0 # clear the row count...
temprows = [] # Clear the temprows...
if scl.value:
name = tag.name + "SCALE"
y = height * row_count
parameters = '{"TagPath":' +'"'+ tag.path +'"'+'}'
row = [name, template2, layup, x, y, width2, height, parameters]
temprows.append(row)
row_count += 1
name = tag.name + "SCL"
y = height * row_count
parameters = '{"Alarm":"ALM", "TagPath":' +'"'+ tag.path +'"'+'}'
row = [name, template, layup, x, y, width, height, parameters]
temprows.append(row)
row_count += 1
if hh.value:
name = tag.name + "HHALM"
y = height * row_count
parameters = '{"Alarm":"HHALM", "TagPath":' +'"'+ tag.path +'"'+'}'
row = [name, template, layup, x, y, width, height, parameters]
temprows.append(row)
row_count += 1
if h.value:
name = tag.name + "HALM"
y = height * row_count
parameters = '{"Alarm":"HALM", "TagPath":' +'"'+ tag.path +'"'+'}'
row = [name, template, layup, x, y, width, height, parameters]
temprows.append(row)
row_count += 1
if l.value:
name = tag.name + "LALM"
y = height * row_count
parameters = '{"Alarm":"LALM", "TagPath":' +'"'+ tag.path +'"'+'}'
row = [name, template, layup, x, y, width, height, parameters]
temprows.append(row)
row_count += 1
if ll.value:
name = tag.name + "LLALM"
y = height * row_count
parameters = '{"Alarm":"LLALM", "TagPath":' +'"'+ tag.path +'"'+'}'
row = [name, template, layup, x, y, width, height, parameters]
temprows.append(row)
row_count += 1
if (scl.value or hh.value or h.value or l.value or ll.value) and blanks: #Add a blank space for separation between tags.
row_count += 1
if (page == page_count): # Add these rows if this is the correct page
rows = rows + temprows
# Add the button at the bottom.
for button_count in range(page_count):
temprows = []
name = "Button " + str(button_count)
if button_count == (page - 1):
pass # This is the page we are on...
else:
if button_count == 0:
x3 = 0
else:
x3 = (width3 * button_count) + (10 * button_count)
y = canvas_height - height3
parameters = '{"page": "' +str(button_count+1) + '", "text":' +'"Page '+ str(button_count+1) +'"'+'}'
row = [name, template3, layup, x3, y, width3, height3, parameters]
temprows.append(row)
rows = rows + temprows
# Create the dataset to send back.
headers = ["name", "template", "layup", "x", "y", "width", "height", "parameters"]
data = system.dataset.toDataSet(headers, rows)
# Let's send the data back.
event.source.templates = data
event.source.setPropertyValue('totalpage', page_count)
The tricky part is getting the buttons to set the 'page' property on the Template Canvas.
The easiest way I found was go to the Top Level and drill back down.
Here is the code for the actionPerformed on the event handler of the button.
from com.inductiveautomation.factorypmi.application.components import TemplateCanvas
# Get the custom property 'page' from the button.
page = event.source.parent.page
#Get the component count and the components below the 'Root Container'
count = event.source.getRootPane().getLayeredPane().getComponents()[0].getComponentCount()
components = event.source.getRootPane().getLayeredPane().getComponents()[0].getComponents()
for i in range(count):
#Look for the TemplateCanvas instance, then check if the page property exists.
if isinstance(components[i],TemplateCanvas):
if 'page' in components[i].dynamicProps:
components[i].setPropertyValue('page', page)
So I can now make all my analog pages dynamically and they fit on to any size monitor.