Python is a popular high-level programming language known for its readability and performance. Typically, when you code in Python, you’re using the standard Python implementation – CPython – which is simply Python written in C. When scripting in the Ignition SCADA software by Inductive Automation however, you’re actually using Jython – a flavor of Python that runs in the Java Virtual Machine. With Jython come a few tips that you should know.
All Java Packages Are Available To You
Ignition does a great job of including the necessary components to make a full-featured SCADA system. There are times, though, where you find yourself wishing for some extra functionality. In these scenarios, being able to access Java packages without the need for writing a custom module is incredibly handy.
Take for instance the popup message boxes. Ignition provides confirm, text input, message, warning, and error dialog boxes, but does not provide a way to present a series of choices and get user feedback. Luckily, Java has the JOptionPane component that we can configure and bring in with only a few lines of code.
from javax.swing import JOptionPane
jop = JOptionPane(
message = 'What is the best language?'
title = 'Select an Option'
messageType = -1
icon = event.source.parent.getComponent('Logo').getIcon()
options = ['Python','Java','C#','C','Ruby','Pascal','Assembly','Javascript']
isv = 'Python'
bestLang = jop.showInputDialog(None,message,title,messageType,icon,options,isv)
event.source.parent.getComponent('Label').text = "You Selected: " + bestLang
from javax.swing import JOptionPane
Ignition Components Are Just Java Components
Ignition is written in Java. Therefore, the UI components that you use are just new classes that extend a parent class. This means that the methods and properties available for the parent are inherited by the child. Let’s look at the standard table component. The class name for the component is PMIChart and it belongs to the com.inductiveautomation.factorypmi.application.components package. If you go to the web documentation for this class, you can see the full hierarchy.
Further down in the documentation, you can also see all of the methods defined for the PMIChart class, as well as for the methods inherited from all of the classes above it in the hierarchy. As an example, here are the methods inherited from the ChartPanel class:
Using Python scripting, you can use any of these methods to retrieve information or change the value.
More Properties Are Available To You Than You Think
Along the lines of the previous section, there are more properties you can change than you would think from looking at the Property Editor panel. Let’s use the Pie Chart component as an example of what you can do.
We want to use the pie chart as a base to make a progress donut. After changing the colors, dataset, and making the shape into a ring, we’re left with the picture on the left. After accessing the actual pie chart and its plot component (and adding a label), we can make the one on the right. Putting the following lines in visionWindowOpened event script, we can make a progress donut that’s similar to ones you see in web design.
from java.awt import BasicStroke
pieChartNew = event.source.parent.getComponent('Pie Chart New')
plot = pieChartNew.getChart().getPlot()
# remove border
plot.setOutlineVisible(0)
# remove shadow
plot.setShadowPaint(None)
# remove separator lines
stroke = BasicStroke(0)
plot.setSeparatorStroke(stroke)
You Can Alter Defaults
Another way that you can alter how components look is to change their default settings using Java’s UIManager. The UIManager manages how everything looks within a Java application typically through setting the Look and Feel to a particular class (Ignition uses the Alloy Look and Feel) and providing default values for components to use such as colors and borders. Let’s look at redesigning the Ignition scrollbar to match our light color scheme with a blue accent color. Additionally, we’ll add some padding to the text area so that the text isn’t touching the boundaries.
To start, we have the standard text box with a changed background color and antialiasing turned on.
Next we’ll call the following script:
from javax.swing import UIManager
from javax.swing.plaf import ColorUIResource, FontUIResource, InsetsUIResource, DimensionUIResource
from java.awt import Color, Dimension
from javax.swing import BorderFactory, ImageIcon
UIManager.put("ArrowButton.arrowColor",ColorUIResource(33,150,243))
UIManager.put("ArrowButton.arrowShadow",ColorUIResource(245,245,245))
UIManager.put("ArrowButton.background",ColorUIResource(245,245,245))
UIManager.put("ArrowButton.borderColor",ColorUIResource(245,245,245))
UIManager.put("ArrowButton.innerHighlight",ColorUIResource(245,245,245))
UIManager.put("ArrowButton.innerShadow",ColorUIResource(245,245,245))
UIManager.put("ArrowButton.rolloverIndicator",ColorUIResource(Color(0,0,0,0)))
UIManager.put("ScrollBar.background",ColorUIResource(245,245,245))
UIManager.put("ScrollBar.border",BorderFactory.createEmptyBorder())
UIManager.put("ScrollBar.isButtonRollover",False)
UIManager.put("ScrollBar.isThumbRollover",False)
UIManager.put("ScrollBar.thumbBackground",ColorUIResource(230,230,230))
UIManager.put("ScrollBar.thumbBorderColor",ColorUIResource(230,230,230))
UIManager.put("ScrollBar.thumbHighlight",ColorUIResource(224,224,224))
UIManager.put("ScrollBar.thumbRolloverBorderColor",ColorUIResource(224,224,224))
UIManager.put("ScrollBar.thumbShadow",ColorUIResource(224,224,224))
UIManager.put("ScrollBar.width",15)
UIManager.put("ScrollPane.background",ColorUIResource(250,250,250))
UIManager.put("ScrollPane.border",BorderFactory.createEmptyBorder())
UIManager.put("TextArea.border",BorderFactory.createEmptyBorder(10,10,10,10))
system.nav.closeWindow("Main Window")
system.nav.openWindow("Main Window")
The text box now looks like this:
All text boxes in the project will be updated to have a text padding and any component that has a scrollbar – text areas, tables, alarm journals, etc. - will have this new scrollbar style.
Keep in mind that components that have their default settings changed, need to be refreshed in order for the change to be seen. The easiest case is to just close and reopen an uncached window or to run the script on client startup.
You Can’t Use Most Python Extensions
While there is plenty that you can do with Jython – especially within Ignition, it would be remiss to not mention that most Python extensions are not compatible. This includes the popular packages NumPy and SciPy, as well as several others. Thankfully, nearly all built in Python libraries are supported by Jython or are easily substituted by Java functionality.
Additional Resources
Blog: Tips for optimizing Ignition SCADA performance
White paper: Learn how to improve your SCADA UI designs
Comments